webpack 的热更新是如何做到的?原理是什么?
Hot Module Replacement,简称 HMR,在不需要刷新整个页面的同时更新模块,能够提升开发的效率和体验。热更新时只会局部刷新页面上发生了变化的模块,同时可以保留当前页面的状态,比如复选框的选中状态等。
在 webpack 中配置开启热模块也非常的简单,如下代码:
const webpack = require('webpack')
module.exports = {// ...devServer: {// 开启 HMR 特性hot: true,// hotOnly: true},
}
热更新的实现
webpack-dev-server 启动的时候会做三件事情
- 启动 webpack,生成 compiler 实例,compiler 实例的功能很多,比如用来启动 webpack 的编译工作,监听文件变化等。
- 使用 Express 启动一个本地服务,使得浏览器可以访问本地服务
- 启动 websocket 服务,用于浏览器和本地 node 服务进行通讯。
监听文件变化
webpack 监听文件变化主要是通过 webpack-dev-middleware 这个库来完成,它负责本地文件的编译、输出和监听 webpack-dev-middleware 中执行了 compiler.watch 方法,它主要做了两件事情
- 对本地文件编译打包
- 编译结束之后,开启监听,文件发生变化时重新编译,并持续进行监听
监听 webpack 编译结束
setupHooks 方法用来注册监听事件,当监听到 webpack 编译结束时,通过 websocket 给浏览器发通知,浏览器拿到 hash 只之后就可以做检查更新逻辑。
一、是什么
HMR
全称 Hot Module Replacement
,可以理解为模块热替换,指在应用程序运行过程中,替换、添加、删除模块,而无需重新刷新整个应用
例如,我们在应用运行过程中修改了某个模块,通过自动刷新会导致整个应用的整体刷新,那页面中的状态信息都会丢失
如果使用的是 HMR
,就可以实现只将修改的模块实时替换至应用中,不必完全刷新整个应用
在webpack
中配置开启热模块也非常的简单,如下代码:
const webpack = require('webpack')
module.exports = {// ...devServer: {// 开启 HMR 特性hot: true,// hotOnly: true},
}
通过上述这种配置,如果我们修改并保存css
文件,确实能够以不刷新的形式更新到页面中
但是,当我们修改并保存js
文件之后,页面依旧自动刷新了,这里并没有触发热模块
所以,HMR
并不像 Webpack
的其他特性一样可以开箱即用,需要有一些额外的操作
我们需要去指定哪些模块发生更新时进行HRM
,如下代码:
if (module.hot) {module.hot.accept('./util.js', () => {console.log('util.js更新了')})
}
二、实现原理
首先来看看一张图,如下:
- Webpack Compile:将 JS 源代码编译成 bundle.js
- HMR Server:用来将热更新的文件输出给 HMR Runtime
- Bundle Server:静态资源文件服务器,提供文件访问路径
- HMR Runtime:socket 服务器,会被注入到浏览器,更新文件的变化
- bundle.js:构建输出的文件
- 在 HMR Runtime 和 HMR Server 之间建立 websocket,即图上 4 号线,用于实时更新文件变化
上面图中,可以分成两个阶段:
- 启动阶段为上图 1 - 2 - A - B
在编写未经过webpack
打包的源代码后,Webpack Compile
将源代码和 HMR Runtime
一起编译成 bundle
文件,传输给Bundle Server
静态资源服务器
- 更新阶段为上图 1 - 2 - 3 - 4
当某一个文件或者模块发生变化时,webpack
监听到文件变化对文件重新编译打包,编译生成唯一的hash
值,这个hash
值用来作为下一次热更新的标识
根据变化的内容生成两个补丁文件:manifest
(包含了 hash
和 chundId
,用来说明变化的内容)和chunk.js
模块
由于socket
服务器在HMR Runtime
和 HMR Server
之间建立 websocket
链接,当文件发生改动的时候,服务端会向浏览器推送一条消息,消息包含文件改动后生成的hash
值,如下图的h
属性,作为下一次热更细的标识
在浏览器接受到这条消息之前,浏览器已经在上一次socket
消息中已经记住了此时的hash
标识,这时候我们会创建一个 ajax
去服务端请求获取到变化内容的 manifest
文件
mainfest
文件包含重新build
生成的hash
值,以及变化的模块,对应上图的c
属性
浏览器根据 manifest
文件获取模块变化的内容,从而触发render
流程,实现局部模块更新
相关文章:

webpack 的热更新是如何做到的?原理是什么?
Hot Module Replacement,简称 HMR,在不需要刷新整个页面的同时更新模块,能够提升开发的效率和体验。热更新时只会局部刷新页面上发生了变化的模块,同时可以保留当前页面的状态,比如复选框的选中状态等。 在 webpack 中…...

嵌入式ARM设计编程(一) 简单数据搬移
文章和代码已归档至【Github仓库:hardware-tutorial】,需要的朋友们自取。或者公众号【AIShareLab】回复 嵌入式 也可获取。 一、实验目的 熟悉实验开发环境,掌握简单ARM汇编指令的使用方法。 二、实验环境 硬件:PC机 软件&am…...

【Selenium】十分钟手把手带你学会WebDriver API
目录 1、定位元素【8种】 2、操作测试对象 3、添加等待 4、弹窗类型 5、浏览器的操作 6、键盘事件 7、选择框 8、上传文件 1、定位元素【8种】 元素定位是自动化测试的核心,想要去操作一个对象,第一步就是需要我们先去识别这个对象。每个对象就会…...

3DMAX高级弯曲插件使用教程
3dMax高级弯曲插件是对3dmax原生“弯曲(Bend)”修改器的一个增强,给用户更多控制弯曲修改器的参数设置,它让用户输入宽度,插件脚本将移动中心以获得正确的宽度。 主要特性: - 使用智能捕捉捕捉到自定义网格…...
前端面试题之性能优化大杂烩
主要内容为下面几大类:移动端、图片、JavaScript、css、html、页面内容、服务器、cookie。 移动端性能优化: 保持单个文件小于25KB 移动网站页面要求下载资源,如果文件过大,会大大减慢页面加载速度。 打包内容为分段multipart文…...

SpringBoot+Vue实现养老智慧服务平台
文末获取源码 开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7/8.0 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven包:Maven3.3.9 浏…...
tigervnc2023
sudo apt-get install tigervnc-standalone-server 配置用户 /etc/tigervnc/vncserver.users :1user1 :2user2 :3user3 全局配置 /etc/tigervnc/vncserver-config-defaults $localhost"no"; $geometry "1920x1200"; 分别进入user1 user2 user3 用户…...

智能三子棋(人机大战)—— 你会是最终赢家吗?万字讲解让你实现与自己对弈
魔王的介绍:😶🌫️一名双非本科大一小白。魔王的目标:🤯努力赶上周围卷王的脚步。魔王的主页:🔥🔥🔥大魔王.🔥🔥🔥 ❤️…...

【自制开发板】自制STM32F407开发板(含TFT 8080串口屏幕接口)
【2023 年 2 月 14 日】 许久没有更新,最近做了个小开发板玩了玩。更新一下吧,作为记录!! 主要是象试一下LVGL在STM32上的应用,所以开发板的大小都是基于屏幕大小来设计的。 分享出来,给大家一个板子结构…...

openvino yolov5/ssd 实时推流目标检测在html上显示
安装ffmepg并添加到环境变量中,流媒体使用m7s 运行效果 SSD:检测在10ms左右,yolov5在100ms左右 app.py #!/usr/local/bin/python3 # encodin: utf-8import subprocess import threading import time import cv2 import osfrom OpenVinoYoloV…...

基于FPGA的 SPI通信 设计(1)
引言 低速通信目前搞过 UART串口通信、IIC通信。其实 SPI 也算是中低速(有时也可以用作高速通信)串行通信的范畴,但是一直还没真正实现过,所以此系列就 SPI的协议以及FPGA设计作几篇博客记录。欢迎订阅关注~ SPI 标准协议 x1模式…...

为什么西门子、美的等企业这样进行架构升级,看看改造效果就知道了
在工业领域, 生产、测试、运行阶段都可能会产生大量带有时间戳的传感器数据,这都属于典型的时序数据。时序数据主要由各类型实时监测、检查与分析设备所采集或产生,涉及制造、电力、化工、工程作业等多个行业,具备写多读少、量非常…...

open3d点云配准函数registration_icp
文章目录基本原理open3d调用绘图基本原理 ICP, 即Iterative Closest Point, 迭代点算法。 ICP算法有多种形式,其中最简单的思路就是比较点与点之间的距离,对于点云P{pi},Q{qi}P\{p_i\}, Q\{q_i\}P{pi},Q{qi}而言,如果二者是同一目标&am…...

HTML编码规范
本篇文章是基于王叨叨大佬师父维护的文档梳理的,有兴趣可以去看一下原文HTML编码规范。 1. 缩进与换行 【建议】 使用 2 个空格作为一个缩进层级,不允许使用tab字符 解释: 具体项目,可以使用2个空格,也可以使用…...

PDF SDK for Linux 8.4.2 Crack
PDF SDK for Linux 是适用于任何 Linux 企业或云应用程序的强大解决方案,非常适合需要完全可定制的 PDF 查看器或后端流程的任何 Linux 开发人员。 将 Foxit PDF SDK 嵌入到基于 Linux 的应用程序中非常容易。只需打开您最喜欢的 Linux IDE,复制您需要的…...

vb 模块和作用域的关系
模块在VB中有三种类型的模块,分别是窗体模块、标准模块和类模块。窗体模块窗体模块中包含了窗体以及窗体中所有控件的事件过程,文件扩展名为(*.frm),窗体文件中不仅包含窗体对象的外观设计,也包含窗体模块(…...

Redis分布式锁
一、背景 与分布式锁相对应的是「单机锁」,我们在写多线程程序时,避免同时操作一个共享变量产生数据问题,通常会使用一把锁来「互斥」,以保证共享变量的正确性,其使用范围是在「同一个进程」中。单机环境下࿰…...
京东前端经典面试题整理
img的srcset属性的作⽤? 响应式页面中经常用到根据屏幕密度设置不同的图片。这时就用到了 img 标签的srcset属性。srcset属性用于设置不同屏幕密度下,img 会自动加载不同的图片。用法如下: <img src"image-128.png" srcset&qu…...

django+mysql实现一个简单的web登录页面
目录 一、使用pyacharm创建一个django项目 二、启动django项目验证 三、配置mysql数据库 1、本地安装mysql数据库 1)安装mysql数据库 2)自己创建一个数据库 2、安装 pymysql 3、配置mysql数据库 1)在项目同名包下的_init_.py里面添加…...

python cartopy手动导入地图数据绘制底图/python地图上绘制散点图:Downloading:warnings/散点图添加图里标签
……开学回所,打开电脑spyder一看一脸懵逼,简直不敢相信这些都是我自己用过的代码,想把以前的自己喊过来科研了() 废话少说,最近写小综述论文,需要绘制一个地图底图+散点图ÿ…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...

算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...

c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...

客户案例 | 短视频点播企业海外视频加速与成本优化:MediaPackage+Cloudfront 技术重构实践
01技术背景与业务挑战 某短视频点播企业深耕国内用户市场,但其后台应用系统部署于东南亚印尼 IDC 机房。 随着业务规模扩大,传统架构已较难满足当前企业发展的需求,企业面临着三重挑战: ① 业务:国内用户访问海外服…...
前端工具库lodash与lodash-es区别详解
lodash 和 lodash-es 是同一工具库的两个不同版本,核心功能完全一致,主要区别在于模块化格式和优化方式,适合不同的开发环境。以下是详细对比: 1. 模块化格式 lodash 使用 CommonJS 模块格式(require/module.exports&a…...