Gulp + browserify + watchify + gulp-sass で自動高速コンパイル環境

Gulp とは

Gulp は Web 制作に関するいろいろな作業を自動化するためのツールです。Sass のコンパイルや Gulp の使用には node.js や Sass などのインストールが必要なので、ちょっと古い記事ですが下記を参考に適当にインストールしてみてください。

browserify とは

browserify

そんなに詳しくないのですが、browserify はざっくりと言えば js で requireを使えるようにするためのツールです。今までであれば複数の js ファイルが必要な場合、例えば、a.js と、a.js がないと動かないb.js を読み込む場合だと、HTML ファイルに下記のような記述が必要でした。

// index.html
<script src=".js/a.js"></script>
<script src=".js/b.js"></script>

browserify を使えば、次のように書くことができます。

// b.js
var a = require( './a.js' );
return a();

これで b.js をコンパイルすれば a.js と b.js が合体した1つの js ファイルが生成されます。js ファイルを複数読み込むと表示が遅くなるので、1つにまとめることで高速化することが可能です。

watchify とは

Gulp にはwatchというモジュールがあり、これを使って特定のファイルが変更されたときに自動的にコンパイルを行うことができますが、browserify で扱う js ファイルが多くなってくるとコンパイルに時間がかかるようになってきます。watchifyは変更された差分でコンパイルできるものです。そのためコンパイルにかかる時間をかなり短縮することができ、快適に開発を行うことができます。

ファイル構成

次のようなファイル構成を想定しています。

/ 作業ディレクトリ
 - gulpfile.js
 - /bootstrap ( Sass版のBootstrap )
 - /src
    - /js
       - app.js
       - jquery.js とか
    - /scss
       - style.scss
       - _hoge.scss
 - /js
    - app.js ( 自動で書き出される )
 - /css
    - style.css ( 自動で書き出される )
 - index.html

Bootstrap をよく使うので、メインの scss ファイル(style.scss)から Bootstrap を import して使うようにしています。

@import 'bootstrap';

#header {
    ....
}

インストール

Gulp、browserify、watchify をインストールします。

# グローバルに Gulp、browserify、watchify をインストール
$ sudo npm install -g gulp browserify watchify

次に、Gulp を実行させたいディレクトリ(作業ディレクトリ)に移動し、必要なモジュールをインストールします。

# 作業ディレクトリに Gulp をインストール
$ npm install --save-dev gulp gulp-watch gulp-sass gulp-ruby-sass browserify gulp-uglify vinyl-source-stream vinyl-buffer

gulp-ruby-sassのインストールは本来は不要ですが、速度を比較するために一応いれています。
※また、本当はここで watchify も入れたいのですけど、なぜか watchify じゃなくて gulp-watchify をいれようとしてきて、これだと browserify のバージョンがあわなくてエラーになっちゃうので外しています。一応グローバルにはインストールしているので動作は問題ありません。

gulpfile.js の作成

gulpで実行させたいもろもろは、gulpfile.jsに記述します。下記の内容で作業ディレクトリに gulpfile.js を作成します。

/**************************************************
 * modules laod
 *************************************************/
var gulp       = require( 'gulp' );
var watch      = require( 'gulp-watch' );
var sass       = require( 'gulp-sass' );
var rubysass   = require( 'gulp-ruby-sass' );
var browserify = require( 'browserify' );
var watchify   = require( 'watchify' );
var uglify     = require( 'gulp-uglify' );
var source     = require( 'vinyl-source-stream' );
var buffer     = require( 'vinyl-buffer' );

/**************************************************
 * path
 *************************************************/
var cssSrcPath        = './src/scss';
var cssDestPath       = './css';
var jsSrcPath         = './src/js';
var jsDestPath        = './js';
var scssPath          = './src/scss';
var bootstrapScssPath = './bootstrap/assets/stylesheets';

/**************************************************
 * tasks
 *************************************************/
/**
 * sass
 */
gulp.task( 'sass', function() {
	return gulp.src( cssSrcPath + '/*.scss' )
		.pipe( sass( {
			outputStyle : 'compressed',
			includePaths: [

				cssSrcPath,

				bootstrapScssPath

			]
		} ) )
		.pipe( gulp.dest( cssDestPath ) );
} );

/**
 * rubysass
 */
gulp.task( 'rubysass', function() {
	return rubysass( cssSrcPath, {
			style   : 'compressed',

			loadPath: [

				cssSrcPath,

				bootstrapScssPath

			]
		} )
		.pipe( gulp.dest( cssDestPath ) );
} );

/**
 * browserify
 */
gulp.task( 'browserify', function() {
	return jscompile( false );
} );

/**
 * watchify
 */
gulp.task( 'watchify', function() {
	return jscompile( true );
} );

function jscompile( is_watch ) {
	var bundler;
	if ( is_watch ) {
		bundler = watchify( browserify( jsSrcPath + '/app.js' ) );
	} else {
		bundler = browserify( jsSrcPath + '/app.js' );
	}

	function rebundle() {
		return bundler
			.bundle()
			.pipe( source( 'app.js' ) )
			.pipe( buffer() )
			.pipe( uglify() )
			.pipe( gulp.dest( jsDestPath ) );
	}
	bundler.on( 'update', function() {
		rebundle();
	} );
	bundler.on( 'log', function( message ) {
		console.log( message );
	} );
	return rebundle();
}

/**
 * watch
 */
gulp.task( 'watch', ['sass', 'watchify'], function() {
	gulp.watch( scssPath + '/*.scss', ['sass'] );
} );

実行してみる

gulpfile.js を作成できたら、コンソールで実行してみましょう。

# /src/js/app.js のコンパイル
gulp browserify

# /src/scss/style.scss のコンパイル ( gulp-sass )
gulp sass

# /src/scss/style.scss のコンパイル ( gulp-ruby-sass )
gulp rubysass

# scss、js に変更があったら自動的にコンパイル
gulp watch

コンパイル時間など

もともと watch + browserify + ruby-sass でやっていたのを watchify + browserify + sass の構成に変えたのですが、平均すると下記のような感じでコンパイル時間が短縮されました。

js のコンパイル
browserify 10s -> watchify 1.1s

scss のコンパイル
rubysass 2.8s -> sass 500ms

  • ブックマーク
  • Feedly

この記事を書いた人

キタジマタカシ

長崎在住、フリーランスのWordPress テーマ / プラグインデベロッパー。 多数のプロダクトをオープンソースで開発・公開しています。現在は WordPress 有料テーマ Snow Monkey を開発・販売しています。