-
Notifications
You must be signed in to change notification settings - Fork 30k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
module: fix extension searching for exports #32351
Conversation
//cc @nodejs/modules-active-members I would like to try and get this landed for the release next week if possible (and possibly before the next meeting). Please take a look if you have time. |
I very much disagree with this; CommonJS means extension searching, and every context that involves CJS should always support it. This, thus, does not have modules group consensus, and I'd prefer we discuss it before landing it. |
If we want CJS and ESM to be the same, the path to that is adding extension searching to ESM, not the reverse. |
|
For an example of the problem this is fixing see Babel at babel/babel#11283, where @ljharb I would really like to get this out in the coming 13 release before the meeting if you would reconsider your objection. |
I feel very strongly that anything CJS should always have extension and index searching. |
There is very clearly a mutually exclusive choice here between having full
parity of exports resolution between esm and cjs and supporting extension
searching.
If it comes down to it, there is simply no way we would change the esm
implementation to support extension searching. So we arrive at this local
non optimal footgun position. That will be the only outcome, and if that
must be it then ok, but it would be a shame for users.
…On Mon, Mar 23, 2020 at 08:16 Jordan Harband ***@***.***> wrote:
I feel very strongly that anything CJS should always have extension and
index searching.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#32351 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAESFSSEDXU4PKEEQAOPLP3RI35DBANCNFSM4LO46XHA>
.
|
I'd agree with @guybedford , having the field vary between CJS and ESM usage would lead to fragmentation. We need to pick a single choice to always, or never do extension searching for the field. I'd prefer we pick the simpler, non-searching behavior as it is easier for tools to coordinate around that form rather than when we might not know which extensions are supported in CJS at the current time of evaluation (people mutating |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
FWIW my LGTM is dependent on discussion in the modules team and ensuring there are no large concerns with it. So please do not land yet |
There's another complication. Here's how CommonJS treats trailing slashes today: // ./main.js
require('./folder/');
// ./folder/index.js
console.log('hi'); node ./main.js
hi Yet, of course, per the So the existing behavior doesn't actually match CommonJS searching behavior already. |
Trying to parse how your example relates to
Where |
In CJS, you'd use |
Test A, traditional CommonJS: // ./main.js
require('foo/'); // Note the trailing slash
// ./node_modules/foo/dist/index.js
console.log('hi');
// ./node_modules/foo/package.json
{ "main": "./dist/index.js" } node ./main.js
hi Test B, with // ./main.js and ./node_modules/foo/dist/index.js unchanged from A
// ./node_modules/foo/package.json
{ "exports": "./dist/index.js" } node ./main.js
internal/modules/cjs/loader.js:524
throw new ERR_PACKAGE_PATH_NOT_EXPORTED(basePath, mappingKey);
^
Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './' is not defined by "exports" in /private/tmp/test/node_modules/foo/package.json
at applyExports (internal/modules/cjs/loader.js:524:9)
at resolveExports (internal/modules/cjs/loader.js:541:12)
at Function.Module._findPath (internal/modules/cjs/loader.js:661:22)
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:963:27)
at Function.Module._load (internal/modules/cjs/loader.js:859:27)
at Module.require (internal/modules/cjs/loader.js:1036:19)
at require (internal/modules/cjs/helpers.js:72:18)
at Object.<anonymous> (/private/tmp/test/main.js:1:1)
at Module._compile (internal/modules/cjs/loader.js:1147:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1167:10) {
code: 'ERR_PACKAGE_PATH_NOT_EXPORTED'
} |
Right, but that example is just any unexported path which isn't specific to trailing slash afaict? |
Well it just doesn't match the CommonJS behavior. If in test B you change |
Adding a trailing slash changes the behavior, that's not really the same thing. |
What I think they're saying is that |
92fc811
to
17e65cf
Compare
As discussed in the meeting, I've added the new commit to retain extension searching for folder exports in CommonJS exports resolution only, along with tests of the various lookups. |
This comment has been minimized.
This comment has been minimized.
} | ||
} | ||
|
||
const basePath = path.resolve(curPath, request); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will delete require('path').resolve
break this code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, although there are a lot of calls to path.resolve
within this module, so changing that is best done as a separate refactoring.
84baa57
to
bfe4cab
Compare
bfe4cab
to
ce967de
Compare
|
||
const basePath = path.resolve(nmPath, name); | ||
return applyExports(basePath, expansion); | ||
const [, name, expansion = ''] = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using array destructuring means it will break if Symbol.iterator is deleted off of Array.prototype. this one has a lot of places in the codebase to fix, tho, so it’s probably fine to skip for now.
PR-URL: #32351 Reviewed-By: Geoffrey Booth <webmaster@geoffreybooth.com> Reviewed-By: Bradley Farias <bradley.meck@gmail.com> Reviewed-By: Jan Krems <jan.krems@gmail.com> Reviewed-By: Myles Borins <myles.borins@gmail.com>
Landed in 534c204. |
PR-URL: #32351 Reviewed-By: Geoffrey Booth <webmaster@geoffreybooth.com> Reviewed-By: Bradley Farias <bradley.meck@gmail.com> Reviewed-By: Jan Krems <jan.krems@gmail.com> Reviewed-By: Myles Borins <myles.borins@gmail.com>
PR-URL: #32351 Reviewed-By: Geoffrey Booth <webmaster@geoffreybooth.com> Reviewed-By: Bradley Farias <bradley.meck@gmail.com> Reviewed-By: Jan Krems <jan.krems@gmail.com> Reviewed-By: Myles Borins <myles.borins@gmail.com>
PR-URL: nodejs#32351 Reviewed-By: Geoffrey Booth <webmaster@geoffreybooth.com> Reviewed-By: Bradley Farias <bradley.meck@gmail.com> Reviewed-By: Jan Krems <jan.krems@gmail.com> Reviewed-By: Myles Borins <myles.borins@gmail.com>
Node v13.13.0 introduced a change that is incompatible with `@babel/preset-env` versions `< 7.9.0`. See: nodejs/node#32351 nodejs/node#32852 babel/babel#11283 Bump our direct dependencies to `7.9.5` and manually cause additional bumps in `yarn.lock` that result in all versions of `@babel/preset-env` installed in the monorepo's `node_modules` trees being `>= 7.9.0`.
Node v13.13.0 introduced a change that is incompatible with `@babel/preset-env` versions `< 7.9.0`. See: * nodejs/node#32351 * nodejs/node#32852 * babel/babel#11283 Bump our direct dependencies to `7.9.5` and manually cause additional bumps in `yarn.lock` that result in all versions of `@babel/preset-env` installed in the monorepo's `node_modules` trees being `>= 7.9.0`.
Node v13.13.0 introduced a change that is incompatible with `@babel/preset-env` versions `< 7.9.0`. See: * nodejs/node#32351 * nodejs/node#32852 * babel/babel#11283 Bump our direct dependencies to `7.9.5` and manually cause additional bumps in `yarn.lock` that result in all versions of `@babel/preset-env` installed in the monorepo's `node_modules` trees being `>= 7.9.0`.
Due to the following breaking change: nodejs/node#32351 This fixes compatibility with Node.js: - v12.17.0+ - v13.13.0+ It probably also makes us compatible with Node.js v14.
This PR disables extension searching for the CommonJS exports implementation.
The catch with supporting extension searching for exports on CommonJS is having differences between the ESM and CJS implementations so this brings the gap back together on this, as it really should have been to begin with I think.
Please review @addaleax @jkrems when you can. Would be good to get this out soon as it is a breaking change under the experimental status.
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes