<Vite>HMR实现原理

什么是HMR?

在这里插入图片描述

HMR(Hot Module Replacement)是一种开发工具,也就是热更新。用于在应用程序运行时替换、添加或删除模块,而无需完全重新加载整个页面或重新启动应用程序。这可以极大地提高开发效率和调试体验。

HMR的优势

通过使用HMR,当你修改了一个模块的代码后,在保存文件的瞬间,只有该模块及其依赖关系会被重新编译,并且新的代码将立即生效。这使得你能够实时查看对应用程序所做更改的影响结果,无需手动刷新页面。

Vite的HMR功能是通过以下原理实现的:

在这里插入图片描述

  1. ES模块和浏览器原生支持: Vite利用了现代浏览器对ES模块加载机制的支持。在开发环境中,Vite将每个文件作为一个独立的模块进行处理,并且使用浏览器自身提供的importexport语法来实现模块之间的依赖关系。

  2. WebSocket通信: 当源代码发生更改时,Vite会检测到变化并建立与客户端之间的WebSocket连接。这样,服务器可以向客户端发送更新消息。

  3. 按需编译和替换: 一旦服务器检测到代码更改,它会根据变化重新编译受影响的文件,并生成新版本。然后,服务器通过WebSocket将更新消息发送给客户端。

  4. 局部更新: 客户端收到更新消息后,它会根据需要下载新版本并对页面进行局部刷新,而无需完全重新加载整个页面。这种局部刷新使得应用程序保持在开发状态下无缝运行,并提供快速反馈。

具体而言,在Vite中实现HMR特性主要涉及以下三个步骤:

  1. 监听文件改动: 在开发模式下,Vite使用一个文件系统监视器(watcher)来监听源代码文件的变化。当文件被修改、添加或删除时,watcher会立即捕获到这些变化。

  2. 服务器端编译资源并推送新模块内容给浏览器: 一旦有文件更改被捕获,Vite启动一个服务器,并执行相应的编译过程。它会根据需要重新构建受影响的模块,并生成新版本。然后,服务器通过WebSocket与客户端保持连接,并将更新消息推送给浏览器。

  3. 浏览器接收并处理新模块内容: 浏览器收到更新消息后,在不刷新整个页面的情况下下载和加载新版本的模块。对于支持HMR功能的前端框架(如Vue.js和React),它们具备能力在接收到新模块内容后进行局部渲染或组件重载操作(例如Vue中即是rerender)。这使得应用程序可以实现热更新效果,即时地反映出源代码更改所带来的变化。

serverPluginClient 源码举例

serverPluginClient是Vite中的一个插件,用于在开发服务器上提供客户端代码。它负责将构建后的客户端代码发送给浏览器,并处理与客户端相关的请求。

服务端由 serverPluginClient 插件进行处理
代码举例:

export const clientPlugin: ServerPlugin = ({ app, config }) => {// 读取客户端代码文件内容,并替换其中的占位符const clientCode = fs.readFileSync(clientFilePath, 'utf-8').replace(`__MODE__`, JSON.stringify(config.mode || 'development')).replace(`__DEFINES__`,JSON.stringify({...defaultDefines,...config.define}))// 使用中间件处理请求app.use(async (ctx, next) => {if (ctx.path === clientPublicPath) {ctx.type = 'js'ctx.status = 200// 返回具体内容,将端口号动态替换到客户端代码中的占位符处ctx.body = clientCode.replace(`__PORT__`, ctx.port.toString())} else {// 兼容历史逻辑,并进行错误提示if (ctx.path === legacyPublicPath) {console.error(chalk.red(`[vite] client import path has changed from "/vite/hmr" to "/vite/client". ` +`please update your code accordingly.`))}return next()}})
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/66108.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JAVA日期相关操作

JAVA日期相关操作 计算两个日期相差的天数 /*** 计算两个日期相差的 天数* param smdate String类型初始时间* param bdate String类型截至时间* return Integer*/public static Integer dayCompare(String smdate, String bdate) throws Exception {Date start sdf.par…

深度学习快速入门系列---损失函数

在深度学习中,损失函数的作用是量化预测值和真实值之间的差异,使得网络模型可以朝着真实值的方向预测,损失函数通过衡量模型预测结果与真实标签之间的差异,反映模型的性能。同时损失函数作为一个可优化的目标函数,通过…

Ansible的安装和配置

安装和配置 Ansible 安装所需的软件包 创建名为 /home/greg/ansible/inventory 的静态清单文件,以满足以下要求: 172.25.250.9 是 dev 主机组的成员 172.25.250.10 是 test 主机组的成员 172.25.250.11 和 172.25.250.12 是 prod 主机组的成员 172.2…

解读spring中@Value 如何将配置转自定义的bean

实现方式 着急寻求解决方式的猿友先看这块 定义配置转化类 public class UserConverter implements Converter<String, List<User>> {Overridepublic List<User> convert(String config) {if (StringUtils.isEmpty(config)) {return Collections.emptyLis…

hive on tez资源控制

sql insert overwrite table dwintdata.dw_f_da_enterprise2 select * from dwintdata.dw_f_da_enterprise; hdfs文件大小数量展示 注意这里文件数有17个 共计321M 最后是划分为了21个task 为什么会有21个task&#xff1f;不是128M 64M 或者说我这里小于128 每个文件一个map…

从LeakCanary看Fragment生命周期监控

前文中我们已经了解到LeakCanary中Service生命销毁的监听方式&#xff0c;那么Fragment的生命周期监听又是怎么实现的呢&#xff1f; Activity生命周期监听&#xff0c;在Application里面有ActivityLifecycleCallbacks&#xff0c;那么Fragment是否相似呢&#xff1f;我们的第…

Linux 终端操作命令(2)内部命令

Linux 终端操作命令 也称Shell命令&#xff0c;是用户与操作系统内核进行交互的命令解释器&#xff0c;它接收用户输入的命令并将其传递给操作系统进行执行&#xff0c;可分为内部命令和外部命令。内部命令是Shell程序的一部分&#xff0c;而外部命令是独立于Shell的可执行程序…

【前端 | CSS】align-items与align-content的区别

align-items 描述 CSS align-items 属性将所有直接子节点上的 align-self 值设置为一个组。align-self 属性设置项目在其包含块中在交叉轴方向上的对齐方式 align-items是针对每一个子项起作用&#xff0c;它的基本单位是每一个子项&#xff0c;在所有情况下都有效果&…

并行FIR滤波器

FIR 滤波器原理 FIR 滤波器是有限长单位冲击响应滤波器&#xff0c;又称为非递归型滤波器。FIR 滤波器具有严格的线性相频特性&#xff0c;同时其单位响应是有限长的&#xff0c;因而是稳定的系统。 FIR 滤波器本质上就是输入信号与单位冲击响应函数的卷积&#xff0c;表达式…

【马蹄集】第二十二周——进位制与字符串专题

进位制与字符串专题 目录 MT2179 01操作MT2182 新十六进制MT2172 萨卡兹人MT2173 回文串等级MT2175 五彩斑斓的串 MT2179 01操作 难度&#xff1a;黄金    时间限制&#xff1a;1秒    占用内存&#xff1a;128M 题目描述 刚学二进制的小码哥对加减乘除还不熟&#xff0c;他…

剑指 Offer 61. 扑克牌中的顺子

题目描述 从若干副扑克牌中随机抽 5 张牌&#xff0c;判断是不是一个顺子&#xff0c;即这5张牌是不是连续的。2&#xff5e;10为数字本身&#xff0c;A为1&#xff0c;J为11&#xff0c;Q为12&#xff0c;K为13&#xff0c;而大、小王为 0 &#xff0c;可以看成任意数字。A 不…

Tubi 前端测试:迁移 Enzyme 到 React Testing Library

前端技术发展迅速&#xff0c;即便不说是日新月异&#xff0c;每年也都推出新框架和新技术。Tubi 的产品前端代码仓库始建于 2015 年&#xff0c;至今 8 年有余。可喜的是&#xff0c;多年来紧随 React 社区的发展&#xff0c;Tubi 绝大多数的基础框架选型都遵循了社区流行的最…