Настройка tsconfig.json для Rollup

tsconfig.json при использовании Rollup определяет не процесс сборки, а правила компиляции TypeScript до этапа бандлинга. Rollup в этой связке выступает как инструмент объединения модулей, а TypeScript — как транспайлер и система типизации. Граница ответственности между ними принципиальна: TypeScript превращает TS в JS, Rollup формирует итоговые бандлы, выполняет tree-shaking и оптимизацию.

Основная сложность настройки заключается в том, что конфигурация TypeScript должна быть согласована с моделью ESM, которую ожидает Rollup, иначе возникают конфликты модульной системы, дублирование преобразований или некорректная генерация типов.


Базовая стратегия конфигурации

При работе с Rollup TypeScript чаще всего используется в режиме:

  • транспиляции без изменения структуры модулей
  • генерации исходных sourcemaps
  • передачи ESM-кода в Rollup без предварительного бандлинга

Ключевая идея — TypeScript не должен превращать модули в CommonJS, иначе Rollup теряет возможность корректного tree-shaking.


Настройка module и target

Наиболее критичные поля tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2019",
    "module": "ESNext"
  }
}

target определяет уровень синтаксиса, в который компилируется код. Для Rollup предпочтительны значения ES2017–ES2022, так как современные окружения и бандлеры поддерживают этот синтаксис без дополнительной трансформации.

module должен быть строго "ESNext" или "ES2020+".

Любые значения вроде "CommonJS" или "AMD" ломают модель Rollup, поскольку:

  • tree-shaking становится невозможным
  • Rollup перестаёт анализировать статическую структуру импортов
  • плагины ESM-оптимизации теряют эффективность

Module resolution и совместимость с Rollup

Современный стандарт конфигурации:

{
  "compilerOptions": {
    "moduleResolution": "Bundler"
  }
}

moduleResolution: "Bundler" появился в новых версиях TypeScript и предназначен именно для инструментов сборки (Rollup, Vite, esbuild). Он изменяет поведение резолвинга следующим образом:

  • игнорируются некоторые Node.js-специфичные правила
  • корректно обрабатываются export maps
  • уменьшается количество ложных ошибок импорта

Альтернатива:

"moduleResolution": "NodeNext"

Используется при строгой эмуляции Node ESM, но в связке с Rollup часто избыточен и усложняет конфигурацию.


Работа с декларациями типов

Rollup сам по себе не генерирует .d.ts файлы. Это делает TypeScript при включённой опции:

{
  "compilerOptions": {
    "declaration": true,
    "declarationMap": true
  }
}

Однако в связке с Rollup важно разделять:

  • JS-бандл (Rollup output)
  • типы (tsc output)

Типичная ошибка — попытка заставить Rollup генерировать декларации через @rollup/plugin-typescript без отдельной стадии tsc. Это приводит к неполным или некорректным .d.ts.

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

  1. TypeScript генерирует типы
  2. Rollup обрабатывает JS

isolatedModules и влияние на Rollup pipeline

{
  "compilerOptions": {
    "isolatedModules": true
  }
}

Эта опция критична при использовании Rollup через плагины (@rollup/plugin-typescript, rollup-plugin-esbuild).

Причина:

  • Rollup компилирует модули по одному
  • TypeScript должен гарантировать, что каждый файл может быть транспилирован независимо

При отключённом isolatedModules возможны ошибки:

  • невозможность корректной трансформации const enum
  • проблемы с namespace
  • некорректная обработка типов, требующих cross-file анализа

sourceMap и отладка бандла

{
  "compilerOptions": {
    "sourceMap": true,
    "inlineSources": true
  }
}

Rollup поддерживает объединение sourcemap-ов из разных источников. Важный момент — избегать двойной генерации карт:

  • TypeScript генерирует .map
  • Rollup генерирует финальный .map

В итоге используется цепочка:

TS → intermediate JS → Rollup bundle

Rollup должен уметь объединять sourcemap через sourcemap: true в output конфигурации.


esModuleInterop и взаимодействие с CJS-зависимостями

{
  "compilerOptions": {
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true
  }
}

Эти параметры критичны при смешанных зависимостях.

Rollup часто подключает плагины:

  • @rollup/plugin-commonjs
  • @rollup/plugin-node-resolve

При этом TypeScript сам по себе не знает, как выглядят CJS-модули в рантайме. Поэтому:

  • esModuleInterop позволяет корректно импортировать default из CommonJS
  • allowSyntheticDefaultImports снижает количество ошибок компиляции

Компиляция без лишней генерации выходных файлов

При использовании Rollup TypeScript не должен создавать собственный output-бандл:

{
  "compilerOptions": {
    "noEmit": true
  }
}

Эта настройка переводит TypeScript в режим проверки типов и подготовки AST для плагинов.

Типичная схема:

  • tsc → только проверка типов
  • Rollup → генерация JS

lib и окружение выполнения

{
  "compilerOptions": {
    "lib": ["ES2020", "DOM"]
  }
}

Параметр lib определяет доступные глобальные API.

Для библиотек, собираемых Rollup, выбор lib влияет на:

  • корректность типизации Promise, Map, Set
  • наличие DOM API (если это frontend-библиотека)
  • совместимость с target

Важно избегать избыточного расширения lib, так как это может привести к ложным ожиданиям API в рантайме.


paths и alias-структуры в Rollup

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@core/*": ["src/core/*"],
      "@utils/*": ["src/utils/*"]
    }
  }
}

TypeScript понимает алиасы, но Rollup — нет по умолчанию.

Поэтому требуется синхронизация:

  • TypeScript paths для компиляции
  • @rollup/plugin-alias или rollup-plugin-tsconfig-paths для сборки

Несовпадение приводит к ошибкам вида:

  • модуль не найден
  • разные резолвы путей в TS и Rollup

strict-режим и влияние на архитектуру библиотеки

{
  "compilerOptions": {
    "strict": true
  }
}

Strict-режим в связке с Rollup усиливает требования к качеству кода:

  • строгая проверка null/undefined
  • контроль типов внешних API
  • предотвращение неявных any

При сборке библиотек это критично, поскольку Rollup не исправляет ошибки типов — он работает уже с готовым JS.


skipLibCheck и ускорение сборки

{
  "compilerOptions": {
    "skipLibCheck": true
  }
}

Опция отключает проверку .d.ts файлов зависимостей.

В проектах с Rollup это часто используется для:

  • ускорения CI
  • уменьшения времени компиляции
  • снижения конфликтов типов сторонних библиотек

Composite и project references в сборке с Rollup

{
  "compilerOptions": {
    "composite": true
  }
}

Используется в монорепозиториях, где Rollup собирает отдельные пакеты.

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

  • ускоренная инкрементальная компиляция
  • поддержка project references
  • разделение сборки типов по пакетам

Rollup при этом остаётся финальным шагом объединения артефактов.


Практическая модель разделения ответственности

В типичной архитектуре:

TypeScript конфигурация отвечает за:

  • типизацию
  • транспиляцию TS → ESNext
  • генерацию деклараций

Rollup отвечает за:

  • объединение модулей
  • tree-shaking
  • код-сплиттинг
  • финальный формат (ESM, CJS, UMD)

Пересечение этих зон приводит к избыточным трансформациям и нестабильной сборке.


Минимально согласованная конфигурация tsconfig.json для Rollup

{
  "compilerOptions": {
    "target": "ES2019",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "strict": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "declaration": true,
    "sourceMap": true,
    "isolatedModules": true,
    "skipLibCheck": true,
    "noEmit": true,
    "lib": ["ES2020"]
  }
}

Такая конфигурация ориентирована на сценарий, где TypeScript выполняет роль строгого анализатора и подготовителя типов, а Rollup — полностью контролирует генерацию артефактов сборки.