jsファイルの結合・圧縮をgruntを使って完全自動化

#はじめに
JavaScriptファイルの読み込み時間を短縮させるため、ファイルの結合や圧縮を行うという場面がある。
エディタやIDEに組み込んだ機能や、WEBで公開されているツールもあるが、今回はその結合・圧縮をgruntを使って自動化、さらにファイル状態監視によってそのスクリプトが自動実行されるように設定してゆく。

#プラグインのインストール
ここでは3つのgruntプラグインを利用する。

`grunt-contrib-concat` 複数のJavaScriptファイルの結合に使用。
`grunt-contrib-uglify` JavaScriptファイルの圧縮に使用。
`grunt-contrib-watch` ファイルの状態監視に使用。

作業ディレクトリにて、以下のコマンドを実行。

```
> npm install grunt-contrib-concat -save-dev
> npm install grunt-contrib-uglify -save-dev
> npm install grunt-contrib-watch -save-dev
```

インストールが無事済んだら次へ。
#Gruntfile.jsの編集
インストールしたプラグインを動作させるため、Gruntfile.jsを編集してゆく。
##grunt-contrib-concatの設定
`grunt-contrib-concat`は複数のファイルを任意に結合させることができる。ここでは、jsディレクトリ直下のjsファイルを、1つのファイルに結合してconcatディレクトリに出力する設定をしている。

```js:Gruntfile.js
grunt.initConfig({
    concat: {
        files: {
            // 元ファイルの指定。
            src : 'js/*.js',
            // 出力ファイルの名前・パス指定
            dest: 'js/concat/hogehoge.js'
        }
    }
});

grunt.loadNpmTasks('grunt-contrib-concat');
grunt.registerTaks('default', ['concat']);
```

##grunt-contrib-uglifyの設定
`grunt-contrib-uglify`は任意のファイルの圧縮（変数名の短縮化や未使用変数の削除などなど）を行うことができる。ここでは、concatディレクトリの`hogehoge.js`というファイルを圧縮し、minディレクトリに`hogehoge-min.js`というファイル名で出力する設定をしている。

```js:Gruntfile.js
grunt.initConfig({
    uglify: {
		dist: {
			files: {
				// 出力ファイル: 元ファイル
				'js/min/hogehoge-min.js': 'js/concat/hogehoge.js'
			}
		}
	},
});

grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.registerTask('default', ['uglify']);
```

#ファイル状態監視によるタスク実行自動化
ここまで設定で、各タスクをコマンドで叩けば実行されるようになったが、ファイル編集するたびにコマンドを叩くことを繰り返すのはあまりナウでヤングでクールではないし、なによりモテない。

ここではファイルの状態変更を監視し、変更があった場合に任意のタスクを自動実行させる`grunt-contrib-watch`の設定をしてゆく。
##grunt-contrib-watchの設定
ここでは、jsディレクトリ直下の全jsファイルを監視対象にし、変更をトリガーとしてconcat、uglifyの順番にタスクを自動実行させる。
あえて「jsディレクトリ直下」と指定しているのは、各タスクの出力先であるconcatディレクトリやminディレクトリ内のjsファイルの状態変更を監視対象から外すためである。

```js:Gruntfile.js
grunt.initConfig({
	watch: {
		js: {
			files: 'js/*.js', // 監視対象ファイル
			tasks: ['concat', 'uglify'] // 実行させるタスク
		}
	}
});

grunt.loadNpmTasks('grunt-contrib-watch');
```

`grunt watch`を叩けば`files`で指定したファイルへの監視が始まる。変更（上書き等）を検知すると、このような実行ログが表示される。

```
> grunt watch
Running "watch" task
Waiting...
>> File "js\original.js" changed.
Running "concat:files" (concat) task
File js/concat/hogehoge.js created.

Running "uglify:dist" (uglify) task
File js/min/hogehoge-min.js created: 155 B → 87 B

Done, without errors.
Completed in 0.918s at Fri Apr 25 2014 10:59:44 GMT+0900 (東京 (標準時)) - Waiting...
```

#今回のGruntfile.jsの完成形
今回のGruntfile.jsの完成形は、以下の様な形になる。

```js:Gruntfile.js
module.exports = function (grunt) {
	var pkg = grunt.file.readJSON('package.json');
	grunt.initConfig({
		concat: {
			files: {
				// 元ファイルの指定
				src : 'js/*.js',
				// 出力ファイルの指定
				dest: 'js/concat/hogehoge.js'
			}
		},

		uglify: {
			dist: {
				files: {
					// 出力ファイル: 元ファイル
					'js/min/hogehoge-min.js': 'js/concat/hogehoge.js'
				}
			}
		},

		watch: {
			js: {
				files: 'js/*.js',
				tasks: ['concat', 'uglify']
			}
		}
	});

	// プラグインのロード・デフォルトタスクの登録
	grunt.loadNpmTasks('grunt-contrib-uglify');
	grunt.loadNpmTasks('grunt-contrib-concat');
	grunt.loadNpmTasks('grunt-contrib-watch');
	grunt.registerTask('default', ['concat', 'uglify']);
};
```

これでナウでヤングでクールなタスク自動化が実現したので、モテる(☝ ՞ਊ ՞)☝

突っ込みどころ、盛大に間違っている部分等ありましたら是非ご指摘ください。