Skip to content

服务引擎 Nitro

Nitro 是 Nuxt 的服务端引擎,提供了跨平台的服务端运行时。它是让 Nuxt 成为"全栈框架"的核心——没有 Nitro,Nuxt 只是一个前端框架。

为什么需要了解 Nitro?

你想做的事Nitro 的角色
写 API 接口Nitro 提供 server/api/defineEventHandler
部署到不同平台Nitro 的"一次构建,处处部署"
用 Redis 缓存Nitro 的存储层(unstorage)
服务端启动时初始化Nitro 插件
每个 API 请求前做检查Nitro 中间件

你不需要"学 Nitro"

——Nitro 是 Nuxt 的内部引擎,你通过 Nuxt 的约定(server/ 目录)使用它。但了解 Nitro 的能力,能帮你更好地利用 Nuxt 的全栈特性。

Nitro 架构

text
                    ┌─────────────┐
                    │   Nuxt App  │
                    └──────┬──────┘

                    ┌──────▼──────┐
                    │    Nitro    │ ← 服务端引擎
                    └──────┬──────┘

              ┌────────────┼────────────┐
              │            │            │
        ┌─────▼────┐ ┌────▼────┐ ┌────▼────┐
        │   h3     │ │ unjs    │ │ Deploy  │
        │ (HTTP)   │ │ (工具链) │ │ (多平台) │
        └──────────┘ └─────────┘ └─────────┘

核心组成

组件说明你需要了解吗?
h3轻量级 HTTP 框架,处理请求/响应是——写 API 时用到的都是 h3 的 API
unjsJavaScript 工具链(ofetch、unstorage 等)了解即可
Rollup服务端代码打包不需要
unstorage跨平台存储层用缓存时了解

h3 是什么?

它是 Nitro 团队开发的 HTTP 框架,类似 Express,但更轻量、更快、原生支持 TypeScript。你在 server/ 目录下写的每个 API,底层都是 h3 在处理。

h3 框架

h3 是 Nitro 使用的 HTTP 框架,所有服务端代码都基于 h3 编写。

事件处理器

ts
// 每个 API 路由都是一个事件处理器
export default defineEventHandler((event) => {
  // event 是 H3Event 对象,包含请求的所有信息
  return { message: 'Hello' }
})

event 对象是什么?

它是 h3 对 HTTP 请求的封装,包含:

  • 请求方法(GET、POST 等)
  • 请求 URL
  • 请求头
  • 请求体
  • Cookie
  • 路由参数
  • 上下文(context)

所有的 readBodygetQuerygetRouterParam 等函数,都是从这个 event 对象中提取信息。

H3 请求工具

ts
// 读取请求体(POST/PUT 请求)
const body = await readBody(event)
// body: { name: 'Alice', email: 'alice@example.com' }

// 读取查询参数(?page=1&size=20)
const query = getQuery(event)
// query: { page: '1', size: '20' }  ← 注意:值都是 string 类型!

// 读取路由参数(/api/users/123)
const id = getRouterParam(event, 'id')
// id: '123'

// 读取请求头
const auth = getRequestHeader(event, 'authorization')

// 读取 Cookie
const cookies = parseCookies(event)
const token = getCookie(event, 'auth-token')

// 获取请求 URL
const url = getRequestURL(event)

// 设置响应状态码
setResponseStatus(event, 201)

// 设置响应头
setResponseHeader(event, 'x-custom', 'value')

// 发送重定向
await sendRedirect(event, '/new-page', 302)

INFO

getQuery 返回的值都是 string!

ts
const query = getQuery(event)
// ?page=1&size=20
// query.page 是 '1'(string),不是 1(number)
// 如果需要数字,手动转换:
const page = Number(query.page)

事件上下文

可以在中间件中设置 event.context,在后续处理器中访问:

ts
// server/middleware/auth.ts
export default defineEventHandler((event) => {
  // 从 Cookie 中获取 token,验证后把用户信息存入 context
  const token = getCookie(event, 'auth-token')
  if (token) {
    event.context.user = verifyToken(token)  // 自定义字段
  }
})

// server/api/me.ts
export default defineEventHandler((event) => {
  // 在 API 中直接使用中间件设置的数据
  return event.context.user
})

event.context 的作用

在不同中间件和 API 之间传递数据,避免重复计算。类似于 Express 的 req.xxx,但更规范。

INFO

类型安全:如果你使用了 event.context 建议扩展类型

ts
// server/types/index.ts
declare module 'h3' {
interface H3EventContext {
user?: { id: number; name: string }
}
}

通用部署

Nitro 最大的特点是一次构建,处处部署。通过预设(preset)支持多种部署目标:

ts
// nuxt.config.ts
export default defineNuxtConfig({
  nitro: {
    preset: 'node-server',  // 部署预设
  },
})

常用预设

预设说明适合场景
node-serverNode.js 服务器传统 VPS/云服务器
node-clusterNode.js 集群模式高性能 Node.js 部署
vercelVercel 平台快速部署,零配置
netlifyNetlify 平台类似 Vercel
cloudflare-pagesCloudflare Pages边缘渲染,全球加速
deno-deployDeno DeployDeno 运行时
bunBun 运行时Bun 运行时
static纯静态站点不需要服务器的纯静态网站

为什么"一次构建"能"处处部署"?

Nitro 把你的服务端代码编译为标准格式,不同预设生成不同入口文件,但业务逻辑不变。你写的 defineEventHandler 代码在所有平台上都一样,只是底层运行时不同。

Nitro 存储层

Nitro 提供跨平台的存储层,基于 unstorage

ts
// nuxt.config.ts
export default defineNuxtConfig({
  nitro: {
    storage: {
      redis: {
        driver: 'redis',
        host: '127.0.0.1',
        port: 6379,
      },
    },
  },
})
ts
// server/api/cache.ts
export default defineEventHandler(async () => {
  // 读取
  const value = await useStorage('redis').getItem('key')

  // 写入
  await useStorage('redis').setItem('key', 'value')

  // 删除
  await useStorage('redis').removeItem('key')

  // 列出所有 key
  const keys = await useStorage('redis').getKeys()

  return { value, keys }
})

什么时候用存储层?

  • 缓存 API 响应
  • 存储会话数据
  • 速率限制(rate limiting)
  • 临时数据存储

支持的存储驱动:Redis、Cloudflare KV、Vercel KV、MongoDB、GitHub、本地文件系统等。

开发模式下

不配置存储时,Nitro 使用内存存储。生产环境建议配置 Redis 等持久化存储。

Nitro 配置

ts
export default defineNuxtConfig({
  nitro: {
    // 部署预设
    preset: 'node-server',

    // 存储
    storage: { /* ... */ },

    // 环境变量前缀
    envPrefix: 'NUXT_',

    // 预渲染路由
    prerender: {
      routes: ['/about', '/blog'],
    },

    // 压缩
    compress: true,

    // 自定义 rollup 配置
    rollupConfig: { /* ... */ },
  },
})

Nitro 钩子

ts
// server/plugins/nitro.ts
export default defineNitroPlugin((nitroApp) => {
  nitroApp.hooks.hook('request', (event) => {
    console.log('请求到达', event.path)
  })

  nitroApp.hooks.hook('close', () => {
    console.log('服务器关闭')
  })
})

Nitro 钩子 vs Nuxt 钩子的区别

  • Nitro 钩子:服务端运行时事件(请求、关闭等)
  • Nuxt 钩子:构建/开发时事件(页面扩展、配置等)
  • 如果你需要"每个请求都执行"的逻辑,用 Nitro 钩子

Nitro vs Express

特性Nitro/h3Express
体积超轻量较重
TypeScript原生支持需要额外配置
SSR 集成与 Nuxt 深度集成需要手动配置
跨平台部署✅ 原生支持❌ 仅 Node.js
自动导入
生态Nuxt 生态npm 生态

可以在 Nuxt 中用 Express 吗?

技术上可以,但不推荐。Nitro/h3 更轻量、类型更好、与 Nuxt 集成更深、部署更灵活。如果你习惯了 Express,h3 的 API 风格非常相似,上手很快。

知识脉络

text
自动导入 → 你在这里:服务引擎 Nitro

              ├─→ 相关:API 路由(09-服务端开发)

              ├─→ 相关:服务中间件(09-服务端开发)

              └─→ 相关:部署上线(18-部署上线)

基于 Nuxt 4 官方文档整理编写