Grunt から gulp へ移行してみた

年度が変わるあたりから、改めて制作環境の見直しを図っているBUNです。
なぜか CodeKit 2 の購入と同時に Grunt をメインで使うようになり、さらにこのブログのリニューアルとあわせて gulp に乗り換えました。

折角なので、移行の際に試行錯誤してみたことをまとめてみようと思います。

そもそも、gulp.js とは?

スクリーンショット

Sass や JavaScript の圧縮処理などを自動化できる、タスクランナーツール。
語弊があるかとは思いつつ「黒い画面で操作する CodeKit」でカスタマイズがより柔軟にできる・・・といったイメージでしょうか。

詳しくは下記などをご覧いただくとして、先に進みましょう(。-_-。) w

【Gulp.js入門】新鋭フロンエンド・タスクランナーツール を試してみました。:
http://dev.classmethod.jp/tool/gulpjs-part-001/

接頭辞が「gulp- | gulp.」なプラグインを一括読込

Grunt を使っているときは、Gruntfile.js へ以下の記述を加えてパッケージをまとめて読み込んでいました。

// Gruntfile.js
module.exports = function(grunt) {
    // Params
    var _package, _taskName;
    _package = grunt.file.readJSON('package.json');

    // load dependenciesPackages
    for(_taskName in _package.devDependencies) {
        if(_taskName.substring(0, 6) == 'grunt-') {
            grunt.loadNpmTasks(_taskName);
        }
    }
};

これと似たようなことを gulp でできないか探したところ、gulp-load-plugins プラグインで実現できました。

参考サイト:
http://www.mikestreety.co.uk/blog/an-advanced-gulpjs-file

$ npm install --save-dev gulp-load-plugins

プラグインをインストールしたら、gulpfile.js の require 部分を修正します。
サンプルコードの場合、gulp-sass は $.sass で実行できます。

// gulpfile.js
var gulp            = require('gulp'),
            $               = require('gulp-load-plugins')({
                                pattern: ['gulp-*', 'gulp.*'],
                                replaceString: /\bgulp[\-.]/
                              }),
            merge       = require('event-stream').merge,
            runSequence = require('run-sequence');

// task.scss
gulp.task('scss', function(){
    return gulp.src('./src/*.scss')
                .pipe($.sass())
                .pipe(gulp.dest('./dist/css'));
});

新しくプラグインを追加した場合でも、都度 require を調整する必要がなくなるので便利ですよね。

gulp.src で基準ディレクトリをセット

参考にしていたサイトでは特に記載がなかったため、しばらく気がつかなかったものの。
最終的に cwd オプションを利用することにしました。

// task.copy
gulp.task('copy', function(){
    return gulp.src(['**/*.{png}', '!sprite/**/*.{png}'], {cwd: './src/img'})
                .pipe(gulp.dest('./dist/img'));
});

基準ディレクトリを指定することで、対象ソースの記述が少しすっきりです。

gulp.spritesmith タスクの見直し

当初 gulp-spritesmith をインストールしてしまい、動かないェ...とハマっていたのは内緒ですが(。-_-。)
spritesmith の設定は、西畑さんのブログ記事を参考にさせていただきました。

gulp.spritesmithを便利にカスタマイズ - to-R:
http://blog.webcreativepark.net/2014/05/26-121844.html

ただ、個人的にタスクを単独でも実行できるようにしたかったため、ディレクトリを配列にセットしておいて forEach でループさせる形に調整してみました。

var sprite_dir = ['aaa', 'bbb', 'ccc'];

// task.sprites
gulp.task('sprites', function() {
    sprite_dir.forEach(function (target) {
        var spriteData  = gulp.src('sprite/' + target + '/*.png', {cwd: './src/img'}).pipe($.spritesmith({
            imgName:    'sprite-' + target + '.png',
            imgPath:    '../img/sprite-' + target + '.png',
            cssName:    target + '.scss',
            cssFormat:  'scss'
        }));

        spriteData.img.pipe(gulp.dest('./src/img'));
        spriteData.css.pipe(gulp.dest('./src/scss'));
    });
});

gulp.task の function に配列を渡せば済む話・・・かとは思いつつ。
そんなことできるのか?すらよく判っていないので、現時点ではこれでいいことにします w

実際に移行してみて

事前に見聞きしていたとおり、並列処理ということで Grunt よりも早い印象。
また、jQuery に似た感覚でタスクごとの処理を定義できるので、判りやすいですね。

とはいえ、一部のタスクは Grunt を利用しているので、状況に応じて使いわけようかなと考えています。