SWC(Speedy Web Compiler)是一个用 Rust 编写的超快 JavaScript 和 TypeScript 编译器。它以比 Babel 快 20-70 倍的速度进行编译、压缩、打包和转换现代 JavaScript 和 TypeScript。SWC 由 Donny (kdy1) 创建,已成为现代 Web 生态系统中的基础工具,驱动着 Next.js、Parcel、Deno 和 Vercel。无论你需要 Babel 的替代品、高性能压缩器还是快速的 TypeScript 转译器,SWC 都能提供生产构建系统所需的速度和正确性。
SWC 是基于 Rust 的 JavaScript/TypeScript 编译器,速度比 Babel 快 20-70 倍。它处理 JSX/TSX 转译、TypeScript 剥离、装饰器转换、模块系统转换(ESM/CJS/UMD/AMD)、通过 swc-minify 的压缩以及通过 swcpack 的打包。通过 .swcrc 或 swc.config.js 配置。SWC 从 v12 起驱动 Next.js,通过插件与 Vite 和 Webpack 集成,并提供 Rust 或 Wasm 自定义 AST 转换的插件系统。从 Babel 迁移非常简单,功能几乎完全对等。
- SWC 用 Rust 编写,利用零成本抽象和并行性实现比 Babel 快 20-70 倍的编译速度。
- 开箱即用支持 JSX、TSX、TypeScript、装饰器(遗留和 2024)和所有现代 ECMAScript 特性。
- .swcrc 配置文件对解析、转换、模块输出和压缩提供细粒度控制。
- 从 v12 起 SWC 作为 Next.js 的默认编译器,替代 Babel 实现更快的构建和 HMR。
- swcpack 是内置打包器,提供类似 Webpack 的 Tree-shaking、代码分割和模块解析。
- 基于 Wasm 的插件系统让你编写以接近原生速度运行的自定义 AST 转换。
为什么 SWC 如此快速
SWC 通过 Rust 固有的架构优势和其内部设计实现了非凡的编译速度。
- 用 Rust 编写:Rust 编译为原生机器码,具有零成本抽象、无垃圾回收器和确定性内存管理。这消除了 V8 为 Babel 等基于 JavaScript 的编译器引入的运行时开销。:用 Rust 编写:Rust 编译为原生机器码,具有零成本抽象、无垃圾回收器和确定性内存管理。这消除了 V8 为 Babel 等基于 JavaScript 的编译器引入的运行时开销。
- 并行处理:SWC 使用 Rust 线程并发处理多个文件。每个文件独立解析、转换和输出,充分利用所有 CPU 核心。:并行处理:SWC 使用 Rust 线程并发处理多个文件。每个文件独立解析、转换和输出,充分利用所有 CPU 核心。
- 单遍转换:SWC 尽可能在单次 AST 遍历中应用多个转换,避免 Babel 插件链所需的重复解析-转换-序列化周期。:单遍转换:SWC 尽可能在单次 AST 遍历中应用多个转换,避免 Babel 插件链所需的重复解析-转换-序列化周期。
- 高效内存布局:Rust 的结构体和枚举使用紧凑的栈分配内存布局。AST 表示对缓存友好,减少了与 JavaScript 对象图相比的内存访问延迟。:高效内存布局:Rust 的结构体和枚举使用紧凑的栈分配内存布局。AST 表示对缓存友好,减少了与 JavaScript 对象图相比的内存访问延迟。
# Benchmark: Compile 10,000 TypeScript files
#
# SWC 1.2s (Rust, parallel)
# esbuild 0.8s (Go, parallel)
# Babel 45.0s (JS, single-threaded)
# tsc 60.0s (TS, single-threaded)
#
# SWC is 37-50x faster than Babel/tsc
# for equivalent compilation tasks安装
SWC 根据使用场景提供多个包。核心 CLI 包处理独立编译,集成包将 SWC 连接到现有构建工具。
# Core SWC CLI
npm install --save-dev @swc/cli @swc/core
# Compile a single file
npx swc src/index.ts -o dist/index.js
# Compile a directory
npx swc src -d dist
# Watch mode
npx swc src -d dist --watch
# Integration packages
npm install --save-dev swc-loader # Webpack
npm install --save-dev @vitejs/plugin-react-swc # Vite
npm install --save-dev @swc/jest # Jest
# Verify installation
npx swc --version
# @swc/cli: 0.4.x
# @swc/core: 1.7.x.swcrc 配置
.swcrc 文件是 SWC 的主要配置机制。它控制解析行为、转换规则、模块输出格式、压缩设置和环境目标。将其放在项目根目录下与 package.json 并列。
用于 React TypeScript 项目的基本 .swcrc:
// .swcrc — Basic React + TypeScript configuration
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true,
"decorators": false,
"dynamicImport": true
},
"transform": {
"react": {
"runtime": "automatic",
"throwIfNamespace": true,
"useBuiltins": true
}
},
"target": "es2020",
"loose": false,
"externalHelpers": false
},
"module": {
"type": "es6"
},
"minify": false,
"sourceMaps": true
}带有装饰器、模块别名和环境目标的高级 .swcrc:
// .swcrc — Advanced configuration with decorators and aliases
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true,
"decorators": true,
"dynamicImport": true,
"importAssertions": true
},
"transform": {
"legacyDecorator": true,
"decoratorMetadata": true,
"react": {
"runtime": "automatic",
"importSource": "@emotion/react"
}
},
"target": "es2021",
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"],
"@components/*": ["./src/components/*"],
"@utils/*": ["./src/utils/*"]
},
"externalHelpers": true
},
"module": {
"type": "commonjs",
"strict": true,
"lazy": true
},
"env": {
"targets": {
"chrome": "90",
"firefox": "88",
"safari": "14",
"node": "18"
},
"mode": "usage",
"coreJs": "3.36"
},
"sourceMaps": true
}解析和语法支持
SWC 包含一个功能完整的 JavaScript 和 TypeScript 解析器,支持所有 ECMAScript 2024 特性、JSX、TSX、装饰器(遗留和 TC39 第 3 阶段)、动态导入、顶级 await、导入断言和可选链。解析器通过 .swcrc 的 jsc.parser 部分进行配置。
不同语法模式的解析器配置:
// TypeScript parser with all features enabled
"parser": {
"syntax": "typescript",
"tsx": true,
"decorators": true,
"dynamicImport": true,
"importAssertions": true
}
// JavaScript parser (ECMAScript)
"parser": {
"syntax": "ecmascript",
"jsx": true,
"decorators": true,
"decoratorsBeforeExport": true,
"dynamicImport": true,
"importAssertions": true,
"topLevelAwait": true,
"exportDefaultFrom": true
}转换
SWC 根据目标环境和配置应用代码转换。转换包括 JSX 编译、TypeScript 剥离、装饰器降级、类属性、可选链、空值合并等。
JSX 和 TSX 转换
SWC 将 JSX 语法转换为函数调用。它支持经典的 React.createElement 运行时和 React 17 引入的现代自动 JSX 运行时。自动运行时不需要在每个文件中导入 React。
// Input: JSX component
function App() {
return (
<div style={{ padding: 16 }}>
<h1>Hello SWC</h1>
<Button onClick={handleClick}>Click me</Button>
</div>
);
}
// Output with runtime: "automatic" (React 17+)
// SWC auto-inserts the jsx import
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
function App() {
return _jsxs("div", {
style: { padding: 16 },
children: [
_jsx("h1", { children: "Hello SWC" }),
_jsx(Button, { onClick: handleClick, children: "Click me" })
]
});
}
// Output with runtime: "classic"
function App() {
return React.createElement("div", { style: { padding: 16 } },
React.createElement("h1", null, "Hello SWC"),
React.createElement(Button, { onClick: handleClick }, "Click me")
);
}装饰器支持
SWC 支持遗留装饰器规范(TypeScript experimentalDecorators)和 TC39 2024 装饰器规范。遗留模式兼容 Angular、NestJS、MobX 和 TypeORM。2024 规范是标准轨道版本。
// Input: TypeScript class with legacy decorators
// Requires: "decorators": true, "legacyDecorator": true
import { Injectable, Controller, Get } from "@nestjs/common";
@Injectable()
class UserService {
findAll() {
return [{ id: 1, name: "Alice" }];
}
}
@Controller("/users")
class UserController {
constructor(private userService: UserService) {}
@Get()
getUsers() {
return this.userService.findAll();
}
}
// SWC compiles decorators to __decorate() calls
// compatible with TypeScript emitDecoratorMetadata类属性和私有字段
SWC 将类字段、静态属性和私有字段(使用 # 语法)转换为兼容旧环境的输出。启用 useDefineForClassFields 后,类字段使用符合 TC39 规范的 Object.defineProperty 语义。
// Input: Modern class with all field types
class Config {
// Public field with initializer
apiUrl = "https://api.example.com";
// Private field (# syntax)
#secretKey = "abc123";
// Static field
static version = "2.0.0";
// Static private field
static #instances = 0;
constructor() {
Config.#instances++;
}
getSecret() {
return this.#secretKey;
}
}
// SWC transforms private fields to WeakMap
// when targeting older environments模块系统
SWC 可以以四种不同的模块格式输出代码:ES 模块(ESM)、CommonJS(CJS)、UMD 和 AMD。模块配置决定输出中 import/export 语句的转换方式。
- ESM: ES 模块 (es6):保留 import/export 语法。用于现代打包器、支持模块的浏览器和 Node.js type: "module"。
- CommonJS: CommonJS (commonjs):转换为 require/module.exports。用于 Node.js 包、Jest 测试和不支持 ESM 的环境。
- UMD: UMD (umd):通用模块定义,可在浏览器全局和 CommonJS 中使用。用于需要支持多种使用模式的库包。
- AMD: AMD (amd):用于 RequireJS 和类似 AMD 加载器的异步模块定义。在现代项目中很少需要。
// Input: ES module syntax
import { readFile } from "fs/promises";
import path from "path";
export const loadConfig = async (file) => {
const content = await readFile(path.resolve(file), "utf-8");
return JSON.parse(content);
};
export default loadConfig;
// Output: CommonJS (module.type: "commonjs")
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const _promises = require("fs/promises");
const _path = _interopRequireDefault(require("path"));
const loadConfig = async (file) => {
const content = await (0, _promises.readFile)(
_path.default.resolve(file), "utf-8"
);
return JSON.parse(content);
};
exports.loadConfig = loadConfig;
exports.default = loadConfig;
// Output: UMD (module.type: "umd")
(function(global, factory) {
if (typeof define === "function" && define.amd)
define(["exports", "fs/promises", "path"], factory);
else if (typeof exports !== "undefined")
factory(exports, require("fs/promises"), require("path"));
else {
var mod = { exports: {} };
factory(mod.exports);
global.myModule = mod.exports;
}
})(this, function(exports, _promises, _path) {
// ... module code
});使用 SWC 进行压缩
SWC 包含内置压缩器(swc-minify),它是 Terser 的 Rust 移植版本。它执行死代码消除、常量折叠、标识符混淆、空白移除以及内联和分支简化等高级优化。压缩器适用于 JavaScript 并支持 Source Map 生成。
压缩配置选项:
// .swcrc — Minification configuration
{
"jsc": {
"parser": { "syntax": "typescript", "tsx": true },
"target": "es2020",
"minify": {
"compress": {
"dead_code": true,
"drop_console": true,
"drop_debugger": true,
"pure_funcs": ["console.info", "console.debug"],
"passes": 2,
"toplevel": true,
"unused": true
},
"mangle": {
"toplevel": true,
"keep_classnames": false,
"keep_fnames": false
}
}
},
"minify": true
}
// CLI minification
// npx swc src/index.ts -o dist/index.min.js --minify压缩器基准比较:
# Minification benchmark: 1MB JavaScript bundle
#
# swc-minify 0.4s 152 KB output
# esbuild 0.3s 155 KB output
# terser 8.2s 148 KB output
# uglify-js 12.1s 150 KB output
#
# swc-minify is 20x faster than Terser
# with comparable output size (2-3% larger)使用 swcpack 打包
swcpack 是 SWC 的内置打包器,处理模块解析、Tree-shaking、代码分割和输出生成。虽然仍标记为实验性,但它展示了 SWC 作为完整构建工具的发展方向。通过项目根目录的 spack.config.js 配置。
基本 swcpack 配置:
// spack.config.js — swcpack bundler configuration
const { config } = require("@swc/core/spack");
module.exports = config({
entry: {
web: __dirname + "/src/index.ts",
},
output: {
path: __dirname + "/dist",
name: "[name].bundle.js",
},
module: {},
options: {
jsc: {
parser: {
syntax: "typescript",
tsx: true,
},
target: "es2020",
},
},
});
// Run the bundler
// npx spack与 Next.js 集成
Next.js 从 v12 起使用 SWC 作为默认编译器,完全替代了大多数项目中的 Babel。这一切换使 Fast Refresh(HMR)速度提升 3 倍,构建时间提升多达 5 倍。Next.js 通过 next.config.js 自动配置 SWC,无需单独的 .swcrc 文件。
next.config.js 中的 SWC 配置:
// next.config.js — SWC configuration in Next.js
/** @type {import("next").NextConfig} */
const nextConfig = {
// SWC is enabled by default since Next.js 12
// These options customize its behavior
compiler: {
// styled-components support
styledComponents: true,
// Emotion CSS-in-JS support
emotion: {
sourceMap: true,
autoLabel: "dev-only",
labelFormat: "[local]",
},
// Remove console.log in production
removeConsole: {
exclude: ["error", "warn"],
},
// Import path optimization
modularizeImports: {
"lodash": {
transform: "lodash/\{\{member}}",
},
"@mui/icons-material": {
transform: "@mui/icons-material/\{\{member}}",
},
},
// React Server Components configuration
reactRemoveProperties: true,
},
// TypeScript path aliases work automatically
// SWC reads tsconfig.json paths
};
module.exports = nextConfig;Next.js SWC 功能包括:styled-components 和 emotion 支持、自动 React 运行时、通过 modularizeImports 的导入路径优化、通过 removeConsole 的服务端死代码移除、TypeScript 路径别名和实验性 server actions 编译。
与 Vite 集成
Vite 可以通过 @vitejs/plugin-react-swc 插件使用 SWC 作为 JavaScript/TypeScript 转换器。这将默认的基于 esbuild 的 JSX 转换替换为 SWC,在保持类似速度的同时提供更好的 Babel 兼容性(装饰器、遗留类属性)。
使用 SWC 的 Vite 配置:
// vite.config.ts — Using SWC with Vite
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react-swc";
export default defineConfig({
plugins: [
react({
// Enable TypeScript decorators
tsDecorators: true,
// Custom SWC plugins
plugins: [
["@swc/plugin-styled-components", {}],
],
}),
],
build: {
target: "es2020",
sourcemap: true,
},
});
// Installation:
// npm install --save-dev vite @vitejs/plugin-react-swc
// npm install --save-dev @swc/plugin-styled-components (optional)与 Webpack 集成
swc-loader 包为 Webpack 项目提供 babel-loader 的直接替代品。它使用 SWC 进行 JavaScript 和 TypeScript 编译,同时保留 Webpack 作为打包器。这是现有 Webpack 项目最快的迁移路径。
使用 swc-loader 的 Webpack 配置:
// webpack.config.js — Using SWC with Webpack
const path = require("path");
module.exports = {
entry: "./src/index.tsx",
output: {
path: path.resolve(__dirname, "dist"),
filename: "bundle.js",
},
module: {
rules: [
{
test: /\.(ts|tsx|js|jsx)\$/,
exclude: /node_modules/,
use: {
loader: "swc-loader",
options: {
jsc: {
parser: {
syntax: "typescript",
tsx: true,
decorators: true,
},
transform: {
react: {
runtime: "automatic",
},
},
target: "es2020",
},
},
},
},
],
},
resolve: {
extensions: [".ts", ".tsx", ".js", ".jsx"],
},
};
// Migration from babel-loader:
// 1. npm uninstall babel-loader @babel/core @babel/preset-env
// 2. npm install --save-dev swc-loader @swc/core
// 3. Replace "babel-loader" with "swc-loader" in webpack config插件系统
SWC 提供基于 Wasm 的插件系统,允许自定义 AST 转换。插件用 Rust 编写,编译为 WebAssembly,在运行时加载。这使得自定义语法转换、代码检测和编译时代码生成成为可能,同时保持接近原生的性能。
创建基本的 SWC 插件:
// Rust SWC plugin example (lib.rs)
// Cargo.toml dependency: swc_plugin_macro, swc_ecma_ast, swc_ecma_visit
use swc_plugin_macro::plugin_transform;
use swc_ecma_ast::Program;
use swc_ecma_visit::{VisitMut, VisitMutWith};
struct ConsoleRemover;
impl VisitMut for ConsoleRemover {
fn visit_mut_call_expr(
&mut self,
call: &mut swc_ecma_ast::CallExpr,
) {
// Visit children first
call.visit_mut_children_with(self);
// Custom transformation logic here
// e.g., remove console.log calls
}
}
#[plugin_transform]
fn process(program: Program, _config: String) -> Program {
let mut visitor = ConsoleRemover;
let mut program = program;
program.visit_mut_with(&mut visitor);
program
}
// Build: cargo build --target wasm32-wasi --release在 .swcrc 中使用插件:
// .swcrc — Using custom and community plugins
{
"jsc": {
"parser": { "syntax": "typescript", "tsx": true },
"target": "es2020",
"experimental": {
"plugins": [
// Community plugin (npm package)
["@swc/plugin-styled-components", {
"displayName": true,
"ssr": true
}],
// Custom local plugin (.wasm file)
["./plugins/my-transform.wasm", {
"option1": "value1"
}],
// Emotion CSS-in-JS plugin
["@swc/plugin-emotion", {}]
]
}
}
}从 Babel 迁移到 SWC
对于大多数项目,从 Babel 迁移到 SWC 非常简单,因为 SWC 支持大多数常用的 Babel 预设和插件。主要步骤是将 babel-loader 或 @babel/cli 替换为 SWC 等效项,并将 Babel 配置转换为 .swcrc 格式。
逐步迁移过程:
# Step 1: Install SWC packages
npm install --save-dev @swc/core @swc/cli
# For Webpack projects:
npm install --save-dev swc-loader
# For Jest:
npm install --save-dev @swc/jest
# Step 2: Remove Babel packages
npm uninstall @babel/core @babel/cli @babel/preset-env
npm uninstall @babel/preset-react @babel/preset-typescript
npm uninstall babel-loader babel-jest
# Step 3: Create .swcrc from your babel config
# (see mapping table below)
# Step 4: Update package.json scripts
# Before: "build": "babel src -d dist"
# After: "build": "swc src -d dist"
# Step 5: Update Jest config (jest.config.js)
# Before: transform: { "^.+\\.tsx?\$": "babel-jest" }
# After: transform: { "^.+\\.tsx?\$": ["@swc/jest", {}] }
# Step 6: Delete .babelrc or babel.config.js
# Step 7: Test build and fix any edge cases常见 Babel 预设和插件到 SWC 配置的映射:
| Babel Config | SWC Equivalent (.swcrc) |
|---|---|
| @babel/preset-env | jsc.target: "es2020" or env.targets |
| @babel/preset-react | jsc.transform.react.runtime: "automatic" |
| @babel/preset-typescript | jsc.parser.syntax: "typescript" |
| @babel/plugin-proposal-decorators | jsc.parser.decorators: true + jsc.transform.legacyDecorator |
| @babel/plugin-proposal-class-properties | Built-in (jsc.target controls output) |
| @babel/plugin-transform-runtime | jsc.externalHelpers: true |
| babel-plugin-module-resolver | jsc.baseUrl + jsc.paths |
| babel-plugin-styled-components | @swc/plugin-styled-components |
SWC vs Babel vs esbuild vs TypeScript 编译器
了解 SWC 与其他编译器的比较有助于为项目选择正确的工具。
| 特性 | SWC | Babel | esbuild | tsc |
|---|---|---|---|---|
| 编写语言 | Rust | JavaScript | Go | TypeScript |
| 速度(10K 文件) | ~1.2秒 | ~45秒 | ~0.8秒 | ~60秒 |
| 类型检查 | 否 | 否 | 否 | 是 |
| 装饰器(遗留) | 是 | 是 | 否 | 是 |
| 插件系统 | Wasm 插件 | JS 插件(庞大生态) | Go 插件(小型) | 编译器 API |
| 打包 | swcpack(实验性) | 否 | 是(内置) | 否 |
| 压缩 | 内置(类 Terser) | 通过 babel-minify | 内置 | 否 |
| 框架采用 | Next.js、Parcel、Deno | 大多数(遗留) | Vite(开发)、tsup | 不适用(参考) |
SWC 擅长具有高 Babel 兼容性的快速编译,非常适合从 Babel 迁移的大型项目和框架集成(Next.js)。esbuild 在纯打包和简单转译方面最快。Babel 对于需要 SWC 尚不支持的小众插件的项目仍然必要。tsc 是编译期间需要类型检查时的唯一选项。
最佳实践
- 尽可能通过框架集成(Next.js、Vite、Parcel)使用 SWC。框架级集成自动处理配置并确保兼容性。
- 单独运行 tsc --noEmit 进行类型检查。SWC 剥离 TypeScript 类型但不验证它们。
- 设置 jsc.target 选项以匹配最低浏览器或 Node.js 支持。这避免了对已支持语法的不必要转换。
- 为生产构建启用带有 compress 和 mangle 的压缩器。SWC 压缩在输出质量上与 Terser 相当但显著更快。
- 尽可能使用 ES 模块输出格式。ESM 实现更好的 Tree-shaking、静态分析和与现代工具的兼容性。
- 对于 monorepo,使用 extends 字段共享基础 .swcrc 配置以保持包间一致性。
- 从 Babel 迁移时仔细测试输出。装饰器行为或松散模式转换中的某些边缘情况在 Babel 和 SWC 之间可能不同。
- 使用 SWC playground (swc.rs/playground) 在更新构建管道之前测试配置更改并查看转换输出。
// Complete SWC production workflow (package.json)
{
"scripts": {
"dev": "swc src -d dist --watch --source-maps",
"build": "swc src -d dist --minify --source-maps",
"typecheck": "tsc --noEmit",
"test": "jest --config jest.config.js",
"lint": "eslint src --ext .ts,.tsx",
"ci": "npm run typecheck && npm run lint && npm run test && npm run build"
},
"devDependencies": {
"@swc/cli": "^0.4.0",
"@swc/core": "^1.7.0",
"@swc/jest": "^0.2.0",
"typescript": "^5.6.0"
}
}常见问题
为什么 SWC 比 Babel 快?
SWC 用 Rust 编写,编译为原生机器码,具有零成本抽象和无垃圾回收器开销。Babel 在 Node.js 中运行 JavaScript,需要 V8 JIT 编译、垃圾回收暂停,默认是单线程的。SWC 还在更少的 AST 遍历中应用多个转换,减少冗余的解析和序列化。
SWC 支持 TypeScript 类型检查吗?
不支持。SWC 在编译期间剥离 TypeScript 类型注解但不执行类型检查。这是为了速度的刻意设计选择。你应该在 CI 管道或开发工作流中单独运行 tsc --noEmit 来捕获类型错误。
SWC 能完全替代 Babel 吗?
对于大多数项目可以。SWC 支持 JSX、TypeScript、装饰器、类属性、可选链、空值合并和大多数常用 Babel 预设。但是某些小众 Babel 插件可能还没有 SWC 等效项。
SWC 如何与 Next.js 配合?
Next.js 从 v12 起使用 SWC 作为默认编译器。Next.js 根据 next.config.js 设置自动配置 SWC。不需要单独的 .swcrc 文件。集成包括 styled-components 支持、导入优化、console 移除等。
swcpack 是什么,它适合生产环境吗?
swcpack 是 SWC 的内置打包器,处理模块解析、Tree-shaking 和代码分割。截至 2026 年,它仍标记为实验性。生产打包中大多数团队在 Webpack、Vite 或 Next.js 内使用 SWC 作为编译器。
如何编写 SWC 插件?
SWC 插件用 Rust 编写并编译为 WebAssembly。你创建一个实现 visit_mut trait 进行 AST 转换的 Rust 库,用 swc_plugin_runner 编译,在 .swcrc 配置中引用 .wasm 文件。
SWC 兼容现有的 Babel 配置吗?
SWC 不直接读取 .babelrc 文件。你需要将 Babel 配置转换为 .swcrc 格式。常见映射包括:@babel/preset-env 映射到 jsc.target,@babel/preset-react 映射到 jsc.transform.react 等。
应该选择 SWC 还是 esbuild?
如果需要高 Babel 兼容性、使用 Next.js 或需要 Wasm 插件系统,选择 SWC。如果需要最快的打包速度、更简单的配置或构建简单需求的库,选择 esbuild。两者都是现代 JavaScript 工具链的优秀选择。