百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

又一款 JavaScript 后端 Web 框架:Elysia v1.0 来了!

myzbx 2024-12-08 16:37 44 浏览

Elysia 是一个符合人体工程学的 Web 框架,用于使用 Bun 构建后端服务器。设计时考虑到简单性和类型安全性,使用熟悉的 API 和对 TypeScript 的广泛支持,并针对 Bun 进行了优化。

Elysia 针对 Bun 进行设计但不限于 Bun,对其他运行环境也做了兼容。Elysia 符合 WinterCG 的设计要求,您可以在 Cloudflare Worker、Vercel Edge Function 以及支持 Web 标准请求的大多数其他运行时上部署 Elysia 服务器。

Elysia 1.0 是经过 1.8 年开发后的第一个稳定版本。自开始以来,我们一直在等待一个专注于开发人员经验、速度以及如何为人类而不是机器编写代码的框架。

Elysia 在各种情况下对其进行实战测试,模拟中型和大型项目,向客户交付代码,这是 Elysia 有足够信心交付的第一个版本。Elysia 1.0 引入了重大改进,并包含 1 项必要的重大更改。

  • Sucrose - 重写模式匹配静态分析而不是正则表达式
  • 启动时间提高了 14 倍
  • 移除约 40 个路由和 TypeScript 实例限制
  • 更快的类型推断速度提高了约 3.8 倍
  • Treaty 2
  • Hook 类型(破坏性变化)
  • 严格错误检查的内联错误

Sucrose

Elysia 经过优化,在各种基准测试中表现出色,其中一个主要因素就是 Bun 和我们自定义的 JIT 静态代码分析。如果你不知道 Elysia 内嵌了某种「编译器」,它可以读取你的代码并生成优化的函数处理方式。

这个过程非常快速,而且无需构建步骤直接运行。不过由于它主要是用许多复杂的正则表达式编写的,因此维护起来很有挑战性,而且如果发生递归,速度有时会很慢。因此我们重写了静态分析部分,使用基于部分 AST 和模式匹配的混合方法「Sucrose」来分离代码注入阶段。

我们没有使用更准确的基于 AST 的完整方法,而是选择只实现所需的规则子集,以提高性能,因为它需要在运行时快速运行。Sucrose 擅长以较低的内存使用率准确推断处理程序函数的递归属性,推断时间最多可缩短 37%,内存使用率也显著降低。

从 Elysia 1.0 开始,Sucrose 将取代基于 RegEx 的部分 AST 和模式匹配。

缩短启动时间

有了 Sucrose 以及与动态注入阶段的分离,我们可以推迟 JIT 而不是 AOT 的分析时间。换句话说,「编译」阶段可以懒散地进行评估。

在路由首次匹配时,将评估阶段从 AOT 卸载到 JIT,并在服务器启动前缓存结果,按需编译而不是编译所有路由。

在运行时性能方面,单次编译通常很快,不超过 0.01-0.03 毫秒(毫秒而不是秒)。在中型应用和压力测试中,我们测得的启动时间快达 6.5-14 倍。

移除路由和实例限制

自 Elysia 0.1 以来,您最多只能堆叠 ~40 个路由和 1 个 Elysia 实例。

这是 TypeScript 的限制,每个队列的内存都是有限的,如果超过了,TypeScript 就会认为类型实例化过深,可能是无限的。作为一种变通方法,我们需要将实例分离到控制器中,以克服限制,并像这样重新合并类型以卸载队列。

const main = new Elysia()
    .get('/1', () => '1')
    .get('/2', () => '2')
    .get('/3', () => '3')
    // 重复 40 次
    .get('/42', () => '42')
    // 类型实例化过深,可能是无限的

不过,从 Elysia 1.0 开始,经过一年的类型性能优化(特别是尾部调用优化)和差异优化,我们已经克服了这一限制。这意味着理论上我们可以无限量地堆叠路由和方法,直到 TypeScript 崩溃。

const controller1 = new Elysia()
    .get('/42', () => '42')
    .get('/43', () => '43')

const main = new Elysia()
    .get('/1', () => '1')
    .get('/2', () => '2')
    // 重复 40 次
    .use(controller1)

因此,我们将 ~40 条路由的限制增加到 JavaScript 内存限制,因此尽量不要堆叠超过 ~558 条路由 / 实例,并在必要时分离到一个插件中。

让我们感觉 Elysia 还没有准备好投入生产的阻碍终于得到了解决。

类型推断改进

由于我们在优化方面付出的努力,我们在大多数 Elysia 服务器上的测试结果达到了约 82% 。

由于消除了堆栈的限制并提高了类型性能,即使在 500 个路由堆栈之后,我们也可以期望几乎即时的类型检查和自动完成。

通过预先计算类型而不是将类型重新映射到 Eden,Eden 条约的类型推断性能提高了 13 倍。总体而言 Elysia 和 Eden Treaty 一起执行时速度将提高约 3.9 倍。

以下是 450 条路由的 Elysia + Eden Treaty 在 0.8 和 1.0 上的比较。

使用 Eden Treaty 对 Elysia 进行 450 个路由的压力测试,结果如下:Elysia 0.8 花费了 ~1500 毫秒,Elysia 1.0 花费了 ~400 毫秒。

由于移除了堆栈限制和重新映射过程,现在可以为单个 Eden Treaty 实例叠加超过 1000 个路由。

Treaty 2

我们请求您就 Eden Treaty 提供反馈,告诉我们您喜欢什么以及可以改进的地方。您已经向我们指出了条约设计中的一些缺陷,并提出了几项改进建议。

正因如此,今天我们推出了 Eden Treaty 2,这是对更符合人体工程学设计的全面革新。

尽管我们不喜欢破坏性变化,但 Treaty 2 是对 Treaty 1 的继任者。

在 Treaty 2 中有哪些新内容:

  • 更符合人体工程学的语法
  • 端到端单元测试类型安全性
  • 拦截器
  • 无"#34;前缀和属性

我们最喜欢的是端到端单元测试类型安全性,因此与其启动模拟服务器并发送获取请求,不如使用 Eden Treaty 2 编写具有自动完成和类型安全性的单元测试。

两者之间的区别在于 Treaty 2 是 Treaty 1 的继任者。我们不打算对 Treaty 1 引入任何破坏性变化,也不强迫您升级到 Treaty 2。

您可以选择继续在当前项目中使用 Treaty 1,而无需升级到 Treaty 2,并且我们将以维护模式进行维护。您可以导入 treaty 来使用 Treaty 2,或者导入 edenTreaty 来使用 Treaty 1。

Treaty 2 的文档可在「Treaty概述」中找到,而 Treaty 1 的文档则位于「Treaty Legacy」。

Hook 类型

我们讨厌破坏性更改,这是我们第一次在大规模上进行此操作。我们为 API 设计投入了很多精力,以减少对 Elysia 所做的更改,但这是修复有缺陷设计的必要步骤。

以前当我们添加一个带有 on 的挂钩时,比如 onTransform 或者 onBeforeHandle,它会变成一个全局挂钩。这对于创建像插件之类的东西非常好,但不适合像控制器之类的本地实例。

const plugin = new Elysia()
    .onBeforeHandle(() => {
        console.log('Hi')
    })
    // log Hi
    .get('/hi', () => 'in plugin')

const app = new Elysia()
    .use(plugin)
    // will also log hi
    .get('/no-hi-please', () => 'oh no')

为了解决这个问题,我们引入了一个钩子类型,通过引入 hook-type 来指定钩子应该如何继承。

钩子类型可分为以下几类:

  • local(默认)- 仅适用于当前实例和后代实例
  • 作用域 - 仅适用于 1 个上代实例、当前实例和后代实例
  • 全局(旧行为)- 适用于应用该插件的所有实例(所有祖先、当前和后代)

要指定钩子的类型,只需向钩子添加 { as: hookType } 即可。

内联错误

从 Elysia 0.8 开始,我们可以使用该 error 函数返回带有状态代码的响应以进行 Eden 推理。然而这有一些缺陷。

如果您为路由指定响应架构,Elysia 将无法为状态代码提供准确的自动完成功能。例如,缩小可用状态代码的范围。

内联错误可以从模式生成细粒度类型,提供类型缩小、自动完成和对值准确性的类型检查,在值而不是整个函数处用红色波浪线下划线。我们建议使用内联错误而不是导入错误,以获得更准确的类型安全性。

后续的计划

达到稳定发布意味着我们相信 Elysia 足够稳定并且可以在生产中使用。保持向后兼容性现在是我们的目标之一,除了安全性之外,我们努力避免对 Elysia 进行重大更改。我们的目标是让后端开发变得简单、有趣和直观,同时确保使用 Elysia 构建的产品拥有坚实的基础。

我们将专注于完善我们的生态系统和插件。引入一种符合人体工程学的方法来处理冗余和平凡的任务,开始一些内部插件重写、身份验证、JIT 和非 JIT 模式之间的同步行为以及通用运行时支持。

Bun 在运行时、包管理器及其提供的所有工具中都表现出色,我们相信 Bun 将成为 JavaScript 的未来。我们相信,通过向 Elysia 开放更多运行时并提供有趣的 Bun 特定功能,或者至少易于配置,例如 Bun Loaders API,最终将让人们更多地尝试 Bun,而不是 Elysia 选择仅支持 Bun。

Elysia 核心本身部分兼容 WinterCG,但并非所有官方插件都适用于 WinterCG,有一些具有 Bun 特定功能,我们希望修复该问题。我们还没有通用运行时支持的具体日期或版本,因为我们将逐步采用和测试,直到确保它可以正常工作而不会出现意外行为。

您可以期待以下运行时的支持:Node、Deno、Cloudflare Worker。

我们还希望支持以下内容:Vercel Edge Function、Netlify Function、AWS Lambda / LLRT。

我们还支持并测试 Elysia 在以下支持服务器端渲染或边缘功能的框架上:Nextjs、Expo、Astro、SvelteKit。

相关推荐

如何设计一个优秀的电子商务产品详情页

加入人人都是产品经理【起点学院】产品经理实战训练营,BAT产品总监手把手带你学产品电子商务网站的产品详情页面无疑是设计师和开发人员关注的最重要的网页之一。产品详情页面是客户作出“加入购物车”决定的页面...

怎么在JS中使用Ajax进行异步请求?

大家好,今天我来分享一项JavaScript的实战技巧,即如何在JS中使用Ajax进行异步请求,让你的网页速度瞬间提升。Ajax是一种在不刷新整个网页的情况下与服务器进行数据交互的技术,可以实现异步加...

中小企业如何组建,管理团队_中小企业应当如何开展组织结构设计变革

前言写了太多关于产品的东西觉得应该换换口味.从码农到架构师,从前端到平面再到UI、UE,最后走向了产品这条不归路,其实以前一直再给你们讲.产品经理跟项目经理区别没有特别大,两个岗位之间有很...

前端监控 SDK 开发分享_前端监控系统 开源

一、前言随着前端的发展和被重视,慢慢的行业内对于前端监控系统的重视程度也在增加。这里不对为什么需要监控再做解释。那我们先直接说说需求。对于中小型公司来说,可以直接使用三方的监控,比如自己搭建一套免费的...

Ajax 会被 fetch 取代吗?Axios 怎么办?

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!今天给大家带来的主题是ajax、fetch...

前端面试题《AJAX》_前端面试ajax考点汇总

1.什么是ajax?ajax作用是什么?AJAX=异步JavaScript和XML。AJAX是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX可以使网页实...

Ajax 详细介绍_ajax

1、ajax是什么?asynchronousjavascriptandxml:异步的javascript和xml。ajax是用来改善用户体验的一种技术,其本质是利用浏览器内置的一个特殊的...

6款可替代dreamweaver的工具_替代powerdesigner的工具

dreamweaver对一个web前端工作者来说,再熟悉不过了,像我07年接触web前端开发就是用的dreamweaver,一直用到现在,身边的朋友有跟我推荐过各种更好用的可替代dreamweaver...

我敢保证,全网没有再比这更详细的Java知识点总结了,送你啊

接下来你看到的将是全网最详细的Java知识点总结,全文分为三大部分:Java基础、Java框架、Java+云数据小编将为大家仔细讲解每大部分里面的详细知识点,别眨眼,从小白到大佬、零基础到精通,你绝...

福斯《死侍》发布新剧照 "小贱贱"韦德被改造前造型曝光

时光网讯福斯出品的科幻片《死侍》今天发布新剧照,其中一张是较为罕见的死侍在被改造之前的剧照,其余两张剧照都是死侍在执行任务中的状态。据外媒推测,片方此时发布剧照,预计是为了给不久之后影片发布首款正式预...

2021年超详细的java学习路线总结—纯干货分享

本文整理了java开发的学习路线和相关的学习资源,非常适合零基础入门java的同学,希望大家在学习的时候,能够节省时间。纯干货,良心推荐!第一阶段:Java基础重点知识点:数据类型、核心语法、面向对象...

不用海淘,真黑五来到你身边:亚马逊15件热卖爆款推荐!

Fujifilm富士instaxMini8小黄人拍立得相机(黄色/蓝色)扫二维码进入购物页面黑五是入手一个轻巧可爱的拍立得相机的好时机,此款是mini8的小黄人特别版,除了颜色涂装成小黄人...

2025 年 Python 爬虫四大前沿技术:从异步到 AI

作为互联网大厂的后端Python爬虫开发,你是否也曾遇到过这些痛点:面对海量目标URL,单线程爬虫爬取一周还没完成任务;动态渲染的SPA页面,requests库返回的全是空白代码;好不容易...

最贱超级英雄《死侍》来了!_死侍超燃

死侍Deadpool(2016)导演:蒂姆·米勒编剧:略特·里斯/保罗·沃尼克主演:瑞恩·雷诺兹/莫蕾娜·巴卡林/吉娜·卡拉诺/艾德·斯克林/T·J·米勒类型:动作/...

停止javascript的ajax请求,取消axios请求,取消reactfetch请求

一、Ajax原生里可以通过XMLHttpRequest对象上的abort方法来中断ajax。注意abort方法不能阻止向服务器发送请求,只能停止当前ajax请求。停止javascript的ajax请求...