@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.
- package/CHANGELOG.md +728 -0
- package/LICENSE +21 -0
- package/README.md +131 -0
- package/__tests__/bridge.spec.tsx +160 -0
- package/__tests__/createLazyComponent.spec.tsx +209 -0
- package/__tests__/prefetch.spec.ts +156 -0
- package/__tests__/router.spec.tsx +82 -0
- package/__tests__/setupTests.ts +8 -0
- package/__tests__/util.ts +36 -0
- 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-CPSTBjEp.mjs +211 -0
- package/dist/bridge-base-RStDxH71.js +226 -0
- package/dist/createHelpers-B_L612IN.js +190 -0
- package/dist/createHelpers-Ui5pt7je.mjs +191 -0
- package/dist/data-fetch-server-middleware.cjs.js +163 -0
- package/dist/data-fetch-server-middleware.d.ts +15 -0
- package/dist/data-fetch-server-middleware.es.js +164 -0
- package/dist/data-fetch-utils.cjs.js +24 -0
- package/dist/data-fetch-utils.d.ts +81 -0
- package/dist/data-fetch-utils.es.js +26 -0
- package/dist/index-DRSBaSu3.js +45 -0
- package/dist/index-DyQNwY2M.mjs +46 -0
- package/dist/index.cjs.js +125 -0
- package/dist/index.d.ts +299 -0
- package/dist/index.es.js +109 -0
- package/dist/index.esm-BWaKho-8.js +491 -0
- package/dist/index.esm-CPwSeCvw.mjs +492 -0
- package/dist/lazy-load-component-plugin-CSRkMmKF.js +521 -0
- package/dist/lazy-load-component-plugin-DXqhuywC.mjs +522 -0
- package/dist/lazy-load-component-plugin.cjs.js +6 -0
- package/dist/lazy-load-component-plugin.d.ts +16 -0
- package/dist/lazy-load-component-plugin.es.js +6 -0
- package/dist/lazy-utils.cjs.js +24 -0
- package/dist/lazy-utils.d.ts +149 -0
- package/dist/lazy-utils.es.js +24 -0
- package/dist/plugin.cjs.js +14 -0
- package/dist/plugin.d.ts +22 -0
- package/dist/plugin.es.js +14 -0
- package/dist/prefetch-A3QkU5oZ.js +1272 -0
- package/dist/prefetch-zMJL79zx.mjs +1273 -0
- package/dist/router-v5.cjs.js +55 -0
- package/dist/router-v5.d.ts +18 -0
- package/dist/router-v5.es.js +32 -0
- package/dist/router-v6.cjs.js +84 -0
- package/dist/router-v6.d.ts +20 -0
- package/dist/router-v6.es.js +61 -0
- 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 +82 -0
- package/dist/router.d.ts +20 -0
- package/dist/router.es.js +60 -0
- package/dist/utils-dUgb9Jkm.mjs +2016 -0
- package/dist/utils-tM9yE73c.js +2015 -0
- package/dist/v18.cjs.js +15 -0
- package/dist/v18.d.ts +114 -0
- package/dist/v18.es.js +15 -0
- package/dist/v19.cjs.js +15 -0
- package/dist/v19.d.ts +115 -0
- package/dist/v19.es.js +15 -0
- package/jest.config.ts +21 -0
- package/package.json +173 -0
- package/project.json +23 -0
- package/src/base.ts +50 -0
- package/src/index.ts +50 -0
- package/src/lazy/AwaitDataFetch.tsx +215 -0
- package/src/lazy/constant.ts +30 -0
- package/src/lazy/createLazyComponent.tsx +411 -0
- package/src/lazy/data-fetch/cache.ts +291 -0
- package/src/lazy/data-fetch/call-data-fetch.ts +13 -0
- package/src/lazy/data-fetch/data-fetch-server-middleware.ts +196 -0
- package/src/lazy/data-fetch/index.ts +16 -0
- package/src/lazy/data-fetch/inject-data-fetch.ts +109 -0
- package/src/lazy/data-fetch/prefetch.ts +112 -0
- package/src/lazy/data-fetch/runtime-plugin.ts +115 -0
- package/src/lazy/index.ts +35 -0
- package/src/lazy/logger.ts +6 -0
- package/src/lazy/types.ts +75 -0
- package/src/lazy/utils.ts +372 -0
- package/src/lazy/wrapNoSSR.tsx +10 -0
- package/src/modern-app-env.d.ts +2 -0
- package/src/plugins/lazy-load-component-plugin.spec.ts +21 -0
- package/src/plugins/lazy-load-component-plugin.ts +57 -0
- package/src/provider/context.tsx +4 -0
- package/src/provider/plugin.ts +22 -0
- package/src/provider/versions/bridge-base.tsx +150 -0
- package/src/provider/versions/legacy.ts +87 -0
- package/src/provider/versions/v18.ts +47 -0
- package/src/provider/versions/v19.ts +48 -0
- 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/router-component/component.tsx +104 -0
- package/src/remote/router-component/create.tsx +23 -0
- package/src/remote/router-component/index.tsx +10 -0
- package/src/router/default.tsx +73 -0
- package/src/router/v5.tsx +43 -0
- package/src/router/v6.tsx +74 -0
- package/src/router/v7.tsx +75 -0
- package/src/types.ts +147 -0
- package/src/utils/index.ts +44 -0
- package/src/v18.ts +9 -0
- package/src/v19.ts +9 -0
- package/tsconfig.json +42 -0
- package/tsconfig.node.json +11 -0
- package/tsconfig.spec.json +26 -0
- package/vite.config.ts +112 -0
- package/vitest.config.ts +27 -0
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import React, { useContext, useEffect, useState, forwardRef } from 'react';
|
|
2
|
+
import * as ReactRouterDOM from 'react-router-dom';
|
|
3
|
+
import { dispatchPopstateEnv } from '@module-federation/bridge-shared';
|
|
4
|
+
import { LoggerInstance, pathJoin } from '../../utils';
|
|
5
|
+
import { RemoteAppWrapper } from '../RemoteAppWrapper';
|
|
6
|
+
|
|
7
|
+
interface ExtraDataProps {
|
|
8
|
+
basename?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function withRouterData<
|
|
12
|
+
P extends Parameters<typeof RemoteAppWrapper>[0],
|
|
13
|
+
>(
|
|
14
|
+
WrappedComponent: React.ComponentType<P & ExtraDataProps>,
|
|
15
|
+
): React.FC<Omit<P, keyof ExtraDataProps>> {
|
|
16
|
+
const Component = forwardRef(function (props: any, ref) {
|
|
17
|
+
if (props?.basename) {
|
|
18
|
+
return (
|
|
19
|
+
<WrappedComponent {...props} basename={props.basename} ref={ref} />
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
let enableDispathPopstate = false;
|
|
23
|
+
let routerContextVal: any;
|
|
24
|
+
try {
|
|
25
|
+
ReactRouterDOM.useLocation();
|
|
26
|
+
enableDispathPopstate = true;
|
|
27
|
+
} catch {
|
|
28
|
+
enableDispathPopstate = false;
|
|
29
|
+
}
|
|
30
|
+
let basename = '/';
|
|
31
|
+
|
|
32
|
+
if (!props.basename && enableDispathPopstate) {
|
|
33
|
+
const ReactRouterDOMAny: any = ReactRouterDOM;
|
|
34
|
+
// Avoid building tools checking references
|
|
35
|
+
const useRouteMatch = ReactRouterDOMAny['use' + 'RouteMatch']; //v5
|
|
36
|
+
const useHistory = ReactRouterDOMAny['use' + 'History']; //v5
|
|
37
|
+
const useHref = ReactRouterDOMAny['use' + 'Href'];
|
|
38
|
+
const UNSAFE_RouteContext = ReactRouterDOMAny['UNSAFE_' + 'RouteContext'];
|
|
39
|
+
|
|
40
|
+
if (UNSAFE_RouteContext /* react-router@6 */) {
|
|
41
|
+
if (useHref) {
|
|
42
|
+
basename = useHref?.('/');
|
|
43
|
+
}
|
|
44
|
+
routerContextVal = useContext(UNSAFE_RouteContext);
|
|
45
|
+
if (
|
|
46
|
+
routerContextVal &&
|
|
47
|
+
routerContextVal.matches &&
|
|
48
|
+
routerContextVal.matches.length > 0
|
|
49
|
+
) {
|
|
50
|
+
const matchIndex = routerContextVal.matches.length - 1;
|
|
51
|
+
const pathnameBase =
|
|
52
|
+
routerContextVal.matches[matchIndex].pathnameBase;
|
|
53
|
+
basename = pathJoin(basename, pathnameBase || '/');
|
|
54
|
+
}
|
|
55
|
+
} /* react-router@5 */ else {
|
|
56
|
+
const match = useRouteMatch?.(); // v5
|
|
57
|
+
if (useHistory /* react-router@5 */) {
|
|
58
|
+
// there is no dynamic switching of the router version in the project
|
|
59
|
+
// so hooks can be used in conditional judgment
|
|
60
|
+
const history = useHistory?.();
|
|
61
|
+
// To be compatible to history@4.10.1 and @5.3.0 we cannot write like this `history.createHref(pathname)`
|
|
62
|
+
basename = history?.createHref?.({ pathname: '/' });
|
|
63
|
+
}
|
|
64
|
+
if (match /* react-router@5 */) {
|
|
65
|
+
basename = pathJoin(basename, match?.path || '/');
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
LoggerInstance.debug(`createRemoteAppComponent withRouterData >>>`, {
|
|
71
|
+
...props,
|
|
72
|
+
basename,
|
|
73
|
+
routerContextVal,
|
|
74
|
+
enableDispathPopstate,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
if (enableDispathPopstate) {
|
|
78
|
+
const location = ReactRouterDOM.useLocation();
|
|
79
|
+
const [pathname, setPathname] = useState(location.pathname);
|
|
80
|
+
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
if (pathname !== '' && pathname !== location.pathname) {
|
|
83
|
+
LoggerInstance.debug(
|
|
84
|
+
`createRemoteAppComponent dispatchPopstateEnv >>>`,
|
|
85
|
+
{
|
|
86
|
+
name: props.name,
|
|
87
|
+
pathname: location.pathname,
|
|
88
|
+
},
|
|
89
|
+
);
|
|
90
|
+
dispatchPopstateEnv();
|
|
91
|
+
}
|
|
92
|
+
setPathname(location.pathname);
|
|
93
|
+
}, [location]);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return <WrappedComponent {...(props as P)} basename={basename} ref={ref} />;
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
return forwardRef(function (props, ref) {
|
|
100
|
+
return <Component {...props} ref={ref} />;
|
|
101
|
+
}) as any;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export default withRouterData(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,73 @@
|
|
|
1
|
+
import React, { useContext } from 'react';
|
|
2
|
+
// The upper alias react-router-dom$ into this file avoids the loop
|
|
3
|
+
import * as ReactRouterDom from 'react-router-dom/';
|
|
4
|
+
import { RouterContext } from '../provider/context';
|
|
5
|
+
import { LoggerInstance } from '../utils';
|
|
6
|
+
|
|
7
|
+
function WrapperRouter(
|
|
8
|
+
props:
|
|
9
|
+
| Parameters<typeof ReactRouterDom.BrowserRouter>[0]
|
|
10
|
+
| Parameters<typeof ReactRouterDom.MemoryRouter>[0],
|
|
11
|
+
) {
|
|
12
|
+
const { basename, ...propsRes } = props;
|
|
13
|
+
const routerContextProps = useContext(RouterContext) || {};
|
|
14
|
+
|
|
15
|
+
LoggerInstance.debug(`WrapperRouter info >>>`, {
|
|
16
|
+
...routerContextProps,
|
|
17
|
+
routerContextProps,
|
|
18
|
+
WrapperRouterProps: props,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
if (routerContextProps?.memoryRoute) {
|
|
22
|
+
return (
|
|
23
|
+
<ReactRouterDom.MemoryRouter
|
|
24
|
+
{...props}
|
|
25
|
+
initialEntries={[routerContextProps?.memoryRoute.entryPath]}
|
|
26
|
+
/>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
return (
|
|
30
|
+
<ReactRouterDom.BrowserRouter
|
|
31
|
+
{...propsRes}
|
|
32
|
+
basename={routerContextProps?.basename || basename}
|
|
33
|
+
/>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function WrapperRouterProvider(
|
|
38
|
+
props: Parameters<typeof ReactRouterDom.RouterProvider>[0],
|
|
39
|
+
) {
|
|
40
|
+
const { router, ...propsRes } = props;
|
|
41
|
+
const routerContextProps = useContext(RouterContext) || {};
|
|
42
|
+
const routers = router.routes;
|
|
43
|
+
LoggerInstance.debug(`WrapperRouterProvider info >>>`, {
|
|
44
|
+
...routerContextProps,
|
|
45
|
+
routerContextProps,
|
|
46
|
+
WrapperRouterProviderProps: props,
|
|
47
|
+
router,
|
|
48
|
+
});
|
|
49
|
+
const RouterProvider = (ReactRouterDom as any)['Router' + 'Provider'];
|
|
50
|
+
const createMemoryRouter = (ReactRouterDom as any)['create' + 'MemoryRouter'];
|
|
51
|
+
const createBrowserRouter = (ReactRouterDom as any)[
|
|
52
|
+
'create' + 'BrowserRouter'
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
if (routerContextProps.memoryRoute) {
|
|
56
|
+
const MemeoryRouterInstance = createMemoryRouter(routers, {
|
|
57
|
+
initialEntries: [routerContextProps?.memoryRoute.entryPath],
|
|
58
|
+
});
|
|
59
|
+
return <RouterProvider router={MemeoryRouterInstance} />;
|
|
60
|
+
} else {
|
|
61
|
+
const BrowserRouterInstance = createBrowserRouter(routers, {
|
|
62
|
+
basename: routerContextProps.basename || router?.basename,
|
|
63
|
+
future: router.future,
|
|
64
|
+
window: router.window,
|
|
65
|
+
});
|
|
66
|
+
return <RouterProvider {...propsRes} router={BrowserRouterInstance} />;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export * from 'react-router-dom/';
|
|
71
|
+
|
|
72
|
+
export { WrapperRouter as BrowserRouter };
|
|
73
|
+
export { WrapperRouterProvider as RouterProvider };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React, { useContext } from 'react';
|
|
2
|
+
// The upper alias react-router-dom$ into this file avoids the loop
|
|
3
|
+
// @ts-ignore
|
|
4
|
+
import * as ReactRouterDom from 'react-router-dom/index.js';
|
|
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
|
+
// @ts-ignore
|
|
39
|
+
// because export directly from react-router-dom/index.js will cause build falied.
|
|
40
|
+
// it will be replace by react-router-dom/index.js in building phase
|
|
41
|
+
export * from 'react-router-dom/';
|
|
42
|
+
|
|
43
|
+
export { WraperRouter as BrowserRouter };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import React, { useContext } from 'react';
|
|
2
|
+
// The upper alias react-router-dom$ into this file avoids the loop
|
|
3
|
+
import * as ReactRouterDom from 'react-router-dom/dist/index.js';
|
|
4
|
+
import { RouterContext } from '../provider/context';
|
|
5
|
+
import { LoggerInstance } from '../utils';
|
|
6
|
+
|
|
7
|
+
function WraperRouter(
|
|
8
|
+
props:
|
|
9
|
+
| Parameters<typeof ReactRouterDom.BrowserRouter>[0]
|
|
10
|
+
| Parameters<typeof ReactRouterDom.MemoryRouter>[0],
|
|
11
|
+
) {
|
|
12
|
+
const { basename, ...propsRes } = props;
|
|
13
|
+
const routerContextProps = useContext(RouterContext) || {};
|
|
14
|
+
|
|
15
|
+
LoggerInstance.debug(`WraperRouter info >>>`, {
|
|
16
|
+
...routerContextProps,
|
|
17
|
+
routerContextProps,
|
|
18
|
+
WraperRouterProps: props,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
if (routerContextProps?.memoryRoute) {
|
|
22
|
+
return (
|
|
23
|
+
<ReactRouterDom.MemoryRouter
|
|
24
|
+
{...props}
|
|
25
|
+
initialEntries={[routerContextProps?.memoryRoute.entryPath]}
|
|
26
|
+
/>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
return (
|
|
30
|
+
<ReactRouterDom.BrowserRouter
|
|
31
|
+
{...propsRes}
|
|
32
|
+
basename={routerContextProps?.basename || basename}
|
|
33
|
+
/>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function WraperRouterProvider(
|
|
38
|
+
props: Parameters<typeof ReactRouterDom.RouterProvider>[0],
|
|
39
|
+
) {
|
|
40
|
+
const { router, ...propsRes } = props;
|
|
41
|
+
const routerContextProps = useContext(RouterContext) || {};
|
|
42
|
+
const routers = router.routes;
|
|
43
|
+
LoggerInstance.debug(`WraperRouterProvider info >>>`, {
|
|
44
|
+
...routerContextProps,
|
|
45
|
+
routerContextProps,
|
|
46
|
+
WraperRouterProviderProps: props,
|
|
47
|
+
router,
|
|
48
|
+
});
|
|
49
|
+
const RouterProvider = (ReactRouterDom as any)['Router' + 'Provider'];
|
|
50
|
+
const createMemoryRouter = (ReactRouterDom as any)['create' + 'MemoryRouter'];
|
|
51
|
+
const createBrowserRouter = (ReactRouterDom as any)[
|
|
52
|
+
'create' + 'BrowserRouter'
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
if (routerContextProps.memoryRoute) {
|
|
56
|
+
const MemeoryRouterInstance = createMemoryRouter(routers, {
|
|
57
|
+
initialEntries: [routerContextProps?.memoryRoute.entryPath],
|
|
58
|
+
});
|
|
59
|
+
return <RouterProvider router={MemeoryRouterInstance} />;
|
|
60
|
+
} else {
|
|
61
|
+
const BrowserRouterInstance = createBrowserRouter(routers, {
|
|
62
|
+
// In host app, the routerContextProps is {}, so we should use router.basename as fallback
|
|
63
|
+
basename: routerContextProps.basename || router.basename,
|
|
64
|
+
future: router.future,
|
|
65
|
+
window: router.window,
|
|
66
|
+
});
|
|
67
|
+
return <RouterProvider {...propsRes} router={BrowserRouterInstance} />;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// export * from 'react-router-dom/dist/index.js';
|
|
72
|
+
export * from 'react-router-dom/';
|
|
73
|
+
export { WraperRouter as BrowserRouter };
|
|
74
|
+
export { WraperRouterProvider as RouterProvider };
|
|
@@ -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/src/types.ts
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ErrorBoundaryPropsWithComponent } from 'react-error-boundary';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Options for creating a React root
|
|
6
|
+
*/
|
|
7
|
+
export interface CreateRootOptions {
|
|
8
|
+
identifierPrefix?: string;
|
|
9
|
+
onRecoverableError?: (error: unknown) => void;
|
|
10
|
+
transitionCallbacks?: unknown;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Interface for a React root object
|
|
15
|
+
*/
|
|
16
|
+
export interface Root {
|
|
17
|
+
render(children: React.ReactNode): void;
|
|
18
|
+
unmount(): void;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Type for a root element, which can be either an HTMLElement or a React root
|
|
23
|
+
*/
|
|
24
|
+
export type RootType = HTMLElement | Root;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Parameters for the render function
|
|
28
|
+
*/
|
|
29
|
+
export interface RenderParams {
|
|
30
|
+
moduleName?: string;
|
|
31
|
+
basename?: string;
|
|
32
|
+
memoryRoute?: {
|
|
33
|
+
entryPath: string;
|
|
34
|
+
initialState?: Record<string, unknown>;
|
|
35
|
+
};
|
|
36
|
+
dom: HTMLElement;
|
|
37
|
+
/**
|
|
38
|
+
* Options to pass to createRoot for React 18 and 19
|
|
39
|
+
* @example
|
|
40
|
+
* {
|
|
41
|
+
* identifierPrefix: 'app-',
|
|
42
|
+
* onRecoverableError: (err) => console.error(err)
|
|
43
|
+
* }
|
|
44
|
+
*/
|
|
45
|
+
rootOptions?: CreateRootOptions;
|
|
46
|
+
[key: string]: unknown;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Parameters for the destroy function
|
|
51
|
+
*/
|
|
52
|
+
export interface DestroyParams {
|
|
53
|
+
moduleName: string;
|
|
54
|
+
dom: HTMLElement;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Parameters for the provider function
|
|
59
|
+
*/
|
|
60
|
+
export interface ProviderParams {
|
|
61
|
+
moduleName?: string;
|
|
62
|
+
basename?: string;
|
|
63
|
+
memoryRoute?: {
|
|
64
|
+
entryPath: string;
|
|
65
|
+
initialState?: Record<string, unknown>;
|
|
66
|
+
};
|
|
67
|
+
style?: React.CSSProperties;
|
|
68
|
+
className?: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Parameters for the render function, extending ProviderParams
|
|
73
|
+
*/
|
|
74
|
+
export interface RenderFnParams extends ProviderParams {
|
|
75
|
+
dom: HTMLElement;
|
|
76
|
+
fallback?: React.ComponentType<{ error: Error }>;
|
|
77
|
+
[key: string]: unknown;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Parameters for the provider function
|
|
82
|
+
*/
|
|
83
|
+
export interface ProviderFnParams<T> {
|
|
84
|
+
rootComponent: React.ComponentType<T>;
|
|
85
|
+
render?: (
|
|
86
|
+
App: React.ReactElement,
|
|
87
|
+
id?: HTMLElement | string,
|
|
88
|
+
) => RootType | Promise<RootType>;
|
|
89
|
+
createRoot?: (
|
|
90
|
+
container: Element | DocumentFragment,
|
|
91
|
+
options?: CreateRootOptions,
|
|
92
|
+
) => Root;
|
|
93
|
+
/**
|
|
94
|
+
* Default options to pass to createRoot for React 18 and 19
|
|
95
|
+
* These options will be used when creating a root unless overridden by rootOptions in render params
|
|
96
|
+
* @example
|
|
97
|
+
* {
|
|
98
|
+
* identifierPrefix: 'app-',
|
|
99
|
+
* onRecoverableError: (err) => console.error(err)
|
|
100
|
+
* }
|
|
101
|
+
*/
|
|
102
|
+
defaultRootOptions?: CreateRootOptions;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Parameters for the remote component
|
|
107
|
+
*/
|
|
108
|
+
export interface RemoteComponentProps<T = Record<string, unknown>> {
|
|
109
|
+
props?: T;
|
|
110
|
+
fallback?: React.ComponentType<{ error: Error }>;
|
|
111
|
+
loading?: React.ReactNode;
|
|
112
|
+
[key: string]: unknown;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Parameters for the remote component loader
|
|
117
|
+
*/
|
|
118
|
+
export interface RemoteComponentParams<
|
|
119
|
+
T = Record<string, unknown>,
|
|
120
|
+
E extends keyof T = keyof T,
|
|
121
|
+
> {
|
|
122
|
+
loader: () => Promise<T>;
|
|
123
|
+
loading: React.ReactNode;
|
|
124
|
+
fallback: React.ComponentType<{ error: Error }>;
|
|
125
|
+
export?: E;
|
|
126
|
+
props?: T;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Interface for a remote module provider
|
|
131
|
+
*/
|
|
132
|
+
export interface RemoteModule {
|
|
133
|
+
provider: () => {
|
|
134
|
+
render: (info: RenderFnParams) => void;
|
|
135
|
+
destroy: (info: { dom: any }) => void;
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Parameters for a remote app component
|
|
141
|
+
*/
|
|
142
|
+
export interface RemoteAppParams extends ProviderParams {
|
|
143
|
+
moduleName: string;
|
|
144
|
+
providerInfo: NonNullable<RemoteModule['provider']>;
|
|
145
|
+
exportName: string | number | symbol;
|
|
146
|
+
fallback: ErrorBoundaryPropsWithComponent['FallbackComponent'];
|
|
147
|
+
}
|