Affected URL(s)
https://nodejs.org/api/packages.html#conditional-exports
Description of the problem
I'm coming here from evanw/esbuild#1956. Specifically the esbuild bundler implements node's spec for exports in package.json files. Node's documentation for exports says this:
"import" - matches when the package is loaded via import or import(), or via any top-level import or resolve operation by the ECMAScript module loader. Applies regardless of the module format of the target file. Always mutually exclusive with "require".
"require" - matches when the package is loaded via require(). The referenced file should be loadable with require() although the condition matches regardless of the module format of the target file. Expected formats include CommonJS, JSON, and native addons but not ES modules as require() doesn't support them. Always mutually exclusive with "import".
"default" - the generic fallback that always matches. Can be a CommonJS or ES module file. This condition should always come last.
This is what esbuild implements. The case I'm looking for clarification on is that there are packages that just have require and import but not default. This is reasonable as the example in the documentation also doesn't include a default condition, and the documentation says import and require are mutually exclusive (i.e. exactly one should be present).
However, esbuild performs the following kinds of path resolution:
import-statement
require-call
entry-point
import-rule
url-token
I understand what should happen with the first two but not with the last three. An entry point is path resolution that happens due to a package name provided on the command line. There is no import or require in that case. And the last two happen when you import things from CSS (something a bundler has to deal with) where there is also no JS import statement or require call. If esbuild supported importing things from HTML, which it may one day, there would also be those cases to consider.
Right now esbuild handles these non-JS cases by still running the exports logic but just without the import or require conditions active, since it's neither an import nor a require. But then that breaks when there's no default condition. Do you have any opinion for what should happen here, as the authors of this specification? Some options:
- Don't apply
import or require and fail path resolution if nothing applies (esbuild's current behavior)
- Don't apply
import or require and fall back to legacy module/main fields if nothing applies
- Pick one of
import or require to apply arbitrarily
- Apply both
import and require
- Don't attempt to apply
exports rules at all and only use legacy module/main fields
- Undefined: up to the tool to do whatever they want
- Something else?
Affected URL(s)
https://nodejs.org/api/packages.html#conditional-exports
Description of the problem
I'm coming here from evanw/esbuild#1956. Specifically the esbuild bundler implements node's spec for
exportsinpackage.jsonfiles. Node's documentation forexportssays this:This is what esbuild implements. The case I'm looking for clarification on is that there are packages that just have
requireandimportbut notdefault. This is reasonable as the example in the documentation also doesn't include adefaultcondition, and the documentation saysimportandrequireare mutually exclusive (i.e. exactly one should be present).However, esbuild performs the following kinds of path resolution:
import-statementrequire-callentry-pointimport-ruleurl-tokenI understand what should happen with the first two but not with the last three. An entry point is path resolution that happens due to a package name provided on the command line. There is no import or require in that case. And the last two happen when you import things from CSS (something a bundler has to deal with) where there is also no JS
importstatement orrequirecall. If esbuild supported importing things from HTML, which it may one day, there would also be those cases to consider.Right now esbuild handles these non-JS cases by still running the
exportslogic but just without theimportorrequireconditions active, since it's neither an import nor a require. But then that breaks when there's nodefaultcondition. Do you have any opinion for what should happen here, as the authors of this specification? Some options:importorrequireand fail path resolution if nothing applies (esbuild's current behavior)importorrequireand fall back to legacymodule/mainfields if nothing appliesimportorrequireto apply arbitrarilyimportandrequireexportsrules at all and only use legacymodule/mainfields