タスクの設定

このガイドでは、プロジェクトで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はその構成下で同じ名前のプロパティを探します。 複数のタスクで複数の構成を持つことが可能で、ターゲットに対して任意の名前を定義することが可能です。 下記の例では、連結タスクはfoobarのターゲットを持ち、 圧縮・難読化タスクは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ファイルマッピングを定義する際に冗長性を回避することが可能になります。 多くのタスクは下記の形式を判別可能なため、好みに合わせてこれらの形式を選択することが可能です。

全てのファイル形式はsrcdestをサポートしますが、 "Compact"と"Files Array"形式は、少しの追加プロパティしかサポートしません。

filter
有効な fs.Statsメソッド名 、またはsrcファイルパスを引数にして、trueまたはfalseを返す関数のどちらかを指定します。
nonull
マッチするものが見つからない場合は、パターン自体を含むリストを返します。 それにも一致しない場合は、空のリストが返されます。 Gruntの--verboseフラグと組み合わせると、ファイルパスのデバッグで便利です。
dot
もし、明示的にその場所にピリオドを持っていないとしても、 ピリオドから始まるファイル名のパターンに一致させることが出来ます。
matchBase
設定されると、スラッシュ無しのパターンは、スラッシュを含むパスのベース名に対してマッチするようになります。 例えば、a?bは、/xyz/123/acbのパスにマッチしますが、/xyz/acb/123 にはマッチしません。
expand
src-destでのファイルの動的マッピング処理について、 更に詳しく知りたい場合は、"ファイルの動的ビルド"を参照してください。
その他のプロパティは、一致したオプションとして基本(?)ライブラリに渡されます。 詳しく知りたい場合は、 node-globminimatch のドキュメントを参照してください。

コンパクト形式

この形式は、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-globandminimatch のライブラリを通してファイル名の指定を拡張する機能をサポートしています。

これはglobパターンに関する包括的なチュートリアルではありませんが、 下記に記号についての説明を載せておきます。

*
任意の数の文字列にマッチしますが、/にはマッチしません。
?
任意の1文字にマッチしますが、/にはマッチしません。
**
/(パスの一部とされている)を含む、任意の数の文字列にマッチします。
{}
カンマ区切りを「or」条件として、リストで指定することが可能になります。
!
指定したパターンで開始しない文字列にマッチします。

ご存知のように、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-globminimatch のドキュメントを参照してください。

ファイルの動的ビルド

多くのファイルを個別に処理したい場合、いくつかの追加プロパティで動的にファイルリストをビルドすることが出来ます。 これらのプロパティは"コンパクト"または"ファイル配列"マッピングフォーマットの両方で指定されます。

expand
trueがセットされると、それに続くオプションが有効になります。
cwd
全てのマッチするsrcは、このパス(ただし、含まれない(?))の相対になります。
src
cwdの相対で、マッチするパターンです。
dest
遷移先ファイルパスの先頭部分です。
ext
生成されたdestパスでこの値を持つ既存の拡張機能を置き換えます。
flatten
生成されたdestパスから全てのパスの部分を削除します。
rename
この関数はsrcファイルにマッチする度(renamingとflattening拡張機能の後)に呼び出されます。 この関数はdestと、マッチしたsrcパスを引数として受け取り、 新しいdestの値を返さなければいけません。 もし、同じdestが複数回返される場合、各srcは、元ファイル用の配列に追加されます。(翻訳に自信無し)

下記の例では、minifyタスクは、src-destファイルマッピングの対象として、 static_mappingsdynamic_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') %>)

<%= prop.subprop %>
設定内のprop.subpropを、値の型に関係なく展開します。 文字列だけで無く、配列やその他のオブジェクトも参照します。
<% %>
任意のインラインJavaScriptコードを実行します。これは、制御フローやループで使用すると便利です。

下記のサンプルの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.readJSONgrunt.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'
    }
  }
});

 Back to top

© 2010 - 2017 STUDIO KINGDOM