めんどくさいことはgulpで自動化しよう

本記事は[KIT AppDeveloper Advent Calendar 2015](http://qiita.com/advent-calendar/2015/kitappdeveloper)の11日目の記事です。


# なぜ自動化しようと思ったのか

単純に何回も同じことをするのが **めんどくさい** と思ったからです。

しかし、めんどくさいと思いながらもどうにか対処するためには新しいことを覚えなければなりません。
すると、その新しいことを覚えるのにもまた時間がかかります。
納期があって仕方なくそのままにしておくこともあるでしょう。

ただ、やはり個人的には **めんどくさいことは自動化するべき** だと思っています。
( めんどくさい = 同じことを何度も行わなければならないなどを想定して書いてます。 )

なぜそう思うかは、以下の3点が主な理由です。
・単純に時間が掛かる
・メインの作業のみに集中できない
・ヒューマンエラーが発生する可能性が高い

そんなに回数をこなす必要がなければ時間としては、自動化するための作業を行った方が時間がかかるかもしれません。
ですが、同じ作業は**自動化することで「ヒューマンエラー」を確実に防ぐ**ことができます。


# 具体的にどういうことを自動化する?

定期的にバックアップを取る、システムをアップデートするなど
定期的なことであれば[cron](http://webkaru.net/linux/crontab-command/)や[launchd](http://furudate.hatenablog.com/entry/2014/11/09/155017)などでいいでしょう。

では何を自動化するのか例をあげると
webページを作っているとして**html,cssを更新したらブラウザをリロード**して欲しくないですか？
さらにcssではなくsassを利用していて、**sassを更新したらcssにコンパイル**して、ブラウザをリロードして欲しくないですか？

gulpを使えば、こういう**「何か変更」を監視してそれに対するアクションを自動で実行する**ことができます。


# [gulp](http://gulpjs.com)とは

Node.js上で動作するビルドシステムです。
つまり何?と思う人がいるかもしれないので簡単に説明すると、**様々な処理をタスクとして自動化できるシステム**です。
同系統のものとしては[Grunt](http://gruntjs.com)があります。
gulpはGruntの後発で簡単に使えて、簡単に記述することができます。
gulpのデメリットとしては、Gruntより公開されているプラグインが少ないですが
多くの人がよく使うであろうプラグインは大抵公開されていると思います。


# gulpを使ってみる

長々と文章を書いてきましたが、実際にgulpを触ってみましょう。

※ Node.js上で動作するため、Node.jsがインストールしてあることを前提としています。
（Node.jsのインストール方法がわからない人へ → [Mac](http://qiita.com/ryurock/items/5bb3e432ab5945fdf980), [Win](http://qiita.com/roana0229/items/29232508e71559d0fd5f)）

以下、gulp公式の[チュートリアル](https://github.com/gulpjs/gulp/blob/master/docs/getting-started.md)

## 1.グローバルにgulpをインストール

```
npm install -g gulp
```

## 2.ローカルにgulpをインストール

```
npm install -D gulp
```

## 3.`gulpfile.js`という名前のファイルを作成し、下記をコピペ

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

gulp.task('default', function() {
  // place code for your default task here
});
```

## 4.gulpを実行

任意のタスクを実行するためには引数にタスク名を渡します。
引数を渡さない場合、`default`が渡されます。
そのため下記の２つは同等のコマンドです。

```
gulp
gulp default
```

gulpを実行できましたか？
実行できた場合、以下のようなログが流れて終了します。

```
[~/path/gulp-sample]$ gulp
[10:34:08] Using gulpfile ~/path/gulp-sample/gulpfile.js
[10:34:08] Starting 'default'...
[10:34:08] Finished 'default' after 73 μs
```

前の説明で「何かの変更」を監視と言いながら、なぜ実行後すぐに終了したかというと、defaultタスク内に何も監視する記述をしていないからです。


# gulpのプラグインを利用し、カスタマイズしてみよう

webページを作っているという体で、ファイルを更新したらブラウザをリロードするようにしてみましょう。

## 1.プラグインのインストール

`gulp-webserver`というプラグインを利用します。
gulpをインストールするときのように下記のコマンドを実行するだけで、プラグインが使えるようになります。

```
npm install -D gulp-webserver
```

そして、gulpfile.jsを下記のように編集します。
軽く説明しますと
・`default`タスクを実行すると`serve`タスクを実行する。
（何故こうしているかというと`default`タスクで複数のタスクを実行したい場合にタスクを細かく分けることで必要なタスクだけを同時実行できるようになります。）
・`serve`タスクでカレントディレクトリ全体を監視し、プラグインを使い`port:4000`で`livereload`を開始する。

```gulpfile.js
var gulp = require('gulp'),
    webserver = require('gulp-webserver');

var SERVER_PORT = 4000;

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

gulp.task('serve', function() {
  gulp.src('./')
    .pipe(webserver({
      livereload: true,
      open: true,
      port: SERVER_PORT
    }));
});
```

そしてカレントディレクトリに`index.html`, `index.css`ファイルを作成します。

```index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <title>sample</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="index.css">
  </head>
  <body>
    gulpテストだよ。
  </body>
</html>

```

```index.css
body {
  color: black;
}
```

この状態で`gulp`を実行するとこのようになります。

![gulp.gif](https://qiita-image-store.s3.amazonaws.com/0/42327/6d8f7f3e-39c0-25e6-3bbc-5568145a6ba2.gif)

htmlファイルやcssファイルを更新したら、勝手にブラウザがリロードされていますね。


# 最後に。

gulpを使うことでwebページを作成するときにファイルを更新したら、いちいち自分でブラウザをリロードする必要がなくなりましたね！
今回は説明のために簡単なことしかしていませんが、もっと複雑なこともできます。
ぜひ、快適な自動化生活を送りましょう！


webページを作成するためのgulpを使った構成をgithubに公開しています。
[https://github.com/roana0229/gulp-template-web](https://github.com/roana0229/gulp-template-web)

ここではgulpを使って以下のようなことをしています。

`gulp`コマンド:

* src内の`*.html`,`*,css`,`*.js`を監視して変更があればブラウザリロード
* src/sass内の`*.scss`を監視して変更があれば、compassを使ってcssに変換し、任意のベンダープレフィックスを付加
* compassでコンパイルするときにエラーがあれば、osxの通知機能を使ってエラーを表示

`gulp build`コマンド:

* src内の`*.html`,`*,css`,`*.js`をminifyしてbuildフォルダに出力
* 出力されたbuildフォルダをブラウザで表示、ライブリロード