webpack 学习笔记系列08-HMR热更新

webpack 学习笔记系列08-HMR热更新

Write By CS逍遥剑仙 我的主页: csxiaoyao.com GitHub: github.com/csxiaoyaojianxian Email: sunjianfeng@csxiaoyao.com QQ: 1724338257

1. HMR 概念

HMR - Hot Module Replacement,当 webpack 开启 HMR 功能后,代码修改时 webpack 会重新打包,并将修改后的代码发送到浏览器,浏览器替换老的代码,保证了页面状态不会丢失,在不刷新整个页面的前提下进行局部更新。

当一个模块代码发生更改,就需要执行对应的 update 事件,若当前模块无法处理 HMR,则会顺着 webpack 的 module 树向父依赖节点冒泡,若直至根节点(即 entry 入口文件)都无法处理 update 事件,就会刷新页面,对于大多数的前端框架,如 Vue 等,都会有配套的 HMR 工具,一般通过 loader / babel 插件 / style-loader 来实现。

2. 热更新流程

01.jpg

2.1 webpack-dev-server & contentBase

启动一个 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;
    }
};

2.2 watch

上图共有三个 watch:

step1 中的 watch 监控依赖模块的文件变化,即代码修改触发重新编译(HMR);

step2 是 webpack-dev-middleware 通过 webpack 的 Compiler 钩子监听编译进程并通过 ws 推送编译后的 hash 值以及告诉浏览器当前的页面代码是 invalid 状态的,需要更新;

step3 中的 watch 是设置 devServer.watchContentBase=true 时监听 contentBase 文件变化,触发通知浏览器刷新(非HMR,因为 contentBase 非打包的依赖文件)。

2.3 HotModuleReplacementPlugin 插件

webpack.config.js 中添加的插件 HotModuleReplacementPlugin 会生成两次编译之间差异文件列表,即 manifest JSON 文件。

  • manifest JSON 文件:文件名格式为 [hash].hot-update.json,由插件生成,包含 update 文件列表
  • update 文件:文件名格式为 [id].[hash].hot-update.js,罗列在 manifest JSON 文件中,内容为 HMR 的差异化执行代码

插件会通过 Compilation.mainTemplate 的 bootstrap 钩子根据不同环境注入 runtime.js,在浏览器环境下,注入的是 lib/web/JsonpMainTemplate.runtime.js ,该 runtime.js 中有两个用于更新的关键函数:

  • hotDownloadManifest: 发起 Ajax 请求 mainifest JSON 文件
  • hotDownloadUpdateChunk: 创建 JSONP 请求 update 文件

2.4 WebSocket & hash

webpack-dev-server 利用 sockjs 在浏览器和 Server 间创建一个 WebSocket 长连接,通信内容主要是传递编译模块的文件 hash 值信息。

浏览器获取到新 hash 后,会首先发起一个 ajax 请求获取 manifest 文件 [hash].hot-update.json 内容,再通知 HMR 的 Runtime 按清单列表发起 JSONP 请求,获取两次编译的差异文件 [id].[hash].hot-update.js,插到页面 head 标签的 script 中执行,完成最终的更新。

02.jpeg

注意: 这里的 hash 值为执行本次 Compilation 前确定的 hash 值,因此获取 manifest 和更新文件时用的是上一次更新后返回的 hash 值。

3. HMR 原理——编译差异计算方式

03.jpg

以上图为例,右侧模块 module(4) / module(9) 发生变化,manifest JSON 会更新为其依赖的4个相关 chunk:

  • chunk(3): module(9) 修改后引入新的依赖 module(12),因此 chunk(3) 生成包含 module(9) 和 module(12) 的 update 文件;
  • chunk(4): module(4) 修改后去除 chunk(4) 的依赖,且 chunk(4) 中的 module(10) 和 module(11) 模块未被其他模块使用,因此删除 chunk(4) 中的模块 module(10) / module(11);
  • chunk(1): chunk(1) 依赖 module(4),因此生成 module(4) 的 update 文件;
  • entry(0):最后入口文件更新依赖的新 chunk 文件列表,chunks=1,3,4

sign

原文地址:https://cloud.tencent.com/developer/article/1839709

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340