grunt-task-helperというGruntプラグインを使っている。ざっと言うとsrcdestを比較してフィルターをかけた結果を他のタスクで使えるようになったりするもの。例えばビルトインの比較機能であるnewFileを使うと、更新されたファイルがあった場合にだけ走るタスクと似たようなものが簡単に作れる。

grunt-contrib-concatを使っているとして、そのタスク設定が以下のようになっているとする。

concat: {
  options: {
    seperator: ';'
  },
  prettify: {
    src: [
      'scripts/prettify/prettify.js',
      'scripts/prettify/lang-config.js',
      'scripts/prettify/lang-css.js',
      'scripts/prettify/lang-scss.js',
      'scripts/prettify/lang-vim.js',
      'scripts/prettify/prettify-loader.js'
    ],
    dest: 'scripts/prettify.js'
  }
}

この場合は順番が重要なのでグロブでまとめて拾っていない以外は普通なマルチタスク設定。これをgrunt-task-helperを挟むように書きかえるとこうなる。

concat: {
  options: {
    seperator: ';'
  },
  prettify: {
    files: '<%= taskHelper.prettify.options.filesArray %>'
  }
},

taskHelper: {
  prettify: {
    options: {
      handlerByFile: 'newFile',
      filesArray: []
    },
    src: [
      'scripts/prettify/prettify.js',
      'scripts/prettify/lang-config.js',
      'scripts/prettify/lang-css.js',
      'scripts/prettify/lang-scss.js',
      'scripts/prettify/lang-vim.js',
      'scripts/prettify/loader.js'
    ],
    dest: 'scripts/prettify.js'
  }
}

srcdestをtaskHelperタスクに移して、concatタスクのfilesテンプレートを使ってフィルター結果が格納されるfilesArrayを参照してやる。ここではビルトインのnewFileを使っていて、srcに指定されたファイルのうちひとつでもdestで指定されたファイルより新しい場合にのみfilesArraysrcdestがコピーされる。そうでない場合は空になるのでconcatタスクは何もせず完走する(エラーにはならない)。

比較に使ったnewFileの代わりにサイズで比較するsizeを使うこともできるし、自前でfalseを返して除外していく関数を書いたりもできる。自前で色々やると誰にも読めなくなるGruntfile.jsの出来上がりなので、公の場では控えた方が良さそう。

srcdestの比較だけじゃなくて、srcの内容をちょっといじってdestに吐くみたいなことも出来るhandlerByContentというオプションなどもある。READMEの例ではSSIのインクルードみたいなことやってて、そういったファイルをちょっと弄るだけのタスクなら自前でファイルの読み書きとかをすることなく簡単に書けるようだ。

まだ公開されたばかりのGruntプラグインなので、いろいろな変更や機能の追加がありそうでどういうものになるかはなんとも言えない。けどGruntのとりあえず全部やる的な大雑把さを効率化させるのに役に立ちそうで期待している。