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

Назначение transformSync

transformSync представляет собой синхронный API для преобразования JavaScript и TypeScript кода на уровне AST с использованием компилятора SWC. Функция выполняет полный цикл трансформации: парсинг исходного кода, применение преобразований (transforms), генерацию результирующего кода и, при необходимости, sourcemap — в одном последовательном вызове без асинхронных операций.

Синхронная природа делает transformSync частью низкоуровневого API, ориентированного на сценарии, где критична предсказуемость выполнения и отсутствие промисов: CLI-инструменты, build-скрипты, небольшие сервисы трансформации, интеграции в синхронные пайплайны.


Сигнатура и общая структура

transformSync(code: string, options: TransformOptions): TransformOutput
  • code — исходный текст программы на JavaScript или TypeScript

  • options — конфигурация трансформации

  • возвращаемое значение — объект с полями:

    • code — преобразованный код
    • map — sourcemap (если включён)
    • дополнительные метаданные в зависимости от конфигурации

Архитектурная модель выполнения

Внутренне transformSync проходит несколько этапов:

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

    • разбор исходного кода
    • формирование AST (Abstract Syntax Tree)
  2. Применение трансформаций

    • JSX → JavaScript
    • TypeScript → JavaScript
    • преобразования современного синтаксиса (ESNext)
    • плагины и кастомные трансформеры
  3. Генерация кода

    • обход AST
    • генерация строкового представления
  4. Sourcemap (опционально)

    • связывание исходных и итоговых позиций кода

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

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

parser

Определяет, как исходный код интерпретируется.

parser: {
  syntax: "ecmascript" | "typescript" | "jsx",
  jsx: boolean,
  dynamicImport: boolean,
  decorators: boolean,
  tsx: boolean
}

Ключевые режимы:

  • ecmascript — стандартный JS
  • typescript — поддержка типов и TS-синтаксиса
  • jsx / tsx — React-подобные конструкции

jsc (JavaScript Compiler options)

Ядро конфигурации трансформации.

jsc: {
  target: "es5" | "es2015" | "es2020" | "es2022" | "esnext",
  parser: {...},
  transform: {...},
  keepClassNames: boolean,
  externalHelpers: boolean,
  loose: boolean
}
target

Определяет уровень транспиляции:

  • es5 — максимальная совместимость
  • es2015+ — современные среды
  • esnext — минимальная трансформация
loose mode

loose: true активирует упрощённые преобразования, ориентированные на производительность, но с отклонением от спецификации ECMAScript в некоторых краевых случаях.


transform

Секция, отвечающая за включение конкретных трансформаций.

transform: {
  react: {
    runtime: "automatic" | "classic",
    development: boolean,
    refresh: boolean
  },
  optimizer: {
    globals: {
      vars: Record<string, string>
    }
  },
  legacyDecorator: boolean
}
React трансформация
  • runtime: automatic — JSX без явного import React
  • runtime: classic — старый режим с React.createElement
  • development — добавление dev-метаданных
  • refresh — поддержка fast refresh

minify (если включён)

Хотя transformSync чаще используется без минификации, некоторые конфигурации допускают базовую оптимизацию:

  • удаление мёртвого кода
  • упрощение выражений
  • инлайнинг констант

sourceMaps

sourceMaps: boolean | "inline" | "both"
  • true — отдельный sourcemap
  • “inline” — встроенный map
  • “both” — комбинированный режим

Простейший пример использования

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

const result = transformSync(
  `const sum = (a, b) => a + b;`,
  {
    jsc: {
      parser: {
        syntax: "ecmascript"
      },
      target: "es5"
    }
  }
);

console.log(result.code);

Результат:

var sum = function(a, b) {
  return a + b;
};

Трансформация TypeScript

const input = `
  type User = { name: string };

  const user: User = { name: "Alex" };
`;
transformSync(input, {
  jsc: {
    parser: {
      syntax: "typescript"
    },
    target: "es2020"
  }
});

Особенности:

  • удаление type annotations
  • преобразование enum (в зависимости от конфигурации)
  • поддержка namespace (частично)

Работа с JSX

const input = `<div>Hello</div>`;
transformSync(input, {
  jsc: {
    parser: {
      syntax: "jsx"
    },
    transform: {
      react: {
        runtime: "automatic"
      }
    }
  }
});

Результат в automatic runtime:

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

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

Синхронность выполнения

transformSync блокирует поток выполнения до завершения всех этапов трансформации. Это создаёт следующие характеристики:

  • отсутствие промисов
  • невозможность частичного выполнения
  • предсказуемое время завершения
  • пригодность для CLI-инструментов

В высоконагруженных сервисах синхронный вызов может стать узким местом из-за блокировки event loop, особенно при обработке больших файлов или массовой компиляции.


Обработка ошибок

Ошибки возникают на этапе парсинга или трансформации AST.

Типичные классы ошибок:

  • SyntaxError — некорректный JavaScript/TypeScript
  • Unexpected token — нарушение грамматики
  • Plugin transform errors — ошибки кастомных трансформеров

Пример обработки:

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

Поведение sourcemap

При включении sourcemap SWC строит карту соответствий между:

  • исходными строками
  • итоговым кодом
  • позициями AST-узлов

Это особенно важно при:

  • отладке транспилированного кода
  • использовании bundler-ов
  • интеграции с тестовыми раннерами

Производительность

Синхронный режим SWC демонстрирует высокую скорость благодаря Rust-реализации компилятора и минимальным накладным расходам JavaScript-обёртки.

Факторы, влияющие на производительность:

  • размер AST
  • количество включённых трансформаций
  • использование JSX/TS
  • включение sourcemap
  • уровень target (es5 требует больше преобразований)

Оптимизация достигается через:

  • отключение лишних transforms
  • использование es2020+ targets
  • минимизацию plugin-цепочек

Поведение externalHelpers

externalHelpers: true

При включении вспомогательные функции (helpers) выносятся во внешние импорты, что снижает дублирование кода между модулями.

Пример:

import { _extends } from "@swc/helpers";

Это особенно актуально для:

  • монорепозиториев
  • больших bundle-систем
  • серверной сборки

Особенности loose режима

loose: true изменяет стратегию трансформации:

  • упрощение классов
  • менее строгая семантика for-of
  • оптимизированные конструкции вместо спецификационных

Пример различий:

Строгий режим:

class A {
  constructor() {
    this.x = 1;
  }
}

Loose режим может генерировать более прямые присваивания без дополнительных проверок прототипа.


React refresh и development режим

При включении:

refresh: true
development: true

добавляются:

  • хуки обновления компонентов
  • метаданные компонентов
  • поддержка hot reload

Это используется в dev-средах bundler-ов и dev-server-ов.


Ограничения transformSync

  • блокирующее выполнение
  • отсутствие стриминга
  • менее гибок по сравнению с async API
  • не подходит для параллельной компиляции больших проектов без worker-пула

Поведение в связке с bundler-ами

transformSync часто используется как:

  • pre-transform шаг перед bundling
  • fallback трансформер
  • инструмент для единичных файлов

В современных сборках он нередко заменяется transform (async) или интеграцией через плагины, однако синхронная версия остаётся полезной в простых пайплайнах и тестовых окружениях.