直接升级Vite 8需手动处理三处关键变更:1.确认Node.js≥20.19或≥22.12;2.修正CJS default导入为显式解构或命名导入;3.将manualChunks改用函数式写法或Rolldown原生codeSplitting配置。

直接升级到 Vite 8 是可行的,但不能只改 vite 版本号就完事——Rolldown 引擎切换、CJS 导入语义变更、manualChunks 移除这三处是真实构建失败的高发区,必须手动干预。
检查 Node.js 版本是否达标
Vite 8 要求 Node.js 20.19+ 或 Node.js 22.12+,低于这个版本会直接拒绝启动,不报错也不提示兼容方案。这不是警告,是硬性拦截。
- 运行
node -v确认当前版本 - 若为
v18.x或v20.0–v20.18,必须升级,nvm install 20.19.0或nvm use 22.12.0是唯一路径 - 旧版 Node 下即使加了
legacy: { inconsistentCjsInterop: true }也无效,该配置在 Vite 8 中已被标记弃用且不再生效
修复 CJS default 导入行为不一致问题
Vite 8 对 import xxx from 'cjs-pkg' 的解析逻辑变了:默认不再自动提取 module.exports.default,而是把整个 module.exports 当作 default 值返回——尤其在普通 .js 文件(无 "type": "module")中引入未打标 __esModule 的 CJS 包时,极易出现 TypeError: xxx is not a function。
- 先验证实际导出结构:
node -e "const m = require('cjs-pkg'); console.log(m, m.__esModule, typeof m.default)" - 若输出显示
m.__esModule === false且m.default是函数,则需显式改写导入:import { default as greet } from 'cjs-pkg'或import * as pkg from 'cjs-pkg'; const greet = pkg.default - 不要依赖
commonjsOptions.defaultIsModuleExports,它在 Rolldown 下已失效
重写 manualChunks 配置
Vite 8 彻底移除了 rollupOptions.output.manualChunks 的对象写法,旧配置会直接导致构建失败,不是警告,是报错退出。
- 原写法(Vite 7):
manualChunks: { vendor: ['react', 'react-dom'] }→ 必须删除 - 新写法仅支持函数形式,但注意:它已被官方标记为“弃用”,只是暂未移除:
manualChunks: (id) => { if (id.includes('node_modules/react')) return 'vendor' } - 推荐转向 Rolldown 原生切分:
build.rolldownOptions.codeSplitting,目前文档尚简略,但实测可用:codeSplitting: { format: 'es', manualChunks: { vendor: ['react', 'react-dom'] } }
留意 init_runtime_dom_esm_bundler 运行时错误
升级后打开页面白屏,控制台报 Uncaught ReferenceError: init_runtime_dom_esm_bundler is not defined,这是 Rolldown 早期版本(如 v8.0.0~v8.0.12)的已知 bug,与 Vue 插件初始化顺序有关。
- 临时解法:降级到
vite@8.0.13或更高稳定小版本(截至 2026-11-10,v8.0.15已修复) - 不要尝试 patch
node_modules/vite/dist,Rolldown 编译产物是二进制,无法热修 - 该错误不会出现在构建日志里,只在浏览器运行时报出,容易误判为应用代码问题
真正卡住人的从来不是“怎么升”,而是“升完为什么 dev 正常 build 报错”——Rolldown 统一了引擎,但也统一了所有底层解析逻辑,过去被 esbuild 宽容绕过的 CJS 边界、模块图歧义、动态 import 推导偏差,现在全暴露在同一个 Rust 解析器下。多花十分钟查一个包的 exports 字段,比反复重装依赖更有效。











