Vue.jsを触っていたときに、componentに指定するtemplateでhtmlファイルを直接requireしたいと感じた。こんなときがbrowserifyの使いどころ(?)だと思ったはなし。
...
// template: <div>Hello!</div>ではなくて
// 下みたいな感じにファイル名指定でテンプレートをrequireしたい
var components = {
root: Vue.extend({
template: require("./main.html")
}),
entrance: Vue.extend({
template: require("./entrance.html")
})
};
...
いろいろ調べたところ、stringifyというパッケージを使うとコンポーネントのテンプレートへ渡すために文字列化したhtmlをjsファイルにbundleすることができて、結果requireできるようになるらしい。
Gulpfile
自分のプロジェクトでは下のような感じでjs/
ディレクトリ以下に入っているソースを一旦application.js
にまとめてdist/
ディレクトリに放り込んでいる。
var targets = [
...
js: [
"./js/*.js",
"./js/**/*.js"
],
...
]
var concatJS = "application.js"
var destDir = "./dest/";
...
gulp.task("concat-js", function() {
return gulp.src(targets.js)
.pipe(plumber())
.pipe(concat(concatJS))
.pipe(gulp.dest(destDir))
});
...
テンプレートエンジンにはjadeを使っているのでもちろんjadeをトランスパイルするタスクもある
var targets = [
...
jade: [
"./jade/*.jade",
"./jade/**/*.jade",
"./jade/**/_*.jade"
],
...
]
...
gulp.task("jade", function() {
return gulp.src(targets.jade)
.pipe(plumber())
.pipe(jade({
pretty: true
}))
.pipe(gulp.dest(destDir))
});
つまりjadeのタスクが終わるときにはjsのタスクで生成されるapplication.js
と同じdest/
以下にhtmlファイルがjadeファイルと同じ数だけ生成されることになっている。
さて、こういう環境を前提にした上でのbrowserifyのタスクがこちら。
...
var stringify = require("stringify");
var browserify = require("browserify");
var source = require("vinyl-source-stream");
...
gulp.task("browserify", function() {
return browserify({
entries: [destDir + concatJS]
})
.transform(stringify([".html"]))
.bundle()
.pipe(source(concatJS))
.pipe(gulp.dest(destDir))
});
stringifyはテキストファイルなどをrequireできるようにしてくれるパッケージで、.html
以外にも何でもいけるとのこと。ちなみにminifyオプションやらrequireするときの拡張子を省くextensionsオプションやら、stringifyにはいろいろあるらしいのでnpmのページを見に行くとよさそう(https://www.npmjs.com/package/stringify)
ファイルパスの指定はなにが何なのか一瞬混乱したけれど、とりあえずはentries: [...]
へ指定したファイルにbrowserifyが適用されてsource(...)
へ出て行くみたいな、そんな感じ。(ちなみにentriesにはワイルドカード指定ができなかった)
まとめ
ここまでやって生成されたapplication.jsを開いてみると、ソースの中にhtmlの中身がstringify(文字列化)されたものが埋め込まれているのがわかる。requireするファイルがソースの中に埋め込まれているってのは若干不思議な気がしたけれど、今回のケースではbrowserifyがgulpのタスクとして予めrequireをパースして処理していると考えれば、requireは実際はただのマークみたいなものだと考えていいのかもしれないと思った。