@module-federation/bridge-react 0.0.0-docs-remove-invalid-lark-link-20251205062649

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/CHANGELOG.md +728 -0
  2. package/LICENSE +21 -0
  3. package/README.md +131 -0
  4. package/__tests__/bridge.spec.tsx +160 -0
  5. package/__tests__/createLazyComponent.spec.tsx +209 -0
  6. package/__tests__/prefetch.spec.ts +156 -0
  7. package/__tests__/router.spec.tsx +82 -0
  8. package/__tests__/setupTests.ts +8 -0
  9. package/__tests__/util.ts +36 -0
  10. package/dist/base.cjs.js +29 -0
  11. package/dist/base.d.ts +311 -0
  12. package/dist/base.es.js +30 -0
  13. package/dist/bridge-base-CPSTBjEp.mjs +211 -0
  14. package/dist/bridge-base-RStDxH71.js +226 -0
  15. package/dist/createHelpers-B_L612IN.js +190 -0
  16. package/dist/createHelpers-Ui5pt7je.mjs +191 -0
  17. package/dist/data-fetch-server-middleware.cjs.js +163 -0
  18. package/dist/data-fetch-server-middleware.d.ts +15 -0
  19. package/dist/data-fetch-server-middleware.es.js +164 -0
  20. package/dist/data-fetch-utils.cjs.js +24 -0
  21. package/dist/data-fetch-utils.d.ts +81 -0
  22. package/dist/data-fetch-utils.es.js +26 -0
  23. package/dist/index-DRSBaSu3.js +45 -0
  24. package/dist/index-DyQNwY2M.mjs +46 -0
  25. package/dist/index.cjs.js +125 -0
  26. package/dist/index.d.ts +299 -0
  27. package/dist/index.es.js +109 -0
  28. package/dist/index.esm-BWaKho-8.js +491 -0
  29. package/dist/index.esm-CPwSeCvw.mjs +492 -0
  30. package/dist/lazy-load-component-plugin-CSRkMmKF.js +521 -0
  31. package/dist/lazy-load-component-plugin-DXqhuywC.mjs +522 -0
  32. package/dist/lazy-load-component-plugin.cjs.js +6 -0
  33. package/dist/lazy-load-component-plugin.d.ts +16 -0
  34. package/dist/lazy-load-component-plugin.es.js +6 -0
  35. package/dist/lazy-utils.cjs.js +24 -0
  36. package/dist/lazy-utils.d.ts +149 -0
  37. package/dist/lazy-utils.es.js +24 -0
  38. package/dist/plugin.cjs.js +14 -0
  39. package/dist/plugin.d.ts +22 -0
  40. package/dist/plugin.es.js +14 -0
  41. package/dist/prefetch-A3QkU5oZ.js +1272 -0
  42. package/dist/prefetch-zMJL79zx.mjs +1273 -0
  43. package/dist/router-v5.cjs.js +55 -0
  44. package/dist/router-v5.d.ts +18 -0
  45. package/dist/router-v5.es.js +32 -0
  46. package/dist/router-v6.cjs.js +84 -0
  47. package/dist/router-v6.d.ts +20 -0
  48. package/dist/router-v6.es.js +61 -0
  49. package/dist/router-v7.cjs.js +83 -0
  50. package/dist/router-v7.d.ts +20 -0
  51. package/dist/router-v7.es.js +61 -0
  52. package/dist/router.cjs.js +82 -0
  53. package/dist/router.d.ts +20 -0
  54. package/dist/router.es.js +60 -0
  55. package/dist/utils-dUgb9Jkm.mjs +2016 -0
  56. package/dist/utils-tM9yE73c.js +2015 -0
  57. package/dist/v18.cjs.js +15 -0
  58. package/dist/v18.d.ts +114 -0
  59. package/dist/v18.es.js +15 -0
  60. package/dist/v19.cjs.js +15 -0
  61. package/dist/v19.d.ts +115 -0
  62. package/dist/v19.es.js +15 -0
  63. package/jest.config.ts +21 -0
  64. package/package.json +173 -0
  65. package/project.json +23 -0
  66. package/src/base.ts +50 -0
  67. package/src/index.ts +50 -0
  68. package/src/lazy/AwaitDataFetch.tsx +215 -0
  69. package/src/lazy/constant.ts +30 -0
  70. package/src/lazy/createLazyComponent.tsx +411 -0
  71. package/src/lazy/data-fetch/cache.ts +291 -0
  72. package/src/lazy/data-fetch/call-data-fetch.ts +13 -0
  73. package/src/lazy/data-fetch/data-fetch-server-middleware.ts +196 -0
  74. package/src/lazy/data-fetch/index.ts +16 -0
  75. package/src/lazy/data-fetch/inject-data-fetch.ts +109 -0
  76. package/src/lazy/data-fetch/prefetch.ts +112 -0
  77. package/src/lazy/data-fetch/runtime-plugin.ts +115 -0
  78. package/src/lazy/index.ts +35 -0
  79. package/src/lazy/logger.ts +6 -0
  80. package/src/lazy/types.ts +75 -0
  81. package/src/lazy/utils.ts +372 -0
  82. package/src/lazy/wrapNoSSR.tsx +10 -0
  83. package/src/modern-app-env.d.ts +2 -0
  84. package/src/plugins/lazy-load-component-plugin.spec.ts +21 -0
  85. package/src/plugins/lazy-load-component-plugin.ts +57 -0
  86. package/src/provider/context.tsx +4 -0
  87. package/src/provider/plugin.ts +22 -0
  88. package/src/provider/versions/bridge-base.tsx +150 -0
  89. package/src/provider/versions/legacy.ts +87 -0
  90. package/src/provider/versions/v18.ts +47 -0
  91. package/src/provider/versions/v19.ts +48 -0
  92. package/src/remote/RemoteAppWrapper.tsx +108 -0
  93. package/src/remote/base-component/component.tsx +2 -0
  94. package/src/remote/base-component/create.tsx +23 -0
  95. package/src/remote/base-component/index.tsx +10 -0
  96. package/src/remote/createHelpers.tsx +130 -0
  97. package/src/remote/router-component/component.tsx +104 -0
  98. package/src/remote/router-component/create.tsx +23 -0
  99. package/src/remote/router-component/index.tsx +10 -0
  100. package/src/router/default.tsx +73 -0
  101. package/src/router/v5.tsx +43 -0
  102. package/src/router/v6.tsx +74 -0
  103. package/src/router/v7.tsx +75 -0
  104. package/src/types.ts +147 -0
  105. package/src/utils/index.ts +44 -0
  106. package/src/v18.ts +9 -0
  107. package/src/v19.ts +9 -0
  108. package/tsconfig.json +42 -0
  109. package/tsconfig.node.json +11 -0
  110. package/tsconfig.spec.json +26 -0
  111. package/vite.config.ts +112 -0
  112. package/vitest.config.ts +27 -0
@@ -0,0 +1,10 @@
1
+ import { createLazyComponent } from './createLazyComponent';
2
+ import type { CreateLazyComponentOptions } from './createLazyComponent';
3
+
4
+ export function wrapNoSSR<T, E extends keyof T>(
5
+ createLazyComponentFn: typeof createLazyComponent<T, E>,
6
+ ) {
7
+ return (options: Omit<CreateLazyComponentOptions<T, E>, 'noSSR'>) => {
8
+ return createLazyComponentFn({ ...options, noSSR: true });
9
+ };
10
+ }
@@ -0,0 +1,2 @@
1
+ /// <reference types='@modern-js/module-tools/types' />
2
+ /// <reference types='@modern-js/plugin-testing/types' />
@@ -0,0 +1,21 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { lazyLoadComponentPlugin } from './lazy-load-component-plugin';
3
+ import type { ModuleFederation } from '@module-federation/runtime';
4
+
5
+ describe('lazyLoadComponentPlugin', () => {
6
+ it('should register lazy load component methods on the instance', () => {
7
+ const instance = {
8
+ registerPlugins: vi.fn(),
9
+ } as unknown as ModuleFederation;
10
+
11
+ const plugin = lazyLoadComponentPlugin();
12
+ if (plugin.apply) {
13
+ plugin.apply(instance);
14
+ }
15
+
16
+ expect(instance.registerPlugins).toHaveBeenCalled();
17
+ expect(typeof instance.createLazyComponent).toBe('function');
18
+ expect(typeof instance.prefetch).toBe('function');
19
+ expect(typeof instance.collectSSRAssets).toBe('function');
20
+ });
21
+ });
@@ -0,0 +1,57 @@
1
+ import type {
2
+ ModuleFederation,
3
+ ModuleFederationRuntimePlugin,
4
+ } from '@module-federation/runtime';
5
+ import {
6
+ createLazyComponent,
7
+ prefetch,
8
+ collectSSRAssets,
9
+ autoFetchDataPlugin,
10
+ } from '../lazy';
11
+ import type { CreateLazyComponentOptions, PrefetchOptions } from '../lazy';
12
+
13
+ declare module '@module-federation/runtime-core' {
14
+ interface ModuleFederation {
15
+ createLazyComponent<T, E extends keyof T>(
16
+ options: Omit<CreateLazyComponentOptions<T, E>, 'instance'>,
17
+ ): ReturnType<typeof createLazyComponent<T, E>>;
18
+ prefetch(
19
+ options: Omit<PrefetchOptions, 'instance'>,
20
+ ): ReturnType<typeof prefetch>;
21
+ collectSSRAssets(
22
+ options: Omit<Parameters<typeof collectSSRAssets>[0], 'instance'>,
23
+ ): ReturnType<typeof collectSSRAssets>;
24
+ }
25
+ }
26
+
27
+ export function lazyLoadComponentPlugin(): ModuleFederationRuntimePlugin {
28
+ return {
29
+ name: 'lazy-load-component-plugin',
30
+ apply(instance: ModuleFederation) {
31
+ instance.registerPlugins([autoFetchDataPlugin()]);
32
+
33
+ instance.createLazyComponent = (options) => {
34
+ return createLazyComponent({
35
+ instance,
36
+ ...options,
37
+ });
38
+ };
39
+
40
+ instance.prefetch = (options) => {
41
+ return prefetch({
42
+ instance,
43
+ ...options,
44
+ });
45
+ };
46
+
47
+ instance.collectSSRAssets = (options) => {
48
+ return collectSSRAssets({
49
+ instance,
50
+ ...options,
51
+ });
52
+ };
53
+ },
54
+ };
55
+ }
56
+
57
+ export default lazyLoadComponentPlugin;
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { ProviderParams } from '../types';
3
+
4
+ export const RouterContext = React.createContext<ProviderParams | null>(null);
@@ -0,0 +1,22 @@
1
+ import type {
2
+ ModuleFederationRuntimePlugin,
3
+ ModuleFederation,
4
+ } from '@module-federation/runtime';
5
+
6
+ export type FederationRuntimeType = {
7
+ instance: ModuleFederation | null;
8
+ };
9
+
10
+ export const federationRuntime: FederationRuntimeType = { instance: null };
11
+
12
+ function BridgeReactPlugin(): ModuleFederationRuntimePlugin {
13
+ return {
14
+ name: 'bridge-react-plugin',
15
+ beforeInit(args) {
16
+ federationRuntime.instance = args.origin;
17
+ return args;
18
+ },
19
+ };
20
+ }
21
+
22
+ export default BridgeReactPlugin;
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Base bridge component implementation
3
+ * This file contains bridge component logic shared across all React versions
4
+ */
5
+ import * as React from 'react';
6
+ import type {
7
+ ProviderParams,
8
+ ProviderFnParams,
9
+ RootType,
10
+ DestroyParams,
11
+ RenderParams,
12
+ CreateRootOptions,
13
+ } from '../../types';
14
+ import { ErrorBoundary, FallbackProps } from 'react-error-boundary';
15
+ import { RouterContext } from '../context';
16
+ import { LoggerInstance } from '../../utils';
17
+ import { federationRuntime } from '../plugin';
18
+
19
+ export function createBaseBridgeComponent<T>({
20
+ createRoot,
21
+ defaultRootOptions,
22
+ ...bridgeInfo
23
+ }: ProviderFnParams<T>) {
24
+ return () => {
25
+ const rootMap = new Map<any, RootType>();
26
+ const instance = federationRuntime.instance;
27
+ LoggerInstance.debug(
28
+ `createBridgeComponent instance from props >>>`,
29
+ instance,
30
+ );
31
+
32
+ const RawComponent = (info: { propsInfo: T; appInfo: ProviderParams }) => {
33
+ const { appInfo, propsInfo, ...restProps } = info;
34
+ const { moduleName, memoryRoute, basename = '/' } = appInfo;
35
+ return (
36
+ <RouterContext.Provider value={{ moduleName, basename, memoryRoute }}>
37
+ <bridgeInfo.rootComponent
38
+ {...propsInfo}
39
+ basename={basename}
40
+ {...restProps}
41
+ />
42
+ </RouterContext.Provider>
43
+ );
44
+ };
45
+
46
+ const DefaultFallback = ({ error }: FallbackProps) => (
47
+ <div role="alert">
48
+ <p>Something went wrong:</p>
49
+ <pre style={{ color: 'red' }}>{error.message}</pre>
50
+ </div>
51
+ );
52
+
53
+ const BridgeWrapper = ({
54
+ basename,
55
+ moduleName,
56
+ memoryRoute,
57
+ propsInfo,
58
+ fallback,
59
+ }: {
60
+ basename?: string;
61
+ moduleName?: string;
62
+ memoryRoute?: any;
63
+ propsInfo: T;
64
+ fallback?: React.ComponentType<FallbackProps>;
65
+ }) => (
66
+ <ErrorBoundary FallbackComponent={fallback || DefaultFallback}>
67
+ <RawComponent
68
+ appInfo={{
69
+ moduleName,
70
+ basename,
71
+ memoryRoute,
72
+ }}
73
+ propsInfo={propsInfo}
74
+ />
75
+ </ErrorBoundary>
76
+ );
77
+
78
+ return {
79
+ async render(info: RenderParams) {
80
+ LoggerInstance.debug(`createBridgeComponent render Info`, info);
81
+ const {
82
+ moduleName,
83
+ dom,
84
+ basename,
85
+ memoryRoute,
86
+ fallback,
87
+ rootOptions,
88
+ ...propsInfo
89
+ } = info;
90
+
91
+ const mergedRootOptions: CreateRootOptions | undefined = {
92
+ ...defaultRootOptions,
93
+ ...(rootOptions as CreateRootOptions),
94
+ };
95
+
96
+ const beforeBridgeRenderRes =
97
+ instance?.bridgeHook?.lifecycle?.beforeBridgeRender?.emit(info) || {};
98
+
99
+ const rootComponentWithErrorBoundary = (
100
+ <BridgeWrapper
101
+ basename={basename}
102
+ moduleName={moduleName}
103
+ memoryRoute={memoryRoute}
104
+ fallback={fallback as React.ComponentType<FallbackProps>}
105
+ propsInfo={
106
+ {
107
+ ...propsInfo,
108
+ basename,
109
+ ...(beforeBridgeRenderRes as any)?.extraProps,
110
+ } as T
111
+ }
112
+ />
113
+ );
114
+
115
+ if (bridgeInfo.render) {
116
+ await Promise.resolve(
117
+ bridgeInfo.render(rootComponentWithErrorBoundary, dom),
118
+ ).then((root: RootType) => rootMap.set(dom, root));
119
+ } else {
120
+ let root = rootMap.get(dom);
121
+ // Do not call createRoot multiple times
122
+ if (!root && createRoot) {
123
+ root = createRoot(dom, mergedRootOptions);
124
+ rootMap.set(dom, root as any);
125
+ }
126
+
127
+ if (root && 'render' in root) {
128
+ root.render(rootComponentWithErrorBoundary);
129
+ }
130
+ }
131
+ instance?.bridgeHook?.lifecycle?.afterBridgeRender?.emit(info) || {};
132
+ },
133
+
134
+ destroy(info: DestroyParams) {
135
+ const { dom } = info;
136
+ LoggerInstance.debug(`createBridgeComponent destroy Info`, info);
137
+ const root = rootMap.get(dom);
138
+ if (root) {
139
+ if ('unmount' in root) {
140
+ root.unmount();
141
+ } else {
142
+ LoggerInstance.warn('Root does not have unmount method');
143
+ }
144
+ rootMap.delete(dom);
145
+ }
146
+ instance?.bridgeHook?.lifecycle?.afterBridgeDestroy?.emit(info);
147
+ },
148
+ };
149
+ };
150
+ }
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Entry point for React 16/17 (legacy) specific bridge components
3
+ * This file provides support for React 16 and 17 versions, using the traditional ReactDOM.render API
4
+ */
5
+ import type { ProviderFnParams } from '../../types';
6
+ import { createBaseBridgeComponent } from './bridge-base';
7
+ import ReactDOM from 'react-dom';
8
+ import { LoggerInstance } from '../../utils';
9
+
10
+ export interface CreateRootOptions {
11
+ identifierPrefix?: string;
12
+ onRecoverableError?: (error: unknown, errorInfo: unknown) => void;
13
+ }
14
+
15
+ export interface Root {
16
+ render(children: React.ReactNode): void;
17
+ unmount(): void;
18
+ }
19
+
20
+ /**
21
+ * Default createRoot function that automatically detects React version and uses the appropriate API(only support React 16/17, 18)
22
+ *
23
+ * Note: Users can also directly import version-specific bridge components:
24
+ * - import { createBridgeComponent } from '@module-federation/bridge-react'
25
+ * - import { createBridgeComponent } from '@module-federation/bridge-react/v18'
26
+ * - import { createBridgeComponent } from '@module-federation/bridge-react/v19'
27
+ */
28
+
29
+ export function createReact16Or17Root(
30
+ container: Element | DocumentFragment,
31
+ ): Root {
32
+ return {
33
+ render(children: React.ReactNode) {
34
+ /**
35
+ * Detect React version
36
+ */
37
+ const reactVersion = ReactDOM.version || '';
38
+ const isReact18 = reactVersion.startsWith('18');
39
+ const isReact19 = reactVersion.startsWith('19');
40
+
41
+ /**
42
+ * Throw error for React 19
43
+ *
44
+ * Note: Due to Module Federation sharing mechanism, the actual version detected here
45
+ * might be 18 or 19, even if the application itself uses React 16/17.
46
+ * This happens because in MF environments, different remote modules may share different React versions.
47
+ * The console may throw warnings about version and API mismatches. If you need to resolve these issues,
48
+ * consider disabling the shared configuration for React.
49
+ */
50
+ if (isReact19) {
51
+ throw new Error(
52
+ `React 19 detected in legacy mode. This is not supported. ` +
53
+ `Please use the version-specific import: ` +
54
+ `import { createBridgeComponent } from '@module-federation/bridge-react/v19'`,
55
+ );
56
+ }
57
+
58
+ /**
59
+ * Provide warning for React 18
60
+ */
61
+ if (isReact18) {
62
+ LoggerInstance.warn(
63
+ `[Bridge-React] React 18 detected in legacy mode. ` +
64
+ `For better compatibility, please use the version-specific import: ` +
65
+ `import { createBridgeComponent } from '@module-federation/bridge-react/v18'`,
66
+ );
67
+ }
68
+
69
+ // @ts-ignore - React 17's render method is deprecated but still functional
70
+ ReactDOM.render(children, container);
71
+ },
72
+ unmount() {
73
+ ReactDOM.unmountComponentAtNode(container as Element);
74
+ },
75
+ };
76
+ }
77
+
78
+ export function createBridgeComponent<T = any>(
79
+ bridgeInfo: Omit<ProviderFnParams<T>, 'createRoot'>,
80
+ ) {
81
+ const fullBridgeInfo = {
82
+ createRoot: createReact16Or17Root,
83
+ ...bridgeInfo,
84
+ } as unknown as ProviderFnParams<T>;
85
+
86
+ return createBaseBridgeComponent(fullBridgeInfo);
87
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Entry point for React 18 specific bridge components
3
+ */
4
+ import React from 'react';
5
+ import { createRoot as createReactRoot, hydrateRoot } from 'react-dom/client';
6
+ import { createBaseBridgeComponent } from './bridge-base';
7
+ import type { ProviderFnParams } from '../../types';
8
+
9
+ export interface CreateRootOptions {
10
+ identifierPrefix?: string;
11
+ onRecoverableError?: (error: unknown, errorInfo: unknown) => void;
12
+ }
13
+
14
+ export interface Root {
15
+ render(children: React.ReactNode): void;
16
+ unmount(): void;
17
+ }
18
+
19
+ export function createReact18Root(
20
+ container: Element | DocumentFragment,
21
+ options?: CreateRootOptions,
22
+ ): Root {
23
+ return createReactRoot(container, options);
24
+ }
25
+
26
+ export function hydrateReact18Root(
27
+ container: Element | DocumentFragment,
28
+ initialChildren: React.ReactNode,
29
+ options?: CreateRootOptions,
30
+ ) {
31
+ return hydrateRoot(
32
+ container as Element,
33
+ initialChildren as React.ReactElement,
34
+ options,
35
+ );
36
+ }
37
+
38
+ export function createBridgeComponent<T = any>(
39
+ bridgeInfo: Omit<ProviderFnParams<T>, 'createRoot'>,
40
+ ) {
41
+ const fullBridgeInfo = {
42
+ createRoot: createReact18Root,
43
+ ...bridgeInfo,
44
+ } as unknown as ProviderFnParams<T>;
45
+
46
+ return createBaseBridgeComponent(fullBridgeInfo);
47
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Entry point for React 19 specific bridge components
3
+ * This file provides support for React 19 version, using the new ReactDOM.createRoot API
4
+ */
5
+ import React from 'react';
6
+ import { createRoot, hydrateRoot } from 'react-dom/client';
7
+ import { createBaseBridgeComponent } from './bridge-base';
8
+ import type { ProviderFnParams } from '../../types';
9
+ export interface CreateRootOptions {
10
+ identifierPrefix?: string;
11
+ onRecoverableError?: (error: unknown, errorInfo: unknown) => void;
12
+ transitionCallbacks?: unknown;
13
+ }
14
+
15
+ export interface Root {
16
+ render(children: React.ReactNode): void;
17
+ unmount(): void;
18
+ }
19
+
20
+ export function createReact19Root(
21
+ container: Element | DocumentFragment,
22
+ options?: CreateRootOptions,
23
+ ): Root {
24
+ return createRoot(container as Element, options);
25
+ }
26
+
27
+ export function hydrateReact19Root(
28
+ container: Element | DocumentFragment,
29
+ initialChildren: React.ReactNode,
30
+ options?: CreateRootOptions,
31
+ ): Root {
32
+ return hydrateRoot(
33
+ container as Element,
34
+ initialChildren as React.ReactElement,
35
+ options,
36
+ );
37
+ }
38
+
39
+ export function createBridgeComponent<T = any>(
40
+ bridgeInfo: Omit<ProviderFnParams<T>, 'createRoot'>,
41
+ ) {
42
+ const fullBridgeInfo = {
43
+ createRoot: createReact19Root,
44
+ ...bridgeInfo,
45
+ } as unknown as ProviderFnParams<T>;
46
+
47
+ return createBaseBridgeComponent(fullBridgeInfo);
48
+ }
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Shared RemoteAppWrapper component used by both base and router versions
3
+ * This component handles the lifecycle of remote Module Federation apps
4
+ */
5
+ import React, { useEffect, useRef, useState, forwardRef } from 'react';
6
+ import { LoggerInstance, getRootDomDefaultClassName } from '../utils';
7
+ import { federationRuntime } from '../provider/plugin';
8
+ import { RemoteComponentProps, RemoteAppParams } from '../types';
9
+
10
+ export const RemoteAppWrapper = forwardRef(function (
11
+ props: RemoteAppParams & RemoteComponentProps,
12
+ ref,
13
+ ) {
14
+ const {
15
+ moduleName,
16
+ memoryRoute,
17
+ basename,
18
+ providerInfo,
19
+ className,
20
+ style,
21
+ fallback,
22
+ loading,
23
+ ...resProps
24
+ } = props;
25
+
26
+ const instance = federationRuntime.instance;
27
+ const rootRef: React.MutableRefObject<HTMLDivElement | null> =
28
+ ref && 'current' in ref
29
+ ? (ref as React.MutableRefObject<HTMLDivElement | null>)
30
+ : useRef(null);
31
+
32
+ const renderDom: React.MutableRefObject<HTMLElement | null> = useRef(null);
33
+ const providerInfoRef = useRef<any>(null);
34
+ const [initialized, setInitialized] = useState(false);
35
+
36
+ LoggerInstance.debug(`RemoteAppWrapper instance from props >>>`, instance);
37
+
38
+ // 初始化远程组件
39
+ useEffect(() => {
40
+ if (initialized) return;
41
+ const providerReturn = providerInfo();
42
+ providerInfoRef.current = providerReturn;
43
+ setInitialized(true);
44
+
45
+ return () => {
46
+ if (providerInfoRef.current?.destroy) {
47
+ LoggerInstance.debug(
48
+ `createRemoteAppComponent LazyComponent destroy >>>`,
49
+ { moduleName, basename, dom: renderDom.current },
50
+ );
51
+
52
+ instance?.bridgeHook?.lifecycle?.beforeBridgeDestroy?.emit({
53
+ moduleName,
54
+ dom: renderDom.current,
55
+ basename,
56
+ memoryRoute,
57
+ fallback,
58
+ ...resProps,
59
+ });
60
+
61
+ providerInfoRef.current?.destroy({
62
+ moduleName,
63
+ dom: renderDom.current,
64
+ });
65
+
66
+ instance?.bridgeHook?.lifecycle?.afterBridgeDestroy?.emit({
67
+ moduleName,
68
+ dom: renderDom.current,
69
+ basename,
70
+ memoryRoute,
71
+ fallback,
72
+ ...resProps,
73
+ });
74
+ }
75
+ };
76
+ }, [moduleName]);
77
+
78
+ // trigger render after props updated
79
+ useEffect(() => {
80
+ if (!initialized || !providerInfoRef.current) return;
81
+
82
+ let renderProps = {
83
+ moduleName,
84
+ dom: rootRef.current,
85
+ basename,
86
+ memoryRoute,
87
+ fallback,
88
+ ...resProps,
89
+ };
90
+ renderDom.current = rootRef.current;
91
+
92
+ const beforeBridgeRenderRes =
93
+ instance?.bridgeHook?.lifecycle?.beforeBridgeRender?.emit(renderProps) ||
94
+ {};
95
+ // @ts-ignore
96
+ renderProps = { ...renderProps, ...beforeBridgeRenderRes.extraProps };
97
+ providerInfoRef.current.render(renderProps);
98
+ instance?.bridgeHook?.lifecycle?.afterBridgeRender?.emit(renderProps);
99
+ }, [initialized, ...Object.values(props)]);
100
+
101
+ // bridge-remote-root
102
+ const rootComponentClassName = `${getRootDomDefaultClassName(moduleName)} ${className || ''}`;
103
+ return (
104
+ <div className={rootComponentClassName} style={style} ref={rootRef}>
105
+ {loading}
106
+ </div>
107
+ );
108
+ });
@@ -0,0 +1,2 @@
1
+ import { RemoteAppWrapper } from '../RemoteAppWrapper';
2
+ export default RemoteAppWrapper;
@@ -0,0 +1,23 @@
1
+ import RemoteApp from './component';
2
+ import {
3
+ createLazyRemoteComponentFactory,
4
+ createRemoteAppComponentFactory,
5
+ createDeprecatedRemoteComponentFactory,
6
+ type LazyRemoteComponentInfo,
7
+ } from '../createHelpers';
8
+
9
+ export type { LazyRemoteComponentInfo };
10
+
11
+ const createLazyRemoteComponent = createLazyRemoteComponentFactory(RemoteApp);
12
+
13
+ export const createRemoteAppComponent =
14
+ createRemoteAppComponentFactory(RemoteApp);
15
+
16
+ /**
17
+ * @deprecated createRemoteComponent is deprecated, please use createRemoteAppComponent instead!
18
+ */
19
+ export const createRemoteComponent = createDeprecatedRemoteComponentFactory(
20
+ createRemoteAppComponent,
21
+ );
22
+
23
+ export { createLazyRemoteComponent };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Base entry point without React Router dependencies
3
+ * Re-exports from base/create.tsx
4
+ */
5
+ export {
6
+ createRemoteAppComponent,
7
+ createRemoteComponent,
8
+ createLazyRemoteComponent,
9
+ type LazyRemoteComponentInfo,
10
+ } from './create';