比较Node.js框架——tinyhttp与Express.js

857 阅读5分钟

在本指南中,我们将比较用Node.js构建Web应用程序的最常用框架之一Express.js和其最流行的替代品之一tinyhttp。

以下是我们要介绍的内容。

什么是 tinyhttp?

tinyhttp是一个类似于 Express.js 的现代网络框架,是用 TypeScript 编写的。与 Express.js 相比,它使用了非常少的依赖性,这使得它的速度超快。

tinyhttp 提供了路由、req/res 扩展等功能,同时只依赖于六个模块,其中四个是 tinyhttp 自己的。

所有为 Express.js 创建的中间件都能与 tinyhttp 顺利地工作。请看这个tinyhttp + Express/GraphQL集成的例子,了解如何用 tinyhttp 使用 Express.js 中间件。

tinyhttp 还支持路由的 async/await,这在 Express.js 中是不存在的。tinyhttp 内部有适当的类型和一个函数检查器,可以解决异步函数。换句话说,同步和异步在 tinyhttp 中都能正常工作。看看这些asyncMongoDB的例子,看看如何制作 async 处理程序。

根据官方文档,下面是 tinyhttp 最重要的功能的简短列表。

  • 比 Express 快 2.5 倍
  • 完整的Express中间件支持
  • 支持异步中间件
  • 本地ESM和CommonJS支持
  • 没有遗留的依赖,只有 JavaScript 本身
  • 开箱即用的类型
  • 没有内置的中间件支持

什么是Express.js?

Express.js是一个灵活的Node.js框架,为Web和移动应用程序提供了一套强大的功能。创建强大的API非常容易,因为Express.js带有很多中间件和其他内置的支持。

Express.js并没有配备数据库,这要由第三方模块来完成,这使得你可以与几乎所有的数据库对接。Express.js支持无数的模板引擎,与(path, locals, callback) 签名。

这个框架的构建方式是,它作为一个最小和灵活的Node.js网络应用程序框架,为构建单页、多页和混合网络应用程序提供了一套强大的功能。

Express.js的一些特点。

  • 开源社区支持
  • 快速的应用开发
  • 易于学习
  • 支持模板引擎
  • I/O处理
  • 内置的中间件支持

tinyhttp vs. Express.js:一个基本的比较

对于 tinyhttp 和 Express v4 的高层次比较,让我们看看支持的最小 Node.js 版本、ECMAScript 版本、测试覆盖率等。

标准tinyhttpExpress v4
最低支持的 Node.js 版本12.4.00.10.0
最低支持的ECMAScript版本ES2019ES5 (?)
req /res 扩展✔✔
测试覆盖率92%100%
编译为本地ESM✔✖
支持TypeScript✔✖
软件包大小(仅核心部分35.2 kB208 kB
内置中间件✖✔

关于上表的一些说明。

  • tinyhttp工作所需的最低Node.js版本是12.4.0,而在Express v4中,我们甚至可以从Node.js 0.10.0开始工作。
  • tinyhttp的最低支持版本是ES2019(ES10),而在Express v4中,我们需要ES5。
  • req 是一个包含引发事件的 HTTP 请求信息的对象。在对req 的响应中,你使用res 来发回所需的 HTTP 响应。tinyhttp 和 express v4 都支持req/res 扩展。
  • 对于 tinyhttp 来说,代码库的测试覆盖率是 92%,对于 Express.js v4 来说是 100%。
  • 与ES6(或ES2015)规范一起引入的ESM(EcmaScript Modules)规范描述了如何在JavaScript中导入和导出模块。我们可以在 tinyhttp 中使用 ESM,但我们需要外部支持,比如Babel,用于 Express.js。
  • 与Express.js不同,tinyhttp带有TypeScript支持。
  • tinyhttp 的核心包大小为 35.2kB,而 Express.js 为 208kB。
  • tinyhttp没有内置的中间件。Express.js 则有内置的中间件

性能标杆

说完了基本情况,让我们看看使用fastify 基准测试工具的性能报告。在这里,我们使用req/s、transfer/s和latency等参数来衡量两个框架的性能。

下面是关于这个基准测试所使用的硬件、系统和条件的一些说明。

  • 硬件
    • 小米Pro 2019版(笔记本电脑
    • CPU。英特尔酷睿i7-8550U
    • 内存:16GB
  • 系统。
    • 内核:5.7.19-2
    • 节点。15.5
  • 条件
    • 100个连接
    • 10条管道
    • 40s持续时间
框架req/s传输/秒延迟
@tinyhttp/app (w/o exts)245753.81 MB3.37毫秒
@tinyhttp/app (esm)228203.54 MB4.04 ms
@tinyhttp/app (cjs)226373.51 MB4.08 ms
express@4.17.1129862 MB7.11 ms

req/s 是指每秒的请求数。Latency 是指用户的行动和网络应用程序对该行动的响应之间的延迟,也被称为总的往返时间。

从上表中,我们可以看到,tinyhttp能够以更低的延迟在每秒进行更多的传输,而不是Express.js v4

注意:基准测试并不完全准确,在每次运行和每台机器上都可能有所不同。关键是要比较比例而不是绝对值。

总结我们的性能基准,tinyhttp(没有额外的req/res 扩展)比 Express.js 快了 ~1.9 倍。

tinyhttp 和 Express.js 在运行。一个简单的例子

现在是时候建立一个简单的应用实例了,这样我们就可以看到 tinyhttp 和 Express.js 并肩作战的情况。

你可以使用任何软件包管理器来安装 tinyhttp 和 Express。我将使用npm来演示。

要安装 tinyhttp。

npm i @tinyhttp/app

安装 Express.js。

npm install express

'Hello World

Express.js 和 tinyhttp 应用程序的结构非常相似。如果你知道 Express.js,那么你也知道 tinyhttp。

tinyhttp。

import { App } from '@tinyhttp/app'
const app = new App()
const PORT = 3000

app
  .get('/', (_, res) => void res.send('<h1>Hello World</h1>'))
  .listen(PORT, () => console.log(`Started on http://localhost:${PORT}!`))

Express.js。

const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send('Hello world');
});

app.listen(3000, () => console.log('listening on port 3000'));

你可能注意到,我们没有使用require ,而是使用了 ESM 的导入。tinyhttp 被设计为与Native ESM 一起使用。与 Express 不同,tinyhttp 被编译为 ESM 和 CommonJS 的模块系统。同时,不知为何,它仍然比 Express.js 小得多。

你可以用它在 Node.js 中使用import/export 语法。要设置一个Node ESM包,把"type": "module" 放在package.json 文件中,像这样。

{
  "type": "module"
}

另一个选择是使用.mjs 扩展。这样,你就不需要把那个"type" 字段放在package.json 。欲了解更多信息,请查看ECMAScript Modules Node.js文档

因为最流行的 Express.js 中间件也使用了过时的模块,所以 tinyhttp 提供了一套它对流行的物品的重写/重制,比如logger,session, 等等。

路由

现在让我们来看看如何在 tinyhttp 和 Express.js 中处理一些基本的路由。Express.js 在他们的reqres 对象中包含了很多辅助函数。tinyhttp 使用诸如res.send,res.download,res.redirect 等方法完全实现了 Express.js 的 APIs。

tinyhttp。

import { App } from '@tinyhttp/app'
import { once } from 'events'

const app = new App()
const PORT = 3000

app.get('/', (req, res) => {
    res.send('Sent a GET!')
})

app.post('/', async (req, res) => {
    // Nothing complex here, we just listen to 'data' event and return the data as a promise to a `data` variable
    const data = await once(req, 'data').then(d => d.toString())

    // And then we send it
    res.end(`Sent some data: ${data}`)
})

app.listen(PORT, () => console.log(`Started on http://localhost:${PORT}!`))

Express.js

var express = require('express');
var app = express();

app.get('/', function(req, res){
   res.send("Send a GET!");
});

app.post('/', function(req, res){
   res.send("hello'!\n");
});

app.listen(3000);

结论

tinyhttp 既快又轻,你今天就可以开始在后端应用中使用它。tinyhttp存储库包含了很多例子,包括MongoDBGraphQL的集成。当你需要用最少的代码快速入门时,我会推荐使用 tinyhttp。

也就是说,Express.js仍然很受欢迎,并将继续在主要项目和行业中使用,因为它有广泛的开源社区支持和简单的学习曲线。

tinyhttp vs. Express.js一文。对比Node.js框架,首先出现在LogRocket博客上。