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一看一脸懵逼,简直不敢相信这些都是我自己用过的代码,想把以前的自己喊过来科研了() 废话少说,最近写小综述论文,需要绘制一个地图底图+散点图ÿ…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态
前言 在人工智能技术飞速发展的今天,深度学习与大模型技术已成为推动行业变革的核心驱动力,而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心,系统性地呈现了两部深度技术著作的精华:…...
