webpack-dev-server — инструмент для локальной разработки
приложений на базе Webpack. Сервер запускает сборку проекта в памяти,
автоматически отслеживает изменения файлов, обновляет браузер и
предоставляет удобную среду для разработки без необходимости вручную
пересобирать проект после каждого изменения.
Основные возможности:
В современных проектах webpack-dev-server практически
всегда используется вместе с webpack и
webpack-cli.
Установка выполняется как зависимость для разработки.
npm install --save-dev webpack-dev-server
yarn add --dev webpack-dev-server
pnpm add -D webpack-dev-server
Пример структуры:
project/
├── src/
│ └── index.js
├── dist/
├── package.json
└── webpack.config.js
Минимальный конфигурационный файл:
const path = require('path');
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true
}
};
Настройки сервера располагаются внутри свойства
devServer.
const path = require('path');
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true
},
devServer: {
port: 3000
}
};
В package.json обычно добавляют отдельный скрипт:
{
"scripts": {
"dev": "webpack serve"
}
}
Запуск:
npm run dev
После запуска сервер становится доступен по адресу:
http://localhost:3000
Команда:
webpack serve
выполняет несколько действий одновременно:
Это отличается от команды:
webpack
которая просто создаёт сборку и завершает работу.
Свойство port задаёт номер порта.
devServer: {
port: 8080
}
Можно использовать строку:
devServer: {
port: 'auto'
}
В этом случае Webpack автоматически выберет свободный порт.
По умолчанию сервер доступен только локально.
devServer: {
host: 'localhost'
}
Для доступа из локальной сети:
devServer: {
host: '0.0.0.0'
}
Это полезно при тестировании на телефонах, планшетах и других устройствах.
Свойство open автоматически открывает браузер после
запуска сервера.
devServer: {
open: true
}
Можно указать конкретный браузер:
devServer: {
open: {
app: {
name: 'chrome'
}
}
}
Свойство static определяет директорию для обслуживания
статических ресурсов.
devServer: {
static: path.resolve(__dirname, 'public')
}
Структура:
project/
├── public/
│ ├── favicon.ico
│ └── robots.txt
Файлы становятся доступны напрямую:
http://localhost:3000/favicon.ico
Допускается массив:
devServer: {
static: [
path.resolve(__dirname, 'public'),
path.resolve(__dirname, 'assets')
]
}
По умолчанию изменения статических файлов отслеживаются автоматически.
Явная настройка:
devServer: {
static: {
directory: path.resolve(__dirname, 'public'),
watch: true
}
}
Отключение наблюдения:
devServer: {
static: {
directory: path.resolve(__dirname, 'public'),
watch: false
}
}
Live Reload обновляет страницу после изменения файлов.
devServer: {
liveReload: true
}
Механизм работы:
HMR обновляет модули без полной перезагрузки страницы.
devServer: {
hot: true
}
Преимущества:
Полностью обновляет страницу.
Изменение → сборка → reload страницы
Обновляет только изменённый модуль.
Изменение → сборка → замена модуля
import './style.css';
console.log('Application started');
devServer: {
hot: true
}
Для React Router, Vue Router и других SPA используется:
devServer: {
historyApiFallback: true
}
Без этой настройки при обновлении страницы:
http://localhost:3000/profile
сервер попытается найти физический файл /profile и
вернёт 404.
С включённым historyApiFallback сервер всегда отдаёт
index.html.
Включение HTTPS:
devServer: {
https: true
}
Современный вариант:
devServer: {
server: 'https'
}
const fs = require('fs');
devServer: {
server: {
type: 'https',
options: {
key: fs.readFileSync('./certs/server.key'),
cert: fs.readFileSync('./certs/server.crt')
}
}
}
Свойство compress включает gzip-сжатие.
devServer: {
compress: true
}
Это позволяет приблизить локальную среду к production-режиму.
Секция client управляет поведением браузерного клиента
Webpack.
devServer: {
client: {
overlay: true
}
}
Ошибки компиляции могут отображаться поверх страницы.
devServer: {
client: {
overlay: {
errors: true,
warnings: false
}
}
}
devServer: {
client: {
logging: 'info'
}
}
Возможные значения:
noneerrorwarninfologverbosedevServer: {
client: {
progress: true
}
}
devServer: {
client: {
webSocketURL: 'ws://0.0.0.0:8080/ws'
}
}
Используется при сложных конфигурациях reverse proxy.
Одна из самых важных возможностей
webpack-dev-server.
Пример:
devServer: {
proxy: {
'/api': {
target: 'http://localhost:5000',
changeOrigin: true
}
}
}
Запрос:
http://localhost:3000/api/users
будет проксирован на:
http://localhost:5000/api/users
Основные причины:
devServer: {
proxy: {
'/api': {
target: 'http://localhost:5000',
pathRewrite: {
'^/api': ''
}
}
}
}
Теперь:
/api/users
станет:
/users
devServer: {
proxy: {
'/api': {
target: 'http://localhost:5000'
},
'/auth': {
target: 'http://localhost:7000'
}
}
}
Добавление HTTP-заголовков:
devServer: {
headers: {
'X-Custom-Header': 'webpack'
}
}
devServer: {
allowedHosts: 'all'
}
Или:
devServer: {
allowedHosts: [
'localhost',
'.example.com'
]
}
devMiddleware управляет внутренним middleware
Webpack.
devServer: {
devMiddleware: {
writeToDisk: true
}
}
По умолчанию сборка хранится только в памяти.
Обычный режим работы:
Webpack → memory filesystem
С writeToDisk:
Webpack → memory filesystem + физические файлы
Это полезно:
devServer: {
devMiddleware: {
publicPath: '/build/'
}
}
Дополнительное отслеживание файлов:
devServer: {
watchFiles: [
'src/**/*.html',
'templates/**/*.twig'
]
}
Автоматическое обнаружение сервера в локальной сети:
devServer: {
bonjour: true
}
Использование Unix Socket:
devServer: {
ipc: true
}
devServer: {
webSocketServer: 'ws'
}
Варианты:
wssockjsconst path = require('path');
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true
},
devtool: 'eval-source-map',
devServer: {
port: 3000,
host: 'localhost',
open: true,
hot: true,
compress: true,
historyApiFallback: true,
static: {
directory: path.resolve(__dirname, 'public'),
watch: true
},
client: {
overlay: true,
progress: true
},
proxy: {
'/api': {
target: 'http://localhost:5000',
changeOrigin: true
}
}
}
};
devServer: {
port: 3000,
hot: true,
open: true,
historyApiFallback: true,
static: {
directory: path.resolve(__dirname, 'public')
}
}
devServer: {
hot: true,
compress: true,
historyApiFallback: true
}
devServer: {
devMiddleware: {
writeToDisk: true
},
static: false
}
Причина:
webpack: command not found
обычно связана с отсутствием webpack-cli.
Решение:
npm install --save-dev webpack-cli
Причины:
webpack.config.js;Причина:
EADDRINUSE
Порт уже используется другим процессом.
Решения:
devServer: {
port: 'auto'
}
или использование другого порта.
Причина — отсутствие:
historyApiFallback: true
Частые причины:
hot;Webpack 5 требует современные версии
webpack-dev-server.
Типичная связка:
webpack: 5.x
webpack-cli: 5.x
webpack-dev-server: 4.x или 5.x
Готовый сервер разработки.
Включает:
Только middleware.
Используется внутри собственных Express/Koa/Fastify серверов.
Иногда проекты переходят на:
Однако webpack-dev-server по-прежнему широко
применяется: