- Настройка webpack 5 [bonus] React Hot Reloading
- Установка webpack
- Начинаем настройку
- Настраиваем webpack для разработки
- Режимы сборки
- Плагины и загрузчики
- Ассеты
- Добавляем поддержку HTML
- Добавляем поддержку стилей
- Browserslist
- Добавляем поддержку изображений и шрифтов
- Babel
- [bonus] Настройка webpack для работы с React
- Заключение
- Полезные ссылки
Настройка webpack 5 [bonus] React Hot Reloading
Что? Webpack — сборщик модулей для JavaScript. Является одним из мощнейших инструментов современной веб-разработки.
Зачем? Webpack позволяет комфортно создавать приложения по модульной структуре, он собирает все модули в один бандл и минифицирует его. Но это лишь поверхностное описание этого инструмента, на деле вебпак имеет значительно больше возможностей.
Почему? Вам теперь больше нет необходимости беспокоится о сборке проекта, один раз настроил webpack и он все будет делать за вас!
P.S. Ну, или не один раз.
P.S.S. Ладно, точно не один раз.
Установка webpack
npm i -D webpack webpack-cli
- В корне проекта создаем:
src — папку для файлов приложения
webpack.config.js — конфигурационный файл webpack’а.
Начинаем настройку
В папке src создадим файл index.js и напишем в нем любой код в ES6+ синтаксисе, например:
const sayHello = () => console.log('hello'); sayHello();
Переходим в файл webpack.config.js
Из этого файла мы экспортируем объект, содержащий все настройки вебпака.
Для начала укажем точки входа и выхода проекта:
const path = require('path'); module.exports = < entry: './src/index.js', // Указываем точку входа - главный модуль приложения, // в который импортируются все остальные output: < path: path.resolve(__dirname, 'dist'), // Директория, в которой будет // размещаться итоговый бандл, папка dist в корне приложения clean: true, // Очищает директорию dist перед обновлением бандла // Свойство стало доступно с версии 5.20.0, до этого использовался // CleanWebpackPlugin >, >
Настраиваем webpack для разработки
Устанавливаем webpack-dev-server — инструмент, позволяющий не перезапускать вебпак после каждого изменения. Это сервер, хранящий данные в памяти(вы не сможете увидеть их в папке dist ) и запускающий ваше приложение на localhost (порт по умолчанию :8080 )
Также для разработки будем использовать devtool: ‘source-map’ . Поскольку вебпак собирает все модули в один бандл, может быть весьма проблематично понять, что у нас за ошибка на 1593 строке минифицированного кода. Именно эта проблема решается при помощи source-map , благодаря этой настройке нумерация строк и названия функций и переменных в инструментах разработчика отображаются как в исходном коде.
Дополним module.exports в webpack.config.js следующими свойствами:
devtool: 'source-map', devServer: < hot: true, // Включает автоматическую перезагрузку страницы при изменениях >
Теперь перейдем в файл package.json и создадим скрипты для нашего проекта:
Режимы сборки
В webpack есть два режима сборки проекта: development и production .
- development — режим для разработки, максимальная скорость сборки, низкая производительность приложения.
- production — режим для продакшена, медленная сборка, высокая производительность приложения.
Режим сборки указывается в свойстве mode в настройках webpack, для правильной работы скриптов в webpack.config.js внесем следующие изменения:
const path = require('path'); let mode = 'development'; // По умолчанию режим development if (process.env.NODE_ENV === 'production') < // Режим production, если // при запуске вебпака было указано --mode=production mode = 'production'; >module.exports = < mode, // Сокращенная запись mode: mode в ES6+ entry: './src/index.js', devtool: 'source-map', output: < path: path.resolve(__dirname, 'dist'), clean: true, >, devServer: < hot: true, >, >
Плагины и загрузчики
Именно благодаря плагинам и загрузчикам webpack является действительно мощным инструментом, ведь по умолчанию вебпак умеет обрабатывать только js и json.
- Загрузчики (loaders) предоставляют возможность работать не только с базовыми js и json, но с практически любым типом данных. Устанавливаются в module.rules .
- Плагины в некотором смысле являются более мощной версией загрузчиков, они выполняются после сборки бандла и предоставляют широкие возможности. В конфигурацию следует передавать новый экземпляр плагина через new . Устанавливаются в plugins
Ассеты
Ассеты(Asset Modules) — одно из нововведений webpack 5, которое позволяет избавится от file-loader , url-loader и raw-loader . Подробнее про ассеты вы можете почитать здесь.
Для комфортного использования ассетов обновим output в webpack.config.js :
Добавляем поддержку HTML
Для поддержки HTML нам понадобится загрузчик html-loader и html-webpack-plugin :
npm i -D html-loader html-webpack-plugin
Вносим изменения в webpack.config.js :
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); // Импортируем плагин let mode = 'development'; if (process.env.NODE_ENV === 'production') < mode = 'production'; >const plugins = [ new HtmlWebpackPlugin(< template: './src/index.html', // Данный html будет использован как шаблон >), ]; // Создаем массив плагинов module.exports = < mode, plugins, // Сокращенная запись plugins: plugins в ES6+ entry: './src/index.js', devtool: 'source-map', output: < path: path.resolve(__dirname, 'dist'), clean: true, >, devServer: < hot: true, >, module: < rules: [ < test: /\.(html)$/, use: ['html-loader'] >, // Добавляем загрузчик для html ], > >
html-webpack-plugin автоматически импортирует главный javascript-файл в документ, поэтому нет необходимости это делать вручную.
Добавляем поддержку стилей
Для поддержки стилей нам понадобится mini-css-extract-plugin , css-loader , sass-loader / less-loader (В зависимости от используемого вами препроцессора), sass / less , postcss , postcss-preset-env и postcss-loader .
npm i -D mini-css-extract-plugin css-loader sass-loader sass postcss postcss-preset-env postcss-loader
Или, если вы используете less:
npm i -D mini-css-extract-plugin css-loader less-loader less postcss postcss-preset-env postcss-loader
Начнем с создания в корне проекта файла postcss.config.js , этот инструмент автоматически подставляет вендорные префиксы в стилях в зависимости от вашей конфигурации browserslist (но о нем чуть позже). Из файла экпортируем данный объект:
Вносим изменения в webpack.config.js :
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // Импортируем плагин let mode = 'development'; if (process.env.NODE_ENV === 'production') < mode = 'production'; >const plugins = [ new HtmlWebpackPlugin(< template: './src/index.html', >), new MiniCssExtractPlugin(< filename: '[name].[contenthash].css', // Формат имени файла >), // Добавляем в список плагинов ]; module.exports = < // . module: < rules: [ < test: /\.(html)$/, use: ['html-loader'] >, < test: /\.(s[ac]|c)ss$/i, // /\.(le|c)ss$/i если вы используете less use: [ MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'sass-loader', ], >, // Добавляем загрузчики стилей ], > >
При использовании webpack стили импортируются не в html-файле, а непосредственно в javascript(не касается подключения через cdn):
Browserslist
Browserslist — конфиг, который служит для обозначения браузеров, которые должны поддерживаться данным приложением.
В корне приложения создадим файл .browserslistrc
Подробно про конфигурацию browserslist вы можете прочитать здесь
Вы можете использовать следующую конфигурацию:
> 0.5% # На браузер должно приходится не менее 0.5% пользователей not dead # Браузеры с официальной поддержкой
В webpack.config.js вносим следующие изменения:
// . let mode = 'development'; let target = 'web'; // в режиме разработки browserslist не используется if (process.env.NODE_ENV === 'production') < mode = 'production'; target = 'browserslist'; // в продакшен режиме используем browserslist >// . module.exports = < mode, target, // Сокращенная запись target: target в ES6+, // . >
Добавляем поддержку изображений и шрифтов
Для обработки изображений и шрифтов в конфигурации вебпака в module.rules добавим следующие правила:
Теперь, помимо классического использования в html и css, вы можете импортировать изображения напрямую в javascript. Пример использования:
import image from './assets/image.jpg'; document.getElementById('root').innerHTML = ` />`;
Babel
Babel — это транскомпилятор JavaScript. Мы можем использовать все новые возможности языка, а babel сделает наш код совместимым с предыдущими версиями JavaScript.
Установим необходимые для babel зависимости: @babel/core , @babel/preset-env и babel-loader :
npm i -D @babel/core @babel/preset-env babel-loader
В корне проекта создадим файл babel.config.js и экспортируем данный объект:
Далее в webpack.config.js добавим следующее правило в module.rules :
Теперь, если соберем проект:
И посмотрим в папке dist на наш код из начала статьи в ES6+ синтаксисе, мы увидим, что теперь современные функции JavaScript заменены на полифилы:
var sayHello = function sayHello() < return console.log('hello'); >;
На этом базовая настрока webpack подходит к концу, вы можете использовать данную сборку для своих проектов. Далее будет рассмотрена настройка webpack для работы с React, а также в конце статьи вы сможете найти полезные ссылки(в том числе на github данной сборки).
[bonus] Настройка webpack для работы с React
Теперь добавим поддержку React и подключим плагин react-refresh-webpack-plugin . Данный плагин является экспериментальным, но работает достаточно стабильно. Благодаря этому плагину при перезагрузке страницы состояния state компонентов остаются неизменными. Здесь вы можете увидеть пример работы hot reloading в React(на данном видео эта функция реализована благодаря create-react-app ).
Установим необходимые зависимости:
npm i -D @babel/preset-react cross-env react-refresh pmmmwh/react-refresh-webpack-plugin
cross-env позволяет получить доступ к установке переменных окружения в windows.
Теперь при запуске сервера мы будем передавать SERVE=true через переменные окружения. Внесем следующие изменения в наши скрипты:
Добавляем поддержку React и плагин в babel.config.js :
const plugins = []; if (process.env.NODE_ENV === 'development') < plugins.push('react-refresh/babel'); >// React hot reloading необходим только в режиме разработки module.exports = < presets: ['@babel/preset-env', '@babel/preset-react'], // Добавляем в babel // пресет для работы с React plugins, >;
Последний шаг: добавим поддержку jsx и подключим плагин в webpack.config.js :
const path = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); // Импортируем плагин // . if (process.env.SERVE) < // Используем плагин только если запускаем devServer plugins.push(new ReactRefreshWebpackPlugin()); >// Данный код должен быть размещен после объявления массива plugins module.exports = < // . module: < rules: [ // . < test: /\.jsx?$/, // обновляем регулярное выражение для поддержки jsx exclude: /node_modules/, use: < loader: 'babel-loader', options: < cacheDirectory: true, >, >, >, ], >, >;
Заключение
Спасибо за прочтение, надеюсь эта статья помогла вам разобраться в webpack 5. На моем github размещены обе версии сборки webpack: базовая сборка и сборка для React.