gulp.jsでWeb開発環境をつくる


gulpの勉強として、Web開発環境を作ってみたのでメモ。
([Google Web Starter Kit](https://github.com/google/web-starter-kit)を参考にしています。)

## 必要なパッケージ

|パッケージ|説明|
|---|---|
|gulp|gulp本体。グローバルとローカル両方にインストールする|
|browser-sync|ブラウザを自動リロードさせる|
|gulp-autoprefixer|cssのベンダープレフィックスをCan I Useを元にいい感じにつけてくれる|
|gulp-csso|cssの軽量化|
|gulp-if|gulpのタスクの処理で、条件指定でいろいろできるようになる|
|gulp-imagemin|画像の軽量化|
|gulp-jshint|jsの構文チェック|
|gulp-load-plugins|gulp-XXX系のプラグインをまとめてロードできる|
|gulp-minify-html|htmlの軽量化|
|gulp-ruby-sass|sass|
|gulp-uglify|jsの軽量化|
|gulp-useref|html内のcssやjsの読込み部分を変更|
|jshint-stylish|gulp-jshintの出力をスタイリッシュにする|
|rimraf|nodeのためのrm -rf ディレクトリの削除に使用|
|run-sequence|gulpタスクの実行順序を指定できる|

## インストール

```bash
# グローバルインストール
npm install -g gulp

#package.json作成
npm init

# ローカルインストール
npm install --save-dev gulp browser-sync gulp-autoprefixer gulp-csso gulp-if gulp-imagemin gulp-jshint gulp-load-plugins gulp-minify-html gulp-ruby-sass gulp-uglify gulp-useref jshint-stylish rimraf run-sequence

```

## ディレクトリ構成

```bash
.
├── gulpfile.js
├── package.json
├── .jshintrc
└── src
    ├── images
    │   └── picture.jpg
    ├── index.html
    ├── page.html
    ├── scripts
    │   ├── lib
    │   │   └── jquery.js
    │   └── main.js
    └── styles
        ├── main.scss
        └── sub.scss

```


## タスク作成
```javascript:gulpfile.js
var gulp = require('gulp');
var $ = require('gulp-load-plugins')();
var browserSync = require('browser-sync');
var rimraf = require('rimraf');
var runSequence = require('run-sequence');


gulp.task('jshint', function () {
  return gulp.src('src/scripts/**/*.js')
    .pipe($.jshint())
    .pipe($.jshint.reporter('jshint-stylish'));
});

gulp.task('image', function () {
  return gulp.src('src/images/**/*')
    .pipe($.imagemin({
      progressive: true,
      interlaced: true
    }))
    .pipe(gulp.dest('dist/images'));
});

gulp.task('scss',function(){
  return gulp.src('src/styles/**/*.scss')
    .pipe($.rubySass({
      style: 'expaned',
    }))
    .pipe($.autoprefixer('last 1 version'))
    .pipe(gulp.dest('.tmp/styles'));
});

gulp.task('html',function(){
  var assets = $.useref.assets({searchPath: ['.tmp','src']});
  return gulp.src('src/**/*.html')
    .pipe(assets)
    .pipe($.if('*.js',$.uglify({preserveComments: 'some'})))
    .pipe($.if('*.css',$.csso()))
    .pipe(assets.restore())
    .pipe($.useref())
    .pipe($.if('*.html',$.minifyHtml()))
    .pipe(gulp.dest('dist'));
});

gulp.task('clean',function(cb){
  rimraf('dist',cb);
});

gulp.task('watch',function(){
  browserSync.init({
    server:{
      baseDir: ['src','.tmp']
    },
    notify: false
  });

  gulp.watch(['src/styles/**/*.scss'], ['scss']);
  gulp.watch(['src/**/*.html'], browserSync.reload);
  gulp.watch(['{.tmp,src}/styles/**/*.css'], browserSync.reload);
  gulp.watch(['src/scripts/**/*.js'], ['jshint',browserSync.reload]);
  gulp.watch(['src/images/**/*'], browserSync.reload);
});

gulp.task('build', function (cb) {
  runSequence('clean','scss', ['jshint', 'html', 'image'], cb);
});

gulp.task('default',['watch']);

```


|タスク|説明|
|---|---|
|jshint|jsの構文チェック|
|scss|scssをcssに変換後、autoprefixerでベンダープレフィックスを付ける|
|html|読み込んでいるcss、jsを軽量化し、1ファイルにまとめる。htmlファイルも軽量化。最後に出力ディレクトリに展開|
|clean|出力用のディレクトリを削除|
|watch|ファイルが更新されたらブラウザをリロードする。scssの場合はscssタスクを流す→cssが更新されるのでブラウザリロード|
|build|リリース用。出力ディレクトリに出力する|

## gulp-userefの使い方

詳しくは [gulp-useref](https://github.com/jonkemp/gulp-useref)

```:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>タイトル</title>
  <!-- build:css styles/main.min.css -->
  <link rel="stylesheet" href="styles/main.css">
  <link rel="stylesheet" href="styles/sub.css">
  <!-- endbuild -->
</head>
<body>
 <h1>Hello World</h1>
 <img src="images/picture.jpg" alt="">
 <a href="page.html">Test</a>

 <!-- build:js scripts/main.min.js -->
 <script src="scripts/lib/jquery.js"></script>
 <script src="scripts/main.js"></script>
 <!-- endbuild -->

</body>
</html>
```

スタイル読み込み部分がポイント。

```
<!-- build:css styles/main.min.css -->
<link rel="stylesheet" href="styles/main.css">
<link rel="stylesheet" href="styles/sub.css">
<!-- endbuild -->
```

`styles/main.css`と`styles/sub.css`を一つのファイルにまとめて、`styles/main.min.css`というファイル名にすることを宣言。jsも同様。
これでhtmlタスクを実行すると、ファイルがまとめられ、参照部分も`<link rel="stylesheet" href="styles/main.min.css">`に書き換えてくれる。