-
Notifications
You must be signed in to change notification settings - Fork 188
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: Resolving to the wrong package with exports
and nested same package but different versions
#399
Comments
Sounds like a bug, we need to fix it, thank you for issue, if you have time - PR welcome |
For both test case (ESM array fallback and this one), it seems like we just need to abort the resolution in the exports field plugin. But I tried for like an hour but still can't figure out the correct combination of enhanced-resolve/lib/ExportsFieldPlugin.js Lines 149 to 162 in 58464fc
Maybe it's easier for you to add the relevant code :-( As for test cases, array fallback: enhanced-resolve/test/exportsField.test.js Lines 2374 to 2447 in 58464fc
A new test is needed for this issue. |
@Boshen We just need to do this https://github.com/webpack/enhanced-resolve/blob/main/lib/ExportsFieldPlugin.js#L74, maybe adding link why it happens will be great, so developers will less ask why it was changed |
Repro and summary - https://github.com/Boshen/test-nested-exports
Pasting the contents here:
Resolving to the incorrect package with webpack (enhanced-resolve)
tldr;
In a monorepo, ESM saves us from resolving to the wrong package when package exports is configured,
webpack (enhanced-resolve) fails to do so.
Scenario
In a monorepo, there are two versions of the same
package
installed in the root (node_modules/package
)and in a workspace directory (
packages/app/node_modules/package
).node_modules/package
The root
node_modules
, withpackage.json
andindex.js
:node_modules/package/src/index.js
node_modules/package/package.json
packages/app/node_modules/package
And in a app
node_modules
, withpackage.json
andmain.js
packages/app/node_modules/package/src/main.js
packages/app/node_modules/package/package.json
Notice this one does not contain index.js.
Behavior
resolve('/path/to/packages/app', 'package/src/index.js')
enhanced-resolve
The incorrect behavior that comes from enhanced-resolve:
When resolving the specifier
package/src/index.js
inside./packages/app
,it first resolves the specifier to
./packages/app/node_modules/package/src/index.js
and misses the file.It then continues searching and finds
./node_modules/package/src/index.js
.node.js
The correct behavior from Node is:
Aborts when
./packages/app/node_modules/package/src/index.js
is not found.Explanation
Follow the spec (https://nodejs.org/api/modules.html#all-together)
The route
LOAD_NODE_MODULES
->LOAD_PACKAGE_EXPORTS
->RESOLVE_ESM_MATCH
->THROW "not found"
indicates that resolution should stop when a path is not found package#exports.
As a bonus point, the scenario will resolve to the root
./node_modules/package/src/index.js
ifpackage#exports
are removed from both
package.json
s.Replicate
To replicate the behavior, run
bash test.sh
and see the following output:esbuild
esbuild conforms to the spec.
Add
import 'package/src/index.js'
to./packages/app/index.js
Remove both
package#exports
and notice it resolves to the root package:The text was updated successfully, but these errors were encountered: