最近知ったjs task runnerのGruntですが、なるほど便利。
今までは拙作テンプレートエンジン(jingoo)でスクリプトの断片をrawincludeするテンプレートを作って結合していたのですけど、今後はGruntで統一しようと思いました。
Gruntfile.jsでお仕事を定義した後は、こんな感じでMakefileがシンプルに!
all:normal min jshint: grunt jshint:normal normal: grunt concat:normal min: grunt uglify:normal grunt concat:min
ここから覚書です。
- node.jsのインストールとnpmのインストール、gruntのインストールは省略。
- ホームディレクトリ(後述するが要注意)で、
npm install grunt-contrib-(plugin名) --save-dev
として公式のpluginを入れる。
とりあえず、grunt-contrib-jshint、grunt-contrib-concat、grunt-contrib-uglify あたりがマスト。
・プロジェクトディレクトリをつくり、npm initして、package.jsonを作る。
・プロジェクトディレクトリに、先ほどインストールしたgruntプラグインのディレクトリ(~/node_modules)へのシンボリックリンクを作成。こうすると他のプロジェクトでも同じプラグインが使え、何度もディレクトリごとにインストールする必要がなくなる。
でもこうやって一つの場所にインストールして、グローバルに参照するやり方は、公式では非推奨とされている。それぞれのプロジェクトごとに要求するプラグインのバージョンが異なるかもしれないから、ということ。
でも僕みたいにnode.jsでサーバサイドのコードを書くわけじゃなく、単にクライアントサイドのjsを管理したい人にはあんまり関係ないと思われる。
・Gruntfile.jsをごりごりと書く。
module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), // コードチェックするタスク // grunt jshint:normal で、src以下にあるjsをチェック。 // ただし'snipet'と含まれるものはスキップさせる。 jshint:{ normal:{ src:[ "src/*.js" ], // snipet.jsは個人的なゴミjsなのでスキップ filter:function(filepath){ return filepath.indexOf("snipet") < 0; } }, options:{ "smarttabs":true // タブ数に関するエラーについては大目に見る } }, // コードを結合するタスク // grunt concat:normal で、(pkg.name).js をbuildディレクトリに出力 // grunt concat:min で、(pkg.name).min.js をbuildディレクトリに出力 concat:{ normal:{ files:{ "build/<%= pkg.name %>.js":[ "COPYING", "src/aaa.js", "src/bbb.js" ] } }, min:{ files:{ "build/<%= pkg.name %>.min.js":[ "COPYING", "obj/<%= pkg.name %>.cjs" ] } } }, // コードをminifyするタスク // grunt uglify:normal で、objディレクトリに (pkg.name).cjs を出力させる uglify: { normal: { src: 'build/<%= pkg.name %>.js', // このファイルを dest: 'obj/<%= pkg.name %>.cjs' // このようなファイル名でminifyする。 }, options: { // minify処理をした時刻をヘッダに付け足す banner: '/*!<%= pkg.name %><%= grunt.template.today("yyyy-mm-dd") %>*/\n' } } }); // 使用するプラグインをロード。もちろん先にnpm installしてないと駄目。 grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-uglify'); // grunt とだけ押されたときに発動するコマンドを指定。 grunt.registerTask('default', ['concat']); };
後は、先に示したMakefileで、make normal とすれば、(pkg.name).js、make min とすれば(pkg.name).min.js の出来上がり。
ちなみに、デプロイに関しては grunt-contrib-copy が使えそうだけど、コピー対象のファイルを、親ディレクトリを含めてコピーしちゃうのと、それを回避するやり方がよくわからなかったので保留中。