タスクの設定
このガイドでは、プロジェクトでGruntファイルを使ったタスクを構成するための方法について説明します。 もし、Gruntfileのことが分からなければ、はじめにと Gruntfileサンプルを確認してみてください。
Gruntの構成
タスクの構成はGruntfile内のgrunt.initConfig
メソッドを通して指定されます。
この構成は、大抵の場合タスク名のプロパティ下にあり、任意のデータを含むことが可能です。
プロパティが必要とするタスクと衝突しない限り、それらは無視されます。
また、これはJavaScriptでもあるため、JSONに縛られることはありません。 ここにJavaScriptを書くことも可能です。 必要であれば、プログラム処理によって構成情報を生成しても構いません。
grunt.initConfig({
concat: {
// 連結(concat)タスクの構成をここに書きます。
},
uglify: {
// 圧縮・難読化(uglify)タスクの構成をここに書きます。
},
// タスクではない任意の特定のプロパティです。
my_property: 'whatever',
my_src_files: ['foo/*.js', 'bar/*.js'],
});
タスクの構成とターゲット
タスクを実行した際に、Gruntはその構成下で同じ名前のプロパティを探します。
複数のタスクで複数の構成を持つことが可能で、ターゲットに対して任意の名前を定義することが可能です。
下記の例では、連結タスクはfoo
とbar
のターゲットを持ち、
圧縮・難読化タスクはbar
のターゲットのみを持っています。
grunt.initConfig({
concat: {
foo: {
/* 連結(concat)タスク "foo"ターゲットの
オプションとファイルをここに書きます。 */
},
bar: {
/* 連結(concat)タスク "bar"ターゲットの
オプションとファイルをここに書きます。 */
},
},
uglify: {
bar: {
/* 圧縮・難読化(uglify)タスク "bar"ターゲットの
オプションとファイルをここに書きます。 */
},
},
});
タスクとターゲットの両方をgrunt concat:foo
またはgrunt concat:bar
のように指定すると、その特定されたターゲットの処理のみ実行し、
grunt concat
とすれば、実行される度に全てのターゲットに対しての処理を、それぞれ繰り返し行います。
もし、grunt.renameTask
によって、タスクの名前が変更されていれば、
Gruntは構成オブジェクトから、新しいタスク名を探すことに注意してください。
オプション
タスク構成内において、options
プロパティを指定することで
予め組み込まれているデフォルトの設定を上書きすることが可能です。
加えて、各ターゲットはターゲット固有のoptions
プロパティを持つことが出来ます。
ターゲット層のoptions
は、タスク層のを上書きします。
options
オブジェクトは、任意で設定するものなので、
必要なければ省略することも出来ます。
grunt.initConfig({
concat: {
options: {
/* タスク層のオプションをここに書きます。
タスクのデフォルトのものを上書きします。*/
},
foo: {
options: {
/* "foo"ターゲットのオプションをここに書きます。
タスク層のオプションを上書きします。*/
},
},
bar: {
/* オプションの指定はありません。
このターゲットでは、タスク層のオプションが使用されます。*/
},
},
});
ファイル
ほとんどのタスクにおいてファイル操作が必要となるため、Gruntはファイルを定義するための便利な機能を持っており、 src-destファイルマッピングを定義する際に冗長性を回避することが可能になります。 多くのタスクは下記の形式を判別可能なため、好みに合わせてこれらの形式を選択することが可能です。
全てのファイル形式はsrc
とdest
をサポートしますが、
"Compact"と"Files Array"形式は、少しの追加プロパティしかサポートしません。
コンパクト形式
この形式は、src-dest(遷移元-宛先)のファイルマッピングをそれぞれに対して可能にします。
grunt-contrib-jshint
のような、src
は必要だがdest
は不要である読み込み専用のタスクで最も一般的に使用されます。
この形式は、src-destファイルマッピングそれぞれの追加オプションもサポートします。
grunt.initConfig({
jshint: {
foo: {
src: ['src/aa.js', 'src/aaa.js']
},
},
concat: {
bar: {
src: ['src/bb.js', 'src/bbb.js'],
dest: 'dest/b.js',
},
},
});
ファイルオブジェクト形式
この形式はプロパティ名が宛先ファイルで、値がその遷移元ファイル(複数)である 複数のsrc-destマッピングを各対象に対してサポートします。
いくつかのsrc-destファイルマッピングは、この方法によって指定出来ますが、 追加プロパティはマッピング毎に指定出来ないかもしれません。
grunt.initConfig({
concat: {
foo: {
files: {
'dest/a.js': ['src/aa.js', 'src/aaa.js'],
'dest/a1.js': ['src/aa1.js', 'src/aaa1.js'],
},
},
bar: {
files: {
'dest/b.js': ['src/bb.js', 'src/bbb.js'],
'dest/b1.js': ['src/bb1.js', 'src/bbb1.js'],
},
},
},
});
ファイル配列形式
この形式は、マッピング毎の追加オプションを可能にしながら 複数のsrc-destファイルマッピングをそれぞれの対象に対してサポートします。
grunt.initConfig({
concat: {
foo: {
files: [
{src: ['src/aa.js', 'src/aaa.js'], dest: 'dest/a.js'},
{src: ['src/aa1.js', 'src/aaa1.js'], dest: 'dest/a1.js'},
],
},
bar: {
files: [
{src: ['src/bb.js', 'src/bbb.js'], dest: 'dest/b/', nonull: true},
{src: ['src/bb1.js', 'src/bbb1.js'], dest: 'dest/b1/', filter: 'isFile'},
],
},
},
});
古い形式
このファイル形式はマルチタスクと、遷移先ファイルパスが正確なターゲット名でそのターゲットが存在するようになる前の名残です。
残念ながら、ターゲット名がファイルパス、grunt task:target
での実行は使いづらいものです。
ターゲットレベルのオプション、またはは追加プロパティをそれぞれのsrc-destファイルマッピングに指定することも出来ません。
この形式を非推奨にすることを検討しており、出来るだけこの形式は避けるようにしてください。
grunt.initConfig({
concat: {
'dest/a.js': ['src/aa.js', 'src/aaa.js'],
'dest/b.js': ['src/bb.js', 'src/bbb.js'],
},
});
カスタムフィルター関数
filter
プロパティはターゲットにするファイルにおいて、詳細な指定をしたい際に助けになってくれます。
fs.Stats
のメソッド名を単純に指定して使用することが可能です。
下記の例は、パターンにマッチするファイルが存在する場合のみ、cleanを行います。
grunt.initConfig({
clean: {
foo: {
src: ['tmp/**/*'],
filter: 'isFile',
},
},
});
自分でファイルがマッチするか否かをtrue,falseで返すフィルター関数を作成することも可能です。 例えば、下記の例ではフォルダが空の場合のみ、cleanを行います。
grunt.initConfig({
clean: {
foo: {
src: ['tmp/**/*'],
filter: function(filepath) {
return (grunt.file.isDir(filepath) && require('fs').readdirSync(filepath).length === 0);
},
},
},
});
globパターン
個別に全てのファイルに対して、srcファイルパスを指定するのは非効率です。 そこでGruntは、(globbingとして知られている) 組み込みの node-glob と andminimatch のライブラリを通してファイル名の指定を拡張する機能をサポートしています。
これはglobパターンに関する包括的なチュートリアルではありませんが、 下記に記号についての説明を載せておきます。
ご存知のように、foo/*.js
は、foo/
サブディレクトリ内の.js
で終わる
全てのファイルにマッチします。
しかし、foo/**/*.js
は、foo/
とその下層の全サブディレクトリ内の
全ての.js
で終わるファイルにマッチします。
globパターンは複雑ですが、対象としていくファイルの順序はシンプルです。
パターンにマッチした対象は順番に処理され、!
接頭辞にマッチしたものは、結果セットから除かれます。
そのため、常に一意な結果セットになります。
下記の例を参照してください。
// 単一のファイルを指定:
{src: 'foo/this.js', dest: ...}
// 配列で複数ファイルを指定:
{src: ['foo/this.js', 'foo/that.js', 'foo/the-other.js'], dest: ...}
// globパターンを使って指定:
{src: 'foo/th*.js', dest: ...}
// これは、シングルnode-globパターン:
{src: 'foo/{a,b}*.js', dest: ...}
// 上記はこのようにも書き換えられる:
{src: ['foo/a*.js', 'foo/b*.js'], dest: ...}
// 全てのfoo/フォルダ内の.jsファイルをアルファベット順に:
{src: ['foo/*.js'], dest: ...}
// bar.jsファイルが最初に対象となり、その後他のファイルをアルファベット順に:
{src: ['foo/bar.js', 'foo/*.js'], dest: ...}
// bar.jsを除いた、foo/配下の全ファイルをアルファベット順に:
{src: ['foo/*.js', '!foo/bar.js'], dest: ...}
// 全てのファイルをアルファベット順に、ただし、bar.jsだけは最後に:
{src: ['foo/*.js', '!foo/bar.js', 'foo/bar.js'], dest: ...}
// テンプレートはファイルパスやglobパターン内で使用可能:
{src: ['src/<%= basename %>.js'], dest: 'build/<%= basename %>.min.js'}
// また、他の場所の設定で定義されているファイルの一覧を参照することも可能:
{src: ['foo/*.js', '<%= jshint.all.src %>'], dest: ...}
globパターン記法について、更に詳しくしりたい場合は、 node-glob と minimatch のドキュメントを参照してください。
ファイルの動的ビルド
多くのファイルを個別に処理したい場合、いくつかの追加プロパティで動的にファイルリストをビルドすることが出来ます。 これらのプロパティは"コンパクト"または"ファイル配列"マッピングフォーマットの両方で指定されます。
下記の例では、minify
タスクは、src-destファイルマッピングの対象として、
static_mappings
とdynamic_mappings
の両方で、同じリストを参照することになります。
Gruntはdynamic_mappings
ファイルオブジェクトを、実行時に4つのファイルを見つけた際に、
個別の4つの静的なsrc-destファイルマッピングとみなすように、自動的に拡張します。
静的と動的なsrc-destファイルマッピングを組み合わせて指定することも出来ます。
grunt.initConfig({
minify: {
static_mappings: {
// このsrc-destのファイルマッピングは手動で指定されており、新しいファイルの追加や削除が発生する度に
// Gruntfileを更新する必要があります。
files: [
{src: 'lib/a.js', dest: 'build/a.min.js'},
{src: 'lib/b.js', dest: 'build/b.min.js'},
{src: 'lib/subdir/c.js', dest: 'build/subdir/c.min.js'},
{src: 'lib/subdir/d.js', dest: 'build/subdir/d.min.js'},
],
},
dynamic_mappings: {
// Gruntは"minify"タスクが実行さされると、lib/"配下で**/*.js"を探し、
// src-destのファイルマッピングをビルドするため、ファイルが追加・削除されても
// Gruntfileを更新する必要はありません。
files: [
{
expand: true, // 動的拡張機能を有効
cwd: 'lib/', // マッチするsrcはこのパスの相対
src: ['**/*.js'], // マッチする実際のパターン
dest: 'build/', // 遷移先のパスの先頭部分
ext: '.min.js', // 遷移先のファイルパスにつける拡張子
},
],
},
},
});
テンプレート
テンプレートは、<% %>
記号を指定することによって、読み込んだ設定を自動的に展開します。
テンプレートは残りが無くなるまで再帰的に展開を行います。
設定オブジェクトは、プロパティがそっくり展開されたものが入っており、
grunt
と、そのメソッドがテンプレートの内部で利用可能です。
(例えば、<%= grunt.template.today('yyyy-mm-dd') %>
)
下記のサンプルのconcat
タスクは、
concat:sample
が実行されると、
バナーである/* abcde */
と一緒に、
foo/*.js
+ bar/*.js
+ baz/*.js
にマッチする全てのファイルを繋ぎあわせて、
build/abcde.js
を生成します。
grunt.initConfig({
concat: {
sample: {
options: {
banner: '/* <%= baz %> */\n', // '/* abcde */\n'
},
src: ['<%= qux %>', 'baz/*.js'], // [['foo/*.js', 'bar/*.js'], 'baz/*.js']
dest: 'build/<%= baz %>.js', // 'build/abcde.js'
},
},
// 任意のプロパティがタスクの設定テンプレート内で使用可能。
foo: 'c',
bar: 'b<%= foo %>d', // 'bcd'
baz: 'a<%= bar %>e', // 'abcde'
qux: ['foo/*.js', 'bar/*.js'],
});
外部データのインポート
下記のGruntfile内では、package.json
ファイルから、
プロジェクトのメタデータがGruntの設定としてインポートされ、
grunt-contrib-uglifyプラグイン
のuglify
タスクは、srcファイルを圧縮し、バナーコメントをメタデータを使用して動的に生成するように設定されます。
Gruntは、JSONとYAMLデータをインポートするために、
grunt.file.readJSON
とgrunt.file.readJSON
メソッドを
保持しています。
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
options: {
banner: '/*! <%= pkg.name %>d <%= grunt.template.today("yyyy-mm-dd") %>d */
'
},
dist: {
src: 'src/<%= pkg.name %>.js',
dest: 'dist/<%= pkg.name %>.min.js'
}
}
});
© 2010 - 2017 STUDIO KINGDOM