Интеграция с 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. Эта декомпозиция позволяет удерживать стабильное время сборки при росте количества пакетов.