Сервер разработки Webpack
webpack-dev-server — это небольшой сервер Node.js на основе Express, который использует webpack-dev-middleware для предоставления webpack пакета. Он также имеет небольшой запуск, подключенный к серверу через Sock.js.
Сервер передаёт информацию о состоянии компиляции клиенту, который реагирует на эти события. Вы можете выбрать различные режимы в зависимости от ваших потребностей.
Предположим, у вас есть следующий конфигурационный файл (webpack.config.js):
var path = require("path");
module.exports = {
entry: {
app: ["./app/main.js"]
},
output: {
path: path.resolve(__dirname, "build"),
publicPath: "/assets/",
filename: "bundle.js"
}
};
У вас есть папка app с вашим исходным точкой входа, которую webpack соберет в файл bundle.js в папке build.
ПРИМЕЧАНИЕ: Сервер разработки webpack — это отдельный пакет NPM. Вы можете установить его с помощью: npm install webpack-dev-server.
Базовая директория
webpack-dev-server будет обслуживать файлы в текущей директории, если вы не укажете другую базу.
$ webpack-dev-server --content-base build/
Используя эту конфигурацию, webpack-dev-server будет обслуживать статические файлы в вашей папке build. Он будет следить за вашими исходными файлами и перекомпилировать пакет при каждом изменении.
Этот измененный пакет предоставляется из памяти по относительному пути, указанному в publicPath (см. API). Он не будет записан в вашу конфигурированную директорию output. Если пакет уже существует по этому же URL-пути, в памяти пакет имеет приоритет (по умолчанию).
Используя указанную выше конфигурацию, пакет доступен по адресу localhost:8080/assets/bundle.js.
Для загрузки ваших скомпилированных файлов вам нужно создать файл index.html в папке build, из которой обслуживаются статические файлы (опция --content-base). Вот пример:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script src="assets/bundle.js"></script> </body> </html>
По умолчанию перейдите по адресу localhost:8080/, чтобы запустить приложение. В этой конфигурации (с publicPath) перейдите по адресу localhost:8080/assets/.
Автоматическое обновление
webpack-dev-server поддерживает несколько режимов автоматического обновления страницы:
-
Режим IFrame (страница встроена в
iframeи перегружается при изменении) - Режим Inline (в пакет добавляется небольшой клиент webpack-dev-server, который обновляет страницу при изменении)
Каждый режим также поддерживает Горячую замену модулей. При горячей замене модулей пакет уведомляется об изменениях (вместо полной перегрузки страницы). Запуск горячей замены модулей может затем загрузить обновленные модули и вставить их в работающее приложение.
Режим IFrame
Для использования режима IFrame дополнительной конфигурации не требуется. Просто перейдите в браузере по адресу http://«host»:«port»/webpack-dev-server/«path».
С указанной выше конфигурацией: http://localhost:8080/webpack-dev-server/index.html.
- Изменений конфигурации не требуется.
- Полезная информационная панель сверху вашего приложения.
- Изменения URL в приложении не отражаются в адресной строке браузера.
Режим Inline
Для использования режима Inline, либо
- указать
--inlineв командной строке. - указать
devServer: { inline: true }в вашей конфигурацииwebpack.config.js
Это добавляет точку входа клиента webpack-dev-server в конфигурацию webpack. Изменение URL не требуется. Просто перейдите по адресу http://«host»:«port»/«path».
С указанной выше конфигурацией: http://localhost:8080/index.html.
- Требуется опция конфигурации или флаг командной строки.
- Информация о статусе в консоли и (кратко) в журнале консоли браузера.
- Изменения URL в приложении отражаются в адресной строке браузера.
Режим Inline с Node.js API
Флаги inline: true в конфигурации webpack-dev-server нет, так как модуль webpack-dev-server не имеет доступа к конфигурации webpack. Вместо этого пользователь должен добавить точку входа клиента webpack-dev-server в конфигурацию webpack.
Для этого просто добавьте следующее ко всем точкам входа: webpack-dev-server/client?http://«path»:«port»/
С указанной выше конфигурацией:
var config = require("./webpack.config.js");
config.entry.app.unshift("webpack-dev-server/client?http://localhost:8080/");
var compiler = webpack(config);
var server = new WebpackDevServer(compiler, {...});
server.listen(8080);
Режим Inline в HTML
Также есть возможность добавить ссылку на скрипт клиента webpack-dev-server на страницу HTML:
<script src="http://localhost:8080/webpack-dev-server.js"></script>
Горячая замена модулей
Для включения горячей замены модулей с помощью webpack-dev-server укажите --hot в командной строке. Это добавляет HotModuleReplacementPlugin в конфигурацию webpack.
Самый простой способ использовать горячую замену модулей с webpack-dev-server — это использовать режим Inline.
Горячая замена модулей с режимом Inline в командной строке
Больше ничего не нужно. --inline --hot автоматически выполняет все необходимые действия. Командная строка webpack-dev-server автоматически добавляет специальную точку входа webpack/hot/dev-server в вашу конфигурацию.
Просто перейдите по адресу http://«host»:«port»/«path» и посмотрите, что произойдёт.
В журнале браузера должны появиться следующие сообщения:
[HMR] Waiting for update signal from WDS... [WDS] Hot Module Replacement enabled.
Сообщения, начинающиеся с [HMR], происходят из модуля webpack/hot/dev-server. Сообщения, начинающиеся с [WDS], происходят от клиента webpack-dev-server.
Важно указать правильный output.publicPath , иначе фрагменты горячей загрузки не могут быть загружены.
Горячая замена модулей с Node.js API
Аналогично режиму Inline, пользователю необходимо внести изменения в конфигурацию webpack.
Требуются три изменения:
- Добавить точку входа в конфигурацию webpack:
webpack/hot/dev-server. - Добавить
new webpack.HotModuleReplacementPlugin()в конфигурацию webpack. - Добавить
hot: trueв конфигурацию webpack-dev-server для включения HMR на сервере.
С указанной выше конфигурацией:
var config = require("./webpack.config.js");
config.entry.app.unshift("webpack-dev-server/client?http://localhost:8080/", "webpack/hot/dev-server");
var compiler = webpack(config);
var server = new webpackDevServer(compiler, {
hot: true
...
});
server.listen(8080);
Работа с редакторами/IDE, поддерживающими «безопасную запись»
Обратите внимание, что многие редакторы поддерживают функцию «безопасной записи» и по умолчанию её включают, что делает сервер разработки неспособным правильно отслеживать изменения файлов. «Безопасная запись» означает, что изменения записываются не напрямую в исходный файл, а во временный файл, который переименовывается и заменяет исходный файл при успешном завершении операции сохранения. Это поведение приводит к потере отслеживания файловым наблюдателем, поскольку исходный файл удаляется. Чтобы избежать этой проблемы, необходимо отключить функцию «безопасной записи» в вашем редакторе.
-
VIM — установить
:set backupcopy=yes(см. документацию) -
IntelliJ — Настройки ▶︎ Настройки системы ▶︎ Синхронизация ▶︎ Отключить
safe write(может отличаться в разных IDE IntelliJ, но вы можете использовать функцию поиска)
Проксирование
Сервер разработки Webpack использует http-proxy-middleware для необязательного проксирования запросов к отдельному, возможно внешнему, серверу бэкенда. Ниже приведена примерная конфигурация.
proxy: {
'/api': {
target: 'https://other-server.example.com',
secure: false
}
}
// In webpack.config.js
{
devServer: {
proxy: {
'/api': {
target: 'https://other-server.example.com',
secure: false
}
}
}
}
// Multiple entry
proxy: [
{
context: ['/api-v1/**', '/api-v2/**'],
target: 'https://other-server.example.com',
secure: false
}
]
См. документацию по опциям http-proxy-middleware для доступной конфигурации.
Проксирование некоторых URL может быть полезно для различных конфигураций. Один пример — обслуживание файлов JavaScript и других статических ресурсов с локального сервера разработки, но при этом отправка запросов API на внешний сервер разработки бэкенда. Другой пример — разделение запросов между двумя отдельными серверами бэкенда, такими как сервер аутентификации и сервер приложения.
Отклонение проксирования
(Добавлено в v1.13.0) Проксирование может быть необязательно отклонено на основе возвращаемого значением функции. Функция может проверять HTTP-запрос, ответ и любые заданные опции проксирования. Она должна вернуть либо false или путь URL, который будет обслуживаться вместо продолжения проксирования запроса.
Например, следующая конфигурация не будет проксировать HTTP-запросы, исходящие из браузера. Это похоже на опцию historyApiFallback: запросы браузера будут получать HTML-файл как обычно, а запросы API будут проксироваться на сервер бэкенда.
proxy: {
'/some/path': {
target: 'https://other-server.example.com',
secure: false,
bypass: function(req, res, proxyOptions) {
if (req.headers.accept.indexOf('html') !== -1) {
console.log('Skipping proxy for browser request.');
return '/index.html';
}
}
}
Переписывание URL-адресов запроса прокси
(Добавлено в v1.15.0) Запрос к прокси можно необязательно переписать, предоставив функцию. Функция может проверять и изменять HTTP-запрос.
Например, следующая конфигурация перепишет HTTP-запросы, удалив часть /api из начала URL.
proxy: {
'/api': {
target: 'https://other-server.example.com',
pathRewrite: {'^/api' : ''}
}
}
Обратите внимание, что pathRewrite — это функция http-proxy-middleware, поэтому ознакомьтесь с их документацией для получения дополнительной конфигурации.
Проксирование локальных виртуальных хостов
Похоже, что http-proxy-middleware предварительно разрешает локальные имена хостов в localhost, вам потребуется следующая конфигурация для исправления запроса прокси:
var server = new webpackDevServer(compiler, {
quiet: false,
stats: { colors: true },
proxy: {
"/api": {
"target": {
"host": "action-js.dev",
"protocol": 'http:',
"port": 80
},
ignorePath: true,
changeOrigin: true,
secure: false
}
}
});
server.listen(8080);
Командная строка webpack-dev-server
$ webpack-dev-server <entry>
Все опции командной строки webpack CLI также допустимы для командной строки webpack-dev-server, но параметр по умолчанию <output> отсутствует. Для командной строки webpack-dev-server также принимается webpack.config.js (или файл, переданный с помощью опции --config).
Есть несколько дополнительных опций:
-
--content-base <file/directory/url/port>: базовый путь к содержимому. -
--quiet: не выводить ничего в консоль. -
--no-info: подавлять скучную информацию. -
--colors: добавлять цвета в вывод. -
--no-colors: не использовать цвета в выводе. -
--compress: использовать сжатие gzip. -
--host <hostname/ip>: имя хоста или IP.0.0.0.0привязывается ко всем хостам. -
--port <number>: порт. -
--inline: встраивать webpack-dev-server runtime в bundle. -
--hot: добавляетHotModuleReplacementPluginи переключает сервер в горячий режим. Примечание: убедитесь, что вы не добавляетеHotModuleReplacementPluginдважды. -
--hot --inlineтакже добавляет записьwebpack/hot/dev-server. -
--public: перезаписывает хост и порт, используемые в режиме--inlineдля клиента (полезно для виртуальной машины или Docker). -
--lazy: без отслеживания, компилирует по запросу (не может быть объединён с--hot). -
--https: обслуживает webpack-dev-server по протоколу HTTPS. Включает самоподписанный сертификат, который используется при обработке запросов. -
--cert,--cacert,--key: Пути к файлам сертификата. -
--open: открывает URL в стандартном браузере (для версий webpack-dev-server > 2.0). -
--history-api-fallback: включает поддержку отката API истории. -
--client-log-level: управляет сообщениями в консоли браузера. Используйтеerror,warning,infoилиnone.
Дополнительные параметры конфигурации
При использовании командной строки можно разместить параметры webpack-dev-server в файле конфигурации по ключу devServer. Параметры, переданные через аргументы командной строки, переопределяют параметры в файле конфигурации. Для параметров в devServer см. следующий раздел.
Пример
module.exports = {
// ...
devServer: {
hot: true
}
}
API
var WebpackDevServer = require("webpack-dev-server");
var webpack = require("webpack");
var fs = require("fs");
var compiler = webpack({
// configuration
});
var server = new WebpackDevServer(compiler, {
// webpack-dev-server options
contentBase: "/path/to/directory",
// Can also be an array, or: contentBase: "http://localhost/",
hot: true,
// Enable special support for Hot Module Replacement
// Page is no longer updated, but a "webpackHotUpdate" message is sent to the content
// Use "webpack/hot/dev-server" as additional module in your entry point
// Note: this does _not_ add the `HotModuleReplacementPlugin` like the CLI option does.
historyApiFallback: false,
// Set this as true if you want to access dev server from arbitrary url.
// This is handy if you are using a html5 router.
compress: true,
// Set this if you want to enable gzip compression for assets
proxy: {
"**": "http://localhost:9090"
},
// Set this if you want webpack-dev-server to delegate a single path to an arbitrary server.
// Use "**" to proxy all paths to the specified server.
// This is useful if you want to get rid of 'http://localhost:8080/' in script[src],
// and has many other use cases (see https://github.com/webpack/webpack-dev-server/pull/127 ).
setup: function(app) {
// Here you can access the Express app object and add your own custom middleware to it.
// For example, to define custom handlers for some paths:
// app.get('/some/path', function(req, res) {
// res.json({ custom: 'response' });
// });
},
// pass [static options](http://expressjs.com/en/4x/api.html#express.static) to inner express server
staticOptions: {
},
clientLogLevel: "info",
// Control the console log messages shown in the browser when using inline mode. Can be `error`, `warning`, `info` or `none`.
// webpack-dev-middleware options
quiet: false,
noInfo: false,
lazy: true,
filename: "bundle.js",
watchOptions: {
aggregateTimeout: 300,
poll: 1000
},
// It's a required option.
publicPath: "/assets/",
headers: { "X-Custom-Header": "yes" },
stats: { colors: true },
https: {
cert: fs.readFileSync("path-to-cert-file.pem"),
key: fs.readFileSync("path-to-key-file.pem"),
cacert: fs.readFileSync("path-to-cacert-file.pem")
}
});
server.listen(8080, "localhost", function() {});
// server.close();
См. webpack-dev-middleware для документации по параметрам middleware.
Обратите внимание, что конфигурация webpack не передаётся в API WebpackDevServer, поэтому параметр devServer в конфигурации webpack в этом случае не используется. Также для API WebpackDevServer нет режима inline. <script src="http://localhost:8080/webpack-dev-server.js"></script> должен быть вручную добавлен в страницу HTML.
Параметр historyApiFallback
Если вы используете API истории HTML5, вам, вероятно, нужно обслуживать свои index.html вместо ответов 404, что можно сделать, установив historyApiFallback: true. Однако, если вы изменили output.publicPath в своей конфигурации Webpack, вам нужно указать URL для перенаправления. Это делается с помощью параметра historyApiFallback.index.
// output.publicPath: '/foo-app/'
historyApiFallback: {
index: '/foo-app/'
}
Используя переопределения, также можно использовать эту функцию для обслуживания статических страниц:
historyApiFallback: {
rewrites: [
// shows views/landing.html as the landing page
{ from: /^\/$/, to: '/views/landing.html' },
// shows views/subpage.html for all routes starting with /subpage
{ from: /^\/subpage/, to: '/views/subpage.html' },
// shows views/404.html on all other pages
{ from: /./, to: '/views/404.html' },
],
},
Сочетание с существующим сервером
Возможно, вы захотите запустить бэкэнд-сервер или его эмуляцию в процессе разработки. Вы не должны использовать webpack-dev-server в качестве бэкэнда. Его единственная цель — обслуживание статических (webpack) ресурсов.
Вы можете запустить два сервера параллельно: webpack-dev-server и ваш бэкэнд-сервер.
В этом случае вам нужно научить webpack-сгенерированные ресурсы отправлять запросы на webpack-dev-server, даже когда он работает на HTML-странице, отправленной бэкэнд-сервером. С другой стороны, вам нужно научить ваш бэкэнд-сервер генерировать HTML-страницы, которые включают теги script указывающие на ресурсы на webpack-dev-server. Кроме того, вам нужна связь между webpack-dev-server и webpack-dev-server runtime для запуска перезагрузок при перекомпиляции.
Для обучения webpack отправлять запросы (для загрузки модулей или HMR) на webpack-dev-server вам необходимо указать полный URL в параметре output.publicPath.
Для установления соединения между webpack-dev-server и его runtime лучше всего использовать режим inline с --inline. Командная строка webpack-dev-server автоматически включает точку входа, которая устанавливает соединение WebSocket. (Вы также можете использовать режим iframe, если укажете --content-base webpack-dev-server на ваш бэкэнд-сервер. **Если вам нужно соединение WebSocket с вашим бэкэнд-сервером**, вам придется использовать режим iframe).
При использовании режима inline просто откройте URL бэкэнд-сервера в вашем браузере. (Если вы используете режим iframe, откройте URL, начинающийся с /webpack-dev-server/ webpack-dev-server).
Резюме и пример:
- webpack-dev-server на порту
8080. - бэкэнд-сервер на порту
9090. - генерировать HTML-страницы с
<script src="http://localhost:8080/assets/bundle.js">. - конфигурация webpack с
output.publicPath = "http://localhost:8080/assets/". - при компиляции файлов для производства, используйте
--output-public-path /assets/. -
режим inline:
-
--inline. - открыть
http://localhost:9090.
-
- или режим iframe:
- webpack-dev-server
contentBase = "http://localhost:9090/"(--content-base). - открыть
http://localhost:8080/webpack-dev-server/.
- webpack-dev-server
Или используйте параметр proxy…
© 2012–2015 Tobias Koppers
Licensed under the MIT License.
https://webpack.github.io/docs/webpack-dev-server.html