Skip to content

Commit bd37dcc

Browse files
committed
📃 docs(notes): 基于 vercel 边缘函数解决 vercel.json 配置的反向代理方案失效的新方案
1 parent d381d12 commit bd37dcc

File tree

8 files changed

+186
-2
lines changed

8 files changed

+186
-2
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
---
2+
order: 20
3+
---
4+
5+
# 基于 vercel 边缘函数解决 vercel.json 配置的反向代理方案失效的新方案
6+
7+
[之前的方案](./007-vercel-reverse-proxy.md)没用了。被迫用新的方案实现接口的反向代理。
8+
9+
## 无法在生产环境内给接口实现反向代理的旧方案
10+
11+
直接给 vercel.json 写配置,不能实现反向代理了。
12+
13+
::: details 无法实现反向代理的写法
14+
15+
<<< ./code/020/vercel.old-proxy.json
16+
17+
:::
18+
19+
## 基于 vercel 边缘函数实现的代理
20+
21+
首先阅读以下参考资料:
22+
23+
- [vercel](https://oorzc.cn/linux/其他配置/vercel部署项目.html#nodejs项目-跨域配置)
24+
- [Vercel 配置服务端代理](https://blog.csdn.net/u012961419/article/details/112369710)
25+
- [使用 Vercel 来部署静态页面并解决跨域问题](https://lsworl.github.io/2022/05/27/shi-yong-vercel-lai-bu-shu-jing-tai-ye-mian-bing-jie-jue-kua-yu-wen-ti/)
26+
- [Vercel 跨域处理方案](https://segmentfault.com/a/1190000042276351)
27+
- [vercel 配置跨域](https://yalisky.eu.org/blogs/2023/12/28/vercel配置跨域)
28+
29+
## `@ruan-cat/vercel-deploy-tool` 自有部署工具没有考虑到边缘计算函数的情况
30+
31+
我的项目普遍会包含至少一个主项目,一个文档项目,并且很多项目的仓库并不在 github 内,无法在 cloudflare 或 vercel 云平台内触发部署。故必须使用自己封装的库来完成部署。
32+
33+
本工具之前设计时,仅仅是为了准备上传静态文件。即使用 `vc build` 命令的特点,为项目准备好 `.vercel/output/static` 文件夹,随后上传到 vercel 平台。
34+
35+
上述方案是要求我们准备好[云函数的文件结构目录](https://github.com/vercel/examples/tree/main/build-output-api/serverless-functions)的,云函数目录要求满足 `.vercel/output/functions/index.func` 结构,目前我的工具没办法实现这个目录结构,而且识别与处理都很麻烦。
36+
37+
因此,我需要新的方式准备好云函数的文件目录。
38+
39+
## 使用 vite-plugin-vercel 插件生成云函数目录结构
40+
41+
很幸运能够找到这个插件,这个插件可以让 vite 项目的内容,生成出[Vercel Output API (v3)](https://vercel.com/docs/build-output-api)规范的目录结构。包括云函数。这就解决了上面的问题。
42+
43+
## 安装依赖 http-proxy-middleware
44+
45+
```bash
46+
pnpm i -P http-proxy-middleware
47+
```
48+
49+
我们要在产物内准备好能够被 vercel 平台识别的云函数,这个云函数是生产就绪的,所以要安装成生产环境依赖。先按照教程要求,准备好该代理工具。
50+
51+
## 新建云函数
52+
53+
按照 [vite-plugin-vercel](https://github.com/magne4000/vite-plugin-vercel/blob/v9/packages/vercel/README.md) 和上面参考资料的要求,在 vite 项目根目录内,新建 `_api\proxy.js` 云函数。
54+
55+
代码如下:
56+
57+
::: details \_api\proxy.js 云函数
58+
59+
<<< ./code/020/\_api-proxy.js
60+
61+
:::
62+
63+
### 云函数必须写在 `_api` 目录内
64+
65+
按照[文档要求](https://github.com/magne4000/vite-plugin-vercel/blob/v9/packages/vercel/README.md#simple-usage),为了避免重复构建和意外行为,需要将云函数写在 `_api` 目录内。
66+
67+
::: details 文档明确要求
68+
69+
![2025-06-15-17-26-56](https://gh-img-store.ruan-cat.com/img/2025-06-15-17-26-56.png)
70+
71+
:::
72+
73+
目前能诱发出来的意外情况是,http-proxy-middleware 在服务器内找不到,本地因为重复构建,导致依赖丢失。
74+
75+
::: details http-proxy-middleware 找不到
76+
77+
![2025-06-15-17-33-23](https://gh-img-store.ruan-cat.com/img/2025-06-15-17-33-23.png)
78+
79+
:::
80+
81+
## 在 vite.config.ts 内使用 vite-plugin-vercel 插件
82+
83+
::: details 使用插件
84+
85+
<<< ./code/020/vite.config.vercel.ts
86+
87+
:::
88+
89+
## 匹配接口路径到云函数
90+
91+
我们需要让满足特定前缀的后端接口,被代理到我们自写的代理中间件内。
92+
93+
如果我使用的是 vercel 平台的部署,那么在项目根目录内的 vercel.json 写以下内容即可。假设接口的反向代理前缀为: `/backend`
94+
95+
<<< ./code/020/vercel.new-proxy.json
96+
97+
一般情况下,做到这一步,就可以了。但是我的情况需要使用 Vercel Output API (v3)完成部署,没办法在被部署的产物内写入上述的配置。
98+
99+
只能稍微变通一下,在 vite-plugin-vercel 插件提供的 vercel 配置内,补全上述配置。
100+
101+
::: details 在 vite 内补全 vercel.json 配置
102+
103+
<<< ./code/020/vite.config.with-vercel.ts
104+
105+
:::
106+
107+
这样,vercel.json 的配置就能直接写入到本地的 `.vercel/output` 目录内,进而完成反向代理。
108+
109+
## 前端项目仍旧需要完成 vite 的反向代理配置
110+
111+
上述文章仅仅是说明在 vercel 平台内,给接口配置反向代理。项目本身也是需要配置 vite 的前端反向代理的。
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { createProxyMiddleware } from "http-proxy-middleware";
2+
3+
/** @see https://yalisky.eu.org/blogs/2023/12/28/vercel配置跨域 */
4+
export default async function handler(req, res) {
5+
// 判断请求路径是否以 '/backend' 开头,设置代理目标
6+
const target = req.url.startsWith("/backend") ? "被代理的接口baseUrl" : "";
7+
8+
console.log(" 在边缘请求内:req.url ", req.url);
9+
10+
if (target) {
11+
// 设置 CORS 头
12+
res.setHeader("Access-Control-Allow-Origin", "*");
13+
res.setHeader("Access-Control-Allow-Methods", "GET,HEAD,PUT,PATCH,POST,DELETE");
14+
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
15+
16+
// 创建代理并等待完成
17+
await new Promise((resolve) => {
18+
createProxyMiddleware({
19+
target,
20+
changeOrigin: true,
21+
pathRewrite: {
22+
"^/backend/": "/",
23+
},
24+
})(req, res, resolve);
25+
});
26+
} else {
27+
// 如果没有找到匹配的路径,返回 404
28+
res.statusCode = 404;
29+
res.end("Not Found");
30+
}
31+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"rewrites": [
3+
{
4+
"source": "/backend/(.*)",
5+
"destination": "/api/proxy"
6+
}
7+
]
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"rewrites": [
3+
{
4+
"source": "/api/:path*",
5+
"destination": "http://8.154.39.107:10001/:path*"
6+
}
7+
]
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { defineConfig } from "vite";
2+
import vercel from "vite-plugin-vercel";
3+
4+
export default defineConfig(({ mode }) => {
5+
return {
6+
plugins: [vercel()],
7+
};
8+
});
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { defineConfig } from "vite";
2+
export default defineConfig(({ mode }) => {
3+
return {
4+
/** @see https://github.com/magne4000/vite-plugin-vercel/tree/v9 */
5+
vercel: {
6+
rewrites: [
7+
// https://segmentfault.com/a/1190000042276351
8+
{ source: "/backend/(.*)", destination: "/api/proxy" },
9+
],
10+
},
11+
};
12+
});
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# vercel 反向代理问题
2+
3+
请阅读以下文章:
4+
5+
- [vercel 反向代理问题](../bug/007-vercel-reverse-proxy.md)
6+
- [基于 vercel 边缘函数解决 vercel.json 配置的反向代理方案失效的新方案](../bug/020-vercel-reverse-proxy.md)

docs/ruan-cat-notes/docs/vercel/use-github-actions-deploy-vercel-project/4.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
相比于之前冗长的 github action 配置,这次我自写了一个专门的部署工具,编写配置,交由 typescript 运行即可。运行函数即可完成部署。
44

5-
自写了一个名为 `@ruan-cat/vercel-deploy-tool` 的部署工具。
5+
自写了一个名为 [`@ruan-cat/vercel-deploy-tool`](https://github.com/ruan-cat/monorepo/tree/main/packages/vercel-deploy-tool) 的部署工具。
66

77
## 优化
88

@@ -14,4 +14,4 @@
1414
4. 不用编写冗长的 github action 来编排任务。
1515
5. 配置文件有完整的类型声明提示。
1616

17-
这里不介绍该工具的具体用法。应该阅读 readme 文档。
17+
这里不介绍该工具的具体用法。应该阅读 [readme](https://github.com/ruan-cat/monorepo/blob/main/packages/vercel-deploy-tool/README.md) 文档。

0 commit comments

Comments
 (0)