gulp入門と備忘録から作業前の環境構築のパターンまで


## 環境をつくる
下記をインストール

- Homebrew
- Node.js
- npm


## gulpをローカルにインストール
※グローバルにgulpをインストールしない方がいいみたいです。
参考サイト
「[僕がnpm installに-gをつけないわけ](http://qiita.com/Mic-U/items/cd456d6bea72937464f8)」


``` command:command
$ npm init -y
$ npm install --save-dev gulp
$ export PATH=${PATH}:${HOME}/node_modules/.bin
$ gulp -v
```

## Hello World表示

ディレクトリに「gulpfile.js」を作成

``` javascript:gulpfile.js
var gulp = require('gulp');

gulp.task('hello', function() {
  console.log('Hello world');
});
```

``` command:command
$ gulp hello          // 「hello」はタスク名 
```

## 短縮の書き方

``` javascript:gulpfile.js
var gulp = require('gulp');

gulp.task('hello', function() {
  console.log('Hello world');
});

gulp .task('default', ['hello']);
```

``` commnad:commnad
$ gulp
```

## ファイルのコピー方法
圧縮ファイルなどを他のディレクトリに移動させる方法

``` javascript:gulpfile.js
var gulp = require('gulp');

gulp.task('html', function() {
  gulp.src('./src/index.html')
      .pipe(gulp.dest('./'));
});

gulp.task('default', ['html']);
```

``` commnad:command
$ gulp               // src/index.html -> /index.htmlにコピー
```

### srcの使い方
コピーするもの「配列」「*」「!」で選択できる

``` javascript:gulpfile.js
gulp.src('./src/index.html')
gulp.src(['./src/index.html', './src/main.html'])
gulp.src('./src/*.html')
gulp.src('./src/**/*.html')
gulp.src(['./src/**/*.html', '!./src/donotcopy.html'])
```

## 実行の順序を指定
「html」「msg」の順番でタスクを走らせる場合

``` javascript:gulpfile.js
var gulp = require('gulp');

gulp.task('html', function() {
  return gulp.src('./src/index.html')    // returnを記述
    .pipe(gulp.dest('./'));
});

gulp.task('msg', ['html'], function() {  // 第二引数に先に実行したいタスクを記入
  console.log('html copy done!');
});

gulp .task('default', ['msg']);          // タスクは1つだけ記入
```

``` commnad:command
$ gulp               // html実行の後にmsgが実行される
```


## imageファイルを圧縮させる
imageファイル圧縮用のプラグインをインストールする

``` commnad:commnad
$ npm i -D gulp-imagemin

```

``` javascript:gulpfile.js
var gulp = require('gulp');
var imagemin = require('gulp-imagemin');      // プラグインを読み込む

gulp.task('html', function() {
  gulp.src('./src/index.html')
    .pipe(gulp.dest('./'));
});

gulp.task('img', function() {                 // タスク追加
  gulp.src('./src/images/*')                  // 全てのファイル対象
    .pipe(imagemin())　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　 // プラグインを実行
    .pipe(gulp.dest('./images'));            // 圧縮したファイルを置く場所    
});

gulp .task('default', ['html', 'img']);
```

実行するとコマンドに圧縮率が表示される

``` commnad:commnad
gulp
・
・
・
gulp-imagemin: Minified 1 image (saved 589 B - 3.3%)
```

## es6でjsを書くためにBabelを使用

※「preset-es2015」もインストールします。

``` command:command
$ npm i -D gulp-babel babel-preset-es2015
```

``` javascript:gulpfile.js
var gulp = require('gulp');
var babel = require('gulp-babel');

gulp.task('default', function() {
  return gulp.src('src/app.js')
    .pipe(babel({
      presets: ['es2015']
    }))
    .pipe(gulp.dest('./js'));
});
```
## es6にコンパイルしたらsourcemapsが必要

※sourcemapsとは。。
> なぜSourceMapが必要なのか
では、なぜコンパイル前後の対応関係が必要なのでしょうか。
それは、AltJSやReact、ES6のような言語は、デバッグが難しいからです。
ここでのデバッグとは、コンパイル後にブラウザで確認するフェーズのことを言います。
コンソールに吐かれるJavaScriptのErrorは、コンパイル後の箇所を表示します。ただし、コンパイル後のファイルは見づらく、デバッグに向きません。　
そこで、SourceMapを用意しておくとブラウザがSourceMapを頼りに、当該箇所を見に行ってくれるようです。

引用元：[SourceMapとは何なのか](http://chuckwebtips.hatenablog.com/entry/2016/03/02/000000)

``` command:command
$ npm i -D gulp-sourcemaps
```

``` javascript:gulpfile.js
var gulp = require('gulp');
var sourcemaps = require('gulp-sourcemaps');
var babel = require('gulp-babel');

gulp.task('default', function() {
  return gulp.src('src/app.js')
    .pipe(sourcemaps.init())
    .pipe(babel({
      presets: ['es2015']
    }))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('./js'));
});
```


## CoffeeScriptファイルを1つのjsファイルに結合してmin化させる
まずはプラグインを読み込む

``` commnad:command
$ npm i -D gulp-coffee    // CoffeeScriptをコンパイルするプラグイン
$ npm i -D gulp-concat    // 複数のファイルを1つにまとめるプラグイン
$ npm i -D gulp-uglify    // min化させるプラグイン
```

``` javascript:gulpfile.js
var gulp = require('gulp');
var coffee = require('gulp-coffee');      // coffeeスクリプトを読み込む
var concat = require('gulp-concat');      // 2つ以上のファイルを結合
var uglify = require('gulp-uglify');      // minファイルにする

gulp.task('js', function() {
  gulp.src('./src/coffee/*.coffee')
    .pipe(coffee())                      // coffeeプラグイン実行
    .pipe(concat('all.min.js'))          // 結合したファイル名指定
    .pipe(uglify())                      // min化実行
    .pipe(gulp.dest('./js'));            // /js/all.min.jsが作成される
});

gulp .task('default', ['js']);  // タスクにjs追加
```

``` commnad:command
$ gulp
```


## 複数のjsファイルを結合してmin化させる場合

``` commnad:command
$ npm i -D gulp-concat    // 複数のファイルを1つにまとめるプラグイン
$ npm i -D gulp-uglify    // min化させるプラグイン
```

``` javascript:gulpfile.js
var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');

gulp.task('js', function() {
  gulp.src('./src/js/*.js')
    .pipe(concat('all.min.js'))
    .pipe(uglify())
    .pipe(gulp.dest('./js'));
});

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

```

``` commnad:command
$ gulp
```

## 監視「watch」
ファイルに変更があったら自動で「gulp」を走らせる方法。

``` javascript:gulpfile.js
var gulp = require('gulp');
var coffee = require('gulp-coffee');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');

gulp.task('js', function() {
  gulp.src('./src/coffee/*.coffee')
      .pipe(coffee())
      .pipe(concat('all.min.js'))
      .pipe(uglify())
      .pipe(gulp.dest('./js'));
});

gulp.task('watch', function() {
  gulp.watch('./src/coffee/*.coffee', ['js'])
});

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

```

``` commnad:command
$ gulp        // 上記のコードを1回保存後は自動でタスクが走る
```

## 監視「watch」をエラー時でも止めない「plumber」
監視「watch」を使っている時にエラーが出た場合、gulpが止まってしまってその度にgulpコマンドを打つのが面倒。
そのときにエラーが出ても「gulp」を止めないプラグインが「gulp-plumber」

「gulp-plumber」をインストールする。

``` commnad:command
$ npm i -D gulp-plumber
```

``` javascript/gulpfile.js
var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var plumber = require('gulp-plumber');

gulp.task('js', function() {
  gulp.src('./src/js/*.js')
    .pipe(plumber())                       // erorが出そうな記述の前に実行する
    .pipe(concat('all.min.js'))
    .pipe(uglify())
    .pipe(gulp.dest('./js'));
});

gulp.task('watch', function() {
  gulp.watch('./src/js/*.js', ['js'])
});

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

## sassファイルの使用

``` commnad:command
$ npm i -D gulp-sass
```

``` javascript:gulpfile.js
var gulp = require('gulp');
var sass = require('gulp-sass')
var plumber = require('gulp-plumber');

gulp.task('sass', function() {
  gulp.src('./src/sass/*.scss')
    .pipe(plumber())
    .pipe(sass({outputStyle: 'expanded'}))  // 「expanded」はコンパイルしたcssコードを通常の段落ありにする（「compressed」は1行にする）
    .pipe(gulp.dest('./css/'));
});

gulp.task('watch', function() {
  gulp.watch('./src/sass/*.scss', ['sass'])
});

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

## headerにコードを記述する「gulp-header」
minファイル化されたファイルのheaderにコードを記述したいとき(copyrightなど)、「gulp-header」を使う。

「gulp-header」をインストールする。

``` commnad:command
$ npm i -D gulp-header
```

``` javascript:gulpfile.js
var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var plumber = require('gulp-plumber');
var header = require('gulp-header');

gulp.task('js', function() {
  gulp.src('./src/js/*.js')
    .pipe(plumber())
    .pipe(concat('all.min.js'))
    .pipe(uglify())
    .pipe(header('/* this comment */'))     //　「all.min.js」のコードの先頭に追加される
    .pipe(gulp.dest('./js'));
});
```

通常は「package.json」に記述された「name」を引っ張ってくることが多い。
その書き方。

``` javascript:gulpfile.js
var pkg = require('./package.json');  // 変数

gulp.task('js', function() {
  gulp.src('./src/js/*.js')
    .pipe(plumber())
    .pipe(concat('all.min.js'))
    .pipe(uglify())
    .pipe(header('/* copyright <%= pkg.name %> */', {pkg: pkg}))  //　「package.json」に書かれた「name」を引っ張ってくる
    .pipe(gulp.dest('./js'));
});
```

## jade導入

``` commnad:command
$ npm i -D jade
$ npm i -D gulp-jade
```

``` javascript:gulpfile.js
var gulp = require('gulp');
var jade = require('gulp-jade');

gulp.task('jade', function() {
  gulp.src('./src/jade/*.jade')
    .pipe(jade({pretty: true}))    // 「true」でコードのインデントを綺麗にする
    .pipe(gulp.dest('./'));
});

gulp.task('watch', function() {
  gulp.watch('./src/jade/*.jade', ['jade'])
});

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

## 環境構築 パターン1

- 全てのimageファイルを圧縮
- sassを使用
- jsファイルを結合、minファイル化
- jsファイルを変更したら自動で更新される
- sassファイルを変更したら自動で更新される
- jsエラーが出ても「gulp」を止めない
- sassエラーが出ても「gulp」を止めない

### プラグイン

``` command:command
$ sudo npm install gulp --save-dev
$ npm init
$ npm i -D gulp
$ npm i -D gulp-imagemin
$ npm i -D gulp-sass
$ npm i -D gulp-concat
$ npm i -D gulp-uglify
$ npm i -D gulp-plumber
```

### gulpfile.js

``` javascript:gulpfile.js
var gulp = require('gulp');
var imagemin = require('gulp-imagemin');
var sass = require('gulp-sass');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var plumber = require('gulp-plumber');

gulp.task('img', function() {
  gulp.src('./src/images/*')
    .pipe(imagemin())
    .pipe(gulp.dest('./dist/images'));
});

gulp.task('sass', function() {
  gulp.src('./src/sass/*.scss')
    .pipe(plumber())
    .pipe(sass({outputStyle: 'expanded'}))
    .pipe(gulp.dest('./dist/css/'));
});

gulp.task('js', function() {
  gulp.src('./src/js/*.js')
    .pipe(plumber())
    .pipe(concat('script.min.js'))
    .pipe(uglify())
    .pipe(gulp.dest('./dist/js'));
});

gulp.task('watch', function() {
  gulp.watch('./src/js/*.js', ['js'])
  gulp.watch('./src/sass/*.scss', ['sass'])
});

gulp.task('default', ['img', 'sass', 'js', 'watch']);
```

``` command:command
$ gulp
```

## 環境構築 パターン2

- 全てのimageファイルを圧縮
- jadeを使用
- sassを使用
- jsファイルを結合、minファイル化
- jadeファイルを変更したら自動で更新される
- jsファイルを変更したら自動で更新される
- sassファイルを変更したら自動で更新される
- jsエラーが出ても「gulp」を止めない
- sassエラーが出ても「gulp」を止めない

### プラグイン

``` command:command
$ sudo npm install gulp --save-dev
$ npm init
$ npm i -D gulp
$ npm i -D jade
$ npm i -D gulp-jade
$ npm i -D gulp-imagemin
$ npm i -D gulp-sass
$ npm i -D gulp-concat
$ npm i -D gulp-uglify
$ npm i -D gulp-plumber
```

### gulpfile.js

``` javascript:gulpfile.js
var gulp = require('gulp');
var jade = require('gulp-jade');
var imagemin = require('gulp-imagemin');
var sass = require('gulp-sass');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var plumber = require('gulp-plumber');

gulp.task('jade', function() {
  gulp.src('./src/jade/*.jade')
    .pipe(jade({pretty: true}))
    .pipe(gulp.dest('./dist/'));
});

gulp.task('img', function() {
  gulp.src('./src/images/*')
    .pipe(imagemin())
    .pipe(gulp.dest('./dist/images'));
});

gulp.task('sass', function() {
  gulp.src('./src/sass/*.scss')
    .pipe(plumber())
    .pipe(sass({outputStyle: 'expanded'}))
    .pipe(gulp.dest('./dist/css/'));
});

gulp.task('js', function() {
  gulp.src('./src/js/*.js')
    .pipe(plumber())
    .pipe(concat('script.min.js'))
    .pipe(uglify())
    .pipe(gulp.dest('./dist/js'));
});

gulp.task('watch', function() {
　　　　gulp.watch('./src/jade/*.jade', ['jade'])
  gulp.watch('./src/js/*.js', ['js'])
  gulp.watch('./src/sass/*.scss', ['sass'])
});

gulp.task('default', ['jade', 'img', 'sass', 'js', 'watch']);
```

``` command:command
$ gulp
```

## 環境構築 パターン3

- 全てのimageファイルを圧縮
- jadeを使用
- sassを使用
- es6でjsを書くためにBabel使用
- es6デバッグのためにsourcemapsもインストール
- jsファイルを結合、minファイル化
- jadeファイルを変更したら自動で更新される
- jsファイルを変更したら自動で更新される
- sassファイルを変更したら自動で更新される
- jsエラーが出ても「gulp」を止めない
- sassエラーが出ても「gulp」を止めない

### プラグイン

``` command:command
$ sudo npm install gulp --save-dev
$ npm init
$ npm i -D gulp
$ npm i -D jade
$ npm i -D gulp-jade
$ npm i -D gulp-imagemin
$ npm i -D gulp-sass
$ npm i -D gulp-babel babel-preset-es2015
$ npm i -D gulp-sourcemaps
$ npm i -D gulp-concat
$ npm i -D gulp-uglify
$ npm i -D gulp-plumber
```

### gulpfile.js

``` javascript:gulpfile.js
var gulp = require('gulp');
var jade = require('gulp-jade');
var imagemin = require('gulp-imagemin');
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');
var babel = require('gulp-babel');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var plumber = require('gulp-plumber');

gulp.task('jade', function() {
  gulp.src('./src/jade/*.jade')
    .pipe(jade({pretty: true}))
    .pipe(gulp.dest('./dist/'));
});

gulp.task('img', function() {
  gulp.src('./src/images/*')
    .pipe(imagemin())
    .pipe(gulp.dest('./dist/images'));
});

gulp.task('sass', function() {
  gulp.src('./src/sass/*.scss')
    .pipe(plumber())
    .pipe(sass({outputStyle: 'expanded'}))
    .pipe(gulp.dest('./dist/css/'));
});

gulp.task('js', function() {
  gulp.src('./src/js/*.js')
    .pipe(plumber())
    .pipe(sourcemaps.init())
    .pipe(babel({
      presets: ['es2015']
    }))
    .pipe(concat('script.min.js'))
    .pipe(uglify())
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('./dist/js'));
});

gulp.task('watch', function() {
　　　　gulp.watch('./src/jade/*.jade', ['jade'])
  gulp.watch('./src/js/*.js', ['js'])
  gulp.watch('./src/sass/*.scss', ['sass'])
});

gulp.task('default', ['jade', 'img', 'sass', 'js', 'watch']);
```

``` command:command
$ gulp
```


## 参考資料

- [ドットインストール(gulp入門編)](http://dotinstall.com/lessons/basic_gulp/30601)
- [僕がnpm installに-gをつけないわけ](http://qiita.com/Mic-U/items/cd456d6bea72937464f8)
- [軽量なマークアップ言語 Jade 入門 からの Gulp でコンパイルまで - Gulp で作る Web フロントエンド開発環境 #5](https://tech.recruit-mp.co.jp/front-end/post-2581/)