H3 起始于 2020 年末,正值边缘工作者(edge workers)兴起之时。结合 H3 + unjs/unenv,我们可以在带有 Node.js 兼容性的工作者环境中运行 Nitro 部署,兼具两者优势!自从 v1.8 起,H3 已经提升了对 web 标准的支持。
不过,H3 仍然主要基于 Node.js API,带有 web 标准的兼容层。当时这是合乎逻辑的选择,因为 Node.js 在 JavaScript 服务器运行时中非常受欢迎。
得益于像 WinterTC 这样持续发展的 web 标准,以及在 Deno、Bun 和最新的 Node.js 中的运行时支持,生态系统已准备好优先采用 web 标准进行服务器开发。其优势包括:
- 跨运行时互操作性(Node.js、Deno、Bun、Workers 等)
- 跨框架兼容性(H3、Hono、Elysia 等)
- 跨环境兼容性(前后端共享且熟悉的代码)
- 利用更多运行时原生原语,如 (Request、URL、Headers 等)
- 更易进行 API 测试
💥 Srvx:通用 Web 服务器 API
一个主要挑战是 Node.js 缺少对 web 标准 HTTP 服务器的内置支持。为了实现 node:http
兼容,需要一个适配器将 Node.js 的 IncomingMessage
转换为 web 的 Request
,并通过 Node.js 的 ServerResponse
处理 web 的 Response
。我们实现了一个兼容层,桥接接口,并达到原生 node:http
性能的 96.98%(详见基准测试)。
Deno 、 Bun 和边缘工作者等运行时率先采用 web 标准服务器,但由于缺乏足够的规范,它们并未统一接口。那么你如何访问客户端 IP 地址及额外上下文?如何设置服务器端口和 TLS 选项?如何处理 WebSocket 升级?各运行时都创建了自己的 API。
我们创建了 💥 srvx:一个统一的层,在所有环境中均表现一致。兼容 Deno、Bun、Node.js、Service Workers、Edge Workers。
示例
// 根据各运行时的导出条件,动态使用适配器
import { serve } from "srvx";
serve({
port: 3000,
// tls: { cert: "server.crt", key: "server.key" }
fetch(req) {
// 服务器扩展:req.ip, req.waitUntil(), req.runtime?.{bun,deno,node,cloudflare,...}
return new Response("👋 你好!");
},
});
⚡ H3:微型服务器组合器 🎶
我们努力缩小并简化 H3 的功能范围。
import { H3, serve } from "h3";
const app = new H3().get("/", () => "⚡️ Tadaa!");
serve(app, { port: 3000 });
🪶 比羽毛还轻
我们采用了一种新的基准测试方法,着重衡量框架本身引入的开销,而不是网络层。我们的目标是优化所有相关指标,使结果尽可能接近无框架基线。这种方法使 H3 在每个请求的延迟上得到优化提升,并极大缩小了核心包的体积。
测量项 | H3 v1 | 🚀 H3 v2 |
---|---|---|
请求处理时间 | Node: 36 µs Bun: 27 µs Deno: 7 ms | Node: 7 µs (快5倍) Bun: 3 µs (快9倍) Deno: 1.2 µs (快156倍) |
包体积 | 最小: 101 kB 最小+gzip: 39.6 kB | 最小: 9.1 kB (小91%) 最小+gzip: 3.6 kB (小90%) 最小: 5.2 kB / 最小+gzip: 2.1 kB (fetchable 处理器) |
new URL(req.url).pathname
进行路由的纯 fetch
处理器。换句话说,使用 H3 基本没有性能损耗!✅ 类型化 Web 标准
H3 采用 web 标准 API,如 Request、Response、URL 和 Headers,不在标准之上引入新约定。
我们发起了一项强类型 Web API 的新计划:✅ fetchdts。已集成到 H3 中,将标准与类型便利性完美结合。
import { defineHandler } from "h3";
const handler = defineHandler(async (event) => {
// URL 解析
const { pathname, searchParams } = event.url;
// 访问请求头(编辑器中试试自动补全!)
const accept = event.req.headers.get("Accept");
// 读取请求体
const bodyStream = await event.req.body;
const bodyText = await event.req.text();
const bodyJSON = await event.req.json();
const bodyFormData = await event.req.formData();
// 访问运行时特定上下文
const { deno, bun, node } = event.req.runtime;
// 准备响应(h3 会智能处理)
event.res.headers.set("Content-Type", "application/json");
return { hello: "web" };
});
接下来调用处理器的 .fetch
:
const response = await handler.fetch("/");
// 🧙 类型化响应: { hello: string; }
const json = await response.json();
🧩 中间件和插件
H3 现在提供了符合人体工学的、可组合的中间件链式调用方式,基于 next()
函数(灵感来自 Hono middleware 💛)。
同时,我们引入了一种简单而强大的模式,用于扩展 H3 应用,通过可复用的 插件。
import { H3 } from "h3";
const app = new H3().use(async (event, next) => {
// ... 响应前 ...
const body = await next();
// ... 响应后 ...
event.res.headers.append("x-middleware", "works");
event.waitUntil(sendMetrics(event));
return body;
});
import { defineHandler, basicAuth } from "h3";
export default defineHandler({
middleware: [basicAuth({ password: "test" })],
handler: (event) => `Hello ${event.context.basicAuth?.username}!`,
});
import { H3, onRequest } from "h3";
const app = new H3().use(
onRequest((event) => {
console.log(`Request: [${event.req.method}] ${event.url.pathname}`);
}),
);
import { H3, onResponse } from "h3";
const app = new H3().use(
onResponse((response, event) => {
console.log(`Response: [${event.req.method}] ${event.url.pathname}`, body);
}),
);
import { H3, onError } from "h3";
const app = new H3().use(
onError((error, event) => {
console.error(
`[${event.req.method}] ${event.url.pathname} !! ${error.message}`,
);
}),
);
import { H3, serve, definePlugin } from "h3";
const logger = definePlugin((h3, _options) => {
if (h3.config.debug) {
h3.use((req) => {
console.log(`[${req.method}] ${req.url}`);
});
}
});
const app = new H3({ debug: true })
.register(logger())
.all("/**", () => "Hello!");
next
回调是可选的。中间件也可以像 v1 那样编写,不返回响应。⬆️ 从 版本 1 迁移
我们尽力减少了破坏性变更。大部分工具仍保持向后兼容。
🙌 面向所有人的统一 H(TTP) 服务器工具
H3 及相关项目已迁移至专门的 github 组织 和新的 h3.dev 域名(感谢 syntax.fm 和其他赞助商💛的捐赠)。
在 H3 旗帜下,我们维护了若干用于通用 JavaScript 服务器的关键组件。
全部开源,既可与 H3 一起使用,也可独立于 H3,且支持任意 JavaScript 运行时。
❤️ 特别感谢
这次发布离不开优秀的贡献者、社区的反馈(Discord)、受 Hono、Elysia 等 web 标准框架的启发,以及使得开源工作成为可能的赞助商。
🗺️ v2(稳定版)路线图
接下来:
- 收集社区反馈。
- 基于反馈完成 API 更新。
- 确保生态兼容,并升级支持 Nitro v3。