webpack может немного сбивать с толку. Давайте разделим это

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

Согласно официальной документации:

«Webpack - это сборщик статических модулей для современных приложений JavaScript».

Как разработчики JavaScript, мы знаем, что такое модули, но в webpack модули немного другие. Они состоят из :

  • Модули ES - import инструкция
  • Общие модули JS - require() инструкция
  • Модули AMD - заявления define и require
  • Импорт CSS - @import инструкция внутри любых файлов css / sass / less
  • URL изображений - url(...) или <img src="..." />

webpack объединяет все эти различные модули таким образом, чтобы можно было импортировать все в свой код JavaScript.

Стоит ли изучать веб-пакет?

Сегодня большинство приложений построено с использованием React / Vue или любой другой библиотеки. Они предоставляют инструменты CLI (например, create-react-app, @ vue / cli) для создания приложений. Эти инструменты CLI абстрагируют большинство конфигураций и предоставляют значения по умолчанию. Но для вас, как разработчика, полезно понимать, как это работает, так как рано или поздно вы можете захотеть внести некоторые изменения в настройки по умолчанию.

Давайте начнем

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

npm init -y

Теперь давайте установим необходимые пакеты webpack.

npm install --save-dev webpack webpack-cli webpack-dev-server

Давайте откроем package.json файл, удалим уже существующий test сценарий и добавим новый сценарий dev для запуска webpack в режиме разработки. Этот скрипт удобен, когда мы работаем локально. Ваш пакетный файл должен выглядеть примерно так:

Теперь, если вы запустите npm run dev, вы получите неприятную ошибку: Entry module not found. Это потому, что по умолчанию webpack ожидает файл в src/index.js в качестве точки входа. Кроме того, webpack по умолчанию выводит файлы сборки в каталог с именем dist.

Хорошо, давайте исправим эту проблему, создав новый каталог src и файл с именем index.js в нем. А пока давайте введем выражение console.log('hello'); в файл index.js.

А теперь запустим npm run dev. Вы не найдете ошибок, а также найдете встроенный файл main.js в каталоге с именем dist.

Настройка webpack

Чтобы настроить webpack, нам нужно создать файл с именем webpack.config.js внутри корневого каталога. В этом файле нам нужно экспортировать объект конфигурации. webpack работает в автономной среде JavaScript, такой как Node.js.

Некоторые из наиболее широко используемых терминов:

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

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

Изменение точки входа

Если нам нужно, чтобы webpack просматривал source/index.js, а не папку src по умолчанию, нам нужно добавить свойство entry в экспортируемый объект.

Вы также можете использовать альтернативный синтаксис для ввода:

Изменение каталога вывода

Предположим, мы хотим вывести созданные файлы в другой каталог с именем build, а не в каталог по умолчанию dist. Мы можем использовать установку свойства вывода следующим образом:

Включение встроенного файла в файл HTML

В каждом веб-приложении есть как минимум один HTML-файл. Для работы с HTML мы должны использовать плагин под названием html-webpack-plugin. Начнем с установки этого плагина с помощью этой команды:

npm install --save-dev html-webpack-plugin

Что именно делает этот плагин?

Он загружает наши HTML-файлы и вставляет пакет в тот же файл.

Давайте создадим простой HTML-файл и настроим его в конфигурации нашего веб-пакета.

Я создам файл с именем index.html в каталоге source и вставлю в него шаблонный код. Теперь давайте настроим это в нашем файле webpack.

Поскольку наши файлы готовы, нам нужен сервер, который следует использовать для обслуживания этого файла, верно? Итак, давайте использовать webpack-dev-server, который мы установили ранее, для запуска сервера.

сервер разработки webpack

Чтобы настроить webpack-dev-server, нам нужно открыть файл package.json и добавить новый сценарий, который поможет нам запустить сервер. У нас уже есть dev, который мы используем для создания файлов. Теперь давайте создадим start, как показано ниже.

Теперь попробуйте запустить эту команду со своего терминала.

npm start

Перейдите в свой браузер и отметьте localhost:8080. Вы увидите, что там обслуживается index.html, и вы можете открыть инструменты разработчика и увидеть, что в него также включен связанный файл main.js.

Использование загрузчиков веб-пакетов

Как было сказано ранее, загрузчики в webpack - это сторонние расширения, которые имеют дело с различными другими расширениями файлов. Для webpack доступно множество загрузчиков.

Перейдем к настройке загрузчиков в файле конфигурации webpack. У загрузчиков странный синтаксис. Мы используем ключ с именем module, и он состоит из другого свойства с именем rules, которое представляет собой массив загрузчиков. Для каждого файла, который мы хотим рассматривать как модуль, мы помещаем его как объект в этот массив rules. Каждый объект состоит из двух свойств: test определяет тип файла, а use представляет собой массив, состоящий из загрузчиков. Обратите внимание, что загрузчики, определенные здесь в массиве use, загружаются справа налево. Порядок важен при определении загрузчиков. Перед их использованием ознакомьтесь с документацией загрузчика.

Общий синтаксис загрузчика в файле конфигурации выглядит так:

Работа с CSS

Для работы с CSS в webpack нам понадобятся два загрузчика: css-loader и style-loader. Давайте установим их с помощью этой команды.

npm install --save-dev css-loader style-loader

Давайте создадим новый файл styles.css в нашем source каталоге. Добавьте любые базовые стили, чтобы они отражались в index.html при запуске сервера. Затем нам нужно включить файл в наш index.js файл, а не в index.html. Помните, что это руководство основано на объединении и изучении веб-пакетов. Итак, теперь наш index.js файл должен выглядеть так:

Остался последний шаг. То есть настроить загрузчики в нашем webpack.config.js файле. Вот как должен выглядеть наш конфигурационный файл:

css-loader используется для загрузки файлов CSS, а style-loader используется для загрузки таблицы стилей в DOM.

Когда вы перезапустите сервер и снова запустите npm start, вы должны обнаружить, что изменения отразились в вашем браузере.

Работа с SASS

Для работы с файлами SASS (.scss) нам потребуются три загрузчика: sass-loader, css-loader и style-loader, а также дополнительный пакет sass, необходимый для Node. Здесь sass-loader используется для загрузки файлов SASS с импортом. Поскольку мы уже установили два других, давайте теперь установим оставшиеся пакеты.

npm install --save-dev sass-loader sass

Давайте создадим новый файл styles.scss в каталоге source и добавим эти строки или любые базовые стили.

Давайте также включим этот файл в наш index.js файл, используя import './styles.scss' в самом начале файла.

Пришло время добавить загрузчики в наш webpack.config.js файл. Наш загрузчик должен выглядеть так:

Давайте перезапустим сервер и проверим изменения.

Работа с современным JavaScript

Webpack сам по себе не умеет преобразовывать современный JavaScript в совместимый код, который может работать в любом браузере. Поэтому он использует Babel для достижения того же. Давайте установим следующие пакеты: @babel/core, который является собственно движком; babel-loader - загрузчик, необходимый для веб-пакета; и @babel/preset-env для преобразования JavaScript в ES5. Установим зависимости:

npm install --save-dev @babel/core babel-loader @babel/preset-env

Следующим шагом является настройка Babel путем создания нового файла в нашем корневом каталоге с именем babel.config.json. Здесь мы настраиваем Babel для использования установленного нами preset-envm.

Теперь давайте добавим установленный нами загрузчик в наш webpack.config.js файл.

Давайте теперь используем ES6 и указанный выше синтаксис в нашем JS-коде, и после того, как мы снова построим его с помощью npm run dev, мы сможем проверить построенный main.js файл и увидеть, что он автоматически переносится в совместимый с браузером код.

Указание режимов в веб-пакете

В webpack доступны два типа режимов: разработка и производство.

В режиме разработки минификации нет. webpack просто берет весь написанный нами JS-код и загружает его в браузер, что ускоряет перезагрузку приложения.

В производственном режиме webpack применяет множество оптимизаций. Он автоматически применяет минификацию с terser-webpack-plugin, чтобы уменьшить размер пакета. Он также устанавливает process.env.NODE_ENV в production. Эта переменная среды полезна, поскольку мы можем условно выполнять действия как в производстве, так и в разработке.

Чтобы использовать webpack в рабочем режиме, давайте добавим еще один скрипт в package.json файл. Назовем его build. Наши скрипты должны выглядеть так:

Оптимизация - Разделение кода

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

В веб-пакете есть ограничение: максимальный размер файла исходного пакета приложения не должен превышать 244 КиБ. Разделить код в webpack можно тремя способами:

  1. Наличие нескольких точек входа
  2. Использование optimization.splitChunks
  3. Динамический импорт

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

Использование optimisation.splitChunks

Бывают случаи, когда мы используем множество зависимостей в нашем приложении. Например, возьмем популярный пакет для свиданий: Момент. Я выбрал эту упаковку, потому что она немного тяжелая по размеру. Давайте установим его, а затем включим в наш index.js файл и запустим нашу build команду.

npm install moment

Момент будет успешно установлен. Теперь давайте импортируем его в наш index.js файл.

import moment from 'moment'

Теперь давайте запустим нашу build команду.

npm run build

Вы получите это предупреждающее сообщение в терминале:

Так как же решить эту проблему? Это просто. Давайте добавим ключ с именем optimization и еще одно свойство в нем с именем splitChunks, например:

Вы обнаружите, что размер точки входа значительно уменьшился.

Динамический импорт

Динамический импорт используется для условной загрузки кода. Этот подход широко используется в React и Vue. Мы можем загрузить код на основе взаимодействия с пользователем или на основе изменения маршрута.

Чтобы продемонстрировать это, давайте добавим на нашу страницу кнопку, которая при нажатии извлекает для нас список сообщений. Код для этой логики выборки находится в отдельном файле. Он динамически импортируется в наш index.js файл.

Пусть будет только вызов fetch API в файле с именем api.js внутри папки source. Здесь мы экспортируем функцию, которая делает запрос к общедоступному API и возвращает ответ.

Давайте создадим кнопку в нашем index.html файле со свойством id, установленным на btn.

<button id="btn">Click me to load</button>

Давайте выполним динамический импорт в нашем index.js файле с помощью функции для импорта нашего api.js файла.

const getTodos = () => import('./api')

Кроме того, давайте добавим эту логику для регистрации полученных данных, добавив ее в конец файла.

const btn = document.getElementById('btn');
btn.addEventListener('click', () => {
    getTodos().then(({fetchTodos}) => {
        fetchTodos().then(resp => console.log(resp))
    })
})

Этот фрагмент кода вызывает функцию getTodos, которая импортирует файл для нас. Затем, после импорта, мы деструктурируем из него свойство fetchTodos, вызываем функцию и затем регистрируем ответ об успешном завершении.

Давайте создадим наши файлы, запустим наш сервер и обязательно откроем инструменты разработчика и оставим вкладку сети открытой. Вы обнаружите, что при нажатии появляется новый файл JS, который загружается динамически.

0.main.js - это файл, который загружался динамически. Если вы хотите, чтобы у этого файла было читаемое имя, вам просто нужно добавить комментарий во время динамического импорта, например:

const getTodos = () => import(/* webpackChunkName: "postsAPI" */ './api')

Теперь, когда вы повторите ту же процедуру, загрузится файл с именем postsAPI.js, а не 0.main.js.

Все еще любопытно?

Это было всего лишь краткое введение в webpack. Как я уже сказал ранее, эта статья предназначена для начинающих или разработчиков среднего уровня, которые хотят начать изучать webpack. Конечно, в webpack гораздо больше тем. Я только что рассмотрел самые простые. Если вам очень интересно узнать больше о webpack, обратитесь к документации, так как там подробно объясняется много интересных тем.

Git Repo - https://github.com/harshaktg/webpack-demo

Спасибо за прочтение!