• LIGの広告成功事例
WEB

Gulp.js入門 – コーディングを10倍速くする環境を作る方法まとめ

Gulp.js入門 – コーディングを10倍速くする環境を作る方法まとめ
(編集部注*2014年9月18日に公開された記事を再編集したものです。)

先日ランサーズさん主催の「週末ランサーズ」に登壇させていただきました、フロントエンジニアのハカセです。

偶然にもTV取材が入っているという状態でハンズオンな勉強会をすることになり超緊張しました。以下がそのときのスライドです。

勉強会はハンズオンだったため、資料だけでは伝わらない内容を、今回のブログで補っていきたいと思います。

▼目次

Gulpとは

Node.jsのStreamAPIを利用したビルドシステムです。

Gruntとの違い

まとめると、以下のようになります。

Gulp Grunt
プラグインやや少ない プラグイン豊富
8,398star 8,439star
2013/6/30 2011/9/18
gulpfie.js Gruntfile.js
Nodeっぽい JavaScriptっぽい
Nodeのプラグイン Gruntのプラグイン

普通に使う分には全く困らないほどの数のプラグインがGulpにはあります。

Githubでのstar数からも明らかなように、GoogleのWenStarterKitでもGulpが採用されるなど、注目度はますます高くなっています。

Gruntとの比較

Gruntと比較してのメリット・デメリットは以下のようになります。

メリット

  • Gruntより設定ファイルが記述しやすい
  • StreamAPIを利用することでファイルを毎回書き出すGruntより高速でエコ

デメリット

  • 記述がよりNodeに近くなるため、複雑なことは敷居がやや高め
  • プラグイン開発のためのドキュメントが少ない

今日のゴール

Gulp.jsを使ってコーディング作業を10倍速くする!
そんな環境を作りたいと思います。

1. Node.jsをインストール

まずはNode.jsをインストールしましょう。

Node.js

begin-gulp-node-ss

INSTALLをクリックしてインストーラーをDLし、インストーラーを起動してインストールします。
※他にもいろいろなインストール方法がありますが、今回はもっとも簡単な方法にしました。わかる人はbrewとか使うと良いと思います。

インストールが完了したらターミナル(コマンドプロンプト: 以外、ターミナル)を起動し、以下のコマンドを実行します。

node -v

バージョン番号が表示されれば無事にインストール完了です。

npmの準備

続いて、パッケージを管理するための準備をおこないます。これにより、同じ環境をすぐに別でも構築できるようになります。

まずは任意のところにディレクトリを作成し、ターミナルで作成したディレクトリへ移動します。今回はDocuments/blogtestというディレクトリを作りました。

cd Documents/blogtest

移動したら以下のコマンドを実行します。

npm init

すると以下のように質問が続きますので、任意の値を入力します。

$ npm init
(略...

name: (blogtest) gulptest
version: (0.0.0)
description: Gulp入門用テストプロジェクト
entry point: (index.js)
test command:
git repository:
keywords: gulp,lig
author: frontainer
license: (ISC) MIT
About to write to /Users/frontainer/Documents/blogtest/package.json:

{
  "name": "gulptest",
  "version": "0.0.0",
  "description": "Gulp入門用テストプロジェクト",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "gulp",
    "lig"
  ],
  "author": "frontainer",
  "license": "MIT"
}

Is this ok? (yes) 

ただ使うだけならEnterを押すだけでOKです。これらの設定は後で変更することができます。

すべて入力するとpackage.jsonが作られ、先ほど入力内容が記載されます。

2. Gulp.jsをインストール

次にGulpをインストールしていきます。

以下のコマンドでGulpをインストールできます。

npm install gulp -g

※Macユーザの場合はroot権限での実行を求められるのでsudo npm〜としてください。

npm install gulp --save-dev

Gulpをローカルにもインストールします。

–save-devとつけることで、このパッケージを開発用パッケージとしてインストールすることができます。

package.jsonを見るとdevDependecesにGulpが記載されています。

"devDependencies": {
    "gulp": "^3.8.8"
}

package.jsonに記載されたパッケージは次回以降、npm installというコマンドを実行するだけでインストールすることができます。
package.jsonがあれば、いつでも必要なパッケージがすぐにインストールできます。

3. gulpfile.jsの作成

準備も整ったので、Gulpの設定をおこなっていきましょう。

gulpfile.jsをpackage.jsonと同じディレクトリに作成し、以下のように記述してGulpを呼び出します。

  • gulpfile.js
var gulp = require("gulp");

これでgulpを使う準備ができました。

4. Sassのコンパイル

GulpでSassのコンパイルをしてみましょう。まずは以下のSCSSファイルを作成します。

  • sass/style.scss
h1 {
  color: red;
  &:hover {
    color: blue;
  }
}

GulpでSassをコンパイルできるようにするためにプラグインをインストールします。

npm install gulp-sass --save-dev

※ gulp-sassはnode-sassを利用しているのでRubyのSassとは機能が若干異なります。Compassを使う場合はgulp-rubysassを使いましょう。その場合は別途RubyとSassのインストールが必要です。

インストールができたら、gulpfile.jsにSassをコンパイルするタスクを作っていきます。

  • gulpfile.js
var sass = require("gulp-sass");

gulp.task("sass", function() {
    gulp.src("sass/**/*scss")
        .pipe(sass())
        .pipe(gulp.dest("./css"));
});

gulp.task(“タスク名”,function() {});でタスクの登録をおこないます。

gulp.src(“MiniMatchパターン”)で読み出したいファイルを指定します。

pipe(おこないたい処理)でsrcで取得したファイルに処理を施します

gulp.dest(“出力先”)で出力先に処理を施したファイルを出力します。

MiniMatchパターン

“sass/style.scss”
sass/style.scssだけヒット

“sass/*.scss”
sassディレクトリ直下にあるscssがヒット

“sass/**/*.scss”
sassディレクトリ以下にあるすべてのscssがヒット

[“sass/**/.scss”,”!sass/sample/**/*.scss]
sass/sample以下にあるscssを除くsassディレクトリ以下のscssがヒット

gulp.src("sass/**/*scss")
        .pipe(sass())
        .pipe(gulp.dest("./css"));

ではこのタスクを実行してみましょう。以下のコマンドを実行します。

gulp sass

するとCSSディレクトリにstyle.cssが生成されました。

h1 {
  color: red; }
  h1:hover {
    color: blue; }

これでGulpを使ってSassをコンパイルできました。

5. CSSのベンダープレフィックス付与を自動化

CSS3のプロパティの中には-webkit-のようなベンダープレフィックスをつける必要があるものが存在します。
もはや必要なくなったものもありますが、それを覚えるのは大変な労力です。

そのため、たまにはこんな記述をしてしまいます。

E {
    -webkit-transform: translate(10px,0);
    -moz-transform: translate(10px,0);
    -o-transform: translate(10px,0);
    -ms-transform: translate(10px,0);
    transform: translate(10px,0);
}

確かに全てを記述すれば無難ですし、SassやCompassのmixinを使えば修正の手間もさほどかかりません。

しかし不要な記述が増えればCSSの容量も増えてしまいます。削ることができるものは削っていくようにしましょう。

ベンダープレフィックス付与を自動化するためにgulp-autoprefixerを使います。

npm install gulp-autoprefixer --save-dev

先ほど作ったstyle.scssを以下のように修正します。

  • sass/style.scss
h1 {
    color: red;
    transition: 200ms ease-out transform;
    &:hover {
        color: blue;
        transform: translate(10px,0);
  }
}

続いてgulpfile.jsにタスクを追加していきましょう。今回はpipeでautoprefixerを足すだけです。

こうして簡単にタスクを追加していけるのがGulpの良いところです。

  • gulpfile.js
var autoprefixer = require("gulp-autoprefixer");

gulp.task("sass", function() {
    gulp.src("sass/**/*scss")
        .pipe(sass())
        .pipe(autoprefixer())
        .pipe(gulp.dest("./css"));
});

では、Sassタスクをもう1度実行してみましょう。

gulp sass

さきほどのCSSが以下のようになりました。

h1 {
  color: red;
  -webkit-transition: 200ms ease-out -webkit-transform;
          transition: 200ms ease-out transform; }
  h1:hover {
    color: blue;
    -webkit-transform: translate(10px, 0);
        -ms-transform: translate(10px, 0);
            transform: translate(10px, 0); }

ベンダープレフィックスが付与されていますね。

autoprefixerはCan I useをもとにベンダープレフィックスの有無を調べて付与しています。オプションでブラウザやバージョンを指定することができるので、要件ごとにベンダープレフィックスの有無を変えることができ、柔軟性も高いのが特徴です。

ベンダープレフィックスを意識しなくて済み、タイプも減ります。

  • Can I use

6. スタイルガイド生成

CSSの保守性を高めるためにスタイルガイドを作りましょう。ジェネレータを使うことで、SassやCSSに記載されているコメントをもとにガイドを作成します。

今回はFrontNoteという手前味噌なスタイルガイドジェネレータを使いますが、StyleDoccoやKSSなど使いやすいジェネレータを使うのが良いかと思います。

・FrontNote
http://frontainer.com/frontnote/

・StyleDocco
http://jacobrask.github.io/styledocco/

・KSS
http://warpspire.com/kss/

では早速入れてみます。同じようにnpm installします。

npm install gulp-frontnote --save-dev

gulpfile.jsにタスクを追加します。今回はSassに記載したコメントをもとにガイドを作成します。

  • gulpfile.js
var frontnote = require("gulp-frontnote");

gulp.task("sass", function() {
    gulp.src("sass/**/*scss")
        .pipe(frontnote({
            css: '../css/style.css'
        }))
        .pipe(sass())
        .pipe(autoprefixer())
        .pipe(gulp.dest("./css"));
});

続いてstyle.scssにガイド作成用のコメントを記載します。

  • sass/style.scss
/*
#overview
Gulp入門サンプル

サンプルファイルです
*/

/*#styleguide
サンプル見出し1

サンプルの見出しスタイル
hoverすると青く2倍になる

```
<h1>見出し1</h1>
```
*/

ではさっそく実行してみましょう。

gulp sass

guideディレクトリができ、中にHTMLファイルのスタイルガイドが生成されました。

frontnote-ss

こうしておけば半年後、1年後の自分や途中から参加したメンバーへの共有が簡単になります。

7. JavaScriptの圧縮を自動化

続いて、読み込み時間の最適化のよくある手法の1つJavaScriptの圧縮を自動化します。

もう慣れましたね。

npm install gulp-uglify --save-dev

サンプルとしてjsディレクトリにindex.jsを作成します。

  • js/index.js
(function() {
    window.addEventListener('load', function() {
        alert('loaded');
   });
})();

続いてgulpfile.jsにタスクを追加します。

  • gulpfile.js
var uglify = require("gulp-uglify");

gulp.task("js", function() {
    gulp.src(["js/**/*.js","!js/min/**/*.js"])
        .pipe(uglify())
        .pipe(gulp.dest("./js/min"));
});

では実行してみましょう。

gulp js

jsディレクトリ内にminディレクトリができ、中に圧縮されたindex.jsが生成されます。

  • 生成されたindex.js
!function(){window.addEventListener("load",function(){alert("loaded")})}();

これで圧縮もコマンドでできるようになりました。

8. ファイルの監視

さて、ここまでは毎回コマンドを実行するたびにタスクを実行してきました。しかしそれでは面倒なので、ファイルの変更を監視し、変更されたときにタスクが実行されるようにしておきましょう。

今回はインストール不要で、gulpfile.jsにタスクを追加します。

  • gulpfile.js
gulp.task("default", function() {
    gulp.watch(["js/**/*.js","!js/min/**/*.js"],["js"]);
    gulp.watch("sass/**/*.scss",["sass"]);
});

gulp.watch([‘監視するファイルのパターン’],[‘実行したいタスク1’]);で監視するファイルと実行するタスクを指定します。

defaultという名前でtaskを作ると

gulp

とするだけでdefaultタスクを実行することができます。よく使うタスクはdefaultタスクにするといいでしょう。

実行すると監視状態になるので、このままSCSSを修正してみましょう。するとタスクが実行され、CSSが出力されます。

なお、監視状態はctrl+cで解除することができます。

9. LiveReload環境構築

タスクの自動化が済んだところで、毎回更新ボタン押すのも面倒なので、ブラウザへの反映も自動化させていきたいと思います。

今回はbrowser-syncを使用します。ファイルが変更されると画面を更新するだけでなく、スクロールやinputへの入力を全てのブラウザで同期してくれます。
ChromeをスクロールすればiPhoneで見ている方もスクロールされてしまいます。

さっそく導入してみましょう。

npm install browser-sync --save-dev

これまで通りタスクも追加しますが、今回はserver立ち上げタスクだけでなく、ファイルが変更されたらブラウザを更新するための処理をpipeで追加しています。

  • gulpfile.js
var browser = require("browser-sync");

gulp.task("server", function() {
    browser({
        server: {
            baseDir: "./"
        }
    });
});
gulp.task("js", function() {
    gulp.src(["js/**/*.js","!js/min/**/*.js"])
        .pipe(uglify())
        .pipe(gulp.dest("./js/min"))
        .pipe(browser.reload({stream:true}))
});

gulp.task("sass", function() {
    gulp.src("sass/**/*scss")
        .pipe(frontnote())
        .pipe(sass())
        .pipe(autoprefixer())
        .pipe(gulp.dest("./css"))
        .pipe(browser.reload({stream:true}))
});

gulp.task("default",['server'], function() {
    gulp.watch(["js/**/*.js","!js/min/**/*.js"],["js"]);
    gulp.watch("sass/**/*.scss",["sass"]);
});

続いてブラウザで表示するindex.htmlを作成します。

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title></title>
	<meta name="description" content="">
	<meta name="keywords" content=""/>
	<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
	<link rel="stylesheet" href="css/style.css">
</head>
<body>
    <h1>Gulp入門</h1>
</body>
</html>

ではタスクを実行してみましょう。

gulp

ブラウザが起動して、先ほど作ったindex.htmlが表示されます。
この状態でSCSSを修正してスタイルを変更してみてください。

修正直後にブラウザも更新され、スタイルが反映されます。これで毎回更新をする必要もなくなります。

CSSはSocket通信を介して差分更新(画面は更新されずCSSだけ更新)されるので、画像を多用したサイトを構築しているときにはその速度の違いに驚くと思います。

10. エラー時にwatchを止めない

これで完璧に見えますが、Gulpには1つ弱点があります。
今の状態でSCSSを誤った状態で保存すると

stream.js:94
      throw er; // Unhandled stream error in pipe.
            ^
Error: source string:24: error: invalid property name

と出て監視状態が解除されてしまいます。これではうっかりミスをする度にタスクを実行し直さなければならず、かえって面倒になってしまいます。

そこでgulp-plumberを使ってエラーハンドリングをしてあげます。

npm install gulp-plumber --save-dev

gulpfile.jsの各タスク実行前に.pipe(plumber())を実行してあげるだけです。

  • gulpfile.js
var plumber = require("gulp-plumber");

gulp.task("js", function() {
    gulp.src(["js/**/*.js","!js/min/**/*.js"])
        .pipe(plumber())
        .pipe(frontnote({
            css: '../css/style.css'
          }))
        .pipe(sass())
        .pipe(autoprefixer())
        .pipe(gulp.dest("./css"))
        .pipe(browser.reload({stream:true}));
});

gulp.task("sass", function() {
    gulp.src("sass/**/*scss")
        .pipe(plumber())
        .pipe(frontnote())
        .pipe(sass())
        .pipe(autoprefixer())
        .pipe(gulp.dest("./css"))
        .pipe(browser.reload({stream:true}))
});

タスクを実行してエラーを出してみると

[12:11:28] Plumber found unhandled error: Error in plugin 'gulp-sass'
Message:
    source string:24: error: invalid property name

エラーメッセージが表示されますが、監視状態は解除されなくなりました。

まとめ

いかがでしたでしょうか。パッケージにはオプションも数多くあるので、カスタマイズの幅はもっと広いです。
また、今回紹介したもの以外にもたくさんの便利なパッケージが存在します。
こういったパッケージを探す楽しみもありますね。

下記に一部をご紹介します。

Gruntと比べて記述がシンプルで追加しやすいGulpは、効率化のためのツールですら効率化できると思います。
ぜひGulpを使ってさらなる効率化にチャレンジしてください。

Enjoy Gulp.js!!

この記事を書いた人

先生
先生 最高技術責任者 2014年入社
CTOの林です。フロントエンドを専門とし、AngularJSのコミュニティをはじめ、様々な勉強会に顔を出しています。効率化マニアでGrunt,Gulpをはじめ、プロジェクト進行やサーバーサイド、インフラ周りの効率化を目指し日々活動しています。

こちらもおすすめ

現場のプロが教えるHTML+CSSコーディングの最新常識 知らないと困るWebデザインの新ルール4

現場のプロが教えるHTML+CSSコーディングの最新常識 知らないと困るWebデザインの新ルール4

  • 著者大竹孔明,小川裕之,高梨ギンペイ,中江 亮
  • 価格¥ 2,484(2015/11/20 11:39時点)
  • 出版日2015/03/25
  • 商品ランキング70,743位
  • 単行本192ページ
  • ISBN-104844364936
  • ISBN-139784844364931
  • 出版社エムディエヌコーポレーション