gulp でディレクトリ構造を維持したコピー
失敗談 & そこから得られた知見の記録。いままで gulp で複数ディレクトリの構造を維持してコピーするとき以下のようにしていた。
var gulp = require( 'gulp' );
gulp.task( 'copy', function() {
gulp.src( 'src/*.html' ).pipe( gulp.dest( 'dest' ) );
gulp.src( 'src/css/**' ).pipe( gulp.dest( 'dest/css' ) );
gulp.src( 'src/js/*.js' ).pipe( gulp.dest( 'dest/js' ) );
} );
この処理だと gulp.dest
が冗長なうえ同期実行のためにコールバック関数を呼び出す場合も個別に end/error
イベントをハンドリングする必要があり面倒だ。それにもかかわらずこうしているのは gulp.src
の対象は配列を指定可能だけど gulp.dest
は単一であるため。
しかし gulp/API.md を読み直したら gulp.src
の options
に base
というプロパティがあって、これに処理対象のベースとしたいディレクトリを指定すると gulp.dest
上で構成を再現してくれるようだ。よってはじめの処理はこう書ける。
var gulp = require( 'gulp' );
gulp.task( 'copy', function() {
return gulp.src(
[ 'src/*.html', 'src/css/**', 'src/js/*.js' ],
{ base: 'src' }
)
.pipe( gulp.dest( 'dest' ) );
} );
src
以下のものを dest
へ出力する際に src
時点のディレクトリ構成を維持してくれる。gulp.src
のパス指定は非常に柔軟なので、これと base
オプションを組み合わせれば単一の gulp.src
だけで大抵は十分だろう。コピーを独立した task
で定義するときもストリームが単一ならそれを返すだけで同期実行をサポートできて便利だ。
base
オプションは gulp API の冒頭あたりで解説されている基本機能なのに見逃していた。はずかしい。