[GH-ISSUE #2022] [Bug] Extensionless CommonJS require resolves .cjs files that Node does not probe #673

Closed
opened 2026-10-15 18:27:15 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @xu91102 on GitHub (Oct 12, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/2022

Before submitting

  • Searched open/closed issues and recent/open PRs; this is a different behavior from #1939 and the open package-pattern work #2018.
  • Uses source-owned fixtures with no credentials or private target data.

Area

Evidence, artifacts, or reconstruction — JavaScript application analysis.

Observed behavior

Node exits 1 with MODULE_NOT_FOUND. REA selects feature.cjs for require("./feature"). Explicit require("./feature.cjs") is valid, but the extensionless request is a different lookup.

Reproduction

In a built source checkout, materialize the fixture:

node --input-type=module <<'JS'
import { mkdirSync, writeFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
const root = resolve("fixture");
const files = {
  "entry.mjs": "import value from \"./main.cjs\"; console.log(value);",
  "main.cjs": "const value = require(\"./feature\"); module.exports = value;",
  "feature.cjs": "module.exports = 42;"
};
for (const [path, text] of Object.entries(files)) {
 const target = resolve(root,path);
 mkdirSync(dirname(target),{recursive:true});
 writeFileSync(target,text);
}
JS
node fixture/entry.mjs
node scripts/rea.mjs analyze-javascript-application "$(pwd)/fixture" --format json > observed.json

Inspect normalized_result.graph.edges for specifier, resolved_path, and resolution_status, or source-map-original nodes and the graph coverage. The affected source checkout was built and the public CLI was executed on these exact fixture shapes before this report.

Expected behavior

Use the default Node CommonJS extension candidates (.js, .json, .node) for extensionless require and corresponding index lookups. Keep exact .cjs/.mjs requests, TypeScript emitted-source substitution, and non-module artifact-path inference.

Format/loader reference. Runtime/decoder controls were executed rather than inferred from documentation.

Impact and scope

Static dependency graphs disagree with actual Node module lookup. No live browser or native engine is required to reproduce the local directory-analysis failure.

Version and runtime

  • Source revision: 2ff850de68dc9b05c6faf2bbfd26d56bc2d5d27c (main at investigation start).
  • Node 24.18.0, npm 11.16.0, macOS 27.0.1 arm64.
  • Interface: compiled CLI.
  • Target: source-owned local directory.

Source-derived analysis

fileCandidates and indexCandidates share an artifact-wide extension list that includes .cjs, .mjs and HTML regardless of the calling loader.

Originally created by @xu91102 on GitHub (Oct 12, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/2022 ### Before submitting - [x] Searched open/closed issues and recent/open PRs; this is a different behavior from #1939 and the open package-pattern work #2018. - [x] Uses source-owned fixtures with no credentials or private target data. ### Area Evidence, artifacts, or reconstruction — JavaScript application analysis. ### Observed behavior Node exits 1 with MODULE_NOT_FOUND. REA selects feature.cjs for require("./feature"). Explicit require("./feature.cjs") is valid, but the extensionless request is a different lookup. ### Reproduction In a built source checkout, materialize the fixture: ```sh node --input-type=module <<'JS' import { mkdirSync, writeFileSync } from "node:fs"; import { dirname, resolve } from "node:path"; const root = resolve("fixture"); const files = { "entry.mjs": "import value from \"./main.cjs\"; console.log(value);", "main.cjs": "const value = require(\"./feature\"); module.exports = value;", "feature.cjs": "module.exports = 42;" }; for (const [path, text] of Object.entries(files)) { const target = resolve(root,path); mkdirSync(dirname(target),{recursive:true}); writeFileSync(target,text); } JS node fixture/entry.mjs node scripts/rea.mjs analyze-javascript-application "$(pwd)/fixture" --format json > observed.json ``` Inspect `normalized_result.graph.edges` for `specifier`, `resolved_path`, and `resolution_status`, or source-map-original nodes and the graph coverage. The affected source checkout was built and the public CLI was executed on these exact fixture shapes before this report. ### Expected behavior Use the default Node CommonJS extension candidates (.js, .json, .node) for extensionless require and corresponding index lookups. Keep exact .cjs/.mjs requests, TypeScript emitted-source substitution, and non-module artifact-path inference. [Format/loader reference](https://nodejs.org/api/modules.html#file-modules). Runtime/decoder controls were executed rather than inferred from documentation. ### Impact and scope Static dependency graphs disagree with actual Node module lookup. No live browser or native engine is required to reproduce the local directory-analysis failure. ### Version and runtime - Source revision: `2ff850de68dc9b05c6faf2bbfd26d56bc2d5d27c` (main at investigation start). - Node 24.18.0, npm 11.16.0, macOS 27.0.1 arm64. - Interface: compiled CLI. - Target: source-owned local directory. ### Source-derived analysis fileCandidates and indexCandidates share an artifact-wide extension list that includes .cjs, .mjs and HTML regardless of the calling loader.
bsakaguchi 2026-10-15 18:27:15 +00:00
Author
Owner

@chqcjq commented on GitHub (Oct 12, 2026):

Verified on current main (85c547793): the extensionless CommonJS require ./feature is correctly reported as not-found when only feature.cjs exists, matching Node.js behavior. The fix from c0904b4c is working. This issue can likely be closed.

<!-- gh-comment-id:6128730571 --> @chqcjq commented on GitHub (Oct 12, 2026): Verified on current main (85c547793): the extensionless CommonJS require `./feature` is correctly reported as `not-found` when only `feature.cjs` exists, matching Node.js behavior. The fix from c0904b4c is working. This issue can likely be closed.
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#673
No description provided.