Система плагинов Webpack построена вокруг событийной модели, основанной на библиотеке Tapable. В основе лежит идея: весь процесс сборки разбит на стадии, на каждой из которых публикуются хуки (hooks), позволяющие подключаться к внутреннему жизненному циклу компиляции и изменять его поведение.
Ключевыми сущностями выступают два центральных объекта: Compiler и Compilation. Они формируют ядро архитектуры, вокруг которого строятся все плагины, оптимизации и расширения функциональности.
Объект Compiler создаётся один раз при инициализации Webpack. Он представляет собой глобальный контроллер процесса сборки.
Его основные задачи:
Compiler существует на протяжении всего жизненного цикла работы Webpack-инстанса. Именно он инициирует сборку при первом запуске и при каждом изменении файлов в режиме наблюдения.
Compiler предоставляет множество хуков, каждый из которых соответствует определённому этапу жизненного цикла:
initialize — инициализация компилятораrun — запуск полной сборкиwatchRun — запуск сборки в watch-режимеcompile — начало компиляцииcompilation — создание нового объекта Compilationmake — построение графа модулейemit — момент перед записью файлов на дискdone — завершение сборкиКаждый хук позволяет вмешиваться в процесс, добавляя, изменяя или полностью заменяя поведение сборщика.
Если Compiler — это глобальный контроллер, то Compilation — это объект, описывающий конкретный цикл сборки.
Каждый запуск сборки (включая watch-режим) создаёт новый экземпляр Compilation. Он содержит:
Compilation является «рабочей областью», в которой происходит основная магия Webpack: анализ импортов, транспиляция, оптимизация и генерация выходных файлов.
Compilation предоставляет ещё более детализированные точки расширения:
buildModule — сборка конкретного модуляseal — фиксация графа модулей перед генерациейoptimize — общий этап оптимизацииoptimizeChunks — оптимизация чанковprocessAssets — обработка финальных ассетовafterSeal — завершение фиксации графаfinishModules — завершение обработки модулейИменно хуки Compilation чаще всего используются для реализации сложной логики плагинов, так как они дают доступ к внутренним структурам сборки.
Вся система плагинов Webpack построена на библиотеке Tapable, которая реализует различные типы хуков:
Эти хуки обеспечивают гибкость управления процессом сборки и позволяют точно контролировать порядок выполнения логики.
Процесс сборки Webpack можно представить как последовательность стадий, каждая из которых связана с определёнными хуками Compiler и Compilation.
На этапе инициализации происходит:
Здесь активируются базовые хуки, и система подготавливается к запуску.
При вызове сборки активируется цепочка:
run или watchRuncompileНа этом этапе формируется контекст конкретной сборки.
Самый важный этап:
Здесь активно используется хук make, который запускает
загрузку и обработку модулей.
Каждый модуль проходит стадии:
После завершения построения графа вызывается seal.
На этом этапе:
Этот этап критичен, так как после него структура сборки становится неизменяемой.
Webpack выполняет множество оптимизаций:
Хуки оптимизации позволяют плагинам вмешиваться в этот процесс и изменять структуру выходного бандла.
На этапе processAssets формируются финальные файлы:
Именно здесь результат Compilation превращается в набор файлов, готовых к записи.
Финальный этап:
emit)done)После этого Compiler остаётся активным и может запускать следующий цикл сборки.
Плагин в Webpack — это функция или класс с методом
apply, принимающим Compiler:
class ExamplePlugin {
apply(compiler) {
compiler.hooks.emit.tap('ExamplePlugin', (compilation) => {
// изменение ассетов перед записью
});
}
}
Подключение плагина фактически означает регистрацию обработчиков на хуки Compiler или Compilation.
Связь между двумя уровнями выглядит следующим образом:
make,
emit)Такое разделение позволяет отделить глобальную логику от контекста конкретной сборки.
Плагины могут:
Пример вмешательства в Compilation:
compiler.hooks.compilation.tap('MyPlugin', (compilation) => {
compilation.hooks.optimize.tap('MyPlugin', () => {
// изменение структуры модулей перед оптимизацией
});
});
Tapable позволяет управлять порядком выполнения обработчиков:
tap — стандартная регистрацияtapAsync — асинхронный обработчикtapPromise — обработчик через PromiseКроме того, существуют механизмы управления порядком:
stage — приоритет выполненияname — идентификация плагинаЭто критично для сложных плагинов, которые зависят от других расширений.
Compilation содержит множество внутренних структур:
modules — все обработанные модулиchunks — группы модулейassets — итоговые файлыfileDependencies — зависимости файловой системыcontextDependencies — контекстные зависимостиЭти структуры постоянно изменяются в процессе сборки до момента seal.
Архитектура Webpack построена так, чтобы:
Благодаря этому плагины могут работать на уровне ядра сборщика, а не поверх него, что делает систему гибкой, но одновременно сложной для понимания без знания внутреннего устройства.