Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
fastrackavish opened this issue Sep 13, 2023 · 5 comments

Comments

@fastrackavish
Copy link

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
Copy link
Member

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
Copy link
Member

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

@fastrackavish
Copy link
Author

fastrackavish commented Sep 13, 2023

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

  • App1 uses react@16.14.0 But this version of react supports react hooks. It says enabling this component would break the app. However, Hooks were introduced in react@16.8.0. In fact, I tried enabling this component and it loaded fine (without adapter)

  • If I console log React.version in all the useEffects app1 components show react@16.14.0; app2 components (opened in :3001) shows react@18.2.0. So is it bundling both react versions ?

  • Tried to switch to older version (react@16.0.0) react for app1. Both ModernComponent and HookComponent fails to load. If I understand the expectation of this example correctly, the one with ReactAdapterConsumer should work

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

@ScriptedAlchemy
Copy link
Member

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
Copy link

fcano-ut commented Dec 28, 2023

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: webpack/webpack#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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants