@module-federation/bridge-react 0.4.0 → 0.5.1
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 +14 -0
- package/__tests__/bridge.spec.tsx +37 -3
- package/dist/index.cjs.js +126 -92
- package/dist/index.d.ts +10 -7
- package/dist/index.es.js +128 -94
- package/dist/router-v5.cjs.js +56 -0
- package/dist/router-v5.d.ts +9 -0
- package/dist/router-v5.es.js +32 -0
- package/dist/router-v6.cjs.js +83 -0
- package/dist/router-v6.d.ts +11 -0
- package/dist/router-v6.es.js +60 -0
- package/dist/router.cjs.js +8 -12
- package/dist/router.es.js +8 -12
- package/package.json +12 -2
- package/src/create.tsx +21 -25
- package/src/provider.tsx +50 -33
- package/src/remote/index.tsx +93 -56
- package/src/router-v5.tsx +44 -0
- package/src/router-v6.tsx +73 -0
- package/src/router.tsx +8 -10
- package/vite.config.ts +29 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@module-federation/bridge-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -20,12 +20,22 @@
|
|
|
20
20
|
"import": "./dist/router.es.js",
|
|
21
21
|
"require": "./dist/router.cjs.js"
|
|
22
22
|
},
|
|
23
|
+
"./router-v5": {
|
|
24
|
+
"types": "./dist/router-v5.d.ts",
|
|
25
|
+
"import": "./dist/router-v5.es.js",
|
|
26
|
+
"require": "./dist/router-v5.cjs.js"
|
|
27
|
+
},
|
|
28
|
+
"./router-v6": {
|
|
29
|
+
"types": "./dist/router-v6.d.ts",
|
|
30
|
+
"import": "./dist/router-v6.es.js",
|
|
31
|
+
"require": "./dist/router-v6.cjs.js"
|
|
32
|
+
},
|
|
23
33
|
"./*": "./*"
|
|
24
34
|
},
|
|
25
35
|
"dependencies": {
|
|
26
36
|
"@loadable/component": "^5.16.4",
|
|
27
37
|
"react-error-boundary": "^4.0.13",
|
|
28
|
-
"@module-federation/bridge-shared": "0.
|
|
38
|
+
"@module-federation/bridge-shared": "0.5.1"
|
|
29
39
|
},
|
|
30
40
|
"peerDependencies": {
|
|
31
41
|
"react": ">=16.9.0",
|
package/src/create.tsx
CHANGED
|
@@ -13,11 +13,7 @@ export interface RenderFnParams extends ProviderParams {
|
|
|
13
13
|
|
|
14
14
|
interface RemoteModule {
|
|
15
15
|
provider: () => {
|
|
16
|
-
render: (
|
|
17
|
-
info: ProviderParams & {
|
|
18
|
-
dom: any;
|
|
19
|
-
},
|
|
20
|
-
) => void;
|
|
16
|
+
render: (info: RenderFnParams) => void;
|
|
21
17
|
destroy: (info: { dom: any }) => void;
|
|
22
18
|
};
|
|
23
19
|
}
|
|
@@ -34,6 +30,7 @@ function createLazyRemoteComponent<T, E extends keyof T>(info: {
|
|
|
34
30
|
lazyComponent: info.loader,
|
|
35
31
|
exportName,
|
|
36
32
|
});
|
|
33
|
+
|
|
37
34
|
try {
|
|
38
35
|
const m = (await info.loader()) as RemoteModule;
|
|
39
36
|
// @ts-ignore
|
|
@@ -44,8 +41,7 @@ function createLazyRemoteComponent<T, E extends keyof T>(info: {
|
|
|
44
41
|
);
|
|
45
42
|
|
|
46
43
|
// @ts-ignore
|
|
47
|
-
const exportFn = m[exportName]
|
|
48
|
-
|
|
44
|
+
const exportFn = m[exportName];
|
|
49
45
|
if (exportName in m && typeof exportFn === 'function') {
|
|
50
46
|
const RemoteAppComponent = forwardRef<
|
|
51
47
|
HTMLDivElement,
|
|
@@ -53,12 +49,15 @@ function createLazyRemoteComponent<T, E extends keyof T>(info: {
|
|
|
53
49
|
basename?: ProviderParams['basename'];
|
|
54
50
|
memoryRoute?: ProviderParams['memoryRoute'];
|
|
55
51
|
}
|
|
56
|
-
>((props,
|
|
52
|
+
>((props, ref) => {
|
|
57
53
|
return (
|
|
58
54
|
<RemoteApp
|
|
59
|
-
name
|
|
55
|
+
// change `name` key to `moduleName` to avoid same property `name` passed by user's props which may cause unexpected issues.
|
|
56
|
+
moduleName={moduleName}
|
|
60
57
|
providerInfo={exportFn}
|
|
61
58
|
exportName={info.export || 'default'}
|
|
59
|
+
fallback={info.fallback}
|
|
60
|
+
ref={ref}
|
|
62
61
|
{...props}
|
|
63
62
|
/>
|
|
64
63
|
);
|
|
@@ -93,26 +92,23 @@ export function createRemoteComponent<T, E extends keyof T>(info: {
|
|
|
93
92
|
type ExportType = T[E] extends (...args: any) => any
|
|
94
93
|
? ReturnType<T[E]>
|
|
95
94
|
: never;
|
|
95
|
+
|
|
96
96
|
type RawComponentType = '__BRIDGE_FN__' extends keyof ExportType
|
|
97
97
|
? ExportType['__BRIDGE_FN__'] extends (...args: any) => any
|
|
98
98
|
? Parameters<ExportType['__BRIDGE_FN__']>[0]
|
|
99
99
|
: {}
|
|
100
100
|
: {};
|
|
101
101
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
</React.Suspense>
|
|
115
|
-
</ErrorBoundary>
|
|
116
|
-
);
|
|
117
|
-
};
|
|
102
|
+
return forwardRef<HTMLDivElement, ProviderParams & RawComponentType>(
|
|
103
|
+
(props, ref) => {
|
|
104
|
+
const LazyComponent = createLazyRemoteComponent(info);
|
|
105
|
+
return (
|
|
106
|
+
<ErrorBoundary FallbackComponent={info.fallback}>
|
|
107
|
+
<React.Suspense fallback={info.loading}>
|
|
108
|
+
<LazyComponent {...props} ref={ref} />
|
|
109
|
+
</React.Suspense>
|
|
110
|
+
</ErrorBoundary>
|
|
111
|
+
);
|
|
112
|
+
},
|
|
113
|
+
);
|
|
118
114
|
}
|
package/src/provider.tsx
CHANGED
|
@@ -8,65 +8,84 @@ import type {
|
|
|
8
8
|
RenderFnParams,
|
|
9
9
|
} from '@module-federation/bridge-shared';
|
|
10
10
|
import { LoggerInstance, atLeastReact18 } from './utils';
|
|
11
|
+
import { ErrorBoundary } from 'react-error-boundary';
|
|
11
12
|
|
|
13
|
+
type RootType = HTMLElement | ReactDOMClient.Root;
|
|
12
14
|
type ProviderFnParams<T> = {
|
|
13
15
|
rootComponent: React.ComponentType<T>;
|
|
16
|
+
render?: (
|
|
17
|
+
App: React.ReactElement,
|
|
18
|
+
id?: HTMLElement | string,
|
|
19
|
+
) => RootType | Promise<RootType>;
|
|
14
20
|
};
|
|
15
21
|
|
|
16
22
|
export function createBridgeComponent<T>(bridgeInfo: ProviderFnParams<T>) {
|
|
17
23
|
return () => {
|
|
18
|
-
const rootMap = new Map<any,
|
|
19
|
-
|
|
24
|
+
const rootMap = new Map<any, RootType>();
|
|
20
25
|
const RawComponent = (info: { propsInfo: T; appInfo: ProviderParams }) => {
|
|
21
|
-
const { appInfo, propsInfo } = info;
|
|
22
|
-
const {
|
|
23
|
-
|
|
26
|
+
const { appInfo, propsInfo, ...restProps } = info;
|
|
27
|
+
const { moduleName, memoryRoute, basename = '/' } = appInfo;
|
|
24
28
|
return (
|
|
25
|
-
<RouterContext.Provider value={{
|
|
26
|
-
<bridgeInfo.rootComponent
|
|
29
|
+
<RouterContext.Provider value={{ moduleName, basename, memoryRoute }}>
|
|
30
|
+
<bridgeInfo.rootComponent
|
|
31
|
+
{...propsInfo}
|
|
32
|
+
basename={basename}
|
|
33
|
+
{...restProps}
|
|
34
|
+
/>
|
|
27
35
|
</RouterContext.Provider>
|
|
28
36
|
);
|
|
29
37
|
};
|
|
30
38
|
|
|
31
39
|
return {
|
|
32
|
-
render(info: RenderFnParams & any) {
|
|
40
|
+
async render(info: RenderFnParams & any) {
|
|
33
41
|
LoggerInstance.log(`createBridgeComponent render Info`, info);
|
|
34
|
-
const {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
42
|
+
const {
|
|
43
|
+
moduleName,
|
|
44
|
+
dom,
|
|
45
|
+
basename,
|
|
46
|
+
memoryRoute,
|
|
47
|
+
fallback,
|
|
48
|
+
...propsInfo
|
|
49
|
+
} = info;
|
|
50
|
+
const rootComponentWithErrorBoundary = (
|
|
51
|
+
// set ErrorBoundary for RawComponent rendering error, usually caused by user app rendering error
|
|
52
|
+
<ErrorBoundary FallbackComponent={fallback}>
|
|
40
53
|
<RawComponent
|
|
41
|
-
propsInfo={propsInfo}
|
|
42
54
|
appInfo={{
|
|
43
|
-
|
|
55
|
+
moduleName,
|
|
44
56
|
basename,
|
|
45
57
|
memoryRoute,
|
|
46
58
|
}}
|
|
47
|
-
/>,
|
|
48
|
-
);
|
|
49
|
-
} else {
|
|
50
|
-
ReactDOM.render(
|
|
51
|
-
<RawComponent
|
|
52
59
|
propsInfo={propsInfo}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
/>
|
|
61
|
+
</ErrorBoundary>
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
if (atLeastReact18(React)) {
|
|
65
|
+
if (bridgeInfo?.render) {
|
|
66
|
+
// in case bridgeInfo?.render is an async function, resolve this to promise
|
|
67
|
+
Promise.resolve(
|
|
68
|
+
bridgeInfo?.render(rootComponentWithErrorBoundary, dom),
|
|
69
|
+
).then((root: RootType) => rootMap.set(info.dom, root));
|
|
70
|
+
} else {
|
|
71
|
+
const root: RootType = ReactDOMClient.createRoot(info.dom);
|
|
72
|
+
root.render(rootComponentWithErrorBoundary);
|
|
73
|
+
rootMap.set(info.dom, root);
|
|
74
|
+
}
|
|
75
|
+
} else {
|
|
76
|
+
// react 17 render
|
|
77
|
+
const renderFn = bridgeInfo?.render || ReactDOM.render;
|
|
78
|
+
renderFn?.(rootComponentWithErrorBoundary, info.dom);
|
|
61
79
|
}
|
|
62
80
|
},
|
|
63
|
-
destroy(info: { dom: HTMLElement }) {
|
|
81
|
+
async destroy(info: { dom: HTMLElement }) {
|
|
64
82
|
LoggerInstance.log(`createBridgeComponent destroy Info`, {
|
|
65
83
|
dom: info.dom,
|
|
66
84
|
});
|
|
67
85
|
if (atLeastReact18(React)) {
|
|
68
86
|
const root = rootMap.get(info.dom);
|
|
69
|
-
root?.unmount();
|
|
87
|
+
(root as ReactDOMClient.Root)?.unmount();
|
|
88
|
+
rootMap.delete(info.dom);
|
|
70
89
|
} else {
|
|
71
90
|
ReactDOM.unmountComponentAtNode(info.dom);
|
|
72
91
|
}
|
|
@@ -84,5 +103,3 @@ export function ShadowRoot(info: { children: () => JSX.Element }) {
|
|
|
84
103
|
|
|
85
104
|
return <div ref={domRef}>{root && <info.children />}</div>;
|
|
86
105
|
}
|
|
87
|
-
|
|
88
|
-
// function ShadowContent() {}
|
package/src/remote/index.tsx
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {
|
|
2
|
+
useContext,
|
|
3
|
+
useEffect,
|
|
4
|
+
useRef,
|
|
5
|
+
useState,
|
|
6
|
+
forwardRef,
|
|
7
|
+
} from 'react';
|
|
2
8
|
import * as ReactRouterDOM from 'react-router-dom';
|
|
3
9
|
import type { ProviderParams } from '@module-federation/bridge-shared';
|
|
4
10
|
import { LoggerInstance, pathJoin } from '../utils';
|
|
5
11
|
import { dispatchPopstateEnv } from '@module-federation/bridge-shared';
|
|
12
|
+
import { ErrorBoundaryPropsWithComponent } from 'react-error-boundary';
|
|
6
13
|
|
|
7
14
|
declare const __APP_VERSION__: string;
|
|
8
|
-
|
|
9
15
|
export interface RenderFnParams extends ProviderParams {
|
|
10
16
|
dom?: any;
|
|
17
|
+
fallback: ErrorBoundaryPropsWithComponent['FallbackComponent'];
|
|
11
18
|
}
|
|
12
19
|
|
|
13
20
|
interface RemoteModule {
|
|
@@ -22,71 +29,97 @@ interface RemoteModule {
|
|
|
22
29
|
}
|
|
23
30
|
|
|
24
31
|
interface RemoteAppParams {
|
|
25
|
-
|
|
32
|
+
moduleName: string;
|
|
26
33
|
providerInfo: NonNullable<RemoteModule['provider']>;
|
|
27
34
|
exportName: string | number | symbol;
|
|
35
|
+
fallback: ErrorBoundaryPropsWithComponent['FallbackComponent'];
|
|
28
36
|
}
|
|
29
37
|
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
38
|
+
const RemoteAppWrapper = forwardRef(function (
|
|
39
|
+
props: RemoteAppParams & RenderFnParams,
|
|
40
|
+
ref,
|
|
41
|
+
) {
|
|
42
|
+
const RemoteApp = () => {
|
|
43
|
+
LoggerInstance.log(`RemoteAppWrapper RemoteApp props >>>`, { props });
|
|
44
|
+
const {
|
|
45
|
+
moduleName,
|
|
46
|
+
memoryRoute,
|
|
47
|
+
basename,
|
|
48
|
+
providerInfo,
|
|
49
|
+
className,
|
|
50
|
+
style,
|
|
51
|
+
fallback,
|
|
52
|
+
...resProps
|
|
53
|
+
} = props;
|
|
54
|
+
|
|
55
|
+
const rootRef: React.MutableRefObject<HTMLDivElement | null> =
|
|
56
|
+
ref && 'current' in ref
|
|
57
|
+
? (ref as React.MutableRefObject<HTMLDivElement | null>)
|
|
58
|
+
: useRef(null);
|
|
59
|
+
|
|
60
|
+
const renderDom: React.MutableRefObject<HTMLElement | null> = useRef(null);
|
|
61
|
+
const providerInfoRef = useRef<any>(null);
|
|
62
|
+
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
const renderTimeout = setTimeout(() => {
|
|
65
|
+
const providerReturn = providerInfo();
|
|
66
|
+
providerInfoRef.current = providerReturn;
|
|
67
|
+
|
|
68
|
+
const renderProps = {
|
|
69
|
+
moduleName,
|
|
70
|
+
dom: rootRef.current,
|
|
71
|
+
basename,
|
|
72
|
+
memoryRoute,
|
|
73
|
+
fallback,
|
|
74
|
+
...resProps,
|
|
75
|
+
};
|
|
76
|
+
renderDom.current = rootRef.current;
|
|
77
|
+
LoggerInstance.log(
|
|
78
|
+
`createRemoteComponent LazyComponent render >>>`,
|
|
79
|
+
renderProps,
|
|
80
|
+
);
|
|
81
|
+
providerReturn.render(renderProps);
|
|
72
82
|
});
|
|
73
|
-
};
|
|
74
|
-
}, []);
|
|
75
83
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
84
|
+
return () => {
|
|
85
|
+
clearTimeout(renderTimeout);
|
|
86
|
+
setTimeout(() => {
|
|
87
|
+
if (providerInfoRef.current?.destroy) {
|
|
88
|
+
LoggerInstance.log(
|
|
89
|
+
`createRemoteComponent LazyComponent destroy >>>`,
|
|
90
|
+
{ moduleName, basename, dom: renderDom.current },
|
|
91
|
+
);
|
|
92
|
+
providerInfoRef.current?.destroy({
|
|
93
|
+
dom: renderDom.current,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
};
|
|
98
|
+
}, []);
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
<div
|
|
102
|
+
className={props?.className}
|
|
103
|
+
style={props?.style}
|
|
104
|
+
ref={rootRef}
|
|
105
|
+
></div>
|
|
106
|
+
);
|
|
107
|
+
};
|
|
79
108
|
|
|
80
|
-
(RemoteApp as any)['__APP_VERSION__'] = __APP_VERSION__;
|
|
109
|
+
(RemoteApp as any)['__APP_VERSION__'] = __APP_VERSION__;
|
|
110
|
+
return <RemoteApp />;
|
|
111
|
+
});
|
|
81
112
|
|
|
82
113
|
interface ExtraDataProps {
|
|
83
114
|
basename?: string;
|
|
84
115
|
}
|
|
85
116
|
|
|
86
|
-
export function withRouterData<
|
|
117
|
+
export function withRouterData<
|
|
118
|
+
P extends Parameters<typeof RemoteAppWrapper>[0],
|
|
119
|
+
>(
|
|
87
120
|
WrappedComponent: React.ComponentType<P & ExtraDataProps>,
|
|
88
121
|
): React.FC<Omit<P, keyof ExtraDataProps>> {
|
|
89
|
-
|
|
122
|
+
const Component = forwardRef(function (props: any, ref) {
|
|
90
123
|
let enableDispathPopstate = false;
|
|
91
124
|
let routerContextVal: any;
|
|
92
125
|
try {
|
|
@@ -158,8 +191,12 @@ export function withRouterData<P extends Parameters<typeof RemoteApp>[0]>(
|
|
|
158
191
|
}, [location]);
|
|
159
192
|
}
|
|
160
193
|
|
|
161
|
-
return <WrappedComponent {...(props as P)} basename={basename} />;
|
|
162
|
-
};
|
|
194
|
+
return <WrappedComponent {...(props as P)} basename={basename} ref={ref} />;
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
return forwardRef(function (props, ref) {
|
|
198
|
+
return <Component {...props} ref={ref} />;
|
|
199
|
+
}) as any;
|
|
163
200
|
}
|
|
164
201
|
|
|
165
|
-
export default withRouterData(
|
|
202
|
+
export default withRouterData(RemoteAppWrapper);
|
|
@@ -0,0 +1,44 @@
|
|
|
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
|
+
|
|
6
|
+
import { RouterContext } from './context';
|
|
7
|
+
import { LoggerInstance } from './utils';
|
|
8
|
+
|
|
9
|
+
function WraperRouter(
|
|
10
|
+
props:
|
|
11
|
+
| Parameters<typeof ReactRouterDom.BrowserRouter>[0]
|
|
12
|
+
| Parameters<typeof ReactRouterDom.MemoryRouter>[0],
|
|
13
|
+
) {
|
|
14
|
+
const { basename, ...propsRes } = props;
|
|
15
|
+
const routerContextProps = useContext(RouterContext) || {};
|
|
16
|
+
|
|
17
|
+
LoggerInstance.log(`WraperRouter info >>>`, {
|
|
18
|
+
...routerContextProps,
|
|
19
|
+
routerContextProps,
|
|
20
|
+
WraperRouterProps: props,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
if (routerContextProps?.memoryRoute) {
|
|
24
|
+
return (
|
|
25
|
+
<ReactRouterDom.MemoryRouter
|
|
26
|
+
{...props}
|
|
27
|
+
initialEntries={[routerContextProps?.memoryRoute.entryPath]}
|
|
28
|
+
/>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
return (
|
|
32
|
+
<ReactRouterDom.BrowserRouter
|
|
33
|
+
{...propsRes}
|
|
34
|
+
basename={routerContextProps?.basename || basename}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// @ts-ignore
|
|
40
|
+
// cause export directly from react-router-dom/index.js will cause build falied.
|
|
41
|
+
// it will be replace by react-router-dom/index.js in building phase
|
|
42
|
+
export * from 'react-router-dom/';
|
|
43
|
+
|
|
44
|
+
export { WraperRouter as BrowserRouter };
|
|
@@ -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/dist/index.js';
|
|
4
|
+
|
|
5
|
+
import { RouterContext } from './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.log(`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.log(`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
|
+
basename: routerContextProps.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 { WraperRouter as BrowserRouter };
|
|
73
|
+
export { WraperRouterProvider as RouterProvider };
|
package/src/router.tsx
CHANGED
|
@@ -4,7 +4,7 @@ import * as ReactRouterDom from 'react-router-dom/';
|
|
|
4
4
|
import { RouterContext } from './context';
|
|
5
5
|
import { LoggerInstance } from './utils';
|
|
6
6
|
|
|
7
|
-
function
|
|
7
|
+
function WrapperRouter(
|
|
8
8
|
props:
|
|
9
9
|
| Parameters<typeof ReactRouterDom.BrowserRouter>[0]
|
|
10
10
|
| Parameters<typeof ReactRouterDom.MemoryRouter>[0],
|
|
@@ -12,12 +12,11 @@ function WraperRouter(
|
|
|
12
12
|
const { basename, ...propsRes } = props;
|
|
13
13
|
const routerContextProps = useContext(RouterContext) || {};
|
|
14
14
|
|
|
15
|
-
LoggerInstance.log(`
|
|
15
|
+
LoggerInstance.log(`WrapperRouter info >>>`, {
|
|
16
16
|
...routerContextProps,
|
|
17
17
|
routerContextProps,
|
|
18
|
-
|
|
18
|
+
WrapperRouterProps: props,
|
|
19
19
|
});
|
|
20
|
-
if (!routerContextProps) return <ReactRouterDom.BrowserRouter {...props} />;
|
|
21
20
|
|
|
22
21
|
if (routerContextProps?.memoryRoute) {
|
|
23
22
|
return (
|
|
@@ -35,16 +34,16 @@ function WraperRouter(
|
|
|
35
34
|
);
|
|
36
35
|
}
|
|
37
36
|
|
|
38
|
-
function
|
|
37
|
+
function WrapperRouterProvider(
|
|
39
38
|
props: Parameters<typeof ReactRouterDom.RouterProvider>[0],
|
|
40
39
|
) {
|
|
41
40
|
const { router, ...propsRes } = props;
|
|
42
41
|
const routerContextProps = useContext(RouterContext) || {};
|
|
43
42
|
const routers = router.routes;
|
|
44
|
-
LoggerInstance.log(`
|
|
43
|
+
LoggerInstance.log(`WrapperRouterProvider info >>>`, {
|
|
45
44
|
...routerContextProps,
|
|
46
45
|
routerContextProps,
|
|
47
|
-
|
|
46
|
+
WrapperRouterProviderProps: props,
|
|
48
47
|
router,
|
|
49
48
|
});
|
|
50
49
|
const RouterProvider = (ReactRouterDom as any)['Router' + 'Provider'];
|
|
@@ -52,7 +51,6 @@ function WraperRouterProvider(
|
|
|
52
51
|
const createBrowserRouter = (ReactRouterDom as any)[
|
|
53
52
|
'create' + 'BrowserRouter'
|
|
54
53
|
];
|
|
55
|
-
if (!routerContextProps) return <RouterProvider {...props} />;
|
|
56
54
|
|
|
57
55
|
if (routerContextProps.memoryRoute) {
|
|
58
56
|
const MemeoryRouterInstance = createMemoryRouter(routers, {
|
|
@@ -71,5 +69,5 @@ function WraperRouterProvider(
|
|
|
71
69
|
|
|
72
70
|
export * from 'react-router-dom/';
|
|
73
71
|
|
|
74
|
-
export {
|
|
75
|
-
export {
|
|
72
|
+
export { WrapperRouter as BrowserRouter };
|
|
73
|
+
export { WrapperRouterProvider as RouterProvider };
|
package/vite.config.ts
CHANGED
|
@@ -22,6 +22,8 @@ export default defineConfig({
|
|
|
22
22
|
entry: {
|
|
23
23
|
index: path.resolve(__dirname, 'src/index.ts'),
|
|
24
24
|
router: path.resolve(__dirname, 'src/router.tsx'),
|
|
25
|
+
'router-v5': path.resolve(__dirname, 'src/router-v5.tsx'),
|
|
26
|
+
'router-v6': path.resolve(__dirname, 'src/router-v6.tsx'),
|
|
25
27
|
},
|
|
26
28
|
formats: ['cjs', 'es'],
|
|
27
29
|
fileName: (format, entryName) => `${entryName}.${format}.js`,
|
|
@@ -32,6 +34,33 @@ export default defineConfig({
|
|
|
32
34
|
'@remix-run/router',
|
|
33
35
|
'react-router',
|
|
34
36
|
'react-router-dom/',
|
|
37
|
+
'react-router-dom/index.js',
|
|
38
|
+
'react-router-dom/dist/index.js',
|
|
39
|
+
],
|
|
40
|
+
plugins: [
|
|
41
|
+
{
|
|
42
|
+
name: 'modify-output-plugin',
|
|
43
|
+
generateBundle(options, bundle) {
|
|
44
|
+
for (const fileName in bundle) {
|
|
45
|
+
const chunk = bundle[fileName];
|
|
46
|
+
// if (fileName.includes('router-v6') && chunk.type === 'chunk') {
|
|
47
|
+
// chunk.code = chunk.code.replace(
|
|
48
|
+
// // Match 'react-router-dom/' followed by single quotes, double quotes, or backticks, replacing only 'react-router-dom/' to react-router-v6 dist file structure
|
|
49
|
+
// /react-router-dom\/(?=[\'\"\`])/g,
|
|
50
|
+
// 'react-router-dom/dist/index.js',
|
|
51
|
+
// );
|
|
52
|
+
// }
|
|
53
|
+
|
|
54
|
+
if (fileName.includes('router-v5') && chunk.type === 'chunk') {
|
|
55
|
+
chunk.code = chunk.code.replace(
|
|
56
|
+
// Match 'react-router-dom/' followed by single quotes, double quotes, or backticks, replacing only 'react-router-dom/' to react-router-v5 dist file structure
|
|
57
|
+
/react-router-dom\/(?=[\'\"\`])/g,
|
|
58
|
+
'react-router-dom/index.js',
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
},
|
|
35
64
|
],
|
|
36
65
|
},
|
|
37
66
|
minify: false,
|