昨天 InfoQ 发了条消息:pnpm 12 用 Rust 重写了核心。今天一上班我先去 npm 上拉了一遍 dist-tags,latest 已经是 12.3.4 了------距离发布才一天,官方就把 latest 标签转正了,说明这次升级官方自己心里是有底的。 顺手我又把手里那个测试用的小 monorepo 拿出来,实测了一轮 pnpm 12 的安装速度和 Vite 7 → 8 的构建变化。一轮测下来我的感受是:Rust 化是真的,速度提升也是真的,但小项目上的体感远没有官方 benchmark 里那么夸张。
pnpm 12 到底换了什么
简单说,pnpm 12 把原本用 TypeScript + Node.js 写的核心重写成了 Rust。但注意一个细节:它刻意保留了 pnpm 11 的命令、参数、锁文件格式和 node_modules 目录结构。也就是说,这不是一次推倒重来的"pnpm 12",而是一次对用户完全无感的引擎替换------你现有的 CI 脚本、锁文件、团队工作流都不需要动。
官方 benchmark 给的数据挺吓人:
- 文件量较大的测试集,全新安装从 8.2 秒缩短到 5 秒
- 缓存、锁文件、node_modules 都预热好的状态下,重复安装从 472ms 降到 15ms
- Vercel 的 21 个项目组成的 Turborepo 工作区(1670 个包),六种场景下安装时间中位数缩短了 64.4% 到 90.5%
前两条是"加速明显",最后一条才是重点------工作区越大,Rust 内核的收益越夸张。说白了 Rust 工具就是这么个调性:启动开销低、文件系统操作并行度高,依赖树越大越能拉开差距。 我自己在沙箱里想复现一次完整对比,结果发现环境限制 symlink 创建,pnpm 的 .pnpm 目录结构根本建不起来。完整对比没跑成,这块就引用官方数据吧。
升级过程里的两个小坑
升级方式官方给了两条路,用 corepack 的话是这样:
sql
corepack prepare pnpm@12.3.4 --activate
corepack enable
pnpm --version # 确认变成 12.3.4
不想动 corepack 的,pnpm self-update 也能直接拉最新。我实际观察到的两个点,提前说下免得你们踩:
坑一:npm latest 标签有延迟。 InfoQ 发布当天的文章里还写着"latest 仍然指向 pnpm 11",但第二天我再查 dist-tags,latest 已经是 12.3.4 了。如果你照着旧教程用 npm i -g pnpm 升级,可能装到的还是 11------升级前先 npm view pnpm dist-tags 确认一下当前 latest 指向哪个版本。
坑二:Corepack 首次启动反而更慢。 因为 Rust 编译出来的原生二进制体积更大,Corepack 首次下载解压会慢一点,官方数据是慢 11.1%。但缓存之后启动速度能提升 74.7%。也就是说,第一次装完的体验是"哎怎么还慢了",等你跑第二次、第三次,才会意识到确实快了。这个落差很真实,别第一次跑完就急着回滚。
顺手实测:Vite 7 换 Vite 8,构建到底快多少
pnpm 12 只是 Rust 化浪潮里的一个点。真正把这股浪潮推到台前的是 Vite 8------今年 3 月 12 日正式发布,把用了多年的"esbuild 开发 + Rollup 生产"双引擎架构拆了,换成 Rolldown 一个 Rust 打包器一统到底。Vite 8 内部还顺手把 JS 转换和压缩也换成了 Oxc,CSS 压缩交给 Lightning CSS,整个构建链路基本没有 JavaScript 的活儿了。 我在本机用同一份代码(30 个模块的模拟业务项目,5000 条数据处理逻辑)分别跑了 Vite 7.3.6 和 Vite 8.2.2 的 vite build,各跑两遍:
| 版本 | 第一次构建 | 第二次构建 |
|---|---|---|
| vite 7.3.6(Rollup 引擎) | 15.76s | 12.66s |
| vite 8.2.2(Rolldown 引擎) | 7.98s | 10.37s |
两遍平均下来,vite 8 是 9.17s,vite 7 是 14.21s,提速大约 35% 。产物都验证过是有效的 bundle,体积还略小了一点(12.8KB → 12.3KB)。 我这个小项目没测到官方宣传的 10-30 倍,毕竟 demo 就 30 个模块,构建瓶颈不在这儿。但方向是明确的------模块越多、依赖越深,差距会指数级放大。同一条赛道上的玩家也都在这上面押注:Rspack 是 Rust、Turbopack 是 Rust、Bun 从第一天起就用 Zig 写、连 TypeScript 官方编译器都开始用 Go 重写了。
Rust 化的底层逻辑,其实就一句话
这些工具加速的秘密不在于"Rust 语言本身快",而在于工具链共享同一套解析器和 AST。 传统链路里,Babel 解析一遍、ESLint 又解析一遍、Prettier 再解析一遍,同一份代码被反复 tokenize、反复建 AST,每一次都是纯 JavaScript 在单线程里跑。Oxc 的做法是:parser、linter、formatter、transformer、minifier、resolver 全部共享同一个 Rust 解析器和同一份 AST,解析一次,后面所有环节都在内存里直接用结果。
我第一次看到这个设计时第一反应是"就这么简单?"------是的,就这么简单,只是这么多年没人愿意把这套东西用系统化工程去重做一遍。 Oxlint 就是这个思路下的产物,官方 benchmark 是比 ESLint 快 50-100 倍,844 条内置规则,还支持 type-aware linting。我自己还没在正式项目里全量切换过 Oxlint,但 8 月初 oxc 发布 Rust 原生 React Compiler 支持后,有人在 1036 个文件的代码库上测过,编译部分从 14.3s 降到 0.81s,17 倍多的提速------这个数字放在 CI 场景里意味着省下的可不是一星半点。
我的看法
对普通前端开发者来说,短期内你其实不用做什么。pnpm 12 完全兼容 v11,Vite 8 对绝大多数插件开箱即用,Oxlint 可以直接替换 ESLint 跑在 CI 里。真正值得留意的反而是生态拐点:当 lint、format、build、install 全变成原生二进制之后,前端工程化会从"装一堆 JS 工具"变成"装一两个工具",配置量肉眼可见地变少。
你要是在大 monorepo 或者 CI 构建十分钟起步的项目里,这个时间点值得认真看一眼 pnpm 12 和 Vite 8------迁移成本不高,收益倒是确定的。小项目就随意,反正我实测也就快三分之一,不着急。