transform(code, options): асинхронная трансформация

Функция transform в SWC является центральной точкой компиляции и преобразования JavaScript/TypeScript кода. Она выполняет синтаксический разбор исходного текста, построение AST, применение трансформаций (TypeScript, JSX, современные ECMAScript-фичи), генерацию итогового кода и, при необходимости, source map. Асинхронная версия API используется для неблокирующего выполнения трансформации, особенно в серверных средах и сборочных пайплайнах.


Базовая сигнатура и поведение

Асинхронная форма доступна в пакете @swc/core:

import { transform } from "@swc/core";

Сигнатура:

transform(code: string, options: TransformOptions): Promise<TransformOutput>

Возвращаемое значение представляет собой Promise, который резолвится в объект:

{
  code: string,
  map?: string
}

Ключевые особенности асинхронной версии

  • выполнение не блокирует event loop Node.js
  • подходит для параллельных трансформаций
  • оптимальна при работе с большим количеством файлов
  • используется в сборщиках (Webpack, Vite-плагины, custom pipelines)

Архитектура процесса трансформации

Процесс внутри SWC можно разложить на несколько этапов:

  1. Лексический анализ

Исходный код разбивается на токены:

  • ключевые слова
  • идентификаторы
  • операторы
  • литералы

Этот этап формирует поток токенов для парсера.

  1. Синтаксический разбор (Parser)

Токены преобразуются в AST (Abstract Syntax Tree):

Program
 ├── FunctionDeclaration
 ├── VariableDeclaration
 └── ExpressionStatement

AST в SWC строго типизирован и соответствует ECMAScript спецификации.

  1. Трансформации

Применяются плагины и встроенные преобразования:

  • TypeScript → JavaScript
  • JSX → React.createElement или automatic runtime
  • optional chaining → логические выражения
  • nullish coalescing
  • class fields
  • async/await lowering (в зависимости от target)

  1. Генерация кода

AST преобразуется обратно в строку кода с учетом:

  • форматирования
  • минимизации (если включено)
  • совместимости target environment

  1. Source map (опционально)

Генерируется mapping между исходным и результирующим кодом:

original.ts → transformed.js

Конфигурация options

Объект options управляет поведением трансформации.

Основная структура

interface TransformOptions {
  filename?: string;
  sourceMaps?: boolean | "inline";
  minify?: boolean;
  jsc?: JscConfig;
  module?: ModuleConfig;
  isModule?: boolean;
}

JSC-конфигурация

jsc — основная зона управления поведением JavaScript трансформации.

jsc: {
  parser: {
 syntax: "typescript" | "ecmascript" | "jsx",
 tsx?: boolean,
 decorators?: boolean
  },
  target: "es5" | "es2015" | "es2020" | "es2022",
  transform?: {
 react?: {
runtime: "automatic" | "classic",
importSource?: string
 }
  }
}

Парсер

SWC поддерживает три основных режима:

ECMAScript

parser: {
  syntax: "ecmascript"
}

Используется для обычного JS без расширений.

TypeScript

parser: {
  syntax: "typescript",
  tsx: true
}

Поддерживает:

  • типы
  • интерфейсы
  • enum
  • generics
  • TSX

JSX

parser: {
  syntax: "jsx"
}

Используется в React-проектах без TypeScript.


Асинхронная природа transform

Асинхронность реализована через внутренний thread pool Rust-библиотеки SWC. JavaScript-обертка лишь возвращает Promise.

Пример выполнения:

const result = await transform(code, {
  filename: "example.ts",
  jsc: {
 parser: {
syntax: "typescript"
 },
 target: "es2020"
  }
});

Что происходит внутри

  1. JS передает код в native binding
  2. Rust поток обрабатывает AST
  3. результат сериализуется обратно
  4. Promise резолвится в JS-слое

Обработка TypeScript

При включенном TypeScript-парсере SWC:

  • удаляет типы на этапе AST
  • не выполняет type-checking
  • преобразует только синтаксис

Пример:

const add = (a: number, b: number): number => {
  return a + b;
};

Результат:

const add = (a, b) => {
  return a + b;
};

JSX трансформация

SWC поддерживает два режима React runtime:

Classic runtime

jsc: {
  transform: {
 react: {
runtime: "classic"
 }
  }
}

Результат:

React.createElement("div", null, "text");

Automatic runtime

jsc: {
  transform: {
 react: {
runtime: "automatic"
 }
  }
}

Результат:

import { jsx as _jsx } from "react/jsx-runtime";





_jsx("div", { children: "text" });

Работа с source maps

Source map включается через:

sourceMaps: true

или inline:

sourceMaps: "inline"

Пример результата

{
  code: "...compiled code...",
  map: "{\"version\":3,...}"
}

Source maps используются:

  • дебаггинг в браузере
  • трассировка ошибок
  • dev tooling

Минификация в transform

Хотя SWC имеет отдельный minify, базовый transform может включать упрощенные оптимизации:

minify: true

Поддерживаемые операции:

  • удаление dead code (частично)
  • упрощение выражений
  • сокращение идентификаторов (в ограниченном режиме)

Обработка модулей

module: {
  type: "es6" | "commonjs" | "amd" | "umd"
}

ES Modules

module: {
  type: "es6"
}

Оставляет import/export без изменений.

CommonJS

module: {
  type: "commonjs"
}

Преобразует:

import x from "y";

в:

const x = require("y");

Практическая модель выполнения transform

Асинхронная обработка позволяет запускать несколько трансформаций параллельно:

const tasks = files.map(file =>
  transform(file.code, {
    filename: file.name,
    jsc: {
      parser: { syntax: "typescript" },
      target: "es2020"
    }
  })
);

const results = await Promise.all(tasks);

Поведение при нагрузке

  • задачи распределяются по потокам
  • минимизируется блокировка event loop
  • Rust runtime выполняет CPU-bound работу

Ошибки трансформации

Ошибки возвращаются через rejected Promise:

try {
  await transform("const a =", {
    jsc: { parser: { syntax: "ecmascript" } }
  });
} catch (e) {
  console.log(e.message);
}

Типичные причины:

  • синтаксическая ошибка
  • неверный parser syntax
  • несовместимый JSX/TSX режим

Оптимизационные особенности SWC

Асинхронная трансформация выигрывает за счет:

  • отсутствия JS-парсинга (всё в Rust)
  • многопоточности
  • низкого overhead на AST
  • эффективной сериализации результата

Поведение filename

filename: "input.tsx"

Используется для:

  • определения режима JSX/TSX
  • генерации source map
  • диагностических сообщений

Взаимодействие с build tools

Функция transform часто используется как низкоуровневый API:

  • Webpack loader
  • Vite plugin transform hook
  • custom bundlers
  • server-side rendering pipelines

Асинхронная версия предпочтительна, поскольку не блокирует обработку очереди сборки и позволяет параллелизацию файловых операций и трансформаций AST.