diff --git a/.changeset/kind-eagles-dream.md b/.changeset/kind-eagles-dream.md new file mode 100644 index 00000000000..4baa5db9e93 --- /dev/null +++ b/.changeset/kind-eagles-dream.md @@ -0,0 +1,5 @@ +--- +'@module-federation/bridge-react': minor +--- + +feat(bridge-react): Added support for custom `createRoot` on `createBridgeComponent` diff --git a/packages/bridge/bridge-react/__tests__/bridge.spec.tsx b/packages/bridge/bridge-react/__tests__/bridge.spec.tsx index 786a33432ab..b09fbdf6314 100644 --- a/packages/bridge/bridge-react/__tests__/bridge.spec.tsx +++ b/packages/bridge/bridge-react/__tests__/bridge.spec.tsx @@ -102,4 +102,36 @@ describe('bridge', () => { expect(getHtml(container)).toMatch('hello world'); expect(ref.current).not.toBeNull(); }); + + it('createRemoteComponent with custom createRoot prop', async () => { + const renderMock = vi.fn(); + + function Component({ props }: { props?: Record }) { + return
life cycle render {props?.msg}
; + } + const BridgeComponent = createBridgeComponent({ + rootComponent: Component, + createRoot: () => { + return { + render: renderMock, + unmount: vi.fn(), + }; + }, + }); + const RemoteComponent = createRemoteComponent({ + loader: async () => { + return { + default: BridgeComponent, + }; + }, + fallback: () =>
, + loading:
loading
, + }); + + const { container } = render(); + expect(getHtml(container)).toMatch('loading'); + + await sleep(200); + expect(renderMock).toHaveBeenCalledTimes(1); + }); }); diff --git a/packages/bridge/bridge-react/src/provider/create.tsx b/packages/bridge/bridge-react/src/provider/create.tsx index 64e4592e774..eff9be4167f 100644 --- a/packages/bridge/bridge-react/src/provider/create.tsx +++ b/packages/bridge/bridge-react/src/provider/create.tsx @@ -8,7 +8,7 @@ import { ErrorBoundary } from 'react-error-boundary'; import { RouterContext } from './context'; import { LoggerInstance } from '../utils'; import { federationRuntime } from './plugin'; -import { createRoot } from './compat'; +import { createRoot as defaultCreateRoot } from './compat'; type RenderParams = RenderFnParams & { [key: string]: unknown; @@ -17,7 +17,7 @@ type DestroyParams = { moduleName: string; dom: HTMLElement; }; -type RootType = HTMLElement | ReturnType; +type RootType = HTMLElement | ReturnType; export type ProviderFnParams = { rootComponent: React.ComponentType; @@ -25,9 +25,16 @@ export type ProviderFnParams = { App: React.ReactElement, id?: HTMLElement | string, ) => RootType | Promise; + createRoot?: ( + container: Parameters[0], + options?: Parameters[1], + ) => ReturnType; }; -export function createBridgeComponent(bridgeInfo: ProviderFnParams) { +export function createBridgeComponent({ + createRoot = defaultCreateRoot, + ...bridgeInfo +}: ProviderFnParams) { return () => { const rootMap = new Map(); const instance = federationRuntime.instance;