Vite 6 升级排障:真正的断点是默认值重排,不是 Environment API
2024-11-26 发布 Vite 6.0,官方称之为 Vite 2 之后最大主版本,引入了实验性 Environment API。但按官方迁移说明,多数项目「升级就是改个版本号」。实际升级时咬人的反而是几个默认值调整:它们不报错、不告警,却会静默改变解析结果。下面按踩坑概率排列,记录关键断点和取舍。
涉及材料:官方 v6 迁移指南(英文 / 中文),vitejs/vite CHANGELOG 6.0.0(仓库:vitejs/vite,文档:cn.vite.dev,迁移指南 v6.vite.dev/guide/migration)。
一、resolve.conditions 默认值改变:最典型的静默断点 #18395
Vite 5 里 resolve.conditions 默认 [],内部再补条件;ssr.resolve.conditions 默认继承 resolve.conditions。Vite 6 起这些内部补充没了,必须显式写进配置。
不再由内部添加的默认值:
resolve.conditions = ['module', 'browser', 'development|production']ssr.resolve.conditions = ['module', 'node', 'development|production']
同时 ssr.resolve.conditions 不再以 resolve.conditions 为默认。其中 development|production 是特殊变量,按 process.env.NODE_ENV 替换。这些默认值已从 Vite 导出为 defaultClientConditions / defaultServerConditions。
如果你自定义过 resolve.conditions,例如原来是:
resolve: {
conditions: ['custom']
}
升级后必须改成:
import { defaultClientConditions } from 'vite'
resolve: {
conditions: ['custom', ...defaultClientConditions]
}
否则你的自定义值会直接顶掉默认值,node / browser 等条件不再命中,依赖解析会走到意想不到的 export 分支上。
机制:Vite 读依赖 package.json 的 exports map,按条件列表顺序决定 import 解析到哪个文件。Vite 6 重排了默认列表,module 相比 browser 更早被查询。对于同时发布 ESM module 构建和 browser 专用构建的双发布包,可能静默翻转为打包到另一个文件。多数情况下无害,偶尔表现为「dev 正常、Node 测试里坏」或某个 polyfill 不再被应用。因为两条解析路径都合法,所以没有告警——只能升级后重跑 ESM/CJS 互操作相关测试,若发现某包行为回归,就显式拼出 resolve.conditions 固定解析方式,而不是继承新默认值。
二、JSON stringify 默认改为 'auto' #18303
Vite 5 中 json.stringify: true 会禁用 json.namedExports。Vite 6 起即使 stringify: true,namedExports 仍保留并尊重该值;要恢复老行为需设置 json.namedExports: false。
新增默认值 'auto':只在 JSON 文件满足可序列化条件时把数据内联成 JSON.parse("...") 形式,避免小 JSON 生成独立模块。后续修复补了一条:对数组不做 stringify(#18541)。想关闭就设 json.stringify: false。
三、Sass 默认改用现代 API #17937
Vite 5 默认 legacy API,Vite 6 起默认 modern / modern-compiler API。想退回老行为:
css: {
preprocessorOptions: {
scss: { api: 'legacy' }
}
}
注意 legacy 支持会在 Vite 7 移除。自定义 importer 缺失 source map 时的告警处理也变了;项目里用了 additionalData 的话,升级后要重测。
四、postcss-load-config 从 v4 升 v6 #15235
TypeScript postcss 配置现在需要 tsx 或 jiti 加载(不再是 ts-node);YAML postcss 配置需要 yaml 包。另外 postcss 配置只从 workspace 根加载(#18440)。
五、库模式 CSS 输出文件名变化 #18488
Vite 5 库模式 CSS 固定输出 style.css。Vite 6 默认使用 package.json 的 name 字段(与 JS 输出一致);build.lib.fileName 为字符串时同名规则也用于 CSS。要显式区分可设 build.lib.cssFileName。依赖 style.css 的引用方要么改成新文件名,要么显式指定:
build: {
lib: {
cssFileName: 'style'
}
}
六、SSR dev 不再注入 CSS 的默认 import #17922
对 CSS 默认导入的支持在 Vite 4 弃用、Vite 5 移除,但 SSR dev 模式意外地仍然支持。Vite 6 一并移除,修正了 dev/build 行为不一致的问题。如果你在 SSR dev 里仍靠 import './style.css' 拿副作用,升级后会失效。
七、其余影响少数人的变更
build.cssMinify默认改为esbuild,SSR 构建时也会压缩 CSS(#15637)- glob 引擎从 fast-glob 换成 tinyglobby(#18243),范围大括号
{01..03}、增量大括号{2..8..2}不再支持;import.meta.glob、optimizeDeps.include都受影响 - chokidar 升级 v4(#18453),移除
fs.cachedChecks(#18493) - proxy bypass 现在也用于 WebSocket 升级请求(#18070),
req的res可能为undefined - 任意协议 URL 一律视为 external(#17369)
.git目录默认进入 deny 列表(#18382)- 环境变量命名约束收紧(#18255)
- Node 21 支持移除;最低版本调整为 18.18 / 20.19 / 22.12(#18729)
- dotenv-expand v12:用于插值的变量必须先声明(#18697)
minify: 'terser'最低要求 terser 5.16.0(#18209)
插件 / SSR 迁移建议
Environment API 仍属实验性。稳妥姿势:对已发布的插件继续读旧的 ssr 布尔,别急着切 this.environment;新写的分支按 this.environment.name 走,免得以后积累一堆要迁的代码。低层 API 有变,例如 server.moduleGraph 改为按环境访问:server.environments.client.moduleGraph。Vite Runtime API(5.1 引入)演进为 Module Runner API,属实验性且非破坏性移除。