Write By CS逍遥剑仙 我的主页: csxiaoyao.com GitHub: github.com/csxiaoyaojianxian Email: sunjianfeng@csxiaoyao.com QQ: 1724338257
HMR - Hot Module Replacement,当 webpack 开启 HMR 功能后,代码修改时 webpack 会重新打包,并将修改后的代码发送到浏览器,浏览器替换老的代码,保证了页面状态不会丢失,在不刷新整个页面的前提下进行局部更新。
当一个模块代码发生更改,就需要执行对应的 update 事件,若当前模块无法处理 HMR,则会顺着 webpack 的 module 树向父依赖节点冒泡,若直至根节点(即 entry 入口文件)都无法处理 update 事件,就会刷新页面,对于大多数的前端框架,如 Vue 等,都会有配套的 HMR 工具,一般通过 loader / babel 插件 / style-loader 来实现。
启动一个 Express Server,整合 webpack-dev-middleware 中间件、WebSocket 长连接、 proxy、静态资源服务器等功能。
webpack-dev-server 的 contentBase 为临时的静态资源服务器的目录文件夹,启动 server 后,可通过 url 访问,但不会落盘(存储硬盘),且这个文件和 webpack 打包出的路径并不一样。
在 webpack-dev-middleware 中,使用了 memory-fs 内存文件系统模块,替换 Webpack 的 Compiler 对象的输出打包结果文件模块 outputFileSystem
// webpack-dev-middleware/lib/fs.js const MemoryFileSystem = require('memory-fs'); module.exports = { setFs(context, compiler) { // ... fileSystem = new MemoryFileSystem(); compiler.outputFileSystem = fileSystem; } };
上图共有三个 watch:
step1 中的 watch 监控依赖模块的文件变化,即代码修改触发重新编译(HMR);
step2 是 webpack-dev-middleware 通过 webpack 的 Compiler
钩子监听编译进程并通过 ws 推送编译后的 hash 值以及告诉浏览器当前的页面代码是 invalid
状态的,需要更新;
step3 中的 watch 是设置 devServer.watchContentBase=true
时监听 contentBase 文件变化,触发通知浏览器刷新(非HMR,因为 contentBase 非打包的依赖文件)。
在 webpack.config.js
中添加的插件 HotModuleReplacementPlugin
会生成两次编译之间差异文件列表,即 manifest JSON 文件。
[hash].hot-update.json
,由插件生成,包含 update 文件列表[id].[hash].hot-update.js
,罗列在 manifest JSON 文件中,内容为 HMR 的差异化执行代码插件会通过 Compilation.mainTemplate 的 bootstrap 钩子根据不同环境注入 runtime.js,在浏览器环境下,注入的是 lib/web/JsonpMainTemplate.runtime.js ,该 runtime.js 中有两个用于更新的关键函数:
webpack-dev-server 利用 sockjs 在浏览器和 Server 间创建一个 WebSocket 长连接,通信内容主要是传递编译模块的文件 hash 值信息。
浏览器获取到新 hash 后,会首先发起一个 ajax 请求获取 manifest 文件 [hash].hot-update.json
内容,再通知 HMR 的 Runtime 按清单列表发起 JSONP 请求,获取两次编译的差异文件 [id].[hash].hot-update.js
,插到页面 head
标签的 script
中执行,完成最终的更新。
注意: 这里的 hash 值为执行本次 Compilation 前确定的 hash 值,因此获取 manifest 和更新文件时用的是上一次更新后返回的 hash 值。
以上图为例,右侧模块 module(4) / module(9) 发生变化,manifest JSON 会更新为其依赖的4个相关 chunk:
作者:朱祝元 技术架构 物理部署: 1master;5 Data;1 Logstash+kibana;3 kafk...
刚刚结束的第一期实时数仓入门训练营异常火爆 没来得及报名的小伙伴不断私信留言...
3月份GitHub上最热门的JavaScript开源项目排行已经出炉啦,一起来看看吧: 1. We...
查看精彩回放 https://developer.aliyun.com/live/245624 本文大纲 一、Serverle...
科学技术的不断发展,互联网技术的不断成熟,人们的生活、工作方式都发生了很大...
现在提到买云服务器,很多用户的第一选择就是阿里云服务器,的确,在云服务器市...
01 导入Matplotlib 如果你安装了完整的Python Anaconda,那么你已经安装了Matplo...
本文转载自微信公众号「石杉的架构笔记」,作者崔皓。转载本文请联系石杉的架构...
TOP云 (west.cn)3月2日消息,,.car、.cars、.auto等土豪 域名 的注册局Unireg...
迁移到面向金融服务的全新业务架构 加速转型 随着银行加速适应数字化技术,加之...