编程 Vite 6 升级排障:真正的断点是默认值重排,不是 Environment API

2026-09-10 00:04:00

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.jsonexports 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: truenamedExports 仍保留并尊重该值;要恢复老行为需设置 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 配置现在需要 tsxjiti 加载(不再是 ts-node);YAML postcss 配置需要 yaml 包。另外 postcss 配置只从 workspace 根加载(#18440)。

五、库模式 CSS 输出文件名变化 #18488

Vite 5 库模式 CSS 固定输出 style.css。Vite 6 默认使用 package.jsonname 字段(与 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.globoptimizeDeps.include 都受影响
  • chokidar 升级 v4(#18453),移除 fs.cachedChecks#18493
  • proxy bypass 现在也用于 WebSocket 升级请求(#18070),reqres 可能为 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,属实验性且非破坏性移除。

推荐文章

程序员茄子在线接单