
H3 项目源码研读指南从架构设计到贡献实践的完整地图【免费下载链接】h3⚡️ Minimal H(TTP) framework built for high performance and portability项目地址: https://gitcode.com/GitHub_Trending/h31/h3H3读作 /eɪtʃθriː/是一个以高性能与可移植性为设计目标的最小化 HTTP 框架当前处于v2大版本——一次基于Web 标准原语Request、Response、URL、Headers的彻底重写。本文以仓库根目录的 AGENTS.md 为骨架结合 src、test、package.json 等源码与配置系统讲解 H3 的核心架构、目录组织、代码规范、请求处理流程、测试方法论、构建链路与包导出设计帮助你快速建立对仓库的全局认知并具备直接参与贡献的能力。快速参考开发命令一览AGENTS.md 给出了从环境搭建到基准测试的完整命令集全部基于 pnpm 运行# 环境搭建 corepack enable pnpm install # 开发 pnpm dev # vitest watch 模式监听全部测试 pnpm vitest run path # 运行指定测试文件 pnpm test # 完整测试lint typecheck coverage pnpm build # 使用 obuild 构建 pnpm lint # oxlint oxfmt --checklint typecheck pnpm fmt # automd oxlint --fix oxfmt pnpm bench:node # node 基准测试 pnpm bench:bun # bun 基准测试这些脚本在 package.json 中有精确定义dev对应vitesttest是pnpm lint pnpm typecheck vitest --run --coverage的组合链bench:node通过node --expose-gc --allow-natives-syntax运行 test/bench/bench.tsbench:bun则直接以bun run执行同一文件。注意engines要求node 20.11.1包管理器为pnpm11.15.1。核心架构设计Web 标准优先H3 v2 的底层不做任何自定义的请求/响应抽象而是直接构建在 Web 标准之上Web standards first基于原生Request、Response、URL、Headers不发明私有协议对象Multi-runtime同时支持 Node.js、Bun、Deno、Cloudflare Workers、Service Workers 与浏览器Minimal core生产依赖仅 2 个——rou3路由匹配引擎与srvx多运行时服务器抽象见 package.json 的dependencies字段Handler-based可组合的 handler 中间件模式不采用类继承重型的框架风格Type-safe全仓库启用严格 TypeScript贯穿始终的泛型推断保证端到端类型安全。sideEffects: false与type: module的配置package.json进一步确认了这是一个纯 ESM、可被 tree-shaking 的现代库。关键类类文件用途H3src/h3.ts主应用类继承H3Core补充路由方法get/post/put/delete/...H3Eventsrc/event.ts请求包装器——以惰性属性URL、context包装 WebRequestHTTPErrorsrc/error.ts结构化 HTTP 错误携带 status、data、headersHTTPResponsesrc/response.ts灵活响应构建器从源码看H3与H3Core的分工非常清晰H3Coresrc/h3.ts#L41-L114承载事件创建、fetch/handler调度、全局onRequest钩子触发与错误处理H3src/h3.ts#L152-L303在其上叠加rou3路由表~rou3、on()/all()注册方法、use()/mount()中间件与子应用挂载并通过一个循环为GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、CONNECT、TRACE、QUERY十个方法批量生成get()/post()等快捷方法。H3Eventsrc/event.ts#L34-L120则在构造时完成pathname的规范化解码对/%61dmin这类“多余转义”做一次解码%2F、%25除外它们必须保持不透明使路由匹配、use()匹配器与 handler 内读取event.url.pathname比较的是同一个字符串杜绝编码绕过而对/foo%、/%ZZ这类无规范形式的畸形编码则标记kMalformedURL在任意 handler 运行前以400拒绝除非开启allowMalformedURL配置。请求处理流程Request FlowAGENTS.md 明确了七步请求生命周期源码中每一步都有对应实现请求经平台适配器进入——各运行时入口位于 src/_entriesgeneric、node、bun、deno、cloudflare、service-workerH3.fetch()从Request创建H3Event——见 src/h3.ts#L60-L62fetch委托给~request后者在 src/h3.ts#L73-L100 中new H3Event(request, context, app)并先检查畸形 URL全局onRequest钩子运行——config.onRequest在 src/h3.ts#L85-L93 中于路由分发前同步或异步执行中间件链执行——按路由/方法匹配。createDispatchersrc/h3.ts#L121-L138是性能关键点默认情况下中间件列表会被composeMiddleware预组合一次并缓存~composed只在首次请求或use()/mount()使缓存失效后重建避免每次请求的逐层分发开销路由 handler 处理请求并返回值——findRoute匹配时还会为 HEAD 请求回退到 GET 路由RFC 9110见 src/h3.ts#L254-L262toResponse()将返回值转换为Response——自动处理 JSON、流、Blob 与原始类型同时扁平化 Promise 链并在响应前运行onResponse钩子src/response.ts#L13-L60全局onResponse钩子运行——作为终端的副作用钩子即使抛错也不会逃逸生命周期错误被捕获并视silent配置决定是否console.error。错误路径同样有保障toErrorsrc/response.ts#L73-L83会把抛出的数字强制为状态码throw 404、把未知对象包装为带unhandled标记的500且绝不信任非Error对象的结构来塑造响应——所有status/data/headers都被丢弃只保留为cause防止请求体回显等注入手段伪造响应描述符。项目结构速览src/ ├── index.ts # 公开 API 出口 ├── h3.ts # H3Core H3 类 ├── event.ts # H3Event ├── handler.ts # defineHandler、defineValidatedHandler 等 ├── middleware.ts # 中间件系统 ├── response.ts # toResponse、HTTPResponse ├── error.ts # HTTPError ├── adapters.ts # Web/Node handler 适配器 ├── tracing.ts # Tracing 插件独立入口 ├── types/ # 类型定义 │ ├── h3.ts # 应用类型H3Config、H3Plugin、H3Route、HTTPMethod │ ├── handler.ts # handler 类型EventHandler、Middleware │ ├── context.ts # H3EventContext │ ├── route-rules.ts # RouteRules共享、可增强合并到 event.context.routeRules │ └── _utils.ts # 内部类型工具 ├── utils/ # 约 30 个工具模块公开 API │ ├── request.ts # getQuery、getRouterParams、getRequestURL 等 │ ├── response.ts # redirect、noContent、html、iterable 等 │ ├── body.ts # readBody、readValidatedBody、assertBodySize │ ├── cookie.ts # getCookie、setCookie、parseCookies、分块 cookie │ ├── session.ts # getSession、useSession、sealSession 等 │ ├── auth.ts # requireBasicAuth、basicAuth │ ├── cors.ts # handleCors、appendCorsHeaders 等 │ ├── proxy.ts # proxy、proxyRequest、fetchWithEvent │ ├── ws.ts # defineWebSocketHandler、defineWebSocket │ ├── json-rpc.ts # defineJsonRpcHandler、defineJsonRpcWebSocketHandler │ ├── event-stream.ts # createEventStreamSSE │ ├── static.ts # serveStatic │ ├── cache.ts # handleCacheHeaders │ ├── middleware.ts # onRequest、onResponse、onError、bodyLimit │ ├── route.ts # defineRoute │ ├── base.ts # withBase │ └── internal/ # 内部辅助不导出 │ ├── auth.ts、body.ts、cors.ts、encoding.ts 等 │ ├── iron-crypto.ts # Session 密封加密 │ ├── standard-schema.ts # 标准 schema 校验 │ └── validate.ts ├── rules/ # 路由规则h3/rules 子路径入口 │ ├── index.ts # h3/rules — routeRules 中间件、匹配器、内置 handler │ ├── middleware.ts # routeRules() 即插即用中间件 │ ├── normalize.ts # normalizeRouteRules配置 → 运行时规则 │ ├── match.ts # createRouteRulesMatcher、createMatcherFromFind、memoize │ ├── merge.ts # mergeMatchedRouteRules层合并语义 │ ├── types.ts # RouteRuleConfig、NormalizedRouteRules 等 │ ├── cache.ts # h3/rules/cache — ocache 支撑的缓存 handler可选 peer │ ├── proxy.ts # h3/rules/proxy — proxyRequest 支撑的代理 handler │ ├── compiler.ts # h3/rules/compiler — 构建期 codegen │ ├── handlers/ # 内置规则 handlerheaders、redirect、cors、cache │ ├── compiler/ # Codegen 内部实现 │ └── internal/ # key 解析、作用域检查、node-key 分桶、预合并分析 ├── _entries/ # 平台特定入口 │ ├── generic.ts # Web Worker / 浏览器 │ ├── node.ts # Node.js附加 toNodeHandler │ ├── bun.ts # Bun │ ├── deno.ts # Deno │ ├── cloudflare.ts # Cloudflare Workers │ ├── service-worker.ts # Service Workers │ └── _common.ts # 共享入口工具 └── _deprecated.ts # 已废弃导出v1 兼容 test/ ├── _setup.ts # 测试基础设施describeMatrix、setupWebTest、setupNodeTest ├── *.test.ts # 约 30 个集成测试文件 ├── rules/ # 路由规则测试含类型测试 types.test-d.ts ├── unit/ # 单元测试含类型测试 types.test-d.ts ├── bench/ # 基准测试mitata └── fixture/ # 运行时专用 playground 夹具公开 API 的完整清单以 src/index.ts 为准它集中导出了路由、请求、响应、body、cookie、session、auth、cors、proxy、SSE、WebSocket、JSON-RPC、tracing、路由规则等全部工具函数与类型——这恰好印证了 AGENTS.md 中“utils 提供约 30 个公开工具模块”的说法。代码规范Code Conventions风格约束仅 ESM——不引入 CommonJS所有导入路径显式携带.ts扩展名无 barrel 文件——直接从具体模块导入src/index.ts 是唯一的公共聚合出口内部文件使用_前缀如_deprecated.ts、_entries/、_utils.ts内部辅助函数放在文件末尾或utils/internal/下保持文件短小——单文件目标 200 行超出即拆分多参数函数以第二个参数作为 options 对象格式化使用oxfmt零配置采用默认值lint 使用oxlint并启用unicorn、typescript、oxc插件。命名约定约定含义示例k前缀符号常量kNotFound、kHandled见 src/response.ts#L10-L11~前缀私有/不可枚举属性~middleware、~routes、~dispatch#前缀真正私有的类字段HTTPResponse的#headers、#initdefine*()工厂函数defineHandler、defineMiddleware、defineWebSocketHandlerto*()转换函数toResponse、toEventHandler、toWebHandlerfrom*()适配器函数fromWebHandler、fromNodeHandler这些命名贯穿全仓库例如defineHandlersrc/handler.ts#L23-L51接受函数或对象含handler/fetch/middleware字段并合成带.fetch能力的 handlertoResponsesrc/response.ts负责将任意 handler 返回值收敛为ResponsefromWebHandler/fromNodeHandler等适配器在 src/adapters.ts 中承担跨运行时桥接。TypeScript 配置严格模式 isolatedDeclarationsverbatimModuleSyntaxerasableSyntaxOnly: true——禁止 enum 与 namespace保证类型可被无缝擦除Target/ModuleESNext/NodeNextLib[ESNext, WebWorker, DOM, DOM.Iterable]——这组 lib 正是“一套代码运行于 Node 与浏览器/Worker 两类环境”的类型学基础handler 中大量使用泛型做类型推断defineValidatedHandler等实验性 API 与utils/internal/standard-schema.ts的 Standard Schema 校验协作。响应处理模型H3 采用handler 直接返回值而非res.send()模式返回值到响应的映射规则如下返回string→ 文本响应返回object→ JSON 响应返回Response/HTTPResponse→ 直接透传响应返回ReadableStream/Blob/File→ 流式响应返回kNotFound符号 →404返回kHandled符号 → 已处理完成SSE、WebSocket 等场景。值得注意的细节kNotFound与kHandled是Symbol.for注册的全局符号src/response.ts#L10-L11即使存在多份 h3 副本或跨 realm 也能稳定匹配。HTTPResponse的识别同样采用注册符号kHTTPResponsesrc/response.ts#L94而非constructor.name——注释明确指出 JSON 解析可伪造constructor属性duck-typing 的 name 检查存在注入风险。中间件遵循同一“返回值”哲学normalizeMiddlewaresrc/middleware.ts#L14-L29会把返回undefined或kNotFound的中间件视为“继续走next()”让中间件既可以“短路响应”也可以“静默放行”。测试体系框架与矩阵测试Vitestv4见 package.json 的 devDependencies配合v8覆盖率vitest/coverage-v8矩阵测试每个测试都在web与node两种模式下各跑一遍。describeMatrix的实现见 test/_setup.ts#L11-L38它在内部生成web、node两个describe分组分别调用setupWebTest走ctx.app.request(...)纯内存路径与setupNodeTest起真实node:http服务器 toNodeHandler适配。web 模式会自动补Host: localhost头node 模式还会模拟反向代理场景补Host。编写测试import { describeMatrix } from ./_setup.ts; describeMatrix(feature name, (ctx, { it, expect }) { it(does something, async () { ctx.app.get(/test, () hello); const res await ctx.fetch(/test); expect(await res.text()).toBe(hello); }); });关键模式使用describeMatrix编写跨运行时测试ctx.app是每个测试独立的全新H3实例由beforeEach保证ctx.fetch统一处理 web/node 两种模式的 URL 解析ctx.errors追踪未处理错误afterEach中自动断言用it.skipIf(ctx.target node)跳过运行时特定用例。运行测试pnpm vitest run test/body.test.ts # 单文件 pnpm vitest run test/unit/ # 单元测试 pnpm dev # watch 模式全部 pnpm test # 完整lint typecheck coverageBug 修复工作流编写可复现 bug 的回归测试在改动任何代码前确认测试失败以最小改动修复实现确认测试通过运行更广的测试集做回归检查。这套 TDD 式流程与仓库中的测试组织一一对应集成测试平铺在 test 根目录约 30 个*.test.ts规则子系统在 test/rules单元测试与类型测试在 test/unit基准在 test/bench。构建与包导出构建链路使用obuild基于 Rolldown 打包器见 package.json 的build: obuild脚本6 个平台入口tracing.ts 4 个rules/*入口分别作为独立 entry 构建开启code splitting产出h3-[hash].mjs分块自定义插件剥离注释保留#/注解产物dist/_entries/*.mjsdist/*.d.mts。包导出映射h3 → 按运行时自动解析deno/bun/workerd/node/default h3/node → Node.js 运行时附加 toNodeHandler h3/bun → Bun 运行时 h3/deno → Deno 运行时 h3/cloudflare → Cloudflare Workers h3/service-worker → Service Workers h3/generic → 通用 Web 标准 h3/tracing → Tracing 插件 h3/rules → 路由规则routeRules 中间件、匹配器、内置 handler h3/rules/cache → ocache 支撑的 cache 规则 handler可选 ocache peer h3/rules/proxy → proxy 规则 handler引入 proxyRequest h3/rules/compiler → 构建期路由规则 codegen上述导出与 package.json#L18-L39 的exports字段完全一致根入口.使用deno/bun/workerd/browser/node/default条件导出按运行时解析到 dist/_entries 下对应的入口文件。h3/rules各子路径则对应该系统独立构建的产物。依赖一览依赖用途rou3路由匹配引擎^0.9.2srvx服务器抽象层多运行时支持^0.12.7crosswsWebSocket 抽象可选 peer 依赖ocache为h3/rules/cache提供响应缓存可选 peer 依赖package.json#L101-L112 证实crossws与ocache均为optional: true的 peerDependencies——即核心零负担仅在需要 WebSocket 或规则缓存能力时由使用者自行安装这再次呼应了“minimal core”的设计哲学。贡献最佳实践AGENTS.md 最后给出了面向贡献者的五条准则优先使用 Web 标准 API 而非运行时特定 API保持核心最小化——新增工具函数而不是为核心增加复杂度使用describeMatrix跨运行时测试handler 返回值而非修改响应对象使用defineHandler/defineMiddleware获得类型安全。配套的 examples 目录提供了大量可运行示例例如 examples/middleware.mjs 展示了new H3()、链式.get()注册路由、onRequest/onResponse/onError全局钩子的组合用法是理解“返回值哲学”与钩子语义最直接的入口。结语AGENTS.md 是一份面向 Agent 与人类开发者的“仓库宪法”它浓缩了 H3 v2 的架构决策Web 标准优先、多运行时、最小核心、handler 组合、工程化约定命名、ESM、类型擦除、短文件与质量红线矩阵测试、回归优先、树摇友好。当你阅读本文并对照 src、test 与 package.json 逐一验证时会发现自己已经掌握了这个仓库从请求进入、路由匹配、中间件组合、响应序列化到测试与构建交付的完整闭环——这正是参与 H3 贡献前需要建立的心智模型。【免费下载链接】h3⚡️ Minimal H(TTP) framework built for high performance and portability项目地址: https://gitcode.com/GitHub_Trending/h31/h3创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考