Skip to content

Fix .js/.node precedence in isNodeApiModule; dedupe Info.plist checks (builds on #426) - #450

Closed
kraenhansen wants to merge 3 commits into
nextfrom
claude/426-followup
Closed

Fix .js/.node precedence in isNodeApiModule; dedupe Info.plist checks (builds on #426)#450
kraenhansen wants to merge 3 commits into
nextfrom
claude/426-followup

Conversation

@kraenhansen

Copy link
Copy Markdown
Collaborator

Summary

This builds directly on @wanxiankai's #426 (branch fix/verify-prebuild-fixtures, included here as the first commit) with a few refinements on top. It closes #424, superseding #448 and #449 (two independent attempts at the same fix, opened before this one was aware #426 already existed).

Note: this PR targets next in this repo rather than #426's branch directly, because this session's GitHub access is scoped to callstackincubator/react-native-node-api only and can't open a PR against a fork. @kraenhansen — happy to have this merged as-is, or closed in favor of #426 if you'd rather land these follow-ups there instead; wanxiankai's original commit is preserved either way.

What's on top of #426

  • Move the .js/.node precedence fix into isNodeApiModule (packages/host/src/node/path-utils.ts) instead of guarding the Babel plugin's require() rewrite with createRequire(this.filename).resolve(id). Reasons:
    • isNodeApiModule is the shared utility (also used by findNodeAddonForBindings), so fixing it there benefits every caller instead of only the plugin's require() handling.
    • createRequire(...).resolve() runs Node's own CommonJS resolution algorithm at Babel-transform time to predict what React Native's Metro bundler will resolve at runtime — but Metro doesn't use Node's resolver (it has its own, with platform extensions, Haste, etc.), so the two can diverge. Checking for a same-named .js/.cjs/.mjs/.json sibling file directly is simpler and doesn't depend on that assumption holding.
  • Validate the parsed Info.plist with a zod schema instead of ad hoc "key" in obj checks on an unknown value, matching how the rest of the codebase validates untrusted structured data (zod is already a dependency across several packages).
  • Reuse the exported escapeBundleIdentifier (now re-exported from react-native-node-api's node entrypoint) instead of re-deriving the bundle-identifier escaping regex inline in verify-prebuilds.mts, so the verifier can't silently drift out of sync with what writeFrameworkInfoPlist actually writes.

Test plan

  • pnpm install && pnpm run build — clean
  • pnpm --filter react-native-node-api test — the plugin, isNodeApiModule, and escapeBundleIdentifier suites pass; the only failures are 4 pre-existing permission-based tests that fail identically with and without this diff (confirmed via git stash) because this sandbox runs as root
  • pnpm exec tsc --build packages/node-addon-examples/tsconfig.node-scripts.json — clean (type-checks verify-prebuilds.mts)
  • pnpm exec eslint on all changed files — clean
  • pnpm run prettier:check — clean

Closes #424

cc @kraenhansen for review.

🤖 Generated with Claude Code


Generated by Claude Code

wanxiankai and others added 2 commits August 13, 2026 21:20
- Replace the Babel-transform-time require.resolve() guard with a check
  inside isNodeApiModule itself, so the fix lives in the shared utility
  (also used by findNodeAddonForBindings) instead of duplicating Node's
  module resolution algorithm via a second, independent code path that
  could diverge from what Metro actually resolves at runtime.
- Verify the Info.plist contents with a zod schema instead of ad hoc
  "in" checks on an untyped object, matching how the rest of the repo
  validates untrusted structured data.
- Reuse the exported escapeBundleIdentifier instead of re-deriving the
  bundle-identifier escaping regex inline in the verify script, so the
  two can't silently drift apart.

Closes #424

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q1k6UQJPPaqKEKmnsRUatt
@kraenhansen kraenhansen added Apple 🍎 Anything related to the Apple platform (iOS, macOS, Cocoapods, Xcode, XCFrameworks, etc.) Android 🤖 Anything related to the Android platform (Gradle, NDK, Android SDK) Host 🏡 Our `react-native-node-api-modules` package labels Aug 16, 2026 — with Claude
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q1k6UQJPPaqKEKmnsRUatt
@kraenhansen

Copy link
Copy Markdown
Collaborator Author

Closing as I pushed to #426 instead.

@kraenhansen
kraenhansen deleted the claude/426-followup branch August 16, 2026 18:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Android 🤖 Anything related to the Android platform (Gradle, NDK, Android SDK) Apple 🍎 Anything related to the Apple platform (iOS, macOS, Cocoapods, Xcode, XCFrameworks, etc.) Host 🏡 Our `react-native-node-api-modules` package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Two test gaps: unverified prebuild Info.plist and a missing .node fixture in the Babel plugin tests

3 participants