Search code examples
node.jsrequirecommonjs

NodeJS - How the LOAD_SELF_REFERENCE of the "require" function works?


According to NodeJS docs, the require function has a loading stage named LOAD_SELF_REFERENCE. It has the following pseudo-code:

LOAD_SELF_REFERENCE(X, START)
1. Find the closest package scope to START.
2. If no scope was found, return.
3. If the `package.json` has no "exports", return.
4. If the name in `package.json` isn't a prefix of X, throw "not found".
5. Otherwise, load the remainder of X relative to this package as if it was loaded via `LOAD_NODE_MODULES` with a name in `package.json`.

I assume that this algorithm resolves modules, which are nested inside the same package as the "require" caller. For instance, calling require("a/x") from a/y.js.

According to (4.), if the name in package.json is not a prefix of X the algorithm should throw an error. So I assume that the following code and the folders structure should crash:

node_modules
|-a
  |-package.json
  |-a.js
|-b
  |-package.json
  |-b.js
  |-x.js

where:

node_modules/a/package.json:

{
    "name": "a",
    "main": "./a",
    "exports": {
        ".": "./a"
    }
}

node_modules/a/a.js:

require("b/x");

node_modules/b/package.json:

{
    "name": "b",
    "main": "./b",
    "exports": {
        ".": "./b",
        "./x": "x"
    }
}

But it somehow works. Is this a mistake in documentation? Or I interpret the pseudo-code incorrectly?

Please, advice. Thanks.


Solution

  • It seems that this is a specification bug.