watchifyとgulpで自動コンパイルと差分更新をおこなう

vuejsの開発環境を構築するでvueをビルドする環境を作成しました。

今回は開発環境をさらに便利にするために、ファイルが変更されたら自動でビルドを実行し、ブラウザをリロードする処理を実装します。

ファイルの監視とブラウザの自動更新

開発用のWEBサーバーを起動するパッケージgulp-webserverをインストールします。

npm install gulp-webserver --save-dev

前回作成したgulpfile.babel.jsを以下のように修正します。

import gulp from 'gulp';
import source from 'vinyl-source-stream';
import buffer from 'vinyl-buffer';
import webserver from 'gulp-webserver';
import browserify from 'browserify';
import babelify from 'babelify';
import vueify from 'vueify';

//デフォルトのタスク
gulp.task('default', ['build', 'webserver', 'watch']);

//開発用のWEBサーバーを起動するタスク
gulp.task('webserver', () => {
  gulp.src('./')
  .pipe(webserver({
    livereload: true,
    open: true
  }));
});

//vueをビルドするタスク
gulp.task('build', () => {
  browserify('./assets/app.js')
  .transform(babelify, { presets: ['es2015'] })
  .transform(vueify)
  .bundle()
  .pipe(source('app.js'))
  .pipe(buffer())
  .pipe(gulp.dest('./js'));
});

//ファイルを監視するタスク
gulp.task('watch', () => {
  gulp.watch('./assets/**/*', ['build']);
});

コマンドでgulpと実行するとWEBブラウザが立ち上がりlocalhost:8000が表示されると思います。

その状態で例えばApp.vueファイルを以下のように変更してみます。

<template>
  <div class="root">
    Hellow world
  </div>
</template>

<style scoped>
.root {
  --background-color: red; --修正前
  background-color: blue; --修正後
}
</style>

<script>
export default {
};
</script>

ファイルを保存すると自動でビルド処理が実行され、ブラウザが更新されると思います。

差分ビルド

ビルドを自動で行えるようになりましたが、1つのファイルを変更するたびに全てをビルドし直すと、規模が大きくなるとビルドに時間がかかってしまいます。

なので変更された部分のみ差分でビルドが行えるようにします。

差分更新を可能にするパッケージwatchifyをインストールします。

npm install watchify --save-dev

watchifyはビルド時にログを出力しないのでgulp-durationを使ってログを出力するようにします。

npm install gulp-duration --save-dev

gulp.babel.jsを以下のように変更します。

import gulp from 'gulp';
import source from 'vinyl-source-stream';
import buffer from 'vinyl-buffer';
import webserver from 'gulp-webserver';
import duration from 'gulp-duration';
import browserify from 'browserify';
import watchify from 'watchify';
import babelify from 'babelify';
import vueify from 'vueify';

gulp.task('default', ['build', 'webserver', 'watch']);

gulp.task('webserver', () => {
  gulp.src('./')
  .pipe(webserver({
    livereload: true,
    open: true
  }));
});

function buildScript (watch) {
  const props = {
    entries: ['./assets/app.js'],
    cache: {},
    packageCache: {},
    fullPaths: true
  };
  const bundler = watch ? watchify(browserify(props)) : browserify(props);
  bundler.transform(babelify, { presets: ['es2015'] });
  bundler.transform(vueify);
  function rebundle () {
    return bundler
    .bundle()
    .pipe(duration('compiled \'app.js\''))
    .pipe(source('app.js'))
    .pipe(buffer())
    .pipe(gulp.dest('./js'));
  };
  if (watch) {
    bundler.on('update', () => {
      rebundle();
    });
  }
  return rebundle();
};

gulp.task('build', () => {
  return buildScript(false);
});

gulp.task('watch', ['build'], () => {
  return buildScript(true);
});

gulpと実行すると先ほどと同様にブラウザでlocalhost:8000が起動します。

ファイルを変更すると自動でビルドが行われ、ブラウザが再読込されますが、ビルドの時間が初回時のビルドと比べて減っているのを確認できると思います。


関連記事