1 个不稳定版本
0.1.0 | 2024 年 8 月 5 日 |
---|
#1142 in 网页编程
每月 114 次下载
86KB
1.5K SLoC
js_sidecar 是一个 Rust 包,它不是直接将 JS 库嵌入到应用程序中,而是将 JavaScript 代码传递给一个独立的、持久的 Node.js 进程来执行。
如果你想要完整的 API 可用性,现在在应用程序中嵌入一个功能齐全的 JS 引擎有些困难,所以这个方案绕过了这个问题,同时避免了为每次表达式评估启动新进程的开销。
性能
一些相关的基准测试时间(cargo bench
),在 M3 Max Macbook Pro 和 Node 20.16 上运行。
- 一个简单的脚本执行("2 + 2")需要大约 200 微秒将代码发送到 Node.js、运行它并返回结果。
- 从 Rust 主机到 Node.js 的 ping 样式消息,不运行任何代码,大约需要 13 微秒。
替代方案
嵌入 Deno
在我过去的经验中,这效果还不错,但你需要自己设置很多运行时环境。一起更新所有 Deno 包也很痛苦,经常需要处理破坏性的更改。随着 Deno 本身的成熟,其中一些可能变得更好,但总的来说,嵌入一个“功能齐全的 Deno”似乎并不容易,除非从 Deno 仓库复制一大堆代码。
QuickJS/Boa 等
这里的主要问题是生态系统兼容性和 API 可用性,特别是缺少 fetch
。这可能不是某些应用程序的问题,但有时你需要只能在与 Node 或 WinterCG 兼容的 JS 引擎中工作的 API。
随着 QuickJS 通过 LLRT 项目获得更多的 WinterCG API,这个问题也可能变得不那么严重。Boa,一个用 Rust 编写的 JS 运行时,还处于早期阶段,但看起来很有前途。
与嵌入相比的缺点
这需要在系统上安装 Node.js,这可能会使分发变得复杂,并可能使某些用例无法实现。未来我可能会考虑直接嵌入 Bun 可执行文件,以便在需要时实现自包含的使用。
主要缺点是每次通信都需要通过Unix套接字,这会降低性能。在大多数情况下这不会成为问题,特别是考虑到嵌入式JS引擎中零拷贝实际上是不可能的,但这是值得考虑的。
使用大量从脚本回调到Rust宿主的案例将看到性能下降最严重。(这也尚未支持此crate,但计划在未来实现。)
依赖关系
~7–18MB
~261K SLoC