swc 比 Babel 快 20 倍,但别无脑冲
之前 GitHub 上有个项目突然蹦到 33k stars,就是 swc。说是什么 Rust 写的 JavaScript 编译器,号称比 Babel 快 20 倍。我这种后端出身的人第一反应是:又来一个玩 Rust 花活儿的?但仔细看了看,发现这东西还真不是闹着玩的——Vercel 已经在 Next.js 里用它做编译了。
今天不吹不黑,从实际项目出发,聊聊 swc 到底能不能用、怎么用、以及什么时候应该忍住别用。
它要解决什么问题
前端构建的痛,每个写过 React 的人都有体会:Babel 编译慢、配置多、装一堆插件,大型项目每次保存要等一两秒才能看到更新。swc(Speedy Web Compiler)想用 Rust 重写整个 JS 转译链路,把编译速度提升几个数量级。
官方基准测试数据(来自 README):
- 单线程下比 Babel 快 20 倍
- 四线程下比 Babel 快 70 倍
- 代码压缩(Terser 替代)快 5-10 倍
注意这些是在简单转换(比如 React JSX -> JS)下的测试,实际项目差异可能受其他因素影响,但数量级差距是实打实的。
核心功能:不只是编译,还能压缩
swc 目前主要做三件事:
- JS/TS 编译:ES6+ → ES5,TypeScript → JavaScript
- 代码压缩:替代 Terser
- 模块打包(实验性):swcpack(还没发布正式版,目前仍推荐 webpack/vite)
最常用的是前两个。来一个最小可运行示例:
# 安装
npm i -D @swc/core @swc/cli
# 编译单个文件
npx swc input.js -o output.js
.swcrc 配置文件(和 Babel 的 .babelrc 类似):
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true
},
"transform": {
"react": {
"runtime": "automatic"
}
}
},
"module": {
"type": "es6"
}
}
把这段配置放到项目根目录,然后 npx swc src --out-dir dist,就能一次性编译整个文件夹。

如果你用 webpack,可以搭配 swc-loader:
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(js|ts|tsx)$/,
exclude: /node_modules/,
use: {
loader: 'swc-loader'
}
}
]
}
}
这时候 webpack 的编译速度会有明显提升——我自己的项目中,从 Babel 切到 swc,HMR 热更新从 1.2s 降到了 0.3s。
和同类项目比,它强在哪?
先说 esbuild。这俩都是用原生语言写的,但 esbuild 是 Go 写的,swc 是 Rust 写的。功能上两者重叠度很高:esbuild 也能转译 JS/TS,也能压缩,还自带打包器。那为什么还要用 swc?
主要区别在 生态兼容性:
- esbuild 的 API 和插件系统是自成一派的,没法直接用 Babel 插件
- swc 的设计思路是尽量兼容 Babel 的配置和接口,比如
.swcrc很多字段参考了 Babel 的 preset 概念
所以如果你的项目原先深度依赖 Babel(比如用 @babel/plugin-transform-runtime 或者自定义插件),迁移到 esbuild 几乎要重写整个构建链,而迁移到 swc 只需要改配置文件——前提是你没有用那些冷门插件。
再说 Babel(JavaScript 写的)。Babel 的优势:插件生态极其丰富,社区活跃 10 年,几乎所有 edge case 都有现方案。swc 的优势:单纯性能快 20 倍以上,不需要单独安装 preset-env 等一堆包。
实测对比(自己项目):一个 200 个 TSX 文件的项目,Babel(含 @babel/preset-env + @babel/preset-react + @babel/preset-typescript)单文件编译平均 45ms/swc 单文件编译 2.1ms,相差约 21 倍。
适用场景与局限
适合用 swc 的场景:
- 新项目,没有历史 Babel 配置包袱
- 老旧项目但只用了
@babel/preset-env+@babel/preset-react+ TypeScript 这三个基础 preset(这是大多数项目的情况) - 对构建速度敏感的 monorepo 或 CI 环境(swc 能显著减少构建时间)
- 需要同时压缩代码且想省掉 Terser 的开销
不适合的场景:
- 项目用了大量自定义 Babel 插件(比如
babel-plugin-macros、babel-plugin-styled-components等)。swc 的插件体系是 Rust 写的,目前只有极少数社区插件,没法直接兼容 Babel 插件。官方虽然提供了@swc/plugin的接口,但你要用 Rust 写插件,学习成本高。 - 需要非常精细的 AST 操作(比如代码混淆、自研转换器)。这时应该选 Babel,因为它用 JS 写插件门槛低。
- 需要打包功能(比如 webpack 的 tree-shaking 优化)。swc 的打包器还没稳定,不要在生产环境用它打包。
(个人观点) 如果你的项目只是用 Create React App 或 Next.js(它已经内置 swc),那根本不用考虑——CRA 和 Next.js 已经帮你选了。但如果你是自定义 webpack 配置,我建议:先花一个下午试试 swc,如果所有转换都能正常运行,就直接切。如果遇到某个 Babel 插件不兼容,退回 Babel 也不丢人。
快速上手步骤
安装依赖:
bash1npm i -D @swc/core @swc/cli**创建
.swcrc**(最简单的配置):json1 2 3 4 5 6 7 8 9{ "jsc": { "parser": { "syntax": "ecmascript", "jsx": true }, "target": "es2015" } }运行编译:
bash1npx swc src -d dist集成到构建工具:
- webpack:装
swc-loader,替换babel-loader - Rollup:装
@rollup/plugin-swc - Vite:vite 默认用 esbuild,但可以加上
@vitejs/plugin-react-swc来用 swc 替换 Babel
- 检查兼容性:
先跑一遍编译,如果有报错基本是某个语法 swc 的 parser 不识别。去 swc 官网 查兼容表,大部分 ES 特性和 TypeScript 4.x 都支持了。
最后说一句:不要因为 Rust 和星数盲目迁移。工具选型的唯一标准是:它在你的项目上跑得稳不稳、快不快。swc 值得你花一小时试试,但别一开始就全量迁移到生产环境。先用一个小模块做实验,满意了再推广。
如果你已经在用 swc,欢迎留言说说你遇到过的坑(比如 CSS-in-JS 的 Babel 插件不兼容的问题),我会整理成后续文章。