2018年の終わりに改めてgulpでsass(scss)をコンパイルする【決定版】

# 2018年の終わりに改めて _gulp_ 4系で _sass_ (_scss_) をコンパイルする
2018年の終わりが目前に迫った年の暮れ、改めて _gulp_ にて _sass_ をコンパイルする環境を構築してみました。


## 仕様
- _gulp_ 4系を用いる
- _scss_ を _css_ にコンパイルする
- _autoprefixer_ でベンダープレフィックスを補完する
- minify （以下 圧縮）した `.min.css` も生成する
- 圧縮していない _css_ に _sourcemaps_ を付与する


## ディレクトリ構造

```text
root/
 ├─ dist/            # コンパイルされたファイルの出力先
 │ └─ css/             # cssのディレクトリ
 │   ├─ main.css         # 出力されるsourcemaps付きのcssファイル
 │   └─ main.min.css     # 出力される圧縮された本番用cssファイル
 │
 ├─ src/             # コンパイル前のファイルの保存先
 │ └─ scss/            # scssのディレクトリ
 │   ├─ main.scss        # コンパイル対象のscssファイル
 │   └─ _module.scss     # パーシャル化されたscssファイル
 │
 ├─ gulpfile.js
 ├─ package.json
 └─ node_modules/
```


## _gulp_ でコンパイルする環境を整える

### _gulp_ のインストール
まずは _gulp_ をインストールする。
（※ _yarn_ を使用する場合は上を、_npm_ を使用する場合は下をターミナルから実行してください）

```bash
# yarn 
yarn add gulp --dev

# npm
npm install gulp --save-dev
```


### _gulp-sass_ のインストール
_sass_ をコンパイルするため、_gulp-sass_ をインストールする。

```bash
# yarn 
yarn add gulp-sass --dev

# npm
npm install gulp-sass --save-dev
```


### _gulp-autoprefixer_ のインストール
ベンダープレフィックスを補完するため、_gulp-autoprefixer_ をインストールする。
> ※ ベンダープレフィックスとは一言で説明すると、特定のスタイルを各ブラウザに対応させるために付与する必要のある接頭辞（`-webkit-`, `-moz-`, `-ms-`, `-o-` など）のこと

```bash
# yarn 
yarn add gulp-autoprefixer --dev

# npm
npm install gulp-autoprefixer --save-dev
```


### _gulp-sourcemaps_ のインストール
_sourcemaps_ の付与を行うため、_gulp-sourcemaps_ をインストールする。
> ※ sourcemapsとは一言で説明すると、ブラウザでのデバッグ時にコンパイル前のソースコードを確認できるようにするためのコンパイル前後の関係を表したもの

```bash
# yarn 
yarn add gulp-sourcemaps --dev

# npm
npm install gulp-sourcemaps --save-dev
```


### _gulp-clean-css_ のインストール
コンパイルした _css_ を圧縮するため、_gulp-clean-css_ をインストールする。

```bash
# yarn 
yarn add gulp-clean-css --dev

# npm
npm install gulp-clean-css --save-dev
```


### _gulp-rename_ のインストール
圧縮した _css_ のファイル名に`.min`を追加するため、_gulp-rename_ をインストールする。

```bash
# yarn 
yarn add gulp-rename --dev

# npm
npm install gulp-rename --save-dev
```


## _gulpfile.js_ に処理を記述する
まずは今回作った _`gulpfile.js`_ の全貌です。

```js
const gulp = require('gulp');
const autoprefixer = require('gulp-autoprefixer');
const cleanCSS = require('gulp-clean-css');
const rename = require('gulp-rename');
const sass = require('gulp-sass');
const sourcemaps = require('gulp-sourcemaps');

const paths = {
  'src': {
    'scss': 'src/scss/**/*.scss',
  },
  'dist': {
    'css': 'dist/css/',
  }
};

gulp.task('sass', done => {
  gulp.src(paths.src.scss)
  .pipe(sourcemaps.init())
  .pipe(sass({
    outputStyle: 'expanded',
  }).on('error', sass.logError))
  .pipe(autoprefixer({
    browsers: ['last 2 versions'],
  }))
  .pipe(sourcemaps.write())
  .pipe(gulp.dest(paths.dist.css))
  .pipe(cleanCSS())
  .pipe(rename({
    suffix: '.min',
  }))
  .pipe(gulp.dest(paths.dist.css));
  done();
});

gulp.task('dev', () => {
  gulp.watch(paths.src.scss, gulp.task('sass'));
});
```


### 必要なパッケージの定義
インストールした、必要なパッケージを以下のように定義します。

```js
const gulp = require('gulp');
const autoprefixer = require('gulp-autoprefixer');
const cleanCSS = require('gulp-clean-css');
const rename = require('gulp-rename');
const sass = require('gulp-sass');
const sourcemaps = require('gulp-sourcemaps');
```


### _scss_, _css_ ファイルのパスを指定
コンパイルの対象となるディレクトリ, コンパイル後の保存先のディレクトリを、今回のディレクトリ構造に合わせて以下のように定義します。

```js
const paths = {
  'src': {
    'scss': 'src/scss/**/*.scss',
  },
  'dist': {
    'css': 'dist/css/',
  }
};
```


### コンパイルタスクの定義
`gulp.src()` にてコンパイル対象のパスを指定し、`.pipe()` で処理をパイプします。
まず、`sourcemaps` に対応させた状態で `sass()` でコンパイルを行います。
その後、ベンダープレフィックスを `autoprefixer()` にて補完し、`gulp.dest()` にて出力先に保存します。
更に、`cleanCSS()` で圧縮を行い、`rename()` で `.min` を付与した状態でも保存します。

```js
gulp.task('sass', done => {
  gulp.src(paths.src.scss)
  .pipe(sourcemaps.init())
  .pipe(sass({
    outputStyle: 'expanded',
  }).on('error', sass.logError))
  .pipe(autoprefixer({
    browsers: ['last 2 versions'],
  }))
  .pipe(sourcemaps.write())
  .pipe(gulp.dest(paths.dist.css))
  .pipe(cleanCSS())
  .pipe(rename({
    suffix: '.min',
  }))
  .pipe(gulp.dest(paths.dist.css));
  done();
});
```


### _scss_ ファイルを変更し保存する度にコンパイル
_scss_ ファイルが変更し保存される度に、上記で定義したコンパイルタスクを実行します。（※ 今回はこの処理の名前を`dev`としました）

```js
gulp.task('dev', () => {
  gulp.watch(paths.src.scss, gulp.task('sass'));
});
```


## _package.json_ の記述
まずは今回作った _`package.json`_ の全貌です。

```json
{
  "dependencies": {},
  "devDependencies": {
    "gulp": "^4.0.0",
    "gulp-autoprefixer": "^6.0.0",
    "gulp-clean-css": "^4.0.0",
    "gulp-rename": "^1.4.0",
    "gulp-sass": "^4.0.2",
    "gulp-sourcemaps": "^2.6.4"
  },
  "scripts": {
    "dev": "gulp dev"
  }
}
```

`devDependencies` の部分に今回使用するパッケージ一覧が記載されています。
また、`scripts` の部分の `"dev": "gulp dev"` でタスクの実行について定義しています。


## 実行方法
ここまでで記載してきた `package.json`, `gulpfile.js` が存在するディレクトリでにて以下をターミナルより実行してください。

```bash
# yarn 
yarn run dev

# npm
npm run dev
```


## まとめ
最後までご覧いただきありがとうございました。
以前ほど _**gulp**_ を使用する機会は減ってしまったものの、慣れているせいもあってか便利なので改めてまとめてみました。

また、`browser-sync` などもタスクとして連携するとより便利にコーディングを行うことができるので、**いいね**をしていただけましたら時間のある時に追記したいと思います(笑)