Description
📗 API Reference Docs Problem
- Version: 14.2.0
- Platform: any
- Subsystem: esm
Location
Section of the site where the content exists
Affected URL(s):
Problem description
Concise explanation of what you found to be problematic
With the introduction of pkg.exports
a module only exports the paths explicitly listed in pkg.exports
, any other path can no longer be required. Let's have a look at an example:
Node 12.16.3:
> require.resolve('uuid/dist/v1.js');
'/example-project/node_modules/uuid/dist/v1.js'
Node 14.2.0:
> require.resolve('uuid/dist/v1.js');
Uncaught:
Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './dist/v1.js' is not defined by "exports" in /example-project/node_modules/uuid/package.json
So far, so good. The docs describe this behavior (although not super prominently):
Now only the defined subpath in "exports" can be imported by a consumer:
…
While other subpaths will error:
…
While this meets the expectations set out by the docs I stumbled upon package.json
no longer being exported:
> require.resolve('uuid/package.json');
Uncaught:
Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './package.json' is not defined by "exports" in /example-project/node_modules/uuid/package.json
For whatever reason I wasn't assuming the documented rules to apply to package.json
itself since I considered it package metadata, not package entrypoints whose visibility a package author would be able to control.
This new behavior creates a couple of issues with tools/bundlers that rely on meta information from package.json
.
- So right now, packages that do contain information to be consumed externally (e.g. by bundlers) in their
package.json
have to add thepackage.json
to thepkg.exports
field. - On the other hand bundlers/etc should then handle the case where a dependency doesn't export the
package.json
gracefully, since it might very well be the fact that a given package doesn't need to export any bundler meta information (and otherwise almost all packages on npm that could ever be used in a react-native project would have to addpackage.json
to their exports). - If bundlers however handle a missing
package.json
exports gracefully, I see the risk that many modules that currently rely on theirpackage.json
simply being externally consumable without additional effort might suddenly behave in odd ways when the meta information frompackage.json
is no longer readable by bundlers (and no error is thrown).
Examples where this issue already surfaced:
- package.json is not defined by "exports" uuidjs/uuid#444
- Plugin incompatible with Node.js
exports
package.json field sveltejs/rollup-plugin-svelte#104 - Package subpath './package.json' is not defined by "exports" react-native-community/cli#1168
- Importing error in React Native starting from nanoevents 3.0 version ai/nanoevents#44 (comment)
- Warning: Ignored package due to "Package subpath './package.json' is not defined by "exports"" facebook/react-native#28710
- https://github.com/locize/i18next-locize-backend/pull/326/files
- Metro Bundler ignores make-plural eemeli/make-plural#15
Now the question is how to move forward with this?
- One option would be to keep the current behavior and improve the documentation to explicitly warn about the fact, that
package.json
can no longer be resolved unless added toexports
. EDIT: Already done in 1ffd182 / Node.js v14.3.0 - Another option would be to consider adding an exception for
package.json
and always export it.
I had some discussion on slack with @ljharb and @wesleytodd but we didn't come to an ultimate conclusion yet 🤷♂️ .
- I would like to work on this issue and submit a pull request.