Типы плагинов: Transformer, Resolver, Packager, Optimizer, Reporter, Namer

Parcel использует модульную систему расширений, основанную на строгом разделении ответственности между типами плагинов. Каждый тип плагина отвечает за отдельный этап обработки модуля или всего графа зависимостей. Такая архитектура позволяет строить предсказуемый и масштабируемый пайплайн сборки, где поведение легко расширяется без изменения ядра сборщика.

Плагинная система Parcel строится вокруг нескольких ключевых точек расширения:

  • Resolution layer — определение того, откуда берутся модули
  • Transformation layer — преобразование исходного кода
  • Packaging layer — формирование выходных бандлов
  • Optimization layer — финальная оптимизация результата
  • Reporting layer — сбор диагностической информации
  • Naming layer — управление именами выходных файлов

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


Transformer: преобразование исходного кода

Transformer-плагины являются одной из центральных точек расширения Parcel. Они отвечают за преобразование содержимого модулей до того, как код попадёт в этап упаковки.

Основные задачи Transformer

Transformer выполняет следующие операции:

  • транспиляция современных стандартов JavaScript (ESNext → ES5 или другой таргет)
  • обработка TypeScript, JSX, Flow
  • компиляция CSS-препроцессоров (Sass, Less)
  • генерация вспомогательных модулей (например, CSS Modules mapping)
  • модификация AST дерева

Transformer работает на уровне содержимого файла, а не графа зависимостей.

Модель работы

Parcel передаёт Transformer-плагину объект модуля, содержащий:

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

Плагин возвращает преобразованный код и дополнительные зависимости.

Пример логики Transformer

export default function transformer({ asset }) {
  if (asset.type === 'js') {
    const transformed = compileToES5(asset.code);
    asset.setCode(transformed);
  }

  if (asset.type === 'css') {
    const result = compileSass(asset.code);
    asset.setCode(result.css);
    asset.addDependencies(result.imports);
  }
}

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

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

Transformer — наиболее часто используемый тип плагинов, поскольку именно он отвечает за совместимость исходного кода с целевой средой.


Resolver: разрешение зависимостей

Resolver-плагины отвечают за определение реального местоположения импортируемых модулей. Они участвуют в процессе построения графа зависимостей.

Основные функции Resolver

  • обработка import/require выражений
  • поиск файлов в файловой системе
  • поддержка алиасов
  • работа с node_modules
  • обработка виртуальных модулей
  • разрешение условных импортов

Resolver работает до загрузки содержимого модуля, на этапе анализа ссылок.

Логика разрешения

При встрече импорта:

import utils from "@lib/utils";

Resolver выполняет цепочку операций:

  1. проверка алиасов
  2. проверка локальных путей
  3. поиск в node_modules
  4. проверка расширений файлов
  5. fallback-обработка

Пример Resolver-плагина

export default function resolver({ dependency }) {
  if (dependency.specifier.startsWith('@lib/')) {
    return {
      filePath: dependency.specifier.replace('@lib/', './src/lib/')
    };
  }

  return null;
}

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

  • влияет на структуру графа зависимостей
  • может переопределять стандартное поведение Node resolution
  • работает до загрузки кода
  • критичен для монорепозиториев и алиасов

Resolver обеспечивает гибкость архитектуры проекта, позволяя абстрагироваться от физического расположения файлов.


Packager: формирование бандлов

Packager-плагины отвечают за объединение модулей в итоговые файлы. Это стадия, где граф зависимостей превращается в физический артефакт.

Основные задачи Packager

  • формирование структуры бандла
  • объединение модулей
  • вставка runtime-обвязки Parcel
  • управление порядком модулей
  • генерация итогового кода

Packager работает с уже полностью построенным графом.

Принцип работы

Parcel передаёт Packager:

  • набор модулей
  • порядок выполнения
  • зависимости между ними

Packager формирует текстовый или бинарный результат.

Пример логики Packager

export default function packager({ bundle }) {
  let output = '';

  for (const asset of bundle.assets) {
    output += `// ${asset.id}\n`;
    output += asset.generatedCode + '\n';
  }

  return output;
}

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

  • определяет финальную структуру файла
  • может создавать несколько выходных файлов из одного бандла
  • тесно связан с типом выходного формата (JS, CSS, HTML)
  • учитывает runtime Parcel

Packager является завершающей стадией формирования артефакта до оптимизации.


Optimizer: оптимизация выходного кода

Optimizer-плагины применяются после упаковки и отвечают за улучшение качества и производительности итогового кода.

Основные задачи Optimizer

  • минификация JavaScript и CSS
  • tree-shaking на финальном уровне
  • удаление мёртвого кода
  • сжатие строк и структур
  • оптимизация изображений
  • пост-обработка ассетов

Optimizer работает с уже готовыми бандлами.

Модель работы

Optimizer получает:

  • итоговый код
  • метаданные бандла
  • тип ресурса

И возвращает оптимизированную версию.

Пример Optimizer

export default function optimizer({ bundle }) {
  if (bundle.type === 'js') {
    bundle.code = minifyJS(bundle.code);
  }

  if (bundle.type === 'css') {
    bundle.code = minifyCSS(bundle.code);
  }
}

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

  • не изменяет структуру графа
  • работает только с финальными артефактами
  • может существенно уменьшить размер выходных файлов
  • часто заменяется внешними инструментами (Terser, esbuild)

Optimizer влияет на производительность загрузки и выполнения приложения.


Reporter: система диагностики и отчётности

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

Основные функции Reporter

  • логирование этапов сборки
  • сбор статистики
  • отображение ошибок и предупреждений
  • визуализация прогресса
  • экспорт отчётов

Reporter работает параллельно с остальными стадиями.

Типы событий

Parcel генерирует события:

  • начало сборки
  • завершение трансформации
  • ошибки модулей
  • завершение бандла

Reporter подписывается на эти события.

Пример Reporter

export default function reporter({ event }) {
  if (event.type === 'buildStart') {
    console.log('Сборка началась');
  }

  if (event.type === 'buildError') {
    console.error(event.error);
  }

  if (event.type === 'buildSuccess') {
    console.log('Сборка завершена');
  }
}

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

  • не влияет на выходной код
  • используется для CI/CD интеграций
  • может формировать метрики
  • полезен для мониторинга производительности сборки

Reporter играет ключевую роль в наблюдаемости процесса сборки.


Namer: управление именованием выходных файлов

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

Основные задачи Namer

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

Namer работает на этапе формирования финального результата.

Механика работы

Parcel передаёт Namer:

  • бандл
  • контекст сборки
  • исходные модули

Плагин возвращает строку пути.

Пример Namer

export default function namer({ bundle }) {
  if (bundle.type === 'js') {
    return `dist/${bundle.name}.${bundle.hash}.js`;
  }

  if (bundle.type === 'css') {
    return `dist/styles.${bundle.hash}.css`;
  }

  return `dist/${bundle.name}`;
}

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

  • влияет на кеширование в браузере
  • критичен для CDN-доставки
  • позволяет реализовать сложные схемы версионирования
  • может учитывать контекст окружения (dev/prod)

Namer завершает процесс формирования структуры выходных файлов, обеспечивая стабильную и предсказуемую систему хранения артефактов.