Description
If we make package deep linking explicit for ES packages, we could treat all other deep links as CommonJS resolutions by default.
That is, users would need to opt-in to get ES module deep links. By making it explicit, we (1) provide a future path where entry points are explicit, while also (2) fully supporting subpaths for CommonJS.
The idea would be to define a package.json "entrypoints" or similar along the lines of
{
"entrypoints": {
"x": "./x.js"
}
}
The new behaviour would then be:
import "es-package/x"
will check the package.json for "entrypoints", "default" or "default.js". If any of those are found (first in order), and "x" is found in "entrypoints" then load "x.js". Otherwise if any of those fields are found, and "x" is not found then throw an explicit error -Entry points must be explicit for ES packages through the "entrypoints" property
.import "cjs-package/x"
will check the package.json and see no "entrypoints" or "default" or "default.js" file. It will then loadcjs-package/x
as a CommonJS module.import '/path/to/es-package/x'
would have to do the same resolution check reading the package.json file from the package boundary (if not the same package.json boundary as the importer). This is a little complex, but important for completeness.
We end up treating "default", "entrypoints" and "default.js" as a flag here, yes, but at some level flagging behaviours are important I think... these flags form a convenience though making it easy for users go get started over the more explicit "mode" proposal.
The edge cases all work out as I can tell, for example I might start writing an "x.js" file that is an ES module that I can execute. To publish this and have "x.js" loadable I do need to explicitly declare it as an entry point.
Thoughts?