タスク実装が面倒臭い問題
例) src 配下のファイルを拡張子別にコンパイルするタスク
/**
* ES6, JSXコンパイル
*/
gulp.task('js', function(){
return gulp.src('src/**/*.{js,jsx}')
.pipe($.babel())
.pipe(gulp.dest('build'));
});
/**
* slimコンパイル
*/
gulp.task('slim', function(){
return gulp.src('src/**/*.slim')
.pipe($.slim({ pretty: true }))
.pipe(gulp.dest('build'));
});
gulp.task('css', function(){
return gulp.src('src/**/*.*')
.pipe(gulp.dest('build'));
});
/*
* build 以下削除
*/
gulp.task('clean', function(target){
del(['build/**/*'],target);
});
gulp.task('compile', ['clean', 'slim', 'css','js']);
全て src/ 配下を対象としているにも関わらず拡張子別にタスクを設定しなければいけないため
同じようなタスクが量産されている。
コンパイルする拡張子が増えれば増えるほどタスクを複製するのは面倒なので何とか この記述をDRYにしてみる。
gulp-if による拡張子別処理の実装
ストリームの処理に対して条件分岐をかけることができるモジュール。
今回は このモジュールを使って拡張子別に実行モジュールを振り分ける実装を行う。
使い方は以下の通り( 引用:https://github.com/robrich/gulp-if )
var gulpif = require('gulp-if');
var uglify = require('gulp-uglify');
var condition = true; // TODO: add business logic
gulp.task('task', function() {
gulp.src('./src/*.js')
.pipe(gulpif(condition, uglify()))
.pipe(gulp.dest('./dist/'));
});
gulpif の第一引数に対し、boolean を渡すことで後述のモジュールを実行することができる。
今回はストリームで渡されたファイルの拡張子を判定し、それに応じたモジュールを実行する必要があるため、以下のようなメソッドを実装する。
var matcher = function(pattern){
var reg = new RegExp(pattern),
chain = {};
chain.check = function(file){
return reg.test(JSON.stringify(file));
}
return chain;
}
単順にメソッドチェーンを利用し、指定した拡張子のストリームで渡されたファイルの拡張子が等しいかを判定することができる。
このメソッドと先述のgulp-ifで手抜きタスクを実装してみる。
手抜きタスクを実装
gulp.task('test', function(){
return gulp.src('src/**/*.*') //コンパイル対象のディレクトリ以下 全指定
.pipe(gulpif(matcher('slim').check, $.slim({ pretty: true })))
.pipe(gulpif(matcher('js').check, $.babel()))
.pipe(gulp.dest('build'));
});
gulp.task('clean', function(target){
del(['build/**/*'],target);
});
gulp.task('compile', ['clean', 'test']);
スッキリ。
ただし、全ファイルを総なめするためタスク実行速度が遅くなってしまう問題があるので
逐一タスク書くのが面倒でタスク実行速度が多少遅くなっても構わないという場合に使ってみるのが良いかもしれない。