Edited at

Sassの複数のimportはglobを使って一つにまとめると幸せ

CSSの拡張言語Sassの強力な機能の一つは、ファイルを複数に分割できる「Partials」です。ファイルを機能ごとに分割することで、見通しのよいコードを記述できます。近年注目を浴びている「OOCSS」をSassで実現する上でもよく使われています。

しかし、分割するファイルが多くなればなるほど、大量の@importを記述したり、ファイル分割の度に@importを書き換える手間がかかります。本エントリーでは、このような大量のimport文を短くまとめる方法について紹介します


Sassのファイルの分割と問題点

例えば、_a.scss_b.scssの2ファイルに分割したスタイル設定を、style.scssにて読み込む設定をしてみます。


_a.scss

.classA {

background-color: red;
}


_b.scss

.classB {

background-color: blue;
}


style.scss

@import "a";

@import "b";

style.scssをコンパイルすることで、_a.scss_b.scssが結合されてCSSが出力されます。


結合後のCSS

.classA {

background-color: red;
}

.classB {
background-color: blue;
}



ファイルの増加と共に増加する@import

2ファイルくらいの場合は特に問題ありませんが、例えば次のように多階層・多数に分割したSassファイルの読み込みを考えてみましょう。


└── sass
├── foundation
│   ├── _foundation1.scss
│   └── _foundation2.scss
├── layout
│   ├── _layout1.scss
│   └── _layout2.scss
├── object
│   ├── component
│   │   ├── _component1.scss
│   │   └── _component2.scss
│   ├── project
│   │   ├── _project1.scss
│   │   └── _project2.scss
│   └── utility
│   ├── _utility1.scss
│   └── _utility2.scss
└── style.scss

これらのSassファイルを読み込む場合、次のように多くの@importを記述しなければなりません。

@import "foundation/foundation1";

@import "foundation/foundation2";

@import "layout/layout1";
@import "layout/layout2";

@import "object/component/component1";
@import "object/component/component2";

@import "object/project/project1";
@import "object/project/project2";

@import "object/utility/utility1";
@import "object/utility/utility2";

また、ファイルを追加・削除する度に@importを追加・削除する必要があります。Node.jsのファイル操作機能のように、@import "hoge/**";という記述(globパターン)ができれば短く済みそうですが、Sassの現在のバージョン(3.4)ではそのような機能はありません。

globパターンが使えるプラグインを使うことでこの問題は解決します。


glob用のプラグインでSassのimport文を減らす

Gulp用のプラグイン「gulp-sass-glob」やNode.jsの「node-sass-globbing」といったプラグインを使うと、Sassにおいても@import "hoge/ **";の記述でSassファイルの読み込みが可能になります。今回は、Gulp(※)での設定事例を紹介します。

※ 参考記事「5分で導入! タスクランナーGulpでWeb制作を効率化しよう - ICS MEDIA


環境のセットアップ

まずは環境設定を行います。Gulpがグローバルにインストールされていない場合は、インストールしておいてください(npm install -g gulp-cli)。

プロジェクトフォルダにて、npmの初期設定を行います

npm init -y

Gulp、Sass、そしてgulp-sass-globのプラグインをローカルにインストールします。

npm i -D gulp gulp-sass gulp-sass-glob


タスクの設定

globを用いて記述されたimport文を解釈しつつ、style.scssファイルをコンパイルするタスクを定義します。


gulpfile.js

// プラグインの読み込み

const gulp = require("gulp");
const sass = require("gulp-sass");
const sassGlob = require("gulp-sass-glob");

// Sassコンパイルタスクの定義
gulp.task("default", function() {
return gulp.src("sass/style.scss")
.pipe(sassGlob()) // Sassの@importにおけるglobを有効にする
.pipe(sass())
.pipe(gulp.dest("css"));
});


以上で準備は完了です。Sassファイルをコンパイルしてみましょう。


Sassファイルをコンパイルする

任意のSassファイルを準備します。例として、冒頭で示したファイル構成のSassファイルをstyle.scssで読み込むことを考えます。下記のURLの[Clone or download]よりダウンロードできますので、サンプルを試したい場合はご利用ください。

└── sass

├── foundation
│   ├── _foundation1.scss
│   └── _foundation2.scss
├── layout
│   ├── _layout1.scss
│   └── _layout2.scss
├── object
│   ├── component
│   │   ├── _component1.scss
│   │   └── _component2.scss
│   ├── project
│   │   ├── _project1.scss

(中略)

└── style.scss

▲ コンパイル対象のSassファイル群


globパターンを使って@importを定義

style.scssでglobパターンによる@importを記述します。全てのSassファイル名を記述する必要はなく、最低限の行数のコードで記述可能です。


globパターンを使った読み込み

@import "foundation/**";

@import "layout/**";
@import "object/**";

Sassのコンパイルタスクを実行します


コマンドラインで実行

gulp


出力されたCSSを確認すると、目的のCSSファイルが全て読み込まれていることがわかります。


コンパイル後のCSS

/* foundation1 */

/* foundation2 */
/* layout1 */
/* layout2 */
/* component1 */
/* component2 */
/* project1 */
/* project2 */
/* utility1 */
/* utility2 */

foundationフォルダやlayoutフォルダでファイルの追加・削除があった場合も、style.scssを書き換える必要はありません。


ファイル順を無視すればさらに短く

通常の@importと同じく、記述順にSassファイルは読み込まれます。前述の例では、foundationlayoutobjectの順番にCSSを読み込むために3つの@importを記述しましたが、ファイル順を無視できるファイル構成ならば@importは1行で済みます


更に短いimport

@import "**";



import文は半分以下になり、ファイルの追加・削除

globを用いることで10行あった@importは、3行(構成によっては1行)に減りました。

機能ごとにファイルを分割して見通しのよいSassコードを書いたり、OOCSSに基づくCSS設計を行ったとしても、大量の@import記述に時間を使う必要はありません。glob機能を使いこなし、効率的なSassのコーディングを行いましょう。