服务端与 Nitro
每个 Nuxt 应用背后都有 Nitro —— 负责 SSR、API 路由、中间件、部署预设的 HTTP 引擎。server/ 目录下的一切都跑在 Nitro 上,Vite 不参与。
Nitro 的能力
- 构建出一个
.output/目录,能运行在所有 JS 运行时。 - 15+ 部署预设(Node、Vercel、Netlify、Cloudflare Workers、AWS Lambda、Deno……)。
- 基于
h3的 HTTP 原语 —— 小、快、可移植。 - 通过
routeRules做混合渲染(SSR / ISR / SWR / 预渲染 / CSR)。 - 文件式 API 路由、中间件、插件。
目录布局
server/
├── api/ # /api/* 接口
│ ├── posts.get.ts
│ └── posts.post.ts
├── routes/ # 自定义路由
│ └── sitemap.xml.ts
├── middleware/ # 每个请求都会跑
└── plugins/ # Nitro 插件(钩子、长连接)
HMR 与自动导入机制跟 Vue 层一致。
API 路由
文件名后缀映射 HTTP 方法:
// server/api/posts.get.ts
export default defineEventHandler(async () => {
return await db.posts.findMany()
})
// server/api/posts.post.ts
export default defineEventHandler(async (event) => {
const body = await readBody<{ title: string }>(event)
const post = await db.posts.create({ data: body })
return post
})
可以返回字符串、可 JSON 序列化对象、Response 或 ReadableStream,Nitro 负责序列化。
动态参数用方括号:
// server/api/posts/[id].get.ts
export default defineEventHandler((event) => {
const id = event.context.params!.id
return db.posts.findUnique({ where: { id: Number(id) } })
})
自定义路由(非 API)
想要根路径的 /sitemap.xml、/healthz?放 server/routes/:
// server/routes/healthz.ts
export default defineEventHandler(() => 'ok')
服务端中间件
在所有 API handler 之前,每个服务端请求都会跑:
// server/middleware/request-id.ts
export default defineEventHandler((event) => {
event.context.requestId = crypto.randomUUID()
})
通过 event.context 往下游传值最方便。
Nitro 插件
挂到服务端生命周期上做日志、数据库连接池、定时任务等:
// server/plugins/db.ts
import { prisma } from '~~/server/utils/prisma'
export default defineNitroPlugin((nitro) => {
nitro.hooks.hook('close', async () => {
await prisma.$disconnect()
})
})
h3 常用工具
Nuxt / Nitro 内置的这些工具又快又兼容 Edge:
export default defineEventHandler(async (event) => {
const body = await readBody(event) // 解析 body
const query = getQuery(event) // 解析 ?query
const headers = getRequestHeaders(event) // 读取 headers
setResponseStatus(event, 201) // 设置状态码
setResponseHeader(event, 'x-custom', '1') // 设置响应头
return { ok: true }
})
错误
用 createError 抛结构化错误:
throw createError({ status: 404, statusText: 'Post Not Found' })
Nitro 会转成正确的 HTTP 响应(面向 HTML 请求还会渲染错误页)。
通过 routeRules 做混合渲染
SSR / ISR / 预渲染 / CSR 的策略都放在 routeRules 里:
export default defineNuxtConfig({
routeRules: {
'/': { prerender: true }, // 构建期静态化
'/blog/**': { swr: 3600 }, // SWR 1 小时
'/api/public/*': { cache: { maxAge: 300 } },
'/admin/**': { ssr: false }, // 只 CSR
'/old': { redirect: { to: '/new', statusCode: 301 } },
},
})
Nitro 会把这些规则翻译成各平台原生能力:Cloudflare Workers 用 Cache API,Vercel 用 ISR,Node 用内存缓存。
部署相关
部署预设常见几个:
export default defineNuxtConfig({
nitro: {
preset: 'node-server', // 也可 'vercel'、'netlify'、'cloudflare-pages' 等
},
})
详见“部署”那一章 —— 这里只要记住 server/ 里的东西都会随应用一起进入你选的运行时。
Checklist
- 数据库连接放 Nitro 插件里,每个进程一个连接池。
- 横切关注点(请求 ID、鉴权)用
server/middleware/。 - 渲染策略能用
routeRules就用,别自己写轮子。 - 抛错用
createError,不要手写状态码。 - 纯数据逻辑抽到
server/utils/,它们也会被自动导入。
至此你就拥有了一个完整的全栈 Nuxt 应用:前端 Vue + 后端 Nitro,都在同一个仓库里。