This document serves as a migration guide for [email protected].
webpack-dev-serverv3 andwebpack-dev-serverv4 automatically applyHotModuleReplacementPluginplugin when you sethot: true, so please check you don't haveHotModuleReplacementPluginin yourpluginsif you havehot: true/hot: "only"webpack-dev-serverv3 andwebpack-dev-serverv4 automatically injectwebpack/hot/dev-serverin yourentryoption when you sethot: true(except when you useinjectHotfor webpack-dev-server v3), please check you don't havewebpack/hot/dev-serverin yourentryoptionwebpack-dev-serverv3 andwebpack-dev-serverv4 automatically injectwebpack-dev-server/client/index.jsin yourentryoption (except when you useinjectClientfor webpack-dev-server v3), please check you don't havewebpack-dev-server/client/index.jsin yourentryoption
- Minimum supported
Node.jsversion is12.13.0. - Minimum supported
webpackversion is4.37.0(but we recommend usingwebpack >= v5.0.0). - Minimum compatible
webpack-cliversion is4.7.0. - The
hotOnlyoption 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
setupoption was removed without replacement. - The
beforeoption was renamed toonBeforeSetupMiddlewareand 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
afteroption was renamed toonAfterSetupMiddlewareand 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
featuresoption was removed in favoronBeforeSetupMiddlewareandonAfterSetupMiddlewareoptions. - The
key,cert,pfx,pfx-passphrase,cacert,caandrequestCertoptions were moved tohttpsoptions, 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
compressoption is nowtrueby default. filenameandlazyoptions were removed in favor experiments.lazyCompilation.- The
inline(iframelive mode) option was removed without replacement. log,logLevel,logTime,quiet,noInfo, andreporteroptions were removed without replacement, now we use built-in logger.- The
useLocalIpoption 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/portoptions can't benullor empty string, please usehost: 'local-ip'orport: 'auto'.- the
warnoption was removed in favor of ignoreWarnings fs,index,mimeTypes,publicPath,serverSideRender,stats, andwriteToDisk(related towebpack-dev-middleware) were moved todevMiddlewareoption.
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/clientLogLeveloption were moved to theclientoption:
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, andsockPortoptions were removed in favorclient.webSocketURLoption:
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 theoverlayoption ) is nowtrueby default.contentBase/contentBasePublicPath/serveIndex/watchContentBase/watchOptions/staticOptionsoptions were moved tostaticoption:
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
staticoption ispath.resolve(process.cwd(), 'public')directory and enabled by default. static.watchis enabled by default.- The
socketoption was renamed toipc(also supportsstringtype, i.e. path to unix socket):
v3:
module.exports = {
devServer: {
socket: true,
},
};v4:
module.exports = {
devServer: {
ipc: true,
},
};- The
disableHostCheckoption was removed in favorallowedHosts: 'all':
v3:
module.exports = {
devServer: {
disableHostCheck: true,
},
};v4:
module.exports = {
devServer: {
allowedHosts: "all",
},
};openandopenPageoptions were unionized in favor of theopenoption:
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.serveroptions) were removed in favor ofclient.webSocketTransportandwebSocketServer:
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
resetflag, i.e.--static-reset --static my-directory -
Many CLI options were renamed in favor of the above change, please use
webpack serve --helpto get a list of them. -
The
stdinoption was removed in favor of--watch-options-stdin. -
injectClientandinjectHotwere removed in favor of manual setup entries.injectClient: falsewas replaced withclient: false:
v3:
module.exports = { devServer: { injectClient: false, }, };
v4:
module.exports = { devServer: { client: false, }, };
injectHot: falseis now assumed whenhot: falseis used:
v3:
module.exports = { devServer: { injectHot: false, }, };
v4:
module.exports = { devServer: { hot: false, }, };
-
The
sockWritepublic method was renamed tosendMessage. -
The
profileoption was removed in favorProfilingPlugin. -
The
addDevServerEntrypointsmethod 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"); })();
-
constructorarguments 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);
-
listenmethod is deprecated in favor asyncstartorstartCallbackmethodsv3:
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"); });
-
closemethod is deprecated in favor asyncstoporstopCallbackmethodsv3:
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
setupExitSignalsoption, it takes a boolean and iftrue(default on CLI), the server will close and exit the process onSIGINTandSIGTERM. - Print a warning if the
host/portoption and thehost/portargument passed toserver.listen()are different. - Allowed to disable web socket server using
webSocketServer: false. - Added the
watchFilesoption, 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
bonjouroptions. - The
headersoption can beFunctiontype. - Overlay can be closed in browser.
- The
allowedHostsoption can beautoor custom string with your domain (i.e. default value). - The
staticoption can be disabled usingstatic: false. - Added async
startandstopmethods to API - Added
startCallbackandstopCallbackmethods to API - Migrate on built-in
webpacklogger.
- Compatibility with the
targetoption (you can usetarget: ['web', 'es5']). publicPath: autois now working out of box.- No problems with the
targetoption anymore, you can remove workaround (i.e.target: 'web'for webpack v5). - Fix
webpack-dev-serverbinary, i.e.webpack serverandwebpack-dev-serverwill work identically. - Empty and multiple entries support.
- IPv6 supported.
chokidarwas updated.- Respect the
client.loggingoption for HMR logging. - Show plugin name in progress log.
- Use value of the
infrastructureLogging.leveloption by default forclient.logging. - Allow to pass options without the
targetoption for theproxyoptions. - Support lazy compilation.
There are a lot of other bug fixes.
-
Compatibility with
IE11/IE10/IE9:- For
IE11/IE10you need polyfillfetch()andPromise, example:
module.exports = { entry: { entry: ["whatwg-fetch", "core-js/features/promise", "./entry.js"], }, };
- For
IE9you need polyfillfetch()andPromiseand usesockjsfor communications (becauseWebSocketis 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-serverthrough the Node.js API.