Общая конфигурация SWC для нескольких пакетов
## Общая структура конфигурации SWC в мультипакетных проектах
В проектах с несколькими пакетами (монорепозитории, workspaces, библиотеки с разделением на ядро и расширения) конфигурация SWC требует централизованного подхода. Основная цель — избежать дублирования настроек, обеспечить единообразие трансформации кода и сохранить возможность локальных переопределений там, где это необходимо.
SWC использует файл конфигурации `.swcrc`, который может находиться как в корне проекта, так и внутри каждого пакета. При работе с несколькими пакетами важно понимать механику поиска конфигурации: SWC рекурсивно ищет ближайший `.swcrc`, начиная от текущего файла вверх по дереву директорий.
---
## Базовая модель конфигурации в монорепозитории
Типичная структура мультипакетного проекта:
```
repo/
packages/
core/
ui/
utils/
.swcrc
```
Корневой `.swcrc` выступает как **базовая конфигурация**, а пакеты могут либо наследовать её, либо расширять.
Ключевая идея — разделение ответственности:
* корень содержит общие правила трансформации
* пакеты определяют специфические особенности (например, React, Node, targets)
---
## Центральная конфигурация как основа
Базовый `.swcrc` обычно содержит минимальный набор общих правил:
```json
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true,
"decorators": true
},
"target": "es2020",
"transform": {
"decoratorMetadata": true
}
},
"module": {
"type": "es6"
},
"sourceMaps": true,
"minify": false
}
```
### Роль базовой конфигурации
* унификация синтаксического анализа (TypeScript, JSX)
* единый target ECMAScript
* согласованная работа модулей
* контроль source maps
Важно, что базовая конфигурация не должна включать пакет-специфичные настройки, иначе возникает конфликт при переопределении.
---
## Наследование конфигурации между пакетами
SWC не поддерживает классическое наследование через `extends`, как Babel, поэтому мультипакетная архитектура строится через:
* дублирование `.swcrc` с частичным перекрытием
* использование общего конфигурационного файла + скриптов генерации
* внешние инструменты (например, сборщики, управляющие конфигами)
---
## Переопределение конфигурации в пакетах
Каждый пакет может иметь собственный `.swcrc`:
```
packages/ui/.swcrc
```
Пример:
```json
{
"extends": "../. ./.swcrc",
"jsc": {
"transform": {
"react": {
"runtime": "automatic"
}
}
}
}
```
Однако ключевой момент: поле `extends` не является нативной возможностью SWC. Оно может быть реализовано через инструменты сборки или кастомные скрипты. Поэтому на практике используется один из подходов ниже.
---
## Подход 1: единый конфиг + контекстная настройка
В этом варианте весь репозиторий использует один `.swcrc`, а различия задаются через:
* переменные окружения
* разные команды сборки
* фильтрацию входных файлов
Пример:
```bash
SWC_ENV=browser swc src -d dist
SWC_ENV=node swc src -d dist
```
И конфигурация:
```json
{
"env": {
"browser": {
"jsc": {
"target": "es5"
}
},
"node": {
"jsc": {
"target": "es2020"
}
}
}
}
```
### Особенность подхода
* один источник истины
* нет дублирования конфигов
* сложность возрастает при большом количестве пакетов
---
## Подход 2: конфигурация на уровне пакетов
Каждый пакет содержит собственный `.swcrc`:
```
packages/core/.swcrc
packages/ui/.swcrc
packages/utils/.swcrc
```
### Преимущества
* высокая гибкость
* независимость пакетов
* проще локально тестировать
### Недостатки
* дублирование настроек
* риск рассинхронизации
* сложнее поддерживать единые правила
---
## Подход 3: генерация конфигураций
В крупных монорепозиториях используется генерация `.swcrc` через скрипты.
Пример структуры:
```
config/
swc.base.json
swc.react.json
swc.node.json
scripts/
generate-swc-config.js
```
Базовый конфиг:
```json
{
"jsc": {
"parser": {
"syntax": "typescript"
},
"target": "es2020"
},
"module": {
"type": "es6"
}
}
```
Скрипт генерации объединяет конфиги:
```js
const fs = require("fs");
const base = require("../config/swc.base.json");
const react = require("../config/swc.react.json");
const merged = {
...base,
jsc: {
...base.jsc,
...react.jsc
}
};
fs.writeFileSync(".swcrc", JSON.stringify(merged, null, 2));
```
---
## Управление конфигурацией модулей в разных пакетах
### ESM и CommonJS
В мультипакетной среде часто требуется смешанный режим модулей:
```json
{
"module": {
"type": "commonjs"
}
}
```
или
```json
{
"module": {
"type": "es6"
}
}
```
Важный момент: несовместимость модулей между пакетами может приводить к ошибкам резолва зависимостей.
---
## Разделение конфигурации для frontend и backend пакетов
Типичная структура:
```
packages/
frontend/
backend/
```
### frontend:
```json
{
"jsc": {
"target": "es5",
"parser": {
"jsx": true
}
}
}
```
### backend:
```json
{
"jsc": {
"target": "es2022",
"parser": {
"jsx": false
}
}
}
```
---
## Общие поля конфигурации и их роль в мультипакетной архитектуре
### jsc
Определяет поведение компилятора:
* парсер
* трансформации
* target ECMAScript
В мультипакетной среде именно `jsc` чаще всего переопределяется.
---
### module
Отвечает за систему модулей:
* `es6`
* `commonjs`
* `umd`
* `amd`
Разные пакеты могут требовать разные форматы вывода.
---
### minify
Минификация обычно отключается в библиотеках и включается в приложениях.
```json
{
"minify": false
}
```
или
```json
{
"minify": true
}
```
---
### sourceMaps
При мультипакетной сборке важно унифицировать source maps:
* inline
* external
* disabled
---
## Проблема согласованности конфигураций
В больших проектах основная сложность заключается не в настройке SWC, а в поддержании согласованности:
* разные target в пакетах
* различия в parser options
* несовместимые module types
* случайные расхождения minify/sourceMaps
Эти проблемы часто проявляются не сразу, а в момент интеграции пакетов.
---
## Организация базовых пресетов конфигурации
Распространённый подход — выделение пресетов:
```
swc-presets/
base.json
react.json
node.json
library.json
```
### base.json
Общие настройки:
```json
{
"jsc": {
"parser": {
"syntax": "typescript"
},
"target": "es2020"
}
}
```
### react.json
```json
{
"jsc": {
"transform": {
"react": {
"runtime": "automatic"
}
}
}
}
```
### library.json
```json
{
"minify": false,
"sourceMaps": true
}
```
---
## Интеграция с системами сборки монорепозитория
SWC часто используется вместе с инструментами управления монорепозиториями:
* Turborepo
* Nx
* pnpm workspaces
В таких системах конфигурация SWC часто становится частью pipeline:
* кеширование результатов трансформации
* параллельная сборка пакетов
* изоляция конфигураций по workspace
---
## Ошибки конфигурации в мультипакетных проектах
### Несовместимость target
Пакет A:
```json
"target": "es5"
```
Пакет B:
```json
"target": "es2022"
```
Результат — непредсказуемое поведение при импорте.
---
### Разные системы модулей
CommonJS + ESM в одном дереве зависимостей часто приводит к:
* ошибкам `require is not defined`
* проблемам tree-shaking
* конфликтам bundler’ов
---
### Дублирование конфигураций
При копировании `.swcrc`:
* сложно обновлять изменения
* легко пропустить пакет
* возникает дрейф конфигураций
---
## Практика стабилизации конфигурации
Основной принцип устойчивой архитектуры SWC в мультипакетной системе:
* один базовый конфиг как источник правил
* минимальное число переопределений
* централизованное управление пресетами
* избегание ручного копирования `.swcrc`
* строгая синхронизация target и module across packages