BEMのSCSSファイルをgulpを使って自動コンパイルする

コーディングをする際、CSSのクラス命名に悩んでいたので、BEMというCSSの設計手法を只今勉強しておりますまっちーです。
今回はBEMで設計したSCSSファイルをgulpを使って自動でコンパイルする方法について、記して行きます。

誤っている情報等があるかもしれませんが、その際は優しく教えてくださいませ。

BEMについて

BEMの概要

BEMとは、Block(かたまり)・Element(要素)・Modifier(修飾)の頭文字をとったものです。

BlockElementModifier
説明大きい括り大きい括りの中にある要素状態
header、
content、
footerなど
btn、img、textなどcurrent、大きさ、色など

これらをつなげて以下のように書きます。

block__element--modifier

BlockとElementはアンダースコア2つ__で区切り, ElementとModifierはハイフン2つで区切ります。

少し長いクラス名になりますが、BEMを使うと、HTMLを見ただけでスタイルが予測しやすくなるなどのメリットがあります。

これなら命名に迷わないかも。でもクラス名が長いからcssに書くのが大変そう。。

Scssの書き方

CSSを効率的にかくための言語「Scss」を使うと、BEMは以下のように定義することができます。

.content{
  background-colo:fff;

  &__btn{
    padding:20px 40px;
  }
}

「&」とアンダースコア2つを組み合わせ「&__(Element)」と記述すると、CSSに下記のようにコンパイルされます。

.content {
  background-color: #fff;
}

.content__btn {
  padding: 20px 40px;
}

まっちー

ネスト構造(入れ子)で&__を使えばシンプルに書ける!

BEMのディレクトリ構造

BEMのSCSSファイルは、1blockにつき1ファイルで作成するというルールがあり、複数ファイルに分割されます。ここではとにかくたくさんのscssファイルがたくさんある、ということを理解しておきます。

BEMのSCSSファイルのディレクトリ構造は以下の通り

scss

base

_base.scss

_reset.scss

mixin

(以下割愛)

module

page

pilgins

setting

style.css

index.htmlなどと同じ階層にあるscssディレクトリから、6つのディレクトリに分けられ、その中に、それぞれ_○○.scssファイルが格納されます。BEMの各ディレクトリの役割については下記のサイトを参照してください。

参考

複数のscssファイルをgulpでコンパイルする

なぜgulpなのか

これまでSassのコンパイルはVisual Studio CodeのEasy Sassを使用していましたが、これを使うと、SCSSファイルごとにcssファイルが生成されてしまい、ファイル数が膨大になる問題がありました。

そこで、様々な「タスク」を自動化してくれるgulpが登場します。

gulpにはさまざまな用途がありますが、今回はgulpを使い「各ディレクトリに配置された複数のscssファイルを1つのstyle.scssファイルに読み込み、更新の都度、自動でstyle.cssファイルにコンパイルする」ことを目指します。

gulp・・・難しそうで避けていたけど・・やってみよう!

gulpをインストールしSassを自動でコンパイルする

インストールについては、こちらの記事がわかりやすかったです。

最終項の「watch機能を使えばファイルの更新後に自動で処理を実行できる」まで進めると下記のように自動でコンパイルされるようになります。

複数のscssファイルを1つのstyle.scssファイルに集約する

scssファイルが1つであれば、上記までの操作で自動コンパイルが使えるようになりますが、BEMは複数のscssファイルがあります。そのため各scssファイルを1つのstyle.scssファイルに集約します。

style.scssに下記のように定義することで、集約することができます。

@import "ファイル名";
まっちー

この記述は簡単!でも_base.scssファイルを更新しても全然コンパイルされないなぁ・・

watch()メソッドの「監視するファイル」を変更する

現在のgulpfile.jsは下記の通りになっており、25行目に定義しているように、「css/style.scss」に変更があったときにコンパイルを実行するという処理になっています。

// gulpプラグインを読み込みます
const { src, dest, watch } = require("gulp");
// Sassをコンパイルするプラグインを読み込みます
const sass = require("gulp-sass")(require("sass"));

/**
 * Sassをコンパイルするタスクです
 */
const compileSass = () =>
  // style.scssファイルを取得
  src("css/style.scss")
    // Sassのコンパイルを実行
    .pipe(
      // コンパイル後のCSSを展開
      sass({
        outputStyle: "expanded"
      })
    )
    // cssフォルダー以下に保存
    .pipe(dest("css"));

/**
 * Sassファイルを監視し、変更があったらSassを変換します
 */
const watchSassFiles = () => watch("css/style.scss", compileSass);

// npx gulpというコマンドを実行した時、watchSassFilesが実行されるようにします
exports.default = watchSassFiles;

しかしながら、実際にコードを入力し更新していくファイルはcss/style.scssではなく、css/○○/_○○.scssであるため、25行目のwatch()メソッドの監視するファイル名を変更します。

ファイル名は以下の様に記述をするととってもシンプルになります。

特定のディレクトリ直下にある全てのファイルとディレクトリを扱いたい場合は、アスタリスク2つとスラッシュ、その後ろにアスタリスク1つをつけて指定します。逆にアスタリスクを文字列に置き換えれば、そのファイルだけが監視されるという設定にも出来ます。

https://youki-takemoto.net/archives/106 「Youki Takemoto’s Blog」
"css/**/*.scss"

上記のように定義することで、cssディレクトリ以下の全てのscssファイルが変更された時にコンパイルされるようになります。

まとめると25行目は以下のコードになります。

const watchSassFiles = () => watch("css/**/*.scss", compileSass);

gulpを実行する

gulpを実行する際はコマンドラインでnpx gulpと入力しENTERを押します。

npx gulp

css/base/_base.scssに記述した内容がcss/style.scssにインポートされ、css/stye.cssにコンパイルされるようになりました!


まっちー

うおおおおお!

gulpがうまく動かない時は、Ctrl + cを押して実行中のコマンドを強制終了し、再びnpx gulpと入力すると動くことがあります。

久しぶりにgulpを使おうと思ったら以下のエラーが

Error in plugin "gulp-sass"
Message:
    
gulp-sass no longer has a default Sass compiler; please set one yourself.
Both the "sass" and "node-sass" packages are permitted.
For example, in your gulpfile:

  const sass = require('gulp-sass')(require('sass'));

上記記事を参考に「sass」をインストールします。

npm i -D sass

無事使えるようになりました。

終わり

gulpを使うことでBEMのSCSSファイルを自動でコンパイルすることができました。BEMなどのクラス命名規則を学び、読めやすい、修正しやすいCSS が設計できるように頑張ります。

gulpって「一気に飲む」っていう意味らしい。まさに!

最後までお読みいただきありがとうございました。

この記事を書いた人

まっちー

WEB制作のフリーランスをしていいます。
Shopify構築やWordpress構築を行なっています。