Skip to content

Commit 80912a6

Browse files
Stoica, Radu (External)radualex
Stoica, Radu (External)
authored andcommitted
feat(bridge-react): add support for React v19
1 parent cbd5b7e commit 80912a6

File tree

3 files changed

+47
-3
lines changed

3 files changed

+47
-3
lines changed

.changeset/kind-eagles-dream.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@module-federation/bridge-react': minor
3+
---
4+
5+
feat(bridge-react): Added support for custom `createRoot` on `createBridgeComponent`

packages/bridge/bridge-react/__tests__/bridge.spec.tsx

+32
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,36 @@ describe('bridge', () => {
102102
expect(getHtml(container)).toMatch('hello world');
103103
expect(ref.current).not.toBeNull();
104104
});
105+
106+
it.only('createRemoteComponent with custom createRoot prop', async () => {
107+
const renderMock = vi.fn();
108+
109+
function Component({ props }: { props?: Record<string, any> }) {
110+
return <div>life cycle render {props?.msg}</div>;
111+
}
112+
const BridgeComponent = createBridgeComponent({
113+
rootComponent: Component,
114+
createRoot: () => {
115+
return {
116+
render: renderMock,
117+
unmount: vi.fn(),
118+
};
119+
},
120+
});
121+
const RemoteComponent = createRemoteComponent({
122+
loader: async () => {
123+
return {
124+
default: BridgeComponent,
125+
};
126+
},
127+
fallback: () => <div></div>,
128+
loading: <div>loading</div>,
129+
});
130+
131+
const { container } = render(<RemoteComponent />);
132+
expect(getHtml(container)).toMatch('loading');
133+
134+
await sleep(200);
135+
expect(renderMock).toHaveBeenCalledTimes(1);
136+
});
105137
});

packages/bridge/bridge-react/src/provider/create.tsx

+10-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { ErrorBoundary } from 'react-error-boundary';
88
import { RouterContext } from './context';
99
import { LoggerInstance } from '../utils';
1010
import { federationRuntime } from './plugin';
11-
import { createRoot } from './compat';
11+
import { createRoot as defaultCreateRoot } from './compat';
1212

1313
type RenderParams = RenderFnParams & {
1414
[key: string]: unknown;
@@ -17,17 +17,24 @@ type DestroyParams = {
1717
moduleName: string;
1818
dom: HTMLElement;
1919
};
20-
type RootType = HTMLElement | ReturnType<typeof createRoot>;
20+
type RootType = HTMLElement | ReturnType<typeof defaultCreateRoot>;
2121

2222
export type ProviderFnParams<T> = {
2323
rootComponent: React.ComponentType<T>;
2424
render?: (
2525
App: React.ReactElement,
2626
id?: HTMLElement | string,
2727
) => RootType | Promise<RootType>;
28+
createRoot?: (
29+
container: Parameters<typeof defaultCreateRoot>[0],
30+
options?: Parameters<typeof defaultCreateRoot>[1],
31+
) => ReturnType<typeof defaultCreateRoot>;
2832
};
2933

30-
export function createBridgeComponent<T>(bridgeInfo: ProviderFnParams<T>) {
34+
export function createBridgeComponent<T>({
35+
createRoot = defaultCreateRoot,
36+
...bridgeInfo
37+
}: ProviderFnParams<T>) {
3138
return () => {
3239
const rootMap = new Map<any, RootType>();
3340
const instance = federationRuntime.instance;

0 commit comments

Comments
 (0)