#quickjs #run-time #javascript-engine #javascript #async #engine

quickjs_runtime

QuickJS JavaScript 引擎的包装 API 和工具,支持 Promise、模块、Async/await

40 个版本

0.13.4 2024 年 6 月 1 日
0.13.3 2024 年 3 月 18 日
0.12.1 2024 年 2 月 15 日
0.11.5 2023 年 8 月 1 日
0.2.3 2021 年 3 月 31 日

#279开发工具

Download history 39/week @ 2024-04-21 21/week @ 2024-04-28 47/week @ 2024-05-12 84/week @ 2024-05-19 163/week @ 2024-05-26 95/week @ 2024-06-02 24/week @ 2024-06-09 27/week @ 2024-06-16 19/week @ 2024-06-23 18/week @ 2024-06-30 34/week @ 2024-07-07 9/week @ 2024-07-14 13/week @ 2024-07-21 130/week @ 2024-07-28

每月 156 次下载
用于 vitrine

MIT 许可证

575KB
12K SLoC

quickjs_runtime

quickjs_runtime 是一个库,用于快速在 Rust 项目中嵌入 JavaScript 引擎。

截至 2024 年,此库不再依赖于 libquickjs-sys,而是使用我们自己的 hirofa-quickjs-sys,增加了对 QuickJS 版本使用的灵活性

quickjs_runtime 使用 EventLoop 在单个线程中运行所有 JavaScript 操作。这意味着您可以通过向 EventLoop 添加任务来安全地从多个线程调用 JavaScript。

quickjs 或 quickjs-ng

quickjs_runtime 支持原始 quickjs 和 quickjs-ng 项目。

您可以通过将依赖项添加到 quickjs_runtime 中来尝试 quickjs-ng(请在自己的风险下使用,因为我还没有对其进行彻底测试)

quickjs_runtime = {git="https://github.com/HiRoFa/quickjs_es_runtime", features=["console", "setimmediate", "setinterval", "settimeout", "typescript", "quickjs-ng"], default-features=false}

用法和功能

有关如何使用此库在 Rust 中嵌入脚本引擎的示例,请参阅此处:github.com/andrieshiemstra/ScriptExtensionLayerExample。它已在 TWIR 中作为教程发布。

quickjs_runtime 专注于使 quickjs 更易于使用,不添加任何附加功能,这正是这些项目所在之处

  • 一个功能更丰富的运行时(例如,支持 fetch api、基于 http 的模块加载器等):GreenCopperRuntime
  • 命令行客户端:GreenCopperCmd

请参阅 DOCS 了解所有内部工作原理

此库有两个主要目标

1. 为与 quickjs 一起工作提供简单的工具(这些位于 quickjs_utils 模块中)

  • QuickJsRuntime 结构,这应该在单个线程中使用
  • 例如,objects::set_property()、functions::invoke_func()
  • 将JSValue封装以提供引用计数(初始化时+1,丢弃时-1)(QuickJsValueAdapter
  • 传递模块加载器

2. 将quickjs封装为现成的JavaScript运行时

  • 从QuickjsRuntimeFacade开始,它提供了一个包含thread_local QuickJsRuntimeAdapter的事件队列
  • 所有值都通过JsValueFacades进行复制或抽象
  • 因此无需担心垃圾回收
  • 在等待结果时评估脚本和调用函数,可以是阻塞或使用async/await
  • 阻塞或使用async/await获取Promise结果

什么可以工作?

脚本和模块

  • Typescript(通过SWC)
  • console (.log/info/debug/trace/error) (文档
  • 评估脚本(文档
  • 在JavaScript中创建执行异步操作的Promise
  • 评估模块(文档
  • 加载模块(动态和静态)(文档
  • fetch api(在GreenCopperRuntime中实现)
  • setImmediate
  • setTimeout/Interval(和清除)
  • 脚本预处理(在GreenCopperRuntime中可以找到ifdef/macro的类型化或Rust函数或Proxy类的实现)

Rust-Script互操作性

  • 从Rust函数返回Promise并在Rust中解决它们(文档
  • 从Rust添加函数(文档
  • 从Rust调用JS函数(文档
  • 从Rust和到Rust传递原始数据、对象和数组(文档
  • 从Rust创建类(文档
  • 在eval/call_function/promise解决过程中支持async/await
  • 导入本地模块(例如,Rust函数或Proxy类的动态加载)(文档

目标

在Rust项目中嵌入脚本引擎似乎是一个非常繁琐的工作,这涉及到对该引擎内部工作原理的大量了解。

本项目的主要目标是使这项工作变得简单!

实现这一目标的方法主要关注从实现者那里抽象出引擎的工作原理,因此某些功能可能不是完成任务的最快方式。

因此,第二个目标是使初学者能够实现快速高效的集成,使用此包中的实用工具和测试模块中的示例应该能够完成最常见的工作。

我选择QuickJS作为引擎的原因是我一直在我的Java项目中处理较旧的引擎,而无法使用最新的ECMA-script功能有时会相当令人失望。

关于QuickJS的有趣之处

  • 小体积
  • 快速编译/启动
  • 出色的JS兼容性

示例

Cargo.toml

[dependencies]
quickjs_runtime = "0.13.1"

以下是一些快速入门指南

quickjs Api实用工具

依赖关系

~17–32MB
~614K SLoC