The Hot Module Replacement(HMR)俗称热模块替换。主要用来当代码产生变化后,能够在不刷新游览器的状况下对局部代码块进行替换更新。这在不少状况下都颇有用,例如在处理弹出框时,使用HMR能够及时的看到变化,若是用刷新游览器的方式会回到初始页面。css
不少人使用过HMR殊不知道它是如何工做的,这里会对HMR实现原理进行解析。html
HMR是Webpack的一个可选功能,若是想使用须要主动打开。react
须要经过webpack-dev-server方式来管理webpack(另外一种方式是CLI)webpack
HMR只能工做在实现了HMR API的loaders里,例如:‘style-loader’,'react-hot-loader'web
HMR只能在开发环境中使用,由于HMR会在打包的js中添加了不少额外的代码,而且webpack-dev-server也只用于开发环境。ajax
webpack会在打包的js中注入不少js库来让HMR工做,下图展现了当一个文件发生变化是HMR是如何工做的。json
图片颜色说明:app
紫色:发生改变的js或者css文件webpack-dev-server
橘色:发生变化的代码块说明,变化后的代码块内容ide
彩兰色:项目代码
绿色:webpack-dev-server相关的库,有图中能够发现,webpack-dev-server主要负责server端和游览器端的通讯。
蓝色:webpack核心和插件库,由图中能够发现,server端代码的监听以及游览器端新代码的替换都是由webpack的不一样模块处理。
红色:react-loader或者style-loader等HMR库
当监听到文件发生变化时,webpack 使用HotModuleReplacementPlugin生成一个mainifest(一个json结构描述了发生变化的modules列表)和update file(一个js文件包含修改后的代码内容)
webpack将上述变化信息告诉webpack-dev-server
webpack-dev-server经过webSocket给运行在游览器上的‘webpack-dev-server/client’(在打包时注入的js代码)发送一条‘invalide’信息以及更新后代码的hash值(该hash值本次不会用到,使用上一版本的hash值).
’webpack-dev-server/client’会将上一版本代码的hash传递给“hot/dev-server”
‘hot/dev-server’使用JsonpRuntime向server端发送带有上版本hash的ajax请求,server端返回一个json,该json包含要全部要更新的模块的hash值。
JsonpRuntime根据返回的json值使用jsonp请求具体的代码块,jsonp返回的js代码相似下面:
webpackHotUpdate(0,
{
82:
function(module, exports, __webpack_require__) {
exports = module.exports = __webpack_require__(79)();
exports.push([module.id, “input {\n background: pink;\n}”, “”])
}
})
代码会调用webpackHotUpdate方法并携带module_id和具体修改内容。
HMR runtime自己并不会处理代码修改,它会将不一样文件交给对应的loader runtime处理(例如:react-hot-loader runtime 或者 style-loader runtime)
若是更新失败,会回退刷新游览器获取最新代码。
当游览器首次加载app时,server端会推送当前代码版本号current_hash。
当修改style文件后,server端HotModuleReplacementPlugin会根据更新内容生成manifest和js文件,文件名根据current_hash生成,而后更新current_hash,并将新的hash值推送给游览器端,用做下次更新。
游览器端webpack-dev-server/client接收到新的hash值后,会将previous hash值传递给webpack/hot/dev-server,dev-server根据previous hash请求具体的mainifest和js代码,并使用jsonp更新。
参考文档:
Webpack & The Hot Module Replacement
原文出处:https://www.cnblogs.com/chenkeyu/p/10801197.html