lib = require './lib'console.log lib.data
lib.printSelf()
counter = 0
setInterval ->
counter += 1
console.log counter
, 2000
if module.hot
module.hot.accept './lib', ->
lib = require './lib'
console.log lib.data
lib.printSelf()
跑一跑 Demo, 就知道效果怎么样了, setInterval 不受替换的干扰
而在 build/ 目录, 每次修改都会生成一个 JSON 文件记录修改的内容:
➤➤ l build/
0.1dadeb2eb7b01e150126.hot-update.js 0.c1d0d73de39660806d0c.hot-update.js 2849b61a15d31ffe5e08.hot-update.json 0.99ea3ea7633f6b3750e6.hot-update.js 0.eaa7b323eba37ae58997.hot-update.js 9b4a5ad617ec1dbc48a3.hot-update.json fb584971920454f9ccbe.hot-update.json
0.9abf25005c61357a0ce5.hot-update.js 0.fb584971920454f9ccbe.hot-update.js a664b5851a99ac0865ca.hot-update.json
0.9b4a5ad617ec1dbc48a3.hot-update.js 1dadeb2eb7b01e150126.hot-update.json bundle.js
0.a664b5851a99ac0865ca.hot-update.js 256267122c6d325755b0.hot-update.json c1d0d73de39660806d0c.hot-update.json
具体的文件内容也就是这样, 大致可以认为包含了识别更新所需的信息:
➤➤ cat build/0.c797c084381bfeac37f7.hot-update.js
exports.id = 0;
exports.modules = {/***/ 3:
/***/ function(module, exports, __webpack_require__) {
var counter, lib;
lib = __webpack_require__(4);
console.log(lib.data);
lib.printSelf();
counter = 0;
setInterval(function() {
counter += 1;
return console.log(counter, 3);
}, 2000);
if (true) {
module.hot.accept(4, function() {
lib = __webpack_require__(4);
console.log(lib.data);
return lib.printSelf();
});
}
/***/ }
};
其他方案
白天在网上查找方案, 顺便在论坛上发了个帖子问这个事情,现成的主要两个说明比较清楚的方案, 值得借鉴一下
一个是百度的技术博客上, 写的大概是怎么对 module 对象做处理,也就是手工监听文件修改, 然后清楚模块缓存, 重新挂载模块
思路清晰考虑细致, 虽然有点冗余代码, 还是可以一试:
//www.jb51.net/article/73739.htm
另一个似乎是对 require.extensions 做了 hack, 增加了操作和事件,当模块文件更新时, 对应模块自动更新, 并且 emit 一个事件,通过这样的效果, 模块引用的位置可以做一些处理, 使用新的代码,这个应该说还是比较粗暴的, 毕竟不是所有的代码都容易替换
https://github.com/rlidwka/node-hotswap
感想
考虑到我已经在 Webpack 这棵树上吊死, 也就不打算深入研究了,也许 Node.js 官方对 lib/module.js 做下优化能搞出不错的功能来,然而, JavaScript 毕竟不是不可变数据使用成风的社区, 比不了 Erlang,因为代码替换就涉及到状态更新的问题, 不好搞, 不如重启来得省事,而重启现在有 node-dev supervisor nodemon 三套方案任你选









