官方文档:
https://h3.dev/guide
示例代码:
https://gitee.com/itshizhan/nuxt-inaction-course/tree/master/h3js_study/quick_start

先从一个简单的H3 start example 看起:

初始化一个项目

javascript 复制代码
mkdir quick_start
pnpm init 
// 注意安装方式,目前官方文档已经是v2 版本,但是还没有发布正式的npm包
pnpm add npm:h3-nightly@2x

Create a new file server.mjs

javascript 复制代码
import { H3, serve } from "h3";

const app = new H3();

// eventHandler 是一个 handler: EventHandler | H3 类型
// EventHandler 是一个函数类型,它会接收一个 H3Event 对象作为参数,用于处理客户端的请求并返回响应。
// H3 则代表另一个 h3 应用实例,这意味着可以将一个 h3 应用嵌套到另一个 h3 应用中。
app.get("/", (event) => {
  // 如果不设置Content-Type,表情符号可能乱码
  event.res.headers.set("Content-Type", "text/plain;charset=UTF-8");
  return "⚡️ Hello, Tadaa!";
});


serve(app, { port: 3000 });

执行代码

javascript 复制代码
node --watch ./server.mjs

new H3() 执行逻辑

javascript 复制代码
const app = new H3();

当执行上述代码时,会创建一个 h3 app instance , app 是一个微型服务器,能够匹配路由、生成响应,并处理生命周期钩子(如错误处理)。

我们可以看下 H3 的类型定义文件:

javascript 复制代码
declare class H3 {
    #private;
    /**
     * Global h3 instance config.
     */
    readonly config: H3Config;
    /**
     * An h3 compatible event handler useful to compose multiple h3 app instances.
     */
    handler: EventHandler<EventHandlerRequest, unknown | Promise<unknown>>;
    /**
     * Create a new h3 app instance
     *
     * @param config - h3 config
     */
    constructor(config?: H3Config);
    /**
     * Websocket hooks compatible with [🔌 crossws](https://crossws.h3.dev/).
     */
    get websocket(): WebSocketOptions;
    /**
     * A [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)-like API allowing to fetch app routes.
     *
     * Input can be a URL, relative path or standard [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object.
     *
     * Returned value is a standard [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) or a promise resolving to a Response.
     */
    fetch(_request: Request | URL | string, options?: RequestInit, context?: H3EventContext): Response | Promise<Response>;
    /**
     * Resolve a route handler by method and path.
     */
    resolve(method: HTTPMethod, path: string): Promise<ResolvedEventHandler | undefined>;
    all(route: string, handler: EventHandler | H3): this;
    get(route: string, handler: EventHandler | H3): this;
    post(route: string, handler: EventHandler | H3): this;
    put(route: string, handler: EventHandler | H3): this;
    delete(route: string, handler: EventHandler | H3): this;
    patch(route: string, handler: EventHandler | H3): this;
    head(route: string, handler: EventHandler | H3): this;
    options(route: string, handler: EventHandler | H3): this;
    connect(route: string, handler: EventHandler | H3): this;
    trace(route: string, handler: EventHandler | H3): this;
    on(method: HTTPMethod | Lowercase<HTTPMethod> | "", route: string, handler: EventHandler | H3): this;
    /**
     * Register a global middleware
     *
     * Global middleware will be called before all routes on each request.
     *
     * If the first argument is a string, it will be used as the route.
     */
    use(arg1: string | EventHandler | H3 | H3Route, arg2?: EventHandler | H3 | Partial<H3Route>, arg3?: Partial<H3Route>): this;
}

这段代码是一个 TypeScript 类型声明(type declaration),用于描述一个名为 H3 的类的接口和行为。这个类看起来是用于构建 HTTP 服务的一个轻量级框架,类似于 Express 或 Fastify,但更现代化、模块化,并且兼容 fetch API 和 WebSocket。

下面我会逐行详细解释每个部分的作用和含义:


🧱 类定义

ts 复制代码
declare class H3 {
    #private;
}
  • #private;: 表示该类中使用了私有字段(ES2021 私有字段语法),可能用于封装内部状态或配置。

🔧 只读属性:config

ts 复制代码
readonly config: H3Config;
  • config 是一个只读属性,类型为 H3Config,表示这个类实例的全局配置对象。
  • 只读意味着一旦初始化后就不能被外部修改。

🔄 请求处理器:handler

ts 复制代码
handler: EventHandler<EventHandlerRequest, unknown | Promise<unknown>>;
  • handler 是一个事件处理函数,接受请求并返回一个值或 Promise。
  • 它符合 Node.js/HTTP 服务器常见的“事件处理”模式。
  • 类型 EventHandler<Request, Response> 意味着这是一个异步处理函数,接收请求,返回响应。

🛠 构造函数

ts 复制代码
constructor(config?: H3Config);
  • 构造函数可以传入一个可选的 H3Config 配置对象来初始化 H3 实例。

🌐 Websocket 支持

ts 复制代码
get websocket(): WebSocketOptions;
  • 提供了一个 getter 方法 websocket,返回 WebSocket 的配置选项。
  • 这个特性说明 H3 可以与 WebSocket 一起工作。

🚀 fetch 方法(类似浏览器 Fetch API)

ts 复制代码
fetch(_request: Request | URL | string, options?: RequestInit, context?: H3EventContext): Response | Promise<Response>;
  • 提供一个类似浏览器 fetch() 的方法,允许你模拟发送 HTTP 请求到当前应用的路由。
  • 参数:
    • _request: 可以是字符串路径、URL 对象或标准的 Request 对象。
    • options: 标准的 RequestInit,如 headers、body 等。
    • context: 自定义上下文信息(可选)。
  • 返回值:标准 Response 或其 Promise。

🗺 路由解析器

ts 复制代码
resolve(method: HTTPMethod, path: string): Promise<ResolvedEventHandler | undefined>;
  • 根据 HTTP 方法(GET、POST 等)和路径查找对应的路由处理器。
  • 返回的是一个 Promise,因为可能需要异步加载模块或中间件。
  • 如果找不到对应路由,返回 undefined

📦 HTTP 方法注册路由(all, get, post...)

ts 复制代码
all(route: string, handler: EventHandler | H3): this;
get(route: string, handler: EventHandler | H3): this;
post(route: string, handler: EventHandler | H3): this;
...
  • 提供了常见的 HTTP 方法绑定函数。
  • 每个方法都接受一个路径 route 和一个处理器 handler
  • 处理器可以是一个 EventHandler 函数或者另一个 H3 实例(支持嵌套路由或组合多个 app)。
  • 返回 this,意味着支持链式调用。

🧩 泛用的 on 方法

ts 复制代码
on(method: HTTPMethod | Lowercase<HTTPMethod> | "", route: string, handler: EventHandler | H3): this;
  • 更通用的路由注册方式,允许传入任意 HTTP 方法名(大小写不敏感)。
  • 例如:.on("GET", "/hello", handler).on("", "/any", handler)(监听所有方法)。

⚙ 注册中间件:use

ts 复制代码
use(arg1: string | EventHandler | H3 | H3Route, arg2?: EventHandler | H3 | Partial<H3Route>, arg3?: Partial<H3Route>): this;
  • use 用于注册全局中间件。
  • 中间件会在每次请求开始时被调用。
  • 参数灵活,支持多种传参形式:
    • use("/path", handler)
    • use(handler)
    • use("/path", h3App)
    • use({ path: '/path', handler })

🧠 总结

成员 类型 用途
config 只读属性 存储应用配置
handler 属性 整体事件处理函数
websocket getter 获取 WebSocket 配置
fetch 方法 模拟请求当前应用路由
resolve 方法 异步查找路由处理器
all, get, post... 方法 绑定特定 HTTP 方法的路由
on 方法 泛用的路由绑定
use 方法 添加中间件或子路由

H3 App Instance

上文提到,当穿件 h3 app instance 时, app 只是一个微型服务器,能够匹配路由、生成响应,并处理生命周期钩子(如错误处理)。 但是 app 本身还不是完整的http服务器,自身不能直接监听 HTTP 端口,不过可以借助 serve 函数来启动服务器并监听端口。

例如,我们可以借助于node 内置的 createServer 创建一个 http 服务器,并监听端口,通过 h3 app instance 来处理路由请求等。如下:

javascript 复制代码
import { H3 } from "h3";
import { createServer } from 'node:http';
const app = new H3();

// eventHandler 是一个 handler: EventHandler | H3 类型
// EventHandler 是一个函数类型,它会接收一个 H3Event 对象作为参数,用于处理客户端的请求并返回响应。
// H3 则代表另一个 h3 应用实例,这意味着可以将一个 h3 应用嵌套到另一个 h3 应用中。
app.get("/", (event) => {
  event.res.headers.set("Content-Type", "text/plain;charset=UTF-8");
  return "⚡️ Hello, Tadaa!";
});


// serve(app, { port: 3000 });
// 创建HTTP服务器并将所有请求传递给H3实例处理
const serverCustom = createServer(async (req, res) => {
  const response = await app.fetch(req.url, { method: req.method }, /* 可选的上下文 */);
  res.writeHead(response.status, response.headers);
  res.end(await response.text());
});

// 让服务器监听3000端口
serverCustom.listen(3000, () => {
  console.log('Server is listening on port 3000');
});

h3 serve

实际上,h3 框架内置了一个serve , 用来处理 app instance 在不同运行时环境的行为。

源码如下:

javascript 复制代码
/**
 * Serve the h3 app, automatically handles current runtime behavior.
 */
export function serve(app: H3, options?: Omit<ServerOptions, "fetch">): Server {
  return srvxServe({ fetch: app.fetch, ...options });
}

即,我们可以通过下面的方式,启动一个h3的 http 服务。

javascript 复制代码
import { H3, serve } from "h3";

const app = new H3();

app.get("/", () => "⚡️ Tadaa!");

// serve 基于 srvx 库
serve(app, { port: 3000 });

srvx(https://srvx.h3.dev/) 提供了一个统一的标准 API,用于基于标准网络平台原语(fetch、Request 和 Response)创建 HTTP 服务器,并且能够与 Deno、Bun 和 Node.js 无缝协作。

其基本用法即:

javascript 复制代码
import { serve } from "srvx";

// 即上文srvxServe 的实现
const server = serve({
  fetch(request) {
    return new Response("👋 Hello there!");
  },
});