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

Integrating React 17 Remote Entry MFE with Host Application React 18

Open wsh92 opened this issue 1 year ago • 11 comments

Manifest file and remoteEntry.js files are loading in the host application but getting following runtime error while trying to load the child remote app using the router.

Element type is invalid. Received a promise that resolves to: undefined. Lazy element type must resolve to a class or function.
    at mountLazyComponent (webpack://host-app/./node_modules/react-dom/cjs/react-dom.development.js?:20037:9)
    at beginWork (webpack://host-app/./node_modules/react-dom/cjs/react-dom.development.js?:21627:16)
    at HTMLUnknownElement.callCallback (webpack://host-app/./node_modules/react-dom/cjs/react-dom.development.js?:4164:14)
    at Object.invokeGuardedCallbackDev (webpack://host-app/./node_modules/react-dom/cjs/react-dom.development.js?:4213:16)
    at invokeGuardedCallback (webpack://host-app/./node_modules/react-dom/cjs/react-dom.development.js?:4277:31)
    at beginWork$1 (webpack://host-app./node_modules/react-dom/cjs/react-dom.development.js?:27485:7)
    at performUnitOfWork (webpack://host-app/./node_modules/react-dom/cjs/react-dom.development.js?:26591:12)
    at workLoopConcurrent (webpack://host-app./node_modules/react-dom/cjs/react-dom.development.js?:26577:5)
    at renderRootConcurrent (webpack:/host-app./node_modules/react-dom/cjs/react-dom.development.js?:26539:7)
    at performConcurrentWorkOnRoot (webpack://host-app/./node_modules/react-dom/cjs/react-dom.development.js?:25772:38)

Host Application - React 18 Remote Child Application - React 17

I have used the following example to setup my project. https://github.com/module-federation/module-federation-examples/tree/master/different-react-versions-16-18

wsh92 avatar Aug 06 '24 20:08 wsh92

Need to check this project again, E2E was failing

ScriptedAlchemy avatar Aug 09 '24 00:08 ScriptedAlchemy

Any update on this?

I'm just now beginning to look into how to gradually migrate our apps to use React 19. They cannot all make the jump at the same time, so its important that any remotes that are on 19 will also work on 18 if the host is not yet upgraded (given that they don't rely on React 19 apis in that part of the code of course).

I managed to do this when going from 17 til 18, but now I'm struggling to get it working.

Shouldn't the remote accept the host React version, even when its lower than its own React version, as long as the MF config is accepting it?

I'm using this share config on both the host (which is on 18) and the remote (which is on 19).

  react: {
    requiredVersion: false,
    singleton: true,
    version: '^18.0.0 || ^19.0.0',
  },
  'react-dom': {
    requiredVersion: false,
    singleton: true,
    version: '^18.0.0 || ^19.0.0',
  },


einarq avatar Mar 28 '25 11:03 einarq

You should use framework bridges. This was the solution we chose instead of magic runtime plugin

ScriptedAlchemy avatar Mar 28 '25 21:03 ScriptedAlchemy

I dont know enough about MF internals to know what you mean by "magic runtime plugin".

When we went from 17 to 18 we were able to do this gradually, now this seems much harder for some reason.

We are still on the webpack plugin, but I can prioritize migrating to the new one if there is a better concept for it there, like the Bridge you mentioned. I'm assuming its this one? https://module-federation.io/practice/bridge/react-bridge

Are there any examples in the examples repo of how to use it?

einarq avatar Mar 29 '25 10:03 einarq

Check the core repo. It has bridge samples in the apps directory.

ScriptedAlchemy avatar Mar 31 '25 08:03 ScriptedAlchemy

I’ll take a look. Still a bit unclear why the behavior is different from before tho. Maybe now it’s more strict about always selecting the highest possible version?

einarq avatar Mar 31 '25 13:03 einarq

If a remote has React 18 installed, and this MF config:

    react: {
      requiredVersion: false,
      singleton: true,
      version: '^18 || ^19',
    },
    'react-dom': {
      requiredVersion: false,
      singleton: true,
      version: '^18 || ^19',
    },

And the host has React 19 installed, and this MF config:

    react: {
      requiredVersion: false,
      singleton: true,
      version: '19',
    },
    'react-dom': {
      requiredVersion: false,
      singleton: true,
      version: '19',
    },

Shouldn't that then work fine? Surely MF doesn't force us to upgrade all major versions exactly in tandem, across builds?

Or is there some other config needed?

einarq avatar Apr 01 '25 12:04 einarq

Seems there still might be issues with React 19 support with bridge/react?

https://github.com/module-federation/core/issues/3632

Also might not be related, but getting this error when trying to use createBridgeComponent to wrap my import:

const FederatedAppHeader = createBridgeComponent(()=> import('remote/AppHeader'));

Uncaught (in promise) ReferenceError: exports is not defined

einarq avatar Apr 01 '25 21:04 einarq

react-bridge seems to about routing mainly? Thats not really what I'm after.

einarq avatar Apr 02 '25 08:04 einarq

@ScriptedAlchemy Ok, I've tried the react-bridge package to the best of my ability.

I've gotten it working with React 18 in both host and remote, but when I try to switch to 19 in the host I still get the same error:

(default error boundary from the react-bridge example) Image

In the remote:

export default createBridgeComponent({
  rootComponent: AppHeader,
});

With this config for shared react:

    react: {
      singleton: true,
      strictVersion: true,
      requiredVersion: ">=18.0.0 <20.0.0"
    },
    'react-dom': {
      singleton: true,
      strictVersion: true,
      requiredVersion: ">=18.0.0 <20.0.0"
    },

In the consumer:

const FederatedAppHeader = createRemoteComponent({
  loader: () => loadRemote('remote/AppHeader'),
  fallback: FallbackErrorComp,
  loading: <FederatedAppHeaderLoader />,
});

Maybe these issues are related to this one that @danpeen seems to be working on? https://github.com/module-federation/core/issues/3632

Are there any examples of bridge-react working with 18 in the remote and 19 in the host?

einarq avatar Apr 02 '25 10:04 einarq

Seems like I will have to give this a try:

https://github.com/module-federation/module-federation-examples/tree/master/runtime-plugins/multiple-react-versions

einarq avatar Apr 03 '25 06:04 einarq