Gathering detailed insights and metrics for webpack-dev-middleware
Gathering detailed insights and metrics for webpack-dev-middleware
Gathering detailed insights and metrics for webpack-dev-middleware
Gathering detailed insights and metrics for webpack-dev-middleware
koa-webpack-dev-middleware
webpack dev middleware for koa
webpack-lru-middleware
Augments webpack-dev-middleware with a lazy LRU cache for entrypoints
browsersync-webpack-plugin
Combines BrowserSync, webpack-dev-middleware, and webpack-hot-middleware into one ezpz plugin.
webpack-isomorphic-dev-middleware
The webpack-dev-middleware, but for isomorphic applications.
A development middleware for webpack
npm install webpack-dev-middleware
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
2,500 Stars
1,536 Commits
376 Forks
34 Watching
6 Branches
173 Contributors
Updated on 26 Nov 2024
Minified
Minified + Gzipped
JavaScript (100%)
Cumulative downloads
Total Downloads
Last day
-3.2%
3,899,566
Compared to previous day
Last week
2.8%
20,355,096
Compared to previous week
Last month
11.4%
84,748,754
Compared to previous month
Last year
-4.8%
959,229,457
Compared to previous year
1
43
An express-style development middleware for use with webpack bundles and allows for serving of the files emitted from webpack. This should be used for development only.
Some of the benefits of using this middleware include:
First thing's first, install the module:
1npm install webpack-dev-middleware --save-dev
[!WARNING]
We do not recommend installing this module globally.
1const webpack = require("webpack"); 2const middleware = require("webpack-dev-middleware"); 3const compiler = webpack({ 4 // webpack options 5}); 6const express = require("express"); 7const app = express(); 8 9app.use( 10 middleware(compiler, { 11 // webpack-dev-middleware options 12 }), 13); 14 15app.listen(3000, () => console.log("Example app listening on port 3000!"));
See below for an example of use with fastify.
Name | Type | Default | Description |
---|---|---|---|
methods | Array | [ 'GET', 'HEAD' ] | Allows to pass the list of HTTP request methods accepted by the middleware |
headers | Array|Object|Function | undefined | Allows to pass custom HTTP headers on each request. |
index | boolean|string | index.html | If false (but not undefined ), the server will not respond to requests to the root URL. |
mimeTypes | Object | undefined | Allows to register custom mime types or extension mappings. |
mimeTypeDefault | string | undefined | Allows to register a default mime type when we can't determine the content type. |
etag | boolean| "weak"| "strong" | undefined | Enable or disable etag generation. |
lastModified | boolean | undefined | Enable or disable Last-Modified header. Uses the file system's last modified value. |
cacheControl | boolean|number|string|Object | undefined | Enable or disable setting Cache-Control response header. |
cacheImmutable | boolean\ | undefined | Enable or disable setting Cache-Control: public, max-age=31536000, immutable response header for immutable assets. |
publicPath | string | undefined | The public path that the middleware is bound to. |
stats | boolean|string|Object | stats (from a configuration) | Stats options object or preset name. |
serverSideRender | boolean | undefined | Instructs the module to enable or disable the server-side rendering mode. |
writeToDisk | boolean|Function | false | Instructs the module to write files to the configured location on disk as specified in your webpack configuration. |
outputFileSystem | Object | memfs | Set the default file system which will be used by webpack as primary destination of generated files. |
modifyResponseData | Function | undefined | Allows to set up a callback to change the response data. |
The middleware accepts an options
Object. The following is a property reference for the Object.
Type: Array
Default: [ 'GET', 'HEAD' ]
This property allows a user to pass the list of HTTP request methods accepted by the middleware**.
Type: Array|Object|Function
Default: undefined
This property allows a user to pass custom HTTP headers on each request.
eg. { "X-Custom-Header": "yes" }
or
1webpackDevMiddleware(compiler, { 2 headers: () => { 3 return { 4 "Last-Modified": new Date(), 5 }; 6 }, 7});
or
1webpackDevMiddleware(compiler, {
2 headers: (req, res, context) => {
3 res.setHeader("Last-Modified", new Date());
4 },
5});
or
1webpackDevMiddleware(compiler, { 2 headers: [ 3 { 4 key: "X-custom-header", 5 value: "foo", 6 }, 7 { 8 key: "Y-custom-header", 9 value: "bar", 10 }, 11 ], 12});
or
1webpackDevMiddleware(compiler, { 2 headers: () => [ 3 { 4 key: "X-custom-header", 5 value: "foo", 6 }, 7 { 8 key: "Y-custom-header", 9 value: "bar", 10 }, 11 ], 12});
Type: Boolean|String
Default: index.html
If false
(but not undefined
), the server will not respond to requests to the root URL.
Type: Object
Default: undefined
This property allows a user to register custom mime types or extension mappings.
eg. mimeTypes: { phtml: 'text/html' }
.
Please see the documentation for mime-types
for more information.
Type: String
Default: undefined
This property allows a user to register a default mime type when we can't determine the content type.
Type: "weak" | "strong"
Default: undefined
Enable or disable etag generation. Boolean value use
Type: Boolean
Default: undefined
Enable or disable Last-Modified
header. Uses the file system's last modified value.
Type: Boolean | Number | String | { maxAge?: number, immutable?: boolean }
Default: undefined
Depending on the setting, the following headers will be generated:
Boolean
- Cache-Control: public, max-age=31536000000
Number
- Cache-Control: public, max-age=YOUR_NUMBER
String
- Cache-Control: YOUR_STRING
{ maxAge?: number, immutable?: boolean }
- Cache-Control: public, max-age=YOUR_MAX_AGE_or_31536000000
, also , immutable
can be added if you set the immutable
option to true
Enable or disable setting Cache-Control
response header.
Type: Boolean
Default: undefined
Enable or disable setting Cache-Control: public, max-age=31536000, immutable
response header for immutable assets (i.e. asset with a hash like image.a4c12bde.jpg
).
Immutable assets are assets that have their hash in the file name therefore they can be cached, because if you change their contents the file name will be changed.
Take preference over the cacheControl
option if the asset was defined as immutable.
Type: String
Default: output.publicPath
(from a configuration)
The public path that the middleware is bound to.
Best Practice: use the same publicPath
defined in your webpack config. For more information about publicPath
, please see the webpack documentation.
Type: Boolean|String|Object
Default: stats
(from a configuration)
Stats options object or preset name.
Type: Boolean
Default: undefined
Instructs the module to enable or disable the server-side rendering mode. Please see Server-Side Rendering for more information.
Type: Boolean|Function
Default: false
If true
, the option will instruct the module to write files to the configured location on disk as specified in your webpack
config file.
Setting writeToDisk: true
won't change the behavior of the webpack-dev-middleware
, and bundle files accessed through the browser will still be served from memory.
This option provides the same capabilities as the WriteFilePlugin
.
This option also accepts a Function
value, which can be used to filter which files are written to disk.
The function follows the same premise as Array#filter
in which a return value of false
will not write the file, and a return value of true
will write the file to disk. eg.
1const webpack = require("webpack"); 2const configuration = { 3 /* Webpack configuration */ 4}; 5const compiler = webpack(configuration); 6 7middleware(compiler, { 8 writeToDisk: (filePath) => { 9 return /superman\.css$/.test(filePath); 10 }, 11});
Type: Object
Default: memfs
Set the default file system which will be used by webpack as primary destination of generated files. This option isn't affected by the writeToDisk option.
You have to provide .join()
and mkdirp
method to the outputFileSystem
instance manually for compatibility with webpack@4
.
This can be done simply by using path.join
:
1const webpack = require("webpack"); 2const path = require("path"); 3const myOutputFileSystem = require("my-fs"); 4const mkdirp = require("mkdirp"); 5 6myOutputFileSystem.join = path.join.bind(path); // no need to bind 7myOutputFileSystem.mkdirp = mkdirp.bind(mkdirp); // no need to bind 8 9const compiler = webpack({ 10 /* Webpack configuration */ 11}); 12 13middleware(compiler, { outputFileSystem: myOutputFileSystem });
Allows to set up a callback to change the response data.
1const webpack = require("webpack"); 2const configuration = { 3 /* Webpack configuration */ 4}; 5const compiler = webpack(configuration); 6 7middleware(compiler, { 8 // Note - if you send the `Range` header you will have `ReadStream` 9 // Also `data` can be `string` or `Buffer` 10 modifyResponseData: (req, res, data, byteLength) => { 11 // Your logic 12 // Don't use `res.end()` or `res.send()` here 13 return { data, byteLength }; 14 }, 15});
webpack-dev-middleware
also provides convenience methods that can be use to
interact with the middleware at runtime:
close(callback)
Instructs webpack-dev-middleware
instance to stop watching for file changes.
callback
Type: Function
Required: No
A function executed once the middleware has stopped watching.
1const express = require("express"); 2const webpack = require("webpack"); 3const compiler = webpack({ 4 /* Webpack configuration */ 5}); 6const middleware = require("webpack-dev-middleware"); 7const instance = middleware(compiler); 8 9const app = new express(); 10 11app.use(instance); 12 13setTimeout(() => { 14 // Says `webpack` to stop watch changes 15 instance.close(); 16}, 1000);
invalidate(callback)
Instructs webpack-dev-middleware
instance to recompile the bundle, e.g. after a change to the configuration.
callback
Type: Function
Required: No
A function executed once the middleware has invalidated.
1const express = require("express"); 2const webpack = require("webpack"); 3const compiler = webpack({ 4 /* Webpack configuration */ 5}); 6const middleware = require("webpack-dev-middleware"); 7const instance = middleware(compiler); 8 9const app = new express(); 10 11app.use(instance); 12 13setTimeout(() => { 14 // After a short delay the configuration is changed and a banner plugin is added to the config 15 new webpack.BannerPlugin("A new banner").apply(compiler); 16 17 // Recompile the bundle with the banner plugin: 18 instance.invalidate(); 19}, 1000);
waitUntilValid(callback)
Executes a callback function when the compiler bundle is valid, typically after compilation.
callback
Type: Function
Required: No
A function executed when the bundle becomes valid. If the bundle is valid at the time of calling, the callback is executed immediately.
1const express = require("express"); 2const webpack = require("webpack"); 3const compiler = webpack({ 4 /* Webpack configuration */ 5}); 6const middleware = require("webpack-dev-middleware"); 7const instance = middleware(compiler); 8 9const app = new express(); 10 11app.use(instance); 12 13instance.waitUntilValid(() => { 14 console.log("Package is in a valid state"); 15});
getFilenameFromUrl(url)
Get filename from URL.
url
Type: String
Required: Yes
URL for the requested file.
1const express = require("express"); 2const webpack = require("webpack"); 3const compiler = webpack({ 4 /* Webpack configuration */ 5}); 6const middleware = require("webpack-dev-middleware"); 7const instance = middleware(compiler); 8 9const app = new express(); 10 11app.use(instance); 12 13instance.waitUntilValid(() => { 14 const filename = instance.getFilenameFromUrl("/bundle.js"); 15 16 console.log(`Filename is ${filename}`); 17});
Since output.publicPath
and output.filename
/output.chunkFilename
can be dynamic, it's not possible to know which files are webpack bundles (and they public paths) and which are not, so we can't avoid blocking requests.
But there is a solution to avoid it - mount the middleware to a non-root route, for example:
1const webpack = require("webpack"); 2const middleware = require("webpack-dev-middleware"); 3const compiler = webpack({ 4 // webpack options 5}); 6const express = require("express"); 7const app = express(); 8 9// Mounting the middleware to the non-root route allows avoids this. 10// Note - check your public path, if you want to handle `/dist/`, you need to setup `output.publicPath` to `/` value. 11app.use( 12 "/dist/", 13 middleware(compiler, { 14 // webpack-dev-middleware options 15 }), 16); 17 18app.listen(3000, () => console.log("Example app listening on port 3000!"));
Note: this feature is experimental and may be removed or changed completely in the future.
In order to develop an app using server-side rendering, we need access to the
stats
, which is
generated with each build.
With server-side rendering enabled, webpack-dev-middleware
sets the stats
to res.locals.webpack.devMiddleware.stats
and the filesystem to res.locals.webpack.devMiddleware.outputFileSystem
before invoking the next middleware,
allowing a developer to render the page body and manage the response to clients.
Note: Requests for bundle files will still be handled by
webpack-dev-middleware
and all requests will be pending until the build
process is finished with server-side rendering enabled.
Example Implementation:
1const express = require("express"); 2const webpack = require("webpack"); 3const compiler = webpack({ 4 /* Webpack configuration */ 5}); 6const isObject = require("is-object"); 7const middleware = require("webpack-dev-middleware"); 8 9const app = new express(); 10 11// This function makes server rendering of asset references consistent with different webpack chunk/entry configurations 12function normalizeAssets(assets) { 13 if (isObject(assets)) { 14 return Object.values(assets); 15 } 16 17 return Array.isArray(assets) ? assets : [assets]; 18} 19 20app.use(middleware(compiler, { serverSideRender: true })); 21 22// The following middleware would not be invoked until the latest build is finished. 23app.use((req, res) => { 24 const { devMiddleware } = res.locals.webpack; 25 const outputFileSystem = devMiddleware.outputFileSystem; 26 const jsonWebpackStats = devMiddleware.stats.toJson(); 27 const { assetsByChunkName, outputPath } = jsonWebpackStats; 28 29 // Then use `assetsByChunkName` for server-side rendering 30 // For example, if you have only one main chunk: 31 res.send(` 32<html> 33 <head> 34 <title>My App</title> 35 <style> 36 ${normalizeAssets(assetsByChunkName.main) 37 .filter((path) => path.endsWith(".css")) 38 .map((path) => outputFileSystem.readFileSync(path.join(outputPath, path))) 39 .join("\n")} 40 </style> 41 </head> 42 <body> 43 <div id="root"></div> 44 ${normalizeAssets(assetsByChunkName.main) 45 .filter((path) => path.endsWith(".js")) 46 .map((path) => `<script src="${path}"></script>`) 47 .join("\n")} 48 </body> 49</html> 50 `); 51});
We do our best to keep Issues in the repository focused on bugs, features, and needed modifications to the code for the module. Because of that, we ask users with general support, "how-to", or "why isn't this working" questions to try one of the other support channels that are available.
Your first-stop-shop for support for webpack-dev-server should by the excellent documentation for the module. If you see an opportunity for improvement of those docs, please head over to the webpack.js.org repo and open a pull request.
From there, we encourage users to visit the webpack discussions and
talk to the fine folks there. If your quest for answers comes up dry in chat,
head over to StackOverflow and do a quick search or open a new
question. Remember; It's always much easier to answer questions that include your
webpack.config.js
and relevant files!
If you're twitter-savvy you can tweet #webpack with your question and someone should be able to reach out and lend a hand.
If you have discovered a :bug:, have a feature suggestion, or would like to see a modification, please feel free to create an issue on Github. Note: The issue template isn't optional, so please be sure not to remove it, and please fill it out completely.
Examples of use with other servers will follow here.
1const connect = require("connect"); 2const http = require("http"); 3const webpack = require("webpack"); 4const webpackConfig = require("./webpack.config.js"); 5const devMiddleware = require("webpack-dev-middleware"); 6 7const compiler = webpack(webpackConfig); 8const devMiddlewareOptions = { 9 /** Your webpack-dev-middleware-options */ 10}; 11const app = connect(); 12 13app.use(devMiddleware(compiler, devMiddlewareOptions)); 14 15http.createServer(app).listen(3000);
1const http = require("http"); 2const Router = require("router"); 3const finalhandler = require("finalhandler"); 4const webpack = require("webpack"); 5const webpackConfig = require("./webpack.config.js"); 6const devMiddleware = require("webpack-dev-middleware"); 7 8const compiler = webpack(webpackConfig); 9const devMiddlewareOptions = { 10 /** Your webpack-dev-middleware-options */ 11}; 12const router = Router(); 13 14router.use(devMiddleware(compiler, devMiddlewareOptions)); 15 16var server = http.createServer((req, res) => { 17 router(req, res, finalhandler(req, res)); 18}); 19 20server.listen(3000);
1const express = require("express"); 2const webpack = require("webpack"); 3const webpackConfig = require("./webpack.config.js"); 4const devMiddleware = require("webpack-dev-middleware"); 5 6const compiler = webpack(webpackConfig); 7const devMiddlewareOptions = { 8 /** Your webpack-dev-middleware-options */ 9}; 10const app = express(); 11 12app.use(devMiddleware(compiler, devMiddlewareOptions)); 13 14app.listen(3000, () => console.log("Example app listening on port 3000!"));
1const Koa = require("koa"); 2const webpack = require("webpack"); 3const webpackConfig = require("./webpack.simple.config"); 4const middleware = require("webpack-dev-middleware"); 5 6const compiler = webpack(webpackConfig); 7const devMiddlewareOptions = { 8 /** Your webpack-dev-middleware-options */ 9}; 10const app = new Koa(); 11 12app.use(middleware.koaWrapper(compiler, devMiddlewareOptions)); 13 14app.listen(3000);
1const Hapi = require("@hapi/hapi"); 2const webpack = require("webpack"); 3const webpackConfig = require("./webpack.config.js"); 4const devMiddleware = require("webpack-dev-middleware"); 5 6const compiler = webpack(webpackConfig); 7const devMiddlewareOptions = {}; 8 9(async () => { 10 const server = Hapi.server({ port: 3000, host: "localhost" }); 11 12 await server.register({ 13 plugin: devMiddleware.hapiPlugin(), 14 options: { 15 // The `compiler` option is required 16 compiler, 17 ...devMiddlewareOptions, 18 }, 19 }); 20 21 await server.start(); 22 23 console.log("Server running on %s", server.info.uri); 24})(); 25 26process.on("unhandledRejection", (err) => { 27 console.log(err); 28 process.exit(1); 29});
Fastify interop will require the use of fastify-express
instead of middie
for providing middleware support. As the authors of fastify-express
recommend, this should only be used as a stopgap while full Fastify support is worked on.
1const fastify = require("fastify")(); 2const webpack = require("webpack"); 3const webpackConfig = require("./webpack.config.js"); 4const devMiddleware = require("webpack-dev-middleware"); 5 6const compiler = webpack(webpackConfig); 7const devMiddlewareOptions = { 8 /** Your webpack-dev-middleware-options */ 9}; 10 11(async () => { 12 await fastify.register(require("@fastify/express")); 13 await fastify.use(devMiddleware(compiler, devMiddlewareOptions)); 14 await fastify.listen(3000); 15})();
1import webpack from "webpack"; 2import { serve } from "@hono/node-server"; 3import { Hono } from "hono"; 4import devMiddleware from "webpack-dev-middleware"; 5import webpackConfig from "./webpack.config.js"; 6 7const compiler = webpack(webpackConfig); 8const devMiddlewareOptions = { 9 /** Your webpack-dev-middleware-options */ 10}; 11 12const app = new Hono(); 13 14app.use(devMiddleware.honoWrapper(compiler, devMiddlewareOptions)); 15 16serve(app);
Please take a moment to read our contributing guidelines if you haven't yet done so.
The latest stable version of the package.
Stable Version
3
7.4/10
Summary
Path traversal in webpack-dev-middleware
Affected Versions
<= 5.3.3
Patched Versions
5.3.4
7.4/10
Summary
Path traversal in webpack-dev-middleware
Affected Versions
>= 6.0.0, < 6.1.2
Patched Versions
6.1.2
7.4/10
Summary
Path traversal in webpack-dev-middleware
Affected Versions
>= 7.0.0, < 7.1.0
Patched Versions
7.1.0
Reason
no dangerous workflow patterns detected
Reason
GitHub workflow tokens follow principle of least privilege
Details
Reason
28 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
security policy file detected
Details
Reason
4 existing vulnerabilities detected
Details
Reason
dependency not pinned by hash detected -- score normalized to 5
Details
Reason
Found 0/1 approved changesets -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
project is not fuzzed
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Score
Last Scanned on 2024-11-18
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More