Javascript-将Curveball移植到Bun上

143 阅读4分钟

将Curveball移植到Bun上

Bun是热门的服务器端Javascript运行时,与NodeDeno同属一类。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端口启动一个服务器。正如你在这里看到的,这使用了你在浏览器中使用的标准RequestResponse对象,并且可以使用async/await。

这些都是在Node和Express刚创建时不存在的东西,但对于今天的东西来说似乎是很好的想法。我不认为使用RequestResponse 适合更复杂的使用情况(流式响应、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最近成功的启发。