2014/06/13更新

[JavaScript] Gruntの後発のフロントエンドビルドツール、gulpに入門

このエントリーをはてなブックマークに追加      

こんにちは、@yoheiMuneです。
gulpというフロントエンドのビルドツールが気になってました。 それについて試したり調べたりしてだいぶ理解できたので、今日はその内容をブログに書きたいと思います。

画像


目次




gulpとは

gulpとは、JavaScriptのMinifyやCSSプリプロセッサのコンパイルなどを行うことができるフロントエンドのビルドツールです。 フロントエンドのビルドツールには有名なGrunt.jsがありますが、その後発のビルドツールのようです。


Grunt.jsと何が違うのか

実現できることはぶっちゃけ同じで、その実現方法や思想が異なるのだと思います。 gulpのサイト(英語)からいくつか主張を拝借してみました。

gulp's use of streams and code-over-configuration makes for a simpler and more intuitive build.

(gulpはnode.jsのstreamという機能を用いており、code-over-configuration(設定よりもコード)を重視します。そのためよりシンプルにより直感的にビルドを行うことができます。)

gulpのGrunt.jsと大きく異なる点は、code-over-configurationという所です。 後ほど掲載するサンプルコードを見ると分かりますが、ビルドの処理をJavaScriptで記述します。 もちろんGrunt.jsもビルド処理をJavaScriptで記述します。しかしGruntではJavaScriptオブジェクトを定義する一方で、gulpはJavaScriptの実装そのものを書くというイメージです。


また、gulpのサイトでは以下4つの特徴が強調されています。
1. Easy to use
コードでビルドタスクを実装するため、シンプルにタスクを定義することができます。
2. Efficient
node.jsのstream機能を用いているため、処理の中間ファイルなどを作ることなく、高速にビルドを行うことができます。
3. High Quality
gulpのプラグインは厳しいガイドラインに従って作成されなければいけません。それに違反すればブラックリストに登録される可能性があります。そのため、プラグインの品質は高く保たれるようです。
4. Easy to Learn
gulpのAPIの数は最小に保たれています。そのため覚えることはかなり少なく、簡単に使い始めることができます。
プラグインの質がコントロールされている点は、Gruntと大きく異なる点です。個人的には少し怖いとも感じましたw。
以上をまとめてみると、Grunt.jsとの違いは以下となるでしょうか。

gulpとGruntの違い

  1. gulpはコードベースでタスクを定義する
  2. gulpはプラグインの品質がコントロールされている
  3. gulpはGruntに比べてコード量が少なくタスクを定義できる
  4. gulpはJavaScriptの実装ができる人じゃないと使えなさそう
続いては、gulpを実際に使って見たいと思います。



gulpの導入

gulpの導入は以下のように行います。
まずはターミナルでコマンドとして使うためのグローバルインストールを行います。
$ [sudo] npm install -g gulp
続いてビルドを行うプロジェクトで使うためにローカルにもインストールします。
$ npm intall --save-dev gulp
これでgulpのモジュールが作成できました。



gulpをとりあえず動かしてみる

gulpのタスクは、gulpfile.jsという名前のファイルに定義します。例えば「foo」という特に何もしないタスクを作ってみましょう。
// gulpfile.js
var gulp = require('gulp');

// タスク定義
gulp.task('foo', function () {
    console.log('foo task is called.');
});
これで「foo」というタスクを定義することができました。 このタスクを実行するには、以下のようにターミナルでコマンドを実行します。
$ gulp foo
[20:24:02] Using gulpfile ~/tmp/gulpfile.js
[20:24:02] Starting 'foo'...
foo task is called.
[20:24:02] Finished 'foo' after 113 μs
タスクの実行方法はGruntと似てますね。



gulpでちゃんと意味あるタスクを動かしてみる

上記のタスクだと使い物にならないので、ここではファイルの削除、ファイルのコピー、coffeeスクリプトのビルド、JSのミニファイ、画像の最適化を行うタスクを作ってみましょう。 まずは必要なnpmモジュールをインストールします。
$ npm install --save-dev gulp-coffee
$ npm install --save-dev gulp-concat
$ npm install --save-dev gulp-uglify
$ npm install --save-dev gulp-imagemin
$ npm install --save-dev rimraf  # nodeで「rm -rf」を行うライブラリ
続いて、gulpfile.jsを編集します。
// gulpfile.js

// 必要モジュールをロード
var gulp = require('gulp');
var coffee = require('gulp-coffee');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var imagemin = require('gulp-imagemin');
var rimraf = require('rimraf');

// タスク:無意味...
gulp.task('foo', function () {
    console.log('foo task is called.');
});

// タスク:ビルド先を削除
gulp.task('clean', function(cb){
  rimraf('build/', cb);
});

// タスク:Coffeeのコンパイル、JSのミニファイ
// ['clean']を指定することで、このタスク実行前に行いたいタスクを指定できます.
gulp.task('scripts', ['clean'], function() {
  return gulp.src(['client/js/**/*.coffee', '!client/external/**/*.coffee'])
    .pipe(coffee())
    .pipe(uglify())
    .pipe(concat('all.min.js'))
    .pipe(gulp.dest('build/js'));
});

// タスク:画像の最適化
gulp.task('images', ['clean'], function() {
 return gulp.src('client/img/**/*')
    .pipe(imagemin({optimizationLevel: 5}))
    .pipe(gulp.dest('build/img'));
});

// タスク:ファイルのコピー
// コピーだけなら特にプラグインは不要.
gulp.task('copy-html', function () {
    return gulp.src('*.html')
        .pipe(gulp.dest('build/'));
});

// デフォルトタスクを指定
gulp.task('default', ['scripts', 'images', 'copy-html']);
見て分かる通り、Gruntとはかなり記述内容が異なります。 同じ内容をGruntfileで定義しようとするとコード量はほぼ倍になるでしょう。また、gulpのAPIは、gulp.srcgulp.pipegulp.destの3つだけでAPIの数が最小だという点も分かります。
個人的には少し癖があるかなーと感じますが、でも学んだ次の日には自分も特に参照することなくコードを書けたので、かなり学習コストは少ないと思います。

上記を実行するには以下のようにターミナルで行います。
$ gulp
これでビルドができます。



gulpでwatchをする

gulpではwatchをすることも可能です。上記のgulpfile.jsに以下のタスクを追加します。
gulp.task('watch', function() {
  gulp.watch(['client/js/**/*.coffee', '!client/external/**/*.coffee'], ['scripts']);
  gulp.watch('client/img/**/*', ['images']);
});
そして以下のようにターミナルで実行します。
$ gulp watch
これで指定したファイルが監視されるようになります。 また、gulp-livereloadというモジュールもあるようなので、watch後にlivereloadを行うこともできそうですね。



プラグインを探す

プラグインは、以下のサイトで公開されていますので、そちらから探すことができます。

http://gulpjs.com/plugins/

でもだいたい目星がついているならnpm searchで探すか、Google先生に聞いた方が早いかもですかね。



(追記)Gruntから移行する際のメリット・デメリット

記事を公開したら、「Gruntから移行するメリットは・・・」という話を受けましたので、考えてみました。 執筆時点の感想では「Grunt使っているならわざわざ移行しなくても良いかなー」というのがザックリとした感想です。
Gruntからgulpへ移行する場合のメリットデメリットは以下となるでしょうか。

メリット

  1. ファイルの行数が半分くらいになる。500行なら250行とか
  2. gulpの方が早いらしい(未検証)
  3. 最新ツール使ってるぞと、自慢できるw

デメリット

  1. 日本語でのノウハウは少ないから、何かにはまったら自分で道を切り開く必要がある
  2. 行数が少ないって言ったって、たくさんタスクを定義したら長くなる
  3. JavaScriptを書ける人向け
  4. 何かカスタマイズしようとすると、node.jsのpipe処理を理解しておく必要がある

個人的には「新しいもの好きで使い初めてみる。 気に入ってそのプロダクトの成長へコントリビュートする」というのが、楽しい過ごし方かなと思います。 感想ベースなので間違っていたらごめんなさい。この点、他の方にも意見を伺ってみたいですー。



参考情報

gulp紹介記事や、gulpが利用しているnodeのpipeについて詳しく書かれた記事を紹介します。 より深い理解にご利用下さい。

gulpjs.comの本家ページ(英語)
node.jsのstreamについて(英語)
打倒Grunt!Node.js用の新たなビルドシステムgulpことはじめ(by白石さん)
Gruntfile.js が長すぎてつらい人は gulp を使ってみよう | Qiita



最後に

gulpを触ってみた感想としては、すごく気軽にコード量少なくビルドコードが書ける点がいいなと思いました。 実際に仕事でもちょっと使ってみました(他メンバーはgulpを知らない状態なので、正規のビルドはもちろんGruntを使いますが)。
今後も動向をwatchしつつ、少しずつ自分でも使ってみようと思いました。

最後までご覧頂きましてありがとうございました。
今後もこんな感じでフロントエンドの技術紹介をしていくつもりですので、良かったらRSSTwitterもよろしくお願いします☆





こんな記事もいかがですか?

RSS画像

もしご興味をお持ち頂けましたら、ぜひRSSへの登録をお願い致します。