Что такое webpack?
Согласно официальной документации:
“webpack — это статический бандлер (инструмент для сборки модулей в единые пакеты) для современных приложений JavaScript.”
Как разработчики JavaScript, мы знаем, что такое модули, но в webpack они немного отличаются и состоят из:
- Модулей ES — оператор
import. - Общих модулей JS — оператор
require(). - Модулей AMD — операторы
defineиrequire. - Импортов CSS — оператор
@importвнутри любых файлов css/sass/less. - URL изображений —
url(…)или<img src=”…” />.
webpack объединяет все эти различные модули таким образом, что можно импортировать все в код JavaScript.
Должен ли я изучать webpack?
Сегодня большинство приложений строится с использованием React/Vue или другой библиотеки. Они предоставляют инструменты CLI (например, create-react-app, @vue/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.
Некоторыми из наиболее используемых терминологий являются:
- Точка входа — указывает точку входа для webpack, из которой собираются все зависимости. Они образуют граф зависимостей.
- Вывод — указывает, где в процессе сборки собираются результирующие JS и статические файлы.
- Загрузчики — сторонние расширения, которые помогают webpack работать с различными расширениями файлов. Они преобразуют файлы, отличные от JS, в модули.
- Плагины — сторонние расширения, которые могут изменить способ работы webpack.
- Режим — определяет два режима: разработка и производство. По умолчанию это производство.
Настроим базовую точку входа и выходной каталог.
Изменение точки входа
Если нужно, чтобы webpack работал с source/index.js вместо папки src, заданной по умолчанию, нужно добавить свойство entry в экспортируемый объект:
Также можно использовать альтернативный синтаксис:
Изменение выходного каталога
Предположим, что мы хотим вывести встроенные файлы в каталог build, а не в dist, заданный по умолчанию. Можно использовать свойство output:
Включение собранного файла в HTML файл
В каждом веб-приложении есть по крайней мере один HTML-файл. Для работы с HTML нужно использовать плагин html-webpack-plugin. Начнем с установки:
npm install --save-dev html-webpack-plugin
Что делает этот плагин
Он загружает HTML-файлы и вводит бандл в тот же файл. Создадим простой HTML-файл и настроим его в конфигурации webpack.
Создадим 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 их доступно множество.
Перейдем к настройке загрузчиков в конфигурационном файле webpack. У них странный синтаксис. Мы используем ключ, называемый module, и он состоит из другого свойства, называемого rules, которое представляет собой массив загрузчиков. Для каждого файла, который мы хотим рассматривать как модуль, помещаем его как объект в массив rules. Каждый объект состоит из двух свойств: test определяет тип файла, а use — это массив, состоящий из загрузчиков. Обратите внимание, что загрузчики, определенные здесь в use, загружаются справа налево. Порядок важен при определении загрузчиков. Перед их использованием обратитесь к документации.
Общий синтаксис загрузчика в конфигурационном файле выглядит следующим образом:
Работа с CSS
Для того, чтобы работать с CSS в webpack, нам нужны два загрузчика: CSS-loader и 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 — загрузчик, необходимый для webpack; и @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 доступны два типа режимов: разработка и производство.
В режиме разработки нет минификации. webpack просто берет весь написанный JS-код и загружает его в браузер, тем самым ускоряя перезагрузку приложения.
В производственном режиме webpack применяет множество оптимизаций. Он автоматически использует минификацию с помощью terser-webpack-plugin для уменьшения размера бандла. Он также устанавливает значение process.env.NODE_ENV в production. Эта переменная полезна, поскольку мы можем в зависимости от условия выполнять разные вещи как в производстве, так и в разработке.
Чтобы использовать webpack в этом режиме, добавим еще один скрипт в package.json. Назовем его build. Скрипты должны выглядеть так:
Оптимизации — разделение кода
Разделение кода или ленивая загрузка — это метод оптимизации, позволяющий избежать больших бандлов, а точнее — дублирования зависимостей. Используя его, мы загружаем фрагмент кода по требованию, например, когда пользователь нажимает кнопку, когда меняется маршрут и т. д. Часть кода, который разделяется, называется фрагментом (chunk).
В webpack есть ограничение на максимальный размер файла исходного пакета приложения — меньше 244 КБ. Существует три способа добиться разделения кода в webpack:
- Наличие нескольких точек входа.
- Использование
optimization.splitChunks. - Динамический импорт.
Первый метод хорошо работает для небольших проектов, но не масштабируется в сложных. Мы указываем несколько точек входа в конфигурационный файл webpack.
optimization.splitChunks
Иногда мы используем много зависимостей в приложении. Например, популярный пакет для дат: Moment. Я выбрал его, потому что он тяжеловат по размеру. Установим его, а затем включим в index.js и выполним build:
npm install moment
Moment будет успешно установлен. Теперь импортируем его в index.js.
import moment from 'moment'
Запустим build:
npm run build
Увидим предупреждающее сообщение в терминале:

Как это решить? Все просто. Добавим ключ optimization и свойство splitChunks:
Размер точки входа значительно уменьшается.

Динамические импорты
Они используются для загрузки кода(в React и Vue, например) в зависимости от условия: на основе взаимодействия с пользователем либо изменения маршрута.
Для демонстрации добавим кнопку на страницу, которая по щелчку мыши извлекает список сообщений. Код для этой логики выборки присутствует в отдельном файле. Он импортируется динамически внутри index.js.
Вызовем API fetch отдельно в 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. В документации описано еще больше интересного.
Git — https://github.com/harshaktg/webpack-demo
Спасибо за чтение!
Читайте также:
- Введение: 4 новейших операции JavaScript
- Сравниваем WebGL-фреймворки Three.js и Babylon.js
- Креативное программирование: методы и инструменты для JavaScript, Python и других языков
Читайте нас в Telegram, VK и Дзен
Перевод статьи Harsha Vardhan: Learn webpack in Under 10 Minutes





