zoukankan      html  css  js  c++  java
  • Webpack & The Hot Module Replacement热模块替换原理解析

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

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

    很多人使用过HMR却不知道它是如何工作的,这里会对HMR实现原理进行解析。

    关于HMR需要知道的一些事

    • HMR是Webpack的一个可选功能,如果想使用需要主动打开。

    • 需要通过webpack-dev-server方式来管理webpack(另一种方式是CLI)

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

    • HMR只能在开发环境中使用,因为HMR会在打包的js中添加了很多额外的代码,并且webpack-dev-server也只用于开发环境。

    HMR工作原理

    webpack会在打包的js中注入很多js库来让HMR工作,下图展示了当一个文件发生变化是HMR是如何工作的。

    图片颜色说明:

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

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

    彩兰色:项目代码

    绿色: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原理解析

  • 相关阅读:
    全栈项目|小书架|服务器端-NodeJS+Koa2实现首页图书列表接口
    全栈项目|小书架|微信小程序-首页水平轮播实现
    全栈项目|小书架|微信小程序-登录及token鉴权
    全栈项目|小书架|微信小程序-项目结构设计分包
    Python学习第123天(Django回头看:模板控制语句、filter、simple_tag)
    Python学习第122天(Django回头看:视图函数、redirect、模板变量、过滤器)
    Python学习第121天(Django2的include使用)
    Python学习第120天(Django1和2之间的区别)
    Python学习第119天(练习)
    Python学习第119天(暂停)
  • 原文地址:https://www.cnblogs.com/chenkeyu/p/10801197.html
Copyright © 2011-2022 走看看