Bug report
TLDR: ModuleFederationPlugin won't expose a host's dependency to a remote if the dependency is an external.
To be honest, I'm not completely sure if this is a bug, a missing feature, or just a technical limitation of ModuleFederationPlugin... but i'd like to be able to do that 😄
NOTE: i'm using React as an example, but this behavior occurs regardless of what library i'm trying to externalize+share.
Context
Our module federation setup is pretty standard (except for the externals, apparently). We've got two apps:
(Host) (Remote)
SomePage ----> SomeWidget
Both of these are React apps, with React stuff shared via a typical ModuleFederationPlugin config:
shared: {
'react': { singleton: true },
'react-dom': { singleton: true }
}
This all works fine.
Now, we'd like SomePage to get React from a CDN link, so we tried externalizing it in SomePage via a typical
externals: {
'react': 'SomeGlobalVar',
'react-dom': 'AnotherGlobalVar',
}
the idea being that React would get wired up everywhere like this:
Script tag <script src="/our-cdn/react-stuff.js>
|
|
| webpack `external` (global var)
|
v
SomePage (Host app)
|
|
| ModuleFederationPlugin's `shared` exposes React
|
v
SomeWidget (Remote component)
What is the current behavior?
Unfortunately, despite SomePage successfully loading React from the CDN, this doesn't work.
The externalized React doesn't end up getting get shared between SomePage and SomeWidget, so we get two copies of React in one tree, which leads to a crash for the usual reasons. From my testing, it appears that despite the ModuleFederationPlugin config, SomePage never puts React into the shared WMF scope, so SomeWidget understandably loads its fallback. The versions are the same between both, and removing them doesn't change anything. I've also tried this with lodash, and that also results in two copies, one from the CDN, and one loaded via SomeWidget's fallback.
What is the expected behavior?
Dependencies should be shared between host and remote even if they're externals, as illustrated in the diagram a few paragraphs up.
Steps to reproduce
I've added some externals to basic-host-remote from module-federation-examples to reproduce this setup:
https://github.com/lubieowoce/module-federation-examples/tree/externals-test/basic-host-remote
the change is very small. You can run it via cd basic-host-remote && yarn && yarn start, then navigating to http://localhost:3001/. It'll flash and then turn blank, because when you when mix two copies of React in the same tree, it'll crash with "Error: Invalid hook call". This demonstrates that the library isn't actually being shared between the host and remote.
Other relevant information:
webpack version: 5.70.0
Node.js version: 14.17.6
Operating System: macOS 11.6, ARM
Bug report
TLDR:
ModuleFederationPluginwon't expose a host's dependency to a remote if the dependency is anexternal.To be honest, I'm not completely sure if this is a bug, a missing feature, or just a technical limitation of
ModuleFederationPlugin... but i'd like to be able to do that 😄Context
Our module federation setup is pretty standard (except for the externals, apparently). We've got two apps:
Both of these are React apps, with React stuff shared via a typical
ModuleFederationPluginconfig:This all works fine.
Now, we'd like
SomePageto get React from a CDN link, so we tried externalizing it inSomePagevia a typicalthe idea being that React would get wired up everywhere like this:
What is the current behavior?
Unfortunately, despite
SomePagesuccessfully loading React from the CDN, this doesn't work.The externalized React doesn't end up getting get shared between
SomePageandSomeWidget, so we get two copies of React in one tree, which leads to a crash for the usual reasons. From my testing, it appears that despite theModuleFederationPluginconfig,SomePagenever puts React into the shared WMF scope, soSomeWidgetunderstandably loads its fallback. The versions are the same between both, and removing them doesn't change anything. I've also tried this with lodash, and that also results in two copies, one from the CDN, and one loaded viaSomeWidget's fallback.What is the expected behavior?
Dependencies should be shared between host and remote even if they're externals, as illustrated in the diagram a few paragraphs up.
Steps to reproduce
I've added some externals to
basic-host-remotefrommodule-federation-examplesto reproduce this setup:https://github.com/lubieowoce/module-federation-examples/tree/externals-test/basic-host-remote
the change is very small. You can run it via
cd basic-host-remote && yarn && yarn start, then navigating to http://localhost:3001/. It'll flash and then turn blank, because when you when mix two copies of React in the same tree, it'll crash with "Error: Invalid hook call". This demonstrates that the library isn't actually being shared between the host and remote.Other relevant information:
webpack version:
5.70.0Node.js version:
14.17.6Operating System: macOS 11.6, ARM