Description
Describe the bug
Issue: Module Federation shareScopes Not Working as Expected
Description
We are currently migrating our large application to Module Federation and need to utilize the shareScopes
feature because we cannot upgrade all microfrontends to new React versions simultaneously. Our approach is to have a shareScope
for each React version currently in use and include all additional dependencies in the same React scope.
However, we are encountering an issue where sharing a scope that is not the "default" is not working. We can see the different scopes in the window.__FEDERATION
variable, but two microfrontends using the react19
scope are not sharing their dependencies correctly and end up loading their own React instances.
Current Setup
We have a main app that integrates all remotes. The remotes define their shared dependencies via the rsbuild
plugin. The main app registers the remotes at runtime with the following code:
import { registerPlugins, registerRemotes, init } from '@module-federation/enhanced/runtime';
export const registerMicroFrontends = async () => {
try {
const microfrontendUrls = await getAllMicrofrontends();
const remotes = Object.entries(microfrontendUrls).map(([key, value]) => ({
name: key,
entry: `${value.baseUrl}/mf-manifest.json`,
}));
registerRemotes(remotes);
registerPlugins([errorHandlingPlugin()]);
} catch (e) {
logger.warn('Failed to register (some) microfrontends.', e);
}
};
The main app defines its shared dependencies at build time using the following configuration:
pluginModuleFederation({
name: 'appaxolotl',
dts: false,
shared: [
{
react: { singleton: true, requiredVersion: packageJson.dependencies.react },
'react-dom': { singleton: true, requiredVersion: packageJson.dependencies['react-dom'] },
},
],
});
For microfrontends that use React 19, we use the following configuration and attempt to leverage the shareScope
feature:
pluginModuleFederation({
name: 'portfoliopenguin',
dts: false,
runtimePlugins: [],
exposes: {
'./bootstrap': './src/bootstrap.tsx',
},
shared: [
{
react: { singleton: true, requiredVersion: packageJson.dependencies.react, shareScope: 'react19' },
'react-dom': { singleton: true, requiredVersion: packageJson.dependencies['react-dom'], shareScope: 'react19' },
'@mui/material': { singleton: false, requiredVersion: packageJson.dependencies['@mui/material'], shareScope: 'react19' },
},
],
});
After the microfrondends got registered by the main app they will be loaded via loadRemote
when they are actually needed. The "filterfalcon" gets loaded right after the remotes got registered and the second microfrontend is loaded when its route gets called.
Observed Behavior
At runtime, both React 19 microfrontends have the react19
shareScope, but they do not share dependencies correctly. Here is a snapshot of the window__FEDERATION__SHARE__
.
And here the broken part:
Here we can see that both have the same scope but still both load their own dependencies.
Expected Behavior
Microfrontends using the same react19
scope should share the React instance instead of loading separate copies.
Questions
- Are we missing any additional runtime configuration required for shareScopes?
Any guidance or insights would be greatly appreciated!
Used Package Manager
pnpm
System Info
- Module Federation Version: 0.8.9
- React Versions: 18.3.1, 19.0.0
- Build Tool: `rsbuild`
Validations
- Read the docs.
- Read the common issues list.
- Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- Make sure this is a Module federation issue and not a framework-specific issue.
- The provided reproduction is a minimal reproducible example of the bug.
Activity