2个稳定版本

2.16.2 2024年4月10日
2.16.1 2024年3月19日

#2 in #napi

Download history 341/week @ 2024-04-26 377/week @ 2024-05-03 307/week @ 2024-05-10 188/week @ 2024-05-17 178/week @ 2024-05-24 233/week @ 2024-05-31 164/week @ 2024-06-07 161/week @ 2024-06-14 197/week @ 2024-06-21 174/week @ 2024-06-28 139/week @ 2024-07-05 182/week @ 2024-07-12 247/week @ 2024-07-19 394/week @ 2024-07-26 160/week @ 2024-08-02 154/week @ 2024-08-09

1,007 每月下载量
用于 4 crates

MIT 协议

475KB
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 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
}

更多示例请参考 examples

构建

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

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

[package]
name = "awesome"

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

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

[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 应该是您的 Cargo.toml 中的包名。

xxx=> ./xxx.node

xxx-yyy=> ./xxx_yyy.node

您还可以将 Dynamic lib 文件复制到指定的位置

napi build [--release] ./dll
napi build [--release] ./artifacts

有关 @napi-rs/cli 的更多信息,请参阅 文档

测试

由于依赖于此 crate 的库必须被加载到 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
~121K SLoC