Vite 4.0 发布全解:Rollup 3 驱动、SWC React 插件、CSS ?inline 导入与迁移要点
Vite 4.0 于 2022 年 12 月 9 日发布,是一个以 Rollup 3 作为构建引擎、引入 @vitejs/plugin-react-swc、调整现代构建浏览器目标(默认 safari14)并弃用 CSS 默认字符串导出的大版本。本文以官方发布公告 docs/blog/announcing-vite4.md 为主体,结合当前 Vite 仓库源码(如 CSS 插件、CLI 快捷键、环境变量加载)逐项展开,帮助你在升级 Vite 4 时理解每一项变更的动机与底层实现。
发布背景:生态扩张与 Rollup 3
Vite 3 发布于 2022 年 7 月,到 Vite 4 发布时的五个月里,npm 周下载量从 100 万增长到 250 万;在 Jamstack Conf 调查中,社区使用率从 14% 升至 32%,满意度保持 9.7 的高分。同期 Astro 1.0、Nuxt 3 相继稳定发布,SvelteKit、Solid Start、Qwik City 等框架基于 Vite 创新,Storybook 7.0 将 Vite 支持作为主打特性,Vitest 的采用量也快速增长。2022 年 10 月 11 日的 ViteConf 2022 上,Rollup 团队恰于当天发布了 Rollup 3。
Vite 4 的核心引擎变更即构建阶段改用 Rollup 3,官方说明它“简化了 Vite 内部资源处理并带来许多改进”。公告同时指向了迁移指南与 Changelog,并在 docs/blog/announcing-vite5.md 中记录了后续 Vite 5 的演进脉络,可对照 docs/blog/announcing-vite3.md 了解上一版本的定位。
说明:当前仓库 packages/vite/package.json 显示的版本已是 8.x,构建引擎也演进到 Rolldown;阅读本文时应注意这是 Vite 4.0 的历史公告,但其中多数设计(如
?inline语义、CLI 快捷键、plugin-legacy)至今仍可在仓库源码中找到对应实现。
开始使用 Vite 4
官方推荐三种起步方式:
- 使用
pnpm create vite脚手架创建基于首选框架的 Vite 项目; - 使用 vite.new 在线打开已生成的模板,直接在浏览器中把玩 Vite 4;
- 使用
pnpm create vite-extra获取更多框架与运行时模板(Solid、Deno、SSR 与库脚手架)。create vite-extra的模板在运行create vite时也可以Others选项中找到。
公告特别强调:create vite 的模板定位是“在不同框架上测试 Vite 的 playground”,正式项目应优先使用各框架官方推荐的 starter(如 Vue 的 create-vue、Nuxt 3,Svelte 的 SvelteKit),部分框架甚至会在 create vite 中直接重定向到其官方 starter。当前仓库中 packages/create-vite 目录下的 template-react、template-vue、template-svelte、template-solid、template-qwik、template-lit、template-vanilla 等模板目录,正是这一策略的直接体现。
React 开发的两条路线:Babel 与 SWC
从 Vite 4 起,React 项目有两个官方插件可选,对应不同取舍:
@vitejs/plugin-react
使用 esbuild + Babel 的插件,兼顾快速 HMR、较小的包体积,并保留 Babel 转换管线的灵活性(可自由组合 Babel 插件)。
@vitejs/plugin-react-swc(Vite 4 新增)
构建阶段仍使用 esbuild,但开发阶段用 SWC 替换 Babel。SWC 的 React Fast Refresh 实现比 Babel 更快,对于不依赖非标准 React 扩展的大型项目,冷启动与 HMR 可以有显著提升。官方表示两条路线都值得长期支持,并会继续迭代改进。
浏览器兼容性:现代构建默认目标提升到 safari14
Vite 4 的现代浏览器构建默认目标从更早的版本提升到 safari14,以获得更广的 ES2020 兼容性。具体影响:
- 现代构建产物可以直接使用
BigInt; - 空值合并运算符(nullish coalescing,
??)不再被转译。
需要支持更老浏览器的项目,按惯例添加 @vitejs/plugin-legacy 即可。当前仓库中该插件位于 packages/plugin-legacy,其源码目录 packages/plugin-legacy/src 与 README 说明了它如何为不支持 ES2020 的浏览器生成 legacy 构建。
从源码结构看,Vite 内置的“构建目标 → 浏览器基线”映射表仍在维护,例如 packages/vite/src/node/plugins/css.ts 中的基线表保留了 safari14.1 等条目,与当年默认目标提升到 safari14 的决策一脉相承。
以字符串方式导入 CSS:弃用默认导出,改用 ?inline
这是 Vite 4 中最需要动手修改的行为变更。在 Vite 3 中,导入 .css 文件的默认导出可能导致 CSS 被双重加载:
import cssString from './global.css'
原因是 .css 文件本身会被作为独立资源产出,而应用代码(例如框架运行时注入)往往还会使用这个 CSS 字符串。因此从 Vite 4 起,.css 的默认导出被弃用;如果确实只需要字符串而不希望产出该 CSS 文件,必须使用 ?inline 查询后缀:
import stuff from './global.css?inline'
这一行为在当前源码中有清晰印证。packages/vite/src/node/plugins/css.ts 定义了匹配规则 const inlineRE = /[?&]inline\b/,随后的编译处理器(css.ts L587-L669)对两种情况做了分流:
- 带
?inline:dev 阶段直接返回export default ${JSON.stringify(css)}(构建阶段则先按build.cssMinify决定是否压缩,再导出字符串),并且不会把样式记入styles映射,因而不会被单独产出成 CSS 文件; - 不带
?inline:非 CSS Module 的普通 CSS 编译为“空模块”(code = '',moduleSideEffects: 'no-treeshake'),实际样式在renderChunk阶段从styles映射中取出并写入对应的 chunk CSS 文件。
这套机制同时解释了为什么 ?inline 能“不产出所导入的 CSS 样式”——它从根本上绕过了样式收集流程。若使用 CSS Modules,则 foo.module.css 导出映射对象、foo.module.css?inline 导出原始字符串,二者语义同样由 inlined 标志在 css.ts L590-L596 处区分。
环境变量:升级到 dotenv 16 与 dotenv-expand 9
Vite 4 将环境变量解析从 dotenv 14 / dotenv-expand 5 升级到 dotenv 16 / dotenv-expand 9。新版本解析规则变化带来一个实际迁移点:值中包含 # 或反引号 ` 时必须加引号:
-VITE_APP=ab#cd`ef
+VITE_APP="ab#cd`ef"
未加引号时 # 会被视为注释起始,导致值被截断。加载逻辑位于 packages/vite/src/node/env.ts,该文件引入 dotenv-expand 的 expand 函数,使环境变量可以引用彼此(源码注释明确说明“let environment variables use each other”);仓库根目录的 patches/dotenv-expand@13.0.0.patch 也印证了这条依赖链在当前仓库中依然被持续维护与打补丁。
其他特性:CLI 快捷键、构建日志与 SSR 错误信息
Vite 4 公告还列出以下改进:
- CLI 快捷键:dev 运行时按
h查看全部快捷键; - pre-bundling 时支持 patch-package:依赖预打包流程能够识别并应用 patch-package 的补丁;
- 更干净的构建日志,且体积单位切换为
kB,与浏览器开发者工具保持一致; - SSR 阶段更友好的错误信息。
CLI 快捷键的实现见 packages/vite/src/node/shortcuts.ts:BASE_DEV_SHORTCUTS 定义了 dev 服务器默认快捷键——r 重启服务器(restartServerWithUrls)、u 打印服务器 URL、o 在浏览器中打开、c 清除控制台、q 退出;preview 服务器则有独立的 BASE_PREVIEW_SHORTCUTS(o、q)。输入 h 时,onInput 处理器 会遍历全部快捷键并打印“press key + enter to ...”的帮助列表。此外 bindCLIShortcuts 支持 customShortcuts 选项,允许插件注册自定义快捷键,同名键时自定义优先级更高(h 除外),设 action: undefined 可禁用某个默认快捷键。
更小的安装体积
Vite 持续在意自身体积,以加快文档 playground、复现仓库等场景的安装速度。Vite 4 的安装体积相比 Vite 3.2.5 缩小 23%(14.1 MB 对 18.3 MB)。
Vite Core 治理变化
框架插件移出核心 monorepo
@vitejs/plugin-vue 与 @vitejs/plugin-react 自 Vite 早期版本起与核心同仓,便于 Core 与插件同步测试、同步发布并获得紧密反馈。引入 vite-ecosystem-ci 之后,这种反馈机制在独立仓库中同样成立,因此从 Vite 4 起两个框架插件被移出 Vite 核心 monorepo,各自独立维护。官方建议:提交 bug 或功能请求时,请转到各自新仓库(vitejs/vite-plugin-vue、vitejs/vite-plugin-react)开 issue。这强化了 Vite “框架无关”的立场,也为每个插件组建独立维护团队铺路。
vite-ecosystem-ci 的持续改进
vite-ecosystem-ci 扩展了 Vite 的 CI 能力,对大多数主流下游项目的 CI 状态提供按需报告:每周对 Vite 主分支运行三次,在引入回归前及时收到反馈;也可在 PR 评论中用 /ecosystem-ci run 按需触发,先了解变更影响再合入主分支。Vite 4 发布时,多数下游项目已准备好兼容分支并陆续发布。
致谢与后续
Vite 4 是社区大量贡献者(其中许多同时维护下游项目与插件)与 Vite 团队共同努力的成果,团队也对赞助 Vite 的个人与公司、以及将 Vite 投入直接纳入工作(如 Nuxt Labs、Astro、StackBlitz 相关贡献者)表示感谢。发布后的首要工作是分诊新 issue、避免回归;社区也欢迎更多人参与 issue 分诊、完善文档并在 Discord 社区帮助他人。
从当前仓库状态看,Vite 4 确立的这些机制仍在延续:?inline 的 CSS 字符串语义、h 快捷键体系、plugin-legacy 独立包、dotenv 环境变量加载与补丁维护,都可以在 packages/vite 与 packages/plugin-legacy 中找到对应的现行实现,这也是理解后续版本演进的良好起点。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
