node icon indicating copy to clipboard operation
node copied to clipboard

`imports` allows and ignores `#name/` in package map

Open evanw opened this issue 2 years ago • 1 comments

Version

v17.0.1

Platform

Darwin Evans-MacBook-Pro.local 20.6.0 Darwin Kernel Version 20.6.0: Mon Aug 30 06:12:21 PDT 2021; root:xnu-7195.141.6~3/RELEASE_X86_64 x86_64

Subsystem

No response

What steps will reproduce the bug?

Here's a simple example:

$ cat test.mjs
import * as x from '#x'
console.log(x)

$ cat package.json
{
  "imports": {
    "#x": "#what/foo/y.mjs"
  }
}

$ cat node_modules/foo/y.mjs
export let y = true

$ node test.mjs
[Module: null prototype] { y: true }

Notice the bogus #what/ prefix that is being discarded by node.

How often does it reproduce? Is there a required condition?

Always

What is the expected behavior?

I expected path resolution to fail, at least according to the documented algorithm here: https://nodejs.org/api/esm.html#resolution-algorithm. From what I understand, it's supposed to go something like this:

  1. ESM_RESOLVE("#x", "file://.")
  2. PACKAGE_IMPORTS_RESOLVE("#x", "file://.", ["default"])
  3. PACKAGE_IMPORTS_EXPORTS_RESOLVE("#x", { "#x": "#what/foo/y.mjs" }, "file://.", true, ["default"])
  4. PACKAGE_TARGET_RESOLVE("file://.", "#what/foo/y.mjs", "", false, true, ["default"])
  5. PACKAGE_RESOLVE("#what/foo/y.mjs", "file://./")

At this point packageName should be "#what" and packageSubpath should be ./foo/y.mjs. That should then fail because there is no file called node_modules/#what/foo/y.mjs on the file system.

What do you see instead?

Somehow the #what/ prefix seems to be getting lost in the process which lets the remapping to #what/foo/y.mjs succeed. Specifically #what/foo/y.mjs behaves just like foo/y.mjs. If I'm reading the algorithm correctly, then I think node's implementation is diverging from the specification somewhere and is incorrect.

Additional information

This looks like a bug in node to me. But if it's not, it would be great to update the documentation so that other implementations of node's algorithm can be implemented correctly. I'm trying to get the module resolution algorithm in esbuild to match node and I'm not sure what to do here.

evanw avatar Oct 23 '21 21:10 evanw

Since this is labled esm could someone ping the @nodejs/modules team so we can get a clarification about what the expected behaviour is supposed to be?

merceyz avatar Sep 17 '22 15:09 merceyz