transformFile и transformFileSync

SWC представляет собой высокопроизводительный компилятор и набор инструментов для трансформации JavaScript и TypeScript, реализованный на Rust и предоставляющий API для Node.js через пакет @swc/core. В экосистеме Node.js ключевыми функциями для работы с файлами выступают transformFile и transformFileSync, обеспечивающие преобразование исходного кода с поддержкой конфигураций компиляции, плагинов, генерации sourcemap и интеграции с современными сборочными пайплайнами.

Функция transformFile предназначена для асинхронного чтения и трансформации исходного файла. Внутри SWC происходит несколько этапов:

  • чтение файла с диска через файловую систему Node.js
  • парсинг исходного кода в AST (Abstract Syntax Tree)
  • применение трансформаций (TypeScript, JSX, ESM/CJS, target transpilation)
  • генерация результирующего кода
  • опциональная генерация source map

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

transformFile: сигнатура и базовое использование

Функция доступна в пакете @swc/core:

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

Базовая сигнатура:

transformFile(
  path: string,
  options?: TransformOptions
): Promise<TransformOutput>
  • path — путь к входному файлу
  • options — конфигурация трансформации
  • возвращает Promise, который резолвится в объект с результатом компиляции

Структура TransformOptions

Конфигурация трансформации определяет поведение компилятора:

  • jsc — настройки JavaScript/TypeScript компиляции
  • module — стратегия модульной системы (CommonJS, ES Modules)
  • sourceMaps — генерация sourcemaps
  • minify — минификация кода
  • isModule — принудительное определение модуля

Пример:

{
  jsc: {
    parser: {
      syntax: "typescript",
      tsx: true
    },
    target: "es2020",
    transform: {
      react: {
        runtime: "automatic"
      }
    }
  },
  module: {
    type: "es6"
  },
  sourceMaps: true
}

Асинхронный поток выполнения transformFile

При вызове transformFile SWC выполняет следующие шаги:

  1. Асинхронное чтение файла

    • используется неблокирующий API fs.readFile
    • минимизируется влияние на производительность приложения
  2. Парсинг исходного кода

    • построение AST с учётом выбранного синтаксиса (JS/TS/JSX)
    • валидация структуры кода
  3. Применение трансформаций

    • удаление типов TypeScript
    • преобразование JSX в JavaScript
    • транспиляция современных возможностей языка
  4. Генерация кода

    • сериализация AST обратно в строку кода
    • сохранение форматирования или его оптимизация
  5. Source map (опционально)

    • связывание исходных и преобразованных строк

Пример использования transformFile

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

async function compile() {
  const result = await transformFile("./src/index.ts", {
    jsc: {
      parser: {
        syntax: "typescript"
      },
      target: "es2019"
    },
    module: {
      type: "commonjs"
    },
    sourceMaps: true
  });

  console.log(result.code);
  console.log(result.map);
}

compile();

Особенности обработки ошибок в transformFile

Асинхронная версия возвращает Promise, который может быть отклонён в следующих случаях:

  • файл не найден или отсутствуют права доступа
  • синтаксическая ошибка в исходном коде
  • некорректная конфигурация TransformOptions
  • неподдерживаемые комбинации parser/transform

Типичный обработчик:

try {
  const result = await transformFile("./input.ts", options);
} catch (err) {
  console.error("SWC transform error:", err);
}

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

Асинхронная модель обеспечивает высокую пропускную способность при работе с множеством файлов:

  • не блокирует основной поток Node.js
  • позволяет параллельную обработку через Promise.all
  • эффективно масштабируется в сборках (Webpack-like, custom pipelines)

Пример параллельной трансформации:

await Promise.all(
  files.map(file =>
    transformFile(file, options)
  )
);

transformFileSync: синхронная модель выполнения

transformFileSync реализует ту же функциональность, но с синхронным API. Она блокирует event loop до завершения трансформации, что делает её пригодной только для ограниченных сценариев:

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

Сигнатура transformFileSync

transformFileSync(
  path: string,
  options?: TransformOptions
): TransformOutput

Отличие от асинхронной версии — отсутствие Promise.

Пример использования transformFileSync

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

const result = transformFileSync("./src/index.ts", {
  jsc: {
    parser: {
      syntax: "typescript"
    },
    target: "es2020"
  },
  module: {
    type: "es6"
  }
});

console.log(result.code);

Внутреннее поведение transformFileSync

Синхронная версия выполняет те же этапы, что и асинхронная, но с блокирующими вызовами:

  • чтение файла через fs.readFileSync
  • последовательная обработка AST
  • немедленная генерация результата

Отсутствие асинхронности упрощает контроль потока выполнения, но увеличивает риск деградации производительности при обработке множества файлов.

Сравнение transformFile и transformFileSync

Модель выполнения

  • transformFile — неблокирующая, Promise-based
  • transformFileSync — блокирующая, прямой возврат результата

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

  • асинхронная версия оптимальна для batch-компиляции
  • синхронная версия быстрее в одиночных вызовах за счёт отсутствия Promise overhead, но хуже масштабируется

Использование в сборках

  • transformFile используется в build tools, watch mode, bundlers
  • transformFileSync используется в CLI-скриптах и простых трансформациях

Source maps в обеих функциях

Обе функции поддерживают генерацию source maps при включённой опции:

sourceMaps: true

Результат содержит:

  • code — итоговый JavaScript
  • map — JSON-строка source map

Source map связывает:

  • исходные строки TypeScript/JSX
  • итоговые строки JavaScript

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

Обе функции поддерживают трансформацию модульных систем:

  • ES Modules (import/export)
  • CommonJS (require/module.exports)
  • автоматическое определение модулей

Пример конфигурации:

module: {
  type: "commonjs"
}

или

module: {
  type: "es6"
}

Типовые сценарии применения

  • транспиляция TypeScript без tsc
  • преобразование JSX в React runtime
  • подготовка кода для старых версий Node.js
  • интеграция в кастомные сборщики
  • server-side трансформация модулей

Ограничения синхронной версии

transformFileSync не рекомендуется для:

  • серверных приложений с высокой нагрузкой
  • параллельной обработки множества файлов
  • middleware в HTTP-серверах

Причина — блокировка event loop, приводящая к деградации отклика системы при увеличении времени трансформации.