module-federation / module-federation-examples

Implementation examples of module federation , by the creators of module federation
https://module-federation.io/
MIT License
5.4k stars 1.7k forks source link

Question: Can we have shell application using react 18 and remotes of different versions 16, 17, 18 #3154

Open fastrackavish opened 9 months ago

fastrackavish commented 9 months ago

Hi @ScriptedAlchemy

I see below example, but not quite sure if this will work in case of shell suing modern version of react vs the remote. https://github.com/module-federation/module-federation-examples/tree/master/different-react-versions-16-18.

Appreciate if you add some blogpost or documentation explaining the concept in detail.

ScriptedAlchemy commented 9 months ago

Yeah you can do that. You'd need some adapter patterns like in the examples here. As there are a few. You could also not do it jsx style like I do. And instead just import a entrypoint-like app that mounts onto a ref or DOM node.

Maybe in the future I'll implement something for this or into modernjs as a easy pattern

ScriptedAlchemy commented 9 months ago

I can make a blog about the concept at least in short term

fastrackavish commented 9 months ago

@ScriptedAlchemy @brunos3d First of all, thanks for this awesome feature!

I was running these applications again and thought to update this question to give more context:

Appreciate if you can cover these details somewhere Thanks in Advance!

ScriptedAlchemy commented 9 months ago

probbably my robot updated it to latest v16. It should work if they are both in different share scopes. You probabbly need to do the same to react as done to react-dom

'react-dom': { import: 'react-dom', // the "react" package will be used a provided and fallback module shareKey: 'react-dom', // under this name the shared module will be placed in the share scope shareScope: 'legacy', // share scope with this name will be used singleton: true, // only a single version of the shared module is allowed },

fcano-ut commented 6 months ago

Has anyone figured out what are the settings that allow you to load multiple versions of React with Dynamic Remote Containers?

I was following this example: https://github.com/module-federation/module-federation-examples/tree/master/different-react-versions-16-18; but I couldn't make it work, since it is relying on registering the different react versions as singletons, under different shareScopes. I think this doesn't work with dynamic federation due to this bug: https://github.com/webpack/webpack/issues/13834

As suggested in the other issue I mentioned, I currently have these settings:

react: {
  eager: type === 'host', // eager for host, not eager for micro-frontends
  requiredVersion: dependencies.react,
},
'react-dom': {
  eager: type === 'host',
  requiredVersion: dependencies['react-dom'],
},
// customize the share key of
// any dependency that has react as peerDependency
// workaround to: https://github.com/webpack/webpack/issues/13834
'react-lib': {
  eager: type === 'host',
  requiredVersion: dependencies['react-lib'],
  shareKey: `react-lib for react@17`,
},

However, this is failing with dynamic federation about 30% of the times. It fails without errors, the bug is due to a promise that is never solved:

    if (!(this._config.remoteName in window)) {
      const fetchedContainer: any = await this.fetchRemote();
      await fetchedContainer.init(__webpack_share_scopes__['default']);
    }

    const container: any = window[this._config.remoteName as any];
    const factory = await container.get(moduleName); // ❌ Sometimes this promise hangs forever
    const Module = factory();

As suggested in this issue, I also tried these settings, but it's failing in the same place for the same reason:

react: {
  eager: type === 'host', // eager for host, not eager for micro-frontends
  requiredVersion: dependencies.react,
  shareKey: 'react@17', // or "react@18"
  shareScope: 'react@17',
  singleton: true,
},
'react-dom': {
  eager: type === 'host',
  requiredVersion: dependencies['react-dom'],
  shareKey: 'react-dom@17',
  shareScope: 'react@17',
  singleton: true,
},
// customize the share key of
// any dependency that has react as peerDependency
// workaround to: https://github.com/webpack/webpack/issues/13834
'react-lib': {
  eager: type === 'host',
  requiredVersion: dependencies['react-lib'],
  shareKey: `react-lib for react@17`,
},

I'm confused, since the only example of two react versions that seems to be working relies on multiple share scopes, but there is an issue with that feature and dynamic remote containers.

If someone has any information, I'd be super grateful to hear it. I've spent three days trying different stuff to try and figure this out, but I haven't discovered something that works reliably yet.

kiyass commented 5 days ago

Yeah you can do that. You'd need some adapter patterns like in the examples here. As there are a few. You could also not do it jsx style like I do. And instead just import a entrypoint-like app that mounts onto a ref or DOM node.

Maybe in the future I'll implement something for this or into modernjs as a easy pattern

Hi @ScriptedAlchemy, I use the adapter pattern, but there is a problem that bothers me. For example, I have two applications with different react versions, but they both use dependencies that depend on react and must be single instances (such as styled-components). It seems to work normally, except that a warning will appear in the console, but is there a potential problem? Any help on this will be really appreciated.