将Curveball移植到Bun上
Bun是热门的服务器端Javascript运行时,与Node和Deno同属一类。Bun使用来自Webkit的JavascriptCore引擎,而不像Node和Deno那样使用V8。一个很大的卖点是它在许多基准测试中的速度更快,然而我个人感到兴奋的是它的一些生活质量的特性。
- 它默认解析Typescript和JJSX(但不进行类型检查),这意味着不需要一个单独的 "dist "目录,也不需要像
ts-node。 - 它默认加载
.env文件。 - 它与NPM、
package.json,以及许多内置的Node模块兼容。
我还喜欢它的'Hello world HTTP server',就像写这个文件一样简单。
// http.ts
export default {
port: 3000,
fetch(request: Request): Promise<Response> {
return new Response("Hello world!");
},
};
然后用运行它。
bun run http.ts
Bun会识别出一个带有fetch 功能的对象是默认导出的,并在3000端口启动一个服务器。正如你在这里看到的,这使用了你在浏览器中使用的标准Request和Response对象,并且可以使用async/await。
这些都是在Node和Express刚创建时不存在的东西,但对于今天的东西来说似乎是很好的想法。我不认为使用Request 和Response 适合更复杂的使用情况(流式响应、1xx 响应、拖车、升级到其他协议、获得 tcp 连接元数据如 remoteAddr 是我想到的一些情况),因为这些对象首先是为客户端设计的。
但在很多情况下,人们只是在构建简单的端点,对于这一点,它是很好的。
Bun支持大量的标准Node模块,但它也缺少一些,比如对服务器端websockets和node http/https/https包的支持,这使得它目前与Express等流行框架不兼容。
移植Curveball
Curveball是一个Typescript微框架,我们从2018年中期开始开发,作为Express和Koa的现代替代品。Curveball与这两个框架的一个关键区别是,它完全抽象和封装了Node提供的核心 "请求 "和 "响应 "对象。
这使得过去创建一个lambda集成变得非常容易;而不是映射到Node的Request和Response类型,我所需要的只是Lambdas对请求和响应的想法的简单映射函数。
为了让Express在AWS Lambda上运行,需要模拟Nodehttp 栈,或者需要启动和代理一个完整的HTTP/TCP服务器。这些变通方法都需要从serverless-express等库中获取大量的代码。
因此,随着Bun的出现,要么需要做同样的工作来模拟Node的API,要么Bun就需要为Nodehttp 模块增加完全的兼容性(最终会出现)。
但由于Curveball的消息抽象,它相对容易启动和运行。大部分的工作是把Node特有的代码移到一个新的包里。
这是Bun上的Curveball "hello world"。
import { Application } from '@curveball/kernel';
const app = new Application();
// Add all your middlewares here! This should look familiar to Koa users.
app.use( ctx => {
ctx.response.body = {msg: 'hello world!'};
});
export default {
port: 3000,
fetch: app.fetch.bind(app)
};
它仍然是一个实验性的,但是以下的中间件已经被测试了。
而且由于JSX也只是在Bun中工作,所以用它来生成HTML也相对容易。
import { Application } from '@curveball/kernel';
import reactMw from '@curveball/react';
import React from 'react';
const app = new Application();
app.use(reactMw());
app.use( ctx => {
ctx.response.type = 'text/html; charset=utf-8';
ctx.response.body = <html>
<body>
<div>
<h1>Hello world!</h1>
</div>
</body>
</html>;
});
export default {
port: 3000,
fetch: app.fetch.bind(app)
};
这不是一个完整的水化/服务器渲染解决方案,但JSX已经取代了我们在Bad Gateway的EJS和Handlebars等模板引擎。JSX让你做同样的事情,但你得到了类型检查的优势,它更难创建XSS漏洞和完全的Javascript访问。
关于Bun的最终想法
与Deno相比,将Curveball移植到Bun上要容易得多。Deno是一个更大的挑战,因为它对包和模块的加载有着截然不同的想法。这已经是一年多以前的事了,所以值得再试一试。
所以,我很好奇这一切的发展。也许Bun是未来,也许我们会看到Node与Bun平起平坐,使其过时。无论怎样,竞争是好的。
我觉得Bun比Deno有更好的机会,因为它提供了许多优势和功能,同时大部分是在Node的生态系统中。
尽管事实证明,Deno也改变了他们的调子,并将兼容作为一个新的目标。我不禁要问,这是否也是受到Bun最近成功的启发。