【Grunt】複数のCSS, JavaScriptファイルをminfyする

Gruntメモ。

複数のCSS、JavaScriptのファイルをGruntを使って一気にそれぞれ1ファイルにminfyします。
手順は大きく、
① Gruntfileを書く
② package.jsonを書く
③ 必要なパッケージをインストール
④ htmlのCSS、JavaScript指定箇所にbuildコメントを追加
⑤ gruntタスク実行

最終的なフォルダ構成は次のようになります。srcフォルダには作業対象ファイル群を入れておきます。処理後のファイル群はdistフォルダ内に作成されますが、フォルダごと自動で生成されるので、予め準備する必要はありません。node_moduleにはgruntのパッケージ類が入りますが、こちらも手順③で自動的に生成されます。
![スクリーンショット 2014-08-14 12.35.36.png](https://qiita-image-store.s3.amazonaws.com/0/48393/9edcea56-c7e6-9f83-29ab-208e22f4634d.png)


# ① Gruntfileを書く
Gruntfileの例です。

```coffeescript:Gruntfile.coffee
module.exports = (grunt) ->
    require('load-grunt-tasks')(grunt)

    grunt.initConfig
        pkg : grunt.file.readJSON 'package.json'

        path :
            app  : 'src'
            dist : 'dist'
            tmp  : '.tmp'

        clean :
            dist :
                options :
                    force : true
                files : [{
                    dot : true
                    src : [
                        '<%= path.tmp %>'
                        '<%= path.dist %>'
                    ]
                }]

        useminPrepare :
            options :
                dest : '<%= path.dist %>'
                html : [ '<%= path.app %>/*.html' ]

        usemin :
            options :
                assetesDirs : '<%= path.dist %>'
            html : [ '<%= path.dist %>/*.html' ]

        copy :
            dist :
                files : [{
                    expand : true
                    dot    : true
                    cwd    : '<%= path.app %>'
                    dest   : '<%= path.dist %>'
                    src    : [
                        '*.html'
                    ]
                }, {
                    expand : true
                    dot    : true
                    cwd    : '<%= path.app %>'
                    dest   : '<%= path.tmp %>'
                    src    : [
                        'js/**/*.js'
                        'css/**/*.css'
                    ]
                }]
            dev :
                files : [{
                    expand : true
                    dot    : true
                    cwd    : '<%= path.app %>'
                    dest   : '<%= path.dist %>'
                    src    : [
                        '*.html'
                        '*.json'
                        'js/**/*.js'
                        'css/**/*.css'
                    ]
                }]

        grunt.registerTask 'default', [
            'clean'
            'copy:dev'
        ]

        grunt.registerTask 'build', [
            'clean'
            'copy:dist'
            'useminPrepare'
            'concat'
            'uglify'
            'cssmin'
            'usemin'
        ]

```

pathに指定してあるディレクトリは、src:入力ファイルのディレクトリ、dist:出力ファイルのディレクトリ、.tmp:作業ディレクトリです。minfyするファイル群は一度.tmpにコピーしてから作業されます。デバッグ中はminfyされてしまうと面倒なので、grunt.registerTask 'default'では入力ファイルをそのままdistにコピーするだけのタスクとしています。minfyを実行するときはgrunt.registerTask 'build'のタスクを実行します。どちらのタスクも、最初にcleanを実行して出力・作業ディレクトリの中身を削除しています。
minfy処理の動作としては、
　　1. cleanで出力・作業ディレクトリの内容を削除
　　2. minfyの必要ないファイル群を出力ディレクトリにコピー
　　3. 指定したファイル(CSS or JavaScript)を結合
　　4. minfy実行
といった具合です。

# ② package.jsonを書く
（例）

```json:package.json
{
  "name": "grunt sample",
  "version": "1.0.0",
  "private": true,
  "devDependencies": {
    
  }
}

```
"devDependencies"の中に必要なパッケージ群を書いていきますが、次の手順で自動的に追記される（便利！）のでここまでで大丈夫です。

# ③ 必要なパッケージをインストール
Gruntfile内で指定したタスクに必要なパッケージ群をnpmを使ってインストールします。--save-devオプションでカレントディレクトリ内に"node_module"ディレクトリを作成してその中にパッケージをインストールできます。コマンドラインから、Grundfileを置いてあるディレクトリ内で次のコマンドを入力します。

```
$npm install --save-dev grunt
$npm install --save-dev grunt-contrib-clean
$npm install --save-dev grunt-contrib-concat
$npm install --save-dev grunt-contrib-copy
$npm install --save-dev grunt-contrib-csmin
$npm install --save-dev grunt-contrib-uglify
$npm install --save-dev grunt-contrib-usemin
$npm install --save-dev load-grunt-tasks
```

すると、自動でpackage.jsonの中にも上記パッケージ類の記述が追記されています。

# ④ htmlのCSS、JavaScript指定箇所にbuildコメントを追加
srcの中にあるhtmlのCSS、JavaScriptを読み込む部分に次のようにコメントを追加します。こうすると、コメントで囲んだ部分の複数のcss,jsファイルを指定した1ファイルに結合・minfyしてくれます。
書き方は、

```html:samplecode.html
<!-- build:[ファイルタイプ css or js](.tmp) [出力ファイル名] -->
css or js files...
<!-- endbuild -->
```

```html:index.html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">

        <!-- build:css(.tmp) css/main.css -->
        <link href="css/style1.css" rel="stylesheet">
        <link href="css/style2.css" rel="stylesheet">
        <!-- endbuild -->
    </head>
    <body>
        <h2>Hello, world!</h2>

        <!-- build:js(.tmp) js/main.js -->
        <script src="js/script1.js"></script>
        <script src="js/script2.js"></script>
        <!-- endbuild -->
    </body>
</html>
```

# ⑤ gruntタスク実行
ここまでできれば、あとはコマンドラインから、

```
$grunt build
```

で、src内のファイルのcss,jsフォルダ内のcss,jsファイルがminfyされてdistディレクトリに出力されます。