@umijs/plugins 4.0.11 → 4.0.14
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/dist/antd.js +11 -1
- package/dist/layout.js +14 -3
- package/dist/mf.js +9 -0
- package/dist/request.js +1 -0
- package/dist/utils/mfUtils.d.ts +14 -0
- package/dist/utils/mfUtils.js +56 -0
- package/libs/qiankun/master/MicroApp.tsx +1 -2
- package/libs/qiankun/master/common.ts +55 -19
- package/libs/qiankun/master/masterRuntimePlugin.tsx +10 -2
- package/package.json +6 -4
- package/tpls/mf-runtime.ts.tpl +149 -0
package/dist/antd.js
CHANGED
|
@@ -45,12 +45,14 @@ var import_resolveProjectDep = require("./utils/resolveProjectDep");
|
|
|
45
45
|
var import_withTmpPath = require("./utils/withTmpPath");
|
|
46
46
|
var antd_default = (api) => {
|
|
47
47
|
let pkgPath;
|
|
48
|
+
let antdVersion = "4.0.0";
|
|
48
49
|
try {
|
|
49
50
|
pkgPath = (0, import_resolveProjectDep.resolveProjectDep)({
|
|
50
51
|
pkg: api.pkg,
|
|
51
52
|
cwd: api.cwd,
|
|
52
53
|
dep: "antd"
|
|
53
54
|
}) || (0, import_path.dirname)(require.resolve("antd/package.json"));
|
|
55
|
+
antdVersion = require(`${pkgPath}/package.json`).version;
|
|
54
56
|
} catch (e) {
|
|
55
57
|
}
|
|
56
58
|
api.describe({
|
|
@@ -94,6 +96,10 @@ var antd_default = (api) => {
|
|
|
94
96
|
if (antd.dayjs) {
|
|
95
97
|
memo.alias.moment = (0, import_path.dirname)(require.resolve("dayjs/package.json"));
|
|
96
98
|
}
|
|
99
|
+
if (antdVersion.startsWith("5")) {
|
|
100
|
+
const theme = require("@ant-design/antd-theme-variable");
|
|
101
|
+
memo.theme = __spreadValues(__spreadValues({}, theme), memo.theme);
|
|
102
|
+
}
|
|
97
103
|
if (antd.dark || antd.compact) {
|
|
98
104
|
const { getThemeVariables } = require("antd/dist/theme");
|
|
99
105
|
memo.theme = __spreadValues(__spreadValues({}, getThemeVariables(antd)), memo.theme);
|
|
@@ -105,6 +111,9 @@ var antd_default = (api) => {
|
|
|
105
111
|
});
|
|
106
112
|
api.addExtraBabelPlugins(() => {
|
|
107
113
|
const style = api.config.antd.style || "less";
|
|
114
|
+
if (antdVersion.startsWith("5")) {
|
|
115
|
+
return [];
|
|
116
|
+
}
|
|
108
117
|
return api.config.antd.import && !api.appData.vite ? [
|
|
109
118
|
[
|
|
110
119
|
require.resolve("babel-plugin-import"),
|
|
@@ -151,7 +160,8 @@ export function rootContainer(container) {
|
|
|
151
160
|
});
|
|
152
161
|
api.addEntryImportsAhead(() => {
|
|
153
162
|
const style = api.config.antd.style || "less";
|
|
154
|
-
|
|
163
|
+
const doNotImportLess = api.config.antd.import && !api.appData.vite || antdVersion.startsWith("5");
|
|
164
|
+
return doNotImportLess ? [] : [
|
|
155
165
|
{
|
|
156
166
|
source: style === "less" ? "antd/dist/antd.less" : "antd/dist/antd.css"
|
|
157
167
|
}
|
package/dist/layout.js
CHANGED
|
@@ -30,8 +30,19 @@ var import_fs = require("fs");
|
|
|
30
30
|
var import_path = require("path");
|
|
31
31
|
var import_umi = require("umi");
|
|
32
32
|
var import_plugin_utils = require("umi/plugin-utils");
|
|
33
|
+
var import_resolveProjectDep = require("./utils/resolveProjectDep");
|
|
33
34
|
var import_withTmpPath = require("./utils/withTmpPath");
|
|
34
35
|
var layout_default = (api) => {
|
|
36
|
+
let antdVersion = "4.0.0";
|
|
37
|
+
try {
|
|
38
|
+
const pkgPath2 = (0, import_resolveProjectDep.resolveProjectDep)({
|
|
39
|
+
pkg: api.pkg,
|
|
40
|
+
cwd: api.cwd,
|
|
41
|
+
dep: "antd"
|
|
42
|
+
}) || (0, import_path.dirname)(require.resolve("antd/package.json"));
|
|
43
|
+
antdVersion = require(`${pkgPath2}/package.json`).version;
|
|
44
|
+
} catch (e) {
|
|
45
|
+
}
|
|
35
46
|
api.describe({
|
|
36
47
|
key: "layout",
|
|
37
48
|
config: {
|
|
@@ -253,7 +264,7 @@ const { formatMessage } = useIntl();
|
|
|
253
264
|
type InitDataType = ReturnType<typeof InitialStateType>;
|
|
254
265
|
` : "type InitDataType = any;"}
|
|
255
266
|
|
|
256
|
-
import { IConfigFromPlugins } from '@@/core/pluginConfig';
|
|
267
|
+
import type { IConfigFromPlugins } from '@@/core/pluginConfig';
|
|
257
268
|
|
|
258
269
|
export type RunTimeLayoutConfig = (initData: InitDataType) => Omit<
|
|
259
270
|
ProLayoutProps,
|
|
@@ -427,7 +438,7 @@ export function getRightRenderContent (opts: {
|
|
|
427
438
|
api.writeTmpFile({
|
|
428
439
|
path: "Layout.less",
|
|
429
440
|
content: `
|
|
430
|
-
@import '~antd/es/style/themes/default.less';
|
|
441
|
+
${antdVersion.startsWith("5") ? "" : "@import '~antd/es/style/themes/default.less';"}
|
|
431
442
|
@pro-header-hover-bg: rgba(0, 0, 0, 0.025);
|
|
432
443
|
@media screen and (max-width: @screen-xs) {
|
|
433
444
|
// \u5728\u5C0F\u5C4F\u5E55\u7684\u65F6\u5019\u53EF\u4EE5\u6709\u66F4\u597D\u7684\u4F53\u9A8C
|
|
@@ -480,7 +491,7 @@ export function getRightRenderContent (opts: {
|
|
|
480
491
|
.umi-plugin-layout-name {
|
|
481
492
|
margin-left: 8px;
|
|
482
493
|
}
|
|
483
|
-
|
|
494
|
+
`
|
|
484
495
|
});
|
|
485
496
|
api.writeTmpFile({
|
|
486
497
|
path: "Logo.tsx",
|
package/dist/mf.js
CHANGED
|
@@ -25,6 +25,7 @@ module.exports = __toCommonJS(mf_exports);
|
|
|
25
25
|
var import_fs = require("fs");
|
|
26
26
|
var import_path = require("path");
|
|
27
27
|
var import_plugin_utils = require("umi/plugin-utils");
|
|
28
|
+
var import_mfUtils = require("./utils/mfUtils");
|
|
28
29
|
var { isEmpty } = import_plugin_utils.lodash;
|
|
29
30
|
var mfSetupPathFileName = "_mf_setup-public-path.js";
|
|
30
31
|
var mfAsyncEntryFileName = "asyncEntry.ts";
|
|
@@ -86,6 +87,14 @@ function mf(api) {
|
|
|
86
87
|
__webpack_public_path__ = document.currentScript.src + '/../';`,
|
|
87
88
|
path: mfSetupPathFileName
|
|
88
89
|
});
|
|
90
|
+
const { remotes = [] } = api.config.mf;
|
|
91
|
+
api.writeTmpFile({
|
|
92
|
+
path: "index.tsx",
|
|
93
|
+
context: {
|
|
94
|
+
remoteCodeString: (0, import_mfUtils.toRemotesCodeString)(remotes)
|
|
95
|
+
},
|
|
96
|
+
tplPath: (0, import_path.join)(__dirname, "../tpls/mf-runtime.ts.tpl")
|
|
97
|
+
});
|
|
89
98
|
if (api.env === "development" && api.config.mfsu) {
|
|
90
99
|
return;
|
|
91
100
|
}
|
package/dist/request.js
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
declare type SimpleRemote = {
|
|
2
|
+
entry: string;
|
|
3
|
+
name: string;
|
|
4
|
+
aliasName?: string;
|
|
5
|
+
};
|
|
6
|
+
declare type RemoteEntries = {
|
|
7
|
+
name: string;
|
|
8
|
+
entries: object;
|
|
9
|
+
keyResolver: string;
|
|
10
|
+
aliasName?: string;
|
|
11
|
+
};
|
|
12
|
+
declare type Remote = SimpleRemote | RemoteEntries;
|
|
13
|
+
export declare function toRemotesCodeString(remotes: Remote[]): string;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
|
|
19
|
+
// src/utils/mfUtils.ts
|
|
20
|
+
var mfUtils_exports = {};
|
|
21
|
+
__export(mfUtils_exports, {
|
|
22
|
+
toRemotesCodeString: () => toRemotesCodeString
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(mfUtils_exports);
|
|
25
|
+
function isSimpleRemote(r) {
|
|
26
|
+
return r.entry;
|
|
27
|
+
}
|
|
28
|
+
function isRemoteEntries(r) {
|
|
29
|
+
return r.entries && r.keyResolver;
|
|
30
|
+
}
|
|
31
|
+
function toRemotesCodeString(remotes) {
|
|
32
|
+
const res = [];
|
|
33
|
+
for (const r of remotes) {
|
|
34
|
+
const aliasName = r.aliasName || r.name;
|
|
35
|
+
const remoteName = r.name;
|
|
36
|
+
if (isSimpleRemote(r)) {
|
|
37
|
+
res.push(`${aliasName}: {
|
|
38
|
+
aliasName: "${aliasName}",
|
|
39
|
+
remoteName: "${remoteName}",
|
|
40
|
+
entry: "${r.entry}"
|
|
41
|
+
}`);
|
|
42
|
+
}
|
|
43
|
+
if (isRemoteEntries(r)) {
|
|
44
|
+
res.push(`${aliasName}: {
|
|
45
|
+
aliasName: "${aliasName}",
|
|
46
|
+
remoteName: "${remoteName}",
|
|
47
|
+
entry: (${JSON.stringify(r.entries)})[${r.keyResolver}]
|
|
48
|
+
}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return res.join(",\n");
|
|
52
|
+
}
|
|
53
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
54
|
+
0 && (module.exports = {
|
|
55
|
+
toRemotesCodeString
|
|
56
|
+
});
|
|
@@ -18,13 +18,12 @@ import React, {
|
|
|
18
18
|
useRef,
|
|
19
19
|
useState,
|
|
20
20
|
} from 'react';
|
|
21
|
+
import { qiankunStateForSlaveModelNamespace } from './constants';
|
|
21
22
|
import { ErrorBoundary } from './ErrorBoundary';
|
|
22
23
|
import { getMasterOptions } from './masterOptions';
|
|
23
24
|
import MicroAppLoader from './MicroAppLoader';
|
|
24
25
|
import { MasterOptions } from './types';
|
|
25
26
|
|
|
26
|
-
const qiankunStateForSlaveModelNamespace = '@@qiankunStateForSlave';
|
|
27
|
-
|
|
28
27
|
type HashHistory = {
|
|
29
28
|
type?: 'hash';
|
|
30
29
|
} & any;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import React, { ReactComponentElement } from 'react';
|
|
9
|
-
import type
|
|
9
|
+
import { Navigate, type IRouteProps } from 'umi';
|
|
10
10
|
|
|
11
11
|
export const defaultMountContainerId = 'root-subapp';
|
|
12
12
|
|
|
@@ -94,19 +94,30 @@ export function patchMicroAppRoute(
|
|
|
94
94
|
routeProps,
|
|
95
95
|
};
|
|
96
96
|
route.element = React.createElement(getMicroAppRouteComponent(opts), null);
|
|
97
|
+
} else if (route.redirect) {
|
|
98
|
+
// patchClientRoutes 插入的 redirect 不会被转换,所以这里需要手动处理成重定向组件
|
|
99
|
+
route.element = React.createElement(Navigate, {
|
|
100
|
+
to: route.redirect,
|
|
101
|
+
replace: true,
|
|
102
|
+
});
|
|
97
103
|
}
|
|
98
104
|
}
|
|
99
105
|
|
|
100
106
|
const recursiveSearch = (
|
|
101
107
|
routes: IRouteProps[],
|
|
102
108
|
path: string,
|
|
103
|
-
|
|
109
|
+
parentPath: string,
|
|
110
|
+
): [IRouteProps, IRouteProps[], number, string] | null => {
|
|
104
111
|
for (let i = 0; i < routes.length; i++) {
|
|
105
112
|
if (routes[i].path === path) {
|
|
106
|
-
return routes[i];
|
|
113
|
+
return [routes[i], routes, i, parentPath];
|
|
107
114
|
}
|
|
108
115
|
if (routes[i].children && routes[i].children?.length) {
|
|
109
|
-
const found = recursiveSearch(
|
|
116
|
+
const found = recursiveSearch(
|
|
117
|
+
routes[i].children || [],
|
|
118
|
+
path,
|
|
119
|
+
routes[i].path,
|
|
120
|
+
);
|
|
110
121
|
if (found) {
|
|
111
122
|
return found;
|
|
112
123
|
}
|
|
@@ -116,23 +127,48 @@ const recursiveSearch = (
|
|
|
116
127
|
};
|
|
117
128
|
|
|
118
129
|
export function insertRoute(routes: IRouteProps[], microAppRoute: IRouteProps) {
|
|
119
|
-
const
|
|
130
|
+
const mod =
|
|
131
|
+
microAppRoute.appendChildTo || microAppRoute.insert
|
|
132
|
+
? 'appendChildTo'
|
|
133
|
+
: microAppRoute.insertBefore
|
|
134
|
+
? 'insertBefore'
|
|
135
|
+
: undefined;
|
|
136
|
+
const target =
|
|
137
|
+
microAppRoute.appendChildTo ||
|
|
138
|
+
microAppRoute.insert ||
|
|
139
|
+
microAppRoute.insertBefore;
|
|
140
|
+
const [found, foundParentRoutes = [], index = 0, parentPath] =
|
|
141
|
+
recursiveSearch(routes, target, '/') || [];
|
|
120
142
|
if (found) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
143
|
+
switch (mod) {
|
|
144
|
+
case 'appendChildTo':
|
|
145
|
+
if (
|
|
146
|
+
!microAppRoute.path ||
|
|
147
|
+
!found.path ||
|
|
148
|
+
!microAppRoute.path.startsWith(found.path)
|
|
149
|
+
) {
|
|
150
|
+
throw new Error(
|
|
151
|
+
`[plugin-qiankun]: path "${microAppRoute.path}" need to starts with "${found.path}"`,
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
found.exact = false;
|
|
155
|
+
found.children = found.children || [];
|
|
156
|
+
found.children.push(microAppRoute);
|
|
157
|
+
break;
|
|
158
|
+
case 'insertBefore':
|
|
159
|
+
if (
|
|
160
|
+
!microAppRoute.path ||
|
|
161
|
+
!found.path ||
|
|
162
|
+
!microAppRoute.path.startsWith(parentPath)
|
|
163
|
+
) {
|
|
164
|
+
throw new Error(
|
|
165
|
+
`[plugin-qiankun]: path "${microAppRoute.path}" need to starts with "${parentPath}"`,
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
foundParentRoutes.splice(index, 0, microAppRoute);
|
|
169
|
+
break;
|
|
129
170
|
}
|
|
130
|
-
found.exact = false;
|
|
131
|
-
found.children = found.children || [];
|
|
132
|
-
found.children.push(microAppRoute);
|
|
133
171
|
} else {
|
|
134
|
-
throw new Error(
|
|
135
|
-
`[plugin-qiankun]: path "${microAppRoute.insert}" not found`,
|
|
136
|
-
);
|
|
172
|
+
throw new Error(`[plugin-qiankun]: path "${target}" not found`);
|
|
137
173
|
}
|
|
138
174
|
}
|
|
@@ -24,7 +24,9 @@ async function getMasterRuntime() {
|
|
|
24
24
|
|
|
25
25
|
// modify route with "microApp" attribute to use real component
|
|
26
26
|
function patchMicroAppRouteComponent(routes: any[]) {
|
|
27
|
-
const insertRoutes = microAppRuntimeRoutes.filter(
|
|
27
|
+
const insertRoutes = microAppRuntimeRoutes.filter(
|
|
28
|
+
(r) => r.insert || r.insertBefore || r.appendChildTo,
|
|
29
|
+
);
|
|
28
30
|
// 先处理 insert 配置
|
|
29
31
|
insertRoutes.forEach((route) => {
|
|
30
32
|
insertRoute(routes, route);
|
|
@@ -60,7 +62,13 @@ function patchMicroAppRouteComponent(routes: any[]) {
|
|
|
60
62
|
};
|
|
61
63
|
|
|
62
64
|
patchRoute(microAppRoute);
|
|
63
|
-
|
|
65
|
+
if (
|
|
66
|
+
!microAppRoute.insert &&
|
|
67
|
+
!microAppRoute.insertBefore &&
|
|
68
|
+
!microAppRoute.appendChildTo
|
|
69
|
+
) {
|
|
70
|
+
rootRoutes.unshift(microAppRoute);
|
|
71
|
+
}
|
|
64
72
|
});
|
|
65
73
|
}
|
|
66
74
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umijs/plugins",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.14",
|
|
4
4
|
"description": "@umijs/plugins",
|
|
5
5
|
"homepage": "https://github.com/umijs/umi/tree/master/packages/plugins#readme",
|
|
6
6
|
"bugs": "https://github.com/umijs/umi/issues",
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
"types": "dist/index.d.ts",
|
|
14
14
|
"files": [
|
|
15
15
|
"dist",
|
|
16
|
-
"libs"
|
|
16
|
+
"libs",
|
|
17
|
+
"tpls"
|
|
17
18
|
],
|
|
18
19
|
"scripts": {
|
|
19
20
|
"build": "umi-scripts father build",
|
|
@@ -23,9 +24,10 @@
|
|
|
23
24
|
},
|
|
24
25
|
"dependencies": {
|
|
25
26
|
"@ahooksjs/use-request": "^2.0.0",
|
|
27
|
+
"@ant-design/antd-theme-variable": "^1.0.0",
|
|
26
28
|
"@ant-design/icons": "^4.7.0",
|
|
27
29
|
"@ant-design/pro-layout": "^7.0.1-beta.28",
|
|
28
|
-
"@umijs/bundler-utils": "4.0.
|
|
30
|
+
"@umijs/bundler-utils": "4.0.14",
|
|
29
31
|
"antd-dayjs-webpack-plugin": "^1.0.6",
|
|
30
32
|
"axios": "^0.27.2",
|
|
31
33
|
"babel-plugin-import": "^1.13.5",
|
|
@@ -44,7 +46,7 @@
|
|
|
44
46
|
"warning": "^4.0.3"
|
|
45
47
|
},
|
|
46
48
|
"devDependencies": {
|
|
47
|
-
"umi": "4.0.
|
|
49
|
+
"umi": "4.0.14"
|
|
48
50
|
},
|
|
49
51
|
"publishConfig": {
|
|
50
52
|
"access": "public"
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { lazy, Suspense } from 'react'
|
|
2
|
+
import type { Component, ReactNode } from 'react'
|
|
3
|
+
const remotes = {
|
|
4
|
+
{{{ remoteCodeString }}}
|
|
5
|
+
};
|
|
6
|
+
const scriptLoadedMap: Record<string, Promise<void> | 0 | undefined> = {};
|
|
7
|
+
|
|
8
|
+
type MFModuleImportRequest = { entry: string; remoteName: string; moduleName: string; }
|
|
9
|
+
type MFModuleRegisterRequest = { entry: string; remoteName: string; aliasName?:string; }
|
|
10
|
+
|
|
11
|
+
export async function rawMfImport(opts: MFModuleImportRequest) {
|
|
12
|
+
await loadRemoteScriptWithCache(opts.remoteName, opts.entry);
|
|
13
|
+
return getRemoteModule(opts.remoteName, opts.moduleName);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function registerMfRemote (opts: MFModuleRegisterRequest) {
|
|
17
|
+
const aliasName = opts.aliasName || opts.remoteName;
|
|
18
|
+
if( remotes[aliasName] ){
|
|
19
|
+
return console.warn(`registerMfRemote: ${aliasName} is already registered as`, remotes[aliasName]);
|
|
20
|
+
}
|
|
21
|
+
remotes[aliasName] ={
|
|
22
|
+
...opts,
|
|
23
|
+
aliasName,
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export async function safeMfImport(moduleSpecifier: any, fallback: any) {
|
|
28
|
+
try {
|
|
29
|
+
const i = moduleSpecifier.indexOf('/');
|
|
30
|
+
if (i < 0) {
|
|
31
|
+
console.error(
|
|
32
|
+
`safeMfImport: bad Module Name ${moduleSpecifier}, should match pattern 'remote/moduleName'`,
|
|
33
|
+
moduleSpecifier,
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
return fallback;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const aliasName = moduleSpecifier.slice(0, i);
|
|
40
|
+
const module = moduleSpecifier.slice(i + 1);
|
|
41
|
+
const entry = remotes[aliasName]?.entry;
|
|
42
|
+
const remoteName = remotes[aliasName]?.remoteName;
|
|
43
|
+
|
|
44
|
+
if(!entry){
|
|
45
|
+
console.error(
|
|
46
|
+
`safeMfImport: bad Module Name ${moduleSpecifier}, no remote for "aliasName"`,
|
|
47
|
+
moduleSpecifier,
|
|
48
|
+
);
|
|
49
|
+
return fallback;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
await loadRemoteScriptWithCache(remoteName, entry);
|
|
53
|
+
|
|
54
|
+
return getRemoteModule(remoteName, module);
|
|
55
|
+
} catch (e) {
|
|
56
|
+
console.error('safeMfImport: Module', moduleSpecifier, 'failed', e);
|
|
57
|
+
return fallback;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async function loadScript(url): Promise<void> {
|
|
62
|
+
const element = document.createElement('script');
|
|
63
|
+
element.src = url;
|
|
64
|
+
element.type = 'text/javascript';
|
|
65
|
+
element.async = true;
|
|
66
|
+
|
|
67
|
+
const loadScriptQ = new Promise<void>((resolve, reject) => {
|
|
68
|
+
element.onload = () => {
|
|
69
|
+
document.head.removeChild(element);
|
|
70
|
+
resolve();
|
|
71
|
+
};
|
|
72
|
+
element.onerror = (e) => {
|
|
73
|
+
document.head.removeChild(element);
|
|
74
|
+
reject(e);
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
document.head.appendChild(element);
|
|
78
|
+
|
|
79
|
+
return loadScriptQ;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async function getRemoteModule(remoteName:string, moduleName: string): any {
|
|
83
|
+
// @ts-ignore
|
|
84
|
+
await __webpack_init_sharing__('default');
|
|
85
|
+
const container = window[remoteName]; // or get the container somewhere else
|
|
86
|
+
// Initialize the container, it may provide shared modules
|
|
87
|
+
// @ts-ignore
|
|
88
|
+
await container.init(__webpack_share_scopes__.default);
|
|
89
|
+
// @ts-ignore
|
|
90
|
+
const factory = await window[remoteName].get(`./${moduleName}`);
|
|
91
|
+
return factory();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async function loadRemoteScriptWithCache(remoteName:string, url: string): Promise<void> {
|
|
95
|
+
|
|
96
|
+
const loadCache = scriptLoadedMap[remoteName];
|
|
97
|
+
let scriptLoadQ: Promise<void> | null = null;
|
|
98
|
+
|
|
99
|
+
if(loadCache === 0){
|
|
100
|
+
// script Already loaded
|
|
101
|
+
return;
|
|
102
|
+
} else if(loadCache) {
|
|
103
|
+
await loadCache
|
|
104
|
+
}else{
|
|
105
|
+
let p = loadScript(url).then(()=>{
|
|
106
|
+
scriptLoadedMap[remoteName] = 0;
|
|
107
|
+
},(e)=>{
|
|
108
|
+
scriptLoadedMap[remoteName] = undefined;
|
|
109
|
+
throw e;
|
|
110
|
+
});
|
|
111
|
+
scriptLoadedMap[remoteName] = p;
|
|
112
|
+
await p;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
type SafeRemoteComponentOpts ={
|
|
117
|
+
moduleSpecifier:string;
|
|
118
|
+
fallbackComponent: ComponentType<any>;
|
|
119
|
+
loadingElement: ReactNode
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function safeRemoteComponent<T extends ComponentType<any>>(opts: SafeRemoteComponentOpts): T {
|
|
123
|
+
const Lazy = lazy<T>(()=>safeMfImport(opts.moduleSpecifier, { default: opts.fallbackComponent }));
|
|
124
|
+
return (props)=> (<Suspense fallback={opts.loadingElement}>
|
|
125
|
+
<Lazy {...props} />
|
|
126
|
+
</Suspense>)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
type RawRemoteComponentOpts ={
|
|
130
|
+
mfConfig:{
|
|
131
|
+
entry:string;
|
|
132
|
+
remoteName: string;
|
|
133
|
+
moduleName: string;
|
|
134
|
+
};
|
|
135
|
+
fallbackComponent: ComponentType<any>;
|
|
136
|
+
loadingElement: ReactNode;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export function safeRemoteComponentWithMfConfig<T extends ComponentType<any>>(opts: RawRemoteComponentOpts): T {
|
|
140
|
+
const Lazy = lazy<T>(()=>{
|
|
141
|
+
return rawMfImport(opts.mfConfig)
|
|
142
|
+
.catch(()=>{
|
|
143
|
+
return { default: opts.fallbackComponent };
|
|
144
|
+
})
|
|
145
|
+
})
|
|
146
|
+
return (props)=> (<Suspense fallback={opts.loadingElement}>
|
|
147
|
+
<Lazy {...props} />
|
|
148
|
+
</Suspense>)
|
|
149
|
+
}
|