2013/07/10更新

[gruntJS] gruntJSでタスクを実行する際に、引数で処理対象のファイルを変更する

このエントリーをはてなブックマークに追加      

こんにちは、@yoheiMuneです。
GruntJSについて、「GruntJSで、与えた引数により処理対象のファイルを変更できるか」という質問を頂きました。 結論としては可能だったのですが、その実装方法をこのブログでは書きたいと思います。

画像



GruntJSで引数の内容によって、処理対象のファイルを変更する

今回ですが、引数でイベントIDを渡すことで、処理対象のファイルを変更したいという要件がありました。
たとえば、event001という値を渡すと、

  • event001/
    • dev/
      • aaa.js
      • bb.js
    • dist/
      • event001.js

というディレクトリ構造のdev/aaa.jsとdev/bbb.jsをconcatして、dist/event001.jsというファイルを生成するようなタスクを実行したいとします。 そして、引数で指定する内容が、event002やevent003となると、それに応じて、コンパイル対象も変化させるという内容です。
それでは具体的な実装内容を記載して行きます。



GruntJSで任意の引数を取るには

gruntJSは、引数は「$ grunt concat:foo」といった感じでタスクの内容を指定するのが一般的ですが、 registerTaskメソッドを使って独自に定義したタスクの場合には、引数を受け取ることが可能です。 例えば以下のような実装です。
grunt.registerTask('foo', 'My "foo" task.', function(arg1, arg2) {
  grunt.log.writeln(this.name, arg1, arg2);
});
そして以下のように実行することが出来ます。
$ grunt foo:bar:baz // "foo", "bar", "baz"と表示される
詳細は、gruntjsのドキュメンテーションをご確認下さい。
この仕組みを使ってconcatする際のパスを動的に変更します。



引数の値により、Concatなどのタスクで処理対象とするファイルを動的に変更する

それではここからが本番です。Concatする際に、対象ディレクトリを引数で指定できるようにします。
まずはそれが行えるような、gruntのinitConfigを指定します。
〜省略〜
grunt.initConfig({

  concat: {
    event: {
      // 後続の処理で動的にeventIdが埋め込めるようにしておく
      src: ['{{:eventId}}/dev/*.js'],
      dest: '{{:eventId}}/dest/{{:eventId}}.js'
    }
  }  
});
〜省略〜
そして、registerTaskで以下のような実装を行います。
grunt.registerTask('event_develop', 'event develop', function(eventId) {

    // 上記で設定したinitConfigの内容を取得します。
    var config = grunt.config();

    // {{:eventId}}の部分を置換します。
    config.concat.event.dest = config.concat.event.dest.replace(/{{:eventId}}/g, eventId);
    config.concat.event.src[0] = config.concat.event.src[0].replace(/{{:eventId}}/g, eventId);

    // 上記で上書きした内容をgruntへ設定します。
    grunt.initConfig(config);

    // 引数の値が反映された設定内容で、concatを実行します。
    grunt.task.run('concat:event');
  }
});
確かにできるのですが、ちょっと微妙な気も。。実装を7行程度しなければ行けないのは、面倒です。
実行の度に対象ファイルを変えたいなら引数も良いと思いますが、1週間は同じ開発をするといったスパンがある場合には、外部JSONファイルで保持しても良いかなぁと思いました。具体的には以下のような実装です。
/* gruntfile.js */
module.exports = function(grunt) {

  var pkg = grunt.file.readJSON('setting.json');

  grunt.initConfig({
    concat: {
      event: {
        // setting.jsonで定義したeventIdを元にパスを生成する
        src: [ pkg.eventId + '/dev/*.js'],
        dest: pkg.eventId + '/dest/' + pkg.eventId + '.js'
      }
    } 
  });
};
/* Setting.json */
{
  eventId: "event001"
}
という感じです。

引数を使う場合も、外部JSONを使う場合にも、処理対象を変更する際にgruntJSを書き換える必要がないのは便利で良いですね。



最後に

gruntJSでのビルドは、本当に色々と便利な物が多いですね。 自分でも簡単にタスクを定義できるので、ぜひ自分の案件に最適化されたgruntJSを作ってメンテして行きたいところです。

最後までご覧頂きましてありがとうございました。





こんな記事もいかがですか?

RSS画像

もしご興味をお持ち頂けましたら、ぜひRSSへの登録をお願い致します。