Developer's Blog

gulp.js でタスクを自動化してみよう

Fenrir Advent Calendar 2014

こんにちは!ウェブ開発担当の清水です。

Fenrir Advent Calendar 2014」も終盤の 23 日目となりました。

近年フロントエンド中心の開発が増加し、その際考慮すべきことが複雑になってきました。例えば SASS や CoffeeScript などのコンパイル、複数ファイルの統合、圧縮(Minify)などが挙げられます。

それらのタスクを一度に処理できるツールには Grunt などがありますが、最近はよりシンプルに設定を記述できる gulp.js というなかなか良さそうなものが現れました。

私の「2014年にグッときたコレ」では、その gulp.js について簡単に紹介したいと思います。

インストール

gulp.js は Node.js のモジュールで、npm からインストールします。

 $ npm install gulp -g 

次に init コマンドでパッケージ管理ファイルの package.json を作成します。

 $ npm init 
package.json
 {
  "name": "gulp_test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
} 

gulpfile.js 作成

今回は以下のようなタスクの自動化をしてみましょう。

  1. CoffeeScript のコンパイル
  2. ファイルを圧縮(.min)

必要なプラグインをインストールします。なお、–save-dev オプションを追加することで package.json に自動で登録されます。

 $ npm install gulp gulp-coffee gulp-uglify gulp-rename --save-dev 

では実際のタスクを記述する gulpfile.js 作成しましょう。Grunt における Gruntfile.js にあたります。

gulpfile.js
// プラグインの読み込み
var gulp = require('gulp'),
    coffee = require('gulp-coffee'), // CoffeeScript コンパイル
    uglify = require('gulp-uglify'), // JavaScript 圧縮
    rename = require('gulp-rename'); // リネーム

// タスク定義
gulp.task('coffee-compile', function() {
 // 処理対象ファイル
  return gulp.src('coffee/**/*.coffee') 
    .pipe(coffee())
    .pipe(gulp.dest('js')) 
    .pipe(rename({suffix: '.min'}))
    .pipe(uglify())
    .pipe(gulp.dest('js'));
});

gulp.pipe([実行処理]) を連結し、最後に gulp.dest([出力先]) で出力しています。Gruntfile では各タスクを json 形式で記述していくため若干長くなりがちですが、gulpfile はよりシンプルで処理の流れもわかりやすい印象を受けます。

実行

coffee ディレクトリに適当なファイルを作成し、gulp [タスク名] で実行してみましょう。

coffee/main.coffee
$ ->
  console.log 'gulp test'
  return
$ gulp coffee-compile
[12:39:13] Using gulpfile ~/xxx/gulp_test/gulpfile.js
[12:39:13] Starting 'coffee-compile'...
[12:39:13] Finished 'coffee-compile' after 69 ms

すると js ディレクトリに main.js と main.min.js が生成されました!

js/main.js
(function() {
  $(function() {
    console.log('gulp test');
  });

}).call(this);
js/main.min.js
(function(){$(function(){console.log("gulp test")})}).call(this);

変更を監視

さて、たびたびコマンドを叩くのは手間なので、ファイルの変更を監視して自動で実行するようにしてみましょう。監視メソッド gulp.watch([対象ファイル], [タスク名]) を追記します。

gulpfile.js
...
gulp.task('watch', function() {
    gulp.watch(['coffee/**/*.coffee'], ['coffee-compile']);
});
 
gulp.task('default', ['watch']);

これで coffee/**/*.coffee に変更があるたび coffee-compile が動作します。ちなみに、’default’ に定義してあるものはタスク名を省略できます。

$ gulp
[12:39:58] Using gulpfile ~/xxx/gulp_test/gulpfile.js
[12:39:58] Starting 'watch'...
[12:39:58] Finished 'watch' after 7.55 ms
[12:39:58] Starting 'default'...
[12:39:58] Finished 'default' after 6.68 μs
[12:40:07] Starting 'coffee-compile'...
[12:40:07] Finished 'coffee-compile' after 59 ms

plumber を導入

現在の設定では CoffeeScript から JavaScript へのコンパイルでエラーとなった場合、監視自体が終了してしまいます。そこで plumber というプラグインを追加することで回避してみます。

 $ npm install gulp-plumber --save-dev 
gulpfile.js
var gulp = require('gulp'),
    coffee = require('gulp-coffee'),
    uglify = require('gulp-uglify'),
    rename = require('gulp-rename'),
    plumber = require('gulp-plumber'); // ←追加

gulp.task('coffee-compile', function() {
  return gulp.src('coffee/**/*.coffee')
  .pipe(plumber()) // コンパイルエラー時に中断させない
    .pipe(coffee())
    .pipe(gulp.dest('js'))
    .pipe(rename({suffix: '.min'}))
    .pipe(uglify())
    .pipe(gulp.dest('js'));
});
...

タスクを共有するときは

git などのバージョン管理システムを利用している場合、gulpfile.js と package.json を管理しておけば npm install を実行するだけで必要なプラグインが導入されます。また、npm のインストール時に自動作成される node_modules ディレクトリ以下は管理対象外しておくと良いかもしれません。

まとめ

gulp.js のプラグイン数は Grunt に比べるとまだまだ少ないものの、基本的な機能はそろっています。またタスクの記述がシンプルであるため、わりと理解しやすかと思います。ここで紹介したプラグインはほんの一部でしたが、他にも便利なものが色々とありますので、ぜひ試してみてください!

より詳しく知りたい方へ

フェンリルのオフィシャル Twitter アカウントでは、フェンリルプロダクトの最新情報などをつぶやいています。よろしければフォローしてください!

Copyright © 2019 Fenrir Inc. All rights reserved.