Интеграция с Turborepo и Nx
## Архитектура SWC в монорепозиториях
SWC используется как высокопроизводительный компилятор JavaScript и TypeScript, написанный на Rust и ориентированный на замену Babel и частично TypeScript Compiler в задачах трансформации кода. В монорепозиториях его ценность проявляется в скорости сборки и возможности централизованной конфигурации трансформаций.
В связке с Turborepo и Nx SWC чаще всего выполняет роль:
* транспилятора TypeScript → JavaScript без type-checking;
* трансформера современного JS (ESNext → target environment);
* обработчика JSX/TSX;
* инструмента ускорения CI за счёт кеширования задач сборки.
Ключевая особенность интеграции SWC в монорепо — разделение ответственности:
* SWC отвечает за трансформацию кода;
* Turborepo/Nx отвечают за граф задач, кеширование и оркестрацию;
* TypeScript (tsc) часто используется отдельно только для type-checking.
---
## Интеграция SWC с Turborepo
### Базовая структура проекта
Типичная структура монорепозитория:
```
apps/
web/
packages/
ui/
shared/
turbo.json
package.json
```
Каждый пакет может использовать SWC как основной билд-инструмент.
---
### Конфигурация SWC
Общая конфигурация задаётся через `.swcrc` в корне или на уровне пакета:
```json
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true,
"decorators": true
},
"transform": {
"react": {
"runtime": "automatic"
}
},
"target": "es2020"
},
"module": {
"type": "es6"
},
"sourceMaps": true
}
```
В монорепозитории часто применяется единая конфигурация, чтобы исключить расхождения между пакетами.
---
### SWC в build-скриптах пакета
В каждом пакете добавляется сборка через `@swc/core`:
```json
{
"scripts": {
"build": "swc src -d dist",
"dev": "swc src -d dist -w"
}
}
```
Или через Node API:
```js
const swc = require("@swc/core");
const fs = require("fs");
swc
.transformFile("src/index.ts", {
filename: "index.ts",
sourceMaps: true,
jsc: {
parser: { syntax: "typescript" },
target: "es2020"
}
})
.then((output) => {
fs.writeFileSync("dist/index.js", output.code);
});
```
---
### Интеграция с Turborepo pipeline
Turborepo использует `turbo.json` для описания графа задач:
```json
{
"pipeline": {
"build": {
"outputs": ["dist/**"],
"dependsOn": ["^build"]
},
"lint": {},
"dev": {
"cache": false
}
}
}
```
SWC автоматически становится частью `build`-пайплайна, если используется в скрипте `build`.
---
### Кеширование SWC в Turborepo
Главная ценность Turborepo — content-based caching. SWC идеально ложится в эту модель, так как:
* вход: `src/**`, `.swcrc`, зависимости;
* выход: `dist/**`.
Кеширование работает при совпадении хеша входных данных.
Особенности:
* изменения в `.swcrc` инвалидируют кеш;
* изменение зависимостей пакета также триггерит пересборку;
* независимые пакеты собираются параллельно.
---
### Оптимизация сборки
Для максимальной эффективности SWC используется без лишних шагов:
* отключение type-checking в build;
* разделение `typecheck` и `build` задач;
* минимизация плагинов SWC;
* использование `module.type: "es6"` для tree-shaking.
Пример разделения задач:
```json
{
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
},
"typecheck": {
"outputs": []
}
}
}
```
---
### SWC + Turborepo в связке с TypeScript
Обычно TypeScript используется параллельно:
```json
{
"scripts": {
"build": "swc src -d dist",
"typecheck": "tsc --noEmit"
}
}
```
Такое разделение позволяет:
* ускорить CI (SWC выполняет трансформацию);
* сохранить строгую типизацию через tsc;
* масштабировать монорепозиторий без деградации времени сборки.
---
## Интеграция SWC с Nx
### Архитектурная модель Nx
Nx использует граф зависимостей и executors для задач. SWC интегрируется через `@nx/js` или кастомные executors.
Типичная структура:
```
apps/
libs/
nx.json
workspace.json / project.json
```
---
### Использование SWC executor в Nx
В современных версиях Nx применяется `@nx/js:swc` executor.
Пример `project.json`:
```json
{
"name": "shared",
"sourceRoot": "libs/shared/src",
"targets": {
"build": {
"executor": "@nx/js:swc",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/libs/shared",
"main": "libs/shared/src/index.ts",
"tsConfig": "libs/shared/tsconfig.lib.json",
"assets": ["libs/shared/*.md"]
}
}
}
}
```
---
### SWC и tsconfig в Nx
Nx строго связывает SWC с TypeScript конфигурацией:
```json
{
"compilerOptions": {
"module": "ESNext",
"target": "ES2020",
"declaration": true,
"sourceMap": true
}
}
```
SWC использует tsconfig только для:
* резолва типов путей;
* совместимости с monorepo path aliases;
* определения входных файлов.
---
### Конфигурация SWC внутри Nx
В Nx можно использовать `.swcrc` или inline-конфигурацию через executor:
```json
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": false
},
"target": "es2020"
},
"module": {
"type": "commonjs"
}
}
```
Nx позволяет централизовать конфигурацию через shared config файл:
```
tools/swc/swc.base.json
```
И подключать его в проектах.
---
### Кеширование в Nx
Nx использует локальный и удалённый кеш:
* локальный: `.nx/cache`;
* remote cache: Nx Cloud.
SWC идеально интегрируется, поскольку outputs строго детерминированы.
Условия кеширования:
* вход: `src`, `tsconfig`, `.swcrc`;
* выход: `dist`;
* task hashing учитывает зависимости графа.
---
### Граф зависимостей и SWC
Nx строит dependency graph:
```
app → libA → libB
```
При изменении `libB`:
* SWC пересобирает только затронутые пакеты;
* остальные берутся из кеша.
Это снижает стоимость сборки в больших монорепозиториях.
---
### Разделение задач: build и typecheck
Типовая схема Nx:
```json
{
"targets": {
"build": {
"executor": "@nx/js:swc"
},
"typecheck": {
"executor": "@nx/js:tsc"
}
}
}
```
SWC выполняет трансформацию, tsc — только анализ типов.
---
## Общие паттерны использования SWC в Turborepo и Nx
### Единая конфигурация SWC
В крупных монорепозиториях применяется единый конфиг:
```
config/swc.base.json
```
Переиспользование:
* Turborepo: через CLI аргументы или wrapper-скрипты;
* Nx: через shared config reference.
---
### Разделение библиотек и приложений
SWC особенно эффективен при следующей структуре:
* libraries: компилируются в `dist`;
* apps: потребляют готовый JS.
В этом случае SWC ускоряет сборку библиотек, а Turborepo/Nx управляют порядком сборки.
---
### Инкрементальные сборки
SWC не хранит state между запусками, но:
* Turborepo кеширует результаты задач;
* Nx кеширует задачи + зависимости графа.
Таким образом достигается псевдо-инкрементальность на уровне оркестратора.
---
### Плагины и ограничения
SWC поддерживает ограниченный набор плагинов по сравнению с Babel. В монорепозиториях это приводит к архитектурному выбору:
* сложные трансформации → отдельный Babel step;
* стандартный transpile → SWC;
* JSX/TS → SWC.
---
### Производительность
Ключевые факторы ускорения:
* отсутствие type-checking в SWC pipeline;
* параллельная сборка пакетов;
* кеширование Turborepo/Nx;
* минимизация IO операций;
* использование ESM output для tree-shaking.
---
### Типичные проблемы интеграции
**Несовпадение модульных систем**
* SWC output ESM
* потребитель ожидает CJS
Решение:
* явное указание `module.type`.
---
**Разные SWC конфиги в пакетах**
* приводит к cache miss
Решение:
* единый base config.
---
**Path aliases**
* SWC не всегда резолвит сложные alias без tsconfig
Решение:
* синхронизация `tsconfig.paths` и bundler config.
---
**Разделение dev и build**
* SWC watch mode может конфликтовать с Turborepo/Nx caching
Решение:
* отключение cache для dev задач.
---
### Масштабирование монорепозитория
В больших системах SWC становится частью более широкой схемы:
* Nx/Turborepo → orchestration layer;
* SWC → compilation layer;
* tsc → validation layer;
* Jest/Vitest → testing layer.
Эта декомпозиция позволяет удерживать стабильное время сборки при росте количества пакетов.