插件
使用运行时插件扩展 Nitro 的运行时行为。
运行时插件会在服务器启动期间执行一次,因此它们适合用于一次性初始化以及注册生命周期钩子。每个插件都会接收 nitroApp 上下文。
插件会从 plugins/ 目录自动注册并同步运行。插件函数本身必须是同步的(返回 void),但它们注册的钩子可以是异步的。
import { definePlugin } from "nitro";
export default definePlugin((nitroApp) => {
console.log('Nitro plugin', nitroApp)
})如果你有其他目录中的插件,可以使用 plugins 选项:
import { defineConfig } from "nitro";
export default defineConfig({
plugins: ['my-plugins/hello.ts']
})插件按以下顺序运行:
plugins 选项中列出的顺序运行其中列出的插件。plugins/ 目录自动注册的插件。目录按照 scanDirs 的顺序处理,每个目录中的文件则按路径排序。#nitroApp 上下文
插件函数接收一个具有以下属性的 nitroApp 对象:
| 属性 | 类型 | 描述 |
|---|---|---|
hooks | HookableCore | 用于注册生命周期回调的钩子系统。 |
h3 | H3Core | 底层的 H3 应用实例。 |
fetch | (req: Request) => Response | Promise<Response> | 应用的内部 fetch 处理器。 |
captureError | (error: Error, context) => void | 以编程方式将错误捕获到错误钩子管道中。 |
Note
H3 会在第一个请求时组合一次中间件链。插件在启动期间添加到 nitroApp.h3["~middleware"] 的中间件会被包含在内,但如果它们位于数组前部,则会在 Nitro 的路由规则之前运行。如果插件在处理第一个请求后修改了该数组,则还必须将 nitroApp.h3["~dispatch"] 和 nitroApp.h3["~composed"] 重置为 undefined,以便重新组合该链。
#Nitro 运行时钩子
使用 Nitro 钩子 在请求生命周期中的特定时间点运行自定义函数。在插件内部使用 nitroApp.hooks.hook() 注册它们:
import { definePlugin } from "nitro";
export default definePlugin((nitroApp) => {
nitroApp.hooks.hook("close", async () => {
// 当 nitro 关闭时运行
});
})#可用的钩子
| 钩子 | 签名 | 描述 |
|---|---|---|
request | (event: HTTPEvent) => void | Promise<void> | 在每个请求开始时调用。 |
response | (res: Response, event: HTTPEvent) => void | Promise<void> | 在响应创建后调用。 |
error | (error: Error, context: { event?: HTTPEvent, tags?: string[] }) => void | 当错误被捕获时调用。 |
close | () => void | 当 Nitro 服务器关闭时调用。 |
Note
NitroRuntimeHooks 接口是可扩展的。部署预设(如 Cloudflare)可以使用平台特定的钩子(如 cloudflare:scheduled 和 cloudflare:email)来扩展它。
#注销钩子
hook() 方法返回一个注销函数,可以调用该函数来移除钩子:
import { definePlugin } from "nitro";
export default definePlugin((nitroApp) => {
const unregister = nitroApp.hooks.hook("request", (event) => {
// ......
});
// 稍后,移除该钩子
unregister();
});#示例
#捕获错误
你可以使用插件来捕获所有应用错误。
import { definePlugin } from "nitro";
export default definePlugin((nitroApp) => {
nitroApp.hooks.hook("error", async (error, { event }) => {
console.error(`${event?.req.url} Application error:`, error)
});
})context 对象包含一个可选的 tags 数组,用于标识错误来源(例如 "request"、"response"、"cache"、"plugin"、"unhandledRejection"、"uncaughtException")。
#以编程方式捕获错误
你可以使用 captureError 手动将错误送入错误钩子管道:
import { definePlugin } from "nitro";
export default definePlugin((nitroApp) => {
nitroApp.captureError(new Error("something went wrong"), {
tags: ["startup"],
});
});#优雅关闭
服务器会优雅地关闭,等待所有使用 event.waitUntil 启动的待处理后台任务。使用 close 钩子清理你自己的资源:
import { definePlugin } from "nitro";
export default definePlugin((nitroApp) => {
nitroApp.hooks.hook("close", async () => {
// 清理资源、关闭连接等。
});
});#请求和响应生命周期
你可以使用插件注册在请求生命周期中运行的钩子:
import { definePlugin } from "nitro";
export default definePlugin((nitroApp) => {
nitroApp.hooks.hook("request", (event) => {
console.log("on request", event.req.url);
});
nitroApp.hooks.hook("response", (res, event) => {
// 修改或检查响应
console.log("on response", res.status);
});
});#修改响应头
import { definePlugin } from "nitro";
export default definePlugin((nitroApp) => {
nitroApp.hooks.hook("response", (res, event) => {
const { pathname } = new URL(event.req.url);
if (pathname.endsWith(".css") || pathname.endsWith(".js")) {
res.headers.append("Vary", "Origin");
}
});
});