Gulp で Browser-Sync を動かしてブラウザにリアルタイムに変更を反映させる
前回の記事はコレ。
前回の記事で、Browserify を使って JavaScript ファイルをガッチャンコする Gulp タスクを作った。動作確認には Http-Server というパッケージを使っていたが、JavaScript のビルドは毎度 gulp build-js
(自作タスク名) というコマンドを叩かなくてはならず、HTML ファイルを修正した時もブラウザを F5 しなおさなくてはならなかった。
今回はこれらの細々した動作を完全に自動化させ、ファイルを保存すると自動的にビルドし、ブラウザを自動で更新して変更内容を反映するための環境を作る。
Browser-Sync をインストールする
ブラウザへの反映を自動化するために、Browser-Sync というパッケージを導入する。
# グローバルインストール
$ npm install --global browser-sync
# package.json に書き込みつつローカルインストール
$ npm install -D browser-sync
Browser-Sync を単体で使うこともできるようなのだが、今回は Gulp タスクに組み込んでしまおうと思う。
Gulp タスクの書き換え
これまでは、Browserify を実行する build-js
というタスクしか作っていなかった gulpfile.js
だが、ココにファイルの変更を監視するタスクと、ブラウザを更新するタスクを追加する。
/** gulpfile.js */
var gulp = require("gulp");
var browserify = require("browserify");
var source = require("vinyl-source-stream");
var browserSync = require("browser-sync"); // 今回追加したモジュール。変数名にはハイフンが使えないっぽい (後述)
/** 「gulp」コマンドを打たれた時に実行するコマンドたちを定義 */
gulp.task("default", ["watch", "build-js", "browserSync", "reload"]);
/** ファイルの更新をチェックして JS のビルド処理を呼び出す */
gulp.task("watch", () => {
// () => は function() {} のショートハンド
gulp.watch(["./src.js"], () => {
gulp.start(["build-js"]);
});
});
/** JS のビルド : src.js を main.js にビルドする */
gulp.task("build-js", () => {
browserify({
// ビルド対象ファイル
entries: ["./src.js"]
})
.bundle() // Browserify の実行
.pipe(source("main.js")) // Vinyl に変換
.pipe(gulp.dest("./")); // 出力
});
/** ブラウザ表示 */
gulp.task("browserSync", () => {
browserSync({
server: {
baseDir: "./" // サーバとなる Root ディレクトリ
}
});
// ファイルの監視 : 以下のファイルが変わったらリロード処理を呼び出す
gulp.watch("./main.js", ["reload"]); // ビルドされた JS ファイル
gulp.watch("./*.html", ["reload"]); // HTML ファイル
});
/** リロード */
gulp.task("reload", () => {
browserSync.reload();
});
少々長くなったが、これが gulpfile.js
の全量だ。
build-js
タスクの他に、default
の定義と、watch
・browserSync
・reload
を追加した。
gulp.watch()
というメソッドで、ファイルの更新を監視することができる。監視対象のファイルは *
アスタリスクでの指定も可能。
browserSync
というタスクで、Browser-Sync を使って簡易サーバを立ち上げる。そしてこのタスクからは、ブラウザをリロードするトリガーとなるファイルの変更を監視する。
というわけで、src.js
を変更した時の一連の動作の順番をまとめるとこうなる。
src.js
を書き換えて保存するwatch
タスクがファイルの変更を検知し、build-js
タスクを呼ぶbuild-js
タスクでmain.js
をビルドするmain.js
に変更が入ったことになるので、browserSync
タスクでの監視がこれを検知し、reload
タスクを呼ぶreload
タスクがブラウザをリロードする
一方、HTML ファイルを書き換えた場合は、ビルド処理がないので、直接 browserSync
タスクが変更を検知して reload
タスクを呼ぶ。
一つ注意点としては、gulpfile.js
では変数名にハイフンが使えないらしい。var browserSync
を var browser-sync
と書いていたら、以下のようなエラーが出てしまった。
/NodeJsTest/gulpfile.js:4
var browser-sync = require("browser-sync");
^
SyntaxError: Unexpected token -
Gulp タスクを動かす
gulpfile.js
ができたら、ターミナル (Windows ならコマンドプロンプトか GitBash) を開き、上の gulpfile.js
があるフォルダで gulp
コマンドを打つ。
$ gulp
すると、default
タスクに記載のタスクが実行され、Browser-Sync によってブラウザが開く。
$ gulp
[01:52:48] Using gulpfile /NodeJsTest/gulpfile.js
[01:52:48] Starting 'watch'...
[01:52:48] Finished 'watch' after 25 ms
[01:52:48] Starting 'build-js'...
[01:52:48] Finished 'build-js' after 34 ms
[01:52:48] Starting 'browserSync'...
[01:52:48] Finished 'browserSync' after 296 ms
[01:52:48] Starting 'reload'...
[BS] Reloading Browsers...
[01:52:48] Finished 'reload' after 847 μs
[01:52:48] Starting 'default'...
[01:52:48] Finished 'default' after 3.85 μs
[01:52:49] Starting 'reload'...
[BS] Reloading Browsers...
[01:52:49] Finished 'reload' after 670 μs
[BS] Access URLs:
------------------------------------
Local: http://localhost:3000
External: http://192.168.1.2:3000
------------------------------------
UI: http://localhost:3001
UI External: http://192.168.1.2:3001
------------------------------------
[BS] Serving files from: ./
ブラウザが開くと http://localhost:3000 にアクセスした状態になる。
ターミナルはそのまま置いておき、src.js
なり index.html
なりを編集すると、以下のようにタスクが自動的に実行され、ブラウザがリロードされて変更内容が自動的に反映される。
# src.js を変更して保存した直後のターミナル表示
[01:54:50] Starting 'build-js'...
[01:54:50] Finished 'build-js' after 2.89 ms
[01:54:50] Starting 'reload'...
[BS] Reloading Browsers...
[01:54:50] Finished 'reload' after 1.79 ms
gulp.watch()
を書いているタスクは表示されないが、そこが監視していて呼び出したタスクについてはターミナルに表示される。
開発を中断する時は、Ctrl + C
で gulp コマンドの動作を止めるなり、ターミナルを閉じるなりしてしまえば良い。
自身の開発環境に合わせて gulpfile.js
のタスクを修正する必要はあるものの、一度作ってしまえばある程度使い回しが利くシロモノだ。いちいちビルドタスクを動かして、ブラウザを F5 して…としなくても、完全自動で反映されるのは想像しているよりも快適だ。
今回のソースは以下にコミットしてあるので、よかったらこちらもご覧いただきたい。
参考
- 開発しやすい環境の作り方 Web系 - Qiita
- http://web-devlog.net/post/2015/08/27/072523/
- 遅すぎたgulp実践導入 (Mac編) - Qiita … gulp-webserver というパッケージを使用しているが、
gulp.watch()
に関しての内容は同じように使える