Sassで@import
を使用している場合、大量にファイルがあるとそれらすべてを記述していくのが面倒と感じるときがあります。
また、新たにファイルを作成する度に@import
を追記し、逆に不要なファイルが出てきたら該当の@import
を削除する必要がありますが、それらも頻繁にあると地味に面倒です...。
これらの手間を「gulp-sass-glob」というプラグインを利用して少しでも楽に管理できるようにする方法を紹介します。
プラグインのインストール
「gulp」のインストールなど基本的なものは既に準備できている想定で、まずは下記をコマンドに入力して「gulp-sass-glob」というプラグインをインストールします。
$ npm i -D gulp-sass-glob
タスクの記述
プラグインをインストールしたらタスクを記述していきます。
下記のサンプルコードはもともと「gulp-sass」を使ってCSSにコンパイルするというタスクだったものに赤文字部分を追記してglobが利用できるようにしたもので、「gulp-sass-glob」の処理は「gulp-sass」の前に加えます。
var gulp = require( 'gulp' ),
sass = require( 'gulp-sass' ),
sassGlob = require( 'gulp-sass-glob' );
gulp.task('css', function() {
return gulp.src(paths.src)
.pipe(sassGlob())
.pipe(sass())
.pipe(gulp.dest(paths.dest));
});
paths.src
とpaths.dest
としている部分は、それぞれファイル指定のパスを記述する部分になるので、自身の環境に合わせて任意のものに変更してください。
@importの記述を変更する
今回は例として/import
というディレクトリ内に_a.scss
, _b.scss
, _c.scss
, _d.scss
, _e.scss
という5ファイルがあると想定し、それらを@import
を使って読み込む場合、通常だと下記のような形で5ファイル分の@import
を記述する必要があります。
@import "import/a";
@import "import/b";
@import "import/c";
@import "import/d";
@import "import/e";
これが「gulp-sass-glob」を使うことによって下記のようにワイルドカードを用いて記述することができ、先述したように複数のSCSSファイルがあったとしてもこの1行ですべてを読み込んでくれます。
@import "import/**";
@import
の記述を変更後、今回のサンプルとして用意したタスクを$ gulp css
で実行してみると、ちゃんとすべてのファイルが読み込まれた状態でコンパイルされ、指定した箇所に出力されているのが確認できると思います。
また、例えば新たに_f.scss
というファイルが必要になったら@import "import/f";
と追記したり、逆に_c.scss
というファイルが不要になったら@import "import/c";
を削除する必要がありましたが、そういった追記・削除をするのも「gulp-sass-glob」を使うことで不要になります。
特定のファイルは読み込みたくない場合
「gulp-sass-glob」を使うことでファイルの追加や削除の度に@import
を書き換える手間はなくなりましたが、例えば使用していないのに何らかの理由で消すことができないなど、読み込んでほしくないファイルが指定したディレクトリにあるような場合は、タスク記述時に下記のようにignorePaths
で指定することで特定のファイルを読み込まない形にできます。
下記の場合は/import
ディレクトリ内にある_a.scss
と_b.scss
を無視するという記述になり、この状態でタスクを実行してみると指定した2ファイルが読み込まれていないのを確認できます。
gulp.task('css', function() {
return gulp.src(paths.src)
.pipe(sassGlob({
ignorePaths: [
'import/_a.scss',
'import/_b.scss'
]
}))
.pipe(sass())
.pipe(gulp.dest(paths.dest));
});
上記はファイル名を指定した記述方法ですが、他にも'import/**'
と記述して/import
ディレクトリ内のファイルをすべて無視といった形にすることもできます。
意図的に最初に読み込みたいファイルがある場合にも
上でignorePaths
は読み込みたくないファイルを指定する際に使用するということで紹介しましたが、最初に読み込まれてほしいファイルがある場合にもこのignorePaths
が使えます。
globを使った場合は名前順で読み込まれるので、場合によっては最初に読み込まれてほしいファイルが読み込まれずに最悪スタイルが崩れるといった可能性もあります。(もちろん、そもそもそういったことがないようにCSSを書いておくというのが好ましいですが...)
別途ディレクトリを設けることで対応したり、もっとシンプルな対応方法もあるかもしれませんが、ignorePaths
を下記のように使用することで特定のファイルを最初に読み込むことができます。
先ほどと同様、/import
というディレクトリ内に_a.scss
~ _e.scss
という5ファイルがあると想定し、それを@import "import/**";
で指定した場合は、読み込みは名前順となるのでa → b → c → d → eという順になります。
これを例えば_c.scss
を最初に読み込む形にしたい場合は、gulpfile.js
と@import
を記述するSCSSファイルそれぞれを下記のように記述します。
gulp.task('css', function() {
return gulp.src(paths.src)
.pipe(sassGlob({
ignorePaths: [
'import/_c.scss'
]
}))
.pipe(sass())
.pipe(gulp.dest(paths.dest));
});
@import "import/c";
@import "import/**";
gulpfile.js
ではignorePaths
で最初に読み込みたいファイルである_c.scss
を指定してglobが無視されるようにし、SCSSファイルでは複数ファイルを読み込む@import "import/**";
の前に個別で_c.scss
が読み込まれるように指定します。
この状態でタスクを実行すると先ほどと同じファイルを読み込んではいますが、c → a → b → d → eという順で読み込まれるようになり、ignorePaths
部分を編集する手間が増えてはしまいますが、@import
の記述・削除の手間を省きつつ任意のファイルを先に読み込むという形にすることができます。
絶対使うべきとまでは思いませんが、上でも触れたようにファイルの追加・削除などが多い場合などで少しでも楽したいときには便利なプラグインだと思います。
Stylusのように最初からこのような機能が用意されているものもありますし、Sassも同じようにプラグインとか使用せずに早く使えるようになってくれると嬉しいですね。
プラグインの詳細などについては、以下で確認できます。