webpack-dev-server can be used to quickly develop an application. See the development guide to get started.
This page describes the options that affect the behavior of webpack-dev-server (short: dev-server).
devServer
object
This set of options is picked up by webpack-dev-server and can be used to change its behavior in various ways. Here's a simple example that gzips and serves everything from our dist/
directory in the project root:
webpack.config.js
var path = require('path');
module.exports = {
//...
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
port: 9000
}
};
When the server is started, there will be a message prior to the list of resolved modules:
http://localhost:9000/
webpack output is served from /build/
Content not from webpack is served from /path/to/dist/
that will give some background on where the server is located and what it's serving.
If you're using dev-server through the Node.js API, the options in devServer
will be ignored. Pass the options as a second parameter instead: new WebpackDevServer(compiler, {...})
. See here for an example of how to use webpack-dev-server through the Node.js API.
devServer.after
function (app, server, compiler)
Provides the ability to execute custom middleware after all other middleware internally within the server.
webpack.config.js
module.exports = {
//...
devServer: {
after: function(app, server, compiler) {
// do fancy stuff
}
}
};
devServer.allowedHosts
[string]
This option allows you to whitelist services that are allowed to access the dev server.
webpack.config.js
module.exports = {
//...
devServer: {
allowedHosts: [
'host.com',
'subdomain.host.com',
'subdomain2.host.com',
'host2.com'
]
}
};
Mimicking django's ALLOWED_HOSTS
, a value beginning with .
can be used as a subdomain wildcard. .host.com
will match host.com
, www.host.com
, and any other subdomain of host.com
.
webpack.config.js
module.exports = {
//...
devServer: {
// this achieves the same effect as the first example
// with the bonus of not having to update your config
// if new subdomains need to access the dev server
allowedHosts: [
'.host.com',
'host2.com'
]
}
};
To use this option with the CLI pass the --allowed-hosts
option a comma-delimited string.
webpack serve --entry ./entry/file --output-path ./output/path --allowed-hosts .host.com,host2.com
devServer.before
function (app, server, compiler)
Provides the ability to execute custom middleware prior to all other middleware internally within the server. This could be used to define custom handlers, for example:
webpack.config.js
module.exports = {
//...
devServer: {
before: function(app, server, compiler) {
app.get('/some/path', function(req, res) {
res.json({ custom: 'response' });
});
}
}
};
devServer.bonjour
boolean = false
This option broadcasts the server via ZeroConf networking on start
webpack.config.js
module.exports = {
//...
devServer: {
bonjour: true
}
};
Usage via the CLI
webpack serve --bonjour
devServer.clientLogLevel
string = 'info': 'silent' | 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'none' | 'warning'
When using inline mode, the console in your DevTools will show you messages e.g. before reloading, before an error or when Hot Module Replacement is enabled.
devServer.clientLogLevel
may be too verbose, you can turn logging off by setting it to 'silent'
.
webpack.config.js
module.exports = {
//...
devServer: {
clientLogLevel: 'silent'
}
};
Usage via the CLI
webpack serve --client-log-level silent
devServer.compress
boolean
Enable gzip compression for everything served:
webpack.config.js
module.exports = {
//...
devServer: {
compress: true
}
};
Usage via the CLI
webpack serve --compress
devServer.contentBase
boolean: false
string
[string]
number
Tell the server where to serve content from. This is only necessary if you want to serve static files. devServer.publicPath
will be used to determine where the bundles should be served from, and takes precedence.
By default, it will use your current working directory to serve content. To disable contentBase
set it to false
.
webpack.config.js
const path = require('path');
module.exports = {
//...
devServer: {
contentBase: path.join(__dirname, 'public')
}
};
It is also possible to serve from multiple directories in case you want to serve static content at multiple URLs with contentBasePublicPath
:
webpack.config.js
const path = require('path');
module.exports = {
//...
devServer: {
contentBase: [path.join(__dirname, 'public'), path.join(__dirname, 'assets')]
}
};
Usage via the CLI
webpack serve --content-base ./path/to/content/dir
devServer.contentBasePublicPath
string = '/'
[string]
Tell the server at what URL to serve devServer.contentBase
static content. If there was a file assets/manifest.json
, it would be served at /serve-content-base-at-this-url/manifest.json
webpack.config.js
const path = require('path');
module.exports = {
//...
devServer: {
contentBase: path.join(__dirname, 'assets'),
contentBasePublicPath: '/serve-content-base-at-this-url'
}
};
Provide an array of strings in case you have multiple static folders set in contentBase
.
webpack.config.js
module.exports = {
//...
devServer: {
contentBase: [contentBasePublic, contentBaseOther],
contentBasePublicPath: [
contentBasePublicPath,
contentBasePublicOtherPath
]
}
};
devServer.disableHostCheck
boolean
When set to true
this option bypasses host checking. THIS IS NOT RECOMMENDED as apps that do not check the host are vulnerable to DNS rebinding attacks.
webpack.config.js
module.exports = {
//...
devServer: {
disableHostCheck: true
}
};
Usage via the CLI
webpack serve --disable-host-check
devServer.filename
πstring
This option lets you reduce the compilations in lazy mode. By default in lazy mode, every request results in a new compilation. With filename
, it's possible to only compile when a certain file is requested.
If output.filename
is set to 'bundle.js'
and devServer.filename
is used like this:
webpack.config.js
module.exports = {
//...
output: {
filename: 'bundle.js'
},
devServer: {
lazy: true,
filename: 'bundle.js'
}
};
It will now only compile the bundle when /bundle.js
is requested.
devServer.headers
πobject
Adds headers to all responses:
webpack.config.js
module.exports = {
//...
devServer: {
headers: {
'X-Custom-Foo': 'bar'
}
}
};
devServer.historyApiFallback
boolean = false
object
When using the HTML5 History API, the index.html
page will likely have to be served in place of any 404
responses. Enable devServer.historyApiFallback
by setting it to true
:
webpack.config.js
module.exports = {
//...
devServer: {
historyApiFallback: true
}
};
By passing an object this behavior can be controlled further using options like rewrites
:
webpack.config.js
module.exports = {
//...
devServer: {
historyApiFallback: {
rewrites: [
{ from: /^\/$/, to: '/views/landing.html' },
{ from: /^\/subpage/, to: '/views/subpage.html' },
{ from: /./, to: '/views/404.html' }
]
}
}
};
When using dots in your path (common with Angular), you may need to use the disableDotRule
:
webpack.config.js
module.exports = {
//...
devServer: {
historyApiFallback: {
disableDotRule: true
}
}
};
Usage via the CLI
webpack serve --history-api-fallback
For more options and information, see the connect-history-api-fallback documentation.
devServer.host
string = 'localhost'
Specify a host to use. If you want your server to be accessible externally, specify it like this:
webpack.config.js
module.exports = {
//...
devServer: {
host: '0.0.0.0'
}
};
Usage via the CLI
webpack serve --host 0.0.0.0
devServer.hot
boolean
Enable webpack's Hot Module Replacement feature:
webpack.config.js
module.exports = {
//...
devServer: {
hot: true
}
};
devServer.hotOnly
boolean
Enables Hot Module Replacement (see devServer.hot
) without page refresh as a fallback in case of build failures.
webpack.config.js
module.exports = {
//...
devServer: {
hotOnly: true
}
};
Usage via the CLI
webpack serve --hot only
devServer.http2
boolean = false
Serve over HTTP/2 using spdy. This option is ignored for Node 10.0.0 and above, as spdy is broken for those versions. The dev server will migrate over to Node's built-in HTTP/2 once Express supports it.
If devServer.http2
is not explicitly set to false
, it will default to true
when devServer.https
is enabled. When devServer.http2
is enabled but the server is unable to serve over HTTP/2, the server defaults to HTTPS.
HTTP/2 with a self-signed certificate:
webpack.config.js
module.exports = {
//...
devServer: {
http2: true
}
};
Provide your own certificate using the https option:
webpack.config.js
module.exports = {
//...
devServer: {
http2: true,
https: {
key: fs.readFileSync('/path/to/server.key'),
cert: fs.readFileSync('/path/to/server.crt'),
ca: fs.readFileSync('/path/to/ca.pem'),
}
}
};
Usage via CLI
webpack serve --http2
To pass your own certificate via CLI, use the following options
webpack serve --http2 --key ./path/to/server.key --cert ./path/to/server.crt --cacert ./path/to/ca.pem
devServer.https
boolean
object
By default, dev-server will be served over HTTP. It can optionally be served over HTTP/2 with HTTPS:
webpack.config.js
module.exports = {
//...
devServer: {
https: true
}
};
With the above setting, a self-signed certificate is used, but you can provide your own:
webpack.config.js
module.exports = {
//...
devServer: {
https: true,
key: fs.readFileSync('/path/to/server.key'),
cert: fs.readFileSync('/path/to/server.crt'),
ca: fs.readFileSync('/path/to/ca.pem'),
}
};
This object is passed straight to Node.js HTTPS module, so see the HTTPS documentation for more information.
Usage via the CLI
webpack serve --https
To pass your own certificate via the CLI use the following options
webpack serve --https --key ./path/to/server.key --cert ./path/to/server.crt --cacert ./path/to/ca.pem
devServer.index
string
The filename that is considered the index file.
webpack.config.js
module.exports = {
//...
devServer: {
index: 'index.html'
}
};
devServer.info
- CLI onlyboolean
Output cli information. It is enabled by default.
webpack serve --info false
devServer.injectClient
boolean = false
function (compilerConfig) => boolean
Tells devServer
to inject a client. Setting devServer.injectClient
to true
will result in always injecting a client. It is possible to provide a function to inject conditionally:
module.exports = {
//...
devServer: {
injectClient: (compilerConfig) => compilerConfig.name === 'only-include'
}
};
devServer.injectHot
boolean = false
function (compilerConfig) => boolean
Tells devServer
to inject a Hot Module Replacement. Setting devServer.injectHot
to true
will result in always injecting. It is possible to provide a function to inject conditionally:
module.exports = {
//...
devServer: {
hot: true,
injectHot: (compilerConfig) => compilerConfig.name === 'only-include'
}
};
devServer.inline
boolean
Toggle between the dev-server's two different modes. By default, the application will be served with inline mode enabled. This means that a script will be inserted in your bundle to take care of live reloading, and build messages will appear in the browser console.
It is also possible to use iframe mode, which uses an <iframe>
under a notification bar with messages about the build. To switch to iframe mode:
webpack.config.js
module.exports = {
//...
devServer: {
inline: false
}
};
Usage via the CLI
webpack serve --inline false
devServer.lazy
πboolean
When devServer.lazy
is enabled, the dev-server will only compile the bundle when it gets requested. This means that webpack will not watch any file changes. We call this lazy mode.
webpack.config.js
module.exports = {
//...
devServer: {
lazy: true
}
};
Usage via the CLI
webpack serve --lazy
devServer.liveReload
boolean = true
By default, the dev-server will reload/refresh the page when file changes are detected. devServer.hot
option must be disabled or devServer.watchContentBase
option must be enabled in order for liveReload
to take effect. Disable devServer.liveReload
by setting it to false
:
webpack.config.js
module.exports = {
//...
devServer: {
liveReload: false
}
};
Usage via the CLI
webpack serve --no-live-reload
devServer.mimeTypes
πobject
Allows dev-server to register custom mime types. The object is passed to the underlying webpack-dev-middleware
. See documentation for usage notes.
webpack.config.js
module.exports = {
//...
devServer: {
mimeTypes: { 'text/html': ['phtml'] }
}
};
devServer.noInfo
πboolean = false
Tells dev-server to suppress messages like the webpack bundle information. Errors and warnings will still be shown.
webpack.config.js
module.exports = {
//...
devServer: {
noInfo: true
}
};
devServer.onListening
function (server)
Provides an option to execute a custom function when webpack-dev-server
starts listening for connections on a port.
webpack.config.js
module.exports = {
//...
devServer: {
onListening: function(server) {
const port = server.listeningApp.address().port;
console.log('Listening on port:', port);
}
}
};
devServer.open
boolean = false
string
object
Tells dev-server to open the browser after server had been started. Set it to true
to open your default browser.
webpack.config.js
module.exports = {
//...
devServer: {
open: true
}
};
Provide browser name to use instead of the default one:
webpack.config.js
module.exports = {
//...
devServer: {
open: 'Google Chrome'
}
};
If you want to use flags when opening the browser like opening an incognito window (--incognito
flag), you can set open
to an object. The object accepts all open options, app
property must be an array. The first element in the array must be the browser name and the other following elements are the flags you want to use. For example:
webpack.config.js
module.exports = {
//...
devServer: {
open: {
app: ['Google Chrome', '--incognito', '--other-flag']
}
}
};
Usage via the CLI
webpack serve --open 'Google Chrome'
devServer.openPage
string
[string]
Specify a page to navigate to when opening the browser.
webpack.config.js
module.exports = {
//...
devServer: {
openPage: '/different/page'
}
};
Usage via the CLI
webpack serve --open-page /different/page
If you wish to specify multiple pages to open in the browser.
webpack.config.js
module.exports = {
//...
devServer: {
openPage: ['/different/page1', '/different/page2']
}
};
Usage via the CLI
webpack serve --open-page /different/page1,/different/page2
devServer.overlay
boolean = false
object: { errors boolean = false, warnings boolean = false }
Shows a full-screen overlay in the browser when there are compiler errors or warnings. If you want to show only compiler errors:
webpack.config.js
module.exports = {
//...
devServer: {
overlay: true
}
};
If you want to show warnings as well as errors:
webpack.config.js
module.exports = {
//...
devServer: {
overlay: {
warnings: true,
errors: true
}
}
};
devServer.pfx
string
When used via the CLI, a path to an SSL .pfx file. If used in options, it should be the bytestream of the .pfx file.
webpack.config.js
module.exports = {
//...
devServer: {
pfx: './path/to/file.pfx'
}
};
Usage via the CLI
webpack serve --pfx ./path/to/file.pfx
devServer.pfxPassphrase
string
The passphrase to a SSL PFX file.
webpack.config.js
module.exports = {
//...
devServer: {
pfxPassphrase: 'passphrase'
}
};
Usage via the CLI
webpack serve --pfx-passphrase passphrase
devServer.port
number
Specify a port number to listen for requests on:
webpack.config.js
module.exports = {
//...
devServer: {
port: 8080
}
};
Usage via the CLI
webpack serve --port 8080
devServer.proxy
object
[object, function]
Proxying some URLs can be useful when you have a separate API backend development server and you want to send API requests on the same domain.
The dev-server makes use of the powerful http-proxy-middleware package. Check out its documentation for more advanced usages. Note that some of http-proxy-middleware
's features do not require a target
key, e.g. its router
feature, but you will still need to include a target
key in your configuration here, otherwise webpack-dev-server
won't pass it along to http-proxy-middleware
).
With a backend on localhost:3000
, you can use this to enable proxying:
webpack.config.js
module.exports = {
//...
devServer: {
proxy: {
'/api': 'http://localhost:3000'
}
}
};
A request to /api/users
will now proxy the request to http://localhost:3000/api/users
.
If you don't want /api
to be passed along, we need to rewrite the path:
webpack.config.js
module.exports = {
//...
devServer: {
proxy: {
'/api': {
target: 'http://localhost:3000',
pathRewrite: {'^/api' : ''}
}
}
}
};
A backend server running on HTTPS with an invalid certificate will not be accepted by default. If you want to, modify your configuration like this:
webpack.config.js
module.exports = {
//...
devServer: {
proxy: {
'/api': {
target: 'https://other-server.example.com',
secure: false
}
}
}
};
Sometimes you don't want to proxy everything. It is possible to bypass the proxy based on the return value of a function.
In the function you get access to the request, response, and proxy options.
null
or undefined
to continue processing the request with proxy.false
to produce a 404 error for the request.E.g. for a browser request, you want to serve an HTML page, but for an API request you want to proxy it. You could do something like this:
webpack.config.js
module.exports = {
//...
devServer: {
proxy: {
'/api': {
target: 'http://localhost:3000',
bypass: function(req, res, proxyOptions) {
if (req.headers.accept.indexOf('html') !== -1) {
console.log('Skipping proxy for browser request.');
return '/index.html';
}
}
}
}
}
};
If you want to proxy multiple, specific paths to the same target, you can use an array of one or more objects with a context
property:
webpack.config.js
module.exports = {
//...
devServer: {
proxy: [{
context: ['/auth', '/api'],
target: 'http://localhost:3000',
}]
}
};
Note that requests to root won't be proxied by default. To enable root proxying, the devServer.index
option should be specified as a falsy value:
webpack.config.js
module.exports = {
//...
devServer: {
index: '', // specify to enable root proxying
host: '...',
contentBase: '...',
proxy: {
context: () => true,
target: 'http://localhost:1234'
}
}
};
The origin of the host header is kept when proxying by default, you can set changeOrigin
to true
to override this behaviour. It is useful in some cases like using name-based virtual hosted sites.
webpack.config.js
module.exports = {
//...
devServer: {
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true
}
}
}
};
devServer.progress
- CLI onlyboolean
Output running progress to console.
webpack serve --progress
devServer.public
string
When using inline mode and you're proxying dev-server, the inline client script does not always know where to connect to. It will try to guess the URL of the server based on window.location
, but if that fails you'll need to use this.
For example, the dev-server is proxied by nginx, and available on myapp.test
:
webpack.config.js
module.exports = {
//...
devServer: {
public: 'myapp.test:80'
}
};
Usage via the CLI
webpack serve --public myapp.test:80
devServer.publicPath
πstring = '/'
The bundled files will be available in the browser under this path.
Imagine that the server is running under http://localhost:8080
and output.filename
is set to bundle.js
. By default the devServer.publicPath
is '/'
, so your bundle is available as http://localhost:8080/bundle.js
.
Change devServer.publicPath
to put bundle under specific directory:
webpack.config.js
module.exports = {
//...
devServer: {
publicPath: '/assets/'
}
};
The bundle will now be available as http://localhost:8080/assets/bundle.js
.
It is also possible to use a full URL.
webpack.config.js
module.exports = {
//...
devServer: {
publicPath: 'http://localhost:8080/assets/'
}
};
The bundle will also be available as http://localhost:8080/assets/bundle.js
.
devServer.quiet
πboolean
With devServer.quiet
enabled, nothing except the initial startup information will be written to the console. This also means that errors or warnings from webpack are not visible.
webpack.config.js
module.exports = {
//...
devServer: {
quiet: true
}
};
Usage via the CLI
webpack serve --quiet
devServer.serveIndex
boolean = true
Tells dev-server to use serveIndex
middleware when enabled.
serveIndex
middleware generates directory listings on viewing directories that don't have an index.html file.
module.exports = {
//...
devServer: {
serveIndex: true
}
};
devServer.setup
function (app, server)
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:
webpack.config.js
module.exports = {
//...
devServer: {
setup: function(app, server) {
app.get('/some/path', function(req, res) {
res.json({ custom: 'response' });
});
}
}
};
devServer.sockHost
string
Tells clients connected to devServer
to use provided socket host.
webpack.config.js
module.exports = {
//...
devServer: {
sockHost: 'myhost.test'
}
};
devServer.sockPath
string = '/sockjs-node'
The path at which to connect to the reloading socket.
webpack.config.js
module.exports = {
//...
devServer: {
sockPath: '/socket',
}
};
Usage via the CLI
webpack serve --sock-path /socket
devServer.sockPort
number
string
Tells clients connected to devServer
to use provided socket port.
webpack.config.js
module.exports = {
//...
devServer: {
sockPort: 8080
}
};
devServer.staticOptions
object
It is possible to configure advanced options for serving static files from contentBase
. See the Express documentation for the possible options.
webpack.config.js
module.exports = {
//...
devServer: {
staticOptions: {
redirect: false
}
}
};
devServer.stats
πstring: 'none' | 'errors-only' | 'minimal' | 'normal' | 'verbose'
object
This option lets you precisely control what bundle information gets displayed. This can be a nice middle ground if you want some bundle information, but not all of it.
To show only errors in your bundle:
webpack.config.js
module.exports = {
//...
devServer: {
stats: 'errors-only'
}
};
For more information, see the stats documentation.
devServer.stdin
- CLI onlyboolean
This option closes the server when stdin ends.
webpack serve --stdin
devServer.transportMode
string = 'sockjs': 'sockjs' | 'ws'
object
This option allows us either to choose the current devServer
transport mode for client/server individually or to provide custom client/server implementation. This allows to specify how browser or other client communicates with the devServer
.
The current default mode is 'sockjs'
. This mode uses SockJS-node as a server, and SockJS-client on the client.
'ws'
mode will become the default mode in the next major devServer
version. This mode uses ws as a server, and native WebSockets on the client.
Use 'ws'
mode:
module.exports = {
//...
devServer: {
transportMode: 'ws'
}
};
devServer.transportMode.client
string
path
To create a custom client implementation, create a class that extends BaseClient
.
Using path to CustomClient.js
, a custom WebSocket client implementation, along with the compatible 'ws'
server:
module.exports = {
//...
devServer: {
transportMode: {
client: require.resolve('./CustomClient'),
server: 'ws'
}
}
};
devServer.transportMode.server
string
path
function
To create a custom server implementation, create a class that extends BaseServer
.
Using path to CustomServer.js
, a custom WebSocket server implementation, along with the compatible 'ws'
client:
module.exports = {
//...
devServer: {
transportMode: {
client: 'ws',
server: require.resolve('./CustomServer')
}
}
};
Using class exported by CustomServer.js
, a custom WebSocket server implementation, along with the compatible 'ws'
client:
module.exports = {
//...
devServer: {
transportMode: {
client: 'ws',
server: require('./CustomServer')
}
}
};
Using custom, compatible WebSocket client and server implementations:
module.exports = {
//...
devServer: {
transportMode: {
client: require.resolve('./CustomClient'),
server: require.resolve('./CustomServer')
}
}
};
devServer.useLocalIp
boolean
This option lets the browser open with your local IP.
webpack.config.js
module.exports = {
//...
devServer: {
useLocalIp: true
}
};
Usage via the CLI
webpack serve --use-local-ip
devServer.watchContentBase
boolean
Tell dev-server to watch the files served by the devServer.contentBase
option. It is disabled by default. When enabled, file changes will trigger a full page reload.
webpack.config.js
module.exports = {
//...
devServer: {
watchContentBase: true
}
};
Usage via the CLI
webpack serve --watch-content-base
devServer.watchOptions
πobject
Control options related to watching the files.
webpack uses the file system to get notified of file changes. In some cases, this does not work. For example, when using Network File System (NFS). Vagrant also has a lot of problems with this. In these cases, use polling:
webpack.config.js
module.exports = {
//...
devServer: {
watchOptions: {
poll: true
}
}
};
If this is too heavy on the file system, you can change this to an integer to set the interval in milliseconds.
See WatchOptions for more options.
devServer.writeToDisk
πboolean = false
function (filePath) => boolean
Tells devServer
to write generated assets to the disk. The output is written to the output.path directory.
webpack.config.js
module.exports = {
//...
devServer: {
writeToDisk: true
}
};
Providing a Function
to devServer.writeToDisk
can be used for filtering. The function follows the same premise as Array#filter
in which a boolean return value tells if the file should be written to disk.
webpack.config.js
module.exports = {
//...
devServer: {
writeToDisk: (filePath) => {
return /superman\.css$/.test(filePath);
}
}
};
package.json
{
"scripts": "NODE_OPTIONS='--max-http-header-size=100000' webpack serve"
}