fix(javascript): resolve package exports targets only to the exact file (#1181)

A selected package exports target names one file, and Node tries no
extension or directory index for it. REA still resolved it like a relative
specifier, so `exports: "./file"` with only `file.js` present, or
`"./folder"` with only `folder/index.js`, reported a resolved import that
Node rejects under both import and require.

Resolve an exports target only to its exact file and otherwise report
not-found with a limitation naming the target. Legacy main entries keep
their extension and index fallbacks.

Fixes #1174

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kaoru0822andClaude Opus 5.5 authored and GitHub committed 2026-10-09 11:49:32 +08:00
1 parent e1afbc1914
commit 2a620c06cd
3 files changed
+88 -2

No files matched your search

@@ -105,8 +105,11 @@ const resolvePackagePath = (
],
},
);
const resolved =
mode === "files-and-index"
// An exports target names one exact file; Node tries no extension or index.
const resolved = exportsTargetUrl
? (resolveFileCandidates(input, [confined]) ??
exactExportsTargetNotFound(confined))
: mode === "files-and-index"
? (resolveFileCandidates(input, [
...fileCandidates(confined),
...indexCandidates(confined),
@@ -619,6 +622,14 @@ const notFoundCandidate = (): CandidateResolution => ({
],
});
const exactExportsTargetNotFound = (path: string): CandidateResolution => ({
resolvedPath: null,
status: "not-found",
limitations: [
`The selected package exports target ${path} does not exist in the inventoried artifact container; exports targets are exact files, so no extension or directory index was tried.`,
],
});
const fileUrlPath = (value: string): string | undefined => {
if (!value.startsWith("file://")) return undefined;
try {