Интеграция с Rollup: @rollup/plugin-swc

Интеграция SWC в Rollup основана на концепции трансформационного плагина, который заменяет традиционный этап транспиляции (Babel, TypeScript compiler) высокопроизводительным компилятором на Rust. В связке с Rollup SWC выполняет роль AST-трансформера, преобразующего исходный JavaScript/TypeScript в код, совместимый с целевой средой выполнения, до этапа бандлинга.

Rollup строит граф модулей, после чего каждый модуль проходит через цепочку плагинов. Плагин SWC перехватывает процесс загрузки модуля и выполняет трансформацию исходного кода, возвращая Rollup уже готовый JavaScript. Таким образом, SWC становится промежуточным слоем между файловой системой и системой сборки.

Ключевая особенность подхода заключается в том, что SWC не участвует в бандлинге, tree-shaking или резолве зависимостей. Его зона ответственности ограничена синтаксическими преобразованиями: TypeScript → JavaScript, JSX → JavaScript, современный ECMAScript → совместимый ECMAScript.


Установка и базовая подготовка

Интеграция требует наличия Rollup и SWC core-библиотеки:

npm install -D rollup @swc/core @rollup/plugin-swc

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

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

Файл .swcrc становится центральной точкой управления трансформациями, аналогично tsconfig.json в TypeScript-пайплайне или конфигурации Babel.


Базовая конфигурация Rollup с SWC

Минимальная конфигурация Rollup:

import swc from &

export default {
  input: 'src/index.ts',
  output: {
    file: 'dist/bundle.js',
    format: 'esm',
    sourcemap: true
  },
  plugins: [
    swc({
      jsc: {
        parser: {
          syntax: 'typescript',
          tsx: true
        },
        target: 'es2020'
      }
    })
  ]
};

В этом режиме SWC полностью заменяет TypeScript transpile-only режим. Проверка типов не выполняется — выполняется только синтаксическое преобразование.


Модель работы плагина SWC в Rollup

Плагин перехватывает несколько ключевых стадий:

  • load — получение исходного содержимого модуля
  • transform — преобразование кода через SWC
  • resolveId — опционально влияет на резолвинг (в редких конфигурациях)

Основная нагрузка приходится на transform, где SWC вызывает Rust-ядро через NAPI.

Упрощённая схема:

  1. Rollup читает файл
  2. Передаёт содержимое в SWC
  3. SWC парсит код в AST
  4. Выполняет трансформации (TS/JSX/ESNext)
  5. Генерирует JS + sourcemap
  6. Возвращает результат Rollup

Поддержка TypeScript

SWC обрабатывает TypeScript без проверки типов. Это принципиальное отличие от tsc.

Пример включения TypeScript:

swc({
  jsc: {
    parser: {
      syntax: 'typescript'
    },
    target: 'es2020'
  }
})

Особенности поведения:

  • интерфейсы полностью удаляются
  • type aliases не попадают в output
  • enums компилируются в JS-объекты или IIFE (в зависимости от настроек)
  • generics игнорируются на этапе генерации

Поддержка JSX и React трансформации

SWC включает встроенный JSX-трансформер, который заменяет Babel preset-react.

Конфигурация React runtime:

swc({
  jsc: {
    parser: {
      syntax: 'typescript',
      tsx: true
    },
    transform: {
      react: {
        runtime: 'automatic',
        importSource: 'react'
      }
    }
  }
})

Режимы JSX:

  • automatic runtime — не требует import React
  • classic runtime — требует явного импорта React

JSX преобразуется напрямую в React.createElement или автоматические JSX-runtime вызовы.


Производительность и причины использования SWC

SWC написан на Rust и использует многопоточную архитектуру, что радикально сокращает время трансформации по сравнению с Babel.

Основные причины выбора SWC в Rollup-пайплайне:

  • отсутствие интерпретируемого AST-трансформера (в отличие от Babel)
  • параллельная обработка модулей
  • минимальные накладные расходы на плагины
  • нативная работа с source maps

В больших проектах ускорение сборки может достигать кратных значений, особенно при большом количестве TypeScript-файлов.


Source maps и отладка

SWC генерирует source maps на уровне трансформации. Rollup затем агрегирует их в итоговый map бандла.

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

swc({
  sourceMaps: true
})

Особенности:

  • корректная привязка к исходным TS/JSX файлам
  • поддержка inline и external sourcemaps
  • возможность дебага в браузере без потери исходной структуры

При включённой цепочке Rollup + SWC важно избегать двойной генерации sourcemaps, так как это может приводить к смещению координат.


Фильтрация файлов: include и exclude

Плагин поддерживает ограничение области трансформации:

swc({
  include: ['src/**'],
  exclude: ['node_modules/**']
})

Поведение:

  • include определяет допустимые входные файлы
  • exclude исключает даже при совпадении include

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


Работа с декораторами

SWC поддерживает экспериментальные и legacy-декораторы:

swc({
  jsc: {
    parser: {
      syntax: 'typescript',
      decorators: true
    },
    transform: {
      legacyDecorator: true
    }
  }
})

Особенности:

  • поддержка legacy proposal (TypeScript-style)
  • совместимость с Angular-подобными системами
  • необходимость согласования с TypeScript emitDecoratorMetadata (если используется отдельно)

Конфигурация модулей

SWC позволяет управлять форматом модулей до этапа Rollup:

swc({
  module: {
    type: 'es6'
  }
})

Возможные режимы:

  • es6 — для Rollup (рекомендуемый)
  • commonjs — редко используется в связке с Rollup
  • amd / umd — специализированные сценарии

В Rollup чаще всего SWC оставляет ESM без преобразования модульной системы, чтобы Rollup мог выполнить tree-shaking.


Взаимодействие с tree-shaking Rollup

SWC не влияет напрямую на tree-shaking, но может косвенно изменять его эффективность через трансформации:

  • удаление типов TypeScript улучшает анализ
  • преобразование namespace может ухудшить статический анализ
  • транспиляция class fields влияет на чистоту AST

Рекомендуемая стратегия — минимизировать трансформации SWC, оставляя Rollup максимальную свободу анализа зависимостей.


Кэширование и оптимизация

SWC поддерживает внутренние оптимизации компиляции, а Rollup может кэшировать результаты через watch mode.

Практическая модель:

  • SWC выполняет быстрые однопроходные трансформации
  • Rollup кэширует граф модулей
  • при изменении файла пересобирается только затронутая часть

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


Интеграция с monorepo

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

  • единый .swcrc на корневом уровне
  • переиспользование конфигурации между пакетами
  • исключение дублирующих трансформаций в зависимостях

Типичная структура:

packages/
  ui/
  core/
  utils/
.swcrc
rollup.config.js

Типичные проблемы интеграции

Несовместимость синтаксиса и target

Несоответствие target может привести к генерации кода, который Rollup не ожидает обрабатывать (например, слишком современный JS).

Двойная транспиляция

Использование TypeScript plugin вместе со SWC приводит к деградации производительности и конфликтам AST-результатов.

Source map drift

Неправильная цепочка source map трансформаций вызывает смещение строк в DevTools.

Плагины Rollup, зависящие от Babel AST

Некоторые Rollup-плагины ожидают Babel AST, тогда как SWC генерирует собственную структуру до момента передачи Rollup, что может ограничивать совместимость.


Сравнение SWC и Babel в Rollup-пайплайне

SWC:

  • нативная производительность
  • ограниченная экосистема плагинов
  • строгая ориентация на трансформацию

Babel:

  • гибкая система плагинов
  • медленнее на больших проектах
  • богатая AST-экосистема

В Rollup SWC чаще применяется в сценариях, где критична скорость сборки, а трансформации предсказуемы и стандартизированы.


Расширенные сценарии трансформации

SWC позволяет реализовывать сложные конфигурации:

  • условная транспиляция по environment
  • разные target для ESM и CJS сборок
  • кастомные JSX фабрики
  • поддержка экспериментальных ECMAScript proposal-ов

Пример:

swc({
  jsc: {
    target: 'es2022',
    transform: {
      constModules: true,
      optimizer: {
        globals: {
          vars: {
            __DEV__: 'true'
          }
        }
      }
    }
  }
})

Поведение в watch-режиме Rollup

В режиме rollup -w SWC используется повторно без повторной инициализации компилятора для каждого файла. Это снижает накладные расходы и ускоряет инкрементальные сборки.

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


Роль SWC в современной Rollup-экосистеме

SWC в Rollup становится заменой традиционного Babel-пайплайна в современных фронтенд-стековых архитектурах. Его использование особенно характерно для:

  • библиотек UI-компонентов
  • design systems
  • высоконагруженных SPA
  • monorepo-архитектур

Интеграция через @rollup/plugin-swc формирует компактный, быстрый и предсказуемый этап трансформации, минимизируя зависимость от JavaScript-рантайм инструментов и повышая стабильность сборки в крупных кодовых базах.