Если посредине нет хозяина, оно не остановится, а если снаружи нет праведности, оно не сработает. - Чжуанцзы
Введение
Сейчас в основном используется front-end разработкаreact,vue, используя переднюю частьmvc,mvvmФреймворки в основном включают упаковку и публикацию, а обычно используемые инструменты для упаковки:webpack,gulpи т.п. Если вы используете его часто, вы также должны понимать некоторые его общие процессы, и им будет удобно пользоваться.
Прежде всего, мы должны понять основные концепции веб-пакета:
- Entry: Указывает модуль входа, который вебпак начинает собирать, и начинает собирать и вычислять прямо или косвенно зависимые модули или библиотеки от этого модуля.
- Output: сообщает webpack, как называть выходные файлы и выходные каталоги
- Module: Модуль, в Webpack все является модулем, а модуль соответствует файлу. Webpack будет рекурсивно находить все зависимые модули, начиная с настроенной Entry.
-
Chunk:
coding splitпродукт, мы можем упаковать некоторый код в одинchunk, такие как некоторые распространенные модули, дедупликация и лучшее использование кеша. Или загрузите некоторые функциональные модули по запросу, чтобы оптимизировать время загрузки. существуетwebpack3и прежде чем мы используемCommonsChunkPluginразделить некоторый общий код на одинchunk, чтобы добиться раздельной загрузки. существуетwebpack4серединаCommonsChunkPluginустаревший, бывший в употребленииSplitChunksPlugin - Loader: Преобразователь модулей, который используется для преобразования исходного содержимого модуля в новое содержимое по мере необходимости.
- Plugin: расширяя плагин, он будет транслировать соответствующие события в определенное время в процессе построения Webpack, а плагин может отслеживать возникновение этих событий и выполнять соответствующие действия в определенное время.
Процесс выполнения веб-пакета и поток событий показаны на следующем рисунке:
Более важная концепция в процессе компиляции веб-пакетаcompiler,compilation,следующим образом:
-
Объект компилятора: Отвечает за мониторинг файлов и компиляцию запуска.
CompilerПример содержит полныйwebpackКонфигурация, только одна глобальноCompilerпример. -
Объект компиляции:когда
webpackПри работе в режиме разработки всякий раз, когда обнаруживается изменение файла, создается новыйCompilationбудет создан. ОдинCompilationОбъект содержит текущие ресурсы модуля, скомпилированные ресурсы, измененные файлы и т. д.CompilationОбъект также предоставляет множество обратных вызовов событий для расширений плагинов.
процесс веб-пакета
Работающий процесс Webpack является последовательным процессом, и следующие процессы выполняются последовательно от начала до конца:
- Инициализация: запустите сборку, прочитайте и объедините параметры конфигурации, загрузите подключаемый модуль и создайте экземпляр компилятора.
- Компиляция: отправляется из Entry, последовательно вызывает соответствующий загрузчик для каждого модуля, чтобы перевести содержимое файла, затем находит модуль, от которого зависит модуль, и рекурсивно компилирует его.
- Вывод: объедините скомпилированные модули в куски, преобразуйте куски в файлы и выведите их в файловую систему.
Если выполняется только одна сборка, каждая из вышеперечисленных фаз будет последовательно выполняться один раз. Но при включении режима прослушивания процесс станет следующим:
Ниже приводится подробное введениеwebpackТри основных этапа конкретных маленьких шагов.
фаза инициализации
Фаза инициализации условно делится на:
- сливаться
shellа такжефайл конфигурациипараметры иСоздайте экземпляр объекта компилятора. - Загрузить плагин
- запись обработки
| название события | объяснять |
|---|---|
| Параметры инициализации | Прочитайте и объедините параметры из файлов конфигурации и операторов оболочки, чтобы получить окончательный параметр. Оператор инстанцирования плагина new Plugin() в конфигурационном файле также выполняется во время этого процесса. |
| Создайте экземпляр компилятора | Инициализировать с параметрами, полученными на предыдущем шагеCompilerпример,CompilerОтвечает за мониторинг файлов и компиляцию запуска.CompilerПример содержит полныйWebpackКонфигурация, только одна глобальноCompilerпример. |
| Загрузить плагин | вызывать плагин по очередиapplyчтобы плагин мог прослушивать все последующие узлы событий. Также перейдите к плагинуcompilerСсылку на экземпляр для удобства плагина черезcompilerпередачаWebpackкоторый предоставилAPI. |
| environment | запустить приложениеNode.jsстиль файловой системы дляcompilerобъект для облегчения последующего поиска и чтения файлов. |
| entry-option | чтение конфигурацииEntrys,Для каждогоEntryсоздать соответствующийEntryPlugin, для последнегоEntryПодготовьтесь к рекурсивному синтаксическому анализу. |
| after-plugins | После вызова всех встроенных и настроенных плагиновapplyметод. |
| after-resolvers | Инициализируется в соответствии с конфигурациейresolver,resolverОтвечает за поиск файла по указанному пути в файловой системе. |
этап компиляции
| название события | объяснять |
|---|---|
| before-run | очистить кэш |
| run | Начать новую компиляцию. |
| watch-run | а такжеrunАналогично, разница в том, что он компилируется в режиме прослушивания, и в этом случае можно получить, какие файлы изменились.Начать сначалаНовая компиляция. |
| compile | Событие должно сообщить плагину один разновыйКомпиляция будет запущена и принесет плагинcompilerобъект. |
| compilation | когдаWebpackПри работе в режиме разработки всякий раз, когда обнаруживается изменение файла, создается новыйCompilationбудет создан. ОдинCompilationОбъект содержит текущие ресурсы модуля, скомпилированные ресурсы, измененные файлы и т. д.CompilationОбъект также предоставляет множество обратных вызовов событий для расширений плагинов. |
| make | новенькийCompilationСоздано, собирается начать сEntryНачать чтение файла в зависимости от типа файла и настроенногоLoaderСкомпилируйте файл и после компиляции найдите файлы, от которых зависит файл, и рекурсивно скомпилируйте и проанализируйте. |
| after-compile | однаждыCompilationИсполнение завершено. Здесь мы объединим окончательно сгенерированное имя файла и содержимое файла в соответствии с результатом компиляции. |
| invalid | Это событие инициируется, когда возникает исключение, например, файл не существует или возникает ошибка компиляции файла.Webpackпокидать. |
Самое главное здесьcompilationОбработать,compilationНа самом деле, позвонив в соответствующийloaderГенерация файла процессаchunksи к этимchunksпроцесс оптимизации. несколько ключевых событий (Compilationобъектthis.hooksсередина):
| название события | объяснять |
|---|---|
| build-module | используйте соответствующийLoaderпреобразовать модуль. |
| normal-module-loader | С использованиемLoaderПосле преобразования модуля используйтеacornПроанализируйте преобразованный контент и выведите соответствующее абстрактное синтаксическое дерево (AST), для удобстваWebpackАнализ кода позже. |
| program | Начиная с настроенного входного модуля, проанализируйте егоAST, при встречеrequireПри импорте других операторов модуля добавьте их вСписок зависимых модулей, а вновь найденныйРекурсивный анализ зависимых модулей, и, наконец, разобраться со всеми модулямизависимости. |
| seal | Все модули и ихполагатьсямодули проходят черезLoaderПосле завершения преобразования начните генерировать на основе зависимостейChunk. |
выходной каскад
| название события | объяснять |
|---|---|
| should-emit | Все файлы, которые нужно вывести, сгенерированы, спросите у плагина, какие файлы нужно выводить, а какие нет. |
| emit | После определения файлов для вывода выполните вывод файла, где вы можете получить и изменить содержимое вывода. |
| after-emit | Вывод файла завершен. |
| done | Успешное завершение полного процесса компиляции и вывода. |
| failed | Если во время компиляции и вывода возникает исключениеWebpackПри выходе он перейдет непосредственно к этому шагу, и плагин может получить конкретную причину ошибки в этом событии. |
Tapable
Webpackможно понимать какпоток событийпарадигма программирования, плагинКоллекция. и управлять этими плагинами вwebapckТо, что работает в потоке событий,webpackБазовый класс, написанный вамиTapable.Webpackизпоток событийприменяемый механизмШаблон наблюдателя,а такжеNode.jsсерединаEventEmitterочень похожий.Tapable имеет четыре группы функций-членов.:
-
plugin(name:string, handler:function): позволяет зарегистрировать пользовательский плагин
Tapableсобытие экземпляра. его поведение иEventEmitterизon()Метод аналогичен, используется для регистрацииобработчик/слушатель, приходисигнал/событиеСделайте что-нибудь, когда это произойдет. -
apply(…pluginInstances: (AnyPlugin|function)[]):AnyPluginдолжен быть владельцемapplyКласс метода (может быть и объект, но реже) или просто функция, содержащая регистрационный код. Этот метод просто вызывает определение плагина, чтобы можно было зарегистрировать прослушиватели реальных событий.Tapableрегистрационный список экземпляра. -
applyPlugins(name:string, …):TapableЭкземпляры могут быть указаны с помощью этих функцийhashПримените все плагины ниже. Поведение этого набора методов иEventEmitterизemit()Подход аналогичен, используя различные стратегии для точной настройки запуска событий. -
mixin(pt: Object): простой способ расширения с помощью примесей вместо наследования
TapableПрототип.
Основной объект вышеCompiler,Compilationи т.д. наследуются отTabableДобрый. прямо вCompilerа такжеCompilationBroadcast и listener на объекте, методы следующие:
/**
* 广播出事件
* event-name 为事件名称,注意不要和现有的事件重名
* params 为附带的参数
*/
compiler.apply('event-name',params);
/**
* 监听名称为 event-name 的事件,当 event-name 事件发生时,函数就会被执行。
* 同时函数中的 params 参数为广播事件时附带的参数。
*/
compiler.plugin('event-name',function(params) {
doSomeThing();
});
По аналогии,compilation.applyа такжеcompilation.pluginСпособ применения такой же, как описано выше.
tapableБиблиотека предоставляет множество классов Hook, которые предоставляют крючки для монтирования плагинов.
const {
SyncHook,
SyncBailHook,
SyncWaterfallHook,
SyncLoopHook,
AsyncParallelHook,
AsyncParallelBailHook,
AsyncSeriesHook,
AsyncSeriesBailHook,
AsyncSeriesWaterfallHook
} = require("tapable");
Крючки на Tapable, как показано ниже:Tabable предоставляет два способа привязки хуков:
-
AsyncHook (асинхронный хук):связыватьв состоянии пройти
tapAsyncилиtapPromise(так же какtap),воплощать в жизньпройти черезcallAsync,promise; -
syncHook (крючок):связыватьв состоянии пройти
tap,воплощать в жизньпройти черезcall;
Пожалуйста, ознакомьтесь с конкретным использованиемTapable.
Суммировать
Работающий процесс Webpack является последовательным процессом, и следующие процессы выполняются последовательно от начала до конца:
- Параметры инициализации: чтение и объединение параметров из файлов конфигурации и операторов оболочки для получения окончательных параметров.;
- Начать компиляцию: Инициализируйте объект Compiler с параметрами, полученными на предыдущем шаге, загрузите все настроенные плагины и выполните метод запуска объекта, чтобы начать компиляцию.;
- Определите запись: Найдите все файлы записей в соответствии с записью в конфигурации.;
- Скомпилируйте модуль: начиная с файла записи, вызовите все настроенные загрузчики для перевода модуля, затем найдите модули, от которых зависит модуль, а затем повторите этот шаг, пока все файлы, зависящие от записи, не будут обработаны на этом шаге.;
- Завершение компиляции модуля: после перевода всех модулей с помощью Loader на шаге 4 получается окончательное содержимое каждого модуля после перевода и зависимости между ними.;
- Выходные ресурсы: в соответствии с зависимостями между записями и модулями соберите фрагменты, содержащие несколько модулей, один за другим, а затем преобразуйте каждый фрагмент в отдельный файл и добавьте его в список выходных данных.Этот шаг — последний шанс изменить выходное содержимое.;
- Вывод завершен: после определения содержимого вывода определите путь вывода и имя файла в соответствии с конфигурацией и запишите содержимое файла в файловую систему..
В то же время мы также поняли несколько основных концепций в webpack.compiler,compilation,tapable.
Ссылаться на
примечания к изучению веб-пакета (принцип, реализация загрузчика и плагина)
Анализ исходного кода веб-пакета 6: анализ потока обработки веб-пакета