迁移指南
从 v7 迁移
如果你正在从 rolldown-vite(Rolldown 集成 Vite 的 v6 和 v7 技术预览版)迁移,只需关注标题中带有
默认浏览器目标变更
build.target 的默认值和 'baseline-widely-available' 已更新到更新的浏览器版本:
- Chrome 107 → 111
- Edge 107 → 111
- Firefox 104 → 114
- Safari 16.0 → 16.4
这些浏览器版本与截至 2026-01-01 的 Baseline Widely Available 功能集保持一致。换句话说,它们大约在两年半前发布。
Rolldown
Vite 8 使用基于 Rolldown 和 Oxc 的工具,而非 esbuild 和 Rollup。
渐进式迁移
rolldown-vite 包使用 Rolldown 实现了 Vite 7,但不包含 Vite 8 的其他变更。这可以作为迁移到 Vite 8 的中间步骤。请参阅 Vite 7 文档中的 Rolldown 集成指南,了解如何从 Vite 7 切换到 rolldown-vite。
对于从 rolldown-vite 迁移到 Vite 8 的用户,可以撤销 package.json 中的依赖变更并更新到 Vite 8:
json
{
"devDependencies": {
"vite": "npm:rolldown-vite@7.2.2" // [!code --]
"vite": "^8.0.0" // [!code ++]
}
}
依赖优化器现在使用 Rolldown
依赖优化现在使用 Rolldown 而非 esbuild。Vite 仍然支持 optimizeDeps.esbuildOptions 以向后兼容,会自动将其转换为 optimizeDeps.rolldownOptions。optimizeDeps.esbuildOptions 现已弃用,将在未来移除,我们鼓励你迁移到 optimizeDeps.rolldownOptions。
以下选项会自动转换:
esbuildOptions.minify->rolldownOptions.output.minifyesbuildOptions.treeShaking->rolldownOptions.treeshakeesbuildOptions.define->rolldownOptions.transform.defineesbuildOptions.loader->rolldownOptions.moduleTypesesbuildOptions.preserveSymlinks->!rolldownOptions.resolve.symlinksesbuildOptions.resolveExtensions->rolldownOptions.resolve.extensionsesbuildOptions.mainFields->rolldownOptions.resolve.mainFieldsesbuildOptions.conditions->rolldownOptions.resolve.conditionNamesesbuildOptions.keepNames->rolldownOptions.output.keepNamesesbuildOptions.platform->rolldownOptions.platformesbuildOptions.plugins->rolldownOptions.plugins(部分支持)
你可以通过 configResolved 钩子获取兼容层设置的选项:
js
const plugin = {
name: 'log-config',
configResolved(config) {
console.log('options', config.optimizeDeps.rolldownOptions)
},
},
JavaScript 转换由 Oxc 完成
JavaScript 转换现在使用 Oxc 而非 esbuild。Vite 仍然支持 esbuild 选项以向后兼容,会自动将其转换为 oxc。esbuild 现已弃用,将在未来移除,我们鼓励你迁移到 oxc。
以下选项会自动转换:
esbuild.jsxInject->oxc.jsxInjectesbuild.include->oxc.includeesbuild.exclude->oxc.excludeesbuild.jsx->oxc.jsxesbuild.jsx: 'preserve'->oxc.jsx: 'preserve'esbuild.jsx: 'automatic'->oxc.jsx: { runtime: 'automatic' }esbuild.jsxImportSource->oxc.jsx.importSource
esbuild.jsx: 'transform'->oxc.jsx: { runtime: 'classic' }esbuild.jsxFactory->oxc.jsx.pragmaesbuild.jsxFragment->oxc.jsx.pragmaFrag
esbuild.jsxDev->oxc.jsx.developmentesbuild.jsxSideEffects->oxc.jsx.pure
esbuild.define->oxc.defineesbuild.banner-> 使用 transform 钩子的自定义插件esbuild.footer-> 使用 transform 钩子的自定义插件
esbuild.supported 选项不受 Oxc 支持。如果你需要此选项,请参阅 oxc-project/oxc#15373。
你可以通过 configResolved 钩子获取兼容层设置的选项:
js
const plugin = {
name: 'log-config',
configResolved(config) {
console.log('options', config.oxc)
},
},
目前,Oxc 转换器不支持降低原生装饰器的编译目标,因为我们正在等待规范的进展,参见(oxc-project/oxc#9170)。
:::: details 降低原生装饰器编译目标的临时方案
你可以暂时使用 Babel 或 SWC 来降低原生装饰器的编译目标。
使用 Babel:
code-group
bash$ npm install -D @rolldown/plugin-babel @babel/plugin-proposal-decorators
bash$ yarn add -D @rolldown/plugin-babel @babel/plugin-proposal-decorators
bash$ pnpm add -D @rolldown/plugin-babel @babel/plugin-proposal-decorators
bash$ bun add -D @rolldown/plugin-babel @babel/plugin-proposal-decorators
bash$ deno add -D npm:@rolldown/plugin-babel npm:@babel/plugin-proposal-decorators
ts [vite.config.ts]
import { defineConfig } from 'vite'
import babel from '@rolldown/plugin-babel'
function decoratorPreset(options: Record<string, unknown>) {
return {
preset: () => ({
plugins: [['@babel/plugin-proposal-decorators', options]],
}),
rolldown: {
// 仅当文件包含装饰器时运行此转换
filter: {
code: '@',
},
},
}
}
export default defineConfig({
plugins: [babel({ presets: [decoratorPreset({ version: '2023-11' })] })],
})
使用 SWC:
code-group
bash$ npm install -D @rollup/plugin-swc @swc/core
bash$ yarn add -D @rollup/plugin-swc @swc/core
bash$ pnpm add -D @rollup/plugin-swc @swc/core
bash$ bun add -D @rollup/plugin-swc @swc/core
bash$ deno add -D npm:@rollup/plugin-swc npm:@swc/core
js
import { defineConfig, withFilter } from 'vite'
import swc from '@rollup/plugin-swc'
export default defineConfig({
// ...
plugins: [
withFilter(
swc({
swc: {
jsc: {
parser: { decorators: true, decoratorsBeforeExport: true },
transform: { decoratorVersion: '2023-11' },
},
},
}),
// 仅当文件包含装饰器时运行此转换
{ transform: { code: '@' } },
),
],
})
:> #### esbuild 回退
Vite 不再直接使用
esbuild,它现在是可选依赖。如果你使用的插件依赖transformWithEsbuild函数,你需要将esbuild安装为devDependency。transformWithEsbuild函数已弃用,将在未来移除。我们建议迁移到新的transformWithOxc函数。JavaScript 压缩由 Oxc 完成
JavaScript 压缩现在使用 Oxc 压缩器而非 esbuild。你可以使用已弃用的
build.minify: 'esbuild'选项切换回 esbuild。此配置选项将在未来移除,因为 Vite 不再直接依赖 esbuild,你需要将esbuild安装为devDependency。如果你之前使用
esbuild.minify*选项来控制压缩行为,现在可以使用build.rolldownOptions.output.minify。如果你之前使用esbuild.drop选项,现在可以使用build.rolldownOptions.output.minify.compress.drop*选项。Oxc 不支持属性名混淆及其相关选项(
mangleProps、reserveProps、mangleQuoted、mangleCache)。如果你需要这些选项,请参阅 oxc-project/oxc#15375。esbuild 和 Oxc 压缩器对源代码的假设略有不同。如果你怀疑压缩器导致了代码问题,可以在这里比较这些假设:
如果你在 JavaScript 应用中发现了与压缩相关的问题,请报告给我们。
CSS 压缩由 Lightning CSS 完成
Lightning CSS 现在是默认的 CSS 压缩器。你可以使用
build.cssMinify: 'esbuild'选项切换回 esbuild。注意,你需要将esbuild安装为devDependency。Lightning CSS 支持更好的语法降级,你的 CSS 包体积可能会略有增加。
一致的 CommonJS 互操作
从 CommonJS(CJS)模块进行
default导入现在以一致的方式处理。如果满足以下任一条件,
default导入即为被导入 CJS 模块的module.exports值。否则,default导入为被导入 CJS 模块的module.exports.default值:
- 导入方是
.mjs或.mts文件。- 导入方最近的
package.json中type字段设置为module。- 被导入 CJS 模块的
module.exports.__esModule值未设置为true。 details 之前的行为
在开发模式下,如果满足以下任一条件,default 导入即为被导入 CJS 模块的 module.exports 值。否则,default 导入为被导入 CJS 模块的 module.exports.default 值:
- _导入方包含在依赖优化中_且为
.mjs或.mts文件。 - _导入方包含在依赖优化中_且最近的
package.json中type字段设置为module。 - 被导入 CJS 模块的
module.exports.__esModule值未设置为true。
在构建模式下,条件为:
- 被导入 CJS 模块的
module.exports.__esModule值未设置为true。 module.exports的default属性不存在。
(假设 build.commonjsOptions.defaultIsModuleExports 未从默认值 'auto' 更改)
:::
更多详情请参阅 Rolldown 关于此问题的文档:来自 CJS 模块的 default 导入不明确 - 打包 CJS | Rolldown。
此变更可能会破坏一些导入 CJS 模块的现有代码。你可以使用已弃用的 legacy.inconsistentCjsInterop: true 选项临时恢复之前的行为。如果你发现某个包受此变更影响,请向包作者报告或向其发送拉取请求。务必附上上述 Rolldown 文档链接,以便作者理解上下文。
移除了基于格式嗅探的模块解析
当 package.json 中同时存在 browser 和 module 字段时,Vite 过去会根据文件内容来解析字段,并会为浏览器选择 ESM 文件。引入此行为是因为一些包使用 module 字段指向 Node.js 的 ESM 文件,而另一些包使用 browser 字段指向浏览器的 UMD 文件。鉴于现代 exports 字段已解决此问题且已被许多包采用,Vite 不再使用这种启发式规则,始终尊重 resolve.mainFields 选项的顺序。如果你依赖此行为,可以使用 resolve.alias 选项将字段映射到所需文件,或使用包管理器(如 patch-package、pnpm patch)应用补丁。
外部化模块的 require 调用
外部化模块的 require 调用现在保持为 require 调用,而不会转换为 import 语句。这是为了保留 require 调用的语义。如果你想将它们转换为 import 语句,可以使用 Rolldown 内置的 esmExternalRequirePlugin,该插件已从 vite 重新导出。
js
import { defineConfig, esmExternalRequirePlugin } from 'vite'
export default defineConfig({
// ...
plugins: [
esmExternalRequirePlugin({
external: ['react', 'vue', /^node:/],
}),
],
})
更多详情请参阅 Rolldown 的文档:require 外部模块 - 打包 CJS | Rolldown。
UMD / IIFE 格式中的 import.meta.url
import.meta.url 在 UMD / IIFE 输出格式中不再进行 polyfill。默认情况下,它将被替换为 undefined。如果你更喜欢之前的行为,可以结合使用 define 选项和 build.rolldownOptions.output.intro 选项。更多详情请参阅 Rolldown 的文档:已知 import.meta 属性 - 非 ESM 输出格式 | Rolldown。
移除了 build.rollupOptions.watch.chokidar 选项
build.rollupOptions.watch.chokidar 选项已移除。请迁移到 build.rolldownOptions.watch.watcher 选项。
移除了对象形式的 build.rollupOptions.output.manualChunks 并弃用函数形式
对象形式的 output.manualChunks 选项不再受支持。函数形式的 output.manualChunks 已弃用。Rolldown 提供了更灵活的 codeSplitting 选项。更多关于 codeSplitting 的详情请参阅 Rolldown 文档:手动代码分割 - Rolldown。
build() 抛出 BundleError
此变更仅影响 JS API 用户。
build() 现在抛出 BundleError,而非插件中抛出的原始错误。BundleError 的类型为 Error & { errors?: RolldownError[] },它将各个错误包装在 errors 数组中。如果你需要各个错误,需要访问 .errors:
js
try {
await build()
} catch (e) {
if (e.errors) {
for (const error of e.errors) {
console.log(error.code) // 错误码
}
}
}
模块类型支持和自动检测
此变更仅影响插件作者。
Rolldown 对 模块类型 提供了实验性支持,类似于 esbuild 的 loader 选项。因此,Rolldown 会根据解析 ID 的扩展名自动设置模块类型。如果你在 load 或 transform 钩子中将其他模块类型的内容转换为 JavaScript,可能需要在返回值中添加 moduleType: 'js':
js
const plugin = {
name: 'txt-loader',
load(id) {
if (id.endsWith('.txt')) {
const content = fs.readFile(id, 'utf-8')
return {
code: `export default ${JSON.stringify(content)}`,
moduleType: 'js', // [!code ++]
}
}
},
}
其他相关弃用
以下选项已弃用,将在未来移除:
build.rollupOptions:重命名为build.rolldownOptionsworker.rollupOptions:重命名为worker.rolldownOptionsbuild.commonjsOptions:现在为 no-opbuild.dynamicImportVarsOptions.warnOnError:现在为 no-opresolve.alias[].customResolver:请使用带resolveId钩子和enforce: 'pre'的自定义插件替代
移除的废弃功能
- 不再支持向
import.meta.hot.accept传递 URL。请传递 id。(#21382)
高级
以下破坏性变更预计只会影响少数使用场景:
- 暂不支持 Extglobs(rolldown-vite#365)
- TypeScript 旧式命名空间仅部分支持。更多详情请参阅 Oxc 转换器的相关文档。
define不共享对象的引用:当你将对象作为值传递给define时,每个变量将拥有该对象的独立副本。更多详情请参阅 Oxc 转换器的相关文档。bundle对象变更(bundle是传递给generateBundle/writeBundle钩子的对象,由build函数返回):- 不支持对
bundle[foo]赋值。Rollup 也不鼓励这样做。请使用this.emitFile()替代。 - 该引用不跨钩子共享(rolldown-vite#410)
structuredClone(bundle)会抛出DataCloneError: #<Object> could not be cloned。不再支持此操作。请使用structuredClone({ ...bundle })进行克隆。(rolldown-vite#128)
- 不支持对
- Rollup 中所有并行钩子现在都作为串行钩子工作。更多详情请参阅 Rolldown 的文档。
"use strict";有时不会被注入。更多详情请参阅 Rolldown 的文档。- 不支持通过 plugin-legacy 转换到 ES5 及以下版本(rolldown-vite#452)
- 向
build.target选项传递同一浏览器的多个版本现在会报错:esbuild 会从中选择最新的版本,这可能不是你的本意。 - Rolldown 不支持的功能:以下功能不受 Rolldown 支持,Vite 也不再支持。
build.rollupOptions.output.format: 'system'(rolldown#2387)build.rollupOptions.output.format: 'amd'(rolldown#2528)shouldTransformCachedModule钩子(rolldown#4389)resolveImportMeta钩子(rolldown#1010)renderDynamicImport钩子(rolldown#4532)resolveFileUrl钩子
parseAst/parseAstAsync函数现已弃用,推荐使用功能更丰富的parseSync/parse函数。- 注释在
renderChunk钩子之前而非之后被移除 - 除此处列出的注释外,其他注释会被移动,而 Rollup 仅在相邻代码被移除时才移除注释
从 v6 迁移
请先查看 Vite v7 文档中的 从 v6 迁移指南,了解将应用移植到 Vite 7 所需的更改,然后再继续处理此页面上的更改。
帮助我们改进文档
发现翻译问题或内容错误?请告诉我们。
