Skip to content

Entry points specified as absolute URLs fail to load #46009

Description

@GeoffreyBooth

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    cliIssues and PRs related to the Node.js command-line interface.esmIssues and PRs related to the ECMAScript Modules implementation.moduleIssues and PRs related to the module subsystem.processIssues and PRs related to the process subsystem.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions