Skip to content

Commit 4bbca65

Browse files
kraenhansenclaude
andcommitted
Add a fixture registering via the deprecated napi_module_register (#446)
* Add a fixture registering via the deprecated napi_module_register The host gained support for addons that register themselves by calling napi_module_register while their library loads (#445), but nothing in the repo exercises that path — every other addon here exports napi_register_module_v1, which the loader finds first. This addon exports no such symbol, so it only loads if the fallback works. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013ugFE6vmMUVMTuoupvhMhX * Trigger the label-gated CI jobs The check workflow only re-evaluates its label conditions on opened, synchronize and reopened events, so the labels added after opening this PR need a push to take effect. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013ugFE6vmMUVMTuoupvhMhX * Drop the gyp file from the module-register fixture Nothing builds this from binding.gyp — cmake-rn drives the CMake project directly. The sibling fixtures keep theirs to stay close to upstream sources they were derived from, which does not apply to an addon written here. CMakeLists.txt is now hand-maintained rather than regenerated by gyp-to-cmake, which skips the directory now that there is no binding.gyp. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013ugFE6vmMUVMTuoupvhMhX * Require the addon directly instead of through bindings The bindings package earns its place when an addon has to be found across the several output directories node-gyp might have used. This addon is built by cmake-rn to one known location, so a plain require says the same thing with one less dependency — and it exercises the Babel plugin's ordinary require path rather than its bindings special case. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013ugFE6vmMUVMTuoupvhMhX --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent bd03b8f commit 4bbca65

5 files changed

Lines changed: 87 additions & 0 deletions

File tree

‎packages/node-addon-examples/src/index.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ export const suites: Record<
8686
require("../tests/buffers/addon.js");
8787
},
8888
async: () => require("../tests/async/addon.js") as () => Promise<void>,
89+
"module-register": () =>
90+
require("../tests/module-register/addon.js") as () => void,
8991
"threadsafe-function": () =>
9092
require("../tests/threadsafe-function/addon.js") as () => Promise<void>,
9193
},
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
cmake_minimum_required(VERSION 3.15...3.31)
2+
project(module-register-test)
3+
4+
find_package(weak-node-api REQUIRED CONFIG)
5+
6+
add_library(module-register-test-addon SHARED addon.c)
7+
8+
option(BUILD_APPLE_FRAMEWORK "Wrap addon in an Apple framework" ON)
9+
10+
if(APPLE AND BUILD_APPLE_FRAMEWORK)
11+
set_target_properties(module-register-test-addon PROPERTIES
12+
FRAMEWORK TRUE
13+
MACOSX_FRAMEWORK_IDENTIFIER module-register-test.addon
14+
MACOSX_FRAMEWORK_SHORT_VERSION_STRING 1.0
15+
MACOSX_FRAMEWORK_BUNDLE_VERSION 1.0
16+
XCODE_ATTRIBUTE_SKIP_INSTALL NO
17+
OUTPUT_NAME addon
18+
)
19+
else()
20+
set_target_properties(module-register-test-addon PROPERTIES
21+
PREFIX ""
22+
SUFFIX .node
23+
OUTPUT_NAME addon
24+
)
25+
endif()
26+
27+
target_link_libraries(module-register-test-addon PRIVATE weak-node-api)
28+
target_compile_features(module-register-test-addon PRIVATE cxx_std_17)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#include <node_api.h>
2+
3+
// This addon registers itself the deprecated way — a napi_module_register call
4+
// made while the library loads — and deliberately exports no
5+
// napi_register_module_v1 symbol, so a host that only looks for that symbol
6+
// cannot load it.
7+
//
8+
// The constructor is hand-rolled because node_api.h no longer offers a macro
9+
// that emits one: NAPI_MODULE_X is now an alias of the symbol-based
10+
// NAPI_MODULE.
11+
12+
static napi_value Registration(napi_env env, napi_callback_info info) {
13+
(void)info;
14+
napi_value result;
15+
if (napi_create_string_utf8(env, "napi_module_register", NAPI_AUTO_LENGTH,
16+
&result) != napi_ok) {
17+
return NULL;
18+
}
19+
return result;
20+
}
21+
22+
static napi_value Init(napi_env env, napi_value exports) {
23+
napi_property_descriptor properties[] = {
24+
{"registration", NULL, Registration, NULL, NULL, NULL, napi_default,
25+
NULL},
26+
};
27+
if (napi_define_properties(env, exports,
28+
sizeof(properties) / sizeof(properties[0]),
29+
properties) != napi_ok) {
30+
return NULL;
31+
}
32+
return exports;
33+
}
34+
35+
static napi_module addon_module = {
36+
NAPI_MODULE_VERSION, 0, __FILE__, Init, "module-register-test",
37+
NULL, {0},
38+
};
39+
40+
__attribute__((constructor)) static void RegisterAddon(void) {
41+
napi_module_register(&addon_module);
42+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
const assert = require("assert");
2+
// cmake-rn emits to {targetSourceDir}/build/{configuration}, and this package's
3+
// build script pins the configuration.
4+
const addon = require("./build/RelWithDebInfo/addon.node");
5+
6+
module.exports = () => {
7+
assert.strictEqual(addon.registration(), "napi_module_register");
8+
};
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "module-register-test",
3+
"version": "0.0.0",
4+
"description": "Tests of the deprecated napi_module_register registration",
5+
"main": "addon.js",
6+
"private": true
7+
}

0 commit comments

Comments
 (0)