Кратко
СкопированоWebpack — это самый популярный сборщик в мире JS. Его функции легко расширяются с помощью сторонних пакетов, так что Webpack можно заставить делать практически что угодно. А если готового плагина не нашлось, благодаря мощному API можно написать решение под свой уникальный случай.
Базовое использование
СкопированоНа базовом уровне использовать Webpack довольно просто. Представим, что в нашем приложении есть файл application.js с функциями, необходимыми для работы:
function sayHello() { console.log('Hello!')}function sayBye() { console.log('Bye!')}// Экспортируем эти функции,// чтобы воспользоваться ими в другом месте:export { sayHello, sayBye }
function sayHello() {
console.log('Hello!')
}
function sayBye() {
console.log('Bye!')
}
// Экспортируем эти функции,
// чтобы воспользоваться ими в другом месте:
export { sayHello, sayBye }
Теперь создадим файл index.js, который будет использоваться как входная точка, и вызовем в нем функции приложения:
import { sayHello, sayBye } from './application'sayHello()sayBye()
import { sayHello, sayBye } from './application'
sayHello()
sayBye()
Настроим Webpack, чтобы он собирал единый файл с кодом приложения.
Для начала следует добавить Webpack в список зависимостей приложения:
npm install --dev webpack webpack-cli
npm install --dev webpack webpack-cli
webpack — основная зависимость, в которой хранится весь код, нужный для работы бандлера.
webpack — обёртка для запуска Webpack из командной строки, Command Line Interface.
Теперь достаточно создать простой конфигурационный файл webpack.config.js:
// path — встроенный в Node.js модульconst path = require('path')module.exports = { // Указываем путь до входной точки: entry: './src/index.js', // Описываем, куда следует поместить результат работы: output: { // Путь до директории (важно использовать path.resolve): path: path.resolve(__dirname, 'dist'), // Имя файла со сборкой: filename: 'bundle.js' }}
// path — встроенный в Node.js модуль
const path = require('path')
module.exports = {
// Указываем путь до входной точки:
entry: './src/index.js',
// Описываем, куда следует поместить результат работы:
output: {
// Путь до директории (важно использовать path.resolve):
path: path.resolve(__dirname, 'dist'),
// Имя файла со сборкой:
filename: 'bundle.js'
}
}
Почти готово, осталось только добавить скрипт для сборки в package.json и вызвать его:
{ "scripts": { "build": "webpack" }}
{
"scripts": {
"build": "webpack"
}
}
npm run build
npm run build
После выполнения в директории dist окажется файл bundle.js, который уже можно подключать на страницу в браузере.
В корне проекта нужно создать папку src, а в ней файл index.html и подключить в него файл со сборкой:
<!DOCTYPE html><html> <head> ... </head> <body> ... <script src="./dist/bundle.js"></script> </body></html>
<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
...
<script src="./dist/bundle.js"></script>
</body>
</html>
Если открыть этот файл в браузере, то в консоли появится приветствие и прощание.

Отслеживание изменений в проекте
СкопированоЗаново запускать сборку после внесения каждой правки не очень удобно. Во-первых, придётся каждый раз писать команду в терминале. Во-вторых, полная сборка больших проектов может занимать десятки минут, и тратить столько времени каждый раз просто расточительно.
Для решения этой проблемы можно воспользоваться режимом инкрементальной сборки, когда Webpack отслеживает изменения файлов с исходным кодом и автоматически собирает те части, которые изменились.
Добавим новую команду в package.json:
{ "scripts": { "build": "webpack", "watch": "webpack --watch" }}
{
"scripts": {
"build": "webpack",
"watch": "webpack --watch"
}
}
Теперь достаточно открыть файл index.html в браузере и обновлять страницу после сохранения файлов с исходным кодом.
Для большего удобства можно воспользоваться пакетом webpack-dev-server.
Расширение
СкопированоWebpack — невероятно мощный инструмент, в первую очередь за счёт своей расширяемости. В базовом случае он только собирает несколько JS-файлов в один, но с помощью лоадеров и плагинов можно сильно изменить его функциональность.
Webpack начинает свою работу со входной точки — первого JS-файла. В нём он находит все импорты, по которым собирает файлы с исходным кодом проекта. Во всех найденных файлах снова ищет импорты, и так далее, пока импорты не закончатся. В итоге у Webpack оказывается список всех файлов проекта и информация, как эти файлы связаны. Затем в дело вступают плагины и лоадеры. Для каждого файла Webpack найдёт все подходящие по конфигурации лоадеры и обработает ими файл.
Плагины — это более глобальный способ изменить поведение сборщика. В процессе сборки Webpack будет вызывать специальную функцию в каждом плагине, передавая в неё текущий контекст сборки и API для изменения этого контекста.
Обратная сторона расширяемости Webpack — сложность его конфигурации. В больших проектах файл с настройками сборки может занимать тысячи строк. Часто такую конфигурацию разбивают на несколько файлов, чтобы её было проще читать.
Лоадеры
СкопированоЛоадер — это функция, которая принимает содержимое какого-то файла и должна вернуть изменённое содержимое.
Например, ts превратит любой TypeScript-код в обыкновенный JavaScript-код.
Для Webpack написано огромное число лоадеров — для работы со стилями, с разными языками, для обработки изображений и для многого другого. Вот несколько, которые можно встретить почти в любом проекте:
style— импортирует CSS-файлы и внедряет стили в DOM.- loader css— позволяет работать с- loader @importиurlвнутри CSS.( ) babel— позволяет писать код на современном JS, но исполнять его даже в старых браузерах.- loader
Чтобы добавить новый лоадер, нужно расширить файл webpack.config.js:
module.exports = { // В этом массиве будут перечислены все применяемые лоадеры: module: { rules: [ { // Это правило будет применяться ко всем файлам, // имя которых подойдет под регулярное выражение: test: /\.css$/, // Список лоадеров, которые применятся к файлу: use: [ { loader: 'style-loader' }, { loader: 'css-loader', // Лоадеру можно передать параметры: options: { modules: true } } ] } ] }}
module.exports = {
// В этом массиве будут перечислены все применяемые лоадеры:
module: {
rules: [
{
// Это правило будет применяться ко всем файлам,
// имя которых подойдет под регулярное выражение:
test: /\.css$/,
// Список лоадеров, которые применятся к файлу:
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
// Лоадеру можно передать параметры:
options: { modules: true }
}
]
}
]
}
}
Плагины
СкопированоПлагин — мощный способ расширить или изменить функциональность Webpack. Если лоадер ограничен только одной функцией (принимает содержимое файла и должен вернуть изменённое содержимое), то плагин может делать всё что угодно.
Для Webpack написано огромное количество плагинов — для работы со стилями, повышения удобства разработки и упрощения жизни инженеров, для автоматизации рутинных операций и много других. Вот несколько, которые можно встретить почти в любом проекте:
MiniCssExtract— по умолчанию все стили, которые обработал Webpack, попадают в JS-файл и потом вставляются в тегPlugin <style>. Этот плагин извлекает все стили в отдельный CSS-файл, который можно подключить к странице через тег<link>.HotModuleReplacement— позволяет делать изменения в коде и видеть изменения в браузере без полной перезагрузки страницы, это делает разработку более комфортной.Plugin CompressionWebpack— сжимает все ресурсы, сгенерированные Webpack, чтобы передавать пользователям по сети меньший объём данных.Plugin
Чтобы добавить новый плагин в сборку, нужно расширить файл webpack.config.js:
// Webpack предоставляет несколько плагинов в основном пакете:const { ProgressPlugin } = require('webpack')module.exports = { plugins: [ // При сборке этот плагин будет отображать прогресс в консоли: new ProgressPlugin() ]}
// Webpack предоставляет несколько плагинов в основном пакете:
const { ProgressPlugin } = require('webpack')
module.exports = {
plugins: [
// При сборке этот плагин будет отображать прогресс в консоли:
new ProgressPlugin()
]
}
На практике
Скопированосоветует
Скопировано📄 На практике не очень удобно вручную создавать HTML-файлы и подключать туда сборки, сгенерированные Webpack — ведь количество и имена файлов могут меняться в зависимости от сборки. Для автоматизации часто используют HtmlWebpackPlugin.
В первую очередь, нужно установить пакет с плагином в проект:
npm install --save-dev html-webpack-plugin
npm install --save-dev html-webpack-plugin
const { HtmlWebpackPlugin } = require('html-webpack-plugin')module.exports = { plugins: [new HtmlWebpackPlugin()]}
const { HtmlWebpackPlugin } = require('html-webpack-plugin')
module.exports = {
plugins: [new HtmlWebpackPlugin()]
}
При сборке плагин сгенерирует пустой index.html в папку с собранным проектом и добавит туда ссылки на финальные JS- и CSS-файлы. При необходимости плагин можно кастомизировать.
💫 path — это встроенный в Node.js модуль для работы с путями. Чтобы не беспокоиться об особенностях разных операционных систем, лучше всегда при работе с путями в файловой системе использовать модуль path.
В нём есть несколько полезных для конфигурации Webpack функций:
path— функция, которая принимает любое число сегментов пути и возвращает абсолютный путь. Работает так:. resolve
path.resolve('/foo/bar', './baz')// '/foo/bar/baz'path.resolve('/foo/bar', '/tmp/file/')// '/tmp/file'// Если текущая рабочая директория /home/user:path.resolve('www', 'static_files/png', '../gif/image.gif')// '/home/user/www/static_files/gif/image.gif'
path.resolve('/foo/bar', './baz')
// '/foo/bar/baz'
path.resolve('/foo/bar', '/tmp/file/')
// '/tmp/file'
// Если текущая рабочая директория /home/user:
path.resolve('www', 'static_files/png', '../gif/image.gif')
// '/home/user/www/static_files/gif/image.gif'
-
path— строка разделителя путей в текущем окружении (. sep /или\). -
path— функция, которая принимает строку с именем файла и возвращает расширение этого файла.. extname