Общая конфигурация 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