LoginSignup
2
3

More than 5 years have passed since last update.

Browserify & ReactでCSS in JS対応のHot Module Replacement

Last updated at Posted at 2016-10-11

webpackの提供するHot Module Replacement(HMR)のBrowserifyでの対応についてです。

HMRの対応にbrowserify-hmr
CSS in JSのライブラリとしてAphrodite
それとは別に、従来のCSSで記述する方法としてcssify
をそれぞれ利用しています。

サンプルプロジェクトのGitHubはこちらです

操作画面

こちらはbrowserify-hmrによるJSとCSS編集画面です
hmr-navidate.gif

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使用時の検証がまだ出来ていないためです。

browserify-postcss/browser.js
module.exports = require('cssify')
browserify-postcss/index.js
// パッチ
     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のライブラリ選定とか所感とか

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3