fuse-box で JS を bundle する + HMR

> It is blazing fast (it takes 50-100ms to re-bundle) which makes it extremely convenient for developers. It requires zero configuration to bundle such monsters like babel-core.

> FuseBox loves typescript, and does not require any additional configuration. It will compile and bundle your code within a fraction of a second, yet offering a comprehensive loader API. It is packed with features, and unfolds limitless possibilities of extending the API.

https://github.com/fuse-box/fuse-box/tree/2cc65042dabc1cf0045e13f1a26b1a1275871059

速い、安い、うまい

## 設定ファイルの書き方

```js:fuse-build.js
const { FuseBox, BabelPlugin } = require("fuse-box")

FuseBox.init({
  homeDir: "src/",
  sourcemaps: {
    bundleReference: "./public/sourcemaps.js.map",
    outFile: "./public/sourcemaps.js.map",
  },
  outFile: "./public/bundle.js",
  plugins: [
    BabelPlugin()
  ]
// }).bundle(">index.js")
}).devServer(">index.js")
```

これを node で実行するとファイルが生成される。とくにデフォルトのファイル置き場とかない。bundle がビルド、 devServer で 開発用サーバーとHMR用のレシーバが立ち上がる。

## 実測

https://github.com/mizchi-sandbox/try-fuse-box

```
src/
├── components
│   ├── App.js
│   └── Hello.js
├── index.js
└── init.js

1 directory, 4 files
```

```
> ~/s/try-fuse-box time yarn webpack                                                                                                                                     13:41:34
yarn webpack v0.21.3
$ "/Users/mz/sandbox/try-fuse-box/node_modules/.bin/webpack"
Hash: ba44e4dd8f7c8cac667e
Version: webpack 2.4.1
Time: 1309ms
    Asset    Size  Chunks                    Chunk Names
bundle.js  740 kB       0  [emitted]  [big]  js
   [0] ./~/process/browser.js 5.3 kB {0} [built]
  [15] ./~/react/lib/ReactElement.js 11.2 kB {0} [built]
  [18] ./~/react-dom/lib/ReactReconciler.js 6.21 kB {0} [built]
  [19] ./~/react/lib/React.js 3.32 kB {0} [built]
  [31] ./~/react/lib/canDefineProperty.js 661 bytes {0} [built]
  [81] ./~/fuse-box/modules/fuse-hmr/index.js 2.11 kB {0} [built]
  [82] ./~/react-dom/index.js 59 bytes {0} [built]
  [83] ./~/react/react.js 56 bytes {0} [built]
  [84] ./src/index.js 859 bytes {0} [built]
  [99] ./~/fuse-box/modules/fuse-loader/index.js 203 bytes {0} [built]
 [115] ./~/react-dom/lib/ReactDOM.js 5.14 kB {0} [built]
 [176] ./~/react/lib/ReactDOMFactories.js 5.53 kB {0} [built]
 [177] ./~/react/lib/ReactPropTypes.js 500 bytes {0} [built]
 [179] ./~/react/lib/ReactPureComponent.js 1.32 kB {0} [built]
 [180] ./~/react/lib/ReactVersion.js 350 bytes {0} [built]
    + 170 hidden modules
✨  Done in 1.83s.
        2.03 real         2.17 user         0.18 sys
⋊> ~/s/try-fuse-box time node fuse-build.js                                                                                                                               13:41:43
└── default (2 files,  1.3 kB)
      index.js
      components/Hello.js
└── react (26 files) 106.7 kB
└── object-assign (1 files) 2.2 kB
└── fbjs (23 files) 33.6 kB
└── process (1 files) 3 kB
└── object-assign-polyfill (1 files) 1 kB
└── prop-types (4 files) 22 kB
└── react-dom (126 files) 552.1 kB
└── fuse-box (2 files) 2.6 kB

    Bundle
    Size: 724.6 kB
    Time: 949ms
        1.27 real         1.29 user         0.13 sys
```

Webpackに比べて 60% ぐらい速い。

## HMR

デフォルトで組み込まれてる

```js:src/index.js
/* @flow */
import './init'
import React from 'react'
import ReactDOM from 'react-dom'
import App from './components/App'

ReactDOM.render(
  <App/>,
  document.querySelector('main')
)

// HMR
import {setStatefulModules} from 'fuse-box/modules/fuse-hmr'
setStatefulModules(name => {
  return /init\.js/.test(name)
})
```

ファイルを変更すると、そのファイルの依存ツリーがきて、コールバックで名前に関してtrue が来るとリロードする。ここではinit.js が来たらリロードする、という書き方。

後発だけにこの辺は整ってる。

## 個人の感想

Webpackなんでもできすぎて割れ窓なので、多少機能を絞ってでも速度に注力するのは良いと思う。趣味プロジェクトではこっちを使っていこうと思った。

## 参考

- http://fuse-box.org
- https://medium.com/@basarat/rethinking-hot-module-reloading-58ce15b5f496