webpack: Resolve module (mjs) incorrectly when using Module Federation Plugin
Bug report
What is the current behavior?
When using swr/infinite
with swr>1.1.2
dependency and sharing it with Module Federation (SharePlugin)
new webpack.container.ModuleFederationPlugin({
shared: ['swr'],
}),
We encountered this error:
If the current behavior is a bug, please provide the steps to reproduce.
I created this repo that reproduces the issue: https://github.com/tzachbon/swr-mf-error
All you have to do is to use SWR >= 1.2.0 and add it to the shared array in the Module Federation Plugin. In the change log here: https://github.com/vercel/swr/compare/1.1.2...1.2.0 I found a few things that might be the reason.
In my code, I try to import swr/infinite
, which now has exports field in its package json:
"exports": "./dist/index.mjs",
In the swr
package json, the exports field now has a filename that ends with mjs
extension:
"./infinite": {
"import": "./infinite/dist/index.mjs",
"module": "./infinite/dist/index.esm.js",
"require": "./infinite/dist/index.js",
"types": "./infinite/dist/infinite/index.d.ts"
},
When I manually changed the filename to .js
it worked.
What is the expected behavior?
To resolve it like .js
Other relevant information: webpack version: 5.74.0 Node.js version: 16.15.0 Operating System: MacBook Pro (16-inch, 2021) Additional tools: swr: 1.3.0
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 8
- Comments: 22 (9 by maintainers)
You can skip this issue by also sharing any submodule of swr changing this:
to this
Yeah, looks like a bug, someone wants to send a PR?
I’ve been able to figure out that the issue is in the detection of exportsType of a shared module when passing through from another shared module, it comes back as
default-with-named
instead ofdynamic
, which then means thatinteropDefaultAccessUsed
never gets set to true, andcompatGetDefaultExport
never gets added to the build. What I can’t figure out is why it breaks only when coming in through another shared module. If imported as a first-level shared module, this doesn’t happen, the file is correctly typed as dynamic.Just gonna add a few keywords here for google, because it took me WEEKS to find this issue:
graphql-tag
default export importTypeError: graphql_tag__WEBPACK_IMPORTED_MODULE_0__ is not a function
Thanks! It does work but isn’t it a workaround for an existing bug with the resolution?
Add some addition infomration: The esm assets of swr (
"import"
condition from"exports"
field in package.json) is picked up by webpack correctly, but it seems still act like commonjs module with module federation plugin.If I removed the
import
export condition then everything works well. But it’s still picking up the"module"
condition from"exports"
, which uses exact same esm format like mjs assets does. I think webpack should treat the"module"
and"import"
condition similarly?I’m certainly no expert in how everything weaves together but if this is a question of resolution and it appears to be triggered by shared according to the bug replication by @hangboss1761 I would say a good starting place is here (The link will open the GitHub dev editor)
Relative path in code:
webpack/webpack/lib/sharing/ProvideSharedPlugin.js
I don’t have time to take a deep dive at the moment but hopefully, that helps @tzachbon
Later I can take a look, ran into this I believe after adding the
exports
field to my package, and the ESM was resolved but then it appeared to not seeexports
I’ll blame that piece on my resolution. Upon inspection, the exports object just didn’t exist in the generated Module, once again probably my configuration but if that helps there you go.However, I resolved it by setting it back to my UMD build via an explicit path. The trailing slash did not work with my scoped package.
If the aforementioned behavior is connected then, it looks like the path came from the ConsumeSharedPlugin.
@tzachbon Correct, this issue still needs to be addressed.
@keropodium Thanks! I checked, it resolved the issue! cc @tzachbon