SWC — Rust 写的 TS/JS 编译器
已复核SWC(Speedy Web Compiler)是用 Rust 写的 TypeScript / JavaScript 编译器。日常类比:它像一座用原生机器运转的翻译厂——进门是 TS/JSX,出门是按配置降级、剥类型、可选压缩后的 JS;质检(类型检查)不在厂内。
固定 1.16.1 的 npm 包是 @swc/core。你写:
import { transformSync } from "@swc/core";const { code } = transformSync(src, { jsc: { parser: { syntax: "typescript" } } });同一包还导出 parse / print / minify / bundle 与 Compiler。bundle 是独立的 Spack 路径,不是 transform 的默认后缀。
不理解固定版本的合同,下面这些事会说错:
- 为什么切到 SWC 后类型错误消失了——它本来就不检查
- 为什么 React 17+ 的自动 JSX 没生效——默认 runtime 是
classic - 为什么旧 Wasm plugin 升级后立刻报错——host 与 plugin 的
swc_core/ AST schema 必须对齐 - 为什么
transform和minify是两条入口,不能把 SWC 只理解成“更快的 Babel.transformSync”
固定 @swc/core@1.16.1(swc_core v77.0.2)的主链是:
-
parse → 变换 → 打印:
Compiler先按.swcrc/Options解析,再跑 resolver、可选 decorator、TypeScript strip、Wasm plugin、React/JSX、optimizer、compat/env、module,最后可选 minify 与 codegen。 -
剥类型,不做类型检查:
swc_ecma_transforms_typescript去掉类型语法并处理 enum / namespace 等。parser 把部分 TS 语义错误留给 type checker。 -
默认值会咬人:
jsc.transform.react.runtime默认Classic(源码注明 v2 可能改)。decorator 未写decoratorVersion时走 legacy/2021-12路径;解析 TypeScript 时还会强制legacyDecorator: true。env与jsc.target不能同时开。 -
插件是 Wasm,不是稳定 Babel visitor:生产配置是
jsc.experimental.plugins。swc_plugin_runner校验 AST schema;对不上就失败。@swc/wasm回退会跳过 plugin,也没有bundle/parseFile。JS 侧旧plugin/plugins()已标记 deprecated。
案例 1:transformSync 剥 TS 并开自动 JSX
Section titled “案例 1:transformSync 剥 TS 并开自动 JSX”import { transformSync } from "@swc/core";
const { code } = transformSync(src, { filename: "app.tsx", jsc: { parser: { syntax: "typescript", tsx: true }, transform: { react: { runtime: "automatic" } }, target: "es2020", }, module: { type: "es6" },});不写 runtime: "automatic" 时走 classic JSX,仍可能生成 React.createElement。filename 影响是否查找 .swcrc;省略时文档按 swcrc: false 处理。
案例 2:.swcrc 只描述解析与模块
Section titled “案例 2:.swcrc 只描述解析与模块”{ "jsc": { "parser": { "syntax": "typescript", "tsx": true, "decorators": true }, "target": "es2020", "transform": { "react": { "runtime": "automatic" }, "decoratorVersion": "2022-03" } }, "module": { "type": "es6" }}需要 stage-3 decorator 时必须显式选 2022-03 或 2023-11。只开 decorators: true 不够,默认仍可能走 legacy。本轮未展开 CLI 实现,验收以 @swc/core 读这份配置为准。
案例 3:独立 minify,而不是指望 transform 顺便压
Section titled “案例 3:独立 minify,而不是指望 transform 顺便压”import { minifySync } from "@swc/core";
const { code } = minifySync(js, { compress: true, mangle: true,});minify / minifySync 走 swc_ecma_minifier::optimize。transform 里设 minify: true 也会进同一套 pass,但默认是关的。这是 Terser 风格移植,不保证体积或字节与 Terser 一致。
-
不做类型检查:和 esbuild 一样,类型错误只要能 parse 就会变成 JS。CI 仍要
tsc --noEmit。 -
Decorator 默认不是 2022/2023 语义:未设
decoratorVersion走 legacy 路径;TS 还会强制legacyDecorator。NestJS 一类代码从 Babel / tsc 切过来时,要先对版本。 -
Wasm plugin 必须跟 host 的 swc_core 对齐:schema 校验失败会直接 bail。
@swc/wasm下 plugin 被跳过。 -
JSX 默认 classic:React 17+ 项目不写
runtime: "automatic",输出会回到旧工厂函数。
适用 vs 不适用场景
Section titled “适用 vs 不适用场景”适用:
- 需要把 TS/JSX transform 或 minify 嵌进 Node / Rust 宿主
- 配置面接近 Babel(
transform(code, opts)),但能接受剥类型、默认 classic JSX 和实验性 Wasm plugin - 只要独立 minify API,不把打包当成主路径
不适用:
- 把类型检查、稳定 Babel plugin 生态或与 Terser 字节一致当成合同
- 依赖
@swc/wasm还想跑 Wasm 插件或bundle - 需要本文未核验的 CLI 旗标语义——请回到
swc_cli_impl或当前文档,不要从本页外推
固定版本边界
Section titled “固定版本边界”- 本文绑定
swc-project/swc@490c7d88...,@swc/core与发布说明均为1.16.1;npm 未暴露gitHead。 - 许可为 Apache-2.0。Native 绑定来自
binding_core_node;失败时 postinstall 可回退@swc/wasm。 - 未安装依赖、未跑上游测试、未声明下游框架默认编译器,状态保持
UNVERIFIED。
- “更快的 Babel”不是 API 等价——多了 parse/print/minify/bundle,默认值也不一样
- 默认 runtime / decorator 比宣传口径更重要——classic JSX 和 legacy decorator 都是源码里的 Default
- Wasm plugin 用版本门换隔离——换来的是 ABI 耦合,不是无限稳定
- minify 和 transform 是两条合同——打开
minify: true才共享 minifier pass
transformSync("const x: number = 'a'", { jsc: { parser: { syntax: "typescript" } } })会因为类型错误抛出吗?- 不写
jsc.transform.react.runtime时,默认是 automatic 还是 classic? - 加载的是
@swc/wasm回退绑定时,jsc.experimental.plugins还会执行吗?
检查点:
- 不会。它只剥类型,不跑 type checker。
- classic。自动 JSX 必须显式写
automatic。 - 不会。wasm 回退会跳过 plugin。
- 官方文档:swc.rs
- 固定源码:swc-project/swc —— 本文绑定提交
490c7d88ad15cf84ee410c69e19eef86f445d45b - esbuild —— Go 侧对照:plugin 是 onResolve/onLoad,不是 Wasm
- turbopack —— 常见的 Rust 宿主对照,是否链接本版本需另核
- rspack —— 另一条嵌入式 transform 路线
- esbuild —— Go vs Rust 的同代对照;能力边界不同
- turbopack —— Rust bundler 对照
- rspack —— 同样把原生 transform 嵌进打包器
- rollup —— 库发包与 tree-shake 对照组
- ast-grep —— ast-grep — 按语法树搜代码、改代码的命令行工具
- biome —— Biome — JS/TS 工具链一体化(Rust 写的 linter+formatter)
- bun —— Bun — JS 全能运行时
- dust —— dust — du 的可视化替代,按目录大小排树状条形图
- engine262 —— engine262 — 用 JavaScript 实现的 ECMA-262 参考引擎
- jest —— Jest — 一个包就能跑 JS 测试的全家桶
- lightningcss —— lightningcss — 用 Rust 把 CSS 工具链一遍跑完的编译器
- lingui —— Lingui — 写自然字符串,编译期自动提取 i18n msgid
- oxc —— oxc — Rust 写一整套 JS/TS 工具链的勇气
- ripgrep —— ripgrep — Rust 写的现代 grep
- rolldown —— rolldown — 用 Rust 给 Vite 当统一引擎的打包器
- rspack —— rspack — 用 Rust 重写 webpack 的内核,但留下整个 plugin 生态
- turbopack —— Turbopack — 把 bundler 重做成增量计算应用
- webpack —— webpack 模块打包