This document serves as a migration guide for webpack-dev-server@4.0.0
.
webpack-dev-server
v3 andwebpack-dev-server
v4 automatically applyHotModuleReplacementPlugin
plugin when you sethot: true
, so please check you don't haveHotModuleReplacementPlugin
in yourplugins
if you havehot: true
/hot: "only"
webpack-dev-server
v3 andwebpack-dev-server
v4 automatically injectwebpack/hot/dev-server
in yourentry
option when you sethot: true
(except when you useinjectHot
for webpack-dev-server v3), please check you don't havewebpack/hot/dev-server
in yourentry
optionwebpack-dev-server
v3 andwebpack-dev-server
v4 automatically injectwebpack-dev-server/client/index.js
in yourentry
option (except when you useinjectClient
for webpack-dev-server v3), please check you don't havewebpack-dev-server/client/index.js
in yourentry
option
- Minimum supported
Node.js
version is12.13.0
. - Minimum supported
webpack
version is4.37.0
(but we recommend usingwebpack >= v5.0.0
). - Minimum compatible
webpack-cli
version is4.7.0
. - The
hotOnly
option was removed, if you need hot only mode, use{ hot: 'only' }
value.
v3:
module.exports = {
devServer: {
hotOnly: true,
},
};
v4:
module.exports = {
devServer: {
hot: "only",
},
};
- Default web socket server is
ws
(IE9 does not support web socket, please use{ webSocketServer: 'sockjs' }
). - The
setup
option was removed without replacement. - The
before
option was renamed toonBeforeSetupMiddleware
and changed arguments.
v3:
module.exports = {
devServer: {
before: function (app, server, compiler) {
app.get("/some/path", function (req, res) {
res.json({ custom: "response" });
});
},
},
};
v4:
module.exports = {
devServer: {
onBeforeSetupMiddleware: function (devServer) {
devServer.app.get("/some/path", function (req, res) {
res.json({ custom: "response" });
});
},
},
};
- The
after
option was renamed toonAfterSetupMiddleware
and changed arguments.
v3:
module.exports = {
devServer: {
after: function (app, server, compiler) {
app.get("/some/path", function (req, res) {
res.json({ custom: "response" });
});
},
},
};
v4:
module.exports = {
devServer: {
onAfterSetupMiddleware: function (devServer) {
devServer.app.get("/some/path", function (req, res) {
res.json({ custom: "response" });
});
},
},
};
- The
features
option was removed in favoronBeforeSetupMiddleware
andonAfterSetupMiddleware
options. - The
key
,cert
,pfx
,pfx-passphrase
,cacert
,ca
andrequestCert
options were moved tohttps
options, please usehttps.{key|cert|pfx|passphrase|requestCert|ca}
.
v3:
module.exports = {
devServer: {
ca: "./server.pem",
pfx: "./server.pfx",
key: "./server.key",
cert: "./server.crt",
pfxPassphrase: "webpack-dev-server",
requestCert: true,
},
};
v4:
module.exports = {
devServer: {
https: {
ca: "./server.pem",
pfx: "./server.pfx",
key: "./server.key",
cert: "./server.crt",
passphrase: "webpack-dev-server",
requestCert: true,
},
},
};
- The
compress
option is nowtrue
by default. filename
andlazy
options were removed in favor experiments.lazyCompilation.- The
inline
(iframe
live mode) option was removed without replacement. log
,logLevel
,logTime
,quiet
,noInfo
, andreporter
options were removed without replacement, now we use built-in logger.- The
useLocalIp
option was removed in favor ofhost: 'local-ip'/'local-ipv4'/'local-ipv6'
.
v3:
module.exports = {
devServer: {
useLocalIp: true,
},
};
v4:
module.exports = {
devServer: {
host: "local-ip",
},
};
host
/port
options can't benull
or empty string, please usehost: 'local-ip'
orport: 'auto'
.- the
warn
option was removed in favor of ignoreWarnings fs
,index
,mimeTypes
,publicPath
,serverSideRender
,stats
, andwriteToDisk
(related towebpack-dev-middleware
) were moved todevMiddleware
option.
v3:
module.exports = {
devServer: {
index: true,
mimeTypes: { "text/html": ["phtml"] },
publicPath: "/publicPathForDevServe",
serverSideRender: true,
writeToDisk: true,
},
};
v4:
module.exports = {
devServer: {
devMiddleware: {
index: true,
mimeTypes: { "text/html": ["phtml"] },
publicPath: "/publicPathForDevServe",
serverSideRender: true,
writeToDisk: true,
},
},
};
progress
/overlay
/clientLogLevel
option were moved to theclient
option:
v3:
module.exports = {
devServer: {
clientLogLevel: "info",
overlay: true,
progress: true,
},
};
v4:
module.exports = {
devServer: {
client: {
logging: "info",
// Can be used only for `errors`/`warnings`
//
// overlay: {
// errors: true,
// warnings: true,
// }
overlay: true,
progress: true,
},
},
};
public
,sockHost
,sockPath
, andsockPort
options were removed in favorclient.webSocketURL
option:
v3:
module.exports = {
devServer: {
public: "ws://localhost:8080",
},
};
module.exports = {
devServer: {
sockHost: "0.0.0.0",
sockPath: "/ws",
sockPort: 8080,
},
};
v4:
module.exports = {
devServer: {
client: {
// Can be `string`:
//
// To get protocol/hostname/port from browser
// webSocketURL: 'auto://0.0.0.0:0/ws'
webSocketURL: {
hostname: "0.0.0.0",
pathname: "/ws",
port: 8080,
},
},
},
};
If you need to set custom path
to dev server web socket server, please use:
module.exports = {
devServer: {
webSocketServer: {
options: {
path: "/my/custom/path/to/web/socket/server",
},
},
},
};
client.overlay
(previously theoverlay
option ) is nowtrue
by default.contentBase
/contentBasePublicPath
/serveIndex
/watchContentBase
/watchOptions
/staticOptions
options were moved tostatic
option:
v3:
module.exports = {
devServer: {
contentBase: path.join(__dirname, "public"),
contentBasePublicPath: "/serve-content-base-at-this-url",
serveIndex: true,
watchContentBase: true,
watchOptions: {
poll: true,
},
},
};
v4:
module.exports = {
devServer: {
static: {
directory: path.resolve(__dirname, "static"),
staticOptions: {},
// Don't be confused with `devMiddleware.publicPath`, it is `publicPath` for static directory
// Can be:
// publicPath: ['/static-public-path-one/', '/static-public-path-two/'],
publicPath: "/static-public-path/",
// Can be:
// serveIndex: {} (options for the `serveIndex` option you can find https://github.com/expressjs/serve-index)
serveIndex: true,
// Can be:
// watch: {} (options for the `watch` option you can find https://github.com/paulmillr/chokidar)
watch: true,
},
},
};
Provide an array of objects in case you have multiple static folders:
module.exports = {
//...
devServer: {
static: [
{
directory: path.join(__dirname, "assets"),
publicPath: "/serve-public-path-url",
},
{
directory: path.join(__dirname, "css"),
publicPath: "/other-serve-public-path-url",
},
],
},
};
- Default value of the
static
option ispath.resolve(process.cwd(), 'public')
directory and enabled by default. static.watch
is enabled by default.- The
socket
option was renamed toipc
(also supportsstring
type, i.e. path to unix socket):
v3:
module.exports = {
devServer: {
socket: true,
},
};
v4:
module.exports = {
devServer: {
ipc: true,
},
};
- The
disableHostCheck
option was removed in favorallowedHosts: 'all'
:
v3:
module.exports = {
devServer: {
disableHostCheck: true,
},
};
v4:
module.exports = {
devServer: {
allowedHosts: "all",
},
};
open
andopenPage
options were unionized in favor of theopen
option:
v3:
module.exports = {
devServer: {
// openPage: '/my-page',
openPage: true,
},
};
v4:
module.exports = {
devServer: {
// open: ['/my-page'],
open: true,
},
};
module.exports = {
devServer: {
open: {
target: ["first.html", `http://localhost:8080/second.html`],
app: {
name: "google-chrome",
arguments: ["--incognito", "--new-window"],
},
},
},
};
transportMode
(i.e.transportMode.client
/transportMode.server
options) were removed in favor ofclient.webSocketTransport
andwebSocketServer
:
v3:
module.exports = {
transportMode: "ws",
};
module.exports = {
transportMode: {
client: require.resolve("./CustomClient"),
server: require.resolve("./CustomServer"),
},
};
v4:
module.exports = {
devServer: {
// webSocketServer: 'sockjs',
webSocketServer: "ws",
},
};
module.exports = {
devServer: {
client: {
webSocketTransport: require.resolve("./CustomClient"),
},
webSocketServer: require.resolve("./CustomServer"),
},
};
-
(
webpack-dev-middleware
)[https://github.com/webpack/webpack-dev-middleware] was update to v5. -
All options can be set via CLI, don't forget if you need to override option from configuration(s) you should use
reset
flag, i.e.--static-reset --static my-directory
-
Many CLI options were renamed in favor of the above change, please use
webpack serve --help
to get a list of them. -
The
stdin
option was removed in favor of--watch-options-stdin
. -
injectClient
andinjectHot
were removed in favor of manual setup entries.injectClient: false
was replaced withclient: false
:
v3:
module.exports = { devServer: { injectClient: false, }, };
v4:
module.exports = { devServer: { client: false, }, };
injectHot: false
is now assumed whenhot: false
is used:
v3:
module.exports = { devServer: { injectHot: false, }, };
v4:
module.exports = { devServer: { hot: false, }, };
-
The
sockWrite
public method was renamed tosendMessage
. -
The
profile
option was removed in favorProfilingPlugin
. -
The
addDevServerEntrypoints
method was removed in favor of manual configuration.v4:
const webpack = require("webpack"); const DevServer = require("webpack-dev-server"); const config = { entry: [ // Runtime code for hot module replacement "webpack/hot/dev-server.js", // Dev server client for web socket transport, hot and live reload logic "webpack-dev-server/client/index.js?hot=true&live-reload=true", // Your entry "./src/entry.js", ], plugin: [ // Plugin for hot module replacement new webpack.HotModuleReplacementPlugin(), ], }; const compiler = webpack(config); // `hot` and `client` options are disabled because we added them manually const server = new DevServer({ hot: false, client: false }, compiler); (async () => { await server.start(); console.log("Running"); })();
-
constructor
arguments were changed, the first argument is dev server options, the second is compilerv3:
const devServerOptions = { host: "127.0.0.1", port: 8080 }; const devServer = new Server(compiler, devServerOptions);
v4:
const devServerOptions = { host: "127.0.0.1", port: 8080 }; const devServer = new Server(devServerOptions, compiler);
-
listen
method is deprecated in favor asyncstart
orstartCallback
methodsv3:
const devServerOptions = { host: "127.0.0.1", port: 8080 }; const devServer = new Server(compiler, devServerOptions); devServer.listen(devServerOptions.host, devServerOptions.port, () => { console.log("Running"); });
v4:
const devServerOptions = { host: "127.0.0.1", port: 8080 }; const devServer = new Server(devServerOptions, compiler); (async () => { await devServer.start(); console.log("Running"); })();
const devServerOptions = { host: "127.0.0.1", port: 8080 }; const devServer = new Server(devServerOptions, compiler); devServer.startCallback(() => { console.log("Running"); });
-
close
method is deprecated in favor asyncstop
orstopCallback
methodsv3:
const devServerOptions = { host: "127.0.0.1", port: 8080 }; const devServer = new Server(compiler, devServerOptions); devServer.listen(devServerOptions.host, devServerOptions.port, () => { console.log("Running"); devServer.close(() => { console.log("Closed"); }); });
v4:
const devServerOptions = { host: "127.0.0.1", port: 8080 }; const devServer = new Server(devServerOptions, compiler); (async () => { await devServer.start(); console.log("Running"); await devServer.stop(); console.log("Closed"); })();
const devServerOptions = { host: "127.0.0.1", port: 8080 }; const devServer = new Server(devServerOptions, compiler); devServer.startCallback(() => { console.log("Running"); devServer.stopCallback(() => { console.log("Closed"); }); });
- Added the
setupExitSignals
option, it takes a boolean and iftrue
(default on CLI), the server will close and exit the process onSIGINT
andSIGTERM
. - Print a warning if the
host
/port
option and thehost
/port
argument passed toserver.listen()
are different. - Allowed to disable web socket server using
webSocketServer: false
. - Added the
watchFiles
option, now you can reload server on file changes, for example{ watchFiles: ["src/**/*.php", "public/**/*"] }
. - You can specify multiple targets and browsers for the open option, i.e.
{ open: { target: ['/my-page', '/my-other-page'], app: ['google-chrome', '--incognito'] } }
, also you can use{ open: { target: '<url>', app: ['google-chrome', '--incognito'] } }
to open default URL in multiple browsers. - Support
bonjour
options. - The
headers
option can beFunction
type. - Overlay can be closed in browser.
- The
allowedHosts
option can beauto
or custom string with your domain (i.e. default value). - The
static
option can be disabled usingstatic: false
. - Added async
start
andstop
methods to API - Added
startCallback
andstopCallback
methods to API - Migrate on built-in
webpack
logger.
- Compatibility with the
target
option (you can usetarget: ['web', 'es5']
). publicPath: auto
is now working out of box.- No problems with the
target
option anymore, you can remove workaround (i.e.target: 'web'
for webpack v5). - Fix
webpack-dev-server
binary, i.e.webpack server
andwebpack-dev-server
will work identically. - Empty and multiple entries support.
- IPv6 supported.
chokidar
was updated.- Respect the
client.logging
option for HMR logging. - Show plugin name in progress log.
- Use value of the
infrastructureLogging.level
option by default forclient.logging
. - Allow to pass options without the
target
option for theproxy
options. - Support lazy compilation.
There are a lot of other bug fixes.
-
Compatibility with
IE11
/IE10
/IE9
:- For
IE11
/IE10
you need polyfillfetch()
andPromise
, example:
module.exports = { entry: { entry: ["whatwg-fetch", "core-js/features/promise", "./entry.js"], }, };
- For
IE9
you need polyfillfetch()
andPromise
and usesockjs
for communications (becauseWebSocket
is not supported), example:
module.exports = { entry: { entry: ["whatwg-fetch", "core-js/features/promise", "./entry.js"], }, devServer: { webSocketServer: "sockjs", }, };
IE8 is not supported, sorry
- For
-
Change in Node.js API:
- If you're using dev-server through the Node.js API, the options in devServer will be ignored. Pass the options as a first parameter instead:
v3:
new WebpackDevServer(compiler, {...})
v4:
new WebpackDevServer({...}, compiler)
- See here for an example of how to use
webpack-dev-server
through the Node.js API.