https://wasmer.io/posts/announcing-winterjs-service-workers

宣布 WinterJS

![发布封面图片](https://wasmer.io/_next/image?url=https%253A%252F%252Fstorage.googleapis.com%252Fwapm-registry-prod%252Foriginal_images%252Fcover-image.jpg&w=3840&q=75 )

今天,我们非常高兴地宣布 WinterJS(wasmer/winterjs 包)。

WinterJS 是一个用 Rust 编写的 JavaScript Service Workers 服务器,它使用 SpiderMonkey 运行时来执行 JavaScript(与 Firefox 使用的运行时相同)。 我们选择遵循 WinterCG 规范,以最大程度地兼容其他服务,例如 Cloudflare Workers、Deno Deploy 和 Vercel(因此名为 WinterJS)。

WinterJS 不仅极快™️,而且还可以编译为 WebAssembly 感谢 WASIX,因此也可以与 Wasmer 一起运行。

让我们看看它是如何工作的。 我们将首先创建一个简单的“serviceworker.js”文件,该文件仅返回一个简单的“hello world”;

 addEventListener('fetch', (req) => {
   req.respondWith(new Response('hello'));
 });

使用 WinterJS 运行它就像这样简单:

 $ wasmer run wasmer/winterjs --net --mapdir /app:. /app/serviceworker.js

WinterJS 也可以使用 Rust 本地运行(cargo install --git https://github.com/wasmerio/winterjs && Winterjs serviceworker.js)。 您可以在 GitHub 存储库中找到 WinterJS 的源代码:https://github.com/wasmerio/winterjs

得益于 WinterJS 的 WASIX 功能,JavaScript Service Worker 也可以部署到 Wasmer Edge。 在此处查看工作演示:https://wasmer-winter-js-sample-worker.wasmer.app/

现在您已经了解了如何使用 WinterJS,让我们深入了解一下我们的构建过程。

选择 JS 引擎

在开始创建 JavaScript Service Workers 服务器之前,我们分析了可以使用的 Javacript 运行时。

以下是我们对此类 JavaScript 运行时的主要要求:

  • 速度:跑起来应该很快
  • Wasm兼容:应该能够在Wasm环境(例如Wasmer)中不受限制地运行
  • 开发时间:我们应该能够快速迭代

以下是我们分析的 JS 运行时:

  • QuickJS。 挑战:
    • 我们需要实现所有 JS api diff(peformance.now()addEventListener、…)
    • 我们需要完全用C实现serviceWorker API
  • 静态赫尔墨斯。 挑战:
    • Node.js polyfills 在静态模式下不可用
    • polyfill 中可用的功能不多(例如 http 调用)
    • 必须使用 WASIX 将其编译为 Wasm
  • Bun (JavascriptCore)。 挑战:
    • Zig 不完全支持 WASIX
    • 将 JavascriptCore 编译为 WASIX 是可能的(之前已完成),但并非易事
  • MozJS (SpiderMonkey)。 挑战:
    • 我们需要实现所有 JS api diff(peformance.now()addEventListener、…)
    • 我们需要实现serviceWorker API(用Rust)
    • 我们需要将 WASIX http 服务器插入 Service Worker
  • Node.js (v8)。 挑战:
    • 以 jitless 模式将 v8 编译为 Wasm 是一个未知-未知

将 SpiderMonkey 与 mozjs 一起使用

经过几次运行时试验后,我们将 SpiderMonkey 设置为最合理的方法,适合我们紧迫的时间表。

所以我们开始移植。 我们从支持**名为 PBI 的新编译层**(便携式基线解释器)的 mozjs 分支开始。

在针对 WASIX 的 mozjs 构建系统进行一些工作后,我们能够绕过大多数问题,除了一个:绑定生成。

允许使用 Rust 中的 SpiderMonkey C++ API 的绑定是使用 c-bindgen 自动生成的。 将这些绑定插入 WASIX 是一个挑战,因此我们只是决定以 32 位系统为目标,并手动修改它们(32,000 个文件!)以目标 WASIX。

瞧……一切正常!

然而,在向 JS 添加了一些缺失的资源后,我们意识到也许 mozjs 没有最容易使用的 API:

 不安全 extern "C" fn base64_encode(cx: *mut JSContext, argc: u32, vp: *mut Value) -> bool {
     让 args = CallArgs::from_vp(vp, argc);

     如果 args.argc_ < 1 {
         返回假;
     }

     让 source = js_try!(cx, raw_handle_to_string(cx, args.get(0)));
     让结果 = ::base64::engine::general_ Purpose::STANDARD.encode(bytes);

     rooted!(in(cx) let mut rval = UndefinedValue());
     result.to_jsval(cx, rval.handle_mut());

     args.rval().set(rval.get());

     真的
 }

将 SpiderMokey 与 Spiderfire 结合使用

值得庆幸的是,spiderfire 项目一直致力于改进使用 Rust 中的 SpiderMonkey 的 API 界面。

所以之前的例子看起来更简单,更容易阅读/维护:

 #[js_fn]
 fn btoa<'cx>(val: String) -> String {
     让字节= val.as_bytes();
     ::base64::engine::general_ Purpose::STANDARD.encode(字节)
 }

部署到 Wasmer Edge

将 WinterJS 编译为 WASIX 具有挑战性,但完全值得。 得益于其 WASIX 功能,我们现在可以在 Wasmer Edge 中运行任何 Javascript Service Workers 工作负载。

我们整理了一个关于如何在 Wasmer Edge 中使用 Javascript Service Workers 的深入教程…请查看!

https://docs.wasmer.io/edge/quickstart/js-wintercg

我们相信 WinterJS 将实现许多新的用例。 例如,在 IoT 设备(其中 Node 太重而无法运行)中,甚至在浏览器中本地运行 Service Worker。

在 Wasmer,我们非常高兴看到您将如何使用 WinterJS。

GitHub 上的 WinterJS:https://github.com/wasmerio/winterjs

##### 关于作者

Syrus Akbary 是一位企业家和程序员。 因其对 WebAssembly 领域的贡献而闻名。 他是 Wasmer 的创始人兼首席执行官,这是一家创新公司,专注于创建用于运行 Wasm 的开发人员工具和基础设施

赛勒斯·阿克巴里:创始人兼首席执行官

你可能感兴趣的:(经验分享,javascript)