webpackの提供するHot Module Replacement(HMR)のBrowserifyでの対応についてです。
HMRの対応にbrowserify-hmr、
CSS in JSのライブラリとしてAphrodite、
それとは別に、従来のCSSで記述する方法としてcssify
をそれぞれ利用しています。
操作画面
こちらはbrowserify-hmrによるJSとCSS編集画面です
HMR対応について
.jsx内のHTMLタグは、browserify-hmrにより対応しています、内部でreact-transform-hmrが動いており、それがHMRへの導線となっています、それと、操作画面には映ってないですが「Hello, world!」はjadeテンプレートで書いています、こちらもHMRの対象になっています。
CSSへの対応ですが、cssifyはCSSファイルをJSコードへと埋め込んでおり、それによりHMRの対象に出来ているようです、仕組みまで詳しく終えてませんが、JSコード化出来ている為にそれもHMR対象として拾ってくれてるのだと推測しています。
CSS in JS(Aphrodite)は最初からJSで完結してる為、仕組み的にはcssifyの時よりも分かりやすいかと思います(内部実装は難しいですが)。
CSS Modulesは?
CSS Modulesライブラリは、CSSを別途bundle.cssファイルとして出力する為か、HMRの対象に出来なかった為この記事では扱っていません。
Sass対応は?
sassifyやscssifyがあるのですが、それぞれ以下の理由で没となりました。
sassify
HMRの対象にはなるんですが、styleの削除をしても以前の設定が残ったままとなる為、惜しいですが扱うのをやめにしました。
なお、利用の際は、cssifyと違いautoInjectがデフォルトでfalseの為、transformに渡す際にtrueを設定します。
$ browserify -p browserify-hmr -t [sassify --auto-inject true]
scssify
sassifyと同じくstyleの削除をしても以前の設定が残ったままとなります。
postcss対応は?
2016/12/29追記
browserify-postcssにこのパッチ(Gist)を施せば対応できます。
パッチの内容はcssifyと同じで、cssに対応した一意な名前(cssへのフルパスのハッシュ値)を与え、hmrに対応しているcssifyに丸投げをしています。
PRを送っていないのは、postcss-import使用時の検証がまだ出来ていないためです。
module.exports = require('cssify')
// パッチ
processor.process(body, postCssOptions)
.then(function (result) {
- self.push(moduleify(result.css, opts.inject))
+ self.push(moduleify(result.opts.to, result.css, opts.inject))
done()
}, function (err) {
// 新規コード
function hash (str) {
return '_' + stringHash(str).toString(36)
}
function moduleify(toName, css, inject) {
var exp
if (inject === 'base64') {
exp = 'module.exports = require("' + path.basename(path.dirname(__dirname)) + '").byUrl("' + base64(css) + '")'
} else if (inject) {
// cssifyと同じ方法
// NOTE : ブラウザ環境ではbrowser.jsがrequireされる(cssifyと同じロジックになる)
exp = [
"var inject = require('browserify-postcss');",
"var css = '" + css.replace(/'/gm, "\\'").replace(/\n/gm, ' ') + "';",
"inject(css, undefined, '" + hash(toName) + "');",
"module.exports = css;",
].join('\n');
} else {
exp = 'module.exports = ' + JSON.stringify(css)
}
return exp
}
参考
GitHub: revathskumar/browserify-hmr-example
Hot Module Replacementの設定と仕組みを理解する
Reactと一緒に使う時のCSS in JSのライブラリ選定とか所感とか