[PR #1181] [MERGED] fix(javascript): resolve package exports targets only to the exact file #2706

Closed
opened 2026-10-17 21:09:19 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/1181
Author: @kaoru0822-kitauji
Created: 10/9/2026
Status: ✅ Merged
Merged: 10/9/2026
Merged by: @N0zoM1z0

Base: main ← Head: fix/javascript-exports-exact-target


📝 Commits (1)

  • 5220214 fix(javascript): resolve package exports targets only to the exact file

📊 Changes

3 files changed (+88 additions, -2 deletions)

View changed files

📝 src/application/javascript/JavaScriptArtifactPathResolution.test.ts (+62 -0)
📝 src/application/javascript/JavaScriptArtifactPathResolution.ts (+13 -2)
📝 tests/boundary/filesystem/javascriptPackageExportTargets.test.ts (+13 -0)

📄 Description

Summary

JavaScript application analysis resolved a selected package exports target as if it were a relative specifier, trying appended extensions and directory indexes. With {"exports":"./file"} and only file.js present, or {"exports":"./folder"} with only folder/index.js, REA reported a resolved import to file.js or folder/index.js. Node rejects both, under both import and require.

Fixes #1174

Cause

resolveCandidate handled both legacy main entries and exports targets (exportsTargetUrl = true), and its first step tries candidate followed by candidate + extension. PR #606 had already stopped a missing exports target from falling back to the package's index.*, but the extension list and a directory target's own index were still tried.

Change (src/application/javascript/JavaScriptArtifactPathResolution.ts)

An exports target resolves only to the exact file it names. If that file is absent, the result is not-found with resolved_path: null and a limitation naming the target and stating that no extension or directory index was tried. Legacy main entries and relative specifiers keep their extension, directory-package, and index fallbacks.

Node oracle

exports import require
"./actual" (only actual.cjs) ERR_MODULE_NOT_FOUND MODULE_NOT_FOUND
"./folder" (only folder/index.js) ERR_UNSUPPORTED_DIR_IMPORT MODULE_NOT_FOUND

Tests

  • tests/boundary/filesystem/javascriptPackageExportTargets.test.ts: both cases join the existing real-Node comparison, which runs Node under each loader and requires REA's edge to match (resolved_path: null, not resolved). Fails on main (4 cases).
  • src/application/javascript/JavaScriptArtifactPathResolution.test.ts (package exports exact targets): ./file and ./folder are not-found with the exact-file limitation under both loaders. A legacy main control (./file → file.js, ./folder → folder/index.js) still resolves. Fails on main (2 cases).

Verification

  • npm run check:fast, npm run jscpd (2.49%)
  • npm run test:focused -- the 16 JavaScript test files covering exports, package metadata, and artifact path resolution (314 passed)
  • Built CLI on the issue's three-file fixture: the pkg edge is not-found with resolved_path: null (on main: resolved to node_modules/pkg/file.js)

No Hopper/Ghidra verification was needed: the change is limited to static JavaScript module resolution.

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/1181 **Author:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Created:** 10/9/2026 **Status:** ✅ Merged **Merged:** 10/9/2026 **Merged by:** [@N0zoM1z0](https://github.com/N0zoM1z0) **Base:** `main` ← **Head:** `fix/javascript-exports-exact-target` --- ### 📝 Commits (1) - [`5220214`](https://github.com/morluto/rea/commit/5220214b275a6f33b33a8e254c036beed6037cf5) fix(javascript): resolve package exports targets only to the exact file ### 📊 Changes **3 files changed** (+88 additions, -2 deletions) <details> <summary>View changed files</summary> 📝 `src/application/javascript/JavaScriptArtifactPathResolution.test.ts` (+62 -0) 📝 `src/application/javascript/JavaScriptArtifactPathResolution.ts` (+13 -2) 📝 `tests/boundary/filesystem/javascriptPackageExportTargets.test.ts` (+13 -0) </details> ### 📄 Description ## Summary JavaScript application analysis resolved a selected package `exports` target as if it were a relative specifier, trying appended extensions and directory indexes. With `{"exports":"./file"}` and only `file.js` present, or `{"exports":"./folder"}` with only `folder/index.js`, REA reported a resolved import to `file.js` or `folder/index.js`. Node rejects both, under both `import` and `require`. Fixes #1174 ## Cause `resolveCandidate` handled both legacy `main` entries and exports targets (`exportsTargetUrl = true`), and its first step tries `candidate` followed by `candidate + extension`. PR #606 had already stopped a missing exports target from falling back to the package's `index.*`, but the extension list and a directory target's own index were still tried. ## Change (`src/application/javascript/JavaScriptArtifactPathResolution.ts`) An exports target resolves only to the exact file it names. If that file is absent, the result is `not-found` with `resolved_path: null` and a limitation naming the target and stating that no extension or directory index was tried. Legacy `main` entries and relative specifiers keep their extension, directory-package, and index fallbacks. ## Node oracle | `exports` | `import` | `require` | |---|---|---| | `"./actual"` (only `actual.cjs`) | `ERR_MODULE_NOT_FOUND` | `MODULE_NOT_FOUND` | | `"./folder"` (only `folder/index.js`) | `ERR_UNSUPPORTED_DIR_IMPORT` | `MODULE_NOT_FOUND` | ## Tests - `tests/boundary/filesystem/javascriptPackageExportTargets.test.ts`: both cases join the existing real-Node comparison, which runs Node under each loader and requires REA's edge to match (`resolved_path: null`, not `resolved`). Fails on `main` (4 cases). - `src/application/javascript/JavaScriptArtifactPathResolution.test.ts` (`package exports exact targets`): `./file` and `./folder` are `not-found` with the exact-file limitation under both loaders. A legacy `main` control (`./file` → `file.js`, `./folder` → `folder/index.js`) still resolves. Fails on `main` (2 cases). ## Verification - `npm run check:fast`, `npm run jscpd` (2.49%) - `npm run test:focused --` the 16 JavaScript test files covering exports, package metadata, and artifact path resolution (314 passed) - Built CLI on the issue's three-file fixture: the `pkg` edge is `not-found` with `resolved_path: null` (on `main`: `resolved` to `node_modules/pkg/file.js`) No Hopper/Ghidra verification was needed: the change is limited to static JavaScript module resolution. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-17 21:09:19 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#2706
No description provided.