nodejs / modules

Node.js Modules Team
MIT License
413 stars 43 forks source link

Unable to require.resolve a package location when the package is 'type:module' and 'exports' is defined without exposing `package.json`. #547

Closed trusktr closed 4 years ago

trusktr commented 4 years ago

First, see this popular question on StackOverflow, whose solution is now broken for some packages using Node ESM (with "type": "module" and an "exports" field that does not explicitly expose package.json).

The problem is that if a package has the following in package.json,

{
    "name": "@scope/package",
    ...
    "types": "dist/index.d.ts",
    "exports COMMENT:": "This removes 'dist' from import statements, as well as replaces the 'main' field. See https://github.com/nodejs/node/issues/14970#issuecomment-571887546",
    "exports": {
        ".": "./dist/index.js",
        "./": "./dist/"
    },
    ...
}

Then one can not use require() or require.resolve() to resolve package locations like the can with normal CommonJS packages.

For example, trying to run require.resolve('@scope/package/package.json') will fail with

Uncaught Error: Cannot find module '@scope/package/package.json'

In the repl you'll see a MODULE_NOT_FOUND message.

The package author would need to expose package.json for resolving to work:

{
    "name": "@scope/package",
    ...
    "types": "dist/index.d.ts",
    "exports": {
        "./package.json": "./package.json", // <---- here
        ".": "./dist/index.js",
        "./": "./dist/"
    },
    ...
}

I thought that exports was supposed to affect only import statements, but not require.

trusktr commented 4 years ago

Ah, the ESM doc says

"exports" are not specific to ES modules or CommonJS

So apparently it is supposed to work this way.

Maybe we need a new API, like require.resolvePackageLocation(moduleName)?

In the meantime, the resolve-package-path package works great with any package regardless of what it has for exports.

guybedford commented 4 years ago

This looks like a duplicate of https://github.com/nodejs/node/issues/49445.

GeoffreyBooth commented 4 years ago

Closing as a duplicate of nodejs/node#49445, @trusktr please see that issue and its referenced @nodejs/node issue.