前情:
Vite 8 已经把 Rolldown 作为默认引擎发正式版了,是 vite build 默认走的路。两个测试项目同样的代码分别用vite7和vite8跑,看一下会有什么情况。
一、看 package.json
Vite 7 时代的架构是双引擎:开发阶段用 esbuild 做预构建(transform),生产阶段用 Rollup 打包。
两套引擎,两套插件体系,一次构建要过两道手。
Vite 8 干的事,就是把这个双引擎拆了,换成 Rolldown 一个。看看npm 上 vite@8.2.2 的 dependencies:
1
2
3
4
5
6
7
8
$ npm view vite@8.2.2 dependencies
{
"postcss": "^8.5.26",
"rolldown": "~1.2.4", -- 引擎换人了
"picomatch": "^4.0.5",
"tinyglobby": "^0.2.17",
"lightningcss": "^1.33.0" -- CSS 处理也换成 Rust 系
}
esbuild 的位置从 dependencies 退到了 peerDependencies,还是可选的:
1
"peerDependencies": { ..., "terser": "^5.16.0", "esbuild": "^0.27.0 || ^0.28.0", ... }
一个 dependencies、一个 peerDependencies,引擎的话语权变化写在 manifest 里。npm view 出来的依赖树才是真实的。
Rolldown 的时间线看一下,走的还是很快的
1
2
3
4
5
2025-12-03 Vite 8 Beta(rolldown-vite 试验包转正前奏)
2026-03-12 Vite 8.0 正式发布:Rolldown 成为默认且唯一的打包引擎
2026-05-07 Rolldown 1.0 发布(官方口径:比 Rollup 快 10-30 倍,与 esbuild 打平)
2026-06-23 Vite 8.1
至今 vite 8.2.2 + rolldown 1.2.7,8 月还在活跃迭代
Vite 7 时代有个 rolldown-vite 包(npm 上停在 7.3.1),就是官方提前放出来的换芯预览版,大量兼容性验证是在背地里跑完的。
Vite 官方中文文档现在也还留着从 v7 迁移的指引,把 rolldown-vite 列为迁移到 Vite 8 的中间步骤。
二、双引擎痛点
1. 同一份代码,transform 和 bundle 各解析一遍。 测试时 esbuild 把你的代码过一遍,生产时 Rollup 再从头解析一遍。两套解析器的行为差异(比如不同的警告口径、不同的 ESM 处理细节)也就是意味着测试好好的,生产出问题会一直存在。
2. 插件双轨制。 esbuild 插件和 Rollup 插件是两套接口,Vite 插件作者经常要写兼容分支,社区里也有很多Vite 插件不支持的 issue。
Rolldown 统一引擎后,上述两个问题自然消失:transform 和 bundle 共用同一套解析器,插件只需面向 Rollup 兼容层写一套。
三、同样的代码分别测试
3.1 测试项目
两个目录,分别装 vite@7.3.6 和 vite@8.2.2,代码部分都是一样的:
- 30 个业务模块,每个模块真实 import lodash-es 的 camelCase 和 date-fns 的 addDays
- 每个模块埋一个永远不被引用的导出(
unusedN = 'dead-code-N'),专门测 tree-shaking - 入口汇总 30 个函数跑一遍
纯 vanilla,不带框架插件——把插件变量锁死,只测引擎差异。
3.2 构建耗时:3.19 倍
各跑 5 轮,用 Python 的 perf_counter 计时:
1
2
vite7(Rollup+esbuild): [807.8, 795.2, 799.4, 827.9, 906.5] | 均值 827.4ms
vite8(Rolldown): [259.8, 259.6, 262.8, 255.6, 259.4] | 均值 259.4ms
827.4 → 259.4,3.19 倍
还有就是稳定性,vite7 的五轮里有一轮飙到 906ms(JS 引擎的 GC 抖动),vite7 五轮标准差约 43.5ms,vite8 只有 2.7ms——Rust 侧不仅快,抖动也小了一个数量级。
3.3 产物对比
再来比较体积
1
2
vite7: dist/assets/index-Dpyeg0G3.js 9.78 kB │ gzip: 3.70 kB (9588 字节)
vite8: dist/assets/index-x0SZjdEd.js 9.55 kB │ gzip: 3.63 kB (9360 字节)
体积差 228 字节,rolldown 略小。两边的 tree-shaking 都很干净——我 grep 了产物,「dead-code-1」这个字符串两侧都不存在,30 个死导出全部剔除。这一点上 Rollup 多年积累的摇树能力没有被 Rolldown 输掉,兼容性担忧可以先放一放。
模块数统计 977(vite7)vs 978(vite8),差 1 个。
这个倒是没有去深究,大概率是两版对依赖 ESM 解析粒度的细微差异,不影响产物正确性。可以作为提醒,换引擎后产物 hash 全变,CDN 缓存策略该检查了。
3.4 单独使用
Rolldown 也能脱离 Vite 单独用,我拿它直接打包入口(带内置 minify):
1
2
3
4
5
$ rolldown src/main.js -f esm -o out-cli.js -m
三轮耗时: [125.2, 126.6, 121.3] ms | exit=0
产物字节: 8658 | 行数: 1 | 含 dead-code-1? False
=== 功能验证:node out-cli.js(minify 后产物直接执行)===
mod1Key:1:2026|mod2Key:4:2026|mod3Key:9:2026|mod4Key:16:2026|mod5Key:25:2026|mod
功能验证的输出是mod1Key:1:2026 ,完全符合源码逻辑(camelCase(‘mod_1_key’) + 1×1 + 年份),但产物里 grep 不到 camelCase 这个名字了——minify 把标识符 mangling 成了短名。所以验产物别 grep 函数名,跑一遍看行为。
需要注意的是rolldown 的 CLI 不认 rollup 的 -i 参数,input 是位置参数(rolldown src/main.js)。API 兼容 Rollup,CLI 不完全兼容,查一眼 --help 能省五分钟。
3.5 30 倍的水分在哪
官方口径是10-30 倍是对比 Rollup 单体,对比 esbuild 的说法是「on par」。官方仓库的三方 benchmark 里,rolldown 1032ms vs esbuild 1137ms——基本打平,甚至略快。
至于测试项目里为什么是 3 倍多?那是整条 Vite build 管线的对比,不是裸 bundler 的对比。
Vite 7 的双引擎要在 Rollup 之前先跑一轮 esbuild 预构建,管线开销天然比单引擎大;Vite 8 单引擎一次过,省的就是这部分结构性损耗。
引擎层 Rolldown 与 esbuild 同级,但单引擎架构让 Vite 整体甩掉了双引擎的结构性开销。快 30 倍的标题党数字看看就好,你的项目升级后能快多少,取决于你管线里双引擎损耗占比多大——我这个小项目是 3 倍多,你的中型项目大概率也是这个量级,超大型项目值得自己测。
四、换了 minifier ,同进程测试
3.4 节里 rolldown CLI 带 -m 出的产物,用的就是内置的 Oxc minifier。
这个 oxc 到底啥呢?快在哪儿?
npm view rolldown@1.2.7 dependencies 只有俩包:
1
2
3
4
{
'@oxc-project/types': '=0.148.0', ← oxc 的类型包,精确版本锁死(无 ^ 无 ~)
'@rolldown/pluginutils': '^1.0.0'
}
注意那个 =0.148.0——不带 ^,精确锁定。
oxc 需要交代一下:它是 VoidZero 生态里跟 Rolldown 并排的另一根支柱(Oxidation Compiler),解析器、转换器、minifier 一套 Rust 工具箱。Rolldown 直接编进自己的引擎,版本跟着自己走;oxc 自己也独立发 npm 包(@oxc-minify/binding-linux-x64-gnu 已到 0.149.0),各走各的发版节奏。所以 rolldown 1.2.7 锁 0.148.0、oxc 独立包已经 0.149.0,两边号不同步——正常,关系都写在 manifest 里。
Vite 7 时代 minify 是 esbuild 的活(terser 可选),Vite 8 换成 oxc
4.1 同一个进程,API 直接调
比 minifier 有个大坑:进程启动时间会污染数据(terser 是纯 JS,光 node 启动就上百毫秒)。所以不用 CLI,把三个 minifier 拉进同一个 node 进程,API 级直调:
- oxc:rolldown 的 napi binding 里直接曝着
minifySync函数(那个 19MB 的 .node 二进制,细节在第五个板块),进程内调 Rust - esbuild:vite 7.3.6 自带的 0.28.2(Go),
esbuild.transform(code, { minify: true })——新版没有顶层minify了,transform 加 minify 参数是等效写法 - terser:5.51.2(纯 JS 老牌基准),
terser.minify(code, { compress: true, mangle: true })
输入统一用 rolldown 打包的未压缩产物(35,605 字节,30 模块 + lodash-es/date-fns),预热 3 轮、计时 20 轮取均值,gzip 用 level 9。
三个里面谁压得最小、谁最快?
4.2 数据
答案来了
1
2
3
4
产物字节 gzip(9) 耗时均值(20轮)
oxc 0.148 (Rust) 11,869 3,763 0.59 ms
esbuild 0.28.2 (Go) 12,733 3,704 2.22 ms
terser 5.51.2 (JS) 8,083 2,971 35.10 ms
三个产物都用node 跑了一遍,输出逐字一致(mod1Key:1:2026|mod2Key:4:2026|...)——压缩不是比谁改得狠,行为不能变。
速度:oxc 0.59ms,比 esbuild和terser都快。oxc 和 esbuild 都是原生二进制(Rust vs Go),esbuild 已经很快了,oxc 还要更快。terser 的劣势主要在 watch 场景下的持续开销。
压缩率:terser 压得最小,oxc 和 esbuild 基本持平。原始字节 oxc 比 esbuild 小,但 gzip 之后 esbuild 反而小。说明两家 minify 的方式不同:oxc 把标识符压得更狠,esbuild 的产物里重复模式更多、对 gzip 更友好。
所以 Vite 8 选 oxc 的逻辑很清楚:dev 和 build 要的是速度,压缩率上 oxc 没输,压缩率最好但慢的 terser 就需要自己来配置了。
五、19MB 的 .node
rolldown 的 npm 包里,一堆 .mjs 壳子,真引擎全在 optionalDependencies 里:
1
2
3
4
5
6
"optionalDependencies": {
"@rolldown/binding-darwin-x64": "1.2.7",
"@rolldown/binding-linux-x64-gnu": "1.2.7",
"@rolldown/binding-win32-x64-msvc": "1.2.7",
...
}
npm 只装当前平台那一个,里面的 rolldown-binding.linux-x64-gnu.node——19MB 的原生二进制,napi-rs 的编译产物。这就是 4.1 节能进程内直接调用minifySync 的原因:JS 层只是个 require 那个 .node 文件的薄壳。
1
2
minify, minifySync, parse, parseSync, transform, transformSync,
enhancedTransform, isolatedDeclaration, resolveTsconfig, ...
parse、transform、minify 全是原生函数,oxc minifier 不是外部依赖,是直接编译进这个 .node 的 Rust 代码。
vite8 五轮 260ms 左右的稳定性、oxc 0.59ms 的单轮耗时,构建全链路在原生代码里跑完,node 进程只是个宿主。
这意味着 Rolldown 的构建全链路(解析、转换、压缩)都在原生代码里跑完,Node 进程只是个宿主。这是它与纯 JS 打包器(如 Rollup)最根本的差异:CPU 密集的工作彻底离开了 JS 的解释执行路径。
六、迁移成本很低,但是有几点需要注意
官方给 Vite 7 用户的建议路径:小项目直接 npm i vite@8;大项目先切 rolldown-vite(Vite 7 + Rolldown 引擎的过渡包)跑稳,再升 Vite 8。
实测项目的话,是直接切过去的,没有做任何配置改动,零兼容问题,但那是因为纯 vanilla。你的真实项目就不一样了:
- CSS:Vite 8 用 lightningcss 替代了部分 PostCSS 处理,跑一遍
npm run build检查样式是否正常 - Rollup 插件:检查是否用了
generateBundle、renderChunk等钩子,关注 Vite 8 的插件兼容性 changelog - 产物 hash:
npm run build后对比产物文件名,更新 CDN 缓存策略
总结
Rolldown 不是又一个更快的打包器,而是消除esbuild 和 Rollup 的双引擎内耗、插件双轨制、dev/build 行为不一致等等。
每一次换地基,不仅仅只有快。
Rolldown 和 oxc 背后的 VoidZero(尤雨溪的公司),一整条工具链,下篇可以研究一下这张棋盘:Vite、Rolldown、Oxc、Vitest 如何互相咬合,和 Vercel 的 Turbopack 又是什么对位关系。
参考
- Vite 8.0 is out!(vite.dev blog,2026-03-12)
- Rolldown 1.0(voidzero.dev,2026-05-07)
- rolldown-rs/rolldown GitHub 仓库与官方 benchmark
- Vite 官方中文文档:从 v7 迁移
- npm registry:vite@8.2.2 / rolldown@1.2.7 / rolldown-vite@7.3.1 / @oxc-project/types@0.148.0 / @oxc-minify/binding-linux-x64-gnu@0.149.0
测试的demo可以在gzh程序员蜡笔熊回复「vite8」获取。
期待您的评论和建议。