【温故知新】2018年だけどGruntでscssコンパイル + minifyを初めから丁寧に

## はじめに
長く運用されてるサイトなど、案件によってはGruntを触る事があるでしょう　あるんですよ
せっかくの機会なのでまとめておきます
新人さんがアサインされた時に資料として活用します
  
## 手順
1.macにnode.jsを入れる
2.macにsassを入れる
3.プロジェクトディレクトリに必要なパッケージを入れる
4.Grunt用の設定を記入する
5.!!SUCCESS!!
  
#### 1.macにnode.jsを入れる
公式サイトから落としてきてインストール
https://nodejs.org/ja/  

nodebrew使ってバージョンまで管理したい方はこの記事が参考になります
https://qiita.com/kyosuke5_20/items/c5f68fc9d89b84c0df09
  
#### 2.macにsassを入れる
以下のコマンドをターミナルで実行するのですが…  
  
```
$ sudo gem install sass
```
  
ですが！2018年現在こんなエラーが出るはずです  
  
```
ERROR:  While executing gem ... (Errno::EPERM)
    Operation not permitted - /usr/bin/sass
```
  
mac OSのアップデートに伴い /usr/bin/ へのアクセス権が変更されたためインストールできないというエラーです（出るのが正常！）
そこでパスを変更してインストールします  

```
$ sudo gem install -n /usr/local/bin sass
```
これでOKです 次へ進みましょう  
  
#### 3.プロジェクトディレクトリに必要なパッケージを入れる
ターミナルでGruntを使いたいディレクトリに移動します
今回はユーザー直下にします  
  
```
$ cd ~ // User/(ユーザー名) ディレクトリへ移動
$ mkdir grunt2018 // User/(ユーザー名)/grunt2018を作成
$ cd grunt2018　// 作成したディレクトリへ移動
```
  
これでプロジェクトディレクトリができました
今回の構成です  

```
grunt2018/ 
  ├src/
  │ └_scss/
  │   └style.scss
  ├dist/
  │ └css/
  │   ├style.css
  │   └style.min.css
  ├Gruntfiles.js
  └package.json
```

まずは初期化をします
ターミナルで以下のコマンドを叩いてください  

```
$ npm init
```

続けて今回使うパッケージをインストールします    
```npm install```でインストールを行います
```--save-dev```オプションでpackage.jsonにプラグインの情報を書きつつ、開発環境用としてパッケージを登録します  

```
$ npm install --save-dev grunt grunt-cli grunt-contrib-cssmin grunt-contrib-sass grunt-contrib-watch
```  

* grunt                 : 本体
* grunt-cli             : ターミナルからgruntを使えるようにする
* grunt-contrib-cssmin  : cssのminifyをする
* grunt-contrib-sass    : sassを扱う
* grunt-contrib-watch   : Gruntにファイル変更を監視させる

package.jsonが下記のようになればOKです

``` package.json
{
  "devDependencies": {
    "grunt": "^1.0.3",
    "grunt-cli": "^1.3.1",
    "grunt-contrib-cssmin": "^3.0.0",
    "grunt-contrib-sass": "^1.0.0",
    "grunt-contrib-watch": "^1.1.0"
  }
}
```
  
#### 4.Gruntの設定ファイルを記入する 
プロジェクトディレクトリに Gruntfile.js を作成し書いて行きます

``` Gruntfile.js
module.exports = function(grunt){
  grunt.initConfig({
  })
}
```

まずはcss minifyの設定から書いて行きましょう  
cssminというオブジェクトを追加、中にcompress、filesと書いて行きます  
filesの左側が最小化後のcssファイルパス、右が最小化前のパスです

``` Gruntfile.js
module.exports = function(grunt){
  grunt.initConfig({

    // css minifyの設定
    cssmin: {
      compress: {
        files: {
          'dist/css/style.min.css': ['dist/css/style.css']
        }
      }
    }
  })
}
```
  
これでcssminの設定ができました
dist/css/style.css を元に同じディレクトリへ style.min.css という最小化されたファイルを生成します  
  
次にscssのコンパイル設定を記述します  
sassオブジェクトを追加、中にdist、filesと記述します  
cssmin同様、左側が最小化後のcssファイルパス、右が最小化前のパスです  

``` Gruntfile.js
module.exports = function(grunt){
  grunt.initConfig({
    cssmin: {
      compress: {
        files: {
          'dist/css/style.min.css': ['dist/css/style.css']
        }
      }
    },

    // scssコンパイルの設定
    sass: {
      dist: {
        files: {
          'dist/css/style.css': 'src/_scss/style.scss'
        }
      }
    }
  })
}
```
  
次にファイル変更監視の設定を記述します  
scss等を変更した際に自動で変換処理を走らせるため、watchを記述します

``` Gruntfile.js
module.exports = function(grunt){
  grunt.initConfig({
    cssmin: {
      compress: {
        files: {
          'dist/css/style.min.css': ['dist/css/style.css']
        }
      }
    },
    sass: {
      dist: {
        files: {
          'dist/css/style.css': 'src/_scss/style.scss'
        }
      }
    },

    // ファイル変更監視
    watch: {
      sass: {
        files: ['src/_scss/style.scss'],
        tasks: [ 'sass' ]
      },
      cssmin: {
        files: ['dist/css/style.css'],
        tasks: [ 'cssmin' ]
      }
    }
  })
}
```

最後にGruntへプラグインの読み込みとタスクの登録をします
grunt.loadNpmTasks('プラグイン名')という形で記述してきます

``` Gruntfile.js
module.exports = function(grunt){
  grunt.initConfig({
    cssmin: {
      compress: {
        files: {
          'dist/css/style.min.css': ['dist/css/style.css']
        }
      }
    },
    sass: {
      dist: {
        files: {
          'dist/css/style.css': 'src/_scss/style.scss'
        }
      }
    },
    watch: {
      sass: {
        files: ['src/_scss/*.scss'],
        tasks: [ 'sass' ]
      },
      cssmin: {
        files: ['dist/css/*.css'],
        tasks: [ 'cssmin' ]
      }
    }
  })

  // プラグインの読み込み
  grunt.loadNpmTasks('grunt-contrib-cssmin')
  grunt.loadNpmTasks('grunt-contrib-sass')
  grunt.loadNpmTasks('grunt-contrib-watch')
}
```
  
#### !!SUCCESS!!
  
これでほとんどの設定が終わりました  
ターミナルでプロジェクトディレクトリに移動し、以下のコマンドを入力してください  
これでGruntがファイル変更の監視を始めます
  
```
$ node_modules/.bin/grunt watch
```
  
これで以下のテキストが表示されれば準備OKです  

```
Running "watch" task
Waiting...
```
  
src/_scss/style.scssを書いて保存し、ターミナルに下記のような文字列が出てdist/css/style.min.cssが生成される事を確認しましょう
※何も表示されず生成もされない場合はパスの指定違いかも？
  
```
Done.
Completed in 0.640s at Sat Sep 15 2018 16:10:15 GMT+0900 (GMT+09:00) - Waiting...
```

こんな感じでコンパイルされるはずです！

``` style.scss
html {
  font-size: 10px;
}
.container {
  &__title {
    &--bold{
      font-weight: bold
    }  
  }
}
```
  
``` style.min.css
html{font-size:10px}.container__title--bold{font-weight:700}
```
  
#### おまけ

都度都度以下のコマンドを打つのが面倒な場合はnpm scriptsにショートハンドを登録しましょう  

``` 
$ node_modules/.bin/grunt watch
```

package.jsonを開いて追記します  

```
{
  // scriptsを追加
  "scripts": {
    "watch": "node_modules/.bin/grunt watch"
  },

  "devDependencies": {
    "grunt": "^1.0.3",
    "grunt-cli": "^1.3.1",
    "grunt-contrib-cssmin": "^3.0.0",
    "grunt-contrib-sass": "^1.0.0",
    "grunt-contrib-watch": "^1.1.0"
  }
}
```  
  
これで次からは下記コマンドでファイル監視を始めることができます  

```
$ npm run watch
```


### つまづきやすいポイント
* ググっても情報が古い  
* Sierra以前のOSでの情報がほとんど
* macへのsassインストール手順が違う

### 温故知新したこと
GruntとGulpを使った事ないの少し気にしてたのがスッキリ
あとwebpackができるまでに色々あったんだなぁ、としみじみ

### 参考記事
https://www.qript.co.jp/blog/technique/1601/
https://taxaboxo.com/blog/sass-install-error-mac/