Description
Version
19.3.0
Platform
Darwin Geoffreys-MacBook-Pro.local 22.2.0 Darwin Kernel Version 22.2.0: Fri Nov 11 02:08:47 PST 2022; root:xnu-8792.61.2~4/RELEASE_X86_64 x86_64
Subsystem
module, esm, process, cli
What steps will reproduce the bug?
With a checkout of the node
repo at ~/Sites/node
:
$ pwd
/Users/geoffrey
$ node file:///Users/geoffrey/Sites/node/test/fixtures/es-modules/mjs-file.mjs
node:internal/modules/cjs/loader:1042
throw err;
^
Error: Cannot find module '/Users/geoffrey/file:/Users/geoffrey/Sites/node/test/fixtures/es-modules/mjs-file.mjs'
at Module._resolveFilename (node:internal/modules/cjs/loader:1039:15)
at Module._load (node:internal/modules/cjs/loader:885:27)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:82:12)
at node:internal/main/run_main_module:23:47 {
code: 'MODULE_NOT_FOUND',
requireStack: []
}
Node.js v19.3.0
Note the /Users/geoffrey/file:/Users/geoffrey/Sites/node/test/fixtures/es-modules/mjs-file.mjs
constructed specifier. This doesn’t make sense.
How often does it reproduce? Is there a required condition?
Every time.
What is the expected behavior?
Absolute file URLs should be allowable as program entry points.
What do you see instead?
Error: Cannot find module '/Users/geoffrey/file:/Users/geoffrey/Sites/node/test/fixtures/es-modules/mjs-file.mjs'
Additional information
I understand per https://nodejs.org/api/cli.html#program-entry-point the entry point is parsed by the CommonJS resolver, even when it passes the criteria for being loaded by the ESM one; but it doesn’t make sense that either resolver would be constructing an invalid path.
It’s also counterintuitive that file:///Users/geoffrey/Sites/node/test/fixtures/es-modules/mjs-file.mjs
should be acceptable input for --loader
and --import
but not as the main entry point. For example, all of these are valid:
node --import file:///Users/geoffrey/Sites/node/test/fixtures/es-modules/mjs-file.mjs --eval ';'
node --loader file:///Users/geoffrey/Sites/node/test/fixtures/es-modules/mjs-file.mjs --eval ';'
node --import file:///Users/geoffrey/Sites/node/test/fixtures/es-modules/mjs-file.mjs ./Sites/node/test/fixtures/es-modules/mjs-file.mjs
node --loader file:///Users/geoffrey/Sites/node/test/fixtures/es-modules/mjs-file.mjs ./Sites/node/test/fixtures/es-modules/mjs-file.mjs
cc @aduh95 @JakobJingleheimer @nodejs/modules @nodejs/loaders
This came up because I was writing a test like this:
const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
'--loader',
fixtures.fileURL('/es-module-loaders/loader.mjs'),
fixtures.fileURL('/es-modules/mjs-file.mjs'),
]);
The solution was to change the second fixtures.fileURL
to fixtures.path
; but this feels wrong.