Skip to content
Merged
21 changes: 13 additions & 8 deletions examples/general/proxy-advanced/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,24 @@ module.exports = setup({
context: __dirname,
entry: "./app.js",
devServer: {
proxy: {
"/api": {
port: 8080,
static: {
directory: ".",
},
proxy: [
{
context: "/api/nope",
router: () => "http://localhost:8080",
pathRewrite: () => "/bypass.html",
},
{
context: "/api",
target: "http://jsonplaceholder.typicode.com/",
changeOrigin: true,
pathRewrite: {
"^/api": "",
},
bypass(req) {
if (req.url === "/api/nope") {
return "/bypass.html";
}
},
},
},
],
},
});
7 changes: 4 additions & 3 deletions examples/proxy/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@ module.exports = setup({
onBeforeSetupMiddleware: async () => {
await listenProxyServer();
},
proxy: {
"/proxy": {
proxy: [
{
context: "/proxy",
target: "http://localhost:5000",
},
},
],
},
});
73 changes: 8 additions & 65 deletions lib/Server.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
const os = require("node:os");
const path = require("node:path");
const url = require("node:url");
const util = require("node:util");
const fs = require("graceful-fs");
const ipaddr = require("ipaddr.js");
const { validate } = require("schema-utils");
Expand Down Expand Up @@ -138,14 +137,7 @@ const schema = require("./options.json");
*/

/**
* @callback ByPass
* @param {Request} req
* @param {Response} res
* @param {ProxyConfigArrayItem} proxyConfig
*/

/**
* @typedef {{ path?: HttpProxyMiddlewareOptionsFilter | undefined, context?: HttpProxyMiddlewareOptionsFilter | undefined } & { bypass?: ByPass } & HttpProxyMiddlewareOptions } ProxyConfigArrayItem
* @typedef {{ path?: HttpProxyMiddlewareOptionsFilter | undefined, context?: HttpProxyMiddlewareOptionsFilter | undefined } & HttpProxyMiddlewareOptions } ProxyConfigArrayItem
*/

/**
Expand Down Expand Up @@ -2148,29 +2140,13 @@ class Server {
* @returns {RequestHandler | undefined} request handler
*/
const getProxyMiddleware = (proxyConfig) => {
// It is possible to use the `bypass` method without a `target` or `router`.
// However, the proxy middleware has no use in this case, and will fail to instantiate.
if (proxyConfig.target) {
const context = proxyConfig.context || proxyConfig.path;

return createProxyMiddleware({
...proxyConfig,
pathFilter: /** @type {string} */ (context),
});
}
const context =
proxyConfig.context || proxyConfig.path || proxyConfig.pathFilter;

if (proxyConfig.router) {
return createProxyMiddleware(proxyConfig);
}

// TODO improve me after drop `bypass` to always generate error when configuration is bad
if (!proxyConfig.bypass) {
util.deprecate(
() => {},
`Invalid proxy configuration:\n\n${JSON.stringify(proxyConfig, null, 2)}\n\nThe use of proxy object notation as proxy routes has been removed.\nPlease use the 'router' or 'context' options. Read more at https://github.com/chimurai/http-proxy-middleware/tree/v2.0.6#http-proxy-middleware-options`,
"DEP_WEBPACK_DEV_SERVER_PROXY_ROUTES_ARGUMENT",
)();
}
return createProxyMiddleware({
...proxyConfig,
pathFilter: /** @type {string} */ (context),
});
};

/**
Expand Down Expand Up @@ -2236,40 +2212,7 @@ class Server {
}
}

// - Check if we have a bypass function defined
// - In case the bypass function is defined we'll retrieve the
// bypassUrl from it otherwise bypassUrl would be null
// TODO remove in the next major in favor `context` and `router` options
const isByPassFuncDefined = typeof proxyConfig.bypass === "function";
if (isByPassFuncDefined) {
util.deprecate(
() => {},
"Using the 'bypass' option is deprecated. Please use the 'router' or 'context' options. Read more at https://github.com/chimurai/http-proxy-middleware/tree/v2.0.6#http-proxy-middleware-options",
"DEP_WEBPACK_DEV_SERVER_PROXY_BYPASS_ARGUMENT",
)();
}
const bypassUrl = isByPassFuncDefined
? await /** @type {ByPass} */ (proxyConfig.bypass)(
req,
res,
proxyConfig,
)
: null;

if (typeof bypassUrl === "boolean") {
// skip the proxy
res.statusCode = 404;
req.url = "";
next();
} else if (typeof bypassUrl === "string") {
// byPass to that url
req.url = bypassUrl;
next();
} else if (proxyMiddleware) {
return proxyMiddleware(req, res, next);
} else {
next();
}
return proxyMiddleware(req, res, next);
};

middlewares.push({
Expand Down
44 changes: 44 additions & 0 deletions migration-v6.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ This document serves as a migration guide for `webpack-dev-server@6.0.0`.
## ⚠ Breaking Changes

- Minimum supported `Node.js` version is `20.9.0`.
- Minimum supported `webpack` version is `5.101.0`.
- Support for **SockJS** in the WebSocket transport has been removed. Now, only **native WebSocket** is supported, or **custom** client and server implementations can be used.
- The options for passing to the `proxy` have changed. Please refer to the [http-proxy-middleware migration guide](https://github.com/chimurai/http-proxy-middleware/blob/master/MIGRATION.md) for details.
- Remove support for the spdy server type. Use the http2 server type instead; however, since Express does not work correctly with it, a custom server (e.g., Connect or Hono) should be used.
Expand Down Expand Up @@ -51,3 +52,46 @@ This document serves as a migration guide for `webpack-dev-server@6.0.0`.
```js
const ip = Server.findIp("v4", true);
```

- The bypass function in the proxy configuration was removed. Use the `pathFilter` and `router` for similar functionality. See the example below.

v4:

```js
module.exports = {
// ...
devServer: {
proxy: [
{
context: "/api",
bypass(req, res, proxyOptions) {
if (req.url.startsWith("/api/special")) {
return "/special.html";
}
},
},
],
},
};
```

v5:

```js
module.exports = {
// ...
devServer: {
proxy: [
{
pathFilter: "/api/special",
router: () => "http://localhost:3000", // Original Server
pathRewrite: () => "/special.html",
},
],
},
};
```

When `bypass` was used and that function returned a boolean, it would automatically result in a `404` request. This can’t be achieved in a similar way now, or, if it returned a string, you can do what was done in the example above.

`bypass` also allowed sending data; this can no longer be done. If you really need to do it, you’d have to create a new route in the proxy that sends the same data, or alternatively create a new route on the main server and, following the example above, send the data you wanted.
Loading
Loading