blog.bouzuya.net

2015-01-09 run-sequence をためした

週ぶり (shuburi) 2015-W02 (6) 。

bouzuya/hspd-app の続き。今日も gulpfile 。run-sequence で同期的にタスクを動かしてくれない問題を解消。まだ課題はあるけど、そろそろ開発できそう。

run-sequence がなかなか良くて、gulp のタスクを順番に実行することができる。何を当たり前のことをと思われるかもしれないが、意外とこれが難しい。

gulp ではタスクを呼び出す gulp.run は deprecated になっている。gulp.task / gulp.watch の deps を使うことが推奨されている。だけど、そううまくいかない。たとえば次のようなコードは期待どおりに動かない。

gulp.task 'x', (done) ->
  setTimeout ->
    console.log('x')
    done()
  null

gulp.task 'y', (done) ->
  setTimeout ->
    console.log('y')
    done()
  null

gulp.task 'z', ['x', 'y'], ->
  console.log('z')

gulp の task は stream / promise / callback で処理の完了を待ってくれる。それを考えると、'x', 'y', 'z' の順に処理してくれそうだが、そうとも限らない。この場合、'x' の完了を待たずに 'y' は開始されてしまう。'z' で指定されている ['x', 'y'] は、この順に実行するという意味にはならず、'x', 'y' がともに完了してから開始するという意味になる。

もし、'x', 'y', 'z' としたければ、'y' は ['x'] と指定すれば良い。

でも、話はそう単純ではなくて、['clean', 'build'] みたいな処理をしたい場合、'watch' の中で動かすことも考えると、毎回 'clean' するのはおかしい。だけど、'clean' が先に動いてくれないと困る、みたいなケースもあるわけで、単純に依存関係つければ良いってもんでもない。

そこで run-sequence 。これを使うとこんな感じになる。

gulp.task 'x', (done) ->
  setTimeout ->
    console.log('x')
    done()
  null

gulp.task 'y', (done) ->
  setTimeout ->
    console.log('y')
    done()
  null

gulp.task 'z', (done) ->
  run = require 'run-sequence'
  run.apply run, [
    'x'
    'y'
    (e) ->
      console.log('z')
      done(e)
  ]

README を見てもらえば分かるけど、並列にしたい部分も選べたりする。良い。

ちなみに gulp の次のバージョン ( 4 ? )では task まわりの API がかわって、似たようなことを標準機能のなかでできるようになるみたい。そこまで追いかける気力はないけど。

軽く gulp のソースコードを追ってみたのだけど、gulp って本体のソースコードがほとんどなくて、ほとんど別のリポジトリ (パッケージ) に切りだされている。そういうつくりも依存関係を明確にする点では良いかもと思った。

会社。

vulcand のバージョンを v0.8.0 に。はやく alpha とれないかな、これ。何か問題見つかったら戻す。

その他。

全身が筋肉痛。