grunt.js0.4.0でJSとCompassをコンパイルする

Backbone.jsなどを使っていてjsのファイルが増えてくると、公開するときには1つのファイルにまとめたいなぁとか、コーディングスタイルのチェックもしたいなぁと思っていて、そこで何かいいのないかなと思って調べてみると、「grunt.js」がよさそうだったので今更ながら試してみました。


grunt.jsのバージョンは0.4.0です


今回は、JSに対してJSHintをやって結合して圧縮することと、Compassコンパイルをgrunt.jsにやってもらうことにしました。
(他にもテストや自分で作ったタスクを登録できたりもするのですが今回は省略)

インストール

  • https://github.com/gruntjs/grunt/wiki/Getting-started
  • ドキュメントにも書いてあるのですが、0.4.0からはgrunt-cliというクライアントだけをグローバルにインストールして、gruntはグローバルにインストールしないような構成になっています。
    • もしすでにグローバルにgruntをインストールしていた場合は「npm uninstall -g grunt」して削除しましょう。
grunt-cliのインストール
% npm install -g grunt-cli

これでgruntコマンドにパスが通って使えるようになります。

gruntとpluginたちをインストール
  • 0.4.0からはこれまでgrunt本体に入っていたファイルの結合(concat)や監視(watch)などが全部プラグイン化されているので、必要なものをインストールします。
% cat package.json
{ 
  "name": "p5-petatube", 
  "version": "0.0.1", 
  "description": "This is web application named PetaTube.", 
  "private": true, 
  "repository": { 
    "type": "git", 
    "url": "git://github.com/koba04/p5-petatube.git" 
  },  
  "author": "koba04", 
  "devDependencies": { 
    "grunt": "~0.4.0", 
    "grunt-contrib-watch": "~0.2.0", 
    "grunt-contrib-uglify": "~0.1.1", 
    "grunt-contrib-concat": "~0.1.2", 
    "grunt-contrib-jshint": "~0.1.1", 
    "grunt-contrib-compass": "~0.1.1" 
  }   
} 
% npm install

npm簡単でいいですね。

Gruntfile.jsを作る

  • 実行したいタスクなどはGruntfile.jsというファイルを作ってそこに書いていきます。
module.exports = function(grunt) {
"use strict";

  grunt.initConfig({
    // package.jsonに設定されている内容を取得
    pkg: grunt.file.readJSON("package.json"),
    // watchの設定 (grunt-contrib-watch)
    watch: {
      // jsという名前でtargetを設定
      js: {
        // 監視するファイルを指定
        files: [
          "Gruntfile.js", // このファイルも監視してjshintする
          "src/js/**/*.js"
        ],
        // 変更されたらどのタスクを実行するか
        tasks: ["js"],
        // watchのオプション
        options: {
          // 前回に実行されてから最低空ける間隔(同じファイルに対して)
          debounceDelay: 1000,
          // タスクを実行中に割り込みを許可するか
          // interrupt: false,
          // 変更を検知してからタスクを実行するまでの間隔
          // fs.watchFileがwatcherとして使われた場合しか有効でないので指定しない方がよいらしい
          //interval: 1000
        }
      },
      // CSS用の設定
      css: {
        files: [
          "src/scss/*.scss"
        ],
        tasks: ["css"],
        // オプションはjsと同じものを使用
        options: "<%= watch.js.options %>"
      },
      // JSもCSSも監視したい時の設定
      all: {
        files: [
          "<%= watch.js.files %>",
          "<%= watch.css.files %>"
        ],
        tasks: ["js", "css"],
        options: "<%= watch.js.options %>"
      }
    },
    // 結合の設定 (grunt-contrib-concat)
    concat: {
      options: {
        // 結合したファイルの頭にコメント入れておく
        banner: "/* this file is generated by concat task of grunt.js */\n"
      },
      dist: {
        // 出力元
        src: [
          "src/js/app.js",
          "src/js/model/*.js",
          "src/js/collection/*.js",
          "src/js/view/*.js"
        ],
        // 出力先( package.jsonのnameから値を取得している)
        dest: "static/js/<%= pkg.name %>.js"
      }
    },
    // uglify(minify)の設定 (grunt-contrib-uglify)
    uglify: {
      dist: {
        src: "<%= concat.dist.dest %>",
        dest: "static/js/<%= pkg.name %>.min.js"
      }
    },
    // jshintの設定 (grunt-contrib-uglify)
    jshint: {
      options: { 
        // jshintの設定ファイル
        jshintrc: ".jshintrc" 
      },
      // 対象ファイルを指定
      all: ["Gruntfile.js", "<%= concat.dist.src %>"]
    },
    // compassの設定(grunt-contrib-compass)
    compass: {
      dev: {
        options: {
          // 設定ファイル
          config: "compass_config.rb",
          // 環境
          environment: "development"
        }
      },
      prod: {
        options: {
          config: "compass_config.rb",
          environment: "production"
        }
      }
    }
  });

  // プラグインをロード
  grunt.loadNpmTasks("grunt-contrib-watch");
  grunt.loadNpmTasks("grunt-contrib-concat");
  grunt.loadNpmTasks("grunt-contrib-uglify");
  grunt.loadNpmTasks("grunt-contrib-jshint");
  grunt.loadNpmTasks("grunt-contrib-compass");

  // watchのところにあったタスクの設定
  // jsはjshintしてconcatして、ugilifyする
  grunt.registerTask("js", ["jshint", "concat", "uglify"]);
  // compassはprodのtargetを指定
  grunt.registerTask("css", ["compass:prod"]);
};

コメントあって見にくいと思うので
https://github.com/koba04/p5-petatube/blob/master/Gruntfile.js

実行

  • コマンドから実行
# jsのタスクを実行
% grunt js
# cssのタスクを実行
% grunt css

# jshintだけを実行
% grunt jshint

# targetも指定する compassのprodというtargetを実行
% grunt compass:prod

変更を監視させる

# watch:jsの設定で監視
grunt watch:js

# watch:cssの設定で監視
grunt watch:css

# watch:allの設定で監視
grunt watch:all

これでgrunt watch:allしておけば、自動でJSもJSHintやってまとめてくれるしCompassコンパイル出来るし、grunt.js便利ですね。