ガジェット通信

見たことのないものを見に行こう

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

DATE:
  • ガジェット通信を≫


(編集部注*2014年9月18日に公開された記事を再編集したものです。)

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

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


Gulp入門 – コーディングを10倍速くする from Hayashi Yuichi

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

Gulpとは

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

http://gulpjs.com/

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

http://nodejs.org/

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 https://www.npmjs.org/package/gulp-sass

※ 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

gulp-autoprefixer https://www.npmjs.org/package/gulp-autoprefixer

先ほど作った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

http://caniuse.com/

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

gulp-frontnote https://www.npmjs.org/package/gulp-frontnote

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ファイルのスタイルガイドが生成されました。

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

7. JavaScriptの圧縮を自動化

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

もう慣れましたね。
npm install gulp-uglify –save-dev

gulp-uglify https://www.npmjs.org/package/gulp-uglify

サンプルとして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

browser-sync https://www.npmjs.org/package/browser-sync

これまで通りタスクも追加しますが、今回は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

gulp-plumber https://www.npmjs.org/package/gulp-plumber

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

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

まとめ

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

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

gulp-htmlhint(HTML文法チェック)

gulp-htmlhint https://www.npmjs.org/package/gulp-htmlhint

gulp-jshint(JS文法チェック)

gulp-jshint https://www.npmjs.org/package/gulp-jshint

gulp.spritesmith(スプライト画像生成)

gulp.spritesmith https://www.npmjs.org/package/gulp.spritesmith

gulp-ejs(テンプレートエンジン)

gulp-ejs https://www.npmjs.org/package/gulp-ejs

gulp-ect(テンプレートエンジン)

gulp-ect https://www.npmjs.org/package/gulp-ect

gulp-sftp(SFTPアップロード)

gulp-sftp https://www.npmjs.org/package/gulp-sftp

gulp-load-tasks(タスク読み込み支援)

gulp-load-tasks https://www.npmjs.org/package/gulp-load-tasks

gulp-browserify(Browserify)

gulp-browserify https://www.npmjs.org/package/gulp-browserify

gulp-notify(通知)

gulp-notify https://www.npmjs.org/package/gulp-notify

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

Enjoy Gulp.js!!

カテゴリー : 生活・趣味 タグ :
LIGの記事一覧をみる ▶
  • 誤字を発見した方はこちらからご連絡ください。
  • ガジェット通信編集部への情報提供はこちらから
  • 記事内の筆者見解は明示のない限りガジェット通信を代表するものではありません。

TOP