anti scroll

ブラウザと小説の新しい関係を模索する

Gruntの覚え書き

 最近知った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-jshintgrunt-contrib-concatgrunt-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 が使えそうだけど、コピー対象のファイルを、親ディレクトリを含めてコピーしちゃうのと、それを回避するやり方がよくわからなかったので保留中。