Hono 前后端分离系列 10:部署和生产架构
wxk1991 Lv5

Hono 前后端分离系列 10:部署和生产架构

前后端分离项目最后一定会回到一个问题:

1
怎么部署?

本地跑通只是第一步。

真正上线时,你要考虑:

1
2
3
4
5
6
7
8
前端放哪里?
API 放哪里?
域名怎么分?
环境变量怎么管?
跨域怎么配?
日志怎么看?
数据库在哪里?
回滚怎么做?

Hono 的优势是多运行时。

同一套核心 API 代码,可以跑在 Cloudflare Workers、Node.js、Bun、Deno、Vercel、Netlify 等环境。不同部署方式没有绝对好坏,关键是和项目形态匹配。


一、最推荐的轻量组合

如果是中小型前后端分离项目,我很喜欢这个组合:

1
2
3
4
5
前端:Cloudflare Pages
后端:Cloudflare Workers + Hono
数据库:D1 / 外部 Postgres
文件:R2
缓存:KV / Cache API

优点是:

  • 部署简单
  • 全球边缘节点
  • 不用维护服务器
  • Hono 和 Workers 适配自然
  • 小项目成本很低

Hono 官方 Cloudflare Workers 文档也强调,可以用 Wrangler 本地开发和发布,并通过 c.env 访问 Workers bindings。

如果你已经在用 Cloudflare,这套组合非常顺。


二、域名怎么设计

常见两种方式。

第一种,前端和 API 分不同子域名:

1
2
https://app.example.com
https://api.example.com

优点是边界清楚,部署独立。

缺点是要处理 CORS。

第二种,同域名不同路径:

1
2
https://example.com
https://example.com/api

优点是跨域问题少,cookie 更好处理。

缺点是路由、网关或平台配置要更小心。

如果你是纯 SPA + API,我通常会选:

1
app.example.com + api.example.com

如果你强依赖 cookie 登录,或者想减少跨域复杂度,可以考虑同域路径。


三、Cloudflare Workers 部署

一个基础 wrangler.jsonc

1
2
3
4
5
6
7
8
{
"name": "hono-api",
"main": "src/index.ts",
"compatibility_date": "2026-06-23",
"vars": {
"CORS_ORIGIN": "https://app.example.com"
}
}

Hono 入口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { Hono } from 'hono'

type Bindings = {
CORS_ORIGIN: string
JWT_SECRET: string
}

const app = new Hono<{ Bindings: Bindings }>()

app.get('/api/health', (c) => {
return c.json({ ok: true })
})

export default app

部署:

1
pnpm run deploy

敏感信息不要写到 vars 里提交。

用 Wrangler secret:

1
pnpm exec wrangler secret put JWT_SECRET

四、Node.js 部署

如果你需要传统服务器,也可以用 Node.js。

入口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import { serve } from '@hono/node-server'
import { Hono } from 'hono'

const app = new Hono()

app.get('/api/health', (c) => c.json({ ok: true }))

const server = serve({
fetch: app.fetch,
port: Number(process.env.PORT ?? 3000),
})

process.on('SIGTERM', () => {
server.close()
})

适合 Node.js 的场景:

  • 需要长连接或特殊 Node 能力
  • 已有服务器和运维体系
  • 使用传统数据库连接池
  • 要跑在 Docker / Kubernetes

适合 Workers 的场景:

  • 请求响应型 API
  • Serverless 优先
  • 希望少运维
  • 接近用户的边缘服务
  • 和 D1、KV、R2 集成

不要为了“高级”强行选边缘,也不要因为习惯就永远选服务器。


五、环境变量分层

至少分三套:

1
2
3
local
staging
production

常见变量:

1
2
3
4
5
CORS_ORIGIN
JWT_SECRET
DATABASE_URL
LOG_LEVEL
FEATURE_FLAGS

前端也有自己的变量:

1
VITE_API_BASE_URL

不要让前端构建时拿到后端 secret。

前端环境变量会被打进浏览器包里。任何 VITE_ 开头的变量,都应该默认视为公开信息。


六、生产中间件清单

上线前,Hono API 至少考虑这些中间件:

1
2
3
4
5
6
7
8
9
CORS
secureHeaders
requestId
logger
bodyLimit
timeout
JWT / Bearer Auth
onError
notFound

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import { cors } from 'hono/cors'
import { secureHeaders } from 'hono/secure-headers'
import { requestId } from 'hono/request-id'
import { bodyLimit } from 'hono/body-limit'

app.use('*', requestId())
app.use('*', secureHeaders())
app.use('/api/*', async (c, next) => {
const corsHandler = cors({
origin: c.env.CORS_ORIGIN,
})

return corsHandler(c, next)
})
app.use('/api/*', bodyLimit({ maxSize: 1024 * 1024 }))

app.notFound((c) => {
return c.json({
error: {
code: 'NOT_FOUND',
message: '接口不存在',
},
}, 404)
})

app.onError((err, c) => {
console.error(err)
return c.json({
error: {
code: 'INTERNAL_SERVER_ERROR',
message: '服务器内部错误',
},
}, 500)
})

注意 c.env.CORS_ORIGIN 只能在请求上下文里读取,所以这里用一层 middleware 包起来,根据当前环境创建 cors handler。


七、发布前检查清单

上线前我会检查:

1
2
3
4
5
6
7
8
9
10
生产 CORS origin 是否正确
JWT_SECRET 是否为强随机值
接口错误是否不返回 stack
请求体大小是否有限制
数据库迁移是否执行
前端 API 地址是否指向生产
日志里是否有 requestId
健康检查是否可访问
404 和 500 是否统一
回滚方式是否明确

这张清单比“能部署成功”更重要。

能部署成功只说明平台接受了你的代码。

能稳定运行,才说明你准备好了生产环境。


八、最后的建议

Hono 的部署选择很多。

不要从平台开始选,要从项目需求开始选:

1
2
3
4
5
轻量 API、低运维、全球访问:Cloudflare Workers
传统服务、连接池、长任务:Node.js
前端静态资源:Pages / Vercel / Netlify
同域体验优先:前端和 API 走同域路径
边界清楚优先:app 子域 + api 子域

前后端分离不是部署成两个地址就完了。

真正的生产架构,要把域名、环境变量、安全、日志、数据库、回滚都想清楚。

Hono 让 API 层足够轻,但生产环境不能轻率。


参考资料