Совместное использование SWC и tsc

SWC используется как высокопроизводительная альтернатива транспиляторам и минификаторам, ориентированная на скорость выполнения сборки и масштабируемость проектов. В экосистеме JavaScript он часто применяется совместно с TypeScript Compiler (tsc), поскольку эти инструменты решают разные задачи: SWC отвечает за преобразование кода и ускорение сборочного процесса, тогда как tsc обеспечивает полноценную типизацию и проверку корректности TypeScript-кода.

Ключевая причина совместного использования SWC и tsc заключается в различии их функциональных ролей.

SWC выполняет:

  • трансляцию TypeScript/JavaScript в целевую версию ECMAScript;
  • удаление TypeScript-типов без проверки корректности;
  • поддержку JSX/TSX;
  • базовую транспиляцию современных синтаксических конструкций.

tsc выполняет:

  • строгую статическую проверку типов;
  • анализ соответствия интерфейсов и типов;
  • генерацию .d.ts деклараций;
  • контроль совместимости типов между модулями.

Таким образом, SWC ускоряет сборку, но не заменяет типовой анализ, а tsc гарантирует корректность кода без участия в трансформации в production-бандл.

Базовая архитектура совместного пайплайна

В типичной конфигурации SWC и tsc разделяются на два независимых этапа:

  1. Type-check этап (tsc)

    • выполняется отдельно;
    • не генерирует JavaScript в продакшн-сборке (или генерирует только декларации);
    • используется как инструмент контроля качества.
  2. Build/transpile этап (SWC)

    • отвечает за преобразование исходников;
    • используется в dev-сервере и production-бандле;
    • заменяет Babel и частично tsc emit.

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

Конфигурация TypeScript при использовании SWC

При разделении ответственности TypeScript настраивается так, чтобы он не мешал SWC в генерации JavaScript.

Типичная настройка tsconfig.json:

  • noEmit: true — отключение генерации JS;
  • isolatedModules: true — обязательное требование для корректной работы SWC;
  • строгие проверки типов включены (strict: true).
{
  "compilerOptions": {
    "noEmit": true,
    "strict": true,
    "isolatedModules": true,
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "Bundler"
  }
}

Ключевой момент: SWC компилирует файлы по одному, поэтому TypeScript должен гарантировать, что каждый модуль корректен в изоляции.

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

SWC использует файл .swcrc, который определяет правила трансформации:

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

В этом режиме SWC:

  • удаляет типы TypeScript;
  • преобразует JSX;
  • транспилирует современный синтаксис;
  • сохраняет ESM-структуру.

Практическая схема сборки в проектах

В реальных проектах часто используется следующая схема скриптов:

  • tsc –noEmit — проверка типов;
  • swc src -d dist — транспиляция;
  • параллельный запуск для ускорения CI.

Пример package.json:

{
  "scripts": {
    "build:types": "tsc --noEmit",
    "build:js": "swc src -d dist",
    "build": "npm run build:types && npm run build:js"
  }
}

Такой подход разделяет ответственность и позволяет быстро находить ошибки типов до генерации артефактов.

Использование SWC в режиме разработки

В dev-среде SWC часто интегрируется через инструменты вроде:

  • Vite (через плагины SWC);
  • Next.js (SWC как стандартный транспайлер);
  • custom dev-server на Node.js.

В режиме разработки tsc обычно запускается отдельно:

  • либо как tsc –watch в фоне;
  • либо как отдельный процесс CI-проверки.

Это позволяет избежать задержек hot-reload, так как SWC значительно быстрее TypeScript Compiler в трансформации.

Проблема изоляции модулей

Одним из ключевых ограничений SWC является отсутствие полноценных cross-file проверок. Это приводит к необходимости строгого соблюдения isolatedModules.

Типичные проблемы:

  • использование типов, которые требуют глобального контекста;
  • некорректные re-export’ы типов;
  • зависимость от const enum (в некоторых конфигурациях);
  • сложные условные типы, влияющие на emit.

tsc закрывает этот пробел, выполняя глобальный анализ проекта.

Генерация деклараций типов

SWC не генерирует .d.ts файлы, поэтому эта задача полностью остаётся за tsc.

Обычно используется отдельная конфигурация:

{
  "compilerOptions": {
    "declaration": true,
    "emitDeclarationOnly": true,
    "outDir": "dist/types"
  }
}

Сборка типов может быть вынесена в отдельный pipeline шаг, особенно в библиотечных проектах.

Интеграция в монорепозитории

В монорепозиториях (pnpm, turborepo, nx) схема часто усложняется:

  • SWC используется для каждой библиотеки;
  • tsc выполняет глобальную проверку зависимостей;
  • кэширование ускоряет повторные сборки.

Типичный поток:

  • SWC компилирует каждый пакет независимо;
  • tsc проверяет всю граф-зависимостей;
  • CI объединяет результаты.

Производительность и компромиссы

Главное преимущество SWC — скорость. В сравнении с tsc:

  • SWC быстрее в разы при транспиляции;
  • tsc медленнее, но глубже анализирует код.

Компромисс:

  • SWC не заменяет типовую систему;
  • tsc не подходит для быстрых rebuild-циклов.

Совместное использование позволяет получить:

  • быстрый dev-build;
  • строгую типизацию;
  • предсказуемую CI-проверку.

Интеграция с тестированием и линтингом

В типичном пайплайне SWC не участвует в проверке корректности кода. Вместо этого:

  • ESLint проверяет стиль и потенциальные ошибки;
  • tsc проверяет типы;
  • SWC выполняет трансформацию.

Такое разделение предотвращает дублирование ответственности и ускоряет выполнение тестов в больших проектах.

Ошибки конфигурации и типичные анти-паттерны

Частые ошибки при совместном использовании:

  • попытка заменить tsc полностью SWC;
  • отключение isolatedModules, что приводит к некорректной трансляции;
  • смешивание output SWC и tsc в одной директории без разделения;
  • отсутствие отдельного шага проверки типов в CI.

Корректная архитектура всегда подразумевает независимость процессов трансформации и типизации.

Работа с React и JSX

В проектах React SWC особенно эффективен благодаря встроенной поддержке JSX-трансформации.

tsc:

  • проверяет типы компонентов;
  • анализирует props и state.

SWC:

  • преобразует JSX в JavaScript;
  • применяет оптимизированный runtime (automatic JSX runtime).

Это разделение особенно важно для проектов с большим количеством компонентов, где скорость сборки критична.