Webpack & The Hot Module Replacement热模块替换原理解析

Webpack & The Hot Module Replacement热模块替换原理解析

The Hot Module Replacement(HMR)俗称热模块替换。主要用来当代码产生变化后,能够在不刷新游览器的状况下对局部代码块进行替换更新。这在不少状况下都颇有用,例如在处理弹出框时,使用HMR能够及时的看到变化,若是用刷新游览器的方式会回到初始页面。css

不少人使用过HMR殊不知道它是如何工做的,这里会对HMR实现原理进行解析。react

关于HMR须要知道的一些事

  • HMR是Webpack的一个可选功能,若是想使用须要主动打开。webpack

  • 须要经过webpack-dev-server方式来管理webpack(另外一种方式是CLI)web

  • HMR只能工做在实现了HMR API的loaders里,例如:‘style-loader’,'react-hot-loader'ajax

  • HMR只能在开发环境中使用,由于HMR会在打包的js中添加了不少额外的代码,而且webpack-dev-server也只用于开发环境。json

HMR工做原理

webpack会在打包的js中注入不少js库来让HMR工做,下图展现了当一个文件发生变化是HMR是如何工做的。app

图片颜色说明:webpack-dev-server

紫色:发生改变的js或者css文件ide

橘色:发生变化的代码块说明,变化后的代码块内容jsonp

彩兰色:项目代码

绿色:webpack-dev-server相关的库,有图中能够发现,webpack-dev-server主要负责server端和游览器端的通讯。

蓝色:webpack核心和插件库,由图中能够发现,server端代码的监听以及游览器端新代码的替换都是由webpack的不一样模块处理。

红色:react-loader或者style-loader等HMR库

 

执行流程:

  1. 当监听到文件发生变化时,webpack 使用HotModuleReplacementPlugin生成一个mainifest(一个json结构描述了发生变化的modules列表)和update file(一个js文件包含修改后的代码内容)

  2. webpack将上述变化信息告诉webpack-dev-server

  3. webpack-dev-server经过webSocket给运行在游览器上的‘webpack-dev-server/client’(在打包时注入的js代码)发送一条‘invalide’信息以及更新后代码的hash值(该hash值本次不会用到,使用上一版本的hash值).

  4. ’webpack-dev-server/client’会将上一版本代码的hash传递给“hot/dev-server”

  5. ‘hot/dev-server’使用JsonpRuntime向server端发送带有上版本hash的ajax请求,server端返回一个json,该json包含要全部要更新的模块的hash值。

  6. 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}”, “”])
}
})
  1. 代码会调用webpackHotUpdate方法并携带module_id和具体修改内容。

  2. HMR runtime自己并不会处理代码修改,它会将不一样文件交给对应的loader runtime处理(例如:react-hot-loader runtime 或者 style-loader runtime)

  3. 若是更新失败,会回退刷新游览器获取最新代码。

 

示例

当游览器首次加载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

Webpack HMR原理解析

相关文章
相关标签/搜索