fix(exports): correct ./components/* source targets for two non-tsx modules - #446
Open
YevheniiKotyrlo wants to merge 2 commits into
Open
YevheniiKotyrlo wants to merge 2 commits into
YevheniiKotyrlo wants to merge 2 commits into
Conversation
… modules `./components/*` declares `source` and `react-native` as `./src/components/*.tsx`, but `copyComponentProperties` is authored `.ts` and `index` is `.cts`/`.ts`. Export conditions match on key presence rather than target existence, so both subpaths are a hard ERR_MODULE_NOT_FOUND under either condition, with no fallthrough to import/require. `react-native` is live: Expo sets it for iOS and Android. `source` is what react-native-builder-bob's example-app workflow runs on. An exact key beats a pattern regardless of declaration order, so two entries resolve it. `index` takes `.cts` to match what the existing exact `./components` entry already declares. Closes nativewind#445
Contributor
Author
Why no device screenshot, and no testBoth have the same cause: this changes two The measurement is exhaustive rather than illustrative: 509 declared targets across every entry and condition, 0 missing after the fix. Before it, two are a hard The sweep needs |
… that exists The `./components/*` wildcard maps `source` to `./src/components/*.tsx`, so a non-tsx module under that directory resolves to a file that is not there. Resolution is decidable from source alone, so this needs no build: it walks the exports map the way node does — exact key first, then the pattern whose literal prefix before `*` is longest — and checks the `source` and `react-native` targets on disk. Two censuses drive it, every literal subpath and every module in src/components/, each with a non-empty assertion.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Fixes the four broken targets reported in #445.
./components/*declaressourceandreact-nativeas./src/components/*.tsx, but two modules the pattern matches are not authored.tsx:Export conditions match on key presence, not target existence, so there is no fallthrough to
import/require— both subpaths are a hardERR_MODULE_NOT_FOUNDunder either condition:react-nativeis not dormant — Expo sets it for iOS and Android viaunstable_conditionsByPlatform.sourceis the conditionreact-native-builder-bob's example-app workflow runs on.Solution
Two exact keys. An exact key beats a pattern regardless of declaration order, mirroring the existing
./components/react-native-gesture-handlerentry.indextakes.ctsrather than.tsbecause that is what the exact./componentsentry already declares — the wildcard's.tsxguess contradicted the map's own neighbouring entry.Tests
src/__tests__/package/exports-source-targets.test.ts— 37 cases, no build needed. Resolution is decidable from source alone, so it walks theexportsmap the way node does (exact key first, then the pattern whose literal prefix before*is longest) and asserts everysourceandreact-nativetarget names a file on disk.Two censuses drive it: every literal subpath, and every module in
src/components/reduced to the subpath a consumer would import. A case asserts both are non-empty, so a narrowed map cannot quietly produce zero cases.Reverting the manifest diff reddens exactly
./components/copyComponentPropertiesand./components/index, leaves the other 33 green, and names./src/components/copyComponentProperties.tsxin the failure — the file the wildcard points at and that is not there.Verification
Applied against the published 3.0.7 tarball, both subpaths resolve under
sourceandreact-native, and every other entry is unchanged. I checked the whole map rather than just these two: 509 declared targets across every entry and every condition, 0 missing after the fix.That sweep is how the defect surfaced. It walks the real
dist/module/**tree, expands each wildcard over it (skipping stems that have an exact key, since exact beats pattern) and asserts every declared target exists. The test above is its source-only half — the part that needs noprepareand so can run in CI; thedist/**half would belong post-build if you want it.yarn test— 1085 passed, 21 skipped, 3 failed; the three are the Windows-only babel path-separator failures #390 fixes, green on CI.yarn typecheckandyarn lintclean.Base
This may already be fixed upstream. Current
mainalready declares both./components/copyComponentPropertiesand./components/indexwith the same targets this diff adds, so the change is a no-op against it. #445 was closed as completed on 2026-09-14. Close it if nothing here is still missing; I will fold whatever is into a fresh one.Branched off
f70c402.mainhas since taken #451 (a5002c5). 1 of the 1 files this changes also moved there (package.json), and it still merges cleanly onto currentmain. Every measurement above was taken onf70c402. Say the word and I will re-apply it onto currentmain.