@module-federation/bridge-react 0.0.0-next-20240619092117 → 0.0.0-next-20240620023927
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 +2 -2
- package/__tests__/bridge.spec.tsx +2 -1
- package/dist/{context-CoFgcMIF.js → context-CPtN38Ur.js} +15 -2
- package/dist/{context-C7FfFcIe.cjs → context-ePt4wynZ.cjs} +13 -0
- package/dist/index.cjs.js +77 -34
- package/dist/index.d.ts +3 -2
- package/dist/index.es.js +65 -38
- package/dist/router.cjs.js +1 -1
- package/dist/router.es.js +8 -8
- package/package.json +5 -5
- package/src/create.tsx +24 -13
- package/src/provider.tsx +39 -18
- package/src/utils.ts +20 -0
package/CHANGELOG.md
CHANGED
|
@@ -63,6 +63,7 @@ describe('bridge', () => {
|
|
|
63
63
|
expect(getHtml(container)).toMatch('loading');
|
|
64
64
|
|
|
65
65
|
await sleep(200);
|
|
66
|
-
expect(getHtml(container)).toMatch('life cycle render
|
|
66
|
+
expect(getHtml(container)).toMatch('life cycle render');
|
|
67
|
+
expect(getHtml(container)).toMatch('hello world');
|
|
67
68
|
});
|
|
68
69
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React__default from "react";
|
|
2
2
|
var a = Object.defineProperty;
|
|
3
3
|
var c = (s, e, t) => e in s ? a(s, e, { enumerable: true, configurable: true, writable: true, value: t }) : s[e] = t;
|
|
4
4
|
var i = (s, e, t) => (c(s, typeof e != "symbol" ? e + "" : e, t), t);
|
|
@@ -35,9 +35,22 @@ function f() {
|
|
|
35
35
|
window.dispatchEvent(s);
|
|
36
36
|
}
|
|
37
37
|
const LoggerInstance = new g("bridge-react");
|
|
38
|
-
|
|
38
|
+
function atLeastReact18(React2) {
|
|
39
|
+
if (React2 && typeof React2.version === "string" && React2.version.indexOf(".") >= 0) {
|
|
40
|
+
const majorVersionString = React2.version.split(".")[0];
|
|
41
|
+
try {
|
|
42
|
+
return Number(majorVersionString) >= 18;
|
|
43
|
+
} catch (err) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
} else {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const RouterContext = React__default.createContext(null);
|
|
39
51
|
export {
|
|
40
52
|
LoggerInstance as L,
|
|
41
53
|
RouterContext as R,
|
|
54
|
+
atLeastReact18 as a,
|
|
42
55
|
f
|
|
43
56
|
};
|
|
@@ -36,7 +36,20 @@ function f() {
|
|
|
36
36
|
window.dispatchEvent(s);
|
|
37
37
|
}
|
|
38
38
|
const LoggerInstance = new g("bridge-react");
|
|
39
|
+
function atLeastReact18(React2) {
|
|
40
|
+
if (React2 && typeof React2.version === "string" && React2.version.indexOf(".") >= 0) {
|
|
41
|
+
const majorVersionString = React2.version.split(".")[0];
|
|
42
|
+
try {
|
|
43
|
+
return Number(majorVersionString) >= 18;
|
|
44
|
+
} catch (err) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
} else {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
39
51
|
const RouterContext = React.createContext(null);
|
|
40
52
|
exports.LoggerInstance = LoggerInstance;
|
|
41
53
|
exports.RouterContext = RouterContext;
|
|
54
|
+
exports.atLeastReact18 = atLeastReact18;
|
|
42
55
|
exports.f = f;
|
package/dist/index.cjs.js
CHANGED
|
@@ -2,30 +2,50 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const React = require("react");
|
|
4
4
|
const reactRouterDom = require("react-router-dom");
|
|
5
|
-
const context = require("./context-
|
|
6
|
-
const
|
|
5
|
+
const context = require("./context-ePt4wynZ.cjs");
|
|
6
|
+
const ReactDOM = require("react-dom");
|
|
7
|
+
function _interopNamespaceDefault(e) {
|
|
8
|
+
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
9
|
+
if (e) {
|
|
10
|
+
for (const k in e) {
|
|
11
|
+
if (k !== "default") {
|
|
12
|
+
const d = Object.getOwnPropertyDescriptor(e, k);
|
|
13
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: () => e[k]
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
n.default = e;
|
|
21
|
+
return Object.freeze(n);
|
|
22
|
+
}
|
|
23
|
+
const React__namespace = /* @__PURE__ */ _interopNamespaceDefault(React);
|
|
7
24
|
const RemoteApp = ({
|
|
8
25
|
name,
|
|
9
26
|
memoryRoute,
|
|
10
27
|
basename,
|
|
11
28
|
providerInfo,
|
|
29
|
+
dispathPopstate,
|
|
12
30
|
...resProps
|
|
13
31
|
}) => {
|
|
14
32
|
const rootRef = React.useRef(null);
|
|
15
33
|
const renderDom = React.useRef(null);
|
|
16
|
-
const location = reactRouterDom.useLocation();
|
|
17
|
-
const [pathname, setPathname] = React.useState(location.pathname);
|
|
18
34
|
const providerInfoRef = React.useRef(null);
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
35
|
+
if (dispathPopstate) {
|
|
36
|
+
const location = reactRouterDom.useLocation();
|
|
37
|
+
const [pathname, setPathname] = React.useState(location.pathname);
|
|
38
|
+
React.useEffect(() => {
|
|
39
|
+
if (pathname !== "" && pathname !== location.pathname) {
|
|
40
|
+
context.LoggerInstance.log(`createRemoteComponent dispatchPopstateEnv >>>`, {
|
|
41
|
+
name,
|
|
42
|
+
pathname: location.pathname
|
|
43
|
+
});
|
|
44
|
+
context.f();
|
|
45
|
+
}
|
|
46
|
+
setPathname(location.pathname);
|
|
47
|
+
}, [location]);
|
|
48
|
+
}
|
|
29
49
|
React.useEffect(() => {
|
|
30
50
|
const renderTimeout = setTimeout(() => {
|
|
31
51
|
const providerReturn = providerInfo();
|
|
@@ -68,7 +88,7 @@ function createRemoteComponent(lazyComponent, info) {
|
|
|
68
88
|
const exportName = (info == null ? void 0 : info.export) || "default";
|
|
69
89
|
const routerContextVal = React.useContext(reactRouterDom.UNSAFE_RouteContext);
|
|
70
90
|
let basename = "/";
|
|
71
|
-
if (routerContextVal.matches[0] && routerContextVal.matches[0].pathnameBase) {
|
|
91
|
+
if (routerContextVal && routerContextVal.matches && routerContextVal.matches[0] && routerContextVal.matches[0].pathnameBase) {
|
|
72
92
|
basename = routerContextVal.matches[0].pathnameBase;
|
|
73
93
|
}
|
|
74
94
|
const LazyComponent = React.useMemo(() => {
|
|
@@ -77,7 +97,8 @@ function createRemoteComponent(lazyComponent, info) {
|
|
|
77
97
|
basename,
|
|
78
98
|
lazyComponent,
|
|
79
99
|
exportName,
|
|
80
|
-
props
|
|
100
|
+
props,
|
|
101
|
+
routerContextVal
|
|
81
102
|
});
|
|
82
103
|
const m2 = await lazyComponent();
|
|
83
104
|
const moduleName = m2 && m2[Symbol.for("mf_module_id")];
|
|
@@ -92,6 +113,7 @@ function createRemoteComponent(lazyComponent, info) {
|
|
|
92
113
|
RemoteApp,
|
|
93
114
|
{
|
|
94
115
|
name: moduleName,
|
|
116
|
+
dispathPopstate: (routerContextVal == null ? void 0 : routerContextVal.matches) && (routerContextVal == null ? void 0 : routerContextVal.matches.length) > 0,
|
|
95
117
|
...info,
|
|
96
118
|
...props,
|
|
97
119
|
providerInfo: exportFn,
|
|
@@ -107,7 +129,7 @@ function createRemoteComponent(lazyComponent, info) {
|
|
|
107
129
|
};
|
|
108
130
|
}
|
|
109
131
|
var client = {};
|
|
110
|
-
var m =
|
|
132
|
+
var m = ReactDOM;
|
|
111
133
|
if (process.env.NODE_ENV === "production") {
|
|
112
134
|
client.createRoot = m.createRoot;
|
|
113
135
|
client.hydrateRoot = m.hydrateRoot;
|
|
@@ -136,34 +158,55 @@ function createBridgeComponent(bridgeInfo) {
|
|
|
136
158
|
const RawComponent = (info) => {
|
|
137
159
|
const { appInfo, propsInfo } = info;
|
|
138
160
|
const { name, memoryRoute, basename = "/" } = appInfo;
|
|
139
|
-
return /* @__PURE__ */
|
|
161
|
+
return /* @__PURE__ */ React__namespace.createElement(context.RouterContext.Provider, { value: { name, basename, memoryRoute } }, /* @__PURE__ */ React__namespace.createElement(bridgeInfo.rootComponent, { ...propsInfo, basename }));
|
|
140
162
|
};
|
|
141
163
|
return {
|
|
142
164
|
render(info) {
|
|
143
165
|
context.LoggerInstance.log(`createBridgeComponent render Info`, info);
|
|
144
|
-
const root = client.createRoot(info.dom);
|
|
145
|
-
rootMap.set(info.dom, root);
|
|
146
166
|
const { name, basename, memoryRoute, ...propsInfo } = info;
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
167
|
+
if (context.atLeastReact18(React__namespace)) {
|
|
168
|
+
const root = client.createRoot(info.dom);
|
|
169
|
+
rootMap.set(info.dom, root);
|
|
170
|
+
root.render(
|
|
171
|
+
/* @__PURE__ */ React__namespace.createElement(
|
|
172
|
+
RawComponent,
|
|
173
|
+
{
|
|
174
|
+
propsInfo,
|
|
175
|
+
appInfo: {
|
|
176
|
+
name,
|
|
177
|
+
basename,
|
|
178
|
+
memoryRoute
|
|
179
|
+
}
|
|
156
180
|
}
|
|
157
|
-
|
|
158
|
-
)
|
|
159
|
-
|
|
181
|
+
)
|
|
182
|
+
);
|
|
183
|
+
} else {
|
|
184
|
+
ReactDOM.render(
|
|
185
|
+
/* @__PURE__ */ React__namespace.createElement(
|
|
186
|
+
RawComponent,
|
|
187
|
+
{
|
|
188
|
+
propsInfo,
|
|
189
|
+
appInfo: {
|
|
190
|
+
name,
|
|
191
|
+
basename,
|
|
192
|
+
memoryRoute
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
),
|
|
196
|
+
info.dom
|
|
197
|
+
);
|
|
198
|
+
}
|
|
160
199
|
},
|
|
161
200
|
destroy(info) {
|
|
162
201
|
context.LoggerInstance.log(`createBridgeComponent destroy Info`, {
|
|
163
202
|
dom: info.dom
|
|
164
203
|
});
|
|
165
|
-
|
|
166
|
-
|
|
204
|
+
if (context.atLeastReact18(React__namespace)) {
|
|
205
|
+
const root = rootMap.get(info.dom);
|
|
206
|
+
root == null ? void 0 : root.unmount();
|
|
207
|
+
} else {
|
|
208
|
+
ReactDOM.unmountComponentAtNode(info.dom);
|
|
209
|
+
}
|
|
167
210
|
},
|
|
168
211
|
rawComponent: bridgeInfo.rootComponent,
|
|
169
212
|
__BRIDGE_FN__: (_args) => {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { default as default_2 } from 'react';
|
|
2
|
+
import * as React_2 from 'react';
|
|
2
3
|
import { ReactNode } from 'react';
|
|
3
4
|
|
|
4
5
|
export declare function createBridgeComponent<T>(bridgeInfo: ProviderFnParams<T>): () => {
|
|
@@ -6,7 +7,7 @@ export declare function createBridgeComponent<T>(bridgeInfo: ProviderFnParams<T>
|
|
|
6
7
|
destroy(info: {
|
|
7
8
|
dom: HTMLElement;
|
|
8
9
|
}): void;
|
|
9
|
-
rawComponent:
|
|
10
|
+
rawComponent: React_2.ComponentType<T>;
|
|
10
11
|
__BRIDGE_FN__: (_args: T) => void;
|
|
11
12
|
};
|
|
12
13
|
|
|
@@ -19,7 +20,7 @@ export declare function createRemoteComponent<T, E extends keyof T>(lazyComponen
|
|
|
19
20
|
} & ("__BRIDGE_FN__" extends keyof (T[E] extends (...args: any) => any ? ReturnType<T[E]> : never) ? (T[E] extends (...args: any) => any ? ReturnType<T[E]> : never)["__BRIDGE_FN__"] extends (...args: any) => any ? Parameters<(T[E] extends (...args: any) => any ? ReturnType<T[E]> : never)["__BRIDGE_FN__"]>[0] : {} : {})) => default_2.JSX.Element;
|
|
20
21
|
|
|
21
22
|
declare type ProviderFnParams<T> = {
|
|
22
|
-
rootComponent:
|
|
23
|
+
rootComponent: React_2.ComponentType<T>;
|
|
23
24
|
};
|
|
24
25
|
|
|
25
26
|
export declare interface ProviderParams {
|
package/dist/index.es.js
CHANGED
|
@@ -1,29 +1,33 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import React__default, { useContext, useMemo, useRef, useState, useEffect } from "react";
|
|
2
3
|
import { UNSAFE_RouteContext, useLocation } from "react-router-dom";
|
|
3
|
-
import { L as LoggerInstance, f, R as RouterContext } from "./context-
|
|
4
|
-
import
|
|
4
|
+
import { L as LoggerInstance, f, a as atLeastReact18, R as RouterContext } from "./context-CPtN38Ur.js";
|
|
5
|
+
import ReactDOM from "react-dom";
|
|
5
6
|
const RemoteApp = ({
|
|
6
7
|
name,
|
|
7
8
|
memoryRoute,
|
|
8
9
|
basename,
|
|
9
10
|
providerInfo,
|
|
11
|
+
dispathPopstate,
|
|
10
12
|
...resProps
|
|
11
13
|
}) => {
|
|
12
14
|
const rootRef = useRef(null);
|
|
13
15
|
const renderDom = useRef(null);
|
|
14
|
-
const location = useLocation();
|
|
15
|
-
const [pathname, setPathname] = useState(location.pathname);
|
|
16
16
|
const providerInfoRef = useRef(null);
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
17
|
+
if (dispathPopstate) {
|
|
18
|
+
const location = useLocation();
|
|
19
|
+
const [pathname, setPathname] = useState(location.pathname);
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (pathname !== "" && pathname !== location.pathname) {
|
|
22
|
+
LoggerInstance.log(`createRemoteComponent dispatchPopstateEnv >>>`, {
|
|
23
|
+
name,
|
|
24
|
+
pathname: location.pathname
|
|
25
|
+
});
|
|
26
|
+
f();
|
|
27
|
+
}
|
|
28
|
+
setPathname(location.pathname);
|
|
29
|
+
}, [location]);
|
|
30
|
+
}
|
|
27
31
|
useEffect(() => {
|
|
28
32
|
const renderTimeout = setTimeout(() => {
|
|
29
33
|
const providerReturn = providerInfo();
|
|
@@ -58,7 +62,7 @@ const RemoteApp = ({
|
|
|
58
62
|
});
|
|
59
63
|
};
|
|
60
64
|
}, []);
|
|
61
|
-
return /* @__PURE__ */
|
|
65
|
+
return /* @__PURE__ */ React__default.createElement("div", { ref: rootRef });
|
|
62
66
|
};
|
|
63
67
|
RemoteApp["__APP_VERSION__"] = "0.0.1";
|
|
64
68
|
function createRemoteComponent(lazyComponent, info) {
|
|
@@ -66,16 +70,17 @@ function createRemoteComponent(lazyComponent, info) {
|
|
|
66
70
|
const exportName = (info == null ? void 0 : info.export) || "default";
|
|
67
71
|
const routerContextVal = useContext(UNSAFE_RouteContext);
|
|
68
72
|
let basename = "/";
|
|
69
|
-
if (routerContextVal.matches[0] && routerContextVal.matches[0].pathnameBase) {
|
|
73
|
+
if (routerContextVal && routerContextVal.matches && routerContextVal.matches[0] && routerContextVal.matches[0].pathnameBase) {
|
|
70
74
|
basename = routerContextVal.matches[0].pathnameBase;
|
|
71
75
|
}
|
|
72
76
|
const LazyComponent = useMemo(() => {
|
|
73
|
-
return
|
|
77
|
+
return React__default.lazy(async () => {
|
|
74
78
|
LoggerInstance.log(`createRemoteComponent LazyComponent create >>>`, {
|
|
75
79
|
basename,
|
|
76
80
|
lazyComponent,
|
|
77
81
|
exportName,
|
|
78
|
-
props
|
|
82
|
+
props,
|
|
83
|
+
routerContextVal
|
|
79
84
|
});
|
|
80
85
|
const m2 = await lazyComponent();
|
|
81
86
|
const moduleName = m2 && m2[Symbol.for("mf_module_id")];
|
|
@@ -86,10 +91,11 @@ function createRemoteComponent(lazyComponent, info) {
|
|
|
86
91
|
const exportFn = m2[exportName];
|
|
87
92
|
if (exportName in m2 && typeof exportFn === "function") {
|
|
88
93
|
return {
|
|
89
|
-
default: () => /* @__PURE__ */
|
|
94
|
+
default: () => /* @__PURE__ */ React__default.createElement(
|
|
90
95
|
RemoteApp,
|
|
91
96
|
{
|
|
92
97
|
name: moduleName,
|
|
98
|
+
dispathPopstate: (routerContextVal == null ? void 0 : routerContextVal.matches) && (routerContextVal == null ? void 0 : routerContextVal.matches.length) > 0,
|
|
93
99
|
...info,
|
|
94
100
|
...props,
|
|
95
101
|
providerInfo: exportFn,
|
|
@@ -101,11 +107,11 @@ function createRemoteComponent(lazyComponent, info) {
|
|
|
101
107
|
throw Error("module not found");
|
|
102
108
|
});
|
|
103
109
|
}, [exportName, basename, props.memoryRoute]);
|
|
104
|
-
return /* @__PURE__ */
|
|
110
|
+
return /* @__PURE__ */ React__default.createElement(React__default.Suspense, { fallback: props.fallback }, /* @__PURE__ */ React__default.createElement(LazyComponent, null));
|
|
105
111
|
};
|
|
106
112
|
}
|
|
107
113
|
var client = {};
|
|
108
|
-
var m =
|
|
114
|
+
var m = ReactDOM;
|
|
109
115
|
if (process.env.NODE_ENV === "production") {
|
|
110
116
|
client.createRoot = m.createRoot;
|
|
111
117
|
client.hydrateRoot = m.hydrateRoot;
|
|
@@ -139,29 +145,50 @@ function createBridgeComponent(bridgeInfo) {
|
|
|
139
145
|
return {
|
|
140
146
|
render(info) {
|
|
141
147
|
LoggerInstance.log(`createBridgeComponent render Info`, info);
|
|
142
|
-
const root = client.createRoot(info.dom);
|
|
143
|
-
rootMap.set(info.dom, root);
|
|
144
148
|
const { name, basename, memoryRoute, ...propsInfo } = info;
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
149
|
+
if (atLeastReact18(React)) {
|
|
150
|
+
const root = client.createRoot(info.dom);
|
|
151
|
+
rootMap.set(info.dom, root);
|
|
152
|
+
root.render(
|
|
153
|
+
/* @__PURE__ */ React.createElement(
|
|
154
|
+
RawComponent,
|
|
155
|
+
{
|
|
156
|
+
propsInfo,
|
|
157
|
+
appInfo: {
|
|
158
|
+
name,
|
|
159
|
+
basename,
|
|
160
|
+
memoryRoute
|
|
161
|
+
}
|
|
154
162
|
}
|
|
155
|
-
|
|
156
|
-
)
|
|
157
|
-
|
|
163
|
+
)
|
|
164
|
+
);
|
|
165
|
+
} else {
|
|
166
|
+
ReactDOM.render(
|
|
167
|
+
/* @__PURE__ */ React.createElement(
|
|
168
|
+
RawComponent,
|
|
169
|
+
{
|
|
170
|
+
propsInfo,
|
|
171
|
+
appInfo: {
|
|
172
|
+
name,
|
|
173
|
+
basename,
|
|
174
|
+
memoryRoute
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
),
|
|
178
|
+
info.dom
|
|
179
|
+
);
|
|
180
|
+
}
|
|
158
181
|
},
|
|
159
182
|
destroy(info) {
|
|
160
183
|
LoggerInstance.log(`createBridgeComponent destroy Info`, {
|
|
161
184
|
dom: info.dom
|
|
162
185
|
});
|
|
163
|
-
|
|
164
|
-
|
|
186
|
+
if (atLeastReact18(React)) {
|
|
187
|
+
const root = rootMap.get(info.dom);
|
|
188
|
+
root == null ? void 0 : root.unmount();
|
|
189
|
+
} else {
|
|
190
|
+
ReactDOM.unmountComponentAtNode(info.dom);
|
|
191
|
+
}
|
|
165
192
|
},
|
|
166
193
|
rawComponent: bridgeInfo.rootComponent,
|
|
167
194
|
__BRIDGE_FN__: (_args) => {
|
package/dist/router.cjs.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const React = require("react");
|
|
4
4
|
const ReactRouterDom = require("react-router-dom/");
|
|
5
|
-
const context = require("./context-
|
|
5
|
+
const context = require("./context-ePt4wynZ.cjs");
|
|
6
6
|
function _interopNamespaceDefault(e) {
|
|
7
7
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
8
8
|
if (e) {
|
package/dist/router.es.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React__default, { useContext } from "react";
|
|
2
2
|
import * as ReactRouterDom from "react-router-dom/";
|
|
3
3
|
export * from "react-router-dom/";
|
|
4
|
-
import { R as RouterContext, L as LoggerInstance } from "./context-
|
|
4
|
+
import { R as RouterContext, L as LoggerInstance } from "./context-CPtN38Ur.js";
|
|
5
5
|
function WraperRouter(props) {
|
|
6
6
|
const { basename, ...propsRes } = props;
|
|
7
7
|
const routerContextProps = useContext(RouterContext) || {};
|
|
@@ -11,9 +11,9 @@ function WraperRouter(props) {
|
|
|
11
11
|
WraperRouterProps: props
|
|
12
12
|
});
|
|
13
13
|
if (!routerContextProps)
|
|
14
|
-
return /* @__PURE__ */
|
|
14
|
+
return /* @__PURE__ */ React__default.createElement(ReactRouterDom.BrowserRouter, { ...props });
|
|
15
15
|
if (routerContextProps == null ? void 0 : routerContextProps.memoryRoute) {
|
|
16
|
-
return /* @__PURE__ */
|
|
16
|
+
return /* @__PURE__ */ React__default.createElement(
|
|
17
17
|
ReactRouterDom.MemoryRouter,
|
|
18
18
|
{
|
|
19
19
|
...props,
|
|
@@ -21,7 +21,7 @@ function WraperRouter(props) {
|
|
|
21
21
|
}
|
|
22
22
|
);
|
|
23
23
|
}
|
|
24
|
-
return /* @__PURE__ */
|
|
24
|
+
return /* @__PURE__ */ React__default.createElement(
|
|
25
25
|
ReactRouterDom.BrowserRouter,
|
|
26
26
|
{
|
|
27
27
|
...propsRes,
|
|
@@ -40,19 +40,19 @@ function WraperRouterProvider(props) {
|
|
|
40
40
|
router
|
|
41
41
|
});
|
|
42
42
|
if (!routerContextProps)
|
|
43
|
-
return /* @__PURE__ */
|
|
43
|
+
return /* @__PURE__ */ React__default.createElement(ReactRouterDom.RouterProvider, { ...props });
|
|
44
44
|
if (routerContextProps.memoryRoute) {
|
|
45
45
|
const MemeoryRouterInstance = ReactRouterDom.createMemoryRouter(routers, {
|
|
46
46
|
initialEntries: [routerContextProps == null ? void 0 : routerContextProps.memoryRoute.entryPath]
|
|
47
47
|
});
|
|
48
|
-
return /* @__PURE__ */
|
|
48
|
+
return /* @__PURE__ */ React__default.createElement(ReactRouterDom.RouterProvider, { router: MemeoryRouterInstance });
|
|
49
49
|
} else {
|
|
50
50
|
const BrowserRouterInstance = ReactRouterDom.createBrowserRouter(routers, {
|
|
51
51
|
basename: routerContextProps.basename,
|
|
52
52
|
future: router.future,
|
|
53
53
|
window: router.window
|
|
54
54
|
});
|
|
55
|
-
return /* @__PURE__ */
|
|
55
|
+
return /* @__PURE__ */ React__default.createElement(
|
|
56
56
|
ReactRouterDom.RouterProvider,
|
|
57
57
|
{
|
|
58
58
|
...propsRes,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@module-federation/bridge-react",
|
|
3
|
-
"version": "0.0.0-next-
|
|
3
|
+
"version": "0.0.0-next-20240620023927",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -25,12 +25,12 @@
|
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@loadable/component": "^5.16.4",
|
|
27
27
|
"react-error-boundary": "^4.0.13",
|
|
28
|
-
"@module-federation/bridge-shared": "0.0.0-next-
|
|
28
|
+
"@module-federation/bridge-shared": "0.0.0-next-20240620023927"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
|
-
"react": "
|
|
32
|
-
"react-dom": "
|
|
33
|
-
"react-router-dom": ">=
|
|
31
|
+
"react": ">=16.9.0",
|
|
32
|
+
"react-dom": ">=16.9.0",
|
|
33
|
+
"react-router-dom": ">=4"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@testing-library/react": "15.0.7",
|
package/src/create.tsx
CHANGED
|
@@ -31,6 +31,7 @@ interface RemoteModule {
|
|
|
31
31
|
interface RemoteAppParams {
|
|
32
32
|
name: string;
|
|
33
33
|
providerInfo: NonNullable<RemoteModule['provider']>;
|
|
34
|
+
dispathPopstate: boolean;
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
const RemoteApp = ({
|
|
@@ -38,24 +39,27 @@ const RemoteApp = ({
|
|
|
38
39
|
memoryRoute,
|
|
39
40
|
basename,
|
|
40
41
|
providerInfo,
|
|
42
|
+
dispathPopstate,
|
|
41
43
|
...resProps
|
|
42
44
|
}: RemoteAppParams & ProviderParams) => {
|
|
43
45
|
const rootRef = useRef(null);
|
|
44
46
|
const renderDom = useRef(null);
|
|
45
|
-
const location = useLocation();
|
|
46
|
-
const [pathname, setPathname] = useState(location.pathname);
|
|
47
47
|
const providerInfoRef = useRef<any>(null);
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
48
|
+
if (dispathPopstate) {
|
|
49
|
+
const location = useLocation();
|
|
50
|
+
const [pathname, setPathname] = useState(location.pathname);
|
|
51
|
+
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
if (pathname !== '' && pathname !== location.pathname) {
|
|
54
|
+
LoggerInstance.log(`createRemoteComponent dispatchPopstateEnv >>>`, {
|
|
55
|
+
name,
|
|
56
|
+
pathname: location.pathname,
|
|
57
|
+
});
|
|
58
|
+
dispatchPopstateEnv();
|
|
59
|
+
}
|
|
60
|
+
setPathname(location.pathname);
|
|
61
|
+
}, [location]);
|
|
62
|
+
}
|
|
59
63
|
|
|
60
64
|
useEffect(() => {
|
|
61
65
|
const renderTimeout = setTimeout(() => {
|
|
@@ -124,6 +128,8 @@ export function createRemoteComponent<T, E extends keyof T>(
|
|
|
124
128
|
const routerContextVal = useContext(UNSAFE_RouteContext);
|
|
125
129
|
let basename = '/';
|
|
126
130
|
if (
|
|
131
|
+
routerContextVal &&
|
|
132
|
+
routerContextVal.matches &&
|
|
127
133
|
routerContextVal.matches[0] &&
|
|
128
134
|
routerContextVal.matches[0].pathnameBase
|
|
129
135
|
) {
|
|
@@ -138,6 +144,7 @@ export function createRemoteComponent<T, E extends keyof T>(
|
|
|
138
144
|
lazyComponent,
|
|
139
145
|
exportName,
|
|
140
146
|
props,
|
|
147
|
+
routerContextVal,
|
|
141
148
|
});
|
|
142
149
|
const m = (await lazyComponent()) as RemoteModule;
|
|
143
150
|
// @ts-ignore
|
|
@@ -155,6 +162,10 @@ export function createRemoteComponent<T, E extends keyof T>(
|
|
|
155
162
|
default: () => (
|
|
156
163
|
<RemoteApp
|
|
157
164
|
name={moduleName}
|
|
165
|
+
dispathPopstate={
|
|
166
|
+
routerContextVal?.matches &&
|
|
167
|
+
routerContextVal?.matches.length > 0
|
|
168
|
+
}
|
|
158
169
|
{...info}
|
|
159
170
|
{...props}
|
|
160
171
|
providerInfo={exportFn}
|
package/src/provider.tsx
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import { useLayoutEffect, useRef, useState } from 'react';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import ReactDOM from 'react-dom';
|
|
4
|
+
import ReactDOMClient from 'react-dom/client';
|
|
3
5
|
import { RouterContext } from './context';
|
|
4
6
|
import type {
|
|
5
7
|
ProviderParams,
|
|
6
8
|
RenderFnParams,
|
|
7
9
|
} from '@module-federation/bridge-shared';
|
|
8
|
-
import { LoggerInstance } from './utils';
|
|
10
|
+
import { LoggerInstance, atLeastReact18 } from './utils';
|
|
9
11
|
|
|
10
12
|
type ProviderFnParams<T> = {
|
|
11
13
|
rootComponent: React.ComponentType<T>;
|
|
@@ -13,7 +15,7 @@ type ProviderFnParams<T> = {
|
|
|
13
15
|
|
|
14
16
|
export function createBridgeComponent<T>(bridgeInfo: ProviderFnParams<T>) {
|
|
15
17
|
return () => {
|
|
16
|
-
const rootMap = new Map<any,
|
|
18
|
+
const rootMap = new Map<any, ReactDOMClient.Root>();
|
|
17
19
|
|
|
18
20
|
const RawComponent = (info: { propsInfo: T; appInfo: ProviderParams }) => {
|
|
19
21
|
const { appInfo, propsInfo } = info;
|
|
@@ -29,26 +31,45 @@ export function createBridgeComponent<T>(bridgeInfo: ProviderFnParams<T>) {
|
|
|
29
31
|
return {
|
|
30
32
|
render(info: RenderFnParams & any) {
|
|
31
33
|
LoggerInstance.log(`createBridgeComponent render Info`, info);
|
|
32
|
-
const root = ReactDOM.createRoot(info.dom);
|
|
33
|
-
rootMap.set(info.dom, root);
|
|
34
34
|
const { name, basename, memoryRoute, ...propsInfo } = info;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
35
|
+
|
|
36
|
+
if (atLeastReact18(React)) {
|
|
37
|
+
const root = ReactDOMClient.createRoot(info.dom);
|
|
38
|
+
rootMap.set(info.dom, root);
|
|
39
|
+
root.render(
|
|
40
|
+
<RawComponent
|
|
41
|
+
propsInfo={propsInfo}
|
|
42
|
+
appInfo={{
|
|
43
|
+
name,
|
|
44
|
+
basename,
|
|
45
|
+
memoryRoute,
|
|
46
|
+
}}
|
|
47
|
+
/>,
|
|
48
|
+
);
|
|
49
|
+
} else {
|
|
50
|
+
ReactDOM.render(
|
|
51
|
+
<RawComponent
|
|
52
|
+
propsInfo={propsInfo}
|
|
53
|
+
appInfo={{
|
|
54
|
+
name,
|
|
55
|
+
basename,
|
|
56
|
+
memoryRoute,
|
|
57
|
+
}}
|
|
58
|
+
/>,
|
|
59
|
+
info.dom,
|
|
60
|
+
);
|
|
61
|
+
}
|
|
45
62
|
},
|
|
46
63
|
destroy(info: { dom: HTMLElement }) {
|
|
47
64
|
LoggerInstance.log(`createBridgeComponent destroy Info`, {
|
|
48
65
|
dom: info.dom,
|
|
49
66
|
});
|
|
50
|
-
|
|
51
|
-
|
|
67
|
+
if (atLeastReact18(React)) {
|
|
68
|
+
const root = rootMap.get(info.dom);
|
|
69
|
+
root?.unmount();
|
|
70
|
+
} else {
|
|
71
|
+
ReactDOM.unmountComponentAtNode(info.dom);
|
|
72
|
+
}
|
|
52
73
|
},
|
|
53
74
|
rawComponent: bridgeInfo.rootComponent,
|
|
54
75
|
__BRIDGE_FN__: (_args: T) => {},
|
package/src/utils.ts
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
import React from 'react';
|
|
1
2
|
import { Logger } from '@module-federation/bridge-shared';
|
|
2
3
|
|
|
3
4
|
export const LoggerInstance = new Logger('bridge-react');
|
|
5
|
+
|
|
6
|
+
type typeReact = typeof React;
|
|
7
|
+
|
|
8
|
+
export function atLeastReact18(React: typeReact) {
|
|
9
|
+
if (
|
|
10
|
+
React &&
|
|
11
|
+
typeof React.version === 'string' &&
|
|
12
|
+
React.version.indexOf('.') >= 0
|
|
13
|
+
) {
|
|
14
|
+
const majorVersionString = React.version.split('.')[0];
|
|
15
|
+
try {
|
|
16
|
+
return Number(majorVersionString) >= 18;
|
|
17
|
+
} catch (err) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
} else {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|