Skip to content

fix(react-native): order react-native export condition before require#1028

Closed
kylemcd wants to merge 1 commit into
mainfrom
kyle-kno-14075-fix-knocklabsreact-native-exports-map-ordering-metro-loads
Closed

fix(react-native): order react-native export condition before require#1028
kylemcd wants to merge 1 commit into
mainfrom
kyle-kno-14075-fix-knocklabsreact-native-exports-map-ordering-metro-loads

Conversation

@kylemcd

@kylemcd kylemcd commented Jul 8, 2026

Copy link
Copy Markdown
Member

Description

Fixes the exports map ordering in @knocklabs/react-native so React Native's Metro bundler resolves the package to its source entry point (src/index.ts) rather than the prebuilt dist/cjs bundle.

Root cause. Node/Metro conditional-exports matching is first-match by object-key order. The exports["."] map listed require before the react-native condition:

".": {
  "require": "./dist/cjs/index.js",   // ← matched first
  "types": "./dist/types/index.d.ts",
  "react-native": "./src/index.ts",   // ← never reached
  "default": "./dist/esm/index.mjs"
}

React Native's Metro runs with both require and react-native conditions active, so it matched require first and loaded the prebuilt CommonJS bundle instead of the src/index.ts source the react-native condition exists to serve. Every sibling package (@knocklabs/client, @knocklabs/react-core, @knocklabs/react) already lists react-native first — react-native was the odd one out.

Why it started with RN 0.79. Package-exports resolution is enabled by default in Metro since React Native 0.79. On older RN, Metro used resolverMainFields → the top-level "react-native": "./src/index.ts" field → source, so it worked. This lines up with #838 (Cannot read property 'KnockProvider' of undefined), reported on RN 0.79.2.

Fix. Reorder exports["."] so types + react-native come first, matching @knocklabs/react-core.

Verification. Ran the real export maps through Metro's own resolver (metro-resolver's reduceExportsLikeMap) under RN's active conditions ({default, require, react-native}):

before after
@knocklabs/react-native . ./dist/cjs/index.js ./src/index.ts
./package.json subpath ./package.json ./package.json (unchanged)

Note: the resolution divergence is proven; the exact Hermes runtime crash from #838 was not reproduced end-to-end without a full RN app (loading the dist in plain Node still re-exports KnockProvider). The misconfiguration is unambiguously real and is the most likely trigger. Worth confirming with the reporter or a full Metro/RN repro before closing #838.

Tracked in KNO-14075.

Metro resolves conditional exports by first match in object-key order.
Because the `require` condition was listed before `react-native` in the
`exports["."]` map, Metro (with package exports enabled by default since
React Native 0.79) matched `require` first and resolved
@knocklabs/react-native to the prebuilt `dist/cjs` bundle instead of the
`react-native` -> `src/index.ts` source entry it is meant to serve.

Reorder the map so `types` and `react-native` come first, matching
@knocklabs/react-core and @knocklabs/client. Verified against
metro-resolver: the package now resolves to `./src/index.ts` under RN's
active conditions.

Refs #838
@linear-code

linear-code Bot commented Jul 8, 2026

Copy link
Copy Markdown

KNO-14075

@vercel

vercel Bot commented Jul 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
javascript-ms-teams-connect-example Ready Ready Preview, Comment Jul 8, 2026 3:08pm
javascript-nextjs-example Ready Ready Preview, Comment Jul 8, 2026 3:08pm
javascript-slack-connect-example Ready Ready Preview, Comment Jul 8, 2026 3:08pm
javascript-slack-kit-example Ready Ready Preview, Comment Jul 8, 2026 3:08pm

Request Review

@changeset-bot

changeset-bot Bot commented Jul 8, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: e765e3e

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@knocklabs/react-native Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@codecov

codecov Bot commented Jul 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 64.49%. Comparing base (70e7669) to head (e765e3e).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1028   +/-   ##
=======================================
  Coverage   64.49%   64.49%           
=======================================
  Files         212      212           
  Lines       10217    10217           
  Branches     1389     1389           
=======================================
  Hits         6589     6589           
  Misses       3603     3603           
  Partials       25       25           

@kylemcd kylemcd closed this Jul 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant