Файл tsconfig.json и его влияние на сборку

Роль tsconfig.json в архитектуре сборки

Parcel использует tsconfig.json не как инструмент компиляции в классическом смысле, а как источник семантической информации о проекте TypeScript. Фактическая трансформация кода выполняется собственными трансформерами Parcel (встроенные трансформеры, SWC или Babel в зависимости от конфигурации), тогда как tsconfig.json влияет на:

  • разрешение модулей и алиасов;
  • правила интерпретации TypeScript-синтаксиса;
  • параметры JSX;
  • поведение резолвера файлов;
  • частично — поведение type-checking слоя (если он включён отдельно).

Ключевой принцип: Parcel не делегирует полную компиляцию tsc, но читает конфигурацию для согласования семантики проекта.


Структура tsconfig.json и области влияния

compilerOptions как центральный блок поведения

Раздел compilerOptions оказывает основное влияние на то, как Parcel интерпретирует исходный TypeScript-код.

target

Определяет уровень ECMAScript-выхода:

{
  "compilerOptions": {
    "target": "ES2020"
  }
}

В Parcel значение target используется как ориентир для:

  • выбора polyfill-стратегий (в связке с browserslist);
  • определения допустимого синтаксиса после трансформации;
  • совместимости output-кода с runtime-окружением.

Важно: Parcel может переопределять фактический transpile target на основе browserslist, но target остаётся базовым ограничением.


module

{
  "compilerOptions": {
    "module": "ESNext"
  }
}

В Parcel это влияет на:

  • стратегию обработки import/export;
  • поддержку tree-shaking;
  • сохранение ESM-структуры в графе зависимостей.

При CommonJS Parcel вынужден добавлять дополнительные обёртки, ухудшая оптимизацию графа модулей.


moduleResolution

Наиболее критичный параметр для резолвинга:

{
  "compilerOptions": {
    "moduleResolution": "node"
  }
}

Parcel поддерживает расширенное поведение:

  • node — классический Node.js алгоритм;
  • bundler (в новых версиях TS) — упрощённый алгоритм, ориентированный на сборщики.

При bundler уменьшается количество неоднозначных резолвов, ускоряется граф зависимостей.


baseUrl и paths

Механизм алиасов:

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

Parcel использует эти настройки через TypeScript resolver:

  • преобразует алиасы в реальные пути;
  • участвует в построении dependency graph;
  • влияет на кеширование модулей.

Ключевая особенность: Parcel должен синхронизировать алиасы между TypeScript и собственным resolver-слоем. Несоответствие приводит к:

  • дублированию модулей в графе;
  • ошибкам “module not found”;
  • расхождению между type-check и runtime resolution.

strict и флаговая система типизации

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

Parcel напрямую не использует strict-режим для трансформации, но:

  • strict влияет на результаты type-checker (tsc / fork-ts-checker);
  • косвенно определяет допустимость синтаксиса при интеграции с плагинами;
  • влияет на предупреждения в dev-режиме.

Флаги под strict:

  • noImplicitAny
  • strictNullChecks
  • strictFunctionTypes

Эти параметры не меняют output JavaScript, но влияют на качество проверки.


jsx и jsxRuntime

{
  "compilerOptions": {
    "jsx": "react-jsx"
  }
}

Parcel учитывает JSX-конфигурацию при трансформации:

  • react → классический JSX transform;
  • react-jsx → автоматический runtime (React 17+);
  • preserve → передача JSX дальше по пайплайну.

Также важны:

  • jsxImportSource (для React-like runtime);
  • reactNamespace (редкий кейс кастомных JSX runtime).

Parcel выбирает соответствующий transform pipeline (Babel/SWC), синхронизируя его с TypeScript-ожиданиями.


esModuleInterop и interop-слой

{
  "compilerOptions": {
    "esModuleInterop": true
  }
}

Этот параметр влияет на:

  • совместимость CommonJS и ESM;
  • генерацию default imports;
  • поведение interop helpers.

Parcel использует это для:

  • корректной генерации import wrappers;
  • предотвращения двойного оборачивания модулей;
  • унификации графа зависимостей.

isolatedModules

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

Критично для Parcel, поскольку он компилирует модули по одному.

При включении:

  • каждый файл должен быть самодостаточно транспилируем;
  • запрещены TypeScript-конструкции, требующие глобального анализа;
  • повышается совместимость со SWC/Babel pipeline.

Parcel фактически предполагает isolatedModules: true как безопасную модель сборки.


sourceMap

{
  "compilerOptions": {
    "sourceMap": true
  }
}

Parcel использует это для:

  • генерации inline или external sourcemaps;
  • связывания трансформаций между слоями (TS → JS → bundle);
  • debug-режима HMR.

Однако финальное поведение sourcemaps контролируется Parcel, а не TypeScript напрямую.


noEmit

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

Классическая настройка при использовании Parcel:

  • TypeScript не пишет файлы на диск;
  • Parcel берёт только AST и типы;
  • исключается конфликт между tsc output и bundler output.

include и exclude: границы графа проекта

{
  "include": ["src"],
  "exclude": ["dist", "node_modules"]
}

Parcel использует эти параметры для:

  • построения начального набора входных файлов;
  • ускорения сканирования проекта;
  • ограничения watch-области.

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

  • include влияет только на discovery entry points;
  • реальные зависимости всё равно могут выходить за пределы include;
  • node_modules исключается автоматически, но может быть переопределён.

project references и монорепозитории

{
  "references": [
    { "path": "../shared" }
  ]
}

Parcel частично учитывает project references:

  • позволяет разделять графы зависимостей;
  • улучшает кеширование в монорепозиториях;
  • ускоряет incremental rebuild.

Однако Parcel не использует full TypeScript project graph как tsc --build, а строит собственный граф поверх TS-конфигурации.


Различие между поведением tsc и Parcel

tsc

  • полностью компилирует TypeScript;
  • учитывает все compilerOptions строго;
  • создаёт output JS.

Parcel

  • игнорирует emit-часть TypeScript;
  • использует TS как язык описания типов и структуры;
  • применяет собственный трансформационный pipeline.

Ключевые расхождения:

Область tsc Parcel
Компиляция полная частичная
Типы обязательны опциональны
Output управляется tsc управляется Parcel
Aliases только проверка runtime + build resolution
JSX через TS через Babel/SWC

Влияние tsconfig на кеширование Parcel

Parcel строит кеш на основе:

  • содержимого файлов;
  • графа зависимостей;
  • значений tsconfig.json.

Изменения в:

  • compilerOptions
  • paths
  • baseUrl

могут приводить к инвалидированию кеша всего графа.

Особенно чувствительны:

  • изменение moduleResolution;
  • изменение JSX runtime;
  • переключение strict-режима в связке с плагинами.

Влияние tsconfig на HMR

Hot Module Replacement зависит от:

  • корректного module graph;
  • стабильности идентификаторов модулей;
  • согласованности resolver-слоя.

Ошибки конфигурации tsconfig могут приводить к:

  • полной перезагрузке страницы вместо HMR;
  • разрыву связей модулей;
  • дублированию экземпляров зависимостей.

Наиболее критичные параметры:

  • baseUrl / paths;
  • module;
  • jsx;
  • moduleResolution.

Поведение при конфликте конфигураций

Parcel может получать конкурирующие настройки из:

  • tsconfig.json;
  • package.json (browserslist, sideEffects);
  • собственных конфигураций Parcel;
  • плагинов.

При конфликте приоритет обычно следующий:

  1. Parcel config (если явно задано);
  2. package.json окружение;
  3. tsconfig.json;
  4. дефолтные значения Parcel.

Типичный конфликт:

  • tsconfig module: CommonJS
  • Parcel ожидает ESM для tree-shaking

Результат: деградация оптимизации и увеличение bundle size.


Практика согласования tsconfig под Parcel-архитектуру

Ключевые согласованные установки:

  • "module": "ESNext"
  • "target": "ES2020" или выше
  • "moduleResolution": "bundler" (при поддержке)
  • "isolatedModules": true
  • "noEmit": true
  • "jsx": "react-jsx" (для React проектов)

Эта конфигурация минимизирует расхождения между TypeScript-моделью и сборочным графом Parcel.


Поведение при многокорневых конфигурациях

В проектах с несколькими tsconfig:

  • Parcel выбирает ближайший tsconfig к entry file;
  • возможна агрегация настроек через extends;
  • пересечения paths могут приводить к неоднозначности резолва.

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

tsconfig.json
tsconfig.base.json
tsconfig.app.json
tsconfig.lib.json

Parcel интерпретирует их как иерархию, но фактическое разрешение зависит от конкретного входного файла.


Влияние tsconfig на плагины Parcel

Некоторые плагины используют tsconfig напрямую:

  • TypeScript resolver plugin;
  • path alias resolver;
  • type-checking integration;
  • React/JSX transformers.

Ошибки в tsconfig приводят к:

  • некорректной трансформации AST;
  • несогласованности между dev и build режимами;
  • сбоям при incremental rebuild.