.js suffix rules on file path specifiers in subpath exports clauses in package.json?

75 views Asked by At

In subpath clauses in the package.json exports field, is .js suffix required on the right hand side file path specifiers?

I was earlier told the spec says so, but when I read that spec,

https://nodejs.org/api/packages.html#subpath-exports

I don't actually see it stated anywhere explicitly? Only all the listed examples do include the .js suffix.

The spec details extensions on subpaths, but those only concern the left hand side? (ie the pattern to match, not what it resolves to).

What actually IS the definition for the right hand side? The only concrete statement I've found, claims that it must be "relative file URLs starting with ./." Further I can see from the spec that it allows wildcards. I assume its type is "package entry point", but I haven't found a detailed definition for that.

My interest stems from two issues:

The rules for javascript import statement says plenty about what is legal in the import-moduleName-specifier - specifically that its handling is open to host/implementation/bundler-specific. But it is not immediately obvious to me, that this carries over to rules for package.json exports - in particular, it would only concern left hand side of the exports-clauses?

So, where can I find definitive references for what is legal regarding the right hand file path specifiers?

https://nodejs.org/api/packages.html#extensions-in-subpaths

Examples: - are both of these legal, or only the latter?

{
  "exports": {
    "./examples/jsm/*": "./examples/jsm/*",
    "./addons/*": "./examples/jsm/*",
    "./src/*": "./src/*",
  }
}

{
  "exports": {
    "./examples/jsm/*": "./examples/jsm/*.js",
    "./addons/*": "./examples/jsm/*.js",
    "./src/*": "./src/*.js",
  }
}

UPDATE: I finally figured out, how exports in package.json and import in js impact each other on 'host dependent specifiers': I earlier said, that the js import 'host rules' don't affect the package.json export rules.. But they do..

The reason is that we are making an "A->B->C" chain.

C is the right-hand-side filepath in "package.json"-exports.

B is the left-hand-side subpath in "package.json"-exports.

But, B is also the right-hand-side modulename-specifier in the javascript import! Where the host rules apply!

So, even though we don't discuss suffix-rules regarding left-hand-side in package.json, hostspecific suffix-rules WILL apply when those package.json subpaths are mapped into the javascript import statement as specifiers!

Thus, whether you include or exclude .js suffix in package.json subpaths, WILL influence the host-specific behaviour with import-specifiers in your javascript imports.

1

There are 1 answers

0
jakob gaardsted On

The answer, as I understand it, is that it IS legal. You just have to tolerate the consequences: The mapping between subpath and filepath is a simple string replacement, so you will only achieve a match if there exists a file at the path which that simple string substitution corresponds to. That is, for

"./src/*":    "./source/*",
"./src/*":    "./source/*.js",
"./src/*.js": "./source/*.js",

The first rule would map any raw filename to itself.

The second would map myname to myname.js (and myname.js to myname.js.js!)

The third would restrict the mapping to e.g. myname.js -> myname.js, and ignore any non-js modulename-specifiers (subpaths).

The general rule is that there is no 'extension magic'.

Conclusions based on

https://nodejs.org/api/packages.html#subpath-patterns