Хуки плагинов в Rollup образуют строго определённый конвейер, в котором каждый этап сборки имеет фиксированную точку расширения. Порядок их вызова не является произвольным: он отражает внутреннюю модель работы бандлера, где сборка разделена на фазу построения графа модулей и фазу генерации выходного кода.
Вся система хуков логически делится на две крупные группы:
Эта граница критична, поскольку одни и те же плагины могут участвовать в обоих этапах, но порядок их вызова строго привязан к фазе.
Построение графа начинается с инициализации процесса сборки и завершается фиксацией всех модулей и их связей.
Первым вызывается хук:
buildStart
Он активируется один раз на всю сборку. На этом этапе ещё нет информации о модулях, и его основная роль — подготовка окружения, логирование или инициализация внутренних структур плагина.
Далее начинается процесс разрешения входных точек. Для каждого импорта Rollup последовательно проходит цепочку:
resolveId → load → transform
Хук resolveId вызывается при попытке определить, откуда
должен быть загружен модуль. Он может изменить путь, подменить модуль
или вернуть null, позволяя другим плагинам обработать
запрос.
Порядок важен: плагины вызываются в последовательности их подключения, но с возможностью раннего завершения цепочки при возврате значения.
После успешного разрешения идентификатора вызывается
load. Этот хук отвечает за получение содержимого модуля. Он
может вернуть исходный код напрямую, минуя файловую систему.
Если load возвращает null, Rollup переходит
к стандартному чтению файла.
Следующий этап — transform. Это один из ключевых хуков,
поскольку он позволяет изменять код модуля после загрузки, но до анализа
зависимостей.
На этом этапе выполняются транспиляции, вставка импортов, замена синтаксиса и любые AST-преобразования.
Особенность порядка заключается в том, что transform
может вызываться многократно для одного модуля, если он проходит через
несколько плагинов.
После обработки всех модулей вызывается:
moduleParsed
Этот хук срабатывает после того, как модуль проанализирован и включён в граф зависимостей. Он полезен для сбора метаданных о структуре проекта.
Завершающим хуком фазы построения является:
buildEnd
Он вызывается один раз после завершения анализа всех модулей. На этом этапе граф уже полностью построен, но выходной код ещё не сформирован.
После завершения построения начинается генерация итогового результата. Здесь порядок хуков становится более линейным и ориентированным на работу с чанками.
Первая точка входа в фазу генерации:
renderStart
Этот хук вызывается перед началом формирования чанков. Он позволяет подготовить состояние, необходимое для генерации кода.
Далее Rollup начинает формировать чанки и для каждого из них последовательно вызывает набор хуков.
Хук renderChunk вызывается для каждого создаваемого
чанка. Он получает уже сгенерированный код и может его
модифицировать.
Порядок здесь строго зависит от последовательности генерации чанков: каждый чанк проходит через этот хук отдельно, но в рамках общей очереди сборки.
Этот хук влияет на хеш чанка. Он вызывается перед окончательной фиксацией идентификатора чанка и используется для изменения его стабильности при кешировании.
Порядок вызова связан с вычислением итогового состояния чанка, поэтому любые изменения здесь влияют на финальный output.
Один из самых важных хуков выходной фазы. Он вызывается после того, как все чанки сформированы, но до записи на диск.
В отличие от renderChunk, этот хук получает доступ ко
всему бандлу сразу. Плагины могут:
Порядок вызова generateBundle зависит от порядка
подключения плагинов, но выполняется один раз на весь бандл.
После того как все файлы записаны, вызывается
writeBundle. На этом этапе изменения в бандле уже
невозможны, и хук используется для пост-обработки: публикации,
уведомлений, очистки временных данных.
Порядок в Rollup определяется несколькими принципами:
resolveId или
load при возврате значения).Большинство хуков поддерживают асинхронное выполнение. Это влияет на порядок не в смысле последовательности вызовов, а в смысле завершения:
Некоторые хуки вызываются многократно:
resolveId — для каждого импортаload — для каждого модуляtransform — для каждого модуля и каждого плагинаrenderChunk — для каждого чанкаДругие вызываются строго один раз:
buildStartbuildEndrenderStartwriteBundleПлагины в массиве конфигурации определяют приоритет выполнения:
Это создаёт важную особенность: один и тот же хук может иметь разный эффект в зависимости от позиции плагина.
Последовательность resolveId → load → transform
формирует основу графа модулей. Любое изменение порядка этих операций
привело бы к изменению структуры графа.
resolveId определяет идентичность узлаload определяет содержимое узлаtransform определяет финальную форму узла перед
анализом зависимостейЭта тройка формирует детерминированный цикл обработки каждого модуля.
Хуки можно классифицировать по их роли в общем пайплайне:
resolveIdloadtransformmoduleParsedbuildEndrenderChunkgenerateBundle,
writeBundleЭта классификация напрямую отражает порядок вызова и границы фаз, обеспечивая предсказуемость поведения всей системы сборки.