gulp.watch()でpugのコンパイルをしない方法

前回のポストの続きです。

gulp-changedを使って変更のあったテンプレートのみコンパイルする方法では、include元のファイルに変更が合った場合に、include先のpugファイルに変更が伝わらない問題がありました。

今回は、この問題を解決(回避)する方法を紹介します。

解決したい問題

一般的なGulpタスクのように、

  1. 1. ファイルの変更を検知
  2. 2. src/**/*.pugを全て再コンパイル
  3. 3. browserSyncをリロード

 

のような流れでタスクを書くと…pugファイルが増えた時、2.のコンパイルに時間がかかり、リロードがなかなかされなくなります。
数秒〜数十秒にもなると開発どころではありません。。

pugのlayoutincludeといった機能を使っていると、「どのファイルがどのファイルをインクルードしているか」が分からないため、全てのファイルを再コンパイルする必要があり、この問題を解決する事がどうにも難しいようです。

そこで、コンパイルした静的なHTMLをホストするのではなく、PHPなどと同様に動的に、リクエストに対してHTMLを生成すれば良いのでは…?と思いmiddleware化する事でこれを実現しました。

コンパイルはbrowserSyncのmiddlewareを使う

browserSyncは内部的にconnectが採用されているので、同様のインタフェースでmiddlewareを定義できます。

middlewareを作る

やりたい事は、HTMLへのリクエストに対してpugのコンパイル結果を返すだけなので、1つ関数定義するだけで実現できました。
(gulp-dataなどでデータを渡している場合、もう一手間必要です。)

browserSyncにmiddlewareを渡す

あとは、このmiddlewareをbrowserSyncのmiddlewareとして渡してあげれば完了です。

gulp.watch()

コンパイルはリクエストを受けた時点で行うので、ファイルの変更を検知したらリロードするだけでOKです。 これで、コンパルの待ち時間は実質0秒になりました!

 

さいごに

この方法ならpugにかぎらず、どんなテンプレートエンジンでも同じ方法でコンパイルを最小限に抑えることができます。

ただあくまでも、browserSyncなどを使った開発時に有効な手段のため、最終書き出し時にはある程度時間がかかります。
libsassの様にpugが高速化される事を期待したいところです。

●この記事を書いた人