ビルドシステム gulp を試してみる【すぐに動かせるサンプル付き】
こんにちは!スタッフのめぐみです。
今回は私が Web 制作の際に使用している gulp というビルドシステムの紹介をしたいと思います。
タイトルの通り gulp を試してみよう!ということで、用意したサンプルを使って実際に手を動かしながら記事を読み進めてみてください。
※ この記事では sass (ver 3.1 以上)がすでにインストールされているものとして話を進めますので、ご留意下さい。
gulp とは
gulp は Node.js をベースにした、 Sass のコンパイルや js ファイルの結合・圧縮などを自動化してくれるビルドシステム(ツール)です。同じようなものに Grunt があり、タスクの記述の仕方が違いますができることはほとんど同じです。gulp の場合、必要なタスクはgulpfile.jsに記述します。
ちなみに、 Node.js についての説明は割愛します。以下の記事や公式サイトが詳しいのでそちらを参考にしてください。
gulp を動かすための準備
- Node.js のインストール
- gulp のインストール
- サンプルファイルのダウンロード
1. Node.js のインストール
- Mac の方
Homebrew でインストールします。
ターミナルを立ち上げて、以下のコマンドを入力しましょう。$ brew install node - Windows の方
Node.js のサイトから、インストーラをダウンロードして Node.js をインストールしてください。
2. gulp のインストール
-
以下のコマンドを入力します。
$ npm install --global gulpお使いの環境によっては
sudoを冒頭につける必要があります。もし上記のコマンドででうまくいかない場合は、sudoをつけてコマンドを再入力してみてください。 -
$ gulp -vと入力し、[01:23:28] CLI version 3.8.10 [01:23:28] Local version undefined
のような表示が出ればひとまず OK です。
3. サンプルファイルのダウンロード
サンプルファイルは GitHub のリポジトリにあげてあるので、
$ git clone git@github.com:featherplain/gulp-sample.git
もしくは
zip ファイルでダウンロードしてください。
gulp を動かしてみよう
初期状態のディレクトリ構成
.
├── README.md
├── gulpfile.js
├── index.html
├── package.json
└── src
├── img
│ └── sprite
│ ├── icon_star-red.png
│ ├── icon_star-yellow.png
│ └── icon_star_blue.png
├── js
│ └── lib
│ ├── jquery.bxslider.js
│ └── jquery.magnific-popup.js
└── scss
├── core
│ ├── _config.scss
│ ├── _mixins.scss
│ └── _normalize.scss
├── layout
│ ├── _layout-common.scss
│ ├── _layout-footer.scss
│ └── _layout-header.scss
├── module
│ ├── _module-buttons.scss
│ └── _module-sprite.scss
└── style.scss
このサンプルでできるタスク
- sass のコンパイル (+ sass-globbing)
- js ファイルの圧縮・結合
- css sprite 画像の生成
- ファイル更新でブラウザを自動リロード(BrowserSync を使っています)
使用プラグイン一覧
- BrowserSync※
- gulp-autoprefixer
- gulp-concat
- gulp-plumber
- gulp-rename
- gulp-ruby-sass
- gulp.spritesmith
- gulp-uglify
※ BrowserSync は、単体でも動くので正確に言うと gulp のプラグインではありませんが、便宜的にまとめてリストアップしています。
gulp の実行
$ cdでサンプルをダウンロードしたディレクトリに移動します。$ npm installと入力して、タスクを実行するために必要な gulp のプラグインをインストールします。$ gem install sass-globbingで sass-globbing(説明は後述) をインストールします。-
$ gulpと入力すると、ターミナルの画面が以下のようになり、ローカルサーバーが立ち上がります。
解説
gulp 実行後のディレクトリ構成
.
├── README.md
├── dist
│ ├── css
│ │ └── style.css
│ ├── img
│ │ └── sprite.png
│ └── js
│ └── lib.min.js
├── gulpfile.js
├── index.html
├── node_modules
├── package.json
└── src
├── img
│ └── sprite
│ ├── icon_star-red.png
│ ├── icon_star-yellow.png
│ └── icon_star_blue.png
├── js
│ └── lib
│ ├── jquery.bxslider.js
│ └── jquery.magnific-popup.js
└── scss
├── core
│ ├── _config.scss
│ ├── _mixins.scss
│ └── _normalize.scss
├── layout
│ ├── _layout-common.scss
│ ├── _layout-footer.scss
│ └── _layout-header.scss
├── module
│ ├── _module-buttons.scss
│ └── _module-sprite.scss
└── style.scss
このgulpfile.jsには、src以下で開発を行い最適化した css ファイル、 js ファイル、スプライト画像をdist以下に格納されるようにタスクとして記述しています。
Node.js のパッケージを管理するpackage.jsonに、gulp 拡張のためのプラグインが記述されています。先ほど$ npm install とコマンドを入力して gulp のプラグインをまとめてインストールできたのは、npm が package.jsonの記述に従ってプラグインをインストールしてくれるからです。
npm についても Node.js と同様に説明は省略しますが、以下のサイトや記事を参考にしてみてください。
プラグインの読み込み
var gulp = require('gulp'),
autoprefixer = require('gulp-autoprefixer'),
browserSync = require('browser-sync'),
concat = require('gulp-concat'),
plumber = require('gulp-plumber'),
reload = browserSync.reload,
rename = require('gulp-rename'),
rubySass = require('gulp-ruby-sass'),
sprite = require('gulp.spritesmith'),
uglify = require('gulp-uglify')
;
gulpfile の冒頭では、 gulp のプラグインをこのようにしてまとめて読み込んでいます。
パスの変数化
var paths = {
'dest' : './',
'vhost' : 'example.dev',
'port' : 3000,
// html
'htmlDest' : './',
'htmlFiles' : './*.html',
// images
'imgDest' : 'dist/img',
'imgDir' : 'src/img',
// js
'jsFiles' : 'src/js/**/*.js',
'jsDest' : 'dist/js',
// scss
'scssDest' : 'src/scss',
'scssFiles' : 'src/scss/**/*.scss',
// css
'cssDest' : 'dist/css'
}
タスク実行のために読み込むファイルやディレクトリのパスも、ここでまとめて定義しておきます。こうしておくとディレクトリ構成が変わっても変更箇所が一箇所で済むので楽です。
BrowserSync
// Local server
// gulp.task('browser-sync', function() {
// browserSync({
// proxy: paths.vhost,
// open: 'external'
// });
// });
// Static server
gulp.task('browser-sync', function() {
browserSync({
server: {
baseDir: paths.dest // ベースディレクトリ
},
startPath: paths.htmlDest // ブラウザに立ち上げるディレクトリの場所を指定
});
});
// Reload all browsers
gulp.task('bs-reload', function() {
browserSync.reload()
});
BrowserSync は、その名の通り「ブラウザを同期」してくれるもので、ファイルを編集・保存すると、更新内容がブラウザにリアルタイムに反映されます。
もし WordPress のテーマ開発等で別のローカルサーバと BrowserSync を使用する場合は、// Local serverの方のコメントアウトを解除してください。23行目のvhostにはローカルサーバのホスト名や IP アドレスを入力するとよいでしょう。
sprite 画像の生成
gulp.task('sprite', function() {
var spriteData = gulp.src(paths.imgDir + '/sprite/*.png') // 読み込みたい画像を定義
.pipe(sprite({
imgName: 'sprite.png', // 画像生成後の名前
imgPath: '/' + paths.imgDest + '/sprite.png', // スプライト画像のパス
cssName: '_module-sprite.scss' // スプライト用の scss ファイルの生成
}));
spriteData.img.pipe(gulp.dest(paths.imgDest)); // スプライト画像の出力先
spriteData.css.pipe(gulp.dest(paths.scssDest + '/module')); // スプライト用の scss ファイルの出力先
});
js ファイルの結合・圧縮
gulp.task('jsLib', function() {
return gulp.src(paths.jsFiles) // 読み込む js ファイルを定義
.pipe(concat('lib.js')) // js ファイルを結合
.pipe(uglify()) // 結合した js ファイルを圧縮
.pipe(rename({ suffix: '.min' })) // 圧縮したファイルに '.min' を付与
.pipe(gulp.dest(paths.jsDest)) // 最適化した js ファイルを dist/js へ出力
.pipe(browserSync.reload({ stream: true })); // ファイルの更新を自動リロード
});
sass のコンパイル
gulp.task('rubySass', function () {
gulp.src(paths.scssFiles) // 読み込む scss ファイルを定義
.pipe(plumber()) // エラーを吐いてもタスクを終了させない
.pipe(rubySass({ // sass のコンパイルの実行
r: 'sass-globbing', // sass-globbing 利用オプション
'sourcemap=none': true // ソースマップを生成しない
}))
.pipe(autoprefixer("last 2 version")) // ベンダープレフィックスの自動付与
.pipe(gulp.dest(paths.cssDest)) // コンパイル・最適化した css ファイルを dist/css へ出力
.pipe(reload({ stream: true })); // ファイルの更新を自動リロード
});
gulp-autoprefixer は、オプションでターゲットにするブラウザを指定することが出来ます。ここではlast 2 versionとしていますが、こちらのドキュメントを参考にして、必要に応じて変えてみてください。
sass-globbing について
sass-globbing とは、sass4.0 で実装予定の glob 機能で、sass3.1 以上で先取りして使えます。
サンプルのstyle.scssには以下の様な記述をしていますが、
// ======================================== // modules // ======================================== @import 'modules/*.*'; // ======================================== // layouts // ======================================== @import 'layout/*.*';
本来ならファイル名が増える毎に追加の記述をしたり、減れば減った分だけ@importの記述を削除しなければいけませんでした。しかし上記のように”*(アスタリスク)”でファイルを読み込むようにすることで、ファイルが増えても減っても記述の修正をいちいちする必要がなくなりました。
watch タスク
gulp.task('watch', function() {
gulp.watch([paths.imgDest + '/sprite/*.png'], ['sprite']);
gulp.watch([paths.htmlFiles], ['bs-reload']);
gulp.watch([paths.jsDest], ['jsLib']);
gulp.watch([paths.scssFiles], ['rubySass']);
});
// watch タスクに監視したいタスクを登録
gulp.task('default', [
'browser-sync',
'bs-reload',
'jsLib',
'rubySass',
'sprite',
'watch'
]);
// default というタスクを新たに定義し、すべてのタスクを一括で実行できるようにする
いかがでしたでしょうか?
https://github.com/featherplain/gulp-sample からサンプルを入手できますので、gulp に興味のある方は、是非試してみてくださいね!
動作検証のチェックは行っていますが、万が一バグ等ございましたら GitHub の issue で報告してください。
それではまた!