Жизненный цикл компиляции: основные хуки

Процесс компиляции в Webpack представляет собой строго организованную последовательность этапов, построенную вокруг системы хуков Tapable. Каждый этап жизненного цикла отвечает за конкретную фазу обработки проекта: от инициализации сборки до генерации финальных артефактов. Понимание этого цикла критично для разработки плагинов, оптимизации сборки и отладки сложных конфигураций.

Базовая модель компиляции

В основе Webpack лежат два ключевых объекта:

  • Compiler — глобальный контроллер сборки
  • Compilation — конкретная единица сборки (создаётся при каждом запуске)

Compiler существует на протяжении всего процесса выполнения Webpack, тогда как Compilation создаётся заново при каждой компиляции (или при каждом изменении в режиме watch).

Жизненный цикл строится как последовательность хуков, предоставляемых Tapable:

  • SyncHook
  • SyncBailHook
  • AsyncSeriesHook
  • AsyncParallelHook
  • AsyncSeriesBailHook

Каждый хук определяет характер исполнения подключённых обработчиков.

Инициализация запуска компиляции

Первый этап — подготовка запуска сборки. Он охватывает события старта компиляции и настройку окружения.

beforeRun

Вызывается перед стартом выполнения compiler.run().

Используется для:

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

Тип хука: AsyncSeriesHook

run

Запускается непосредственно перед началом компиляции.

На этом этапе:

  • активируется файловый наблюдатель (в watch-режиме)
  • фиксируется момент начала сборки
  • подготавливается контекст выполнения

Тип хука: AsyncSeriesHook

Формирование Compilation

compile

На этом этапе создаётся новый объект Compilation.

Compiler инициирует создание изолированного контекста сборки, в который входят:

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

Тип хука: SyncHook

compilation

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

Используется для:

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

Тип хука: SyncHook

Построение графа зависимостей

make

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

Webpack:

  • анализирует entry points
  • создаёт initial modules
  • запускает резолв зависимостей
  • вызывает loaders

Тип хука: AsyncParallelHook

На этом этапе активно участвуют:

  • resolver (разрешение путей)
  • loaders (трансформация модулей)
  • dependency graph builder

finishMake

Срабатывает после завершения построения всех модулей.

На этом этапе:

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

Тип хука: AsyncSeriesHook

Фаза стабилизации графа

seal

Один из критических этапов жизненного цикла.

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

Внутри выполняются:

  • сортировка модулей
  • построение chunk graph
  • подготовка к оптимизациям

Тип хука: SyncHook

afterSeal

Вызывается сразу после завершения seal.

Позволяет:

  • анализировать финальную структуру chunks
  • модифицировать результаты до оптимизации эмиссии

Тип хука: AsyncSeriesHook

Оптимизация сборки

На этом этапе Webpack применяет ряд оптимизаций к уже сформированному графу.

optimizeDependencies

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

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

Тип хука: SyncHook

дополнительные optimize-хуки

В реальной цепочке также участвуют:

  • optimizeChunks
  • optimizeModules
  • optimizeChunkModules

Каждый из них отвечает за отдельный уровень структуры сборки.

Генерация ассетов

emit

Один из финальных этапов перед записью файлов на диск.

На этом этапе:

  • создаются output assets
  • формируются bundle-файлы
  • выполняется сериализация модулей

Тип хука: AsyncSeriesHook

Этот этап часто используется плагинами для:

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

afterEmit

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

Используется для:

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

Тип хука: AsyncSeriesHook

Завершение компиляции

done

Финальный успешный хук жизненного цикла.

Вызывается после завершения всей цепочки компиляции без ошибок.

На этом этапе доступны:

  • статистика сборки (stats object)
  • итоговые assets
  • информация о чанках и модулях

Тип хука: SyncHook

failed

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

Позволяет:

  • перехватывать ошибки сборки
  • логировать причины падения
  • инициировать fallback-логику

Тип хука: SyncHook

Цикл watch-режима

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

Дополнительно участвуют:

  • invalid — сигнал о необходимости пересборки
  • watchRun — запуск новой итерации компиляции
  • watchClose — завершение наблюдения

В этом режиме ключевым становится повторное прохождение всех фаз:

  1. run
  2. compile
  3. make
  4. seal
  5. emit
  6. done / failed

Роль Tapable в жизненном цикле

Система Tapable обеспечивает гибкость архитектуры Webpack, позволяя подключаться к любому этапу жизненного цикла.

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

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

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

Взаимосвязь Compiler и Compilation

Compiler управляет общим циклом:

  • запуск
  • остановка
  • watch-режим
  • глобальные хуки

Compilation отвечает за:

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

Каждый запуск compiler.run() создаёт новый Compilation, проходящий полный жизненный цикл от make до emit.

Структурная последовательность жизненного цикла

Последовательность можно представить как фиксированную цепочку:

  • beforeRun
  • run
  • compile
  • compilation
  • make
  • finishMake
  • seal
  • optimizeDependencies
  • emit
  • afterEmit
  • done / failed

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