Webpack - это инструмент, который мы часто видим в современных веб-приложениях. Но что именно он делает? В этой статье мы рассмотрим некоторые ключевые концепции для понимания веб-пакета, его функций и способов его настройки. Мы также создадим собственный плагин для веб-пакетов, который поможет нам лучше понять, как работает веб-пакет в целом.

Что такое веб-пакет?

Webpack берет модули и зависимости из наших веб-приложений и собирает их в актив, оптимизированный для браузеров. Это сборщик статических модулей. Это означает, что когда мы пишем наше веб-приложение и настраиваем множество папок, расширений файлов и зависимостей, составляющих наше приложение, мы можем полагаться на веб-пакет, чтобы взять эту информацию и собрать ее в аккуратный пакет, который браузер может получить. всего за один вызов API. Webpack - это сборщик статических модулей, поскольку он ожидает, что зависимости будут определены во время компиляции.

Когда мы добавляем веб-пакет в наше приложение, нам не нужно беспокоиться об организации или порядке наших зависимостей в пакете кода, обслуживаемом клиентом, и у нас даже есть дополнительные возможности для дальнейшей настройки этого пакета в соответствии с потребностями нашего приложения.

Настройка webpack

Мы используем файлы webpack.config для настройки поведения webpack. Файл webpack.config экспортирует объект, содержащий желаемые настройки.

У нас есть довольно много опций, которые мы можем выбрать для настройки нашей конфигурации, поэтому я упомяну несколько очень полезных:

  • Запись: точка входа - это файл, в котором приложение начинает выполняться. С помощью этой опции точки входа мы можем указать место, где webpack начнет поиск зависимостей и сборку пакета.
  • Вывод: здесь мы можем выбрать целевой каталог для файлов вывода. Это должен быть абсолютный путь, поэтому полезно использовать модуль node path.
  • Загрузчики (правила модуля): опция модуля позволяет нам указать любые загрузчики, которые мы хотим использовать. Загрузчики предварительно обрабатывают файлы по мере их импорта. Они позволяют webpack работать с различными типами файлов и применяются для каждого файла отдельно. В файле конфигурации важно отметить, что они загружаются справа налево в массиве загрузчиков.
  • Плагины. Плагины - это расширения для веб-пакета, которые изменяют работу веб-пакета. Плагины применяются по мере создания пакета. Они подключаются к ключевым событиям в процессе компиляции, чтобы изменить или расширить поведение webpack.

Вот пример файла webpack.config и то, как мы можем определить параметры, перечисленные выше:

Обратите внимание, что с некоторыми изменениями также можно настроить наш файл webpack.config с несколькими конфигурациями для разных сред и / или на языке отличном от JavaScript.

Что происходит, когда веб-пакет объединяет наш проект?

Когда webpack запускается, он строит граф зависимостей, предоставляя интерфейс для webpack для доступа к нашим зависимостям, пока он строит пакет. На графике собраны абсолютные пути и другая информация о файлах. Затем Webpack создает модули из каждой из этих зависимостей, и эти модули анализируются в абстрактное синтаксическое дерево. Ресурс, который в конечном итоге создается для браузера, состоит из стандартных шаблонов. Ваш код берется как данные из AST и вставляется в эти шаблоны, чтобы стать файлом, специально отформатированным для браузера.

Если мы посмотрим на репозиторий webpack на GitHub, мы найдем файлы, содержащие определения некоторых ключевых классов, которые обрабатывают процесс компиляции в webpack. Webpack использует свою библиотеку Tapable, чтобы отображать обработчики событий в процессе создания пакета. Многие классы в webpack расширяют Tapable, чтобы предоставить подключаемые модули, чтобы они тоже могли получать доступ к событиям жизненного цикла.

Компилятор - один из таких классов. Здесь запускаются все события более высокого уровня для webpack, включая создание экземпляров плагинов и класса Compilation.

Класс компиляции строит граф зависимостей приложения, рекурсивно просматривая зависимости в проекте. Это класс, ответственный за передачу зависимостей загрузчикам для преобразования, анализ зависимостей в AST и интерполяцию проанализированного кода в шаблоны для генерации окончательных пакетов.

Создание собственного настраиваемого плагина для веб-пакетов

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

Если мы более внимательно посмотрим, как работают плагины, это может дать нам лучшее понимание того, как работает веб-пакет в целом. Многие основные функции самого веб-пакета построены на той же инфраструктуре, что и любые настраиваемые плагины.

Как упоминалось выше, многие ключевые классы, составляющие веб-пакет, расширяют библиотеку Tapable, чтобы открывать перехватчики в их собственных событиях жизненного цикла. Плагины используют эти хуки для доступа к веб-пакету на разных этапах процесса компиляции и настройки поведения веб-пакета.

Чтобы увидеть, как плагины используют хуки жизненного цикла, мы можем написать простой пример плагина.

В этом плагине (который будет классом JavaScript) нам нужно будет определить метод apply. Webpack будет использовать apply для установки плагина при создании экземпляра компилятора. Он также передаст ссылку на экземпляр компилятора в качестве аргумента плагину. Наш плагин подключится к перехватчику экземпляра компилятора и передаст этому перехватчику обратный вызов, который затем будет выполнен при определенном событии жизненного цикла.

В приведенном выше примере мы видим, что мы принимаем экземпляр компилятора в качестве аргумента и можем получить доступ к ловушке компиляции внутри ловушек компилятора. Затем мы можем вызвать tap на этом хуке и передать ему обратный вызов для запуска нашего плагина.

Затем внутри этого первого обратного вызова мы можем получить доступ к любому из обработчиков событий жизненного цикла компиляции. В этом примере давайте воспользуемся ловушкой succeedModule, которая выполняется каждый раз, когда модуль успешно создается во время компиляции. Мы вызываем метод tap еще раз и снова передаем ему вторую функцию обратного вызова. В рамках этого второго обратного вызова мы можем выполнить код в этот конкретный момент жизненного цикла веб-пакета - когда модуль успешно скомпилирован во время процесса компиляции веб-пакета. (Webpack передаст завершенный модуль в качестве аргумента нашему второму обратному вызову.)

Хуки compilation и succeedModule, которые мы выбрали для включения в приведенном выше примере, - это всего лишь два из длинного списка событий жизненного цикла, к которым мы можем получить доступ с помощью аргумента compiler нашего метода apply. Документация webpack предоставляет список имен и описаний событий, доступных из компилятора здесь, и мы можем использовать метод tap для доступа к любому из этих событий.

Наконец, чтобы установить наш плагин, нам нужно будет включить его в наш webpack.config:

Теперь код нашего плагина будет выполняться каждый раз, когда во время компиляции происходит succeedModule событие жизненного цикла.

Заключение

Итак, подведем итоги: Webpack - это сборщик статических модулей. Он принимает модули и зависимости в наших веб-приложениях и собирает их в актив, оптимизированный для браузеров. Webpack просматривает зависимости в наших приложениях, конвертирует их в модули и анализирует их в AST. Затем эта информация вставляется в шаблоны, составляющие пакет, созданный для нашего браузера.

Мы можем настроить точку входа, выход, загрузчики модулей и плагины webpack, среди прочего, в нашем файле webpack.config. Плагины - это расширения для веб-пакета, которые изменяют работу веб-пакета, подключаясь к событию жизненного цикла веб-пакета и выполняя собственный код.

Если вам интересно узнать больше о веб-пакете и о том, как он работает, отличное место для начала - это раздел концепции в документации веб-пакета, а также репозиторий на GitHub веб-пакета.

Дополнительные ресурсы: альтернативы webpack

Webpack - не единственный вариант создания веб-сайта:

  • Одним из альтернативных инструментов является Snowpack, который отправляет и кэширует каждый файл отдельно. Он использует возможности импорта и экспорта модулей ES, которые в последние годы стали поддерживаться многими современными браузерами.
  • Rollup - еще один вариант, в котором используются модули ES.
  • Посылка - альтернатива, которая подходит для небольших проектов. Для этого требуется меньше настроек, чем для webpack, или вообще не требуется.