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

Webpack & The Hot Module Replacement热模块替换原理解析的更多相关文章

  1. Hot Module Replacement [热模块替换]

    安装了webpack-dev-server后 , 配置 "start": "webpack-dev-server" 然后运行 npm start 会开起一个we ...

  2. webpack的Hot Module Replacement运行机制

    使用webpack打包,难免会使用Hot Module Replacement功能,该功能能够实现修改.添加或删除前端页面中的模块代码,而且是在页面不刷新的前提下.它究竟是怎么运作的呢?本文主要从调试 ...

  3. webpack——Modules && Hot Module Replacement

    blog:JavaScript Module Systems Showdown: CommonJS vs AMD vs ES2015 官网链接: Modules 官网链接:Hot Module Rep ...

  4. webpack摸索(一)webpack-dev-server热模块替换

    webpack-dev-server 是生成在内存中的 本地开发: index.html <!DOCTYPE html> <html lang="en"> ...

  5. 前端技术之:webpack热模块替换(HMR)

    第一步:安装HMR中间件: npm install --save-dev webpack-hot-middleware   第二步:webpack配置中引入webpack对象     const we ...

  6. webpack-Hot Module Replacement(热更新)

    模块热替换(Hot Module Replacement) 模块热替换(HMR - Hot Module Replacement)功能会在应用程序运行过程中替换.添加或删除模块,而无需重新加载整个页面 ...

  7. webpack学习之—— 模块热替换(Hot Module Replacement)

    模块热替换(HMR - Hot Module Replacement)功能会在应用程序运行过程中替换.添加或删除模块,而无需重新加载整个页面.主要是通过以下几种方式,来显著加快开发速度: 保留在完全重 ...

  8. webpack中热模块更新

    Hot Module Replacement,热模块更新,很多时候会简写成HMR. "scripts": { "start": "webpack-de ...

  9. Webpack 2 视频教程 020 - Webpack 2 中的 HMR ( Hot Module Replacement )

    原文发表于我的技术博客 这是我免费发布的高质量超清「Webpack 2 视频教程」. Webpack 作为目前前端开发必备的框架,Webpack 发布了 2.0 版本,此视频就是基于 2.0 的版本讲 ...

随机推荐

  1. python-10多进程

    1-多进程(multiprocessing), 1个父进程可以有多少子进程 1.1下面的例子演示了启动一个子进程并等待其结束 from multiprocessing import Process i ...

  2. 20145202马超 《Java程序设计》第三周学习总结

    ************************http://git.oschina.net/tuolemi/java这是git的那个网址********************* 函数的重载:在同一 ...

  3. 1-Linux运维人员要求

    linux 运维: 1.linux基础操作命令2.linux基础服务搭建3.文本处理命令4.shell脚本编程 python perl php5.数据库 mysql oracle6.lvs集群 热备 ...

  4. 局域网&广域网&Internet&计算机通信过程

    1.局域网 覆盖范围小(100m以内),自己花钱购买,自己单位来维护,带宽固定的(10M,100M,1000M) 2.Internet ISP,有自己的机房,对网民提供访问Internet连接 3.广 ...

  5. sublime text基本配置备份

    sublime text基本配置备份: // Settings in here override those in "Default/Preferences.sublime-settings ...

  6. css 之 border-radius属性

    css中给盒子设置圆角可以通过 border-radius 属性来实现(具体原理就不深入探讨了); 在开发过程中都会遇到浏览器兼容问题,这问题其实也不难解决,无非就是加上私有前缀,在这里先忽略掉.   ...

  7. input()报错:TypeError: '>=' not supported between instances of 'str' and 'int'

    今天学习python基础—分支与循环,接触到了if.在练习一个if语句的时候,出现了错误. 题目是: 根据分数划分成四个级别:优秀.良好.及格.不及格,分数是72: grade = 72if grad ...

  8. web浏览器中的javascript

    window 对象中其中一个最重要的属性是document,它引用document对象,后者表示显示在窗口中的文档.document对象有一些重要方法,比如getElementById(),它可以基于 ...

  9. PHP路径相关 dirname,realpath,__FILE__

    ​比如:程序根目录在:E:\wamp\www 中 1.    __FILE__   当前文件的绝对路径 如果在index.php中调用 则返回  E:\wamp\www\index.php 下面再看一 ...

  10. ftrace 简介

    ftrace 简介 ftrace 的作用是帮助开发人员了解 Linux 内核的运行时行为,以便进行故障调试或性能分析. 最早 ftrace 是一个 function tracer,仅能够记录内核的函数 ...