Vite: 近几个版本的更新

概述

  • 在 2021 年 2 月,尤大正式推出了 Vite 2.0 版本,可以说是 Vite 的一个重要转折点,自此之后 Vite 的用户量发生了非常迅速的增长,很快达到了每周 100 万的 npm 下载量。同时,Vite 的社区也越来越活跃,目前已经形成非常庞大的社区生态(详情可见Github 地址),给整个前端领域带来了诸多的改变,如:
  • Nuxt 3、SvelteKit、Astro、StoryBook 等在内的各大前端框架已经将 Vite 作为内置的构建方案。
  • 基于 Vite 的测试工具 Vitest 诞生,成为替代 Jest 的新一代测试方案。

如今已经 2024 年 7 月,距离 v2 版本已经发布了 16 个月的时间,Vite 正式推出 5.x 版本

一、全新的 VitePress 文档

对于用户侧来说,谈到框架的更新,文档自然是最重要的部分。现在你可以直接
去 vitejs.dev 站点体验到 v3 版本的文档,目前文档同样是使用 VitePress 进行搭建。下面是一张截图:

在这里插入图片描述
不光是 Vite,也有 Vite 生态中其它的一些项目使用 VitePress 进行文档站点的搭建,比如 Vitest, vite-plugin-pwa 以及 VitePress 自身的文档,我也十分推荐大家使用 VitePress 作为自己的文档建站方案之一。如果你需要查看 Vite 3.0 的文章,也可以访问 v3.vitejs.dev

二、开发阶段的更新


1 )CLI 的更新

在执行 vite 命令启动项目时,终端的界面和之前会有所不同,而更重要的是,为了避免 Vite 开发服务的端口和别的应用冲突,默认的端口号从之前的 3000 变成了 5173

在这里插入图片描述
2 ) 开箱即用的 WebSocket 连接策略

Vite 2 中有存在一个痛点,即在存在代理的情况下(比如 Web IDE)需要我们手动配置WebSocket 使 HMR 生效。目前 Vite 内置了一套更加完善的 WebSocket 连接策略,自动满足更多场景的 HMR 需求。

3 ) 服务冷启动性能提升

Vite 3.0 在服务冷启动方面做了非常多的工作,来最大程度提升项目启动的速度。首先我们来盘点一下 Vite 2.x 阶段服务冷启动的一些问题。从 Vite 2.0 到 2.9 版本之前,Vite 会在服务启动之前进行依赖预构建,也就是使用Esbuild 将项目中使用到的依赖扫描出来(Scan),然后分别进行一次打包(Optimize)

在这里插入图片描述
这样会造成两个问题:

  • 依赖预构建会阻塞 Dev Server 启动,但其实不阻塞的情况下,Dev Server 也可以
    正常启动。
  • 当某些 Vite 插件手动注入了 import 语句,比如调用 babel-plugin-import 添加 import Button from ‘antd/lib/button’ ,就会导致 Vite 的二次预构建,因为 antd/lib/button 的引入代码由 Vite 插件注入,属于 Dev Server 运行时发现的依赖,冷启动阶段无法扫描到。

所谓的二次预构建包含两个步骤,一是需要将所有的依赖全量预构建,二是由于依赖更新,页面需要进行 reload,加载最新的依赖代码。这样会导致 Dev Server 性能明显下降,尤其是在新增依赖较多的场景下,很容易出现浏览器 卡住 的情况。因此二次预构建也是需要极力避免的。当时 vite-plugin-optimize-persist 就是为了解决二次预构建带来的问题,通过持久化的方式记录 Dev Server 运行时扫描到的依赖,从而让首次预构建便可以感知到,避免二次预构建的发生。

到了 2.9 版本,Vite 将预构建的逻辑做了一次整体的重构,最后的效果是下面这样的:

  • Dev Server 启动后预构建(Optimize 阶段)在后台执行,也就是预构建不再阻塞Dev Server 的启动,只需要等待 Scan 阶段完成,不过通常这个阶段的开销非常小。
  • 如果某些依赖是 Dev Server 运行时才发现的,那么 Vite 会尽可能地复用已有预构建产物,尽量不进行 page reload。具体实现大家可以去查看这个 PR

那问题就完全解决了吗?其实并不是,在某些场景下,Vite 仍然不可避免地需要二次预构建。如下面的这个例子:

A 和 B 都是项目的第三方依赖,它们也同时依赖 C。那么当 Vite 预构建 A 的时候,将会 A 和 C 一起进行打包。但 Vite 在运行时发现了依赖 B,而 A 和 B 需要共享 C 的代码,这样 C 的代码可能就会被抽离成一个公共的 chunk,因此之前 A 的预构建产物可能就发生变化了,那么此时 Vite 必须要强制刷新页面,让浏览器使用最新的预构建产物。这仍然是一个二次预构建(所有依赖再次打包 + page reload)的过程。总体而言,2.9 版本解决了预构建阻塞服务启动的问题,但并没有完全解决二次预构建的问题。但在 Vite 3.0,二次预构建的问题也得到了根本的解决。那 Vite 3.0 是如何做到的呢?

核心的解决思路在于 延迟处理 ,即把预构建的行为延迟到页面加载的最后阶段进行,此时 Vite 已经编译完了所有的源文件 可以准确地记录下所有需要预构建的依赖(包括Vite 插件添加的一些依赖),然后统一进行预构建,将预构建的产物响应给给浏览器即可。

依赖预构建的代码在 Vite 中先后重构了多次,目前的版本实现比较复杂,后续会单独写一篇文章讨论实现细节。

因此,与 Vite 2.0 相比,Vite 3.0 在冷启动阶段所做的优化主要有两个方面:

  • 预构建不再阻塞 Dev Server 的启动,真正做到服务秒启动的效果;
  • 从根本上防止二次预构建的发生。

4 )import.meta.glob 语法更新

Vite 3.0 中重写对 import.meta.glob 的实现进行了重写,支持了更加灵活的 glob 语法,增加了如下的一些特性:

  • 多种模式匹配: import.meta.glob(["./dir/*.js", "./another/*.js"]);
  • 否定模式( ! ): import.meta.glob(["./dir/*.js", "!**/bar.js"]);
  • 命名导入,可以更好地做到 Tree Shaking: import.meta.glob("./dir/*.js", { import: "setup" });
  • 自定义 query 参数: import.meta.glob("./dir/*.js", { query: { custom: "data" } });
  • 指定 eager 模式,替换掉原来 import.meta.globEager : import.meta.glob("./dir/*.js", { eager: true });

三、生产阶段的更新

1 ) SSR 产物默认使用 ESM 格式

在当下的社区生态中,众多 SSR 框架已经在使用 ESM 格式作为默认的产物格式。Vite 3.0 也积极拥抱社区,支持 SSR 构建默认打包出 ESM 格式的产物。

2 ) Relative Base 支持
Vite 3.0 正式支持 Relative Base(即配置 base: ‘’ ),主要用于构建时无法确定 base 地址的场景。

四、实验性功能

1 ) 更细粒度的 base 配置

在某些场景下,我们需要将不同的资源部署到不同的 CDN 上,比如将图片部署到单独的 CDN,和 JS/CSS 的部署服务区分开来。但 2.x 的版本仅支持统一的部署域名,即 base 配置。在 3.0 中,你可以通过 renderBuiltUrl 进行更细粒度的配置:

{experimental: {renderBuiltUrl: (filename: string, { hostType: 'js' | 'css' | 'html' }) => {if (hostType === 'js') {return { runtime: `window.__toCdnUrl(${JSON.stringify(filename)})` }} else {return 'https://cdn.domain.com/assets/' + filename}}}
}

具体文档见 vitejs.dev/guide/build…

2 ) Esbuild 预构建用于生产环境

这应该是 Vite 架构上非常大的一个改动: 将原来仅仅用于开发阶段的依赖预构建功能应用在生产环境 在 Vite 2 x 中 开发阶段使用 Esbuild 来打包依赖 而在生产环境使用

Rollup 进行打包,用 @rollupjs/plugin-commonjs 来处理 cjs 的依赖,这样做会导致依赖处理的不一致问题,造成一些生产构建中的 bug。

但 Vite 3.0 中支持通过配置将 Esbulid 预构建同时用于开发环境和生产环境,仅添加 optimizeDeps.disabled: false 的配置即可。不过这个改动确实比较大,Vite 团队不打算将此作为 v3 的正式更新内容,而是一个实验性质的功能,不会默认开启。

顺便提一句,Rollup 发布 v3 的大版本,要知道,Rollup 2.0 发布至今已经过去很多年的时间了,无论是 Rollup 还是 Vite 来讲,这都是一次非常重大的变更。由于 Vite 的架构非常依赖 Rollup,在 Rollup 发布 v3 之后 对应着 Vite 跟随着发布的第 4 个 major 版本

Vite 4.0 相比于 Vite 3.0 的进步和更新

  • 升级 Rollup:
    • Vite 4.0 最大的变化是升级了 Rollup 到版本 3。由于 Vite 和 Rollup 同步了主要版本的发布,因此也停止了对旧版 Node.js 的支持,要求使用 Node 14.18+ 及以上版本。
  • 构建工具变化:
    • 弃用了 import.meta.globEager,推荐使用 import.meta.glob(‘*’, { eager: true }) 来代替。增加了对否定模式的支持,可以在 import.meta.glob 中使用 ! 前缀来忽略某些特定文件。
  • 性能优化:
    • 改进了代码分割和 tree-shaking,允许指定命名导入以改进 tree-shaking。增强了开发服务器性能,例如对冷启动和热模块替换速度的改进。
  • 生态系统支持:
    • 采用了由 Arnaud Barre 最初创建的基于 SWC 的 React 插件,提高了 React 项目的构建效率和热更新性能。
    • 增加了对 Lightning CSS 的实验性支持,这是一个使用 Rust 编写的快速 CSS 编译工具,可以加快 CSS 的处理速度。
  • 调试体验:
    • 提升了 source map 的调试体验,与 Chrome Devtools 团队合作修复了一些长期存在的路径显示问题。
  • 其他更新:
    • 添加了 Solid 和 Qwik 模板到 create-vite 中。在安全性和配置上也有一些小改动,如要求在使用 HTTPS 时需要合法可用的证书。

Vite 5.0 相比于 Vite 4.0 的进步和更新

  • 升级 Rollup:
    • Vite 5.0 使用了 Rollup 4,这代表了构建性能的大幅提升。
  • 开发体验优化:
    • 实现了更快速的冷启动时间,利用 ES Module 的特性,使开发者能够更迅速地在浏览器中看到修改的效果。改进了热模块替换(HMR)的性能,进一步提升了开发效率。
  • 框架支持:
    • 增强了对 Vue 3 和 React 的支持,使得开发者可以更加方便地使用这些框架进行项目开发。
  • 多页应用支持:
    • 提供了对多页应用的支持,简化了多页应用的开发配置。
  • 插件系统:
    • 拥有一个灵活的插件系统,允许开发者通过插件扩展构建过程,使得项目的构建配置更加灵活可定制。
  • 生态系统集成:
    • 集成了 VuePress,这是一个基于 Vite 的静态网站生成器,用于快速构建文档和静态网站。
      提供了全局命令行工具,使得创建、启动和构建项目更加方便。
  • API 和工具更新:
    • 正在弃用 CommonJS API,鼓励使用 ESM API,并与大多数相关项目合作推动这一转变。

五、仓库内部的变化

除了本身功能上的演进,Vite 的仓库本身也产生了不少的变化,从中我们也能了解到社区的一些动向:

  • 不再支持 Nodejs 12,需要 Node.js 14.18+ 的版本。
  • 单元测试和 E2E 测试从 Jest 完全迁移到 Vitest,一方面 Vitest 更快、体验更好,另一方面也能在 Vite 这样大型的仓库完善 Vitest 的生态,进一步提升 Vitest 稳定性。
  • VitePress 文档部分也参与 CI 流程。
  • 包管理器 pnpm 迁移至 v7。
  • 不管是 Vite 本身的包还是 E2E 中测试的项目,都在 package.json 中声明 type: “module” ,即 Pure ESM 包,对外提供 ESM 格式的产物,将社区 Pure ESM 的趋势又推动了一步。
  • 官方所有的 Vite 插件都采用 unbuild (新一代库构建工具) 进行构建, pluin-vuejsx 和 plugin-legacy 均迁移到了 TS 上。
  • 包体积优化。3.0 进一步优化 Vite 本身的产物和 node_modules 体积,将 terser 和 node-forge 的依赖移除,让用户进行按需安装( node-forge 的功能是实现 https 证书生成,可用 @vitejs/plugin-basic-ssl 插件替代),效果如下:

不得不说在自身包体积的优化方面, Vite 还是做的很细致的,这也是很多库开发者忽视的一点,有时候加个插件就得安装动辄上百 MB 的依赖,导致项目的 node_modules 最后变得非常臃肿,此时不妨学习一下 Vite 是怎么优化自身体积的。

六、未来规划

首先在 Vite 3.0 发布之后会重点保证 3.0 的稳定性,解决目前的一系列 issue, 其次,Rollup 团队将在接下来的几个月发布新的 major 版本,Vite 将持续跟进,紧接着发布 v4 版本,并在 v4 版本中将目前的一些实践性功能稳定下来, Vite 4.0 和 Vite 5.0 相比于 Vite 3.0 在构建性能、生态系统支持、开发体验、框架兼容性以及插件系统等方面都有了显著的进步和更新。这些更新不仅提升了开发者的开发效率,还增强了项目的可维护性和可扩展性。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

HTTP协议格式

目录 正文: 1.概述 2.主要特点 3.请求协议格式 4.响应协议格式 5.响应状态码 总结: 正文: 1.概述 HTTP 协议是用于传输超文本数据(如 HTML)的应用层协议,它建立在传输层协议 TCP/IP 之上。当我们在…

stm32定时器与pwm波

文章目录 4 TIM4.1 SysTick系统定时器4.2 TIM定时器中断与微秒级延时4.3 TIM使用PWM波4.3.1 PWM介绍4.3.2 无源蜂鸣器实现 4.4 TIM ,PWM常用函数 4 TIM 4.1 SysTick系统定时器 ​ Systick系统滴答,(同时他有属于自己的中断,可以利用它来做看…

Unity 使用AVProMovieCapture实现Game视图屏幕录制

内容将会持续更新,有错误的地方欢迎指正,谢谢! Unity 使用AVProMovieCapture实现Game视图屏幕录制 TechX 坚持将创新的科技带给世界! 拥有更好的学习体验 —— 不断努力,不断进步,不断探索 TechX —— 心探索、心…

【二】Ubuntu24虚拟机在Mac OS的VMware Fusion下无法联网问题

文章目录 1.环境背景2. 需求背景3. 解决方法3.1 在mac的终端查看虚拟机NAT网络3.2 查看unbuntu节点2的网络配置3.3 问题定位与解决3.3.1 检查是否有冲突3.3.2 冲突解决方法 4. 总结4.1 NAT 网关的原理4.2 VMware Fusion 的 NAT 模式4.3 为什么网关冲突会引起问题4.4 理解配置冲…

Linux 程序卡死的特殊处理

一、前言 Linux环境。 我们在日常编写的程序中,可能会出现一些细节问题,导致程序卡死,即程序没法正常运行,界面卡住,也不会闪退... 当这种问题出现在客户现场,那就是大问题了。。。 当我们暂时还无法排…

利用 STM32 实现多协议物联网网关:Modbus/Zigbee 到以太网/Wi-Fi 的数据桥接

摘要: 随着物联网技术的飞速发展,不同通信协议之间的互联互通成为了构建智能化系统的一大挑战。本文将以实战项目为例,详细介绍如何利用 STM32 微控制器实现 Modbus/Zigbee 与以太网/Wi-Fi 之间的协议转换,从而打通传感器数据上传至服务器的“…

代码随想录Day69(图论Part05)

并查集 // 1.初始化 int fa[MAXN]; void init(int n) {for (int i1;i<n;i)fa[i]i; }// 2.查询 找到的祖先直接返回&#xff0c;未进行路径压缩 int.find(int i){if(fa[i] i)return i;// 递归出口&#xff0c;当到达了祖先位置&#xff0c;就返回祖先elsereturn find(fa[i])…

实现沉浸式体验的秘诀:深入了解折幕投影技术!

在当今多媒体技术的浪潮中&#xff0c;投影技术已蜕变成为超越传统内容展示范畴的非凡工具&#xff0c;它深度融合了互动性与沉浸感&#xff0c;成为连接观众与虚拟世界的桥梁。折幕投影技术&#xff0c;作为这一领域的璀璨明珠&#xff0c;更是以其独特而神奇的手法&#xff0…

如何从相机的存储卡中恢复原始照片

“不好了。” 当您意识到自己不小心从存储卡中删除了照片&#xff0c;或者错误地格式化了相机的记忆棒时&#xff0c;您首先会喊出这两个词。这是一种常见的情况&#xff0c;每个人一生中都会遇到这种情况。幸运的是&#xff0c;有办法从相机的 RAW 记忆棒中恢复已删除的照片。…

笛卡尔集的情况 rows 1

running ~ 1 hour and TEMP Space using > 450 GB 1000*4.9k4.9M 1*4.9K4.9K

【LabVIEW学习篇 - 3】:程序结构——顺序结构、for循环、while循环

文章目录 顺序结构案例一案例二 for循环while循环 顺序结构 LabVIEW中的顺序结构是一种常用的控制结构&#xff0c;用于按顺序执行程序的不同部分。顺序结构在程序中按照从左到右的顺序依次执行各个子结构&#xff0c;类似于传统的文本编程语言中的顺序执行。 案例一 案例一…

查询数据库下所有表的数据量

个人思路: 首先把库里Schema下表名拿出来放记事本(EmEditor)里, 用一下正则匹配替换 (\w) → select \1 tableName,count(1) from \1 union all 然后把最后的union all删除掉,替换为order by tableName

C++部分复习笔记上

C语法复习 1. C入门基础 缺省参数 半缺省参数必须从右往左依次来给出&#xff0c;不能间隔着给缺省参数不能在函数声明和定义中同时出现缺省值必须是常量或者全局变量C语言不支持&#xff08;编译器不支持&#xff09; 函数重载 函数重载是函数的一种特殊情况&#xff0c;…

红薯小眼睛接口分析与Python脚本实现

文章目录 1. 写在前面2. 接口分析3. 算法脚本实现 【&#x1f3e0;作者主页】&#xff1a;吴秋霖 【&#x1f4bc;作者介绍】&#xff1a;擅长爬虫与JS加密逆向分析&#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Py…

数据库系统原理练习 | 作业2-第2章关系数据库(附答案)

整理自博主本科《数据库系统原理》专业课完成的课后作业&#xff0c;以便各位学习数据库系统概论的小伙伴们参考、学习。 *文中若存在书写不合理的地方&#xff0c;欢迎各位斧正。 专业课本&#xff1a; 目录 一、选择题 二、填空题 三、简答题 四、关系代数 1.课本p70页&…

Vatee万腾平台:引领智能互联新时代

在科技浪潮的推动下&#xff0c;我们正步入一个前所未有的智能互联新时代。在这个时代里&#xff0c;万物皆可互联&#xff0c;数据成为新的生产要素&#xff0c;智能技术深刻改变着人类社会的每一个角落。而Vatee万腾平台&#xff0c;正是这一新时代的引领者&#xff0c;以其卓…

盘点各个国家的国宝

中国&#xff1a;熊猫 熊猫已有800万年的历史&#xff0c;和它们同时代的动物都已灭绝&#xff0c;大熊猫生存至今成为“活化石”。 俄罗斯&#xff1a;北极熊 北极熊是世界上最大的陆地食肉动物&#xff0c;体型巨大&#xff0c;性格凶猛。 美国&#xff1a;白头海雕 白头海雕…

事件分发机制:demo复现自定义ViewGroup点击事件不起作用

几年前遇到的一个bug&#xff0c;不弄清楚心里就是不舒服&#xff01; 平时应用开发中&#xff0c;经常遇到的UI需求&#xff0c;例如抖音的设置界面&#xff0c;如下图所示&#xff1a; 很容易想到&#xff0c;自定义一个Layout&#xff0c;左边一个图标&#xff0c;中间文…

二维树状数组区域查询

落谷4514 过关代码如下 #define _CRT_SECURE_NO_WARNINGS #include<bits/stdc.h> using namespace std; //#define int long longconst int N 2050; int t1[N][N], t2[N][N], t3[N][N], t4[N][N]; int lowbit(int x) { return x & (-x); } int n, m; void update(…

@Slf4j idea标红Cannot resolve symbol ‘log‘

一、背景 时间久了没有应用idea,打开工程后项目 log 提示报红&#xff0c;未能解析&#xff0c;Cannot resolve symbol log &#xff0c;Slf4j 注解正常&#xff0c;应用的lombok插件。 检查lombok插件安装情况&#xff0c;发现未安装&#xff0c;重新安装重启idea后正常。 二…