Процесс компиляции в Webpack представляет собой строго организованную последовательность этапов, построенную вокруг системы хуков Tapable. Каждый этап жизненного цикла отвечает за конкретную фазу обработки проекта: от инициализации сборки до генерации финальных артефактов. Понимание этого цикла критично для разработки плагинов, оптимизации сборки и отладки сложных конфигураций.
В основе Webpack лежат два ключевых объекта:
Compiler существует на протяжении всего процесса выполнения Webpack, тогда как Compilation создаётся заново при каждой компиляции (или при каждом изменении в режиме watch).
Жизненный цикл строится как последовательность хуков, предоставляемых Tapable:
Каждый хук определяет характер исполнения подключённых обработчиков.
Первый этап — подготовка запуска сборки. Он охватывает события старта компиляции и настройку окружения.
Вызывается перед стартом выполнения compiler.run().
Используется для:
Тип хука: AsyncSeriesHook
Запускается непосредственно перед началом компиляции.
На этом этапе:
Тип хука: AsyncSeriesHook
На этом этапе создаётся новый объект Compilation.
Compiler инициирует создание изолированного контекста сборки, в который входят:
Тип хука: SyncHook
Хук предоставляет доступ к только что созданному Compilation.
Используется для:
Тип хука: SyncHook
Один из ключевых этапов жизненного цикла. Именно здесь начинается построение графа модулей.
Webpack:
Тип хука: AsyncParallelHook
На этом этапе активно участвуют:
Срабатывает после завершения построения всех модулей.
На этом этапе:
Тип хука: AsyncSeriesHook
Один из критических этапов жизненного цикла.
После вызова seal граф модулей считается зафиксированным. Добавление новых модулей в этот момент ограничивается или полностью запрещается.
Внутри выполняются:
Тип хука: SyncHook
Вызывается сразу после завершения seal.
Позволяет:
Тип хука: AsyncSeriesHook
На этом этапе Webpack применяет ряд оптимизаций к уже сформированному графу.
Происходит анализ и оптимизация зависимостей между модулями:
Тип хука: SyncHook
В реальной цепочке также участвуют:
Каждый из них отвечает за отдельный уровень структуры сборки.
Один из финальных этапов перед записью файлов на диск.
На этом этапе:
Тип хука: AsyncSeriesHook
Этот этап часто используется плагинами для:
Срабатывает после завершения записи ассетов.
Используется для:
Тип хука: AsyncSeriesHook
Финальный успешный хук жизненного цикла.
Вызывается после завершения всей цепочки компиляции без ошибок.
На этом этапе доступны:
Тип хука: SyncHook
Альтернативный финальный хук, вызываемый при ошибке компиляции.
Позволяет:
Тип хука: SyncHook
В режиме наблюдения за файлами жизненный цикл компиляции повторяется при каждом изменении исходников.
Дополнительно участвуют:
В этом режиме ключевым становится повторное прохождение всех фаз:
Система Tapable обеспечивает гибкость архитектуры Webpack, позволяя подключаться к любому этапу жизненного цикла.
Основные особенности:
Хуки формируют единый событийный поток, через который проходит вся компиляция.
Compiler управляет общим циклом:
Compilation отвечает за:
Каждый запуск compiler.run() создаёт новый Compilation, проходящий полный жизненный цикл от make до emit.
Последовательность можно представить как фиксированную цепочку:
Эта последовательность образует основу всей системы сборки Webpack и определяет поведение плагинов и внутренней архитектуры компиляции.