-
-
Notifications
You must be signed in to change notification settings - Fork 292
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NAPI-RS 3.0 #1493
Comments
Yes, I need symbols! In order to debug resvg-js in the server, I had to disabled strip and then build a new binary. |
Unless you attach a debugger, wont you only get stack traces for Rust panics? I've used the |
Writing out some regular JavaScript code and then asking ChatGPT to rewrite it into a different programming language has quickly become my preferred way of getting started learning a new language. |
I am using the 3.0 release to write a new tool. I am curious if there is a list of tasks to complete 3.0 and get it released? I would prefer to not depend on a pre-release when I release my tool. |
I'm in the same boat as @andymac4182 (trying to use the new PNPM package template, which uses alpha.64) – @Brooooooklyn any timeline? Is the alpha relatively safe to use? |
Wish add the supports for choosing package-manager in CLI, includes pnpm, bun and npm. |
@Brooooooklyn Hi 😊 So, as you can see, a lot of reasons to wait 😁 Is there any assumption on when it going to be released? |
Goals
The goal of NAPI-RS 2.0 was to make NAPI-RS easier to use, and I believe it has accomplished that goal, with more and more projects using NAPI-RS to build Node.js addons as the barrier to use becomes lower. However, as more and more projects use NAPI-RS, there are some issues that come to light. We hope to solve them in 3.0.
Some abstractions do not fit into the philosophy of Rust
ThreadsafeFunction
Should not have
abort
API.The
ThreasafeFunction
should abort automatically indrop
. This behavior should be tied to the concept of ownership in Rust instead of a explicit API. Thefn abort(&self)
inThreadsafeFunction
introduces a lot of complexity and introduces a lot of mental overhead into the use ofThreadsafeFunction
.We should remove
fn abort(&self)
in 3.0, and this would introduce a breaking change.Buffer/TypedArray
in fn params is not zero overheadTo provide a more convenient API,
NAPI-RS
functions automatically create references (napi_create_reference
) toBuffer
andTypedArray
when they are passed in. This allows the data held byBuffer
andTypedArray
to be accessed correctly, both inasync fn
and inAsyncWork
. But this behavior also introduces unnecessary overhead for the plainfn
.In 3.0, we should enforce our users to pass
Reference<Buffer>/BufferRef
in if they want to use theBuffer/TypedArray
in the async scenario.Buffer/TypedArray
and&mut _
class inasync fn
is unsoundIn fact, in NAPI-RS, any assumption that Rust code holds a mutable borrow of JavaScript values is unsound. Because the Rust compiler would not do the borrow check for your JavaScript codes. You don't know if there will be a mutation to the reference held in
Rust
happen in JavaScript. Fortunately, it wouldn't be a problem in synchronous functions, because JavaScript in Node.js runtime is running in a single thread, there won't be anything happening outside the Rustfn
at the same time.But it will be a problem if you are using
&mut _
inasync fn
. There may be mutations happening in Node.js while the Rust part is suspended. We've enforced theunsafe
keyword in this scenario: #1453. But we need more documentation and examples to describe this mental model to our users.Support WebAssembly
We have had some discussions at #796. This feature is of exceptional importance to the entire community.
If we had a solution that allowed NAPI-RS package authors to easily distribute WebAssembly versions of their projects, more applications could run directly in browsers and other runtimes that support WebAssembly. For many applications in the Node.js/Web ecosystem, having a Playground that can run directly in the browser would be a huge boost.
We have done some experiments in the https://github.com/napi-rs/napi-rs/tree/emnapi branch; It basically verifies that it is possible to get NAPI-RS users to compile to WebAssembly at 0 cost via an external Node-API polyfill. But there are some TODOs that need to be done before 3.0:
Provide
std::thread
polyfill in NAPI-RSMany projects that use NAPI-RS use
std::thread
to take advantage of multi-core processors. This is a part of Node.js itself that it is not good at. However,wasi
/wasm
threads are not yet available in Rust.We need to provide a
napi::thread
module that providesstd::thread
in native binary and a polyfill in WebAssembly.Integrate the WebAssembly package into our package distribution workflow
We already have a working very good multi-platform automated distribution workflow. We need to integrate the WebAssembly package into this workflow and maintain our competitive edge: Keep the cost of installing projects written in NAPI-RS to a minimum, both in terms of the number of files and package size.
Find an implementation that reduces the overhead of passing complex structures between Rust and JavaScript
We are not sure if this part will be part of NAPI-RS, but it is something that is really worthy of exploration.
This is the biggest challenge that many existing projects written in Rust face when trying to provide JavaScript plugins: swc-project/swc#2175.
There are several potentially effective ways to do this that are worth a try.
Lazy Serialize via a Proxy Object
Take the AST plugin as an example, not all plugins need to access or update the entire AST object. Plugins usually only need to access or update a small part of the entire AST, so we don't need to serialize the entire AST to return to JavaScript in the first place: luizperes/simdjson_nodejs#28 (comment). In
simdjson
package, they provide thevalueForKeyPath("foo.bar[1]")
API to access the real data in the large object, and serialize/deserialize it on demand. We can provide a more friendly way to do that withProxy
(likeimmer
).Serialize/Deserialize via WebAssembly in Node.js
From one of my tests in 2017: The overhead of creating JavaScript objects in WebAssembly is much smaller than in Native Addon. (I lost the original data, maybe we can re-test it with the latest Node.js and Rust). Plus, the StringRef proposal will make the serialization much faster in WebAssembly if used properly.
Stream integration
Like
Promise
,Stream
is also the keystone of Node.js applications. CreatingStream
and consumingStream
is really important in many scenarios, like SSR and large data processing apps.Extendable CLI API
Rush stack is trying to integrate with NAPI-RS, and we want to adopt more integration solutions like
Turoborepo
,Nx
in the future: microsoft/rushstack#3961.We need to split things in CLI into an independent package to provide the same ability as in
@napi-rs/cli
.Documents and articles
As developers discover that Rust can do many things that Node.js can't easily do, and that users don't have to deal with node-gyp as often as they do with C/C++ projects, more and more Node.js developers are experimenting with introducing Rust and NAPI-RS into their projects.
While NAPI-RS greatly reduces the mental burden of writing Rust and Node.js APIs,
JavaScript
is ultimately very different from Rust at the language level. We should definitely provide such materials: Adam Wathan's twitterEnhace Publishing Strategy
This is not something that can be done in the 3.0 release, it requires a lot of projects in the community to work together.
In this part, we mainly need to help npm/rfcs#519 to land as soon as possible
Debug symbols
Native addon may crash during run time. When publishing to npm, the binary usually does not contain debug symbols in order to reduce the size of the installation. This makes it difficult to identify the issue when a crash occurs.
We should provide a solution to upload the separated debug symbols automatically and download them on demand.
Developers can use
napi debug-symbols download PACKAGE_NAME
and let the crash happen again, then they will get the correct stack trace and report it to package maintainers.The text was updated successfully, but these errors were encountered: