слова, написанные впереди
чтениеwebpack4.x
В процессе исходного кода я ссылаюсь на книгу «Углубленный веб-пакет» и множество статей великих богов, в сочетании с моим собственным опытом, резюме выглядит следующим образом.
Обзор
webpack
Как и производственная линия, есть серия шагов обработки до того, как исходный файл может быть преобразован в выходной сигнал. Ответственность за каждый процесс обработки на этой производственной линии является одинокой, и существует взаимосвязь зависимости между несколькими процессами. Только после завершения текущей обработки его можно передавать следующему процессу обработки. Плагин - это как функция, вставленная в производственную линию, ресурсы обработки на производственной линии в определенное время.webpack
пройти черезTapable
организовать эту сложную производственную линию.webpack
События транслируются во время рабочего процесса, и плагину нужно только прослушивать те события, о которых он заботится, а затем его можно добавить в производственную линию, чтобы изменить работу производственной линии.webpack
Механизм потока событий обеспечивает упорядоченность плагинов, делая всю систему очень масштабируемой. --Wu Haolin "Объяснение веб-пакета простыми словами"
основные концепции
entry
,loader
,plugin
,module
,chunk
Документов и предисловий к ним очень много, не буду вдаваться в подробности, если есть сомнения, переходите к документу.
процесс сборки
webpack
Текущий процесс является последовательным процессом, и следующие процессы будут выполняться последовательно от начала до конца:
- Параметры инициализации: из конфигурационного файла и
Shell
Прочитайте и объедините параметры в операторе, чтобы получить окончательный параметр; - Начать компиляцию: инициализировать с параметрами, полученными на предыдущем шаге
Compiler
объекта, загружает все настроенные плагины, выполняетrun
Метод начинает выполнять компиляцию; - Определите запись: Найдите все файлы записей в соответствии с записью в конфигурации.
- Скомпилируйте модуль: начиная с файла записи, вызовите все настроенные загрузчики для преобразования модуля, затем найдите модули, от которых зависит модуль, а затем повторите этот шаг, пока все файлы, зависящие от записи, не будут обработаны на этом шаге;
- Завершение компиляции модуля: После перевода всех модулей с помощью Loader на шаге 4 получается финальное содержимое каждого модуля после перевода и зависимости между ними;
- Выходные ресурсы: в соответствии с зависимостями между записью и модулем соберите их в несколько модулей один за другим.
Chunk
, затем поставьте каждыйChunk
Преобразуйте его в отдельный файл и добавьте в список вывода.Этот шаг — последний шанс изменить содержимое вывода; - Вывод завершен: после определения содержимого вывода определите путь вывода и имя файла в соответствии с конфигурацией и запишите содержимое файла в файловую систему.
В ходе вышеуказанного процесса
webpack
Конкретное событие будет транслироваться в определенный момент времени, плагин будет выполнять определенную логику после прослушивания интересующего события, и плагин может вызыватьwebpack
Предоставленные изменения APIwebpack
результат операции.
Сравните два основных объекта в webpack
-
Compile
Объект: Отвечает за мониторинг файлов и инициацию компиляции.Compiler
Пример содержит полныйwebpack
Конфигурация, только одна глобальноCompiler
пример. -
compilation
Объект: когдаwebpack
При работе в режиме разработки всякий раз, когда обнаруживается изменение файла, создается новыйCompilation
будет создан. ОдинCompilation
Объект содержит текущие ресурсы модуля, скомпилированные ресурсы, измененные файлы и т. д.Compilation
Объект также предоставляет множество обратных вызовов событий для расширений плагинов. - Оба объекта наследуются отTapable. к
Compile
Например
const {
Tapable,
SyncHook,
SyncBailHook,
AsyncParallelHook,
AsyncSeriesHook
} = require("tapable");
class Compiler extends Tapable {
constructor(context) {
super();
this.hooks = {
/** @type {SyncBailHook<Compilation>} */
//所有需要输出的文件已经生成好,询问插件哪些文件需要输出,哪些不需要。
shouldEmit: new SyncBailHook(["compilation"]),
/** @type {AsyncSeriesHook<Stats>} */
//成功完成一次完成的编译和输出流程。
done: new AsyncSeriesHook(["stats"]),
/** @type {AsyncSeriesHook<>} */
additionalPass: new AsyncSeriesHook([]),
/** @type {AsyncSeriesHook<Compiler>} */
beforeRun: new AsyncSeriesHook(["compiler"]),
/** @type {AsyncSeriesHook<Compiler>} */
//启动一次新的编译
run: new AsyncSeriesHook(["compiler"]),
/** @type {AsyncSeriesHook<Compilation>} */
// 确定好要输出哪些文件后,执行文件输出,可以在这里获取和修改输出内容。
emit: new AsyncSeriesHook(["compilation"]),
/** @type {AsyncSeriesHook<Compilation>} */
// 输出完毕
afterEmit: new AsyncSeriesHook(["compilation"]),
// 以上几个事件(除了run,beforerun为编译阶段)其余为输出阶段的事件
/** @type {SyncHook<Compilation, CompilationParams>} */
// compilation 创建之前挂载插件的过程
thisCompilation: new SyncHook(["compilation", "params"]),
/** @type {SyncHook<Compilation, CompilationParams>} */
// 创建compilation对象
compilation: new SyncHook(["compilation", "params"]),
/** @type {SyncHook<NormalModuleFactory>} */
// 初始化阶段:初始化compilation参数
normalModuleFactory: new SyncHook(["normalModuleFactory"]),
/** @type {SyncHook<ContextModuleFactory>} */
// 初始化阶段:初始化compilation参数
contextModuleFactory: new SyncHook(["contextModulefactory"]),
/** @type {AsyncSeriesHook<CompilationParams>} */
beforeCompile: new AsyncSeriesHook(["params"]),
/** @type {SyncHook<CompilationParams>} */
// 该事件是为了告诉插件一次新的编译将要启动,同时会给插件带上 compiler 对象
compile: new SyncHook(["params"]),
/** @type {AsyncParallelHook<Compilation>} */
//一个新的 Compilation 创建完毕,即将从 Entry 开始读取文件,根据文件类型和配置的 Loader 对文件进行编译,编译完后再找出该文件依赖的文件,递归的编译和解析。
make: new AsyncParallelHook(["compilation"]),
/** @type {AsyncSeriesHook<Compilation>} */
// 一次Compilation执行完成
afterCompile: new AsyncSeriesHook(["compilation"]),
/** @type {AsyncSeriesHook<Compiler>} */
//监听模式下启动编译(常用于开发阶段)
watchRun: new AsyncSeriesHook(["compiler"]),
/** @type {SyncHook<Error>} */
failed: new SyncHook(["error"]),
/** @type {SyncHook<string, string>} */
invalid: new SyncHook(["filename", "changeTime"]),
/** @type {SyncHook} */
// 如名字所述
watchClose: new SyncHook([]),
// TODO the following hooks are weirdly located here
// TODO move them for webpack 5
/** @type {SyncHook} */
//初始化阶段:开始应用 Node.js 风格的文件系统到compiler 对象,以方便后续的文件寻找和读取。
environment: new SyncHook([]),
/** @type {SyncHook} */
// 参照上文
afterEnvironment: new SyncHook([]),
/** @type {SyncHook<Compiler>} */
// 调用完内置插件以及配置引入插件的apply方法,完成了事件订阅
afterPlugins: new SyncHook(["compiler"]),
/** @type {SyncHook<Compiler>} */
afterResolvers: new SyncHook(["compiler"]),
/** @type {SyncBailHook<string, EntryOptions>} */
// 读取配置的 Entrys,为每个 Entry 实例化一个对应的 EntryPlugin,为后面该 Entry 的递归解析工作做准备。
entryOption: new SyncBailHook(["context", "entry"])
};
существуетwebpack
Во время выполнения последовательно транслируется серия событий --this.hooks
Серия событий в (аналогично жизненному циклу в нашем общем фреймворке), и в каком порядке подписчики этих событий должны быть организованы, выполнены и переданы параметры... ЭтоTapable
список задач.
оTapable
Лучше порекомендовать всем (но объем чтения не сильно похож на 2333)Популярная наука
Детали процесса
Для получения подробной информации о процессе, пожалуйста, обратитесь к тому, на что я ссылаюсь.Compile
Комментарии в объектах, одно замечание, авторhooks
Порядок записи не является порядком вызова.
Есть несколько ситуаций, которые не аннотированы:
- Менее важные или известные по названию и контексту события
- В основном потому, что я еще не знаю (2333, я добавлю новое понимание позже, побег...)
- Конечно, самые важные события в основном освещаются Вот картинка из справочной статьи.
Введение в процесс компиляции
compilation
На самом деле, позвонив в соответствующийloader
Генерация файла процессаchunks
и к этимchunks
процесс оптимизации. Несколько ключевых событий (объект компиляции в this.hooks):
-
buildModule
используйте соответствующийLoader
преобразовать модуль; -
normalModuleLoader
С использованиемLoader
После преобразования модуля используйтеacorn
Проанализируйте преобразованный контент и выведите соответствующее абстрактное синтаксическое дерево (AST) для удобства.webpack
Анализ кода позже. -
seal
Все модули и зависимые от них модули проходят черезLoader
После завершения преобразования начните генерировать на основе зависимостейChunk
.
Наконец, изображение взято из справочной статьи, чтобы иметь более четкое представление обо всем процессе.
Ссылаться на
- Таобао Fed.org/blog/2016/0…
- IM Web.IO/topic/5 Wipe…
- "Углубленный веб-пакет"
Широкая реклама
Эта статья была опубликована вЕженедельный выпуск Mint Front End, Добро пожаловать в Watch & Star ★, пожалуйста, указывайте источник при перепечатке.