かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

Gulp 4 gulp.seriesとgulp.parallel

gulp v4 で追加されたgulp.seriesgulp.parallelを試してみた

  • gulp.series(...tasks) ... 順番に実行する
  • gulp.parallel(...tasks) ... 並列に実行をする

GitHubのサンプル

gulp.task('one', function(done) {
  // do stuff
  done();
});

gulp.task('two', function(done) {
  // do stuff
  done();
});

gulp.task('default', gulp.series('one', 'two', function(done) {
  // do more stuff
  done();
}));

呼び出されるタスク(関数)の引数にdoneがあり、タスクの最後で実行されています。

fn
The fn is passed a single argument, callback, which is a function that must be called when work in the fn is complete. Instead of calling the callback function, async completion can be signalled by:

  • Returning a Stream or EventEmitter
  • Returning a Child Process
  • Returning a Promise
  • Returning an Observable

Once async completion is signalled, if another run is queued, it will be executed.
出典: gulp/API.md at master · gulpjs/gulp · GitHub

これはタスクの完了を通知するコールバック関数で、タスクランナーでよくあるreturn gulp.src()...をしない場合はdone()の実行を忘れると次のようなタスクの終了がわからないというエラーが表示されます。

[00:00:00] The following tasks did not complete: mytask
[00:00:00] Did you forget to signal async completion?

gulp.series()で実行されるタスクは、この終了の合図があると次のタスクに進むので、gulp.series()内にgulp.parallel()があると並行処理されるタスク全てが完了するまで待機されます。

サンプル

"use strict";
const gulp = require('gulp');

// TASK
function task1(done) {
  console.log('task 1');
  setTimeout(function() {
    console.log('task 1 >> 1100ms');
    done();
  }, 1100);
}

function task2(done) {
  console.log('task 2');
  setTimeout(function() {
    console.log('task 2 >> 1000ms');
    done();
  }, 1000);
}

function task3(done) {
  console.log('task 3');
  done();
}

// Default
gulp.task('default', gulp.series(
  gulp.parallel(task1, task2),
  task3,
  function(done) {
    console.log('default');
    done();
  }
));

👇 実行結果

$ npx gulp
[00:10:20] Using gulpfile ~/example/gulpfile.js
[00:10:20] Starting 'default'...
[00:10:20] Starting 'task1'...
[00:10:20] Starting 'task2'...
task 1
task 2
task 2 >> 1000ms
[00:10:21] Finished 'task2' after 1 s
task 1 >> 1100ms
[00:10:21] Finished 'task1' after 1.1 s
[00:10:21] Starting 'task3'...
task 3
[00:10:21] Finished 'task3' after 305 μs
[00:10:21] Starting '<anonymous>'...
default
[00:10:21] Finished '<anonymous>' after 278 μs
[00:10:21] Finished 'default' after 1.11 s

このように、gulp.seriesで順番を指定するとタスク内にsetTimeoutのような処理があってもdoneが実行されるまで、次の処理は実行されません。

以前はrun-sequenceなどを使って順番を決めていましたが、gulp v4からはgulp.seriesgulp.parallelを使えば少しタイプ数は増えますが複雑なタスクの管理がgulpだけでできそうです!


[参考]