Solution
Use singleton: true for every shared library that uses React Context:
// webpack.config.js
// import package.json to get packages' versions
const deps = require('./package.json').dependencies
module.exports = {
// ...
plugins: [
new ModuleFederationPlugin({
name: 'main',
filename: 'remoteEntry.js',
remotes: {
// your remotes config
},
shared: {
react: {
singleton: true,
version: deps['react']
},
'react-dom': {
singleton: true,
version: deps['react-dom']
},
'react-router-dom': {
singleton: true,
version: deps['react-router-dom']
},
'react-redux': {
singleton: true,
version: deps['react-router-dom']
}
},
}),
// other plugins
]
Use this setting in all of your federated modules.
Solution for custom context
If your app has a custom context there is a similar solution. Take a look at the example in the module-federation-examples monorepo.
Explanation
Such errors arise when you have two copies of React Context in your apps. Redux, React Router, Material UI, and other libraries use Context API inside their providers. So when you have, for example, Redux imported in both of your WP5 federated modules, every module (or app) has its own copy of Redux, even if it is the same version of it.
Workaround
If for some reason you can't have singleton module, there is a workaround: pass your Redux store to the remote app's props and wrap it with another Provider like so:
// in your remote app:
const RemoteAppWrapper = ({ store }) => {
return (
<Provider store={store}>
<RemoteApp />
</Provider>
);
};
// and then in your host app:
<RemoteApp store={store} />
There is an app with a complete example in the official module-federation-examples monorepo where this approach is used: https://github.com/module-federation/module-federation-examples/tree/master/redux-reducer-injection