процесс компиляции вебпака

Webpack

Если посредине нет хозяина, оно не остановится, а если снаружи нет праведности, оно не сработает. - Чжуанцзы

Введение

Сейчас в основном используется 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, а плагин может отслеживать возникновение этих событий и выполнять соответствующие действия в определенное время.

Процесс выполнения веб-пакета и поток событий показаны на следующем рисунке:

webpack complier

Более важная концепция в процессе компиляции веб-пакетаcompiler,compilation,следующим образом:

  • Объект компилятора: Отвечает за мониторинг файлов и компиляцию запуска.CompilerПример содержит полныйwebpackКонфигурация, только одна глобальноCompilerпример.
  • Объект компиляции:когдаwebpackПри работе в режиме разработки всякий раз, когда обнаруживается изменение файла, создается новыйCompilationбудет создан. ОдинCompilationОбъект содержит текущие ресурсы модуля, скомпилированные ресурсы, измененные файлы и т. д.CompilationОбъект также предоставляет множество обратных вызовов событий для расширений плагинов.

процесс веб-пакета

Работающий процесс Webpack является последовательным процессом, и следующие процессы выполняются последовательно от начала до конца:

  1. Инициализация: запустите сборку, прочитайте и объедините параметры конфигурации, загрузите подключаемый модуль и создайте экземпляр компилятора.
  2. Компиляция: отправляется из Entry, последовательно вызывает соответствующий загрузчик для каждого модуля, чтобы перевести содержимое файла, затем находит модуль, от которого зависит модуль, и рекурсивно компилирует его.
  3. Вывод: объедините скомпилированные модули в куски, преобразуйте куски в файлы и выведите их в файловую систему.

Если выполняется только одна сборка, каждая из вышеперечисленных фаз будет последовательно выполняться один раз. Но при включении режима прослушивания процесс станет следующим:webpack-flow

Ниже приводится подробное введение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, как показано ниже:webpack-flowTabable предоставляет два способа привязки хуков:

  • AsyncHook (асинхронный хук):связыватьв состоянии пройтиtapAsyncилиtapPromise(так же какtap),воплощать в жизньпройти черезcallAsync,promise;
  • syncHook (крючок):связыватьв состоянии пройтиtap,воплощать в жизньпройти черезcall;

Пожалуйста, ознакомьтесь с конкретным использованиемTapable.

Суммировать

Работающий процесс Webpack является последовательным процессом, и следующие процессы выполняются последовательно от начала до конца:

  1. Параметры инициализации: чтение и объединение параметров из файлов конфигурации и операторов оболочки для получения окончательных параметров.;
  2. Начать компиляцию: Инициализируйте объект Compiler с параметрами, полученными на предыдущем шаге, загрузите все настроенные плагины и выполните метод запуска объекта, чтобы начать компиляцию.;
  3. Определите запись: Найдите все файлы записей в соответствии с записью в конфигурации.;
  4. Скомпилируйте модуль: начиная с файла записи, вызовите все настроенные загрузчики для перевода модуля, затем найдите модули, от которых зависит модуль, а затем повторите этот шаг, пока все файлы, зависящие от записи, не будут обработаны на этом шаге.;
  5. Завершение компиляции модуля: после перевода всех модулей с помощью Loader на шаге 4 получается окончательное содержимое каждого модуля после перевода и зависимости между ними.;
  6. Выходные ресурсы: в соответствии с зависимостями между записями и модулями соберите фрагменты, содержащие несколько модулей, один за другим, а затем преобразуйте каждый фрагмент в отдельный файл и добавьте его в список выходных данных.Этот шаг — последний шанс изменить выходное содержимое.;
  7. Вывод завершен: после определения содержимого вывода определите путь вывода и имя файла в соответствии с конфигурацией и запишите содержимое файла в файловую систему..

В то же время мы также поняли несколько основных концепций в webpack.compiler,compilation,tapable.

Ссылаться на

примечания к изучению веб-пакета (принцип, реализация загрузчика и плагина)

Анализ исходного кода веб-пакета 6: анализ потока обработки веб-пакета

Принципы и практика Webpack (1): процесс упаковки