JavaScriptメインでWeb開発を行う際にさまざまな作業を自動化して開発効率を爆発的に高めるツール(Grunt、Yeoman、Bowerなど)などを紹介していく連載。今回は、既存のプラグインを使用せず、独自タスクを定義したり、独自プラグインを作成してnpmモジュールとして公開したりする方法を紹介します。
前回の「CoffeeScriptやSassなどの使用時にオススメのGruntプラグイン一覧」では、「grunt-contrib」プラグインを使用して基本的なGruntの使い方について解説しました。
今回は、既存のプラグインを使用せず、独自タスクを定義したり、独自のGruntモジュールを作成してプラグインページに公開したりする方法を紹介します。
なお、まだGruntを実行する環境がない場合、連載第1回の「ブラックなWeb開発現場の救世主、Gruntのインストールと使い方」を参考に用意しておいてください。
タスクはGruntにおける1つの実行単位です。前回はgrunt-contribプラグインを使用していろいろなタスクを実行してみましたが、Gruntにはさまざまなタスク(プラグイン)があり、ほしい機能を持つタスクはすでに誰かが作成してくれていることも多いです。
そういった場合にはnpmでそのタスクをインストールして使用すればいいのですが、既存のタスクでは自分の望む機能を実現できないこともあります。
そんなときは自分でタスクを定義しましょう。Gruntではタスクを幾つかの方法で定義・実行できます。
Aliasタスクを定義すると、複数のタスクを1つのタスクとして順番に実行できます。Aliasタスクは、下記のようにregisterTaskを用いて定義します。
grunt.registerTask({タスク名}, [{説明}, ] {タスクの配列});
{タスクの配列}では指定された順番にタスクが実行されます。
Aliasタスクはいままで何度か使用してきました。以前の例では、connectとwatchタスクが、Grunt実行時にタスク指定されなかった場合に自動的に順番に実行されるように、defaultタスクとして定義しています。
・ ・ grunt.registerTask("default", ["connect", "watch"]); ・ ・
これは、connectとwatchに「default」というAlias(エイリアス:別名)を付けて定義していることになります。
ちなみに、タスクの配列ではタスク指定時に「:」を使用して引数を指定することも可能です。
このタスクが実行されると、Gruntは関数の引数として「:」区切りの値を引数として受け取り、指定された関数を実行します。
grunt.registerTask({タスク名}, [{説明}, ] {タスク関数});
例えば、次のようなGruntfile.jsを見てみましょう。下記の例ではfooというBasicタスクを定義しており、これは2つの引数を受け取ることができます。
module.exports = function(grunt) { grunt.registerTask('foo', 'A sample task that logs stuff.', function(arg1, arg2) { if (arguments.length === 0) { grunt.log.writeln(this.name + ", no args"); } else { grunt.log.writeln(this.name + ", " + arg1 + " " + arg2); } }); };
実際にGruntを実行してみます。タスク名のみで引数なしで指定してみると、次のような結果が表示されます。
% grunt foo Running "foo" task foo, no args Done, without errors.
次に「:」区切りでタスクを実行してみます。指定した引数をBasicタスク内で参照できているのが分かります。
% grunt foo:hello:123 Running "foo:hello:123" (foo) task foo, hello 123 Done, without errors.
このタスクが実行されると、Grunt内で同じ名前のプロパティを探して実行します。そして、任意の名前が着いた複数の設定を持つことが可能です。
Multiタスクでは、タスクとターゲットを「grunt {タスク名}:{ターゲット名}」として指定すると、指定されたターゲットが実行されます。また、「grunt {タスク名}」として実行されると、全てのターゲットをそれぞれ実行します。
grunt.registerMultiTask({タスク名}, [{説明}, ] {タスク関数});
次のようなGruntfile.jsを見てみましょう。ここではlogタスクのターゲットとして、「foo」「bar」「baz」がそれぞれ指定されています。registerMultiTaskではlogタスクを定義しています。
logタスクは指定されたターゲット名とそのデータを表示するようになっています。
module.exports = function(grunt) { grunt.initConfig({ log: { foo: [1, 2, 3], bar: 'hello world', baz: false } }); grunt.registerMultiTask('log', 'Log stuff.', function() { grunt.log.writeln(this.target + ': ' + this.data); }); };
タスク名とターゲット名を指定して実行してみます。
% grunt log:foo Running "log:foo" (log) task foo: 1,2,3 Done, without errors.
次にタスク名のみを指定して実行してみます。
% grunt log Running "log:foo" (log) task foo: 1,2,3 Running "log:bar" (log) task bar: hello world Running "log:baz" (log) task baz: false Done, without errors.
全てのターゲットが順番に実行されているのが分かります。
構文的にはBasicタスクと同じですが、Multiタスクのように、タスクを順番に実行できます。このタスクを使用すれば、自分で細かくカスタマイズした形で複数のタスクを実行できます。
module.exports = function(grunt) { grunt.registerTask('foo', 'foo', function() { grunt.log.writeln(this.name + " is execute."); }); grunt.registerTask('bar', 'bar', function() { //タスクキューにfooを入れる.barが完了したら実行される grunt.task.run(['foo']); grunt.log.writeln(this.name + " is execute."); }); };
barタスクでは内部でgrunt.task.run関数を使用してfooタスクを登録しています。
こうすることで、barタスク完了後にfooタスクが実行されます。
% grunt bar Running "bar" task bar is execute. Running "foo" task foo is execute. Done, without errors.
またCustomタスクでは、タスクを非同期でも実行できます。さらにgrunt.task.requires関数を使用して、依存するタスクが実行されて失敗していないかどうかチェックしたり、特定のプロパティが設定されているかどうかチェックしたりすることもできます。
そういった機能や、この章で紹介したタスクについてはGrunt公式のドキュメント「Creating tasks」に詳細な解説があります。ご確認ください。
Copyright © ITmedia, Inc. All Rights Reserved.