162 个版本 (105 个稳定版本)

3.0.0-alpha.82024年7月18日
3.0.0-alpha.32024年6月27日
3.0.0-alpha.02024年3月20日
2.16.9 2024年8月10日
0.1.0 2017年11月30日

#1 in FFI

Download history 76827/week @ 2024-05-04 70435/week @ 2024-05-11 64397/week @ 2024-05-18 70838/week @ 2024-05-25 128779/week @ 2024-06-01 127808/week @ 2024-06-08 133031/week @ 2024-06-15 161393/week @ 2024-06-22 157919/week @ 2024-06-29 154714/week @ 2024-07-06 149021/week @ 2024-07-13 138392/week @ 2024-07-20 141856/week @ 2024-07-27 137742/week @ 2024-08-03 119581/week @ 2024-08-10 118013/week @ 2024-08-17

541,733 每月下载量
用于 46 个 Crates(42 个直接使用)

MIT 许可证

490KB
14K SLoC

napi-rs

此项目是从 xray 初始化的

一个用于通过 Node-API 在 Rust 中构建编译型 Node.js 扩展的框架。网站: https://napi.rs

chat Stake to support us

平台支持

Test & Release FreeBSD Address Sanitizer Memory Leak Detect

MSRV

Rust 1.65.0

node12 node14 node16 node18 node20
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 arm muslebihf
Linux powerpc64le gnu
Linux s390x gnu
Linux riscv64 gnu N/A N/A
Linux aarch64 android
Linux armv7 android
FreeBSD x64

此库依赖于 Node-API,并需要 Node@10.0.0 或更高版本。

我们已经有了一些由 napi-rs 编写的包: node-rs

一个很棒的特性是这个 crate 允许您仅使用 Rust / JavaScript 工具链来构建扩展,而不涉及 node-gyp

尝试

您可以从 package-template 开始使用 napi-rs

定义 JavaScript 函数

/// import the preludes
use napi::bindgen_prelude::*;
use napi_derive::napi;

/// module registration is done by the runtime, no need to explicitly do it now.
#[napi]
fn fibonacci(n: u32) -> u32 {
  match n {
    1 | 2 => 1,
    _ => fibonacci(n - 1) + fibonacci(n - 2),
  }
}

/// use `Fn`, `FnMut` or `FnOnce` traits to defined JavaScript callbacks
/// the return type of callbacks can only be `Result`.
#[napi]
fn get_cwd<T: Fn(String) -> Result<()>>(callback: T) {
  callback(env::current_dir().unwrap().to_string_lossy().to_string()).unwrap();
}

/// or, define the callback signature in where clause
#[napi]
fn test_callback<T>(callback: T)
where T: Fn(String) -> Result<()>
{}

/// async fn, require `async` feature enabled.
/// [dependencies]
/// napi = {version="2", features=["async"]}
#[napi]
async fn read_file_async(path: String) -> Result<Buffer> {
  tokio::fs::read(path)
    .map(|r| match r {
      Ok(content) => Ok(content.into()),
      Err(e) => Err(Error::new(
        Status::GenericFailure,
        format!("failed to read file, {}", e),
      )),
    })
    .await
}

更多示例请参阅 示例

构建

该仓库是一个 Cargo 包。任何基于 napi 的插件都应该包含 Cargo.toml 以使其成为 Cargo 包。

在您的 Cargo.toml 中,您需要将 crate-type 设置为 "cdylib",这样 cargo 就会构建一个可以由 Node 可执行文件动态加载的 C 风格共享库。您还需要将此包作为依赖项添加。

[package]
name = "awesome"

[lib]
crate-type = ["cdylib"]

[dependencies]
napi = "3"
napi-derive = "3"

[build-dependencies]
napi-build = "1"

并在您的项目中创建 build.rs

// build.rs
extern crate napi_build;

fn main() {
  napi_build::setup();
}

到目前为止,napi 构建脚本仅在 macOSLinuxWindows x64 MSVCFreeBSD 上进行了测试。

安装 @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

功能表

Rust 类型 Node 类型 NAPI 版本 最小 Node 版本 通过 napi 功能启用
u32 数字 1 v8.0.0
i32/i64 数字 1 v8.0.0
f64 数字 1 v8.0.0
bool 布尔值 1 v8.0.0
String/&'a str 字符串 1 v8.0.0
Latin1String 字符串 1 v8.0.0 latin1
UTF16String 字符串 1 v8.0.0
对象 对象 1 v8.0.0
serde_json::Map 对象 1 v8.0.0 serde-json
serde_json::Value 任何 1 v8.0.0 serde-json
数组 数组 1 v8.0.0
Vec 数组 1 v8.0.0
缓冲区 缓冲区 1 v8.0.0
外部 外部 1 v8.0.0
null 1 v8.0.0
未定义/() undefined 1 v8.0.0
Result<()> 错误 1 v8.0.0
T: Fn(...) -> Result 函数 1 v8.0.0
异步/未来 Promise 4 v10.6.0 async
AsyncTask Promise 1 v8.5.0
JsGlobal 全局 1 v8.0.0
JsSymbol 符号 1 v8.0.0
Int8Array/Uint8Array ... TypedArray 1 v8.0.0
JsFunction 线程安全函数 4 v10.6.0 napi4
BigInt BigInt 6 v10.7.0 napi6

依赖项

~0.4–11MB
~119K SLoC