-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
esm: modify resolution order for specifier flag #29974
Conversation
This comment has been minimized.
This comment has been minimized.
src/module_wrap.cc
Outdated
".js", | ||
".json", | ||
".node" | ||
".node", | ||
".mjs", |
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.
I don't think we check these in CJS. There is some risk that this leads to two valid resolutions, especially when combined with require hooks:
foo.jsx
orfoo.ts
: Found by CJS.foo.mjs
orfoo.cjs
: Found by ESM.
Should we remove them? I think I'm fine keeping them since require hooks aren't "native".
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.
Don't think we should remove them personally, but maybe I'm not entirely understanding the case here
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.
Should we remove them?
This brings up a good point about whether we should expect the resolution outcomes for --es-module-specifier-resolution=node
and require.resolve()
to be identical.
The rollup-plugin-node-resolve
package refers to the current order of extension resolution as node
(it's in the name).
Maybe a new mode of legacy
(--es-module-specifier-resolution=legacy
) should be introduced to function exactly like require.resolve()
. The ESM package refers to it as legacy internally.
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.
Erm, couldn't we choose to pull the extension list and order from require.extensions
directly, for compat? Even if it's the pre-user-code-modified version (therefore didn't support custom extensions), it'd at least guarantee they're in sync.
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.
What will be the consequences of removing?
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.
So i've gone ahead and left .mjs
extension and removed the .cjs
extension. Thought process here is that the cjs
loader doesn't recognize that extension, so lets keep things consistent. They might be a bit weird... but at least they are primarily the same.
The CJS loader will currently fail on requiring a .mjs extension, not pass it through... so I think the behavior is equivalent.
This will pass through anything that doesn't match to the CJS loader, which in turn will get anything from require.extensions.
I believe this covers all the concerns raised in this thread
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.
I think removing the .cjs
extension is a good start as I personally believe that the node
resolution mode should function exactly as described in the All Together... algorithm.
In defense of modifying the behavior of this flag, the blog post that announced this flag made clear that its behavior would change once the ES module context went live unflagged, so removing or changing extension precedence hopefully won't come as too much of a shock to most.
As long as the --loader
flag will continue to be available, I don't think anyone can justify being too upset about changes like this since the option of supplying one's own resolution algorithm is still on the table.
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.
Makes sense.
I just pushed a super naive solution to TL;DR since we currently error if file extension don't match anything in the map I'm alternatively forwarding any unmatched extensions to the .cjs loader to be resolved. This will mean that any ambiguous (to esm loader) file extension will be forwarded and eventually default to CJS. We could potentially find a more elegant solution that doesn't involve a CJS default, but it is going to require FAR more juggling since the extensions all exist in JS land and the extension resolution for the ESM loader is in C++. If folks are open to this solution I'll write some tests and docs.
edit 2: guy's branch still has the bug... will work on fixing it there |
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.
Re-approved with latest changes FWIW.
This comment has been minimized.
This comment has been minimized.
Currently `--es-module-specifier-resolution=node` has an alternative resolution order than the default in common.js, this causes inconsistencies. As discussed in @nodejs/modules we want to preserve resolution order between implementations.
9467d7f
to
935e46c
Compare
Currently `--es-module-specifier-resolution=node` has an alternative resolution order than the default in common.js, this causes inconsistencies. As discussed in @nodejs/modules we want to preserve resolution order between implementations. PR-URL: #29974 Reviewed-By: Jan Krems <jan.krems@gmail.com> Reviewed-By: Guy Bedford <guybedford@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Landed in 1e5ed9a. |
Currently `--es-module-specifier-resolution=node` has an alternative resolution order than the default in common.js, this causes inconsistencies. As discussed in @nodejs/modules we want to preserve resolution order between implementations. PR-URL: #29974 Reviewed-By: Jan Krems <jan.krems@gmail.com> Reviewed-By: Guy Bedford <guybedford@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Currently `--es-module-specifier-resolution=node` has an alternative resolution order than the default in common.js, this causes inconsistencies. As discussed in @nodejs/modules we want to preserve resolution order between implementations. PR-URL: #29974 Reviewed-By: Jan Krems <jan.krems@gmail.com> Reviewed-By: Guy Bedford <guybedford@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Currently `--es-module-specifier-resolution=node` has an alternative resolution order than the default in common.js, this causes inconsistencies. As discussed in @nodejs/modules we want to preserve resolution order between implementations. PR-URL: #29974 Reviewed-By: Jan Krems <jan.krems@gmail.com> Reviewed-By: Guy Bedford <guybedford@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Currently `--es-module-specifier-resolution=node` has an alternative resolution order than the default in common.js, this causes inconsistencies. As discussed in @nodejs/modules we want to preserve resolution order between implementations. PR-URL: #29974 Reviewed-By: Jan Krems <jan.krems@gmail.com> Reviewed-By: Guy Bedford <guybedford@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
I think this change might be causing this issue: #30520 |
Currently
--es-module-specifier-resolution=node
has an alternativeresolution order than the default in common.js, this causes inconsistencies.
As discussed in @nodejs/modules we want to preserve resolution order between
implementations.