SWC 编译与转译 #
编译基础 #
什么是编译? #
编译是将源代码从一种形式转换为另一种形式的过程。SWC 主要处理:
text
┌─────────────────────────────────────────────────────────────┐
│ SWC 编译流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 现代语法 ───► 目标语法 │
│ TypeScript ───► JavaScript │
│ JSX ───► JavaScript │
│ ES2022 ───► ES5/ES2015 │
│ │
└─────────────────────────────────────────────────────────────┘
基本编译示例 #
javascript
// 输入(ES2022)
class Example {
#privateField = 42;
#privateMethod() {
return this.#privateField;
}
get value() {
return this.#privateMethod();
}
}
// 输出(ES2015)
var Example = function() {
"use strict";
function Example() {
this._privateField = 42;
}
var _proto = Example.prototype;
_proto._privateMethod = function() {
return this._privateField;
};
_proto = Object.create(null, {
value: {
get: function() {
return this._privateMethod();
}
}
});
return Example;
}();
ECMAScript 特性编译 #
箭头函数 #
javascript
// 输入
const add = (a, b) => a + b;
const greet = name => `Hello, ${name}!`;
// 输出(ES5)
var add = function(a, b) {
return a + b;
};
var greet = function(name) {
return "Hello, " + name + "!";
};
类 #
javascript
// 输入
class Person {
constructor(name) {
this.name = name;
}
greet() {
return `Hello, I'm ${this.name}`;
}
static create(name) {
return new Person(name);
}
}
// 输出(ES5)
var Person = function() {
"use strict";
function Person(name) {
this.name = name;
}
var _proto = Person.prototype;
_proto.greet = function() {
return "Hello, I'm " + this.name;
};
Person.create = function(name) {
return new Person(name);
};
return Person;
}();
类字段 #
javascript
// 输入
class Counter {
count = 0;
increment = () => {
this.count++;
};
}
// 输出(ES2015)
class Counter {
constructor() {
this.count = 0;
this.increment = ()=>{
this.count++;
};
}
}
私有字段和方法 #
javascript
// 输入
class Example {
#privateField = 42;
#privateMethod() {
return this.#privateField;
}
}
// 输出(ES2015)
var _privateField = new WeakMap();
var _privateMethod = new WeakSet();
class Example {
constructor() {
_privateMethod.add(this);
_privateField.set(this, {
writable: true,
value: 42
});
}
}
模板字符串 #
javascript
// 输入
const name = "World";
const greeting = `Hello, ${name}!`;
const multiLine = `
Line 1
Line 2
`;
// 输出(ES5)
var name = "World";
var greeting = "Hello, " + name + "!";
var multiLine = "\n Line 1\n Line 2\n";
解构赋值 #
javascript
// 输入
const { a, b: renamed, ...rest } = obj;
const [first, second, ...others] = array;
// 输出(ES5)
var _obj = obj, a = _obj.a, renamed = _obj.b, rest = _objectWithoutProperties(_obj, [
"a",
"b"
]);
var _array = array, first = _array[0], second = _array[1], others = _array.slice(2);
展开运算符 #
javascript
// 输入
const merged = { ...obj1, ...obj2 };
const combined = [...arr1, ...arr2];
// 输出(ES5)
var merged = Object.assign({}, obj1, obj2);
var combined = arr1.concat(arr2);
默认参数 #
javascript
// 输入
function greet(name = "World", greeting = "Hello") {
return `${greeting}, ${name}!`;
}
// 输出(ES5)
function greet() {
var name = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : "World";
var greeting = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "Hello";
return greeting + ", " + name + "!";
}
可选链 #
javascript
// 输入
const value = obj?.nested?.property;
const result = func?.();
// 输出(ES5)
var _obj_nested;
var value = obj === null || obj === void 0 ? void 0 : (_obj_nested = obj.nested) === null || _obj_nested === void 0 ? void 0 : _obj_nested.property;
var result = func === null || func === void 0 ? void 0 : func();
空值合并 #
javascript
// 输入
const value = input ?? "default";
// 输出(ES5)
var _input;
var value = (_input = input) !== null && _input !== void 0 ? _input : "default";
async/await #
javascript
// 输入
async function fetchData() {
const response = await fetch(url);
const data = await response.json();
return data;
}
// 输出(ES2015)
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
}
if (info.done) {
resolve(value);
} else {
Promise.resolve(value).then(_next, _throw);
}
}
function _asyncToGenerator(fn) {
return function() {
var self = this, args = arguments;
return new Promise(function(resolve, reject) {
var gen = fn.apply(self, args);
function _next(value) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
}
function _throw(err) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
}
_next(undefined);
});
};
}
function fetchData() {
return _fetchData.apply(this, arguments);
}
function _fetchData() {
_fetchData = _asyncToGenerator(function*() {
var response = yield fetch(url);
var data = yield response.json();
return data;
});
return _fetchData.apply(this, arguments);
}
TypeScript 编译 #
类型擦除 #
SWC 默认只擦除类型,不进行类型检查:
typescript
// 输入
interface User {
name: string;
age: number;
}
function greet(user: User): string {
return `Hello, ${user.name}!`;
}
const user: User = { name: "Alice", age: 30 };
javascript
// 输出
function greet(user) {
return "Hello, " + user.name + "!";
}
var user = {
name: "Alice",
age: 30
};
枚举 #
typescript
// 输入
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT"
}
const enum Status {
Active,
Inactive
}
javascript
// 输出
var Direction;
(function(Direction) {
Direction["Up"] = "UP";
Direction["Down"] = "DOWN";
Direction["Left"] = "LEFT";
Direction["Right"] = "RIGHT";
})(Direction || (Direction = {}));
// const enum 内联
var Status = {
Active: 0,
Inactive: 1
};
命名空间 #
typescript
// 输入
namespace Utils {
export function log(message: string) {
console.log(message);
}
export const version = "1.0.0";
}
javascript
// 输出
var Utils;
(function(Utils) {
function log(message) {
console.log(message);
}
Utils.log = log;
Utils.version = "1.0.0";
})(Utils || (Utils = {}));
装饰器 #
typescript
// 输入
function logged(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const original = descriptor.value;
descriptor.value = function(...args: any[]) {
console.log(`Calling ${propertyKey}`);
return original.apply(this, args);
};
}
class Example {
@logged
method() {
return "result";
}
}
javascript
// 输出
function logged(target, propertyKey, descriptor) {
var original = descriptor.value;
descriptor.value = function() {
for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
args[_key] = arguments[_key];
}
console.log("Calling " + propertyKey);
return original.apply(this, args);
};
}
class Example {
method() {
return "result";
}
}
_decorate([
logged
], Example.prototype, "method", null);
泛型 #
typescript
// 输入
function identity<T>(arg: T): T {
return arg;
}
const result = identity<string>("hello");
javascript
// 输出(类型被擦除)
function identity(arg) {
return arg;
}
var result = identity("hello");
类型导入 #
typescript
// 输入
import type { User } from './types';
import { type Role, type Permission } from './auth';
function checkUser(user: User) {
return user;
}
javascript
// 输出(类型导入被移除)
function checkUser(user) {
return user;
}
JSX 编译 #
Classic 运行时 #
javascript
// 输入
const element = <div className="container">Hello, World!</div>;
// 输出
var element = React.createElement("div", {
className: "container"
}, "Hello, World!");
Automatic 运行时 #
javascript
// 输入
const element = <div className="container">Hello, World!</div>;
// 输出
import { jsx as _jsx } from "react/jsx-runtime";
var element = _jsx("div", {
className: "container",
children: "Hello, World!"
});
JSX 配置 #
json
{
"jsc": {
"parser": {
"syntax": "ecmascript",
"jsx": true
},
"transform": {
"react": {
"runtime": "automatic",
"importSource": "react",
"pragma": "React.createElement",
"pragmaFrag": "React.Fragment"
}
}
}
}
自定义 JSX #
json
{
"jsc": {
"transform": {
"react": {
"runtime": "classic",
"pragma": "h",
"pragmaFrag": "Fragment"
}
}
}
}
javascript
// 输入
const element = <div>Hello</div>;
// 输出
var element = h("div", null, "Hello");
Vue JSX #
json
{
"jsc": {
"parser": {
"syntax": "ecmascript",
"jsx": true
},
"transform": {
"react": {
"runtime": "classic",
"pragma": "h",
"pragmaFrag": "Fragment"
}
}
}
}
模块转换 #
ES Modules 到 CommonJS #
javascript
// 输入
import { foo, bar } from './module';
import * as utils from './utils';
export default function() {}
export const value = 42;
javascript
// 输出
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "value", {
enumerable: true,
get: function() {
return value;
}
});
exports.default = function() {};
var _module = require("./module");
var utils = require("./utils");
const value = 42;
CommonJS 到 ES Modules #
javascript
// 输入
const foo = require('./foo');
module.exports = { value: 42 };
javascript
// 输出
import foo from "./foo";
export const value = 42;
export default { value: 42 };
动态导入 #
javascript
// 输入
const module = await import('./module');
// 输出(保持动态导入)
const module = await import('./module');
目标环境编译 #
ES5 目标 #
json
{
"jsc": {
"target": "es5"
}
}
ES2015 目标 #
json
{
"jsc": {
"target": "es2015"
}
}
ES2020 目标 #
json
{
"jsc": {
"target": "es2020"
}
}
目标特性对照 #
| 特性 | ES5 | ES2015 | ES2020 |
|---|---|---|---|
| 箭头函数 | 转换 | 保留 | 保留 |
| 类 | 转换 | 保留 | 保留 |
| 模板字符串 | 转换 | 保留 | 保留 |
| 可选链 | 转换 | 转换 | 保留 |
| 空值合并 | 转换 | 转换 | 保留 |
| async/await | 转换 | 转换 | 保留 |
Polyfill 注入 #
配置 #
json
{
"env": {
"targets": {
"chrome": "60"
},
"coreJs": "3.29",
"mode": "usage"
}
}
自动注入 #
javascript
// 输入
const result = [1, 2, 3].includes(2);
const obj = { a: 1, b: 2 };
const copy = { ...obj };
// 输出(自动注入 polyfill)
import "core-js/modules/es.array.includes.js";
import "core-js/modules/es.object.assign.js";
var result = [1, 2, 3].includes(2);
var obj = { a: 1, b: 2 };
var copy = Object.assign({}, obj);
编译 API #
transform 函数 #
javascript
const swc = require('@swc/core');
const result = await swc.transform(sourceCode, {
jsc: {
parser: {
syntax: 'ecmascript'
},
target: 'es2015'
}
});
console.log(result.code);
console.log(result.map);
transformSync 函数 #
javascript
const swc = require('@swc/core');
const result = swc.transformSync(sourceCode, {
jsc: {
parser: {
syntax: 'ecmascript'
},
target: 'es2015'
}
});
parseFile 函数 #
javascript
const swc = require('@swc/core');
const ast = await swc.parseFile('./src/index.js', {
syntax: 'ecmascript'
});
console.log(ast);
print 函数 #
javascript
const swc = require('@swc/core');
const ast = await swc.parse(sourceCode, {
syntax: 'ecmascript'
});
const { code } = await swc.print(ast, {
minify: false
});
实战示例 #
编译 TypeScript 项目 #
javascript
// build.js
const swc = require('@swc/core');
const fs = require('fs');
const path = require('path');
async function build() {
const files = fs.readdirSync('./src');
for (const file of files) {
if (file.endsWith('.ts')) {
const input = fs.readFileSync(`./src/${file}`, 'utf-8');
const result = await swc.transform(input, {
jsc: {
parser: {
syntax: 'typescript'
},
target: 'es2015'
},
module: {
type: 'commonjs'
}
});
const outputFile = file.replace('.ts', '.js');
fs.writeFileSync(`./dist/${outputFile}`, result.code);
}
}
}
build();
编译 React 组件 #
javascript
const swc = require('@swc/core');
const jsxCode = `
import React from 'react';
function Button({ children, onClick }) {
return (
<button className="btn" onClick={onClick}>
{children}
</button>
);
}
export default Button;
`;
const result = await swc.transform(jsxCode, {
jsc: {
parser: {
syntax: 'ecmascript',
jsx: true
},
transform: {
react: {
runtime: 'automatic'
}
},
target: 'es2015'
},
module: {
type: 'es6'
}
});
下一步 #
现在你已经掌握了 SWC 的编译和转译功能,接下来学习 代码压缩 了解如何优化代码体积!
最后更新:2026-03-28