You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, the napi_derive package provides us several proc_macros like js_function which absolutely covered most scenarios.
But when using it, we may have to face the verbose boilerplate:
#[js_function(1)]// ------> arguments lengthfnfibonacci(ctx:CallContext) -> Result<JsNumber>{// fetch args passed from nodelet n = ctx.get::<JsNumber>(0)?.try_into()?;// return the value with manually created JS VALUES
ctx.env.create_int64(fibonacci_native(n))}// and expose the function to JS#[module_exports]fninit(mutexports:JsObject) -> Result<()>{
exports.create_named_method("fibonacci", fibonacci)?;Ok(())}
It would be even worse if we want to create a exported JS class.
So I propose that we could implement a new procedural macro that provides more powerful code parsing and generating abilities.
#[napi_bindgen]// one for all, decorate the stuff could be exported. e.g. classes, functions, implementations#[napi_bindgen('name')]// custom exported alias
// ts declarationexportfunctionfibonacci(nth: number): number
For class and implementation exports:
// or `#[napi_bindgen('MyClass')]` for different class name#[napi_bindgen]pubstructTestClass{pubpub_field:u32
priv_field:String}#[napi_bindgen]implTestClass{pubfnnew(){Self{pub_field:1,priv_field:String::from('1')}}pubfnget_private_field(&self) -> &str{self.priv_field}}
The output would be like:
// ts declarationexportclassTestClass{pubField: number// could also turns static new to constructor directly.staticnew(): TestClassgetPrivateField(): string}
Pros & cons
The Pros
We would benefit a lot from the new napi_bindgen macro absolutely, and the farest I currently can see are:
Easier and faster to get started. With extremely less boilerplate, the developers will no longer need to do a lot repeated work like fetch arguments, wrap return value in JS VALUES.
Runtime type safe. so long as the macro auto box and unbox the arguments to or from JS VALUES, we can do arguments type validation in the macro internally. It will make the functions exported from napi safer and save a lot time if users want to do arguments validation as well.
Typescript support. It's not possible to generate typescript definitions currently because the types of arguments are always parsed in the function body instead of the function signature. Map napi functions signature with native functions directly could make it easy to be well done.
#[napi_bindgen]// tokens:// args[1] = CallContext (ignore)// args[2] = u32 (map to: number)// args[3] = SomeStruct// => if napi_bindgen_done_right(SomeStruct)// map to: SomeStruct// else// bail//fntest(ctx:CallContext,arg1:u32,arg2:SomeStruct) -> u32{}
The Cons
Of course, it's not that easy to achieve these goal. We may need a refresh overwrite of the whole codebase, and also there will be several bad impacts coexist with the final implementation of this proposal.
As we all know, rust macros provide us a fancy development experience when deal with code reuse or generate token stream with procedural macros, which is not even possible in other languages.
But, come back to reality, The convenience of debugging or the readability of macros are not as good as itself. We may possibly meet bugs come from the generated code by new macros because the implementation of #[napi-bindgen] will be far more complicated.
So it would be a great challenge for maintainers about debugging and designing abilities. For the community, this will increase the hardness of newers to get involved in or debugging theirselves.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Currently, the
napi_derive
package provides us several proc_macros likejs_function
which absolutely covered most scenarios.But when using it, we may have to face the verbose boilerplate:
It would be even worse if we want to create a exported
JS class
.napi_bindgen
proposal1So I propose that we could implement a new procedural macro that provides more powerful code parsing and generating abilities.
With this, we can do things like:
The code above would generate function in JS/TS:
For class and implementation exports:
The output would be like:
Pros & cons
The Pros
We would benefit a lot from the new
napi_bindgen
macro absolutely, and the farest I currently can see are:Easier and faster to get started. With extremely less boilerplate, the developers will no longer need to do a lot repeated work like fetch arguments, wrap return value in JS VALUES.
Runtime type safe. so long as the macro auto box and unbox the arguments to or from JS VALUES, we can do arguments type validation in the macro internally. It will make the functions exported from napi safer and save a lot time if users want to do arguments validation as well.
Typescript support. It's not possible to generate typescript definitions currently because the types of arguments are always parsed in the function body instead of the function signature. Map napi functions signature with native functions directly could make it easy to be well done.
The Cons
Of course, it's not that easy to achieve these goal. We may need a refresh overwrite of the whole codebase, and also there will be several bad impacts coexist with the final implementation of this proposal.
As we all know, rust macros provide us a fancy development experience when deal with code reuse or generate token stream with procedural macros, which is not even possible in other languages.
But, come back to reality, The convenience of debugging or the readability of macros are not as good as itself. We may possibly meet bugs come from the generated code by new macros because the implementation of
#[napi-bindgen]
will be far more complicated.So it would be a great challenge for maintainers about debugging and designing abilities. For the community, this will increase the hardness of newers to get involved in or debugging theirselves.
PR
#696
Beta Was this translation helpful? Give feedback.
All reactions