Closed ctavan closed 2 years ago
I'm not sure what the use-case is (if it exists) for restricting access to package.json
via Node.js' module importing facilities. But the ship has sailed.
That said, to avoid breaking things, it would be helpful for tooling authors if Node.js would expose an API like:
// node:util
getPackageJson(resolvable: string | URL): Promise<unknown>;
getPackageJsonSync(resolvable: string | URL): unknown;
...which would fulfill with the contents of the "closest" (sibling or ancestor) package.json
to resolvable
(for a rough userland equivalent, see find-pkg-up).
A simpler and easier-to-implement API would expect a resolvable package name or path/URL to package directory, and resolve with the contents of its package.json
--without otherwise crawling the directory structure (rough userland equivalent: read-pkg).
Should probably throw/reject if the operation fails.
Right now, adding package.json
to exports
is just boilerplate that library authors need to remember to add. Which is crap, of course. 😄
cc @GeoffreyBooth @wesleytodd @ljharb
Yes, a new API could work. Up above I suggested getPackageMetadata
, as this could be added without any breaking changes to "exports"
and has the additional benefit of being able to use the existing internal cache that Node keeps of all the package.json
files it’s already read for all modules.
Here's the recommended way to do this with ES modules:
import { readFileSync } from 'fs'; (async () => { const pkgPath = await import.meta.resolve('pkg/') console.log(pkgPath); console.log(readFileSync(new URL('package.json', pkgPath)).toString()); })();
The above also simplifies with TLA of course.
Currently the above only executes with
--experimental-import-meta-resolve
.@nodejs/modules-active-members I think we should discuss unflagging this feature.
// Nodejs v22.6.0
import.meta.resolve('@babel/runtime/')
// Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './' is not defined by "exports" in /Users/.../node_modules/@babel/runtime/package.json imported from ...
🥲
@GeoffreyBooth Should we open a new issue for adding getPackageMeta
? Or is there no point unless someone is going to send a PR?
📗 API Reference Docs Problem
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 inpkg.exports
, any other path can no longer be required. Let's have a look at an example:Node 12.16.3:
Node 14.2.0:
So far, so good. The docs describe this behavior (although not super prominently):
While this meets the expectations set out by the docs I stumbled upon
package.json
no longer being exported: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
.package.json
have to add thepackage.json
to thepkg.exports
field.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).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:
Now the question is how to move forward with this?
package.json
can no longer be resolved unless added toexports
. EDIT: Already done in https://github.com/nodejs/node/commit/1ffd182264dcf02e010aae3dc88406c2db9efcfb / Node.js v14.3.0package.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 🤷♂️ .