Elysia:由 Bun 驱动的端到端类型安全 TypeScript Web 框架实践指南 后端Web框架【免费下载链接】elysiaErgonomic Framework for Humans项目地址https://gitcode.com/GitHub_Trending/el/elysia点击查看免费下载导读Elysia 是一个为“人”而设计的 Ergonomic符合人体工学TypeScript Web 框架其核心卖点不是堆砌功能而是端到端End-to-End类型安全、type integrity类型完整性与卓越的开发体验并由 Bun 运行时强力加速。本文以仓库根目录的 README.md 为主线结合 package.json当前仓库版本 1.4.30与 example/ 目录下的真实示例、src/index.ts 的底层实现带你掌握如何用 Elysia 在几分钟内搭建一个类型安全、可校验、可扩展的 Bun Web 服务并理解其背后“单一事实来源single source of truth”的类型设计哲学。Elysia 是什么Ergonomic Framework for HumansTypeScript with End-to-End Type Safety, type integrity, and exceptional developer experience. Supercharged by Bun.这是 README 中对 Elysia 最凝练的定位。拆解开来包含四层含义TypeScript 优先全部代码用 TypeScript 编写类型系统不是“补丁”而是框架的一等公民。End-to-End Type Safety从路由注册、参数解析到响应返回类型在编译期贯穿全链路无需额外声明即可自动推断。type integrity类型完整性框架内部对 Schema、路由、Store、Hook 的合并与推导保持类型一致这正是它区别于普通“运行时校验框架”的关键。Supercharged by Bun底层运行时基于 Bun天然继承 Bun 的高性能与 Web 标准 APIRequest/Response/WebSocket同时保留 WinterCG 兼容性。从源码看这一承诺是落在实处的src/index.ts 中Elysia主类定义携带了多达 7 个泛型参数BasePath、Singleton、Definitions、Metadata、Routes、Ephemeral、Volatile分别跟踪基础路径、装饰器/Store/derive/resolve 单例、TypeBox 定义、路由元数据与作用域状态。也就是说框架把“类型状态”显式编码进泛型之中这正是 End-to-End Type Safety 的实现根基。快速开始一个 Hello World最简启动方式如下对应 example/simple.tsimport { Elysia } from elysia new Elysia() .get(/, () Hi) .listen(3000)仅 3 行即可启动一个监听 3000 端口、返回Hi的 Web 服务。若在仓库内直接体验可运行bun run example/simple.ts值得注意的细节是 example/simple.ts 用performance.now()记录了从实例化到调用listen的耗时这侧面反映了 Elysia “启动即用、懒编译”的轻量设计路由在默认 AOT 模式下按需编译冷启动成本极低。从 src/index.ts 的构造函数可以看到Elysia支持丰富的全局配置配置项默认值说明aotenv.ELYSIA_AOT ! false是否开启 AOT编译期生成组合处理器可通过环境变量ELYSIA_AOT关闭nativeStaticResponsetrue静态返回值是否走原生静态响应优化路径normalizetrue是否对输入做规范化normalize处理encodeSchematrue是否编码 Schemaprefixundefined全局路由前缀会自动补全开头的/见 src/index.tscookie{ path: / }全局 Cookie 默认配置如secrets、signseed用于区分同名插件实例的类型种子adapter自动选择 Bun / Web Standard运行时适配器见 src/adapter 目录路由与动态参数类型自动推断路由注册是 Elysia 的日常操作。动态路径参数使用:name语法且类型会被自动推断。参见 example/params.tsconst app new Elysia() .get(/, () Elysia) // Retrieve params, automatically typed .get(/id/:id, ({ params }) params.id) .listen(3000)在GET /id/:id中处理函数的params参数被自动推断为{ id: string }无需任何手动类型标注。这是 Elysia 的核心体验之一类型信息从路径声明流向处理函数。底层支撑这一能力的是 src/index.ts 中add方法的路由注册逻辑路径不以/开头时自动补全if (path ! path.charCodeAt(0) ! 47) path / path存在全局prefix时自动拼接前缀通过supportPerMethodInlineHandler支持同一路径按方法区分的内联处理AOT 模式下调用composeHandler见 src/compose.ts把 Hook 链、校验器与业务处理组合成一个预编译函数见 src/index.ts。路由匹配底层使用memoirist路由树src/index.ts并为 AOT 与非 AOT 模式分别维护http与dynamic两棵路由树参数解码使用fast-decode-uri-component。类型校验TypeBox 与单一事实来源Elysia 采用 TypeBox 作为 Schema 定义语言。它的独特之处在于同一份 Schema 同时服务于编译期类型、运行时校验与搭配 OpenAPI 插件时文档生成即 README 注释中强调的 “single source of truth”——一份类型定义同时是类型、运行时和文档的唯一事实来源。以 example/body.ts 为例import { Elysia, t } from ../src const app new Elysia() .post(/, ({ body: { username } }) Hi ${username}, { body: t.Object({ id: t.Number(), username: t.String() }) }) .listen(3000)这里t.Object({ id: t.Number(), username: t.String() })既是请求体校验规则也让body.username在类型层面成为string。Schema 在编译期被解析成 TypeScript 类型在运行时被编译成校验器getSchemaValidator见 src/schema.ts 与 src/index.ts。Elysia 的 Schema 校验层按global / scoped / local三级合并ValidatorLayer见 src/index.ts并支持coerce对params、query、headers等字符串来源做自动类型强转如123→123具体强转逻辑集中在 src/replace-schema.ts 的queryCoercions、stringToStructureCoercions、coercePrimitiveRoot、coerceFormData中normalize对输入做结构规范化additionalProperties控制是否允许未知字段santize输出净化。参数校验与守卫Guard 的作用域隔离在真实项目中经常需要“一组路由共享同一套校验规则”。Elysia 的guard方法正是为此设计把 Schema 声明提升到路由组级别组内所有路由自动继承。参考 example/guard.tsimport { Elysia, t } from ../src new Elysia() .state(name, salt) .guard( { query: t.Object({ name: t.String() }) }, (app) app // Query type is inherited from guard .get(/profile, ({ query }) Hi) // Store is inherited .post(/name, ({ store: { name }, body, query }) name, { body: t.Object({ id: t.Number({ minimum: 5 }), username: t.String(), profile: t.Object({ name: t.String() }) }) }) ) .listen(3000)要点.guard(schema, fn)返回一个新的子应用实例组内路由共享query校验state声明的 Store 在 guard 内外均可访问路由级 Schema如这里body的最小值minimum: 5在 guard 之上做叠加互不覆盖。从实现看guard 本质是把 Schema 写入实例的scoped校验层随后组内路由在add时通过mergeHook(localHook, instanceValidator)src/index.ts与validator.getCandidate()合并得到最终校验器。测试用例可参考 test/path/guard.test.ts。生命周期 Hook在请求抵达前做处理Elysia 提供完整的事件链onRequest → onParse → onTransform → onBeforeHandle → onError → onAfterHandle → onAfterResponse以及路由级transform/beforeHandle/afterHandle等局部 Hook。example/hook.ts 展示了全局与局部 Hook 的配合new Elysia() .state(counter, 0) // Increase counter by 1 on every request on any handler .onTransform(({ store }) { store.counter }) .get(/, ({ store: { counter } }) counter, { // Increase counter only when this handler is called transform: [ ({ store }) { store.counter }, ({ store }) { store.counter } ] }) .listen(3000)全局onTransform对每一次请求生效路由级transform只在该路由命中时执行且支持数组形式按顺序依次执行。Hook 链的合并与排序由mergeHook、mergeLifeCycle等工具完成见 src/utils.ts组合执行在 src/compose.ts 中实现。相关的类型安全测试可查看 test/lifecycle/hook-types.test.ts。状态管理与 derive在上下文中注入新能力Elysia 的state定义全局可变状态derive则允许在处理函数执行前注入新的上下文属性——可以是新方法也可以派生新字段。example/derive.ts 是一个很有代表性的组合new Elysia() .state(counter, 0) .derive(({ store }) ({ increase() { store.counter } })) .derive(({ store }) ({ store: { doubled: store.counter * 2, tripled: store.counter * 3 } })) .get(/, ({ increase, store }) { increase() const { counter, doubled, tripled } store return { counter, doubled, tripled } }) .listen(3000, ({ hostname, port }) { console.log( running at http://${hostname}:${port}) })两个derive分别注入increase方法闭包引用同一store与doubled/tripled派生值。从类型层面看derive返回的对象形状会被合并进Singleton[derive]与Singleton[store]因此在处理函数中increase、store.doubled全部有精确类型。listen的回调接收{ hostname, port }供打印日志使用。与之相近的还有decorator注入常量属性与resolve每个请求执行并注入结果它们共同组成 src/index.ts 中Singleton泛型追踪的四种单例能力decorator / store / derive / resolve。Cookie签名与读写Elysia 对 Cookie 做了专门的类型化封装支持签名sign与校验。参考 example/cookie.tsconst app new Elysia({ cookie: { secrets: Fischl von Luftschloss Narfidort, sign: name } }) .get(/council, ({ cookie: { council } }) { council.value [{ name: Rin, affilation: Administration }] return council.value }, { cookie: t.Cookie({ council: t.Array(t.Object({ name: t.String(), affilation: t.String() })) }) }) .get(/update, ({ cookie: { name } }) { name.value seminar: Rio name.value seminar: Himari name.maxAge 86400 return name.value }, { cookie: t.Cookie({ name: t.Optional(t.String()) }) }) .listen(3000)要点全局配置cookie.secrets指定签名密钥cookie.sign指定需要签名的 Cookie 名每个 Cookie 以{ value, maxAge, ... }对象暴露写value即可设置响应 Cookiet.Cookie与t.Optional提供 Cookie 级的类型校验。Cookie 的签名、校验与合并逻辑实现在 src/cookies.ts并通过getCookieValidatorsrc/index.ts在 AOT/非 AOT 模式下生成校验器。Cookie 相关测试集中在 test/cookie/ 目录例如签名测试 test/cookie/signature.test.ts。错误处理Error 回调与自定义错误Elysia 允许在路由级声明error回调统一捕获该校验链上的错误同时支持全局onError。参见 example/error.tsnew Elysia() .post(/, ({ body }) body, { body: t.Object({ username: t.String(), password: t.String(), nested: t.Optional(t.Object({ hi: t.String() })) }), error({ error }) { console.log(error) } }) .listen(3000)当请求体不满足 Schema如缺少username时校验错误会进入error回调error对象携带校验失败详情。框架内置了完整的错误类型体系ValidationError、NotFoundError、InternalServerError与状态码常量status见 src/error.ts。全局错误处理可参考 test/core/handle-error.test.ts 与 test/lifecycle/error.test.ts。WebSocket一行声明实时能力Elysia 原生集成 Bun 的 WebSocket用.ws()声明即可。参考 example/websocket.tsconst app new Elysia() .state(start, here) .ws(/ws, { open(ws) { ws.subscribe(asdf) console.log(Open Connection:, ws.id) }, close(ws) { console.log(Closed Connection:, ws.id) }, message(ws, message) { ws.publish(asdf, message) ws.send(message) } }) .get(/publish/:publish, ({ params: { publish: text } }) { app.server!.publish(asdf, text) return text }) .listen(3000, (server) { console.log(http://${server.hostname}:${server.port}) })open/close/message三个事件钩子分别处理连接生命周期与消息ws.subscribe/ws.publish实现频道订阅广播app.server!.publish可从普通 HTTP 路由向频道推送消息底层实现在 src/ws/bun.ts类型定义在 src/ws/types.ts测试见 test/ws/ 目录如连接测试 test/ws/connection.test.ts、消息测试 test/ws/message.test.ts。模块化与扩展use、插件与 OpenAPIElysia 的扩展机制基于.use(plugin)任何new Elysia()实例都可以作为插件被其他实例挂载插件的 Store、decorator、Schema 与生命周期 Hook 会自动合并进宿主实例且类型同步更新。仓库的插件生态还包含官方子包elysiajs/openapi见 package.json 的 devDependencies可用于一键生成 OpenAPI 文档。从类型层面看插件合并依赖checksum指纹机制来区分与去重插件状态deduplicateChecksum见 src/utils.tsseed配置则为同名插件实例提供类型隔离。相关的模块化与类型测试可参考 test/core/modules.test.ts 与 test/plugins/ 目录。运行时适配与部署形态Elysia 采用适配器架构src/adapter/ 下包含三个实现Bun 适配器默认首选直接对接Bun.serve支持原生静态响应nativeStaticResponseWeb Standard 适配器基于标准Request/Response的适配用于 WinterCG 兼容环境Cloudflare Worker 适配器面向 Cloudflare Workers 部署支持预编译precompile以适配无服务器冷启动。构造时按config.adapter或运行环境自动选择typeof Bun ! undefined ? BunAdapter : WebStandardAdapter见 src/index.ts。package.json的exports字段package.json为每个子模块ws、compose、context、cookies、error、schema、sucrose、trace、type-system、adapter等都暴露了独立的 ESM/CJS 双格式入口与类型声明方便按需引入。从仓库源码看 Elysia 的工程化与质量保障若想深入了解框架实现推荐按以下路径阅读入口与路由src/index.ts —— 主类、add路由注册、ValidatorLayer三级校验合并类型系统src/type-system/ ——t.*的 TypeBox 定义与格式化Schema 编译src/schema.ts 与 src/replace-schema.ts —— 校验器生成与强转组合执行src/compose.ts —— AOT 组合处理器类型推导src/sucrose.ts —— 从处理函数签名反推 Schema 的推断引擎错误体系src/error.ts —— 校验错误与自定义状态码。质量保障方面仓库自带完整测试体系package.jsonpackage.json定义了bun test功能测试、tsc --project tsconfig.test.json类型测试、以及 Node 环境下的 CJS/ESM 导入测试test:node。测试用例覆盖路由test/bun/router.test.ts、生命周期test/lifecycle/、校验test/validator/、WebSockettest/ws/、类型系统test/type-system/与标准 Schema 兼容test/standard-schema/等维度。结语从 README 的一句定位出发Elysia 实际交付的是一整套“以类型为中心”的 Web 开发体验TypeBox Schema 同时是类型、校验器与文档来源guard、derive、state、生命周期 Hook 在编译期被精确追踪Bun 运行时与 AOT 编译把类型安全与性能融为一体适配器与插件机制则保证了从本机开发到 Cloudflare Workers 的一贯体验。如果你正在寻找一个既能在编译期抓住错误、又保持编写流畅度的 Bun 原生框架Elysia 值得在你的下一个项目中一试。赞分享后端Web框架【免费下载链接】elysiaErgonomic Framework for Humans项目地址https://gitcode.com/GitHub_Trending/el/elysia点击查看免费下载相关推荐Bun Elysia集成TypeScript优先的Web框架Bun Elysia集成TypeScript优先的Web框架 概述 在现代Web开发中开发者面临着性能、开发体验和类型安全的多重挑战。Bun作为新一代的Ja语言运行时后端开发工具包管理器前端构建测试The Algorithms - PHP从零开始掌握PHP算法与数据结构的完整指南The Algorithms PHP从零开始掌握PHP算法与数据结构的完整指南 The Algorithms PHP 是一个用 PHP 编程语言编写的算法与数音视频跨平台create-t3-app 中的 TypeScript 类型安全实践从类型推断到端到端类型安全create t3 app 中的 TypeScript 类型安全实践从类型推断到端到端类型安全 本指南以 create t3 app https://link开发工具CLI代码生成上一篇Rebass与ESLint组件开发的代码质量保障配置下一篇Nitro Vite tRPC构建无需代码生成的端到端类型安全 API创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考