![发布封面图片](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,让我们深入了解一下我们的构建过程。
在开始创建 JavaScript Service Workers 服务器之前,我们分析了可以使用的 Javacript 运行时。
以下是我们对此类 JavaScript 运行时的主要要求:
以下是我们分析的 JS 运行时:
peformance.now()
、addEventListener
、…)peformance.now()
、addEventListener
、…)经过几次运行时试验后,我们将 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());
真的
}
值得庆幸的是,spiderfire 项目一直致力于改进使用 Rust 中的 SpiderMonkey 的 API 界面。
所以之前的例子看起来更简单,更容易阅读/维护:
#[js_fn]
fn btoa<'cx>(val: String) -> String {
让字节= val.as_bytes();
::base64::engine::general_ Purpose::STANDARD.encode(字节)
}
将 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 的开发人员工具和基础设施