HMR(hot module replacement)
推荐雪凌老师好文
优点
- 保留应用程序
状态 - 只变更修改的内容,
节省开发时间 - 在源代码中修改js/css,可以
立马体现在浏览器中。相当于在浏览器devtools直接修改
对应插件
HotModulePlacementPlugin
热更新原理
- 我们一般使用webpack-dev-server(WDS)通过nodejs-
Express启动一个开发服务,webpack内部实现一个watch,文件发生修改后重新打包并放入内存。 - WDS依赖中间件webpack-dev-middleware和webpack之间交互。主要通过调用webpack暴露的API(compiler.watch)对
代码进行监控 - WDS和浏览器之间建立了websocket长连接。socket注册了两个监听事件:
hash(提供最新一次的hash值)和ok(进行热更新检测),主要是用来将webpack编译打包的各个阶段状态消息告知浏览器
// 通过websoket给客户端发消息
_sendStats() {
this.sockWrite(sockets, 'hash', stats.hash);
this.sockWrite(sockets, 'ok');
}
-
如果文件变化了,没有配置热更新,WDS会通知浏览器进行刷新(
location.reload) -
如果有热更新
5.1.当本地资源更新后,WDS向浏览器推送更新消息,并带上构建的hash值
5.2.客户端向server发送ajax请求,server返回一个json,里面包含了所有要更新的模块的hash值
5.3.获取到需要更新的列表后,客户端再次发送
jsonp请求,利用script脚本,获取替换最新的更新模块代码 -
如果热更新失败,回退到live reload操作,就是直接
location.reload
配置
方法一
利用 devServer.hot = true
module.exports = {
//...
devServer: {
hot: true
}
}
注意:必须有webpack.HotModuleReplacementPlugin才能完全启用HMR。如果webpack或webpack-dev-server是通过--hot选项启动的。那么这个插件会自动被添加。
{
"start": "webpack-dev-server --hot --open"
}
方法二
利用plugin中添加依赖HotModuleReplacementPlugin插件。这里和方法一差不多一个意思
plugins: [
//...
new webpack.HotModuleReplacementPlugin()
]
方法三 react-hot-loader
这个loader也是官方推荐
利用 react-hot-loader导入AppContainer组件。这里主要记住这个loader就好.
引入这个loader,需要配合react-app-rewire-hot-loader
import { AppContainer } from "react-hot-loader"
const render = Component => {
ReactDOM.render(
<Provider store={store}>
<AppContainer>
<Component/>
</AppContainer>
</Provider>
),
document.getElementById("root")
}
render(App);
if (module.hot) {
module.hot.accept("./App", () => {
const nextApp = require("./App").default;
render(nextApp);
})
}