为了账号安全,请及时绑定邮箱和手机立即绑定

2024年Node.js框架大比拼——Elysia、Hono、Nest、Encore,选哪个最适合自己?

Node.js web框架——我们甚至都不知道从哪里开始好了。面对这么多的选择,为项目挑选合适的框架可能会让人感到无从下手。

在这篇文章中,我将带你了解 最火 的 Node.js 生态系统中的框架,分析每个框架的优点、缺点及最佳应用场景。

无论你是追求速度、可扩展性还是简洁,我们希望能涵盖所有这些方面——所以到最后,你就能准确地找到哪个框架最适合你。

我们要看看的框架有:NestElysiaEncore.tsHono

视频版:

来吧,开始!

功能简介

我认为,从最轻量级到功能最丰富的,我将这些框架排列如下:

功能概览图

这并不意味着轻量级就是不好的,这仅仅取决于你的项目需要什么。Hono 的轻量级特性实际上是一个亮点,不到14KB,特别适合用于 Cloudflare Workers。

Encore.ts 相比之下则自带许多内置功能,比如开箱即用的自动跟踪和本地基础设施。

我们先来看看每个框架,我们先从Encore.ts开始。

Encore.ts

一个开源框架,旨在让用TypeScript构建健壮且类型安全的后端更简单。该框架自带大量工具,使开发体验更顺滑,性能上是这轮比较中最快的框架之一。

类型安全的API模式定义 CORS处理 结构化日志 认证
发布/订阅集成 密钥管理 基础设施集成 数据库集成
架构图 本地开发仪表板 服务目录 原生TypeScript
调试 错误处理 事件循环 请求验证
跟踪 API客户端生成 自动本地基础设施 自动化测试

Encore内置了请求验证功能。你用常规TypeScript定义的请求和响应类型将用于编译时和运行时的请求验证。与其他框架不同的是,实际的验证是由Rust而不是JavaScript来完成的。这一特点使得验证非常快,关于这一点,我们稍后会详细说明。

import {api, Header, Query} from "encore.dev/api";

enum 枚举值 {
  FOO = "foo",
  BAR = "bar",
}

// Encore.ts 会自动验证请求模式,如果请求不符合模式,则返回错误信息。
interface 请求验证模式 {
  foo: Header<"x-foo">;
  name?: Query<string>;

  someKey?: string;
  someOtherKey?: number;
  requiredKey: number[];
  nullableKey?: number | null;
  multipleTypesKey?: boolean | number;
  enumKey?: 枚举值;
}

// 验证请求
export const 请求验证模式 = api(
  {expose: true, method: "POST", path: "/validate"},
  (data: 请求验证模式): { message: string } => {
    console.log(data);
    return {message: "验证通过了"};
  },
);

进入全屏模式 或 退出全屏模式

Encore使创建和调用服务变得非常简单。从代码角度来看,一个服务只是你仓库中的另一个文件夹。当你调用服务中的一个端点时,这就像调用一个普通的函数一样。更酷的是,实际上这些函数调用会在后台被转换为真正的 HTTP 请求。部署时,你可以选择将服务部署到不同的实例,比如 Kubernetes 集群中,而所有服务代码仍保留在同一个仓库里。

导入一个服务后,像调用普通函数一样调用 API 端点

    import { api } from "encore.dev/api";
    import { hello } from "~encore/clients"; // 导入 'hello' 服务模块

    export const myOtherAPI = api({}, async (): Promise<void> => {
      // 通过函数调用 ping 端点
      const resp = await hello.ping({ name: "World" });
      console.log(resp.message); // '你好,世界!'
    });

点击全屏 结束全屏

使用 Encore.ts,你可以将基础设施作为类型安全的对象进行集成到应用代码中。创建一个数据库或 Pub/Sub 主题只需几行应用代码。Encore.ts 会将你的应用打包成 Docker 镜像,在部署时,你只需提供运行时配置,就这样。

用一行代码创建PostgreSQL数据库

    import { SQLDatabase } from "encore.dev/storage/sqldb";

    const db = new SQLDatabase("userdb", {migrations: "./migrations"});
    // ... 例如,使用 db.query 进行数据库查询。

进入全屏模式。退出全屏模式。

创建主题并订阅它们

    import { Topic } from "encore.dev/pubsub";

    export interface User { // 属性...
    }

    const signups = new Topic<User>("signup", {
      deliveryGuarantee: "at-least-once",
    });

    await signups.publish({ ... });

全屏。退出全屏。

此外,Encore 还自带一个 内置开发控制台。启动 Encore 应用时,开发控制台可以在 localhost:9400 访问。你可以在这里调用你的端点,有点像 Postman。每次调用你的应用都会生成一个追踪,你可以查看追踪以了解 API 请求、数据库调用和 Pub/Sub 消息。本地开发控制台还提供 自动 API 文档实时更新的架构图

本地发展动态板

值得一提的是,尽管Encore拥有许多功能,却没有任何npm依赖。

霍诺

Hono 是由 Yusuke Wada 创建的。他于 2021 年启动了该项目,因为当时没有适合 Cloudflare Workers 的好 Node.js 框架,这让他感到不满。从那时起,Hono 逐步增加了对 Node.js、Bun 和 Deno 等运行时的支持。

// 导入Hono库
import { Hono } from 'hono'
// 创建一个新的Hono应用
const app = new Hono()

// 当用户访问根路径时,返回'Hono!'文本
app.get('/', (c) => c.text('Hono!'))

// 导出应用
export default app

全屏切换:进入,退出

Hono真的很小,hono/tiny预设的大小只有不到13KB,非常适合部署到Cloudflare Workers上。Hono没有任何NPM依赖项,这真的太棒了!

多运行时的卖点真的很有趣,无论你用哪种 JavaScript 运行时,都可以运行 Hono。在他们的仓库里,有一个称为适配器的概念,你可以看到他们为每个运行时做的调整。这确实对吸引用户和扩展用户基数有很大帮助,但对于单个用户来说,一旦你的应用部署到云端,通常不会去切换运行时。

虽然 Hono 本身很轻量,它也有一系列的 中间件 ,既有第一方的也有第三方的,你可以安装这些中间件来增强你的应用。这种“需要时再添加”的方法与 Express 流行的做法类似。这种做法在应用较小的时候效果很好,但随着应用变大,维护一个庞大的依赖列表可能会变得相当麻烦。

艾丽西娅

Elysia,就像 Encore 一样,是 专为 TypeScript 构建的,并且在你的 API 处理程序中也提供类型安全性。了解你在 API 处理程序中处理的内容可以节省大量时间,而且无需在代码中添加各种类型检查真是太好了。

你通过 t 模块指定类型,该模块是 TypeBox 验证库 的一个扩展。与 Encore 不同,, 验证发生在 JavaScript 层,这会带来一些性能损耗。

    import { Elysia, t } from 'elysia'

    new Elysia()
      .patch("/profile", ({ body }) => body.profile, {
        body: t.Object({
          id: t.Number(),
          profile: t.File({ type: "image" }),
        }),
      })
      .listen(3000);

进入全屏,退出全屏

添加Swagger文档只需一行代码,Elysia内置支持OpenTelemetry,这确实很方便,因此你可以轻松地监控你的应用,无需考虑平台。

艾莉西娅很快啊!但没有恩科拉那么快,如你将在下一节看到的。

Nest.js (一个基于 Node.js 的框架)

Nest.js 与其他用于比较的框架有些不同。Encore、Elysia 和 Hono 提供极简的 API 用于创建端点和中间件,并且你可以自由地按照自己的喜好来构建业务逻辑。而 Nest.js 则更加有自己的主张,强制你以某种特定的方式来组织代码。它提供了一种模块化架构,将代码组织成不同的抽象部分,例如提供者、控制器、模块和中间件。

Nest 设计目的是为了使更大的应用程序的维护和开发变得更加容易。但是否喜欢 Nest 提供的这种有倾向性的结构,最终这完全取决于个人的看法。在我看来,对于那些长期可维护性比速度和简洁性更重要的大规模项目来说,使用 Nest 可能更有优势。但对于只有少数开发者的较小项目来说,这种额外的抽象层次在大多数情况下可能是多余的。与 Hono、Encore 和 Elysia 这些框架相比,Nest 的这种倾向性也会导致一个更陡峭的学习曲线。

[很难学]

在使用 Nest 时,你可以选择使用 ExpressFastify 作为 Nest 底层的 HTTP 服务器框架。所有 Nest 的功能都是在其之上构建的。

性能

速度可能不是选择框架时最重要的考量,但也不能完全忽视。它会影响应用的响应速度,进而影响你的托管费用。

速度

我们分别在有和没有请求验证的情况下进行了性能测试,测量单位为每秒请求数。括号中的名称为所使用的请求验证库(如果有),而Encore.ts自带请求验证。

基准

Encore.ts 在我们进行的基准测试中是所有框架中速度最快的,其次是 Elysia、Hono、Fastify 和 Express。因为 Nest 在底层使用的是 Fastify 或 Express,所以 Nest 应用的性能应该差不多,不过由于 Nest 会增加一些额外的开销,所以可能会稍微慢一点。

Encore.ts怎么可以这么快呀?秘诀就在于Rust运行时,Rust确实很快!

Encore.ts实际上分为两部分。

面向用户的 TypeScript 部分,用于定义 API 和基础架构。

  1. 内部有一个用 Rust 语言编写的支持多线程的运行时。

性能提升的关键是从 Node.js 的单线程事件循环中转移尽可能多的任务到 Rust 的运行时。

例如,Rust 运行时负责处理所有的输入输出,比如接收传入的 HTTP 请求或从数据库读取数据。一旦这些请求或查询被完全处理,就会交给 Node.js 的事件循环。

代码结构

Hono、Elysia 和 Encore 对你如何编写代码没有严格规定。并且它们在创建 API 和中间件的过程中也非常相似。

这里为每个框架提供了一个GET端点。当然存在一些差异,但仔细一看,这些API看起来相当相似。至少在我看来,这不应成为决定性因素。

Encore.ts (一个文件名)

    interface Response {
      message: string;
    }

    export const get = api(
      { expose: true, method: "GET", path: "/hello/:name" },
      async ({ name }: { name: string }): Promise<Response> => {
        const msg = `Hello ${name}!`;
        return { message: msg };
      },
    );

进入全屏 退出全屏

艾莉西亚

    import { Elysia, t } from "elysia";

    new Elysia()
      .get(
        "/hello/:name",
        ({ params }) => {
          const msg = `你好 ${params.name}!`;
          return { message: msg };
        },
        {
          response: t.Object({
            message: t.String(),
          }),
        },
      )

进入全屏,退出全屏

霍诺

    import { Hono } from "hono";

    const app = new Hono();

    app.get("/hello/:name", async (c) => {
      // 这里我们回应一个问候信息给用户
      const msg = `你好 ${c.req.param("name")}!`;
      return c.json({ message: msg });
    });

全屏查看,退出全屏

真正起关键作用的是在构建坚固的应用程序时能够依赖类型安全。Encore 和 Elysia 提供类型安全的 API,而 Encore 更进一步,在与基础架构如 Pub/Sub 交互时提供编译时的类型安全。使用 Encore 调用另一个服务的端点时也能获得编译时的类型安全。如果你之前曾接触过微服务架构,你一定知道这有多重要。

GIF 类型安全

Nest.js 在 API 设计上确实非常出色。Nest 应用中有许多概念和抽象,这完全看你的喜好如何。当你查看一个 Nest 应用时,你会发现一个显眼的特点就是它大量使用了 装饰器。Nest 非常依赖于装饰器,例如,在使用依赖注入将服务插入控制器时。

巢控

    import { Controller, Get } from '@nestjs/common';
    import { AppService } from './app.service';

    /**

* @Controller() 注解用于定义 NestJS 控制器。
     */
    @Controller()
    export class AppController {
      /**

* 构造函数注入 AppService 实例。
       */
      constructor(private readonly appService: AppService) {}

      /**

* @Get() 装饰器定义了一个 HTTP GET 请求处理函数。
       */
      @Get()
      getHello(): string {
        return this.appService.getHello();
      }
    }

全屏模式 退出全屏

说实话,我对这个没太多感觉,我相信我也不是唯一一个这么想的。

部署和基础设施

这些框架都很相似,都可以部署到所有主流的云平台(例如 Digital Ocean 和 Fly.io),或者直接部署到像 AWS 或 GCP 这样的服务商。

Encore 提供自动本地基础设施。运行 encore run 可启动你的应用,并自动搭建所有本地基础设施,如数据库和 Pub/Sub 主题。告别那些 YAML、Docker Compose 等常见麻烦。

GIF,再跑一次

在构建Encore应用时,你可以获得一个运行时配置文件,用于提供连接你云中基础设施所需的配置信息。

如果你想快速将Encore应用部署到云端,又不想自己动手的话,你可以使用Encore Cloud。Encore Cloud 提供 CI/CD 和 pull request 的预览环境。当然,你也可以选择在你的 AWS 或 GCP 上自动为你配置所有必要的基础设施。这意味着你的应用不再受制于任何第三方服务,你对所有基础设施都有完全的控制权。

Hono 的特别之处在于它支持多种不同的运行时,因此在部署方面你有很多选择。你可以轻松地部署到 Cloudflare Workers、Netlify 或 AWS Lambda,且几乎不需要任何配置。

使用 Nest 时,你可以运行 nest build 命令来将你的 TypeScript 代码编译成 JavaScript。该过程会生成一个包含编译文件的 dist 目录。基本上就这样,然后你可以用 Node.js 来运行 dist 文件夹中的代码。

推荐的部署 Elysia 应用方式是使用 bun build 命令将你的应用编译成二进制。一旦编译成二进制,运行服务器时就不需要在机器上安装 Bun 了。

结尾

就这样吧!希望你知道下一个项目该用什么框架了。

如果你想了解更多关于Encore.ts的内容,可以在GitHub上查看这个开源项目:https://github.com/encoredev/encore

推荐:

Encore ## NestJS 与 Encore.ts:选择适合您 TypeScript 微服务架构的正确框架 Marcus Kohlberg 发布于 Encore ・ Oct 30 #javascript #typescript #微服务架构 #webdev

Encore ## 如何使用Docker和Encore在DigitalOcean (数字海洋) 上部署后端应用 Marcus Kohlberg 发布于 Encore ・ 2023年10月 #开源项目 #javascript #docker #go

Encore ## 选择合适的技术栈:开发人员指南 Lucas Lima do Nascimento 供 Encore · 2021年10月28日 #新手 #Web 开发 #教程 #职业

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消