gulpでsassをコンパイルするタスクを作る
何番煎じかわからないけど、gulpを使ってみたら中々良かったのでまとめてみます。
gulp.jsとは
gulp.js はフロントエンド用のタスクランナーってやつです。
同じタスクランナーの競合に Grunt がありますが、後発だけあってストリームを駆使して可読性の良い設定ファイルが書けます。
Gruntでできることは大体gulpでもできるので、どちらを使ったら良いかは好みの問題かも知れません。
この記事ではsassのコンパイルをするタスクと、関連してベンダープレフィックスを自動で付与するところまで紹介します。
gulpのインストール
npmコマンドでサクッと入れます。
$ npm install -g gulp
これでgulp
コマンドが使えるようになりました。
gulpでsassのコンパイルをする
gulpでsassをコンパイルするのに、こちらのプラグインを使います。
gulp-ruby-sass - Compile Sass to CSS with Ruby Sass
よく読むと、rubyとsassが使えるようになっていないといけません。
下準備
rubyは使えるとして、もしsassが入っていなければgem install
します。
(ちなみに私はrbenvでrubyをインストールしています)
$ gem install sass Fetching: sass-3.4.3.gem (100%) Successfully installed sass-3.4.3 Parsing documentation for sass-3.4.3 Installing ri documentation for sass-3.4.3 Done installing documentation for sass after 8 seconds 1 gem installed # (↑既にsassが入ってる状態でinstallした結果) $ rbenv rehash # ←rbenvで自動で反映させるgem使ってなければやる
これで下準備が整ったのでgulp-ruby-sass
を入れます。
$ npm install --save-dev gulp-ruby-sass
それではgulpのタスクを作っていきます。
gulpfile.jsにタスクを作る
プロジェクトルート直下にgulpfile.jsを作成して、中身はこんな感じにします。
// @file gulpfile.js var gulp = require('gulp'); var sass = require('gulp-ruby-sass'); // $ gulp sass で実行するタスク gulp.task('sass', function () { gulp.src('sass/**/*.scss') .pipe(sass({ style : 'expanded' })) .pipe(gulp.dest('dist/css/')); });
何をやっているかというと、gulp.src('sass/**/*.scss')
でsass/
ディレクトリ以下の.scss
ファイルを全てコンパイルの対象にしています。
sass({ style : 'expanded' })
では対象になったファイルを実際にコンパイルしています。
gulp.dest('dist/css/')
ではコンパイルされたcssファイルをdist/css/
以下に、元々あったディレクトリ構成のまま配置しています。
この例は一番簡単な例なので、もう少し見ていきます。
watchタスクを作る
scssファイルに変更があったら自動的にコンパイルしてほしいものです。
そういうときはwatch
タスクを作ります。
// @file gulpfile.js var gulp = require('gulp'); var sass = require('gulp-ruby-sass'); gulp.task('sass', function() { gulp.src('sass/**/*.scss') .pipe(sass({ style : 'expanded', })) .pipe(gulp.dest('dist/css/')); }); // 追記する gulp.task('watch', function () { gulp.watch('sass/**/*.scss', ['sass']); });
gulp.watch()
の第一引数にはgulp.src()
の第一引数と同じ書き方で指定します。(配列でも指定できます)
第二引数には変更を検出した際に実行するタスク名を配列で指定します。
watchタスクができたので$ gulp watch
でwatchを開始します。
$ gulp watch [gulp] Using gulpfile ~/hoge/fuga/gulpfile.js [gulp] Starting 'watch'... [gulp] Finished 'watch' after 7.05 ms
これでscssファイルを編集する度にsassのコンパイルが走るようになりました。
しかし、watch中にsassのコンパイルエラーが発生(シンタックスエラーなど)するとwatchが解除されてしまいます。
これを防止するために gulp-plumber を入れます。
$ npm install --save-dev gulp-plumber
次にsass
タスクを少し修正します。
// @file gulpfile.js var gulp = require('gulp'); var sass = require('gulp-ruby-sass'); var plumber = require('gulp-plumber'); // 追記 gulp.task('sass', function() { gulp.src('sass/**/*.scss') .pipe(plumber) // 追記 .pipe(sass({ style : 'expanded' })) .pipe(gulp.dest('dist/css/')); }); gulp.task('watch', function () { gulp.watch('sass/**/*.scss', ['sass']); });
これでwatch中にエラーが発生しても中断されなくなりました。
autoprefixerを使ってベンダープレフィックスを自動で付ける
ベンダープレフィックスはゆくゆくは外れていくものなので、このブラウザはベンダープレフィックスが必要というような知識はすぐに要らなくなってしまいます。
こういうことは人間が覚えるのではなく、コンピュータに自動でやってもらいましょう。
ということで、autoprefixerを使ってベンダープレフィックスを自動でつけてもらいます。
autoprefixerの仕組ですが、Can I use を見てベンダープレフィックスが必要かどうかチェックしているようです。
ブラウザのバージョン指定もできて便利なので使っておくことを勧めます。
ちょっと調べると gulp-autoprefixer よりも gulp-pleeease の方がおすすめされてるようです。
タスクを細かく分割したいなら gulp-autoprefixer
使えばいいですし、まるっとminifyまでやって欲しいなら gulp-pleeease
使えばいいような気がします。
参考:gulp-autoprefixerよりもいい感じ。gulp-pleeeaseを使ってcssを処理しよう
ということで、gulp-pleeease
をインストールします。
$ npm install --save-dev gulp-pleeease
gulpfile.js
に追記します。
// @file gulpfile.js var gulp = require('gulp'); var sass = require('gulp-ruby-sass'); var plumber = require('gulp-plumber'); var pleeease = require('gulp-pleeease'); // 追記 gulp.task('sass', function() { gulp.src('sass/**/*.scss') .pipe(plumber()) .pipe(sass({ style: 'expanded' })) .pipe(pleeease({ // 追記 autoprefixer: { browsers: ['last 2 versions'] }, minifier: false // minify無効 })) .pipe(gulp.dest('dist/css/')); }); gulp.task('watch', function () { gulp.watch('sass/**/*.scss', ['sass']); });
gulp-pleeease
に指定できるオプションについてはこちらのドキュメントに書いてます。
それではどんな感じにベンダープレフィックスを付けてくれるのか見てみます。
display: flex
display: flexほどベンダープレフィックス覚えるのが大変なものはないのではないでしょうか。
ということで、ためしに上下中央寄せにするsassをコンパイルしてみます。
.centerMiddle { display: flex; justify-content: center; align-items: center; }
出力されたcssファイルはこのようになりました。
.centerMiddle { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-pack: center; -webkit-justify-content: center; -ms-flex-pack: center; justify-content: center; -webkit-box-align: center; -webkit-align-items: center; -ms-flex-align: center; align-items: center; }
今回は出力を見やすくするためにminifier: false
を指定しましたが、デフォルトでminifiler: { preserveHacks: true, removeAllComments: true }
が効いているので、出力をきれいに見たいとき以外は指定しないほうがいいです。
Compassを使っている場合
もしsass+compassを使っている場合、compass側で用意されているscssを読み込もうとしてエラーになる場合があります。
# ↓こんなエラー Plumber found unhandled error: Error in plugin 'gulp-ruby-sass' Message: error hoge.scss (Line 2: File to import not found or unreadable: html5reset.
こういう時はsass()
の部分を次のようにするとエラーを回避できます。
.pipe(sass({ style : 'expanded', compass : true // ←これ付けるだけ }))
それでも以下のようなエラーが出る場合がありますが
gulp-ruby-sass: ERROR: Cannot load compass.
この場合はcompassが原因なので、
$ gem install compass --pre
新しいバージョンのcompassを入れ直すとよいようです。
おわりに
gulpのタスクは上から下へ処理が流れるので読みやすいですね。
gulpはストリームをベースにしているということで、フロー制御がGruntよりもわかりにくい印象あるんですが、慣れればだいぶ親しみわきます。
今回sassのコンパイルの話だけだったので、gulpはもう一回くらいやってみるかも。