Подписка на события сборки

Система событий в Parcel строится вокруг реактивной модели: сборка рассматривается как поток состояний, каждое из которых фиксируется и передаётся подписчикам. Такой подход позволяет интегрировать Parcel с системами логирования, мониторинга, CI/CD и инструментами разработки без вмешательства в сам процесс бандлинга.

События формируются на разных этапах жизненного цикла сборки:

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

Каждый этап сопровождается структурированным объектом события, который содержит контекст текущего состояния сборки.


Основные типы событий сборки

В Parcel (через API @parcel/core) события передаются как поток объектов с типом события, определяющим фазу процесса.

buildStart

Событие фиксирует старт сборки. Оно содержит базовую информацию о конфигурации и входных точках.

Ключевые поля:

  • type: buildStart
  • buildId: идентификатор сборки
  • entries: список входных файлов
  • options: конфигурация бандлера

На этом этапе граф зависимостей ещё не построен, но уже определена структура будущей сборки.


buildProgress

Событие отражает промежуточное состояние процесса.

Используется для отслеживания длительных операций:

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

Содержит:

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

buildSuccess

Финальное успешное состояние сборки.

Содержит:

  • type: buildSuccess
  • buildTime: общее время выполнения
  • bundleGraph: итоговый граф бандлов
  • changedAssets: список изменённых ресурсов
  • requestBundleResults: результаты генерации бандлов

Именно через этот объект доступна структура итогового артефакта сборки, включая все оптимизации и разделения кода.


buildFailure

Событие аварийного завершения процесса.

Основные поля:

  • type: buildFailure
  • diagnostics: массив диагностических сообщений
  • codeFrames: контекст ошибок в исходном коде
  • buildTime: время до ошибки

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


Подписка на события через API @parcel/core

В программной модели Parcel подписка на события реализуется через экземпляр класса Parcel, предоставляемого пакетом @parcel/core.

Механизм основан на функции обратного вызова, принимающей поток событий сборки.

import Parcel from '@parcel/core';

const bundler = new Parcel({
  entries: 'src/index.js',
  defaultConfig: '@parcel/config-default'
});

bundler.watch((err, event) => {
  if (err) {
    // критическая ошибка инфраструктуры
    return;
  }

  switch (event.type) {
    case 'buildStart':
      break;

    case 'buildProgress':
      break;

    case 'buildSuccess':
      break;

    case 'buildFailure':
      break;
  }
});

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


Структура объекта события

Все события Parcel имеют общую основу:

  • type — идентификатор события
  • buildTime — время выполнения (если применимо)
  • buildId — уникальный идентификатор процесса
  • дополнительные поля, специфичные для типа события

Объекты событий не мутируют в процессе передачи. Каждое событие является снимком состояния сборки на конкретный момент времени.


Reporter API и событийная модель плагинов

В Parcel существует отдельный уровень подписки на события — Reporter-плагины. Они предназначены для интеграции с внешними системами: терминалами, логгерами, сервисами мониторинга.

Плагин реализуется через @parcel/plugin:

import { Reporter } from '@parcel/plugin';

export default new Reporter({
  report({ event, options }) {
    switch (event.type) {
      case 'buildStart':
        break;

      case 'buildProgress':
        break;

      case 'buildSuccess':
        break;

      case 'buildFailure':
        break;
    }
  }
});

Reporter получает доступ ко всем событиям сборки без необходимости использования низкоуровневого API Parcel.

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


Подписка в режиме watch и жизненный цикл процесса

При использовании режима наблюдения (watch) события формируются непрерывно, при каждом изменении исходных файлов.

Жизненный цикл выглядит как повторяющийся цикл:

  1. buildStart
  2. buildProgress (несколько раз)
  3. buildSuccess или buildFailure
  4. ожидание изменений файлов
  5. повторение цикла

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


Обработка ошибок в событийной модели

Ошибки в Parcel разделяются на два уровня:

  • инфраструктурные (ошибки API, файловой системы)
  • компиляционные (ошибки кода, зависимостей)

Инфраструктурные ошибки передаются первым аргументом callback:

bundler.watch((err, event) => {
  if (err) {
    // ошибка уровня процесса
  }
});

Компиляционные ошибки приходят как buildFailure, содержащий диагностический массив:

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

Диагностика структурирована так, чтобы обеспечить машинную обработку и группировку ошибок по типам.


Интеграция событий сборки с внешними системами

Событийная модель Parcel часто используется для интеграции с внешними инструментами:

Логирование

События позволяют строить детализированные логи сборки:

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

Метрики производительности

На основе buildTime и buildProgress формируются метрики:

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

CI/CD сценарии

События buildSuccess и buildFailure используются для:

  • определения статуса пайплайна
  • остановки деплоя при ошибках
  • публикации артефактов

Асинхронная природа событий

События Parcel не блокируют основной поток выполнения. Обработчики вызываются асинхронно, что исключает задержки в процессе бандлинга.

Это приводит к следующим характеристикам модели:

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

Особенности повторной сборки и инкрементальности

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

При изменении одного модуля:

  • пересобирается только затронутая часть графа
  • buildProgress отражает локальную переработку
  • buildSuccess содержит обновлённый подграф

Событийная модель остаётся неизменной независимо от масштаба пересборки, что обеспечивает единообразие обработки логики.


Согласованность событийного потока

Parcel гарантирует последовательность событий внутри одного buildId. Это означает:

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

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