Hot Module Replacement(以下简称 HMR)是 webpack 发展至今引入的最令人兴奋的特性之一 ,当你对代码进行修改并保存后,webpack 将对代码重新打包,并将新的模块发送到浏览器端,浏览器通过新的模块替换老的模块,这样在不刷新浏览器的前提下就能够对应用进行更新。
基本实现原理大致这样的,构建
bundle的时候,加入一段HMR runtime的 js 和一段和服务沟通的 js 。文件修改会触发webpack重新构建,服务器通过向浏览器发送更新消息,浏览器通过jsonp拉取更新的模块文件,jsonp回调触发模块热替换逻辑
# 热更新配置
使用
webpack-dev-server,设置hot属性为true.写模块时,按照以下写法:
if (module.hot) { //判断是否有热加载
module.hot.accept('./hmrTest.js', function() { //热加载的模块路径
console.log('Accepting the updated printMe module!'); //热加载的回调,即发生了模块更新时,执行什么 callback
printMe();
})
}
@前端进阶之旅: 代码已经复制到剪贴板
- 缺点:更新逻辑得自己写。比如要使页面显示的内容生效,需要在回调中写入
document.append(xxx)
react的热加载,使用react-hot-loader
import { hot } from'react-hot-loader';
const Record = ()=>{
...
}
exportdefault hot(module)(Record);
或
if (module.hot) {
module.hot.accept('./App', function () {
var NextApp = require('./App')
ReactDOM.render(<NextApp />, rootEl)
})
}
@前端进阶之旅: 代码已经复制到剪贴板
# 实现过程
watch编译过程、devServer推送更新消息到浏览器- 浏览器接收到服务端消息做出响应
- 对模块进行热更新或刷新页面
# watch 编译过程、devServer 推送更新消息到浏览器
webpack-dev-server里引用了webpack-dev-middleware,相关的watch逻辑就是在里面实现的
//webpack-dev-server/lib/Server.js
setupDevMiddleware() {
this.middleware = webpackDevMiddleware(
this.compiler,
Object.assign({}, this.options, { logLevel: this.log.options.level })
);
}
// webpack-dev-middleware/index.js
if (!options.lazy) {
context.watching = compiler.watch(options.watchOptions, 