使用 UniFFI 生成 Javascript 绑定¶
Firefox 支持使用 UniFFI 自动生成 Rust 组件的 JS 绑定。
工作原理¶
Rust crate 包含一个 UniFFI 定义语言 (UDL) 文件,用于描述要为其生成绑定的接口。
UniFFI 核心生成脚手架:从 UDL 文件生成充当 FFI 层的 Rust 代码。此层的所有函数都使用 C 调用约定,所有结构体都使用 C 布局,这是 FFI 互操作的事实标准。
位于 Firefox 源码树中的 uniffi-bindgen-gecko-js
工具生成两样东西
脚手架代码的 JS 接口,使用 WebIDL
一个使用脚手架提供绑定 API 的模块。
目前,这些生成的代码已签入到源代码控制中。我们正在开发一个系统,以避免这种情况,而是在构建时自动生成这些代码(请参阅 bugzilla 1756214)。
在使用 UniFFI 创建新绑定之前¶
在创建新绑定集之前,请牢记以下几点
UniFFI 的编写目的并非为了最大化性能。其代码效率足以处理许多用例,但在目前阶段,对于性能关键型组件,最好避免使用。
uniffi-bindgen-gecko-js 绑定以 chrome 权限运行。请确保这对于您的项目来说是可以接受的。
只能通过 FFI 公开 Rust 类型的一个子集。请查看 UniFFI 手册 以了解哪些类型与 UniFFI 兼容。
如果以上任何一项对您的工作造成了阻碍,请考虑与 UniFFI 开发人员进一步讨论,看看我们是否可以支持您的项目。
在 Matrix/Element 上的
#uniffi
频道与我们聊天在 mozilla/uniffi 上提交问题
使用 UniFFI 创建新绑定¶
您可以查看此功能的使用示例:当 application-services 使用 Rust 替换 tabs js 同步引擎时
以下是如何使用 UniFFI 创建新绑定集的方法
使用 UniFFI 处理您的 crate(如果尚未处理)
按照 UniFFI 用户指南 中的步骤向您的 crate 添加支持。
UDL 和 proc-macros 都受支持。
将您的 crate 添加为 Firefox 依赖项(如果尚未添加)
如果代码存在于 mozilla-central 存储库中
为 Rust crate 创建一个新目录
编辑
toolkit/components/uniffi-bindgen-gecko-js/components/Cargo.toml
并添加对库路径的依赖项
如果代码存在于外部存储库中
编辑
toolkit/components/uniffi-bindgen-gecko-js/components/Cargo.toml
并添加对库 URL 的依赖项运行
mach vendor rust
以引入您的 Rust 代码
配置您的 crate(可选)
编辑
toolkit/components/uniffi-bindgen-gecko-js/config.toml
并添加您的 crate 的条目。
添加您的 crate 的脚手架
编辑
toolkit/components/uniffi-bindgen-gecko-js/components/lib.rs
并添加您的 crate 的 uniffi 脚手架的条目。
为您的 crate 生成绑定代码
运行
./mach uniffi generate
将新生成的
Rust{udl-name}.sys.mjs
文件添加到toolkit/components/uniffi-bindgen-gecko-js/components/moz.build
然后只需将您的模块导入到您想要使用它的文件中,然后开始使用您的 API!
来自 tabs 模块的示例
ChromeUtils.defineESModuleGetters(lazy, { ... TabsStore: "resource://gre/modules/RustTabs.sys.mjs", }); ... this._rustStore = await lazy.TabsStore.init(path);