@module-federation/bridge-react 0.0.0-next-20250926024003 → 0.0.0-perf-devtools-20260107043700
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.
- package/CHANGELOG.md +81 -3
- package/__tests__/bridge.spec.tsx +37 -14
- package/dist/base.cjs.js +29 -0
- package/dist/base.d.ts +311 -0
- package/dist/base.es.js +30 -0
- package/dist/{bridge-base-BwHtOqw_.mjs → bridge-base-CPSTBjEp.mjs} +30 -18
- package/dist/{bridge-base-Ds850AOx.js → bridge-base-RStDxH71.js} +30 -18
- package/dist/createHelpers-B_L612IN.js +190 -0
- package/dist/createHelpers-Ui5pt7je.mjs +191 -0
- package/dist/data-fetch-server-middleware.cjs.js +2 -2
- package/dist/data-fetch-server-middleware.es.js +2 -2
- package/dist/data-fetch-utils.cjs.js +2 -2
- package/dist/data-fetch-utils.es.js +8 -8
- package/dist/{index-eN2xRRXs.js → index-DRSBaSu3.js} +1 -1
- package/dist/{index-rAO0Wr0M.mjs → index-DyQNwY2M.mjs} +1 -1
- package/dist/index.cjs.js +11 -179
- package/dist/index.d.ts +31 -6
- package/dist/index.es.js +19 -186
- package/dist/{index.esm-Ju4RY-yW.js → index.esm-BWaKho-8.js} +108 -46
- package/dist/{index.esm-CtI0uQUR.mjs → index.esm-CPwSeCvw.mjs} +113 -51
- package/dist/{lazy-load-component-plugin-D6tEPyvX.mjs → lazy-load-component-plugin-CNyT62wB.mjs} +2 -2
- package/dist/{lazy-load-component-plugin-CWNzJM0v.js → lazy-load-component-plugin-Dr5VV1mu.js} +2 -2
- package/dist/lazy-load-component-plugin.cjs.js +2 -2
- package/dist/lazy-load-component-plugin.es.js +2 -2
- package/dist/lazy-utils.cjs.js +2 -2
- package/dist/lazy-utils.es.js +4 -4
- package/dist/{prefetch-hTVJ80G6.js → prefetch-J3x-_5zT.js} +43 -141
- package/dist/{prefetch-DCF_oa3O.mjs → prefetch-lrSPKiuu.mjs} +43 -141
- package/dist/router-v5.cjs.js +1 -1
- package/dist/router-v5.es.js +1 -1
- package/dist/router-v6.cjs.js +1 -1
- package/dist/router-v6.es.js +1 -1
- package/dist/router-v7.cjs.js +83 -0
- package/dist/router-v7.d.ts +20 -0
- package/dist/router-v7.es.js +61 -0
- package/dist/router.cjs.js +1 -1
- package/dist/router.es.js +1 -1
- package/dist/{utils-VSOJTX_o.mjs → utils-dUgb9Jkm.mjs} +7 -7
- package/dist/{utils-vIpCrZmn.js → utils-tM9yE73c.js} +1 -1
- package/dist/v18.cjs.js +1 -1
- package/dist/v18.es.js +1 -1
- package/dist/v19.cjs.js +1 -1
- package/dist/v19.es.js +1 -1
- package/package.json +54 -10
- package/src/base.ts +50 -0
- package/src/index.ts +6 -1
- package/src/provider/versions/bridge-base.tsx +45 -17
- package/src/provider/versions/legacy.ts +2 -1
- package/src/remote/RemoteAppWrapper.tsx +108 -0
- package/src/remote/base-component/component.tsx +2 -0
- package/src/remote/base-component/create.tsx +23 -0
- package/src/remote/base-component/index.tsx +10 -0
- package/src/remote/createHelpers.tsx +130 -0
- package/src/remote/{component.tsx → router-component/component.tsx} +3 -110
- package/src/remote/router-component/create.tsx +23 -0
- package/src/remote/router-component/index.tsx +10 -0
- package/src/router/v7.tsx +75 -0
- package/vite.config.ts +25 -0
- package/src/remote/create.tsx +0 -103
|
@@ -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,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,130 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
import { ErrorBoundary, FallbackProps } from 'react-error-boundary';
|
|
3
|
+
import { LoggerInstance } from '../utils';
|
|
4
|
+
import {
|
|
5
|
+
RemoteComponentParams,
|
|
6
|
+
RemoteComponentProps,
|
|
7
|
+
RemoteModule,
|
|
8
|
+
} from '../types';
|
|
9
|
+
|
|
10
|
+
export type LazyRemoteComponentInfo<
|
|
11
|
+
T,
|
|
12
|
+
_E extends keyof T,
|
|
13
|
+
> = RemoteComponentParams<T>;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Creates a factory function for creating lazy remote components
|
|
17
|
+
* @param RemoteApp The RemoteAppWrapper component to use (with or without router)
|
|
18
|
+
*/
|
|
19
|
+
export function createLazyRemoteComponentFactory(
|
|
20
|
+
RemoteApp: React.ComponentType<any>,
|
|
21
|
+
) {
|
|
22
|
+
return function createLazyRemoteComponent<
|
|
23
|
+
T = Record<string, unknown>,
|
|
24
|
+
E extends keyof T = keyof T,
|
|
25
|
+
>(info: LazyRemoteComponentInfo<T, E>) {
|
|
26
|
+
const exportName = info?.export || 'default';
|
|
27
|
+
return React.lazy(async () => {
|
|
28
|
+
LoggerInstance.debug(
|
|
29
|
+
`createRemoteAppComponent LazyComponent create >>>`,
|
|
30
|
+
{
|
|
31
|
+
lazyComponent: info.loader,
|
|
32
|
+
exportName,
|
|
33
|
+
},
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
const m = (await info.loader()) as RemoteModule;
|
|
38
|
+
// @ts-ignore
|
|
39
|
+
const moduleName = m && m[Symbol.for('mf_module_id')];
|
|
40
|
+
LoggerInstance.debug(
|
|
41
|
+
`createRemoteAppComponent LazyComponent loadRemote info >>>`,
|
|
42
|
+
{ name: moduleName, module: m, exportName },
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
// @ts-ignore
|
|
46
|
+
const exportFn = m[exportName];
|
|
47
|
+
if (exportName in m && typeof exportFn === 'function') {
|
|
48
|
+
const RemoteAppComponent = forwardRef<
|
|
49
|
+
HTMLDivElement,
|
|
50
|
+
RemoteComponentProps
|
|
51
|
+
>((props, ref) => {
|
|
52
|
+
return (
|
|
53
|
+
<RemoteApp
|
|
54
|
+
// change `name` key to `moduleName` to avoid same property `name` passed by user's props which may cause unexpected issues.
|
|
55
|
+
moduleName={moduleName}
|
|
56
|
+
providerInfo={exportFn}
|
|
57
|
+
exportName={info.export || 'default'}
|
|
58
|
+
fallback={info.fallback}
|
|
59
|
+
loading={info.loading}
|
|
60
|
+
ref={ref}
|
|
61
|
+
{...props}
|
|
62
|
+
/>
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
default: RemoteAppComponent,
|
|
68
|
+
};
|
|
69
|
+
} else {
|
|
70
|
+
LoggerInstance.debug(
|
|
71
|
+
`createRemoteAppComponent LazyComponent module not found >>>`,
|
|
72
|
+
{ name: moduleName, module: m, exportName },
|
|
73
|
+
);
|
|
74
|
+
throw Error(
|
|
75
|
+
`Make sure that ${moduleName} has the correct export when export is ${String(
|
|
76
|
+
exportName,
|
|
77
|
+
)}`,
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
} catch (error) {
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Creates a factory function for creating remote app components
|
|
89
|
+
* @param RemoteApp The RemoteAppWrapper component to use (with or without router)
|
|
90
|
+
*/
|
|
91
|
+
export function createRemoteAppComponentFactory(
|
|
92
|
+
RemoteApp: React.ComponentType<any>,
|
|
93
|
+
) {
|
|
94
|
+
const createLazyRemoteComponent = createLazyRemoteComponentFactory(RemoteApp);
|
|
95
|
+
|
|
96
|
+
return function createRemoteAppComponent<
|
|
97
|
+
T = Record<string, unknown>,
|
|
98
|
+
E extends keyof T = keyof T,
|
|
99
|
+
>(info: LazyRemoteComponentInfo<T, E>) {
|
|
100
|
+
const LazyComponent = createLazyRemoteComponent(info);
|
|
101
|
+
return forwardRef<HTMLDivElement, RemoteComponentProps>((props, ref) => {
|
|
102
|
+
return (
|
|
103
|
+
<ErrorBoundary
|
|
104
|
+
FallbackComponent={
|
|
105
|
+
info.fallback as React.ComponentType<FallbackProps>
|
|
106
|
+
}
|
|
107
|
+
>
|
|
108
|
+
<React.Suspense fallback={info.loading}>
|
|
109
|
+
<LazyComponent {...props} ref={ref} />
|
|
110
|
+
</React.Suspense>
|
|
111
|
+
</ErrorBoundary>
|
|
112
|
+
);
|
|
113
|
+
});
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Creates the deprecated createRemoteComponent function
|
|
119
|
+
*/
|
|
120
|
+
export function createDeprecatedRemoteComponentFactory<
|
|
121
|
+
T = Record<string, unknown>,
|
|
122
|
+
E extends keyof T = keyof T,
|
|
123
|
+
>(createFn: (info: LazyRemoteComponentInfo<T, E>) => any) {
|
|
124
|
+
return function createRemoteComponent(info: LazyRemoteComponentInfo<T, E>) {
|
|
125
|
+
LoggerInstance.warn(
|
|
126
|
+
`createRemoteComponent is deprecated, please use createRemoteAppComponent instead!`,
|
|
127
|
+
);
|
|
128
|
+
return createFn(info);
|
|
129
|
+
};
|
|
130
|
+
}
|
|
@@ -1,115 +1,8 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
useContext,
|
|
3
|
-
useEffect,
|
|
4
|
-
useRef,
|
|
5
|
-
useState,
|
|
6
|
-
forwardRef,
|
|
7
|
-
} from 'react';
|
|
1
|
+
import React, { useContext, useEffect, useState, forwardRef } from 'react';
|
|
8
2
|
import * as ReactRouterDOM from 'react-router-dom';
|
|
9
3
|
import { dispatchPopstateEnv } from '@module-federation/bridge-shared';
|
|
10
|
-
import { LoggerInstance, pathJoin
|
|
11
|
-
import {
|
|
12
|
-
import { RemoteComponentProps, RemoteAppParams } from '../types';
|
|
13
|
-
|
|
14
|
-
const RemoteAppWrapper = forwardRef(function (
|
|
15
|
-
props: RemoteAppParams & RemoteComponentProps,
|
|
16
|
-
ref,
|
|
17
|
-
) {
|
|
18
|
-
const {
|
|
19
|
-
moduleName,
|
|
20
|
-
memoryRoute,
|
|
21
|
-
basename,
|
|
22
|
-
providerInfo,
|
|
23
|
-
className,
|
|
24
|
-
style,
|
|
25
|
-
fallback,
|
|
26
|
-
loading,
|
|
27
|
-
...resProps
|
|
28
|
-
} = props;
|
|
29
|
-
|
|
30
|
-
const instance = federationRuntime.instance;
|
|
31
|
-
const rootRef: React.MutableRefObject<HTMLDivElement | null> =
|
|
32
|
-
ref && 'current' in ref
|
|
33
|
-
? (ref as React.MutableRefObject<HTMLDivElement | null>)
|
|
34
|
-
: useRef(null);
|
|
35
|
-
|
|
36
|
-
const renderDom: React.MutableRefObject<HTMLElement | null> = useRef(null);
|
|
37
|
-
const providerInfoRef = useRef<any>(null);
|
|
38
|
-
const [initialized, setInitialized] = useState(false);
|
|
39
|
-
|
|
40
|
-
LoggerInstance.debug(`RemoteAppWrapper instance from props >>>`, instance);
|
|
41
|
-
|
|
42
|
-
// 初始化远程组件
|
|
43
|
-
useEffect(() => {
|
|
44
|
-
if (initialized) return;
|
|
45
|
-
const providerReturn = providerInfo();
|
|
46
|
-
providerInfoRef.current = providerReturn;
|
|
47
|
-
setInitialized(true);
|
|
48
|
-
|
|
49
|
-
return () => {
|
|
50
|
-
if (providerInfoRef.current?.destroy) {
|
|
51
|
-
LoggerInstance.debug(
|
|
52
|
-
`createRemoteAppComponent LazyComponent destroy >>>`,
|
|
53
|
-
{ moduleName, basename, dom: renderDom.current },
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
instance?.bridgeHook?.lifecycle?.beforeBridgeDestroy?.emit({
|
|
57
|
-
moduleName,
|
|
58
|
-
dom: renderDom.current,
|
|
59
|
-
basename,
|
|
60
|
-
memoryRoute,
|
|
61
|
-
fallback,
|
|
62
|
-
...resProps,
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
providerInfoRef.current?.destroy({
|
|
66
|
-
moduleName,
|
|
67
|
-
dom: renderDom.current,
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
instance?.bridgeHook?.lifecycle?.afterBridgeDestroy?.emit({
|
|
71
|
-
moduleName,
|
|
72
|
-
dom: renderDom.current,
|
|
73
|
-
basename,
|
|
74
|
-
memoryRoute,
|
|
75
|
-
fallback,
|
|
76
|
-
...resProps,
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
}, [moduleName]);
|
|
81
|
-
|
|
82
|
-
// trigger render after props updated
|
|
83
|
-
useEffect(() => {
|
|
84
|
-
if (!initialized || !providerInfoRef.current) return;
|
|
85
|
-
|
|
86
|
-
let renderProps = {
|
|
87
|
-
moduleName,
|
|
88
|
-
dom: rootRef.current,
|
|
89
|
-
basename,
|
|
90
|
-
memoryRoute,
|
|
91
|
-
fallback,
|
|
92
|
-
...resProps,
|
|
93
|
-
};
|
|
94
|
-
renderDom.current = rootRef.current;
|
|
95
|
-
|
|
96
|
-
const beforeBridgeRenderRes =
|
|
97
|
-
instance?.bridgeHook?.lifecycle?.beforeBridgeRender?.emit(renderProps) ||
|
|
98
|
-
{};
|
|
99
|
-
// @ts-ignore
|
|
100
|
-
renderProps = { ...renderProps, ...beforeBridgeRenderRes.extraProps };
|
|
101
|
-
providerInfoRef.current.render(renderProps);
|
|
102
|
-
instance?.bridgeHook?.lifecycle?.afterBridgeRender?.emit(renderProps);
|
|
103
|
-
}, [initialized, ...Object.values(props)]);
|
|
104
|
-
|
|
105
|
-
// bridge-remote-root
|
|
106
|
-
const rootComponentClassName = `${getRootDomDefaultClassName(moduleName)} ${className || ''}`;
|
|
107
|
-
return (
|
|
108
|
-
<div className={rootComponentClassName} style={style} ref={rootRef}>
|
|
109
|
-
{loading}
|
|
110
|
-
</div>
|
|
111
|
-
);
|
|
112
|
-
});
|
|
4
|
+
import { LoggerInstance, pathJoin } from '../../utils';
|
|
5
|
+
import { RemoteAppWrapper } from '../RemoteAppWrapper';
|
|
113
6
|
|
|
114
7
|
interface ExtraDataProps {
|
|
115
8
|
basename?: string;
|
|
@@ -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,75 @@
|
|
|
1
|
+
import React, { useContext } from 'react';
|
|
2
|
+
// The upper alias react-router$ into this file avoids the loop
|
|
3
|
+
// React Router v7 uses different dist structure, we'll import from the main entry
|
|
4
|
+
import * as ReactRouterDom from 'react-router';
|
|
5
|
+
import { RouterContext } from '../provider/context';
|
|
6
|
+
import { LoggerInstance } from '../utils';
|
|
7
|
+
|
|
8
|
+
function WraperRouter(
|
|
9
|
+
props:
|
|
10
|
+
| Parameters<typeof ReactRouterDom.BrowserRouter>[0]
|
|
11
|
+
| Parameters<typeof ReactRouterDom.MemoryRouter>[0],
|
|
12
|
+
) {
|
|
13
|
+
const { basename, ...propsRes } = props;
|
|
14
|
+
const routerContextProps = useContext(RouterContext) || {};
|
|
15
|
+
|
|
16
|
+
LoggerInstance.debug(`WraperRouter info >>>`, {
|
|
17
|
+
...routerContextProps,
|
|
18
|
+
routerContextProps,
|
|
19
|
+
WraperRouterProps: props,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
if (routerContextProps?.memoryRoute) {
|
|
23
|
+
return (
|
|
24
|
+
<ReactRouterDom.MemoryRouter
|
|
25
|
+
{...props}
|
|
26
|
+
initialEntries={[routerContextProps?.memoryRoute.entryPath]}
|
|
27
|
+
/>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
return (
|
|
31
|
+
<ReactRouterDom.BrowserRouter
|
|
32
|
+
{...propsRes}
|
|
33
|
+
basename={routerContextProps?.basename || basename}
|
|
34
|
+
/>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function WraperRouterProvider(
|
|
39
|
+
props: Parameters<typeof ReactRouterDom.RouterProvider>[0],
|
|
40
|
+
) {
|
|
41
|
+
const { router, ...propsRes } = props;
|
|
42
|
+
const routerContextProps = useContext(RouterContext) || {};
|
|
43
|
+
const routers = router.routes;
|
|
44
|
+
LoggerInstance.debug(`WraperRouterProvider info >>>`, {
|
|
45
|
+
...routerContextProps,
|
|
46
|
+
routerContextProps,
|
|
47
|
+
WraperRouterProviderProps: props,
|
|
48
|
+
router,
|
|
49
|
+
});
|
|
50
|
+
const RouterProvider = (ReactRouterDom as any)['Router' + 'Provider'];
|
|
51
|
+
const createMemoryRouter = (ReactRouterDom as any)['create' + 'MemoryRouter'];
|
|
52
|
+
const createBrowserRouter = (ReactRouterDom as any)[
|
|
53
|
+
'create' + 'BrowserRouter'
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
if (routerContextProps.memoryRoute) {
|
|
57
|
+
const MemeoryRouterInstance = createMemoryRouter(routers, {
|
|
58
|
+
initialEntries: [routerContextProps?.memoryRoute.entryPath],
|
|
59
|
+
});
|
|
60
|
+
return <RouterProvider router={MemeoryRouterInstance} />;
|
|
61
|
+
} else {
|
|
62
|
+
const BrowserRouterInstance = createBrowserRouter(routers, {
|
|
63
|
+
// In host app, the routerContextProps is {}, so we should use router.basename as fallback
|
|
64
|
+
basename: routerContextProps.basename || router.basename,
|
|
65
|
+
future: router.future,
|
|
66
|
+
window: router.window,
|
|
67
|
+
});
|
|
68
|
+
return <RouterProvider {...propsRes} router={BrowserRouterInstance} />;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Export all from react-router for v7 compatibility
|
|
73
|
+
export * from 'react-router';
|
|
74
|
+
export { WraperRouter as BrowserRouter };
|
|
75
|
+
export { WraperRouterProvider as RouterProvider };
|
package/vite.config.ts
CHANGED
|
@@ -20,10 +20,12 @@ export default defineConfig({
|
|
|
20
20
|
lib: {
|
|
21
21
|
entry: {
|
|
22
22
|
index: path.resolve(__dirname, 'src/index.ts'),
|
|
23
|
+
base: path.resolve(__dirname, 'src/base.ts'),
|
|
23
24
|
plugin: path.resolve(__dirname, 'src/provider/plugin.ts'),
|
|
24
25
|
router: path.resolve(__dirname, 'src/router/default.tsx'),
|
|
25
26
|
'router-v5': path.resolve(__dirname, 'src/router/v5.tsx'),
|
|
26
27
|
'router-v6': path.resolve(__dirname, 'src/router/v6.tsx'),
|
|
28
|
+
'router-v7': path.resolve(__dirname, 'src/router/v7.tsx'),
|
|
27
29
|
v18: path.resolve(__dirname, 'src/v18.ts'),
|
|
28
30
|
v19: path.resolve(__dirname, 'src/v19.ts'),
|
|
29
31
|
'lazy-load-component-plugin': path.resolve(
|
|
@@ -49,6 +51,12 @@ export default defineConfig({
|
|
|
49
51
|
'@remix-run/router',
|
|
50
52
|
/react-dom\/.*/,
|
|
51
53
|
'react-router',
|
|
54
|
+
'react-router/',
|
|
55
|
+
'react-router/index.js',
|
|
56
|
+
'react-router/dist/index.js',
|
|
57
|
+
'react-router/dist/development/index.js',
|
|
58
|
+
'react-router/dist/production/index.js',
|
|
59
|
+
/^react-router\/.*/,
|
|
52
60
|
'react-router-dom/',
|
|
53
61
|
'react-router-dom/index.js',
|
|
54
62
|
'react-router-dom/dist/index.js',
|
|
@@ -67,6 +75,23 @@ export default defineConfig({
|
|
|
67
75
|
);
|
|
68
76
|
}
|
|
69
77
|
|
|
78
|
+
if (fileName.includes('router-v7') && chunk.type === 'chunk') {
|
|
79
|
+
// Replace 'react-router' with the correct v7 dist path based on environment
|
|
80
|
+
const isProduction = process.env.NODE_ENV === 'production';
|
|
81
|
+
const distPath = isProduction
|
|
82
|
+
? 'react-router/dist/production/index.js'
|
|
83
|
+
: 'react-router/dist/development/index.js';
|
|
84
|
+
|
|
85
|
+
chunk.code = chunk.code.replace(
|
|
86
|
+
/from\s+['"`]react-router['"`]/g,
|
|
87
|
+
`from '${distPath}'`,
|
|
88
|
+
);
|
|
89
|
+
chunk.code = chunk.code.replace(
|
|
90
|
+
/export\s+\*\s+from\s+['"`]react-router['"`]/g,
|
|
91
|
+
`export * from '${distPath}'`,
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
70
95
|
if (fileName.includes('router-v5') && chunk.type === 'chunk') {
|
|
71
96
|
chunk.code = chunk.code.replace(
|
|
72
97
|
// Match 'react-router-dom/' followed by single quotes, double quotes, or backticks, replacing only 'react-router-dom/' to react-router-v5 dist file structure
|
package/src/remote/create.tsx
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import React, { forwardRef } from 'react';
|
|
2
|
-
import { ErrorBoundary, FallbackProps } from 'react-error-boundary';
|
|
3
|
-
import { LoggerInstance } from '../utils';
|
|
4
|
-
import RemoteApp from './component';
|
|
5
|
-
import {
|
|
6
|
-
RemoteComponentParams,
|
|
7
|
-
RemoteComponentProps,
|
|
8
|
-
RemoteModule,
|
|
9
|
-
} from '../types';
|
|
10
|
-
|
|
11
|
-
type LazyRemoteComponentInfo<T, _E extends keyof T> = RemoteComponentParams<T>;
|
|
12
|
-
|
|
13
|
-
function createLazyRemoteComponent<
|
|
14
|
-
T = Record<string, unknown>,
|
|
15
|
-
E extends keyof T = keyof T,
|
|
16
|
-
>(info: LazyRemoteComponentInfo<T, E>) {
|
|
17
|
-
const exportName = info?.export || 'default';
|
|
18
|
-
return React.lazy(async () => {
|
|
19
|
-
LoggerInstance.debug(`createRemoteAppComponent LazyComponent create >>>`, {
|
|
20
|
-
lazyComponent: info.loader,
|
|
21
|
-
exportName,
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
try {
|
|
25
|
-
const m = (await info.loader()) as RemoteModule;
|
|
26
|
-
// @ts-ignore
|
|
27
|
-
const moduleName = m && m[Symbol.for('mf_module_id')];
|
|
28
|
-
LoggerInstance.debug(
|
|
29
|
-
`createRemoteAppComponent LazyComponent loadRemote info >>>`,
|
|
30
|
-
{ name: moduleName, module: m, exportName },
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
// @ts-ignore
|
|
34
|
-
const exportFn = m[exportName];
|
|
35
|
-
if (exportName in m && typeof exportFn === 'function') {
|
|
36
|
-
const RemoteAppComponent = forwardRef<
|
|
37
|
-
HTMLDivElement,
|
|
38
|
-
RemoteComponentProps
|
|
39
|
-
>((props, ref) => {
|
|
40
|
-
return (
|
|
41
|
-
<RemoteApp
|
|
42
|
-
// change `name` key to `moduleName` to avoid same property `name` passed by user's props which may cause unexpected issues.
|
|
43
|
-
moduleName={moduleName}
|
|
44
|
-
providerInfo={exportFn}
|
|
45
|
-
exportName={info.export || 'default'}
|
|
46
|
-
fallback={info.fallback}
|
|
47
|
-
loading={info.loading}
|
|
48
|
-
ref={ref}
|
|
49
|
-
{...props}
|
|
50
|
-
/>
|
|
51
|
-
);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
return {
|
|
55
|
-
default: RemoteAppComponent,
|
|
56
|
-
};
|
|
57
|
-
} else {
|
|
58
|
-
LoggerInstance.debug(
|
|
59
|
-
`createRemoteAppComponent LazyComponent module not found >>>`,
|
|
60
|
-
{ name: moduleName, module: m, exportName },
|
|
61
|
-
);
|
|
62
|
-
throw Error(
|
|
63
|
-
`Make sure that ${moduleName} has the correct export when export is ${String(
|
|
64
|
-
exportName,
|
|
65
|
-
)}`,
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
} catch (error) {
|
|
69
|
-
throw error;
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export function createRemoteAppComponent<
|
|
75
|
-
T = Record<string, unknown>,
|
|
76
|
-
E extends keyof T = keyof T,
|
|
77
|
-
>(info: LazyRemoteComponentInfo<T, E>) {
|
|
78
|
-
const LazyComponent = createLazyRemoteComponent(info);
|
|
79
|
-
return forwardRef<HTMLDivElement, RemoteComponentProps>((props, ref) => {
|
|
80
|
-
return (
|
|
81
|
-
<ErrorBoundary
|
|
82
|
-
FallbackComponent={info.fallback as React.ComponentType<FallbackProps>}
|
|
83
|
-
>
|
|
84
|
-
<React.Suspense fallback={info.loading}>
|
|
85
|
-
<LazyComponent {...props} ref={ref} />
|
|
86
|
-
</React.Suspense>
|
|
87
|
-
</ErrorBoundary>
|
|
88
|
-
);
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* @deprecated createRemoteAppComponent is deprecated, please use createRemoteAppComponent instead!
|
|
94
|
-
*/
|
|
95
|
-
export function createRemoteComponent<
|
|
96
|
-
T = Record<string, unknown>,
|
|
97
|
-
E extends keyof T = keyof T,
|
|
98
|
-
>(info: LazyRemoteComponentInfo<T, E>) {
|
|
99
|
-
LoggerInstance.warn(
|
|
100
|
-
`createRemoteComponent is deprecated, please use createRemoteAppComponent instead!`,
|
|
101
|
-
);
|
|
102
|
-
return createRemoteAppComponent(info);
|
|
103
|
-
}
|