Grunt入門

# GRUNT入門

## なぜなにGrunt

### Gruntとは

* 自動化ツールです

### Gruntのメリット

* htmlバリデートして、scssビルドして、jslintで監視しながらjs書いて、js結合して、jsミニファイして…などを毎回手動でやらなくてよくなります
* ```peter$ grunt build``` で全部gruntちゃんがやってくれます

## 事前準備

### node.js

* version >= 0.8.0 (grunt 0.4.x+)
* node.js バージョン管理ツール
	* Windows
		* nvmw
	* Mac
		* nodebrew 

### Grunt

* version >= 0.4.x

```
peter$ npm install -g grunt-cli
```

## Grunt

### 新規プロジェクトにGruntを導入する

#### 必要なファイル
##### package.json
* npmのメタデータの設定ファイル
* これから必要なモジュールを自動で設定できたりする（要grunt-init）

##### Gruntfile.js
* 自動化したいコマンド群の設定ファイル

#### 導入手順

##### package.jsonをつくる

1. プロジェクトフォルダのルートに移動
1. ターミナル ``` npm init ```
1. ターミナル上で対話式にpackage.jsonを設定する

```
{
  "name": "sample",
  "version": "0.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": "",
  "author": "",
  "license": "BSD"
}
```

上記のようなpackage.jsonが出力される

```
{
  "name": "sample",
  "version": "0.0.0"
}
```

でもとくに必要ないので消しました

##### gruntモジュールを追加

```
npm install grunt --save-dev
```
* このコマンドは先ほどのnpm installと違い-g（グローバル）オプションがありません
* ですので、このモジュールはカレントフォルダにnode_modulesというフォルダが作られ、そこにインストールされます。
* また--save-devオプションはモジュール追加と同時にpackage.jsonにモジュール名を追加してくれる便利なオプションです

```
{
  "name": "sample",
  "version": "0.0.0",
  "devDependencies": {
    "grunt": "~0.4.1"
  }
}

```
コマンド実行後のpackage.json
もし--save-devオプションを使ってもモジュール名が追加されない場合は
package.jsonのパーミッションが悪さをしてる場合があります

##### Gruntfile.jsをつくる

まずgruntモジュールを作成します

```
module.exports = function (grunt) {
…
}
```

読み込むモジュールは
```npm install grunt-contrib-requirejs --save-dev```
で取得したものです

```
grunt.loadNpmTasks('grunt-contrib-compass');
grunt.loadNpmTasks('grunt-contrib-requirejs');
```

initConfigで各タスクを設定します

```
grunt.initConfig({
	pkg:grunt.file.readJSON('package.json'),
	//compassでscssをビルド
	compass: {
      dist: {
        options: {
          sassDir:'src/scss',
          cssDir:'src/css'
        }
      }
    },
	//requirejsを使ってjsを出力する
	requirejs: {
      compile: {
        options: {
          baseUrl: "src/js/",
          name:"app",
          mainConfigFile: "src/js/app.js",
          out: "dist/js/app.js"
        }
      }
    }
});
```

タスクを登録します

* defaultの場合は``` peter$ grunt ```で実行できます
* タスク名がhogeの場合は``` peter$ grunt hoge ```で実行します

```
grunt.registerTask('default', ['compass','requirejs']);
```

##### 完成

上記をまとめるとこんな感じになります。

```
module.exports = function (grunt) {

  grunt.loadNpmTasks('grunt-contrib-compass');
  grunt.loadNpmTasks('grunt-contrib-requirejs');
	
  grunt.initConfig({

    pkg:grunt.file.readJSON('package.json'),        
	
	compass: {
      dist: {
        options: {
          sassDir:'src/scss',
          cssDir:'src/css'
        }
      }
    },
    requirejs: {
      compile: {
        options: {
          baseUrl: "src/js/",
          name:"app",
          mainConfigFile: "src/js/app.js",
          out: "dist/js/app.js"
        }
      }
    }
  });

  grunt.registerTask('default', ['compass','requirejs']);
};
```

これが実行されると

1. src/scssにあるscssをcomapssがビルドしてsrc/cssに出力されます
2. 次にプロジェクトフォルダのsrc/js/app.jsに記載してある設定に基づき、jsファイルが結合されてdist/js/app.jsに出力されます


### 既存プロジェクトへ導入
したい方は[こちらへ](http://gruntjs.com/getting-started#working-with-an-existing-grunt-project)

### まとめ

今回紹介したのはcompassとrequirejsだけですが、
gruntのモジュールはgithubを探せばたくさんありますので、
自動化できるところは自動化して作業効率化していきましょう。

### おまけ

* grunt
  * 今回紹介したやつ
* [bower](http://bower.io/)
  * jqueryなどのパッケージマネジャー
* [yeoman](http://yeoman.io/)
  * プロジェクトテンプレートジェネレーター

をつかうとさらに便利らしい