[Grunt & Yeoman] Gruntfile をもう少し探る

Gruntfile の中身について確認してみる。

前回の続きです。

公式にのっていた Gruntfile.js を確認してみます。

Gruntfile.js
module.exports = function(grunt) {
  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    uglify: {
      options: {
        banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
      },
      build: {
        src: 'src/sample.js',
        dest: 'build/<%= pkg.name %>.min.js'
      }
    }
  });
  // Load the plugin that provides the "uglify" task.
  grunt.loadNpmTasks('grunt-contrib-uglify');
  // Default task(s).
  grunt.registerTask('default', ['uglify']);
};

Contents

ファイル

uglify を実行すると、src: /src の入力を、dest: /build へ出力するようです。
このディレクトリについては、Grunt Project で推奨されるファイル構成に関する情報は見つけられませんでした。
以下のような命名が多く見られたのですが、

src
  dist (distribution)
  build
dest (destination)
test

/src にソースファイルを置いて、concat や compile を /dist や /build に一時ファイルを置きながら作成して、/dest に納品ファイルを置くような運用イメージでしょうかね?
うーんわからん。

追記(2013/11/11) こんな感じにしようかと思います。

  • docs ドキュメント
  • src コンパイル前のソース。この中をさわる。
  • dist 納品ファイル。デプロイ用。
  • test テスト。

.gitignore

ということはこんな形になるでしょうか。

node_modules/
build/
dist/

ファイル操作の記法

下記の3つがあるそうです。

  • Compact Format
  • Files Object Format
  • Files Array Format

上記の例は、Compact Format になりますね。

テンプレート

<% %> はテンプレートで、実行時に展開されるとのこと。
<%= pkg.name %> は、package.jason の name を引っ張ってくるようで、結果、build/gruntSample.min.js といったファイルが生成されることになります。
src/sample.js を作成して、grunt を実行してみます。

src/sample.js
function hoge() {
    var hoge = " hoge  fuga";
    console.log(hoge);
}
% grunt
Running "uglify:build" (uglify) task
File "build/gruntSample.min.js" created.
Done, without errors.

オプション

uglify に banner オプションを付けて実行されています。

build/gruntSample.min.js
/*! gruntSample 2013-11-08 */
function hoge(){var a=" hoge  fuga";console.log(a)}

コメントが追加されています。

Gruntfile.coffee

ディレクトリを整理したり、初期設定を加えつつ、.coffee に書き直してみる。

Gruntfile.coffee
module.exports = (grunt) ->
  'use strict'
  # package.json の読み込み
  pkg = grunt.file.readJSON 'package.json'
  # グラントタスクの設定
  grunt.initConfig
    # config
    dir:
      src: 'src'
      dest: 'dest'
    pkg:
      name: 'gruntSample'
    # uglifyの設定
    uglify:
      options:
        banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
      build:
        files: [
          src: '<%= dir.src %>/sample.js',
          dest: '<%= dir.dest %>/<%= pkg.name %>.min.js'
        ]
  # プラグインの読み込み
  # grunt.loadNpmTasks 'grunt-contrib-watch'
  for taskName of pkg.devDependencies when taskName.substring(0, 6) is 'grunt-'
    grunt.loadNpmTasks taskName
  # タスクコマンドの設定
  grunt.registerTask 'default', ['uglify']

package.json から、pkg.name を取り出す表現が分からなかった。

以下の追記(2013/11/11)で解決しました。

matchdep でコンポーネントをロードする

package.json の読み込みとコンポーネントのロードを、matchdep で行ったところ、スッキリまとめることができました。

% npm install matchdep --save-dev
Gruntfile.coffee
'use strict'
module.exports = (grunt) ->
  # matchdep を利用してプラグインを読み込む
  require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks)
  # グラントタスクの設定
  grunt.initConfig
    # config
    dir:
      src: 'src'
      dest: 'dest'
    pkg: grunt.file.readJSON "package.json"
    banner: '/*! <%= pkg.name %> <%= pkg.version %>\n'+
            '<%= grunt.template.today("yyyy-mm-dd HH:MM:ss Z") %> */\n'
    # uglifyの設定
    uglify:
      options:
        banner: '<%= banner %>'
      build:
        files: [
          src: '<%= dir.src %>/sample.js',
          dest: '<%= dir.dest %>/<%= pkg.name %>.min.js'
        ]
  # タスクコマンドの設定
  grunt.registerTask 'default', ['uglify']

補遺

こんな書き方もできました。

package.json
"path": {
  "src": "./src",
  "dist": "./dist"
},
Gruntfile.coffee
files: ['<%= pkg.path.src %>/**/*.html']