No description
Find a file
LongYinan 4e50a6eccf
Merge pull request #584 from napi-rs/fix-js-string-leak
fix(napi): JsString* leak in from_js_value
2021-05-28 10:49:41 +08:00
.github ci: pin rust toolchain on 1.51.0 on windows-i686 target 2021-05-17 10:46:29 +08:00
.husky chore: upgrade deps 2021-03-11 13:42:28 +08:00
bench bench: add array suite 2021-05-17 11:42:57 +08:00
build napi-build@1.0.2 2021-04-14 14:57:06 +08:00
cli build(deps): bump fdir from 5.0.0 to 5.1.0 2021-05-24 10:31:23 +00:00
napi fix(napi): JsString* leak in from_js_value 2021-05-28 10:34:42 +08:00
napi-derive napi-derive@1.1.0 2021-04-01 21:08:53 +08:00
napi-derive-example feat(napi): major upgrades for napi@1 2020-11-26 11:31:49 +08:00
sys napi-sys@1.1.1 2021-05-25 11:03:01 +08:00
test_module feat(napi): impl more types AsRef and AsMut for TypedArray 2021-05-25 00:07:16 +08:00
triples chore: rename branch master => main 2020-12-03 16:30:14 +08:00
.cirrus.yml ci: fix FreeBSD 2021-05-27 22:41:31 +08:00
.dockerignore feat(napi): support musl linux 2020-06-11 16:20:37 +08:00
.editorconfig init 2018-04-28 16:26:38 +08:00
.eslintignore feat(cli): start new cli 2020-07-29 23:06:37 +08:00
.eslintrc.yml feat: support linux aarch64 2020-10-15 09:12:43 +08:00
.gitignore ci: setup benchmark action 2020-10-14 01:02:00 +08:00
.npmignore feat: support linux aarch64 2020-10-15 09:12:43 +08:00
.prettierignore refactor(cli): init yarn workspace, move napi-rs package => @napi-rs/cli 2020-12-02 22:34:39 +08:00
.yarnrc feat: upgrade to std-future 2020-02-18 21:09:17 +08:00
alpine.Dockerfile ci: use lts alpine image 2021-03-19 11:53:48 +08:00
ava.config.js refactor(cli): init yarn workspace, move napi-rs package => @napi-rs/cli 2020-12-02 22:34:39 +08:00
Cargo.toml feat(cli): new project command 2020-12-23 00:16:45 +08:00
CODE_OF_CONDUCT.md doc: add email to CODE_OF_CONDUCT 2020-05-20 18:49:36 +08:00
debian.Dockerfile ci: add debian docker image 2021-04-12 11:02:59 +08:00
generate-triplelist.js refactor(cli): init yarn workspace, move napi-rs package => @napi-rs/cli 2020-12-02 22:34:39 +08:00
lerna.json @napi-rs/cli@1.0.0-alpha.12 2020-12-23 22:46:48 +08:00
LICENSE docs: update license 2021-01-25 14:12:44 +08:00
package.json build(deps-dev): bump @typescript-eslint/parser from 4.23.0 to 4.24.0 2021-05-24 09:57:09 +00:00
README.md readme: fix references to Node-API after its renaming 2021-05-19 22:22:40 +02:00
rustfmt.toml Allow dropping of string&buffer values when converting 2021-05-27 20:47:22 +02:00
tsconfig.json refactor(cli): init yarn workspace, move napi-rs package => @napi-rs/cli 2020-12-02 22:34:39 +08:00
tsconfig.root-lint.json refactor(cli): init yarn workspace, move napi-rs package => @napi-rs/cli 2020-12-02 22:34:39 +08:00
yarn.lock build(deps): bump fdir from 5.0.0 to 5.1.0 2021-05-24 10:31:23 +00:00

napi-rs

This project was initialized from xray

A minimal library for building compiled Node.js add-ons in Rust.

Platform Support

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

node12 node14 node16
Windows x64
Windows x86
macOS x64
macOS aarch64
Linux x64 gnu
Linux x64 musl
Linux aarch64 gnu
Linux arm gnueabihf
Linux aarch64 android
FreeBSD x64

This library depends on Node-API and requires Node@10.0.0 or later.

We already have some packages written by napi-rs: node-rs

One nice feature is that this crate allows you to build add-ons purely with the Rust/JavaScript toolchain and without involving node-gyp.

Taste

You can start from package-template to play with napi-rs

Define JavaScript functions

#[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),
  }
}

Register module

#[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(())
}

And you can also create JavaScript value while registering module:

#[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(())
}

Building

This repository is a Cargo crate. Any napi-based add-on should contain Cargo.toml to make it a Cargo crate.

In your Cargo.toml you need to set the crate-type to "cdylib" so that cargo builds a C-style shared library that can be dynamically loaded by the Node executable. You'll also need to add this crate as a dependency.

[package]
name = "awesome"

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

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

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

And create build.rs in your own project:

// build.rs
extern crate napi_build;

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

So far, the napi build script has only been tested on macOS Linux Windows x64 MSVC and FreeBSD.

See the included test_module for an example add-on.

Install the @napi-rs/cli to help you build your Rust codes and copy Dynamic lib file to .node file in case you can require it in your program.

{
  "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"
  }
}

Then you can require your native binding:

require('./jarvis.node')

The module_name would be your package name in your Cargo.toml.

xxx => ./xxx.node

xxx-yyy => ./xxx_yyy.node

You can also copy Dynamic lib file to an appointed location:

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

There are documents which contains more details about the @napi-rs/cli usage.

Testing

Because libraries that depend on this crate must be loaded into a Node executable in order to resolve symbols, all tests are written in JavaScript in the test_module subdirectory.

To run tests:

yarn build:test
yarn test

Features table

Create JavaScript values

NAPI NAPI Version Minimal Node version Status
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 ⚠️

I have no plan to implement nape_type_tag and related API in napi-rs, because we have implemented a rust replacement in TaggedObject which is more convenient and more compatible.

Functions to convert from Node-API to C types

NAPI NAPI Version Minimal Node Version Status
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

Working with JavaScript Values and Abstract Operations

NAPI NAPI Version Minimal Node Version Status
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