module-federation-examples icon indicating copy to clipboard operation
module-federation-examples copied to clipboard

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

Open fastrackavish opened this issue 2 years ago • 9 comments

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.

fastrackavish avatar Sep 13 '23 01:09 fastrackavish

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 avatar Sep 13 '23 09:09 ScriptedAlchemy

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

ScriptedAlchemy avatar Sep 13 '23 09:09 ScriptedAlchemy

@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!

fastrackavish avatar Sep 13 '23 21:09 fastrackavish

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 },

ScriptedAlchemy avatar Sep 14 '23 22:09 ScriptedAlchemy

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.

fcano-ut avatar Dec 28 '23 13:12 fcano-ut

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.

kiyass avatar Jun 26 '24 13:06 kiyass