この記事では、Browserifyとwebpackのビルドにmakefileを用い、依存関係に対応させてソース未編集時の不要な再バンドルをしない方法を紹介します。
makeはGNU Makeを利用しています。
なお、実用性を見出せないので9割程ネタです、こんな事も出来た程度で紹介します。
依存関係ファイルの取得方法
不要な再バンドルをさせない為には、バンドルファイルと依存関係のあるファイル(ソースファイル一式)が必要です、make時にこれらのtimestampを比較し、依存関係のあるファイルの方が新しければ再バンドルが必要と判断されて実行されます。
C++では
古来より一般的なのがC・C++で-MMオプションを使って依存関係を取得し、dependファイルとして出力する方法です。
#include "foo.h"
int main() {}
からは
$ gcc -MM main.cpp
main.o: main.cpp foo.h
という依存関係が取得できます、これを全.cppから取得すれば、各.cpp・h編集時に必要な.oだけリコンパイルされます。
Browserify・webpackでは
ビルド後は成果物であるbundle.jsが直接出力されるので、それとの依存関係である.(t|j)s[x]一覧が必要です。
ソースディレクトリ内一覧を指定しても良いですが、ここでは必要な依存関係のあるファイルを取得して指定させます。
Browserifyの場合
依存関係の取得には、module-depsを使います。
$ module-deps index.js
と実行すると必要なソースファイル・モジュールファイル情報がJSONとして出力されます、このJSONからファイルパス部分をパースすれば依存関係として利用できます。
ファイルパスはkey"file"に格納されています。
[
...
"file":"ここのファイルパス"
...
]
取得にはUNIXコマンドを利用します、
# json出力 | "file":".."部分を取り出す | ファイルパス部分を取り出す
$ module-deps index.js | grep -o '"file":"[^"]*"' | sed -e 's/.*:"\([^"]*\)"/ \1/g'
とすれば取得出来ますので、これをC・C++のdependファイルと同じフォーマットへと整えます。
bundle.js: 依存関係一覧
webpackの場合
webpackの場合はwebpackにJSON出力用のオプションを指定します。
$ webpack --json
webpackのJSONでは、ファイルパスはkey"identifier"に格納されています。
[
...
"chunks": [
...
"identifier": "ここのファイルパス",
...
]
...
"modules": [
...
"identifier": "ここのファイルパス",
...
]
]
webpackもUNIXコマンドにて
# json出力 | "file":".."部分を取り出す | ファイルパス部分を取り出す
$ webpack --json | grep -o '"identifier":[^"]*"[^"]*"' | sed -e 's/.*: "\([^"]*\)"/ \1/g'
と取得出来ますので、こちらもC・C++のdependファイルと同じフォーマットへと整えます。
bundle.js: 依存関係一覧
make
上記の依存関係ファイル作成をdependタスクとしてmakefileへ登録・実行すれば、make時に必要時だけビルドされるようになります。
$ make depend
create depend file
$ make
browserify -o bundle.js index.js
$ make
make: Nothing to be done for 'all'.
で、なんに使えるの?
僕にも分かりません(やってみたかっただけ!)。
フロントエンドのビルドなんて時間のかかるものでもないし、CIツールに導入して必要時だけ発火させるとかでしょうか、それでもbundleファイルをtrimしてhash値比較した方が確実だろうし、やっぱ使い道ないかも。
参考
JavaScriptライブラリ/プロジェクトのファイルサイズの問題点を見つける方法#webpackを使っているプロジェクトで依存ツリーを見る