Skip to content

Support Node-API modules declaring their "Node-API version" #4

Description

@kraenhansen

Node-API modules can declare a version that they want to be initialized with, either:

As per https://nodejs.org/docs/latest/api/n-api.html#node-api-version-matrix I believe this should default to 8 if not explicitly provided by the addon.

Blocked on an upstream Hermes change

Since we moved to Hermes' first-party Node-API implementation, the addon's Node-API version is Hermes' to act on, and its public API currently offers no way to set it:

  • napi_env__::module_api_version is a fixed member initialized to NAPI_VERSION (API/napi/hermes_napi_impl.h), and nothing assigns it afterwards.
  • hermes_napi_create_env(void *hermes_runtime, hermes_napi_host *host) takes no version, so an embedder cannot pass one in.
  • hermes_napi_load_module() — which we now use to load addons — does not look up node_api_module_get_api_version_v1, nor read nm_version off the module it falls back to.

The version is not inert in Hermes: API/napi/hermes_napi_reference.cpp branches on env->module_api_version < 10 for reference semantics, so an addon declaring version 8 is currently served version-10 behavior.

Detecting the version on our side is easy (dlsym the symbol, or read nm_version), but there is nowhere to put the answer. So this needs one of the following upstream in facebook/hermes first, and an issue should be opened there:

  1. hermes_napi_load_module() reads node_api_module_get_api_version_v1 (falling back to nm_version, then to 8) and sets module_api_version on the env itself — matching what Node does in napi_module_register_by_symbol. Preferred: it keeps the detection next to the loading, so every embedder gets it right.
  2. Failing that, a way for the embedder to set it — an extra parameter on a hermes_napi_create_env variant, or a setter — so we can detect the version ourselves and pass it in.

Worth flagging in that upstream issue: Hermes defaults to NAPI_VERSION (the newest version it implements) where Node.js defaults an addon that declares nothing to 8, so the default is a compatibility difference on its own, independent of which option above is taken.

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions