Gulp インストールから 本番環境と開発環境の使い分けまで

# Gulp

フロントサイドの開発でのjavascript のコンパイル、CSS の圧縮などを行うタスクランナー。
詳細は公式サイトを参照。

http://gulpjs.com/

バリバリのサーバーサイドエンジニアの自分がなぜ自分がGulp を触るようになったか、というと
今まで自分の会社ではフロントサイドエンジニアからHTML, CSS, javascript などを納品という形で受け取り、
それをテンプレートエンジンへ変換する（例えばjava でいえばjsp に変換する）という作業の流れだったが、
それだとフロントサイドとサーバーサイドの間に大きな壁ができ、
効率が非常に悪く、良いものができなかったため、
フロントサイドとサーバーサイドが協力して作業をするようにしたためである。

そのためフロントサイドのgulp というタスクランナーの設定なども受け持ったというわけである。

# 環境
* windows 10
* npm 3.7.3
* node v5.8.0

## Gulp のインストール
グローバルインストール

```
$ npm install -g gulp
```

# サンプルの作成
ここではjavascript を圧縮するタスクランナーを作成する。

まずは適当なディレクトリで

```
$ npm init
```

圧縮に必要なgulp-uglify を`devDependencies` に追加する。

```
$ npm install gulp-uglify --save-dev
```


次にgulpfile.js の作成。

```js
var gulp = require('gulp');
var uglify = require('gulp-uglify');

gulp.task('uglify',function () {
	return gulp.src(['src/**/*.js'])
		.pipe(uglify()))
		.pipe(gulp.dest('dist/javascript/'));
});

gulp.task('default', ['uglify'], function () {
    // This will only run if the lint task is successful... 
});
```

簡単に解説すると、`require` で必要なモジュールを追加し、`gulp.task` でタスクを定義している。
圧縮のタスクは`.pipe(uglify())` になる。

デフォルトタスクに追加しているため、以下コマンドで実行できる。

```
$ gulp
```

これでsrc ディレクトリ以下のjs ファイルが圧縮されてdist/javascript 以下に出力される。

# 本番環境と開発環境の使い分け

本番環境と開発環境で別々にタスクを定義してもよいが、それだと２重管理になる恐れが高い。
共通でタスクを定義し、開発環境では必要ないタスクは除いたりしたほうがよい。
jsファイルの圧縮などはまさしく開発環境では不要なタスクである。

それでは本番環境と開発環境の使い分けをしてみよう。
まずは本番環境と開発環境の使い分けに必要なgulp-if, minimist を`devDependencies` に追加する。

```
$ npm install gulp-if --save-dev
$ npm install minimist --save-dev
```

これらを使い、先ほどのgulpfile.js を書き換え、開発環境ではjs ファイルの圧縮をしないようにする。

```js:gulpfile.js
var gulp = require('gulp');
var uglify = require('gulp-uglify');
var gulpif = require('gulp-if');

var minimist = require('minimist');

var options = minimist(process.argv.slice(2), envOption);

var envOption = {
  string: 'env',
  default: { env: process.env.NODE_ENV || 'development' } // NODE_ENVに指定がなければ開発モードをデフォルトにする
};

var isProduction = (options.env === 'production') ? true : false;

console.log('[build env]', options.env, '[is production]', isProduction);

gulp.task('uglify',function () {
	return gulp.src(['src/**/*.js'])
		.pipe(gulpif(isProduction, uglify()))
		.pipe(gulp.dest('dist/javascript/'));
});


gulp.task('default', ['uglify'], function () {
    // This will only run if the lint task is successful... 
});
```


ここでキーとなるのは`minimist` の使い方である。
`minimist` はコマンドライン引数を理解し、配列にしてくれる。
例えばこのようなjs に対して

```js
var argv = require('minimist')(process.argv.slice(2));
console.dir(argv);
```

コマンドライン引数を与えた場合、コンソール出力は以下のようになる。

```
$ node example/parse.js -x 3 -y 4 -n5 -abc --beep=boop foo bar baz
{ _: [ 'foo', 'bar', 'baz' ],
  x: 3,
  y: 4,
  n: 5,
  a: true,
  b: true,
  c: true,
  beep: 'boop' }
```

ついでに`process.argv` には第一引数に`node` が入り、第２引数には実行ファイル名が入る。
第３引数以降にはコマンドライン引数が入るため、`minimist` に渡す場合は`process.argv.slice(2)` がお決まりとなる。


また`minimist` は第２引数にオプション(ここではenvOption と定義)を与えることができ、`envOption.string` に定義した値を取得する。
またコマンドライン引数に該当の値がない場合は`envOption.defaut` に定義した値がデフォルト値となる。

それでは実行してみよう。
まずは本番環境の場合

```
$ gulp --env production
[build env] production [is production] true
```

次に開発環境の場合

```
$ gulp --env production
[build env] undefined [is production] false
```

これで本番環境と開発環境の使い分けができた。


## 最後に。。。
自分のはてなブログを紹介する。
はてなブログに書いていたが、Qiita に移行してきたので以前のブログを紹介しておきたい。
http://aha-oretama.hatenablog.com/