Skip to content

test: assert every path the package manifest declares names a file - #1857

Open
YevheniiKotyrlo wants to merge 1 commit into
nativewind:mainfrom
YevheniiKotyrlo:fix/metro-source-export-target
Open

YevheniiKotyrlo wants to merge 1 commit into
nativewind:mainfrom
YevheniiKotyrlo:fix/metro-source-export-target

Conversation

@YevheniiKotyrlo

@YevheniiKotyrlo YevheniiKotyrlo commented Sep 9, 2026 •

Copy link
Copy Markdown
Contributor

Problem

An export condition matches on key presence, not on whether its target resolves, so a target naming a missing file fails with ERR_MODULE_NOT_FOUND instead of falling through. ./metro's source target named ./src/metro.ts for a module authored .tsx until 361e90b. It was the third broken target in this manifest after #1638 (., ./babel) and #1723 (./types), and consumers found all three.

Why it isn't caught today

Jest, tsc and eslint never resolve the manifest, and .github/scripts/consumer_rc.py loads nativewind/metro and nativewind/babel under Node's default conditions, so no source or types target is ever resolved.

Solution

361e90b fixed ./metro, so this PR now carries only the guard. src/__tests__/package-exports.ts walks main, module, types and every leaf of the exports condition tree and asserts each names a file that exists. The list comes from the manifest, so a new export is covered as soon as it is added, and two cases assert the list is non-empty, so a manifest that stops being read fails instead of passing. Targets under bob's output directory are checked once a build has run, which CI does before testing and prepublishOnly before publishing.

Tests

With ./metro's source set back to ./src/metro.ts, the guard fails on that one target and the other three cases pass:

- Array []
+ Array [
+   "exports[\"./metro\"] [source] -> ./src/metro.ts",
+ ]

Verification

On Windows with Node 26: yarn lint clean · yarn typecheck clean · yarn build clean · yarn test --maxWorkers=2 --coverage 11 suites, 103 tests passed · yarn example expo export --platform web clean · no unstaged files after either build · release guards 17 passed. Not run: the iOS dev build, which no file in this change reaches.

Base

Cut from f9cfae6c, the current main.

An export condition matches on key presence, not on whether its target
resolves, so a target naming a missing file is ERR_MODULE_NOT_FOUND with no
fallthrough to `import` or `require`. Every broken target in this manifest so
far was found by a consumer rather than by CI — nativewind#1638 fixed `.` and
`./babel`, nativewind#1723 fixed `./types`, 361e90b fixed `./metro`'s `source` — because
the test suite, `tsc` and `eslint` never resolve the manifest.

The test walks `main`, `module`, `types` and every leaf of the `exports`
condition tree and asserts each one names a file that exists. Build-output
targets are checked once `yarn build` has run; CI builds before it tests,
and `prepublishOnly` builds before it publishes.
@YevheniiKotyrlo
YevheniiKotyrlo force-pushed the fix/metro-source-export-target branch from d7d66b3 to 637375f Compare October 11, 2026 15:27
@YevheniiKotyrlo YevheniiKotyrlo changed the title fix: point the ./metro source condition at the file it names test: assert every path the package manifest declares names a file Oct 11, 2026

This branch has not been deployed

No deployments
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