Skip to content

Commit

Permalink
feat: allow proxy.bypass to be an async function
Browse files Browse the repository at this point in the history
  • Loading branch information
chenjiahan committed Feb 3, 2025
1 parent e136112 commit b5a8db1
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 11 deletions.
2 changes: 2 additions & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,9 @@ export type {
PostCSSPlugin,
PreviewOptions,
PreconnectOption,
ProxyBypass,
ProxyConfig,
ProxyFilter,
ProxyOptions,
PrintUrls,
PublicDir,
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/server/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ export const createProxyMiddleware = async (

const middleware: Middleware = async (req, res, next) => {
const bypassUrl =
typeof opts.bypass === 'function' ? opts.bypass(req, res, opts) : null;
typeof opts.bypass === 'function'
? await opts.bypass(req, res, opts)
: null;

if (bypassUrl === false) {
res.statusCode = 404;
Expand Down
5 changes: 4 additions & 1 deletion packages/core/src/types/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,9 @@ export type ProxyBypass = (
req: IncomingMessage,
res: ServerResponse,
proxyOptions: ProxyOptions,
) => string | undefined | null | boolean;
) => MaybePromise<string | undefined | null | boolean>;

export type { ProxyFilter };

export type ProxyOptions = HttpProxyOptions & {
/**
Expand All @@ -274,6 +276,7 @@ export type ProxyOptions = HttpProxyOptions & {
* - Return `true` to continue processing the request without proxy.
* - Return `false` to produce a 404 error for the request.
* - Return a path to serve from, instead of continuing to proxy the request.
* - Return a Promise to handle the request asynchronously.
*/
bypass?: ProxyBypass;
/**
Expand Down
14 changes: 9 additions & 5 deletions website/docs/en/config/server/proxy.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ type ProxyOptions = HttpProxyOptions & {
req: IncomingMessage,
res: ServerResponse,
proxyOptions: ProxyOptions,
) => string | undefined | null | boolean;
) => MaybePromise<string | undefined | null | boolean>;
context?: Filter;
};

Expand All @@ -104,21 +104,25 @@ In addition to the `http-proxy-middleware` option, Rsbuild also support the `byp

### bypass

Bypass the proxy based on the return value of a function.
Sometimes you don't want to proxy everything. It is possible to bypass the proxy based on the return value of a `bypass` function.

In the function, you get access to the request, response, and proxy options.

- Return `null` or `undefined` to continue processing the request with proxy.
- Return `true` to continue processing the request without proxy.
- Return `false` to produce a 404 error for the request.
- Return a path to serve from, instead of continuing to proxy the request.
- Return a Promise to handle the request asynchronously.

```js
// custom bypass
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 configure like this:

```ts title="rsbuild.config.ts"
export default {
server: {
proxy: {
'/api': {
target: 'http://localhost:3000',
bypass: function (req, res, proxyOptions) {
bypass(req, res, proxyOptions) {
if (req.headers.accept.indexOf('html') !== -1) {
console.log('Skipping proxy for browser request.');
return '/index.html';
Expand Down
12 changes: 8 additions & 4 deletions website/docs/zh/config/server/proxy.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ type ProxyOptions = HttpProxyOptions & {
req: IncomingMessage,
res: ServerResponse,
proxyOptions: ProxyOptions,
) => string | undefined | null | boolean;
) => MaybePromise<string | undefined | null | boolean>;
context?: Filter;
};

Expand All @@ -104,21 +104,25 @@ type ProxyConfig =

### bypass

根据函数的返回值绕过代理。
一些情况下,你可能不想代理所有请求。可以通过 `bypass` 函数来绕过代理。

在函数中,你可以访问到 request、response 和 proxy 选项。

- 返回 `null``undefined` 会继续用代理处理请求。
- 返回 `true` 会跳过代理继续处理请求。
- 返回 `false` 会返回 404 错误。
- 返回一个具体的服务路径,将会使用此路径替代原请求路径。
- 返回一个 Promise,可以异步处理请求。

例如,你可能希望对浏览器请求返回 HTML 页面,而对 API 请求则进行代理转发。你可以这样配置:

```js
// 自定义 bypass 方法
export default {
server: {
proxy: {
'/api': {
target: 'http://localhost:3000',
bypass: function (req, res, proxyOptions) {
bypass(req, res, proxyOptions) {
if (req.headers.accept.indexOf('html') !== -1) {
console.log('Skipping proxy for browser request.');
return '/index.html';
Expand Down

0 comments on commit b5a8db1

Please sign in to comment.