-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
n-api: add napi_get_module() #28464
n-api: add napi_get_module() #28464
Conversation
3e42bd2
to
0765c5c
Compare
We make the `napi_env` per-module once more because it no longer holds any state that needs to be shared among add-ons. We then add a Node.js-specific N-API which allows one to obtain the module whose exports were initialized at addon startup. Re: nodejs/node-addon-api#449 Re: nodejs/node-addon-api#482 Re: nodejs/node-addon-api#505
0765c5c
to
925097e
Compare
@gabrielschulhof we've had quite a few discussion on the topic and I thought we were still worried about exposing the module object directly because it's specific to CJS module loading ? |
@mhdawson, @devsnek I was keeping that in mind. Yet it looks like at least a few folks were using the Before I submitted a PR I had stuff like NAPI_EXTERN napi_status
napi_get_module_filename(napi_env env, napi_value* result);
NAPI_EXTERN napi_status
napi_require(napi_env env,
napi_value module_name,
napi_value* result); In the case of In the end, this N-API is in As for the CJS "smell" of it, I'm hoping the fact that we're not upending the module initialization, but providing an N-API that one can call, if needed, will minimize the "smell". I do not feel strongly about landing this PR. The only reason I wrote it is that it seems there's a fair chunk of folks who were using the Nan equivalent of this, and now have no reasonable recourse – especially not nodejs/node-addon-api#449, where the native addon is not fronted by a pure-JS module. |
I guess I would like to spur some discussion on what to do with IMO the other important aspect of this PR is that we're moving back away from having a shared |
@gabrielschulhof I don’t know how people use this, but if I may offer an alternative suggestion: I’d like it if we could provide the addon with a way to store native data which is accessible through the
My suggestion for an API would basically be:
with |
@addaleax is it safe to use #include <stdlib.h>
#include <node_api.h>
typedef struct {
int data_item_1;
double data_item_2;
} AddonData;
static void DeleteAddonData(void* data) {
free(data);
}
static napi_value DoSomething(napi_env env, napi_callback_info info) {
AddonData* addon_data;
NAPI_CALL(env, napi_get_cb_info(env, info, NULL, NULL, NULL, &addon_data));
return NULL;
}
static napi_value DoSomethingElse(napi_env env, napi_callback_info info) {
AddonData* addon_data;
NAPI_CALL(env, napi_get_cb_info(env, info, NULL, NULL, NULL, &addon_data));
return NULL;
}
/* napi_value */ NAPI_MODULE_INIT(/* napi_env env, napi_value exports */) {
AddonData* addon_data = malloc(sizeof(*addon_data);
NAPI_CALL(env, napi_add_env_cleanup_hook(env, DeleteAddonDta, addon_data));
napi_property_descriptor bindings[] = {
{
"doSomething",
NULL,
DoSomething,
NULL,
NULL,
NULL,
napi_default,
addon_data
},
{
"doSomethingElse",
NULL,
DoSomethingElse,
NULL,
NULL,
NULL,
napi_default,
addon_data
},
};
NAPI_CALL(env, napi_define_properties(env,
exports,
sizeof(bindings) / sizeof(*bindings),
bindings));
return exports;
} This has the shortcoming that the This PR is more about providing access to |
Exposing things like "filename" makese sense to but it would be great to expose that in a way that is agnostic to CJS or ESM. Maybe napi_get_module_data(napi_env env, char* name); with some fixed values for name, one being 'filename' ? |
This seems like something a module author should expose themselves with a js wrapper. Not even the base filename concept is compatible between esm and cjs. |
@gabrielschulhof It’s not safe to run JS at that point, but otherwise I think this should work. And sure, it’s possible to do this, it’s just not very ergonomical at this point (imo).
I think storing it in
I would agree with @devsnek on this – I’m not a fan of introducing something that’s not going to be ESM-compatible without having a good story for how that’s going to evolve in the context of ESM. But honestly, I also feel like some of these things just belong in the JS wrapper that people usually write for their addon code. |
@addaleax since our discussion is OT wrt. this issue, I opened nodejs/abi-stable-node#378. |
@devsnek I agree that module authors should give themselves any such information they need via a JS module that fronts the native addon. The only reason I made this PR is because of the issues it references. It seems that there are packages out there which make available the native addon directly, the consumers of which expect to be able to simply Moving these use cases to N-API entails an additional effort of re-obtaining buy-in from their consumers for a new loading convention, like maybe const theAddon =
require('./path/to/native-addon.node')(
require.resolve('./path/to/native-addon.node')); It does seem like this use case is not overly widespread though. I'm happy to close this PR if we can agree that the risk of opening a can of worms in the CJS/ESM space outweighs the advantage of supporting the case where the native addon is not fronted by a JS module. |
Based on discussions in the N-API team meeting with Gabriel my current understanding is that we don't plan to land this. |
Added |
@mhdawson yeah, let's leave it in the blocked state for now. |
@gabrielschulhof should this remain open? |
8ae28ff
to
2935f72
Compare
Ping @nodejs/n-api ...Unfortunately this has stalled. Closing but it can be reopened if anyone wants to pick this back up. |
We make the
napi_env
per-module once more because it no longerholds any state that needs to be shared among add-ons.
We then add a Node.js-specific N-API which allows one to obtain the
module whose exports were initialized at addon startup.
Re: nodejs/node-addon-api#449
Re: nodejs/node-addon-api#482
Re: nodejs/node-addon-api#505
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes