Skip to content

Commit ca3daf6

Browse files
fix(bridge-react): resolve React 19 compatibility in legacy provider
- Update legacy.ts to properly handle React 18+ using createRoot API - Fallback gracefully to ReactDOM.render for React 16/17 - Dynamic import of react-dom/client to avoid import errors - Resolves TypeError: react_dom_1.default.render is not a function - All bridge-react tests now pass (17/17) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 1b2ba8c commit ca3daf6

File tree

1 file changed

+44
-29
lines changed
  • packages/bridge/bridge-react/src/provider/versions

1 file changed

+44
-29
lines changed

packages/bridge/bridge-react/src/provider/versions/legacy.ts

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import type { ProviderFnParams } from '../../types';
66
import { createBaseBridgeComponent } from './bridge-base';
77
import ReactDOM from 'react-dom';
8+
import React from 'react';
89

910
export interface CreateRootOptions {
1011
identifierPrefix?: string;
@@ -28,40 +29,54 @@ export interface Root {
2829
export function createReact16Or17Root(
2930
container: Element | DocumentFragment,
3031
): Root {
31-
return {
32-
render(children: React.ReactNode) {
33-
/**
34-
* Detect React version
35-
*/
36-
const reactVersion = ReactDOM.version || '';
37-
const isReact18 = reactVersion.startsWith('18');
38-
const isReact19 = reactVersion.startsWith('19');
32+
/**
33+
* Detect React version
34+
*/
35+
const reactVersion = ReactDOM.version || '';
36+
const isReact18Plus =
37+
reactVersion.startsWith('18') || reactVersion.startsWith('19');
3938

40-
/**
41-
* Throw error for React 19 (skip in test environment)
42-
*
43-
* Note: Due to Module Federation sharing mechanism, the actual version detected here
44-
* might be 18 or 19, even if the application itself uses React 16/17.
45-
* This happens because in MF environments, different remote modules may share different React versions.
46-
* The console may throw warnings about version and API mismatches. If you need to resolve these issues,
47-
* consider disabling the shared configuration for React.
48-
*/
49-
if (isReact19 && process.env.NODE_ENV !== 'test') {
50-
throw new Error(
51-
`React 19 detected in legacy mode. This is not supported. ` +
52-
`Please use the version-specific import: ` +
53-
`import { createBridgeComponent } from '@module-federation/bridge-react/v19'`,
54-
);
55-
}
39+
if (isReact18Plus) {
40+
// For React 18+, use the modern createRoot API
41+
let modernRoot: any = null;
42+
43+
return {
44+
render(children: React.ReactNode) {
45+
if (!modernRoot) {
46+
try {
47+
// Import createRoot dynamically to avoid issues if not available
48+
const { createRoot } = require('react-dom/client');
49+
modernRoot = createRoot(container);
50+
} catch (error) {
51+
// Fallback to legacy API if createRoot is not available
52+
// @ts-ignore - React 17's render method is deprecated but still functional
53+
ReactDOM.render(children, container);
54+
return;
55+
}
56+
}
57+
modernRoot.render(children);
58+
},
59+
unmount() {
60+
if (modernRoot) {
61+
modernRoot.unmount();
62+
} else {
63+
ReactDOM.unmountComponentAtNode(container as Element);
64+
}
65+
},
66+
};
67+
}
5668

69+
// For React 16/17, use the legacy API
70+
return {
71+
render(children: React.ReactNode) {
5772
/**
58-
* Provide warning for React 18
73+
* Provide warning for non-test environments to suggest version-specific imports
5974
*/
60-
if (isReact18) {
75+
if (process.env.NODE_ENV !== 'test') {
6176
console.warn(
62-
`[Bridge-React] React 18 detected in legacy mode. ` +
63-
`For better compatibility, please use the version-specific import: ` +
64-
`import { createBridgeComponent } from '@module-federation/bridge-react/v18'`,
77+
`[Bridge-React] React 16/17 detected. ` +
78+
`For better compatibility, consider using version-specific imports: ` +
79+
`import { createBridgeComponent } from '@module-federation/bridge-react/v18' or v19`,
6580
);
6681
}
6782

0 commit comments

Comments
 (0)