-
-
Notifications
You must be signed in to change notification settings - Fork 399
Description
Clear and concise description of the problem
We're hoping to slowly migrate our MF-based codebase with about 20 projects in total from React 16 to React 19. We were planning on leveraging @module-federation/bridge-react to make it possible to run parts of our codebase with React 16 and other parts with React 19 in parallel. We've confirmed that what we're trying to do works with React 16 and React 18 but it looks like React 19 is not yet supported.
core/packages/bridge/bridge-react/src/provider/compat.ts
Lines 14 to 39 in 5ebc53f
| const isReact18 = ReactDOM.version.startsWith('18'); | |
| /** | |
| * Creates a root for a container element compatible with both React 16 and 18 | |
| */ | |
| export function createRoot( | |
| container: Element | DocumentFragment, | |
| options?: CreateRootOptions, | |
| ): Root { | |
| if (isReact18) { | |
| // For React 18, use the new createRoot API | |
| // @ts-ignore - Types will be available in React 18 | |
| return (ReactDOM as any).createRoot(container, options); | |
| } | |
| // For React 16/17, simulate the new root API using render/unmountComponentAtNode | |
| return { | |
| render(children: React.ReactNode) { | |
| // @ts-ignore - React 17's render method is deprecated but still functional | |
| ReactDOM.render(children, container); | |
| }, | |
| unmount() { | |
| ReactDOM.unmountComponentAtNode(container); | |
| }, | |
| }; | |
| } |
Suggested solution
The required change is that createRoot has to be imported from react-dom/client instead of from react-dom directly since v19. Since adding something like the following line of code will break for everything lower than React v19 and dynamic imports don't make much sense for a library, we're a bit stumped on how we could implement this.
import ReactDOM from 'react-dom';
import ReactDOM19 from 'react-dom/client'; // This will break on react-dom 16, 17, and 18Alternative
Somehow being able to pass our own createRoot function would shift the burden to the consumer. We haven't really investigated this approach so far but by making this possible it's up to the end-user to pass (possibly overwrite) the createRoot function. This way we could import it from the correct dependency depending on the context.
Additional context
The same probably applies to hydrateRoot but we're not using this in our project at the moment.
Validations
- Read the Contributing Guidelines.
- Check that there isn't already an issue that request the same feature to avoid creating a duplicate.