1 个稳定版本

1.7.6 2021年8月30日

#132FFI

MIT 许可证

240KB
6.5K SLoC

napi-rs

Stake to support us chat

此项目基于 xray 初始化。

用于在 Rust 中构建编译的 Node.js 插件的最小库。

生态系统

Prisma     swc     Parcel   next.js   nextjs.svg

平台支持

Lint Linux N-API@3 Linux musl macOS/Windows/Linux x64 Linux-aarch64 Linux-armv7 macOS-Android Windows i686 Windows arm64 FreeBSD

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 MSVCFreeBSD 上进行了测试。

请参阅包含的 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 将是您的 packageCargo.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