编程 Rust 正在吞噬 JavaScript 工具链:从 esbuild/SWC 到 Rolldown/Oxc,2026 前端构建大洗牌一次讲透

2026-07-14 07:43:40 +0800 CST views 18

Rust 正在吞噬 JavaScript 工具链:从 esbuild/SWC 到 Rolldown/Oxc,2026 前端构建大洗牌一次讲透

如果你在 2024 年还觉得「用 Rust 重写前端工具」只是极客玩具,那么到 2026 年 6 月 4 日——Cloudflare 宣布收购尤雨溪创办的 VoidZero 的那一天——这件事就已经从「趋势」变成了「既定事实」。Vite、Vitest、Rolldown、Oxc 这些你每天都在用(或即将用)的工具,背后是一整套用 Rust 重写 JavaScript 工具链的宏大计划。

这篇文章不聊八卦,只聊工程:Rust 凭什么比 JS 快?esbuild、SWC、Turbopack、Rspack、Rolldown 各自解决了什么?Oxc 的「统一 AST」架构到底妙在哪?Rolldown 如何把 Vite 的生产构建速度提升 10–30 倍?以及,作为一个普通前端,你现在该怎么上车。

一、背景介绍:我们为什么受够了 Webpack + Babel

先把时钟拨回 2018 年前后。那时候一个中大型前端项目,启动 npm run dev 要等十几秒,改一行代码热更新要等两三秒,生产构建 npm run build 动辄两三分钟。问题出在哪?

1. 工具链是「碎片化」的。 你想完成一次完整的构建,至少要串起这么多工具:

  • babel / @babel/preset-env:把 ESNext 转成浏览器能跑的 ES5;
  • webpack + 一堆 loader(ts-loadercss-loadervue-loader…):打包;
  • terser:压缩;
  • eslint:lint;
  • typescript:类型检查;
  • 各种插件:每个工具各自解析一遍源码。

注意最后一句:每个工具各自解析一遍源码。一份 App.tsx,Babel 解析一次、webpack 的增强解析器解析一次、ESLint 解析一次、TypeScript 编译器又解析一次。同一个 AST(抽象语法树),被重复构建四五次。这在小型项目里无所谓,但在 monorepo、在几十万行代码的项目里,就是实打实的时间浪费。

2. 这些工具大多跑在 Node.js 上,天生有天花板。 Node.js 是单线程事件循环 + JIT 编译 + 垃圾回收(GC)。对于「解析、转换、打包」这种纯 CPU 密集、且高度可并行的工作,JS 的三个特性都在拖后腿:

  • 单线程:多核 CPU 闲着,JS 只能用一个核;
  • JIT 预热:V8 要先「跑起来」才能把热点代码编译成机器码,短任务反而慢;
  • GC 停顿:处理大文件时频繁分配/回收内存,GC 一卡,构建就抖一下。

3. 配置地狱。 webpack.config.js 几百行是常态,loader、plugin、resolve、optimization 互相耦合。新人上手成本极高,「能跑就行,别动配置」成为团队潜规则。

于是从 2020 年开始,一群人开始用系统级语言(Go、Rust,甚至 Zig)重写这些工具。思路很朴素:把这些 CPU 密集的活,从「在 Node 里用 JS 跑」换成「编译成原生机器码跑」。

这场运动的起点,是一个用 Go 写的工具——esbuild

二、核心概念:需要先说清楚的几件事

在往下看之前,先把几个核心概念对齐,后面才不会乱。

2.1 一条「工具链」由哪些零件组成

一个完整的 JavaScript/TypeScript 工具链,本质上是一串对源码做变换的流水线:

零件干什么经典实现(JS 时代)Rust 重写
Parser(解析器)源码 → AST@babel/parseroxc_parser
Transformer(转译器)ESNext/TSX → 目标 JSbabeltscoxc_transformswc
Resolver(解析器)import './a' 映射到真实文件enhanced-resolveoxc_resolver
Linter(检查器)代码规范/错误检查eslintoxlint
Minifier(压缩器)删空格、缩短变量名terseroxc_minifier
Bundler(打包器)把模块图打成浏览器可加载的包webpackrolluprolldownrspack
Formatter(格式化器)统一代码风格prettieroxc_formatter

你会发现,表格右边几乎被 Rust 填满。这不是巧合。

2.2 为什么是 Rust(而不是继续用 JS)

核心就一句话:构建工具是 CPU 密集型、高度可并行的任务,而这恰恰是 JS 的弱项、Rust 的强项。

  • Rust 编译成原生机器码,没有 JIT 预热、没有 GC 停顿,启动即满速;
  • Rust 的「无畏并发(fearless concurrency)」让你可以安全地用多核:解析、转译、代码生成都能并行;
  • Rust 的内存安全(所有权模型)让你在写高性能 C 级代码时,不会整天踩段错误。

用 Rust 重写后,常见的收益量级是 10 倍到 100 倍。这不是我拍脑袋——后面会给出具体数字。

顺带一提:Bun 用的是 Zig,esbuild 用的是 Go。Rust 不是唯一选择,但它是目前生态最完整、社区最猛的那一个。本文聚焦 Rust 系,是因为 2026 年的「工具链大一统」叙事,正是由 Rust 系项目主导的。

2.3 一个被反复提到的关键洞察:统一 AST

这是 VoidZero(尤雨溪的公司)反复强调的「护城河」idea,也是理解后面一切的钥匙。

传统工具链里,每个工具都有自己的 AST 表示、自己的解析器。Babel 的 AST、TypeScript 的 AST、ESLint 的 AST 结构都不一样,所以谁都用不了谁的结果,只能各解析各的。

VoidZero 的思路是:让整条链共享同一棵 AST、同一个解析器、同一个解析结果。一次解析,多个阶段(lint、transform、bundle、minify)共用。这直接干掉了「重复解析」这个最大的隐性成本。

而承载这个「统一 AST」的,就是后面要讲的 Oxc

三、架构分析:三代工具的演进与两条路线

按时间线和技术定位,Rust 系前端工具可以分成「单点突破」和「大一统」两个阶段。

3.1 第一波:单点突破(esbuild、SWC)

esbuild(Go,作者 Evan Wallace,2020)

esbuild 是点燃这场革命的火把。它用 Go 写成,把「打包 + 转译 + 压缩」做成了一个二进制,速度是当时 webpack 的 10–100 倍。它的设计哲学是「够用就好、极致快」:

  • 不支持 webpack 那种复杂的插件生态,但覆盖了 90% 的需求;
  • 内置转译(JSX/TS)和压缩,不用再串 babel+terser;
  • 直接出原生二进制,零依赖安装。

Vite 在开发环境就用 esbuild 做依赖预构建(pre-bundling),这是 Vite 冷启动飞快的重要原因之一。

SWC(Rust,作者 kdy1)

SWC 是「用 Rust 重写的 Babel」。它提供和 Babel 几乎一一对应的能力(@swc/core 对标 @babel/core.swcrc 对标 .babelrc),但官方宣称:单线程比 Babel 快 20 倍,四核并行快 70 倍

SWC 被 Next.js、Deno 等大量采用,是「Rust 替换 Babel」最成功的案例。

3.2 第二波:打包器战争(Turbopack、Rspack、Rolldown)

打包器是工具链里最复杂的零件,也是收益最大的战场。2022–2026 年,三家 Rust 打包器各走各路:

Turbopack(Rust,Vercel / Next.js)

Turbopack 是 Next.js 的亲儿子,主打「增量构建」:只重新编译被修改的那一小块,其余走缓存。它深度绑定 Next.js,目标是把 Dev Server 和构建都做成「按需、增量」。它的策略是「自上而下」——先服务好 Next.js 这一超级框架,再谈通用。

Rspack(Rust,字节跳动 WebInfra 团队)

Rspack 走的是「兼容 Webpack」路线。它几乎完美兼容 webpack 的配置和 loader/plugin 生态,让存量 webpack 项目可以「近乎无感」地切换,立刻获得数倍提速。它底层用 SWC 做编译。Rspack 的现实意义很大:成千上万个老 webpack 项目,不用重写配置就能上车。

Rolldown(Rust,VoidZero / 尤雨溪)

Rolldown 走的是「兼容 Rollup」路线,但野心比 Rspack 更大。它提供与 Rollup 兼容的插件 API,目标是成为 Vite 未来的统一打包引擎——也就是说,它要同时替换 Vite 开发环境的 esbuild(依赖预构建)和生产环境的 Rollup(应用打包),把两个引擎合成一个。

Rolldown 的官方定位:

性能向 esbuild 看齐(原生级速度),API 向 Rollup 看齐(生态兼容),功能范围更接近 esbuild。

根据公开基准与早期采用者数据:Rolldown 比 Rollup 快 10–30 倍;有团队(如 Linear)把构建时间从 46 秒降到 6 秒

3.3 第三代:大一统地基——Oxc

前面说的 esbuild、SWC、Turbopack、Rspack 都是「单点」或「单引擎」。真正想做「整条链统一」的,是 Oxc(Rust,核心作者 Boshen,后并入 VoidZero 版图)。

Oxc 的野心是重写整条 JavaScript 工具链,并且让它们共享同一个 AST:

oxc_parser     解析器   对标 @babel/parser   解析速度 100x+ 于 Babel
oxc_linter     检查器   对标 eslint          速度 50–100x 于 ESLint
oxc_resolver   解析器   对标 enhanced-resolve 速度 28x 于 webpack 解析
oxc_transform   转译器   对标 babel / tsc
oxc_minifier    压缩器   对标 terser
oxc_formatter   格式化器 对标 prettier

重点不是「每个都快」,而是「它们共用一棵 AST」。Rolldown 正是站在 Oxc 的肩膀上:用 oxc_parser 解析、用 oxc_resolver 解析路径、用 oxc_transform 转译 TSX/JSX,最后自己做模块图与分块。这样一来,从 lint 到 bundle 到 minify,源码只被解析一次。

3.4 VoidZero 的纵向整合

把上面这些拼起来,就是 VoidZero(尤雨溪 2023/2024 年创立,曾获 460 万美元种子轮)的版图:

Oxc(地基:统一 AST 的解析/转译/lint/压缩)
  └─ Rolldown(打包器,基于 Oxc)
       └─ Vite(Web 构建工具,用 Rolldown 做引擎)
            ├─ Vitest(测试)
            ├─ Vue / VitePress(框架与文档)
            └─ Nuxt(元框架)

这条「纵向链」的每一层都基于下一层的同一套 AST,没有重复解析,没有跨工具不一致。这就是「统一、高性能、可组合、运行时无关」的工具链愿景。

3.5 关键转折:Cloudflare 收购 VoidZero(2026-06-04)

2026 年 6 月 4 日,Cloudflare 宣布收购 VoidZero。几个关键信息(来自官方公告与媒体报道):

  • Vite、Vitest、Rolldown、Oxc、Vite+ 全部保持 MIT 开源,路线图仍由尤雨溪团队与社区主导;
  • Cloudflare 主要提供资金与人力,不插手技术方向
  • 外界普遍解读为:Cloudflare 想把自己变成「AI 驱动的 Web 开发平台」,而前端工具链是入口。

对普通开发者而言,这次收购最大的意义是:Rust 系大一统工具链拿到了顶级云厂商的资源背书,基本告别「为爱发电」的不确定性

3.6 Vite 8:Rolldown 成为统一引擎

时间线收口到构建工具本身。早期形态是 rolldown-vite(一个 drop-in 替换包),后续 Vite 8 把 Rolldown 作为统一底层引擎:原本 Vite 开发环境用 esbuild 做依赖预构建、生产环境用 Rollup 做应用打包,现在两者合并由 Rolldown 一体化承担。

带来的直接变化:

  • 开发/生产行为更一致(不再「dev 用 esbuild、build 用 rollup」两套逻辑);
  • 构建速度相比 Rollup 提升 10–30 倍;
  • 绝大多数 Rollup 插件开箱即用(兼容插件 API)。

四、代码实战:现在就上车

光讲架构没用,下面全是可落地的操作。

4.1 把现有 Vite 项目切到 Rolldown

如果你现在用的是 Vite 7 及更早版本,想提前体验 Rolldown 引擎,可以装 rolldown-vite 这个 drop-in 包:

# 移除旧 vite,换成 rolldown-vite(API 基本不变)
npm remove vite
npm add -D rolldown-vite

vite.config.ts 几乎不用改,因为 rolldown-vite 就是按 Vite 的接口实现的:

// vite.config.ts
import { defineConfig } from 'rolldown-vite'

export default defineConfig({
  // 你原来的 rollupOptions / plugins 继续生效
  plugins: [
    // 这里可以放任何兼容 Rollup 的插件
  ],
  build: {
    // Rolldown 作为统一引擎后,无需再为 dev/prod 区分 esbuild 与 rollup
    rollupOptions: {
      output: {
        // 高级分块策略示例
        manualChunks: {
          'vendor-react': ['react', 'react-dom'],
        },
      },
    },
  },
})

等升级到 Vite 8,Rolldown 会成为默认引擎,连 rolldown-vite 都不用单独装。

4.2 用 oxlint 替换 ESLint(CI 提速 50–100 倍)

oxlint 是 Oxc 出品的 linter,配置格式兼容 ESLint,但速度快一到两个数量级。最小上手:

# 直接跑,零配置
npx oxlint@latest src --type module

# 或加配置文件
// .oxlintrc.json
{
  "extends": ["oxc/recommended"],
  "rules": {
    "no-console": "warn",
    "prefer-const": "error",
    "no-debugger": "error"
  },
  "ignore": ["dist", "node_modules", "*.min.js"]
}

在 CI 里把 ESLint 换成 oxlint,体验最明显:

# .github/workflows/lint.yml
name: lint
on: [push, pull_request]
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npx oxlint@latest . --deny-warnings

对一个几万行的仓库,ESLint 可能要跑 30 秒,oxlint 往往 1 秒不到。注意:oxlint 目前规则集不如 ESLint 全,复杂自定义规则还得以 ESLint 补足;但「基础规范 + 速度」场景,oxlint 已经能独当一面。

4.3 给 Rolldown 写个兼容 Rollup 的插件

Rolldown 兼容 Rollup 插件 API,这意味着你以前写的 Rollup 插件基本能直接复用。下面写个示例插件:自动给所有产物注入构建时间戳,并跳过 .vue 文件的处理。

// my-rolldown-plugin.mjs
export default function buildStampPlugin() {
  return {
    name: 'build-stamp',

    // 解析阶段:劫持特殊标识
    resolveId(source) {
      if (source === 'build-time') {
        return '\0build-time' // \0 前缀表示虚拟模块
      }
    },

    // 加载阶段:为虚拟模块提供内容
    load(id) {
      if (id === '\0build-time') {
        return `export default ${Date.now()}`
      }
    },

    // 转换阶段:跳过 .vue,其余原样返回(这里可插入自定义转换)
    transform(code, id) {
      if (id.endsWith('.vue')) return null
      // 示例:统计每个模块行数,可用于分析体积来源
      const lines = code.split('\n').length
      if (lines > 500) {
        this.warn(`模块 ${id} 有 ${lines} 行,考虑拆分`)
      }
      return code
    },
  }
}

vite.config.tsplugins: [buildStampPlugin()] 即可。看到没——和给 Rollup 写插件一模一样,这就是 Rolldown「兼容生态」的价值。

4.4 自己写一个基于 Oxc 的分析工具(Rust 进阶)

如果你想真正理解「统一 AST」的威力,可以试着用 oxc_parser 写个小工具,统计一个 TSX 文件里导出了多少个函数。下面是示意代码(API 会随版本演进,思路不变):

// Cargo.toml 添加:oxc_parser / oxc_allocator / oxc_span
use oxc_allocator::Allocator;
use oxc_parser::Parser;
use oxc_span::SourceType;

fn main() {
    let path = std::env::args().nth(1).expect("usage: analyzer <file>");
    let code = std::fs::read_to_string(&path).unwrap();

    // 1. 一次解析:用 Oxc 把源码变成 AST
    let allocator = Allocator::default();
    let source_type = SourceType::tsx();
    let parsed = Parser::new(&allocator, &code, source_type).parse();

    if !parsed.errors.is_empty() {
        eprintln!("解析有 {} 个错误", parsed.errors.len());
        return;
    }

    // 2. 遍历 AST:统计导出的函数声明
    //    parsed.program 就是共享的 AST,可被 lint/transform/bundle 复用
    let mut exported_fns = 0;
    // (此处用 oxc_ast 的 visitor 遍历 program,统计 Function 节点,略)
    println!("文件 {} 解析成功,AST 已构建", path);
    println!("(基于这棵 AST,你可同时做 lint / transform / bundle,而无需重复解析)");
}

要点不在于这个工具的完整实现,而在于:Rolldown、oxlint、oxc_transform 用的就是同一棵 parsed.program。你写的任何基于 Oxc 的分析,都能无缝接入整条链——这就是「统一 AST」的工程红利。

4.5 自己跑一遍基准测试

别只看别人给的数字,自己量最实在。用 hyperfine 对比切换前后的构建耗时:

# 安装 hyperfine(macOS)
brew install hyperfine

# 对比 Rollup 版 Vite 与 Rolldown 版 Vite 的 build 耗时
hyperfine --warmup 2 --runs 5 \
  'npm run build:rollup' \
  'npm run build:rolldown'

典型结果(中大型项目):Rollup 路径 40–60 秒,Rolldown 路径 5–10 秒。你自己的项目数字,比任何厂商宣传都可信。

五、性能优化:除了「换工具」还能做什么

换 Rust 工具只是第一步,用好它才有满血性能。

1. 把 oxlint 推进 CI,砍掉 ESLint 的等待。 这是投入产出比最高的一步。Lint 本就不该阻塞本地开发,更不该在 CI 占几十秒。oxlint 50–100 倍的优势,直接把这条流水线压到亚秒级。

2. 理解 Rolldown 的「full bundle」能力。 Rolldown 因为基于 Oxc 且范围更接近 esbuild,支持更激进的整体打包模式(full bundle mode),对依赖图和分块的控制更细。配合 manualChunks 把稳定 vendor 与频繁变动的业务代码分开,能进一步提升缓存命中率。

3. 善用 Vite 8 的智能缓存任务运行器。 VoidZero 体系里有一个 vite run——类似 turborepo 的单体任务运行器,但带智能缓存、无需显式配置。重复跑测试/构建/lint 时,未变更的环节直接命中缓存:

# 一条命令跑完 lint + test + build,且各自带缓存
npx vite run lint test build

4. 并行是 Rust 系的默认红利,但你要给它「够大的活」。 Rust 工具会主动用多核,但如果你项目只有三个文件,并行开销反而可能让单次任务变慢(JIT 都没热身的问题在原生工具上基本消失,但进程启动 + 调度仍有底线)。换句话说:项目越大,Rust 工具的收益越夸张。小 demo 感受不到,别因此否定它。

5. 迁移的边界要心里有数。 Rolldown 兼容 Rollup 插件 API,但:

  • 某些重度依赖 Rollup 内部实现的插件可能不兼容;
  • 用到了 esbuild 特有行为(如某些 transform 选项)的地方,切换到 Rolldown 后要做回归测试;
  • oxlint 的规则覆盖度仍不及 ESLint,复杂自定义规则先保留 ESLint 作为补充。

6. 正确测量。 永远用 hyperfinetime,跑多次取中位数,排除机器负载干扰。单次 time 的数字波动很大,别拿它下结论。

六、总结展望:JS 吃下世界,Rust 吃下 JS 的工具链

把视野拉高一点,这场运动其实是一个更大的叙事的注脚:JavaScript 吃下了应用开发的世界,而 Rust 正在吃下 JavaScript 的工具链。

几个判断:

1. 到 2027 年,原生工具链会成为前端默认。 就像今天没人再手写原生 DOM 操作一样,未来新项目默认用 Rust 系工具(Vite+Rolldown、oxlint、Oxc)会是常态,纯 JS 实现的 webpack/babel/terser/eslint 会逐渐退居「存量维护」角色。

2. 「配置疲劳」会大幅缓解。 统一 AST + 统一工具链意味着:你不再需要为每个工具配一遍 parser、配一遍 rules、配一遍 resolve。一份配置,整条链共享。这正是 VoidZero 要解决的核心痛点。

3. Cloudflare + VoidZero = AI Web 开发平台入口。 Cloudflare 收购的意图很清楚:当 Vite 成为绝大多数前端项目的构建入口,谁掌握构建入口,谁就掌握「把 AI 能力塞进开发流程」的咽喉。未来你可能会在 vite 命令里直接调用 CF 的 AI 服务做代码生成、依赖审查、性能诊断。

4. 普通开发者现在该做什么?

  • 新项目直接上 Vite(8+ 会自动用 Rolldown),别再新建 webpack 项目;
  • 把 ESLint 在 CI 里换成 oxlint 试水,本地复杂规则可暂留 ESLint;
  • 学一点 Rust 基础——不是为了写业务,而是为了能读、能改、能基于 Oxc 写自己的小工具;
  • 理解「统一 AST / 共享解析」的思想,它会深刻影响你未来对工具选型的判断。

5. 一个清醒的提醒。 性能数字(10x、30x、100x)大多来自厂商基准或早期采用者报告,不同项目差异巨大。Rust 工具不是银弹:它解决的是「CPU 密集的构建环节」慢,不解决你的「业务逻辑烂」「架构混乱」「网络慢」。工具再快,也救不了设计差的系统。


最后一句:2026 年这场「Rust 吞噬 JS 工具链」的洗牌,本质上不是语言之争,而是工程常识的胜利——把 CPU 密集的活交给原生语言,把开发体验留给 JS/TS。作为每天被构建速度折磨的前端,这波红利,咱们该痛快接住。

本文事实与基准数据综合自 VoidZero 官方公告、Cloudflare 收购新闻(2026-06-04)、Rolldown 1.0 / Vite 8 公开资料、Oxc 官方 benchmark 及社区技术博客,具体数字随版本演进请以各项目官方文档为准。

推荐文章

Golang 随机公平库 satmihir/fair
2024-11-19 03:28:37 +0800 CST
Rust async/await 异步运行时
2024-11-18 19:04:17 +0800 CST
Go 接口:从入门到精通
2024-11-18 07:10:00 +0800 CST
使用 Nginx 获取客户端真实 IP
2024-11-18 14:51:58 +0800 CST
php微信文章推广管理系统
2024-11-19 00:50:36 +0800 CST
如何实现生产环境代码加密
2024-11-18 14:19:35 +0800 CST
程序员茄子在线接单