@module-federation/bridge-react 0.0.0-next-20240704021704 → 0.0.0-next-20240707072703
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/dist/index.cjs.js +74 -81
- package/dist/index.d.ts +2 -2
- package/dist/index.es.js +75 -82
- package/package.json +2 -2
- package/src/create.tsx +180 -62
- package/src/remote/index.tsx +0 -165
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# @module-federation/bridge-react
|
|
2
2
|
|
|
3
|
-
## 0.0.0-next-
|
|
3
|
+
## 0.0.0-next-20240707072703
|
|
4
4
|
|
|
5
5
|
### Patch Changes
|
|
6
6
|
|
|
7
|
-
- @module-federation/bridge-shared@0.0.0-next-
|
|
7
|
+
- @module-federation/bridge-shared@0.0.0-next-20240707072703
|
|
8
8
|
|
|
9
9
|
## 0.2.3
|
|
10
10
|
|
package/dist/index.cjs.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const React = require("react");
|
|
4
|
-
const context = require("./context--mtFt3tp.cjs");
|
|
5
4
|
const ReactRouterDOM = require("react-router-dom");
|
|
5
|
+
const context = require("./context--mtFt3tp.cjs");
|
|
6
6
|
const ReactDOM = require("react-dom");
|
|
7
7
|
function _interopNamespaceDefault(e) {
|
|
8
8
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
@@ -122,11 +122,26 @@ const RemoteApp = ({
|
|
|
122
122
|
memoryRoute,
|
|
123
123
|
basename,
|
|
124
124
|
providerInfo,
|
|
125
|
+
dispathPopstate,
|
|
125
126
|
...resProps
|
|
126
127
|
}) => {
|
|
127
128
|
const rootRef = React.useRef(null);
|
|
128
129
|
const renderDom = React.useRef(null);
|
|
129
130
|
const providerInfoRef = React.useRef(null);
|
|
131
|
+
if (dispathPopstate) {
|
|
132
|
+
const location = ReactRouterDOM__namespace.useLocation();
|
|
133
|
+
const [pathname, setPathname] = React.useState(location.pathname);
|
|
134
|
+
React.useEffect(() => {
|
|
135
|
+
if (pathname !== "" && pathname !== location.pathname) {
|
|
136
|
+
context.LoggerInstance.log(`createRemoteComponent dispatchPopstateEnv >>>`, {
|
|
137
|
+
name,
|
|
138
|
+
pathname: location.pathname
|
|
139
|
+
});
|
|
140
|
+
context.f();
|
|
141
|
+
}
|
|
142
|
+
setPathname(location.pathname);
|
|
143
|
+
}, [location]);
|
|
144
|
+
}
|
|
130
145
|
React.useEffect(() => {
|
|
131
146
|
const renderTimeout = setTimeout(() => {
|
|
132
147
|
const providerReturn = providerInfo();
|
|
@@ -164,9 +179,11 @@ const RemoteApp = ({
|
|
|
164
179
|
return /* @__PURE__ */ React.createElement("div", { ref: rootRef });
|
|
165
180
|
};
|
|
166
181
|
RemoteApp["__APP_VERSION__"] = "0.2.3";
|
|
167
|
-
function
|
|
182
|
+
function createRemoteComponent(info) {
|
|
168
183
|
return (props) => {
|
|
169
184
|
var _a;
|
|
185
|
+
const exportName = (info == null ? void 0 : info.export) || "default";
|
|
186
|
+
let basename = "/";
|
|
170
187
|
let enableDispathPopstate = false;
|
|
171
188
|
let routerContextVal;
|
|
172
189
|
try {
|
|
@@ -175,8 +192,9 @@ function withRouterData(WrappedComponent) {
|
|
|
175
192
|
} catch {
|
|
176
193
|
enableDispathPopstate = false;
|
|
177
194
|
}
|
|
178
|
-
|
|
179
|
-
|
|
195
|
+
if (props.basename) {
|
|
196
|
+
basename = props.basename;
|
|
197
|
+
} else if (enableDispathPopstate) {
|
|
180
198
|
const ReactRouterDOMAny = ReactRouterDOM__namespace;
|
|
181
199
|
const useRouteMatch = ReactRouterDOMAny["useRouteMatch"];
|
|
182
200
|
const useHistory = ReactRouterDOMAny["useHistory"];
|
|
@@ -187,10 +205,11 @@ function withRouterData(WrappedComponent) {
|
|
|
187
205
|
basename = useHref == null ? void 0 : useHref("/");
|
|
188
206
|
}
|
|
189
207
|
routerContextVal = React.useContext(UNSAFE_RouteContext);
|
|
190
|
-
if (routerContextVal && routerContextVal.matches && routerContextVal.matches
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
208
|
+
if (routerContextVal && routerContextVal.matches && routerContextVal.matches[0] && routerContextVal.matches[0].pathnameBase) {
|
|
209
|
+
basename = context.pathJoin(
|
|
210
|
+
basename,
|
|
211
|
+
routerContextVal.matches[0].pathnameBase || "/"
|
|
212
|
+
);
|
|
194
213
|
}
|
|
195
214
|
} else {
|
|
196
215
|
const match = useRouteMatch == null ? void 0 : useRouteMatch();
|
|
@@ -203,80 +222,54 @@ function withRouterData(WrappedComponent) {
|
|
|
203
222
|
}
|
|
204
223
|
}
|
|
205
224
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
const [pathname, setPathname] = React.useState(location.pathname);
|
|
215
|
-
React.useEffect(() => {
|
|
216
|
-
if (pathname !== "" && pathname !== location.pathname) {
|
|
217
|
-
context.LoggerInstance.log(`createRemoteComponent dispatchPopstateEnv >>>`, {
|
|
218
|
-
name: props.name,
|
|
219
|
-
pathname: location.pathname
|
|
220
|
-
});
|
|
221
|
-
context.f();
|
|
222
|
-
}
|
|
223
|
-
setPathname(location.pathname);
|
|
224
|
-
}, [location]);
|
|
225
|
-
}
|
|
226
|
-
return /* @__PURE__ */ React.createElement(WrappedComponent, { ...props, basename });
|
|
227
|
-
};
|
|
228
|
-
}
|
|
229
|
-
const RemoteApp$1 = withRouterData(RemoteApp);
|
|
230
|
-
function createLazyRemoteComponent(info) {
|
|
231
|
-
const exportName = (info == null ? void 0 : info.export) || "default";
|
|
232
|
-
return React.lazy(async () => {
|
|
233
|
-
context.LoggerInstance.log(`createRemoteComponent LazyComponent create >>>`, {
|
|
234
|
-
lazyComponent: info.loader,
|
|
235
|
-
exportName
|
|
236
|
-
});
|
|
237
|
-
try {
|
|
238
|
-
const m2 = await info.loader();
|
|
239
|
-
const moduleName = m2 && m2[Symbol.for("mf_module_id")];
|
|
240
|
-
context.LoggerInstance.log(
|
|
241
|
-
`createRemoteComponent LazyComponent loadRemote info >>>`,
|
|
242
|
-
{ name: moduleName, module: m2, exportName }
|
|
243
|
-
);
|
|
244
|
-
const exportFn = m2[exportName];
|
|
245
|
-
if (exportName in m2 && typeof exportFn === "function") {
|
|
246
|
-
const RemoteAppComponent = React.forwardRef((props, _ref) => {
|
|
247
|
-
return /* @__PURE__ */ React.createElement(
|
|
248
|
-
RemoteApp$1,
|
|
249
|
-
{
|
|
250
|
-
name: moduleName,
|
|
251
|
-
providerInfo: exportFn,
|
|
252
|
-
exportName: info.export || "default",
|
|
253
|
-
...props
|
|
254
|
-
}
|
|
255
|
-
);
|
|
225
|
+
const LazyComponent = React.useMemo(() => {
|
|
226
|
+
return React.lazy(async () => {
|
|
227
|
+
context.LoggerInstance.log(`createRemoteComponent LazyComponent create >>>`, {
|
|
228
|
+
basename,
|
|
229
|
+
lazyComponent: info.loader,
|
|
230
|
+
exportName,
|
|
231
|
+
props,
|
|
232
|
+
routerContextVal
|
|
256
233
|
});
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
234
|
+
try {
|
|
235
|
+
const m2 = await info.loader();
|
|
236
|
+
const moduleName = m2 && m2[Symbol.for("mf_module_id")];
|
|
237
|
+
context.LoggerInstance.log(
|
|
238
|
+
`createRemoteComponent LazyComponent loadRemote info >>>`,
|
|
239
|
+
{ basename, name: moduleName, module: m2, exportName, props }
|
|
240
|
+
);
|
|
241
|
+
const exportFn = m2[exportName];
|
|
242
|
+
if (exportName in m2 && typeof exportFn === "function") {
|
|
243
|
+
return {
|
|
244
|
+
default: () => /* @__PURE__ */ React.createElement(
|
|
245
|
+
RemoteApp,
|
|
246
|
+
{
|
|
247
|
+
name: moduleName,
|
|
248
|
+
dispathPopstate: enableDispathPopstate,
|
|
249
|
+
...info,
|
|
250
|
+
...props,
|
|
251
|
+
providerInfo: exportFn,
|
|
252
|
+
basename
|
|
253
|
+
}
|
|
254
|
+
)
|
|
255
|
+
};
|
|
256
|
+
} else {
|
|
257
|
+
context.LoggerInstance.log(
|
|
258
|
+
`createRemoteComponent LazyComponent module not found >>>`,
|
|
259
|
+
{ basename, name: moduleName, module: m2, exportName, props }
|
|
260
|
+
);
|
|
261
|
+
throw Error(
|
|
262
|
+
`Make sure that ${moduleName} has the correct export when export is ${String(
|
|
263
|
+
exportName
|
|
264
|
+
)}`
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
} catch (error) {
|
|
268
|
+
throw error;
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
}, [exportName, basename, props.memoryRoute]);
|
|
272
|
+
return /* @__PURE__ */ React.createElement(ErrorBoundary, { FallbackComponent: info.fallback }, /* @__PURE__ */ React.createElement(React.Suspense, { fallback: info.loading }, /* @__PURE__ */ React.createElement(LazyComponent, null)));
|
|
280
273
|
};
|
|
281
274
|
}
|
|
282
275
|
var client = {};
|
package/dist/index.d.ts
CHANGED
|
@@ -19,8 +19,8 @@ export declare function createRemoteComponent<T, E extends keyof T>(info: {
|
|
|
19
19
|
fallback: ErrorBoundaryPropsWithComponent['FallbackComponent'];
|
|
20
20
|
export?: E;
|
|
21
21
|
}): (props: {
|
|
22
|
-
basename?: ProviderParams[
|
|
23
|
-
memoryRoute?: ProviderParams[
|
|
22
|
+
basename?: ProviderParams['basename'];
|
|
23
|
+
memoryRoute?: ProviderParams['memoryRoute'];
|
|
24
24
|
} & ("__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;
|
|
25
25
|
|
|
26
26
|
declare type ErrorBoundaryPropsWithComponent = ErrorBoundarySharedProps & {
|
package/dist/index.es.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import React__default, { createContext, Component, createElement, isValidElement, useContext,
|
|
3
|
-
import { p as pathJoin, L as LoggerInstance, f, a as atLeastReact18, R as RouterContext } from "./context-Bw2PEwa6.js";
|
|
2
|
+
import React__default, { createContext, Component, createElement, isValidElement, useContext, useMemo, useRef, useState, useEffect } from "react";
|
|
4
3
|
import * as ReactRouterDOM from "react-router-dom";
|
|
4
|
+
import { p as pathJoin, L as LoggerInstance, f, a as atLeastReact18, R as RouterContext } from "./context-Bw2PEwa6.js";
|
|
5
5
|
import ReactDOM from "react-dom";
|
|
6
6
|
const ErrorBoundaryContext = createContext(null);
|
|
7
7
|
const initialState = {
|
|
@@ -103,11 +103,26 @@ const RemoteApp = ({
|
|
|
103
103
|
memoryRoute,
|
|
104
104
|
basename,
|
|
105
105
|
providerInfo,
|
|
106
|
+
dispathPopstate,
|
|
106
107
|
...resProps
|
|
107
108
|
}) => {
|
|
108
109
|
const rootRef = useRef(null);
|
|
109
110
|
const renderDom = useRef(null);
|
|
110
111
|
const providerInfoRef = useRef(null);
|
|
112
|
+
if (dispathPopstate) {
|
|
113
|
+
const location = ReactRouterDOM.useLocation();
|
|
114
|
+
const [pathname, setPathname] = useState(location.pathname);
|
|
115
|
+
useEffect(() => {
|
|
116
|
+
if (pathname !== "" && pathname !== location.pathname) {
|
|
117
|
+
LoggerInstance.log(`createRemoteComponent dispatchPopstateEnv >>>`, {
|
|
118
|
+
name,
|
|
119
|
+
pathname: location.pathname
|
|
120
|
+
});
|
|
121
|
+
f();
|
|
122
|
+
}
|
|
123
|
+
setPathname(location.pathname);
|
|
124
|
+
}, [location]);
|
|
125
|
+
}
|
|
111
126
|
useEffect(() => {
|
|
112
127
|
const renderTimeout = setTimeout(() => {
|
|
113
128
|
const providerReturn = providerInfo();
|
|
@@ -145,9 +160,11 @@ const RemoteApp = ({
|
|
|
145
160
|
return /* @__PURE__ */ React__default.createElement("div", { ref: rootRef });
|
|
146
161
|
};
|
|
147
162
|
RemoteApp["__APP_VERSION__"] = "0.2.3";
|
|
148
|
-
function
|
|
163
|
+
function createRemoteComponent(info) {
|
|
149
164
|
return (props) => {
|
|
150
165
|
var _a;
|
|
166
|
+
const exportName = (info == null ? void 0 : info.export) || "default";
|
|
167
|
+
let basename = "/";
|
|
151
168
|
let enableDispathPopstate = false;
|
|
152
169
|
let routerContextVal;
|
|
153
170
|
try {
|
|
@@ -156,8 +173,9 @@ function withRouterData(WrappedComponent) {
|
|
|
156
173
|
} catch {
|
|
157
174
|
enableDispathPopstate = false;
|
|
158
175
|
}
|
|
159
|
-
|
|
160
|
-
|
|
176
|
+
if (props.basename) {
|
|
177
|
+
basename = props.basename;
|
|
178
|
+
} else if (enableDispathPopstate) {
|
|
161
179
|
const ReactRouterDOMAny = ReactRouterDOM;
|
|
162
180
|
const useRouteMatch = ReactRouterDOMAny["useRouteMatch"];
|
|
163
181
|
const useHistory = ReactRouterDOMAny["useHistory"];
|
|
@@ -168,10 +186,11 @@ function withRouterData(WrappedComponent) {
|
|
|
168
186
|
basename = useHref == null ? void 0 : useHref("/");
|
|
169
187
|
}
|
|
170
188
|
routerContextVal = useContext(UNSAFE_RouteContext);
|
|
171
|
-
if (routerContextVal && routerContextVal.matches && routerContextVal.matches
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
189
|
+
if (routerContextVal && routerContextVal.matches && routerContextVal.matches[0] && routerContextVal.matches[0].pathnameBase) {
|
|
190
|
+
basename = pathJoin(
|
|
191
|
+
basename,
|
|
192
|
+
routerContextVal.matches[0].pathnameBase || "/"
|
|
193
|
+
);
|
|
175
194
|
}
|
|
176
195
|
} else {
|
|
177
196
|
const match = useRouteMatch == null ? void 0 : useRouteMatch();
|
|
@@ -184,80 +203,54 @@ function withRouterData(WrappedComponent) {
|
|
|
184
203
|
}
|
|
185
204
|
}
|
|
186
205
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
const [pathname, setPathname] = useState(location.pathname);
|
|
196
|
-
useEffect(() => {
|
|
197
|
-
if (pathname !== "" && pathname !== location.pathname) {
|
|
198
|
-
LoggerInstance.log(`createRemoteComponent dispatchPopstateEnv >>>`, {
|
|
199
|
-
name: props.name,
|
|
200
|
-
pathname: location.pathname
|
|
201
|
-
});
|
|
202
|
-
f();
|
|
203
|
-
}
|
|
204
|
-
setPathname(location.pathname);
|
|
205
|
-
}, [location]);
|
|
206
|
-
}
|
|
207
|
-
return /* @__PURE__ */ React__default.createElement(WrappedComponent, { ...props, basename });
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
const RemoteApp$1 = withRouterData(RemoteApp);
|
|
211
|
-
function createLazyRemoteComponent(info) {
|
|
212
|
-
const exportName = (info == null ? void 0 : info.export) || "default";
|
|
213
|
-
return React__default.lazy(async () => {
|
|
214
|
-
LoggerInstance.log(`createRemoteComponent LazyComponent create >>>`, {
|
|
215
|
-
lazyComponent: info.loader,
|
|
216
|
-
exportName
|
|
217
|
-
});
|
|
218
|
-
try {
|
|
219
|
-
const m2 = await info.loader();
|
|
220
|
-
const moduleName = m2 && m2[Symbol.for("mf_module_id")];
|
|
221
|
-
LoggerInstance.log(
|
|
222
|
-
`createRemoteComponent LazyComponent loadRemote info >>>`,
|
|
223
|
-
{ name: moduleName, module: m2, exportName }
|
|
224
|
-
);
|
|
225
|
-
const exportFn = m2[exportName];
|
|
226
|
-
if (exportName in m2 && typeof exportFn === "function") {
|
|
227
|
-
const RemoteAppComponent = forwardRef((props, _ref) => {
|
|
228
|
-
return /* @__PURE__ */ React__default.createElement(
|
|
229
|
-
RemoteApp$1,
|
|
230
|
-
{
|
|
231
|
-
name: moduleName,
|
|
232
|
-
providerInfo: exportFn,
|
|
233
|
-
exportName: info.export || "default",
|
|
234
|
-
...props
|
|
235
|
-
}
|
|
236
|
-
);
|
|
206
|
+
const LazyComponent = useMemo(() => {
|
|
207
|
+
return React__default.lazy(async () => {
|
|
208
|
+
LoggerInstance.log(`createRemoteComponent LazyComponent create >>>`, {
|
|
209
|
+
basename,
|
|
210
|
+
lazyComponent: info.loader,
|
|
211
|
+
exportName,
|
|
212
|
+
props,
|
|
213
|
+
routerContextVal
|
|
237
214
|
});
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
215
|
+
try {
|
|
216
|
+
const m2 = await info.loader();
|
|
217
|
+
const moduleName = m2 && m2[Symbol.for("mf_module_id")];
|
|
218
|
+
LoggerInstance.log(
|
|
219
|
+
`createRemoteComponent LazyComponent loadRemote info >>>`,
|
|
220
|
+
{ basename, name: moduleName, module: m2, exportName, props }
|
|
221
|
+
);
|
|
222
|
+
const exportFn = m2[exportName];
|
|
223
|
+
if (exportName in m2 && typeof exportFn === "function") {
|
|
224
|
+
return {
|
|
225
|
+
default: () => /* @__PURE__ */ React__default.createElement(
|
|
226
|
+
RemoteApp,
|
|
227
|
+
{
|
|
228
|
+
name: moduleName,
|
|
229
|
+
dispathPopstate: enableDispathPopstate,
|
|
230
|
+
...info,
|
|
231
|
+
...props,
|
|
232
|
+
providerInfo: exportFn,
|
|
233
|
+
basename
|
|
234
|
+
}
|
|
235
|
+
)
|
|
236
|
+
};
|
|
237
|
+
} else {
|
|
238
|
+
LoggerInstance.log(
|
|
239
|
+
`createRemoteComponent LazyComponent module not found >>>`,
|
|
240
|
+
{ basename, name: moduleName, module: m2, exportName, props }
|
|
241
|
+
);
|
|
242
|
+
throw Error(
|
|
243
|
+
`Make sure that ${moduleName} has the correct export when export is ${String(
|
|
244
|
+
exportName
|
|
245
|
+
)}`
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
} catch (error) {
|
|
249
|
+
throw error;
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
}, [exportName, basename, props.memoryRoute]);
|
|
253
|
+
return /* @__PURE__ */ React__default.createElement(ErrorBoundary, { FallbackComponent: info.fallback }, /* @__PURE__ */ React__default.createElement(React__default.Suspense, { fallback: info.loading }, /* @__PURE__ */ React__default.createElement(LazyComponent, null)));
|
|
261
254
|
};
|
|
262
255
|
}
|
|
263
256
|
var client = {};
|
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-20240707072703",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -25,7 +25,7 @@
|
|
|
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-20240707072703"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
31
|
"react": ">=16.9.0",
|
package/src/create.tsx
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useContext, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
|
+
import * as ReactRouterDOM from 'react-router-dom';
|
|
2
3
|
import type { ProviderParams } from '@module-federation/bridge-shared';
|
|
3
|
-
import { LoggerInstance } from './utils';
|
|
4
|
+
import { LoggerInstance, pathJoin } from './utils';
|
|
5
|
+
import { dispatchPopstateEnv } from '@module-federation/bridge-shared';
|
|
4
6
|
import {
|
|
5
7
|
ErrorBoundary,
|
|
6
8
|
ErrorBoundaryPropsWithComponent,
|
|
7
9
|
} from 'react-error-boundary';
|
|
8
|
-
|
|
10
|
+
|
|
11
|
+
declare const __APP_VERSION__: string;
|
|
9
12
|
|
|
10
13
|
export interface RenderFnParams extends ProviderParams {
|
|
11
14
|
dom?: any;
|
|
@@ -22,67 +25,79 @@ interface RemoteModule {
|
|
|
22
25
|
};
|
|
23
26
|
}
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
28
|
+
interface RemoteAppParams {
|
|
29
|
+
name: string;
|
|
30
|
+
providerInfo: NonNullable<RemoteModule['provider']>;
|
|
31
|
+
dispathPopstate: boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const RemoteApp = ({
|
|
35
|
+
name,
|
|
36
|
+
memoryRoute,
|
|
37
|
+
basename,
|
|
38
|
+
providerInfo,
|
|
39
|
+
dispathPopstate,
|
|
40
|
+
...resProps
|
|
41
|
+
}: RemoteAppParams & ProviderParams) => {
|
|
42
|
+
const rootRef = useRef(null);
|
|
43
|
+
const renderDom = useRef(null);
|
|
44
|
+
const providerInfoRef = useRef<any>(null);
|
|
45
|
+
if (dispathPopstate) {
|
|
46
|
+
const location = ReactRouterDOM.useLocation();
|
|
47
|
+
const [pathname, setPathname] = useState(location.pathname);
|
|
48
|
+
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
if (pathname !== '' && pathname !== location.pathname) {
|
|
51
|
+
LoggerInstance.log(`createRemoteComponent dispatchPopstateEnv >>>`, {
|
|
52
|
+
name,
|
|
53
|
+
pathname: location.pathname,
|
|
54
|
+
});
|
|
55
|
+
dispatchPopstateEnv();
|
|
56
|
+
}
|
|
57
|
+
setPathname(location.pathname);
|
|
58
|
+
}, [location]);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
const renderTimeout = setTimeout(() => {
|
|
63
|
+
const providerReturn = providerInfo();
|
|
64
|
+
providerInfoRef.current = providerReturn;
|
|
65
|
+
const renderProps = {
|
|
66
|
+
name,
|
|
67
|
+
dom: rootRef.current,
|
|
68
|
+
basename,
|
|
69
|
+
memoryRoute,
|
|
70
|
+
...resProps,
|
|
71
|
+
};
|
|
72
|
+
renderDom.current = rootRef.current;
|
|
41
73
|
LoggerInstance.log(
|
|
42
|
-
`createRemoteComponent LazyComponent
|
|
43
|
-
|
|
74
|
+
`createRemoteComponent LazyComponent render >>>`,
|
|
75
|
+
renderProps,
|
|
44
76
|
);
|
|
77
|
+
providerReturn.render(renderProps);
|
|
78
|
+
});
|
|
45
79
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
basename?: ProviderParams['basename'];
|
|
54
|
-
memoryRoute?: ProviderParams['memoryRoute'];
|
|
55
|
-
}
|
|
56
|
-
>((props, _ref) => {
|
|
57
|
-
return (
|
|
58
|
-
<RemoteApp
|
|
59
|
-
name={moduleName}
|
|
60
|
-
providerInfo={exportFn}
|
|
61
|
-
exportName={info.export || 'default'}
|
|
62
|
-
{...props}
|
|
63
|
-
/>
|
|
80
|
+
return () => {
|
|
81
|
+
clearTimeout(renderTimeout);
|
|
82
|
+
setTimeout(() => {
|
|
83
|
+
if (providerInfoRef.current?.destroy) {
|
|
84
|
+
LoggerInstance.log(
|
|
85
|
+
`createRemoteComponent LazyComponent destroy >>>`,
|
|
86
|
+
{ name, basename, dom: renderDom.current },
|
|
64
87
|
);
|
|
65
|
-
|
|
88
|
+
providerInfoRef.current?.destroy({
|
|
89
|
+
dom: renderDom.current,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
};
|
|
94
|
+
}, []);
|
|
66
95
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
`createRemoteComponent LazyComponent module not found >>>`,
|
|
73
|
-
{ name: moduleName, module: m, exportName },
|
|
74
|
-
);
|
|
75
|
-
throw Error(
|
|
76
|
-
`Make sure that ${moduleName} has the correct export when export is ${String(
|
|
77
|
-
exportName,
|
|
78
|
-
)}`,
|
|
79
|
-
);
|
|
80
|
-
}
|
|
81
|
-
} catch (error) {
|
|
82
|
-
throw error;
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
}
|
|
96
|
+
//@ts-ignore
|
|
97
|
+
return <div ref={rootRef}></div>;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
(RemoteApp as any)['__APP_VERSION__'] = __APP_VERSION__;
|
|
86
101
|
|
|
87
102
|
export function createRemoteComponent<T, E extends keyof T>(info: {
|
|
88
103
|
loader: () => Promise<T>;
|
|
@@ -99,18 +114,121 @@ export function createRemoteComponent<T, E extends keyof T>(info: {
|
|
|
99
114
|
: {}
|
|
100
115
|
: {};
|
|
101
116
|
|
|
102
|
-
const LazyComponent = createLazyRemoteComponent(info);
|
|
103
|
-
|
|
104
117
|
return (
|
|
105
118
|
props: {
|
|
106
119
|
basename?: ProviderParams['basename'];
|
|
107
120
|
memoryRoute?: ProviderParams['memoryRoute'];
|
|
108
121
|
} & RawComponentType,
|
|
109
122
|
) => {
|
|
123
|
+
const exportName = info?.export || 'default';
|
|
124
|
+
let basename = '/';
|
|
125
|
+
let enableDispathPopstate = false;
|
|
126
|
+
let routerContextVal: any;
|
|
127
|
+
try {
|
|
128
|
+
ReactRouterDOM.useLocation();
|
|
129
|
+
enableDispathPopstate = true;
|
|
130
|
+
} catch {
|
|
131
|
+
enableDispathPopstate = false;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (props.basename) {
|
|
135
|
+
basename = props.basename;
|
|
136
|
+
} else if (enableDispathPopstate) {
|
|
137
|
+
const ReactRouterDOMAny: any = ReactRouterDOM;
|
|
138
|
+
// Avoid building tools checking references
|
|
139
|
+
const useRouteMatch = ReactRouterDOMAny['use' + 'RouteMatch']; //v5
|
|
140
|
+
const useHistory = ReactRouterDOMAny['use' + 'History']; //v5
|
|
141
|
+
const useHref = ReactRouterDOMAny['use' + 'Href'];
|
|
142
|
+
const UNSAFE_RouteContext = ReactRouterDOMAny['UNSAFE_' + 'RouteContext'];
|
|
143
|
+
|
|
144
|
+
if (UNSAFE_RouteContext /* react-router@6 */) {
|
|
145
|
+
if (useHref) {
|
|
146
|
+
basename = useHref?.('/');
|
|
147
|
+
}
|
|
148
|
+
routerContextVal = useContext(UNSAFE_RouteContext);
|
|
149
|
+
if (
|
|
150
|
+
routerContextVal &&
|
|
151
|
+
routerContextVal.matches &&
|
|
152
|
+
routerContextVal.matches[0] &&
|
|
153
|
+
routerContextVal.matches[0].pathnameBase
|
|
154
|
+
) {
|
|
155
|
+
basename = pathJoin(
|
|
156
|
+
basename,
|
|
157
|
+
routerContextVal.matches[0].pathnameBase || '/',
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
} /* react-router@5 */ else {
|
|
161
|
+
const match = useRouteMatch?.(); // v5
|
|
162
|
+
if (useHistory /* react-router@5 */) {
|
|
163
|
+
// there is no dynamic switching of the router version in the project
|
|
164
|
+
// so hooks can be used in conditional judgment
|
|
165
|
+
const history = useHistory?.();
|
|
166
|
+
// To be compatible to history@4.10.1 and @5.3.0 we cannot write like this `history.createHref(pathname)`
|
|
167
|
+
basename = history?.createHref?.({ pathname: '/' });
|
|
168
|
+
}
|
|
169
|
+
if (match /* react-router@5 */) {
|
|
170
|
+
basename = pathJoin(basename, match?.path || '/');
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const LazyComponent = useMemo(() => {
|
|
176
|
+
//@ts-ignore
|
|
177
|
+
return React.lazy(async () => {
|
|
178
|
+
LoggerInstance.log(`createRemoteComponent LazyComponent create >>>`, {
|
|
179
|
+
basename,
|
|
180
|
+
lazyComponent: info.loader,
|
|
181
|
+
exportName,
|
|
182
|
+
props,
|
|
183
|
+
routerContextVal,
|
|
184
|
+
});
|
|
185
|
+
try {
|
|
186
|
+
const m = (await info.loader()) as RemoteModule;
|
|
187
|
+
// @ts-ignore
|
|
188
|
+
const moduleName = m && m[Symbol.for('mf_module_id')];
|
|
189
|
+
LoggerInstance.log(
|
|
190
|
+
`createRemoteComponent LazyComponent loadRemote info >>>`,
|
|
191
|
+
{ basename, name: moduleName, module: m, exportName, props },
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
// @ts-ignore
|
|
195
|
+
const exportFn = m[exportName] as any;
|
|
196
|
+
|
|
197
|
+
if (exportName in m && typeof exportFn === 'function') {
|
|
198
|
+
return {
|
|
199
|
+
default: () => (
|
|
200
|
+
<RemoteApp
|
|
201
|
+
name={moduleName}
|
|
202
|
+
dispathPopstate={enableDispathPopstate}
|
|
203
|
+
{...info}
|
|
204
|
+
{...props}
|
|
205
|
+
providerInfo={exportFn}
|
|
206
|
+
basename={basename}
|
|
207
|
+
/>
|
|
208
|
+
),
|
|
209
|
+
};
|
|
210
|
+
} else {
|
|
211
|
+
LoggerInstance.log(
|
|
212
|
+
`createRemoteComponent LazyComponent module not found >>>`,
|
|
213
|
+
{ basename, name: moduleName, module: m, exportName, props },
|
|
214
|
+
);
|
|
215
|
+
throw Error(
|
|
216
|
+
`Make sure that ${moduleName} has the correct export when export is ${String(
|
|
217
|
+
exportName,
|
|
218
|
+
)}`,
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
} catch (error) {
|
|
222
|
+
throw error;
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
}, [exportName, basename, props.memoryRoute]);
|
|
226
|
+
|
|
227
|
+
//@ts-ignore
|
|
110
228
|
return (
|
|
111
229
|
<ErrorBoundary FallbackComponent={info.fallback}>
|
|
112
230
|
<React.Suspense fallback={info.loading}>
|
|
113
|
-
<LazyComponent
|
|
231
|
+
<LazyComponent />
|
|
114
232
|
</React.Suspense>
|
|
115
233
|
</ErrorBoundary>
|
|
116
234
|
);
|
package/src/remote/index.tsx
DELETED
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
import React, { useContext, useEffect, useRef, useState } from 'react';
|
|
2
|
-
import * as ReactRouterDOM from 'react-router-dom';
|
|
3
|
-
import type { ProviderParams } from '@module-federation/bridge-shared';
|
|
4
|
-
import { LoggerInstance, pathJoin } from '../utils';
|
|
5
|
-
import { dispatchPopstateEnv } from '@module-federation/bridge-shared';
|
|
6
|
-
|
|
7
|
-
declare const __APP_VERSION__: string;
|
|
8
|
-
|
|
9
|
-
export interface RenderFnParams extends ProviderParams {
|
|
10
|
-
dom?: any;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
interface RemoteModule {
|
|
14
|
-
provider: () => {
|
|
15
|
-
render: (
|
|
16
|
-
info: ProviderParams & {
|
|
17
|
-
dom: any;
|
|
18
|
-
},
|
|
19
|
-
) => void;
|
|
20
|
-
destroy: (info: { dom: any }) => void;
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
interface RemoteAppParams {
|
|
25
|
-
name: string;
|
|
26
|
-
providerInfo: NonNullable<RemoteModule['provider']>;
|
|
27
|
-
exportName: string | number | symbol;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const RemoteApp = ({
|
|
31
|
-
name,
|
|
32
|
-
memoryRoute,
|
|
33
|
-
basename,
|
|
34
|
-
providerInfo,
|
|
35
|
-
...resProps
|
|
36
|
-
}: RemoteAppParams & ProviderParams) => {
|
|
37
|
-
const rootRef = useRef(null);
|
|
38
|
-
const renderDom = useRef(null);
|
|
39
|
-
const providerInfoRef = useRef<any>(null);
|
|
40
|
-
|
|
41
|
-
useEffect(() => {
|
|
42
|
-
const renderTimeout = setTimeout(() => {
|
|
43
|
-
const providerReturn = providerInfo();
|
|
44
|
-
providerInfoRef.current = providerReturn;
|
|
45
|
-
const renderProps = {
|
|
46
|
-
name,
|
|
47
|
-
dom: rootRef.current,
|
|
48
|
-
basename,
|
|
49
|
-
memoryRoute,
|
|
50
|
-
...resProps,
|
|
51
|
-
};
|
|
52
|
-
renderDom.current = rootRef.current;
|
|
53
|
-
LoggerInstance.log(
|
|
54
|
-
`createRemoteComponent LazyComponent render >>>`,
|
|
55
|
-
renderProps,
|
|
56
|
-
);
|
|
57
|
-
providerReturn.render(renderProps);
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
return () => {
|
|
61
|
-
clearTimeout(renderTimeout);
|
|
62
|
-
setTimeout(() => {
|
|
63
|
-
if (providerInfoRef.current?.destroy) {
|
|
64
|
-
LoggerInstance.log(
|
|
65
|
-
`createRemoteComponent LazyComponent destroy >>>`,
|
|
66
|
-
{ name, basename, dom: renderDom.current },
|
|
67
|
-
);
|
|
68
|
-
providerInfoRef.current?.destroy({
|
|
69
|
-
dom: renderDom.current,
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
};
|
|
74
|
-
}, []);
|
|
75
|
-
|
|
76
|
-
//@ts-ignore
|
|
77
|
-
return <div ref={rootRef}></div>;
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
(RemoteApp as any)['__APP_VERSION__'] = __APP_VERSION__;
|
|
81
|
-
|
|
82
|
-
interface ExtraDataProps {
|
|
83
|
-
basename?: string;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export function withRouterData<P extends Parameters<typeof RemoteApp>[0]>(
|
|
87
|
-
WrappedComponent: React.ComponentType<P & ExtraDataProps>,
|
|
88
|
-
): React.FC<Omit<P, keyof ExtraDataProps>> {
|
|
89
|
-
return (props: any) => {
|
|
90
|
-
let enableDispathPopstate = false;
|
|
91
|
-
let routerContextVal: any;
|
|
92
|
-
try {
|
|
93
|
-
ReactRouterDOM.useLocation();
|
|
94
|
-
enableDispathPopstate = true;
|
|
95
|
-
} catch {
|
|
96
|
-
enableDispathPopstate = false;
|
|
97
|
-
}
|
|
98
|
-
let basename = '/';
|
|
99
|
-
|
|
100
|
-
if (!props.basename && enableDispathPopstate) {
|
|
101
|
-
const ReactRouterDOMAny: any = ReactRouterDOM;
|
|
102
|
-
// Avoid building tools checking references
|
|
103
|
-
const useRouteMatch = ReactRouterDOMAny['use' + 'RouteMatch']; //v5
|
|
104
|
-
const useHistory = ReactRouterDOMAny['use' + 'History']; //v5
|
|
105
|
-
const useHref = ReactRouterDOMAny['use' + 'Href'];
|
|
106
|
-
const UNSAFE_RouteContext = ReactRouterDOMAny['UNSAFE_' + 'RouteContext'];
|
|
107
|
-
|
|
108
|
-
if (UNSAFE_RouteContext /* react-router@6 */) {
|
|
109
|
-
if (useHref) {
|
|
110
|
-
basename = useHref?.('/');
|
|
111
|
-
}
|
|
112
|
-
routerContextVal = useContext(UNSAFE_RouteContext);
|
|
113
|
-
if (
|
|
114
|
-
routerContextVal &&
|
|
115
|
-
routerContextVal.matches &&
|
|
116
|
-
routerContextVal.matches.length > 0
|
|
117
|
-
) {
|
|
118
|
-
const matchIndex = routerContextVal.matches.length - 1;
|
|
119
|
-
const pathnameBase =
|
|
120
|
-
routerContextVal.matches[matchIndex].pathnameBase;
|
|
121
|
-
basename = pathJoin(basename, pathnameBase || '/');
|
|
122
|
-
}
|
|
123
|
-
} /* react-router@5 */ else {
|
|
124
|
-
const match = useRouteMatch?.(); // v5
|
|
125
|
-
if (useHistory /* react-router@5 */) {
|
|
126
|
-
// there is no dynamic switching of the router version in the project
|
|
127
|
-
// so hooks can be used in conditional judgment
|
|
128
|
-
const history = useHistory?.();
|
|
129
|
-
// To be compatible to history@4.10.1 and @5.3.0 we cannot write like this `history.createHref(pathname)`
|
|
130
|
-
basename = history?.createHref?.({ pathname: '/' });
|
|
131
|
-
}
|
|
132
|
-
if (match /* react-router@5 */) {
|
|
133
|
-
basename = pathJoin(basename, match?.path || '/');
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
LoggerInstance.log(`createRemoteComponent withRouterData >>>`, {
|
|
139
|
-
...props,
|
|
140
|
-
basename,
|
|
141
|
-
routerContextVal,
|
|
142
|
-
enableDispathPopstate,
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
if (enableDispathPopstate) {
|
|
146
|
-
const location = ReactRouterDOM.useLocation();
|
|
147
|
-
const [pathname, setPathname] = useState(location.pathname);
|
|
148
|
-
|
|
149
|
-
useEffect(() => {
|
|
150
|
-
if (pathname !== '' && pathname !== location.pathname) {
|
|
151
|
-
LoggerInstance.log(`createRemoteComponent dispatchPopstateEnv >>>`, {
|
|
152
|
-
name: props.name,
|
|
153
|
-
pathname: location.pathname,
|
|
154
|
-
});
|
|
155
|
-
dispatchPopstateEnv();
|
|
156
|
-
}
|
|
157
|
-
setPathname(location.pathname);
|
|
158
|
-
}, [location]);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
return <WrappedComponent {...(props as P)} basename={basename} />;
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
export default withRouterData(RemoteApp);
|