-
-
Notifications
You must be signed in to change notification settings - Fork 33.9k
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.jsonhave to add thepackage.jsonto thepkg.exportsfield. - On the other hand bundlers/etc should then handle the case where a dependency doesn't export the
package.jsongracefully, 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.jsonto their exports). - If bundlers however handle a missing
package.jsonexports gracefully, I see the risk that many modules that currently rely on theirpackage.jsonsimply being externally consumable without additional effort might suddenly behave in odd ways when the meta information frompackage.jsonis 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
exportspackage.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.jsoncan 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.jsonand 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.