Трансформация в SWC строится вокруг этапа JSC (JavaScript Compiler), который отвечает за преобразование современного JavaScript и TypeScript в совместимый с целевой средой код. Основной принцип заключается в разделении конфигурации на уровни: синтаксический анализ, трансформации AST и генерация кода.
Ключевая особенность SWC — высокая скорость за счёт реализации на Rust и строгого разделения трансформационных стадий.
Конфигурация трансформаций задаётся через поле
jsc.transform в .swcrc или при использовании
@swc/core.
{
"jsc": {
"parser": {
"syntax": "typescript"
},
"transform": {
"react": {
"runtime": "automatic"
}
}
}
}
Основная логика трансформаций сосредоточена в объекте:
jsc.transform.react
jsc.transform.optimizer
jsc.transform.regenerator
jsc.transform.legacyDecorator
jsc.transform.decoratorMetadata
SWC поддерживает преобразование JSX через встроенный трансформер React.
{
"jsc": {
"transform": {
"react": {
"runtime": "automatic",
"importSource": "react",
"development": false,
"refresh": false
}
}
}
}
При runtime: “automatic” SWC автоматически вставляет
импорты функций JSX:
Исходный код:
const App = () => <div>Hello</div>;
Результат:
import { jsx as _jsx } from "react/jsx-runtime";
const App = () => _jsx("div", { children: "Hello" });
Важно: необходимость ручного импорта React отпадает.
SWC не выполняет типизацию, а только удаляет типы и преобразует синтаксис.
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true
}
}
}
Поддерживаются:
interface, type
enum
namespace
Пример:
interface User {
name: string;
}
const user: User = { name: "Alex" };
Результат:
const user = { name: "Alex" };
Поле env.target определяет уровень ECMAScript, к которому
приводится код.
{
"env": {
"target": "es2018"
}
}
Возможные значения:
es5
es2015
es2017
es2020
es2022
esnext
SWC автоматически включает или исключает трансформации:
Асинхронные функции требуют отдельного трансформера:
{
"jsc": {
"transform": {
"regenerator": true
}
}
}
Пример:
async function load() {
const data = await fetch("/api");
return data.json();
}
Результат при ES5 target:
function load() {
return _async_to_generator(function* () {
const data = yield fetch("/api");
return data.json();
})();
}
Особенность: SWC использует генераторную модель вместо state machine как у некоторых других компиляторов.
SWC поддерживает два режима декораторов:
{
"jsc": {
"transform": {
"legacyDecorator": true
}
}
}
Пример:
function readonly(target, key, descriptor) {
descriptor.writable = false;
}
class Test {
@readonly
method() {}
}
Дополнительная опция:
{
"jsc": {
"transform": {
"decoratorMetadata": true
}
}
}
Используется для reflection API:
import "reflect-metadata";
SWC включает встроенный optimizer на уровне AST.
{
"jsc": {
"transform": {
"optimizer": {
"globals": {
"vars": {
"DEBUG": false
}
}
}
}
}
}
Пример:
if (false) {
console.log("never");
}
Результат:
// удалено полностью
SWC поддерживает преобразование ES Modules в CommonJS и другие форматы.
{
"module": {
"type": "commonjs"
}
}
Варианты:
commonjs
amd
umd
es6 (без изменений)
systemjs
import fs from "fs";
export const read = () => fs.readFileSync("a.txt");
Результат CommonJS:
const fs = require("fs");
exports.read = () => fs.readFileSync("a.txt");
Помимо .swcrc, трансформации задаются через @swc/core.
import { transform } from "@swc/core";
const output = await transform(code, {
jsc: {
parser: {
syntax: "typescript",
tsx: true
},
transform: {
react: {
runtime: "automatic"
}
}
}
});
filename
sourceMaps
isModule
minify
jsc
При включении source maps SWC связывает трансформированный код с оригинальным AST.
{
"sourceMaps": true,
"inlineSourcesContent": true
}
Особенности:
Трансформации напрямую зависят от конфигурации парсера:
{
"jsc": {
"parser": {
"syntax": "ecmascript",
"jsx": true,
"dynamicImport": true
}
}
}
Ошибка в parser полностью блокирует transform этап.
SWC применяет трансформации в фиксированном порядке:
Порядок важен, так как некоторые трансформации зависят от структуры AST после предыдущих шагов.
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true
},
"transform": {
"react": {
"runtime": "automatic",
"refresh": true
}
}
}
}
{
"env": {
"target": "es5"
},
"jsc": {
"transform": {
"regenerator": true
}
},
"module": {
"type": "commonjs"
}
}
{
"jsc": {
"parser": {
"syntax": "ecmascript"
}
}
}
Ключевой принцип: transform слой не интерпретирует код, а лишь переписывает структуру дерева синтаксиса.