Хук buildStart и buildEnd

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

Эти хуки относятся к этапу bundle lifecycle hooks, то есть они не привязаны к конкретному модулю, а работают на уровне всей сборки.


buildStart: инициализация процесса сборки

Хук buildStart вызывается один раз перед тем, как Rollup начинает разрешение входных точек и построение графа зависимостей. На этом этапе еще отсутствует информация о модулях, и сборка фактически находится в состоянии инициализации.

Сигнатура и особенности

Хук может быть синхронным или асинхронным:

buildStart(options)

Параметр options содержит конфигурацию Rollup, включая входные точки, плагины, режимы кэширования и другие параметры сборки.

Контекст выполнения

Внутри buildStart доступен контекст плагина (this), который позволяет:

  • логировать сообщения через this.warn и this.error
  • сохранять состояние через this.cache
  • вызывать асинхронные операции

Однако доступ к модульному графу отсутствует, так как он еще не построен.


Назначение buildStart

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

Типичные сценарии применения:

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

Поведение при асинхронности

Если buildStart возвращает Promise, Rollup приостанавливает дальнейшую сборку до его завершения. Это важно для плагинов, которым требуется загрузка внешних данных до начала построения графа модулей.

Пример:

export default function examplePlugin() {
  return {
    async buildStart(options) {
      this.data = await fetchConfigFromRemoteService();
    }
  };
}

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


Ограничения buildStart

На этапе выполнения хука:

  • отсутствует доступ к модулям (this.getModuleInfo недоступен)
  • нельзя влиять на уже построенный граф (его еще нет)
  • невозможно модифицировать код модулей

Фактически buildStart работает только с глобальным состоянием сборки, а не с содержимым проекта.


buildEnd: завершение сборки

Хук buildEnd вызывается после завершения всех этапов построения бандла, но до полного завершения процесса Rollup. Он выполняется независимо от того, завершилась ли сборка успешно или произошла ошибка.

Сигнатура

buildEnd(error)

Параметр error содержит объект ошибки, если процесс сборки завершился неудачно. В случае успешной сборки значение будет null или undefined.


Поведение buildEnd при ошибках

Одной из ключевых особенностей buildEnd является его выполнение даже при наличии ошибки в процессе сборки. Это делает его удобным для:

  • освобождения ресурсов
  • записи логов ошибок
  • завершения фоновых процессов

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


Назначение buildEnd

Хук используется для финализации процесса сборки и выполнения завершающих операций:

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

Асинхронное поведение buildEnd

buildEnd также поддерживает асинхронность. Если возвращается Promise, Rollup дождется его завершения перед окончательным завершением процесса.

export default function plugin() {
  return {
    async buildEnd(error) {
      await writeBuildReport({
        success: !error,
        error: error?.message
      });
    }
  };
}

Это позволяет гарантировать, что финальные операции, такие как запись отчетов или отправка аналитики, будут завершены.


Контекст выполнения

Внутри buildEnd доступен тот же плагин-контекст, что и в других hook-функциях:

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

Взаимодействие buildStart и buildEnd

Эти два хука формируют логическую пару, ограничивающую жизненный цикл сборки:

  • buildStart — точка входа в процесс сборки
  • buildEnd — точка выхода из процесса сборки

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


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

Управление ресурсами

Часто используется для открытия и закрытия внешних соединений:

export default function plugin() {
  let connection;

  return {
    async buildStart() {
      connection = await createConnection();
    },

    async buildEnd() {
      await connection.close();
    }
  };
}

Сбор статистики

export default function metricsPlugin() {
  const startTime = Date.now();

  return {
    buildStart() {
      this.startTime = startTime;
    },

    buildEnd(error) {
      const duration = Date.now() - this.startTime;

      report({
        duration,
        success: !error
      });
    }
  };
}

Валидация конфигурации

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

buildStart(options) {
  if (!options.input) {
    this.error('Отсутствует входная точка');
  }
}

Порядок выполнения относительно других хуков

Хуки buildStart и buildEnd располагаются вне основного потока обработки модулей:

  • buildStart выполняется до resolveId, load, transform
  • buildEnd выполняется после генерации бандла (generateBundle, writeBundle) и завершения всех операций сборки

Они служат внешними границами всего pipeline.


Важные особенности поведения

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

Практические ограничения

Использование этих хуков требует учета того, что:

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