1 个稳定版本
1.7.6 | 2021年8月30日 |
---|
#132 在 FFI
240KB
6.5K SLoC
napi-rs
此项目基于 xray 初始化。
用于在 Rust
中构建编译的 Node.js
插件的最小库。
生态系统
平台支持
node12 | node14 | node16 | |
---|---|---|---|
Windows x64 | ✓ | ✓ | ✓ |
Windows x86 | ✓ | ✓ | ✓ |
Windows arm64 | ✓ | ✓ | ✓ |
macOS x64 | ✓ | ✓ | ✓ |
macOS aarch64 | ✓ | ✓ | ✓ |
Linux x64 gnu | ✓ | ✓ | ✓ |
Linux x64 musl | ✓ | ✓ | ✓ |
Linux aarch64 gnu | ✓ | ✓ | ✓ |
Linux aarch64 musl | ✓ | ✓ | ✓ |
Linux arm gnueabihf | ✓ | ✓ | ✓ |
Linux aarch64 android | ✓ | ✓ | ✓ |
FreeBSD x64 | ✓ | ✓ | ✓ |
此库依赖于 Node-API,并且需要 Node@10.0.0
或更高版本。
我们已经有了一些由 napi-rs
编写的包: node-rs
一个很好的功能是,这个包允许你仅使用 Rust/JavaScript 工具链构建插件,而不需要涉及
node-gyp
。
特点
你可以从 package-template 开始,尝试使用
napi-rs
定义 JavaScript 函数
#[js_function(1)] // ------> arguments length
fn fibonacci(ctx: CallContext) -> Result<JsNumber> {
let n = ctx.get::<JsNumber>(0)?.try_into()?;
ctx.env.create_int64(fibonacci_native(n))
}
#[inline(always)]
fn fibonacci_native(n: i64) -> i64 {
match n {
1 | 2 => 1,
_ => fibonacci_native(n - 1) + fibonacci_native(n - 2),
}
}
注册模块
#[macro_use]
extern crate napi_derive;
use napi::{JsObject, Result};
/// `exports` is `module.exports` object in NodeJS
#[module_exports]
fn init(mut exports: JsObject) -> Result<()> {
exports.create_named_method("fibonacci", fibonacci)?;
Ok(())
}
同时,你还可以在注册模块时创建 JavaScript
值
#[macro_use]
extern crate napi_derive;
use napi::{JsObject, Result, Env};
#[module_exports]
fn init(mut exports: JsObject, env: Env) -> Result<()> {
exports.create_named_method("fibonacci", fibonacci)?;
exports.set_named_property("DEFAULT_VALUE", env.create_int64(100)?)?;
Ok(())
}
构建
这个存储库是一个 Cargo
包。任何基于 napi 的插件都应该包含 Cargo.toml
,使其成为一个 Cargo 包。
在你的 Cargo.toml
中,你需要将 crate-type
设置为 "cdylib"
,这样 cargo 就会构建一个可以被 Node 可执行文件动态加载的 C 风格共享库。你还需要将此包作为依赖项添加。
[package]
name = "awesome"
[lib]
crate-type = ["cdylib"]
[dependencies]
napi = "1"
napi-derive = "1"
[build-dependencies]
napi-build = "1"
并在你自己的项目中创建 build.rs
// build.rs
extern crate napi_build;
fn main() {
napi_build::setup();
}
到目前为止,napi
构建脚本只在 macOS
Linux
Windows x64 MSVC
和 FreeBSD
上进行了测试。
请参阅包含的 test_module 示例插件。
安装 @napi-rs/cli
以帮助您构建 Rust 代码,并将 Dynamic lib
文件复制到 .node
文件中,以便您可以在程序中调用它。
{
"package": "awesome-package",
"devDependencies": {
"@napi-rs/cli": "^1.0.0"
},
"napi": {
"name": "jarvis" // <----------- Config the name of native addon, or the napi command will use the name of `Cargo.toml` for the binary file name.
},
"scripts": {
"build": "napi build --release",
"build:debug": "napi build"
}
}
然后您就可以调用您本机绑定了
require('./jarvis.node')
module_name
将是您的 package
在 Cargo.toml
中的名称。
xxx=> ./xxx.node
xxx-yyy=> ./xxx_yyy.node
您也可以将 Dynamic lib
文件复制到指定的位置
napi build [--release] ./dll
napi build [--release] ./artifacts
有关 @napi-rs/cli
的更多信息,请参阅文档。
测试
由于依赖于此包的库必须在 Node 可执行文件中加载以解析符号,因此所有测试都编写在 test_module
子目录中的 JavaScript 中。
要运行测试
yarn build:test
yarn test
相关项目
功能表
创建 JavaScript 值
NAPI | NAPI 版本 | 最小 Node 版本 | 状态 |
---|---|---|---|
napi_create_array | 1 | v8.0.0 | ✅ |
napi_create_array_with_length | 1 | v8.0.0 | ✅ |
napi_create_arraybuffer | 1 | v8.0.0 | ✅ |
napi_create_buffer | 1 | v8.0.0 | ✅ |
napi_create_buffer_copy | 1 | v8.0.0 | ✅ |
napi_create_date | 5 | v11.11.0 | ✅ |
napi_create_external | 1 | v8.0.0 | ✅ |
napi_create_external_arraybuffer | 1 | v8.0.0 | ✅ |
napi_create_external_buffer | 1 | v8.0.0 | ✅ |
napi_create_object | 1 | v8.0.0 | ✅ |
napi_create_symbol | 1 | v8.0.0 | ✅ |
napi_create_typedarray | 1 | v8.0.0 | ✅ |
napi_create_dataview | 1 | v8.3.0 | ✅ |
napi_create_int32 | 1 | v8.4.0 | ✅ |
napi_create_uint32 | 1 | v8.4.0 | ✅ |
napi_create_int64 | 1 | v8.4.0 | ✅ |
napi_create_double | 1 | v8.4.0 | ✅ |
napi_create_bigint_int64 | 6 | v10.7.0 | ✅ |
napi_create_bigint_uint64 | 6 | v10.7.0 | ✅ |
napi_create_bigint_words | 6 | v10.7.0 | ✅ |
napi_create_string_latin1 | 1 | v8.0.0 | ✅ |
napi_create_string_utf16 | 1 | v8.0.0 | ✅ |
napi_create_string_utf8 | 1 | v8.0.0 | ✅ |
napi_type_tag | 8 | v14.8.0, v12.19.0 | ⚠️ |
我没有任何计划在
napi-rs
中实现nape_type_tag
和相关的 API,因为我们已经在 TaggedObject 中实现了一个rust
替代品,它更方便且更兼容。
从 Node-API 转换到 C 类型的函数
NAPI | NAPI 版本 | 最小 Node 版本 | 状态 |
---|---|---|---|
napi_get_array_length | 1 | v8.0.0 | ✅ |
napi_get_arraybuffer_info | 1 | v8.0.0 | ✅ |
napi_get_buffer_info | 1 | v8.0.0 | ✅ |
napi_get_prototype | 1 | v8.0.0 | ✅ |
napi_get_typedarray_info | 1 | v8.0.0 | ✅ |
napi_get_dataview_info | 1 | v8.3.0 | ✅ |
napi_get_date_value | 5 | v11.11.0 | ✅ |
napi_get_value_bool | 1 | v8.0.0 | ✅ |
napi_get_value_double | 1 | v8.0.0 | ✅ |
napi_get_value_bigint_int64 | 6 | v10.7.0 | ✅ |
napi_get_value_bigint_uint64 | 6 | v10.7.0 | ✅ |
napi_get_value_bigint_words | 6 | v10.7.0 | ✅ |
napi_get_value_external | 1 | v8.0.0 | ✅ |
napi_get_value_int32 | 1 | v8.0.0 | ✅ |
napi_get_value_int64 | 1 | v8.0.0 | ✅ |
napi_get_value_string_latin1 | 1 | v8.0.0 | ✅ |
napi_get_value_string_utf8 | 1 | v8.0.0 | ✅ |
napi_get_value_string_utf16 | 1 | v8.0.0 | ✅ |
napi_get_value_uint32 | 1 | v8.0.0 | ✅ |
napi_get_boolean | 1 | v8.0.0 | ✅ |
napi_get_global | 1 | v8.0.0 | ✅ |
napi_get_null | 1 | v8.0.0 | ✅ |
napi_get_undefined | 1 | v8.0.0 | ✅ |
处理 JavaScript 值和抽象操作
NAPI | NAPI 版本 | 最小 Node 版本 | 状态 |
---|---|---|---|
napi_coerce_to_bool | 1 | v8.0.0 | ✅ |
napi_coerce_to_number | 1 | v8.0.0 | ✅ |
napi_coerce_to_object | 1 | v8.0.0 | ✅ |
napi_coerce_to_string | 1 | v8.0.0 | ✅ |
napi_typeof | 1 | v8.0.0 | ✅ |
napi_instanceof | 1 | v8.0.0 | ✅ |
napi_is_array | 1 | v8.0.0 | ✅ |
napi_is_arraybuffer | 1 | v8.0.0 | ✅ |
napi_is_buffer | 1 | v8.0.0 | ✅ |
napi_is_date | 1 | v8.0.0 | ✅ |
napi_is_error | 1 | v8.0.0 | ✅ |
napi_is_typedarray | 1 | v8.0.0 | ✅ |
napi_is_dataview | 1 | v8.3.0 | ✅ |
napi_strict_equals | 1 | v8.0.0 | ✅ |
napi_detach_arraybuffer | 7 | v13.3.0 | ✅ |
napi_is_detached_arraybuffer | 7 | v13.3.0 | ✅ |
napi_object_freeze | 8 | v14.14.0, v12.20.0 | ✅ |
napi_object_seal | 8 | v14.14.0, v12.20.0 | ✅ |
依赖项
~0–2.4MB
~55K SLoC