本来だったら、プロジェクトの依存ファイルをnpmで管理するという性質上、ひとつのpackage.jsonに対してひとつのGruntfileが対応している状態がベストだと思うけど、何らかの事情で、、、とくにWebサイト運用のような何らかの事情が起きがちな状況で、やむを得ず複数のGruntfileを使用するときの設定メモ。
例として以下のようなディレクトリ構成を想定
.
├── Gruntfile.js
├── build
│ └── main.js
├── js
│ ├── bar.js
│ ├── foo.js
│ └── hoge.js
├── node_modules
│ ├── grunt
│ └── grunt-contrib-concat
├── package.json
├── project.json
└── hoge
├── Gruntfile.js
├── js
│ ├── some-module-1.js
│ ├── some-module-2.js
│ └── some-module-3.js
└── project.json
ひとつ下の階層ではファイルを結合処理を行う。
concat : {
develop : {
src: [
'js/some-module-1.js',
'js/some-module-2.js',
'js/some-module-3.js'
],
dest : 'build/main.js'
}
}
ディレクトリ検索は行われない
grunt.loadNpmTasksはrequire関数で読み込むときに行われるような上位ディレクトリのnode_modulesディレクトリの検索が行われないので、普通にGruntfileを別階層に置いた場合、モジュールが見つからなくてエラーになる。
>> Local Npm module "grunt-contrib-concat" not found. Is it installed?
grunt.file.setBaseを使う
grunt.file.setBaseを使うとベースとなるディレクトリが指定できる。これをpackage.jsonのあるディレクトリ(node_modulesがインストールされているディレクトリ)に指定する。
grunt.file.setBase('../');
ベース・ディレクトリがひとつ上の階層に設定されたのでモジュールが見つかりエラーが解消される。
ただし、上記のconcatの設定だと上位ディレクトリのjsディレクトリ内のJSファイルを探しにいくので、見つからずに空のファイルが出力されてしまう。
絶対パスで指定する
concatに指定するjsのファイルのパスを、上位ディレクトリからの相対パスで記述することで解消することもできるが、わかりずらいので、絶対パスで指定することでちゃんと見つかるように変更する。
var path = require('path');
var current = path.resolve('.');
module.exports = function(grunt) {
var Config = grunt.file.readJSON(current + '/project.json');
grunt.initConfig({
concat : {
develop : {
src: [
current + '/js/some-module-1.js',
current + '/js/some-module-2.js',
current + '/js/some-module-3.js'
],
dest : current + '/build/main.js'
},
}
});
grunt.file.setBase('../');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.registerTask("default",["concat"]);
};
ソースの可読性はよくないけど、正常に動作する。
package.jsonが使えないので、それぞれのGruntfileに紐ずく何らかの情報をもたす場合は別のファイルに記述する。上記の例でいうと、project.jsonというものを用意してそこに情報を置いている。
ベースディレクトリへのパス情報を外部化する場合。
{
"base" : "../"
}
grunt.file.setBase(Config.base);
若干、気持ち悪いけど、やむを得ず。
実際は
gruntのバージョンがv0.4にあがったタイミングで、grunt自身もプロジェクト単位でパッケージ管理されるようになったことから、node_modulesを使い回すような微妙なことはあえて使用できないように変更されたのかと思うので、できるだけ使い回しはやめた方がいいかと思う。
ほんとにやむを得ずな時だけにする。
おしまい。