@fulgurjs/federation 4.3.1 → 5.0.0
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 +23 -0
- package/DESIGN.md +1 -0
- package/README.md +26 -33
- package/dist/cli.js +58 -467
- package/dist/context.js +11 -3
- package/dist/index.cjs +28 -26
- package/dist/index.d.cts +87 -2
- package/dist/index.d.ts +87 -2
- package/dist/index.js +30 -29
- package/dist/runtime.js +1 -1
- package/dist/vue-adapter.js +135 -4
- package/docs//350/277/201/347/247/273/346/214/207/345/215/227.md +14 -2
- package/package.json +2 -15
- package/dist/chunk-LU3MBKB2.js +0 -6
- package/dist/chunk-NOMYWDZN.js +0 -141
- package/dist/chunk-WBCXLR2N.js +0 -46
- package/dist/config.cjs +0 -174
- package/dist/config.d.cts +0 -106
- package/dist/config.d.ts +0 -106
- package/dist/config.js +0 -136
- package/dist/options-CRGpSmVj.d.cts +0 -100
- package/dist/options-CRGpSmVj.d.ts +0 -100
- package/dist/vue.cjs +0 -1310
- package/dist/vue.d.cts +0 -10
- package/dist/vue.d.ts +0 -10
package/dist/vue.cjs
DELETED
|
@@ -1,1310 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/vue.ts
|
|
21
|
-
var vue_exports = {};
|
|
22
|
-
__export(vue_exports, {
|
|
23
|
-
createHostPages: () => createHostPages2,
|
|
24
|
-
remoteComponent: () => remoteComponent
|
|
25
|
-
});
|
|
26
|
-
module.exports = __toCommonJS(vue_exports);
|
|
27
|
-
|
|
28
|
-
// src/semver.ts
|
|
29
|
-
var VERSION_RE = /^v?(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:-((?:[0-9A-Za-z-]+)(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z.-]+)?$/;
|
|
30
|
-
function parseVersion(input) {
|
|
31
|
-
const m = VERSION_RE.exec(String(input).trim());
|
|
32
|
-
if (!m) return null;
|
|
33
|
-
return {
|
|
34
|
-
major: Number(m[1]),
|
|
35
|
-
minor: Number(m[2] ?? 0),
|
|
36
|
-
patch: Number(m[3] ?? 0),
|
|
37
|
-
pre: m[4] ? m[4].split(".") : []
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
function preCompare(a, b) {
|
|
41
|
-
if (a.length === 0 && b.length === 0) return 0;
|
|
42
|
-
if (a.length === 0) return 1;
|
|
43
|
-
if (b.length === 0) return -1;
|
|
44
|
-
const len = Math.max(a.length, b.length);
|
|
45
|
-
for (let i = 0; i < len; i++) {
|
|
46
|
-
const x = a[i];
|
|
47
|
-
const y = b[i];
|
|
48
|
-
if (x === void 0) return -1;
|
|
49
|
-
if (y === void 0) return 1;
|
|
50
|
-
const xn = /^\d+$/.test(x);
|
|
51
|
-
const yn = /^\d+$/.test(y);
|
|
52
|
-
if (xn && yn) {
|
|
53
|
-
const d = Number(x) - Number(y);
|
|
54
|
-
if (d !== 0) return d;
|
|
55
|
-
} else if (xn !== yn) {
|
|
56
|
-
return xn ? -1 : 1;
|
|
57
|
-
} else if (x !== y) {
|
|
58
|
-
return x < y ? -1 : 1;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
return 0;
|
|
62
|
-
}
|
|
63
|
-
function compareVersions(a, b) {
|
|
64
|
-
const va = parseVersion(a);
|
|
65
|
-
const vb = parseVersion(b);
|
|
66
|
-
if (!va || !vb) return a < b ? -1 : a > b ? 1 : 0;
|
|
67
|
-
if (va.major !== vb.major) return va.major - vb.major;
|
|
68
|
-
if (va.minor !== vb.minor) return va.minor - vb.minor;
|
|
69
|
-
if (va.patch !== vb.patch) return va.patch - vb.patch;
|
|
70
|
-
return preCompare(va.pre, vb.pre);
|
|
71
|
-
}
|
|
72
|
-
var ANY_RANGE = /^[a-z]+[+:-]/i;
|
|
73
|
-
function satisfies(version, range) {
|
|
74
|
-
if (range === false || range == null || range === "") return true;
|
|
75
|
-
const rangeStr = String(range).trim();
|
|
76
|
-
if (!rangeStr || rangeStr === "*" || rangeStr === "latest" || ANY_RANGE.test(rangeStr)) return true;
|
|
77
|
-
return rangeStr.split("||").some((part) => satisfiesSet(version, part.trim()));
|
|
78
|
-
}
|
|
79
|
-
function satisfiesSet(version, set) {
|
|
80
|
-
if (!set || set === "*") return !parseVersion(version)?.pre.length;
|
|
81
|
-
const hyphen = set.split(/\s+-\s+/);
|
|
82
|
-
if (hyphen.length === 2) {
|
|
83
|
-
const lo = hyphen[0].trim();
|
|
84
|
-
const hi = hyphen[1].trim();
|
|
85
|
-
if (!satisfies(version, `>=${lo}`)) return false;
|
|
86
|
-
if (!satisfies(version, `<=${hi}`)) return false;
|
|
87
|
-
return true;
|
|
88
|
-
}
|
|
89
|
-
const v = parseVersion(version);
|
|
90
|
-
if (!v) return false;
|
|
91
|
-
const comps = parseComparators(set);
|
|
92
|
-
if (comps === null) return true;
|
|
93
|
-
for (const c of comps) {
|
|
94
|
-
if (!testComparator(v, version, c)) return false;
|
|
95
|
-
}
|
|
96
|
-
if (v.pre.length > 0 && !comps.some((c) => c.ver.pre.length > 0)) {
|
|
97
|
-
const tupleMatch = comps.some(
|
|
98
|
-
(c) => c.ver.major === v.major && c.ver.minor === v.minor && c.ver.patch === v.patch
|
|
99
|
-
);
|
|
100
|
-
if (!tupleMatch) return false;
|
|
101
|
-
}
|
|
102
|
-
return true;
|
|
103
|
-
}
|
|
104
|
-
function parseComparators(set) {
|
|
105
|
-
const comps = [];
|
|
106
|
-
const tokens = set.trim().split(/\s+/).filter(Boolean);
|
|
107
|
-
if (tokens.length === 0) return null;
|
|
108
|
-
for (const token of tokens) {
|
|
109
|
-
const m = /^(>=|<=|>|<|=|\^|~)?(.*)$/.exec(token);
|
|
110
|
-
if (!m) return null;
|
|
111
|
-
const op = m[1];
|
|
112
|
-
const raw = m[2];
|
|
113
|
-
const c = buildComparator(op, raw);
|
|
114
|
-
if (c === null) return null;
|
|
115
|
-
comps.push(...c);
|
|
116
|
-
}
|
|
117
|
-
return comps;
|
|
118
|
-
}
|
|
119
|
-
function buildComparator(op, raw) {
|
|
120
|
-
const parsed = parseLoose(raw);
|
|
121
|
-
if (!parsed) return null;
|
|
122
|
-
const { ver, partial } = parsed;
|
|
123
|
-
switch (op) {
|
|
124
|
-
case "^": {
|
|
125
|
-
const upper = caretUpper(ver);
|
|
126
|
-
if (!upper) return null;
|
|
127
|
-
return [{ op: ">=", ver }, { op: "<", ver: upper }];
|
|
128
|
-
}
|
|
129
|
-
case "~": {
|
|
130
|
-
const upper = partial >= 2 ? { major: ver.major, minor: ver.minor + 1, patch: 0, pre: [] } : { major: ver.major + 1, minor: 0, patch: 0, pre: [] };
|
|
131
|
-
return [{ op: ">=", ver }, { op: "<", ver: upper }];
|
|
132
|
-
}
|
|
133
|
-
case ">=":
|
|
134
|
-
return [{ op: ">=", ver }];
|
|
135
|
-
case ">":
|
|
136
|
-
if (partial === 1) return [{ op: ">=", ver: { major: ver.major + 1, minor: 0, patch: 0, pre: [] } }];
|
|
137
|
-
if (partial === 2)
|
|
138
|
-
return [{ op: ">=", ver: { major: ver.major, minor: ver.minor + 1, patch: 0, pre: [] } }];
|
|
139
|
-
return [{ op: ">", ver }];
|
|
140
|
-
case "<":
|
|
141
|
-
if (partial === 1) return [{ op: "<", ver: { major: ver.major, minor: 0, patch: 0, pre: [] } }];
|
|
142
|
-
if (partial === 2)
|
|
143
|
-
return [{ op: "<", ver: { major: ver.major, minor: ver.minor, patch: 0, pre: [] } }];
|
|
144
|
-
return [{ op: "<", ver }];
|
|
145
|
-
case "<=":
|
|
146
|
-
return [{ op: "<=", ver }];
|
|
147
|
-
case "=":
|
|
148
|
-
case void 0:
|
|
149
|
-
if (partial === 1)
|
|
150
|
-
return [
|
|
151
|
-
{ op: ">=", ver },
|
|
152
|
-
{ op: "<", ver: { major: ver.major + 1, minor: 0, patch: 0, pre: [] } }
|
|
153
|
-
];
|
|
154
|
-
if (partial === 2)
|
|
155
|
-
return [
|
|
156
|
-
{ op: ">=", ver },
|
|
157
|
-
{ op: "<", ver: { major: ver.major, minor: ver.minor + 1, patch: 0, pre: [] } }
|
|
158
|
-
];
|
|
159
|
-
return [{ op: "=", ver }];
|
|
160
|
-
default:
|
|
161
|
-
return null;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
function caretUpper(ver) {
|
|
165
|
-
if (ver.major > 0) return { major: ver.major + 1, minor: 0, patch: 0, pre: [] };
|
|
166
|
-
if (ver.minor > 0) return { major: 0, minor: ver.minor + 1, patch: 0, pre: [] };
|
|
167
|
-
return { major: 0, minor: 0, patch: ver.patch + 1, pre: [] };
|
|
168
|
-
}
|
|
169
|
-
function parseLoose(raw) {
|
|
170
|
-
const cleaned = raw.replace(/^v/, "").trim();
|
|
171
|
-
if (!cleaned || cleaned === "*" || cleaned === "x" || cleaned === "X") {
|
|
172
|
-
return { ver: { major: 0, minor: 0, patch: 0, pre: [] }, partial: 0 };
|
|
173
|
-
}
|
|
174
|
-
const parts = cleaned.split(".");
|
|
175
|
-
const nums = [];
|
|
176
|
-
let partial = 0;
|
|
177
|
-
for (const p of parts.slice(0, 3)) {
|
|
178
|
-
if (/^\d+$/.test(p)) {
|
|
179
|
-
nums.push(Number(p));
|
|
180
|
-
partial++;
|
|
181
|
-
} else if (p === "x" || p === "X" || p === "*") {
|
|
182
|
-
break;
|
|
183
|
-
} else {
|
|
184
|
-
break;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
const rest = cleaned.split("-");
|
|
188
|
-
const pre = rest.length > 1 ? rest.slice(1).join("-").split("+")[0].split(".") : [];
|
|
189
|
-
if (partial === 0 && pre.length === 0) return { ver: { major: 0, minor: 0, patch: 0, pre: [] }, partial: 0 };
|
|
190
|
-
return {
|
|
191
|
-
ver: { major: nums[0] ?? 0, minor: nums[1] ?? 0, patch: nums[2] ?? 0, pre },
|
|
192
|
-
partial
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
function cmpToBool(cmp, op) {
|
|
196
|
-
switch (op) {
|
|
197
|
-
case ">=":
|
|
198
|
-
return cmp >= 0;
|
|
199
|
-
case ">":
|
|
200
|
-
return cmp > 0;
|
|
201
|
-
case "<":
|
|
202
|
-
return cmp < 0;
|
|
203
|
-
case "<=":
|
|
204
|
-
return cmp <= 0;
|
|
205
|
-
case "=":
|
|
206
|
-
return cmp === 0;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
function testComparator(v, versionStr, c) {
|
|
210
|
-
const full = `${v.major}.${v.minor}.${v.patch}` + (v.pre.length ? `-${v.pre.join(".")}` : "");
|
|
211
|
-
if (c.upper) {
|
|
212
|
-
const cmpLo = compareVersions(full, `${c.ver.major}.${c.ver.minor}.${c.ver.patch}` + (c.ver.pre.length ? `-${c.ver.pre.join(".")}` : ""));
|
|
213
|
-
if (!(cmpLo >= 0)) return false;
|
|
214
|
-
const cmpHi = compareVersions(full, `${c.upper.major}.${c.upper.minor}.${c.upper.patch}`);
|
|
215
|
-
if (!(cmpHi < 0)) return false;
|
|
216
|
-
return true;
|
|
217
|
-
}
|
|
218
|
-
const cmp = compareVersions(full, `${c.ver.major}.${c.ver.minor}.${c.ver.patch}` + (c.ver.pre.length ? `-${c.ver.pre.join(".")}` : ""));
|
|
219
|
-
const baseOk = cmpToBool(cmp, c.op);
|
|
220
|
-
if (c.ver.pre.length > 0 && v.pre.length === 0 && (c.op === ">" || c.op === "<")) {
|
|
221
|
-
return false;
|
|
222
|
-
}
|
|
223
|
-
return baseOk;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// src/runtime/errors.ts
|
|
227
|
-
var FgError = class extends Error {
|
|
228
|
-
code;
|
|
229
|
-
details;
|
|
230
|
-
constructor(code, message, details) {
|
|
231
|
-
super(`[fulgurjs:${code}] ${message}`);
|
|
232
|
-
this.name = "FgError";
|
|
233
|
-
this.code = code;
|
|
234
|
-
this.details = details;
|
|
235
|
-
}
|
|
236
|
-
};
|
|
237
|
-
var ErrorCodes = {
|
|
238
|
-
/** 远程容器加载失败(网络/超时/重试耗尽/熔断) */
|
|
239
|
-
REMOTE_LOAD_FAILED: "MFU-001",
|
|
240
|
-
/** remoteEntry 自报名与 remotes 配置的名称不匹配 */
|
|
241
|
-
REMOTE_NAME_MISMATCH: "MFU-002",
|
|
242
|
-
/** strictVersion 开启且共享版本不满足 */
|
|
243
|
-
SHARE_STRICT_VERSION: "MFU-003",
|
|
244
|
-
/** 共享模块缺失且无本地 fallback(import: false) */
|
|
245
|
-
SHARE_NOT_AVAILABLE: "MFU-004",
|
|
246
|
-
/** 同一容器用不同 share scope 重复 init */
|
|
247
|
-
CONTAINER_REINIT_CONFLICT: "MFU-005",
|
|
248
|
-
/** 请求的模块未被该远程 exposes */
|
|
249
|
-
MODULE_NOT_EXPOSED: "MFU-006",
|
|
250
|
-
/** 预加载失败 */
|
|
251
|
-
PRELOAD_FAILED: "MFU-007",
|
|
252
|
-
/** 未知远程 */
|
|
253
|
-
REMOTE_UNKNOWN: "MFU-008",
|
|
254
|
-
/** 加载到的模块没有任何导出(常见:exposes 指向了不导出内容的文件) */
|
|
255
|
-
EMPTY_EXPORTS: "MFU-009",
|
|
256
|
-
/** singleton 共享协商版本与消费方 requiredVersion 不一致(使用作用域版本,仅告警) */
|
|
257
|
-
SINGLETON_SKEW: "MFU-010",
|
|
258
|
-
/** setup 生命周期入口导出形态非法(默认导出不是函数,或具名 onSession 不是函数) */
|
|
259
|
-
SETUP_INVALID_EXPORT: "MFU-011",
|
|
260
|
-
/** setup/onSession 执行抛错(该次 loadRemote 拒绝;仅清失败阶段缓存,允许重试) */
|
|
261
|
-
SETUP_RUN_FAILED: "MFU-012",
|
|
262
|
-
/** 远程声明了 onSession 但宿主 AppContext 未提供 sessionKey(登录代次) */
|
|
263
|
-
SETUP_SESSION_KEY_MISSING: "MFU-013",
|
|
264
|
-
/** setup/onSession 执行的同步段内递归 loadRemote 同一远程 */
|
|
265
|
-
SETUP_RECURSION: "MFU-014"
|
|
266
|
-
};
|
|
267
|
-
|
|
268
|
-
// src/runtime/index.ts
|
|
269
|
-
var SETUP_META_KEY = "__fulgurjsSetup";
|
|
270
|
-
var APP_CONTEXT_GLOBAL_KEY = "__FULGURJS_APP_CONFIG__";
|
|
271
|
-
var DEFAULT_TIMEOUT = 15e3;
|
|
272
|
-
var DEFAULT_RETRIES = 2;
|
|
273
|
-
var BREAKER_THRESHOLD = 5;
|
|
274
|
-
var BREAKER_RESET_MS = 3e4;
|
|
275
|
-
var BACKOFF_MAX_MS = 4e3;
|
|
276
|
-
var BACKOFF_JITTER = 0.2;
|
|
277
|
-
function createRuntime() {
|
|
278
|
-
const shareScopeMap2 = /* @__PURE__ */ Object.create(null);
|
|
279
|
-
const remotes = /* @__PURE__ */ new Map();
|
|
280
|
-
const plugins = [];
|
|
281
|
-
const reportedSingletonSkews = /* @__PURE__ */ new Set();
|
|
282
|
-
const loadedModules = /* @__PURE__ */ new Map();
|
|
283
|
-
const remoteManifests = /* @__PURE__ */ new Map();
|
|
284
|
-
const stylesheetLoads = /* @__PURE__ */ new WeakMap();
|
|
285
|
-
const containerInitScopes = /* @__PURE__ */ new WeakMap();
|
|
286
|
-
const hooks = {};
|
|
287
|
-
const applyPlugins = () => {
|
|
288
|
-
for (const p of plugins) {
|
|
289
|
-
try {
|
|
290
|
-
p.init?.(hooks);
|
|
291
|
-
} catch (err) {
|
|
292
|
-
console.warn("[fulgurjs] \u8FD0\u884C\u65F6\u6269\u5C55\u521D\u59CB\u5316\u5931\u8D25\uFF0C\u8BE5\u6269\u5C55\u5C06\u4E0D\u53EF\u7528\uFF1A", p.name, err);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
};
|
|
296
|
-
const lifecycleStates = /* @__PURE__ */ new Map();
|
|
297
|
-
let lifecycleSyncRemote;
|
|
298
|
-
const lifecycleOf = (name) => {
|
|
299
|
-
let st = lifecycleStates.get(name);
|
|
300
|
-
if (!st) lifecycleStates.set(name, st = {});
|
|
301
|
-
return st;
|
|
302
|
-
};
|
|
303
|
-
const currentAppContext = () => globalThis[APP_CONTEXT_GLOBAL_KEY] ?? {};
|
|
304
|
-
async function invokeLifecycleFn(remoteName, fn, ctx, phase) {
|
|
305
|
-
const wrap = (err) => {
|
|
306
|
-
if (err instanceof FgError) return err;
|
|
307
|
-
return new FgError(
|
|
308
|
-
ErrorCodes.SETUP_RUN_FAILED,
|
|
309
|
-
`\u73B0\u8C61\uFF1A\u8FDC\u7A0B\u5E94\u7528 "${remoteName}" \u7684 ${phase} \u521D\u59CB\u5316\u5931\u8D25\u3002
|
|
310
|
-
\u539F\u56E0\uFF1A${String(err?.message ?? err)}
|
|
311
|
-
\u4FEE\u6CD5\uFF1A\u68C0\u67E5\u5E76\u4FEE\u590D\u8BE5 ${phase} \u51FD\u6570\u540E\u91CD\u65B0\u52A0\u8F7D\uFF1B\u5931\u8D25\u7F13\u5B58\u5DF2\u6E05\u9664\uFF0C\u53EF\u4EE5\u76F4\u63A5\u91CD\u8BD5\u3002`,
|
|
312
|
-
{ remote: remoteName, phase }
|
|
313
|
-
);
|
|
314
|
-
};
|
|
315
|
-
lifecycleSyncRemote = remoteName;
|
|
316
|
-
let result;
|
|
317
|
-
try {
|
|
318
|
-
result = fn(ctx);
|
|
319
|
-
} catch (err) {
|
|
320
|
-
throw wrap(err);
|
|
321
|
-
} finally {
|
|
322
|
-
lifecycleSyncRemote = void 0;
|
|
323
|
-
}
|
|
324
|
-
try {
|
|
325
|
-
await result;
|
|
326
|
-
} catch (err) {
|
|
327
|
-
throw wrap(err);
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
async function runSetupPhase(remote, container, setupKey, st) {
|
|
331
|
-
remote.debug.setup = "pending";
|
|
332
|
-
try {
|
|
333
|
-
if (remote.manifestUrl) {
|
|
334
|
-
try {
|
|
335
|
-
await preloadRemote2(`${remote.name}/${setupKey}`);
|
|
336
|
-
} catch {
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
const mod = await container.get(setupKey);
|
|
340
|
-
const setupFn = mod?.default;
|
|
341
|
-
if (typeof setupFn !== "function") {
|
|
342
|
-
throw new FgError(
|
|
343
|
-
ErrorCodes.SETUP_INVALID_EXPORT,
|
|
344
|
-
`\u73B0\u8C61\uFF1A\u8FDC\u7A0B\u5E94\u7528 "${remote.name}" \u7684 setup \u6A21\u5757 "${setupKey}" \u65E0\u6CD5\u521D\u59CB\u5316\u3002
|
|
345
|
-
\u539F\u56E0\uFF1A\u9ED8\u8BA4\u5BFC\u51FA\u7C7B\u578B\u4E3A ${mod == null ? String(mod) : typeof setupFn}\uFF0C\u5E94\u4E3A\u51FD\u6570\u3002
|
|
346
|
-
\u4FEE\u6CD5\uFF1A\u5728 setup \u6307\u5411\u7684\u6587\u4EF6\u4E2D\u9ED8\u8BA4\u5BFC\u51FA\u51FD\u6570\uFF0C\u4F8B\u5982 export default async function setup(context) { ... }\uFF1B\u5177\u540D onSession \u53EF\u9009\u3002`,
|
|
347
|
-
{ remote: remote.name, module: setupKey }
|
|
348
|
-
);
|
|
349
|
-
}
|
|
350
|
-
if (mod.onSession !== void 0 && typeof mod.onSession !== "function") {
|
|
351
|
-
throw new FgError(
|
|
352
|
-
ErrorCodes.SETUP_INVALID_EXPORT,
|
|
353
|
-
`\u73B0\u8C61\uFF1A\u8FDC\u7A0B\u5E94\u7528 "${remote.name}" \u7684 setup \u6A21\u5757 "${setupKey}" \u65E0\u6CD5\u521D\u59CB\u5316\u3002
|
|
354
|
-
\u539F\u56E0\uFF1AonSession \u5BFC\u51FA\u7C7B\u578B\u4E3A ${typeof mod.onSession}\uFF0C\u5E94\u4E3A\u51FD\u6570\u3002
|
|
355
|
-
\u4FEE\u6CD5\uFF1A\u5C06 onSession \u6539\u4E3A\u5177\u540D\u5BFC\u51FA\u7684\u51FD\u6570\uFF0C\u6216\u5220\u9664\u8BE5\u5BFC\u51FA\u3002`,
|
|
356
|
-
{ remote: remote.name, module: setupKey }
|
|
357
|
-
);
|
|
358
|
-
}
|
|
359
|
-
st.setupExports = mod;
|
|
360
|
-
await invokeLifecycleFn(
|
|
361
|
-
remote.name,
|
|
362
|
-
setupFn,
|
|
363
|
-
{ appContext: currentAppContext(), signal: (st.controller ??= new AbortController()).signal },
|
|
364
|
-
"setup"
|
|
365
|
-
);
|
|
366
|
-
remote.debug.setup = "ready";
|
|
367
|
-
} catch (err) {
|
|
368
|
-
remote.debug.setup = "failed";
|
|
369
|
-
st.setupExports = void 0;
|
|
370
|
-
throw err;
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
async function ensureSessionPhase(remote, st, onSession) {
|
|
374
|
-
const appContext = currentAppContext();
|
|
375
|
-
const sessionKey = appContext?.sessionKey;
|
|
376
|
-
if (typeof sessionKey !== "string" || sessionKey === "") {
|
|
377
|
-
throw new FgError(
|
|
378
|
-
ErrorCodes.SETUP_SESSION_KEY_MISSING,
|
|
379
|
-
`\u73B0\u8C61\uFF1A\u8FDC\u7A0B\u5E94\u7528 "${remote.name}" \u58F0\u660E\u4E86 onSession\uFF0C\u4F46\u5BBF\u4E3B\u5C1A\u672A\u63D0\u4F9B\u6709\u6548\u7684 AppContext.sessionKey\u3002
|
|
380
|
-
\u539F\u56E0\uFF1A\u5F53\u524D\u503C\u4E3A ${sessionKey === void 0 ? "\u7F3A\u5931" : JSON.stringify(sessionKey)}\u3002
|
|
381
|
-
\u4FEE\u6CD5\uFF1A\u5BBF\u4E3B\u6BCF\u6B21\u767B\u5F55\u6216\u91CD\u767B\u65F6\u751F\u6210\u65B0\u7684\u975E\u654F\u611F\u767B\u5F55\u4EE3\u6B21 ID\uFF0C\u5E76\u5728\u52A0\u8F7D\u8FDC\u7A0B\u9875\u9762\u524D\u8C03\u7528 provideAppContext({ ..., sessionKey: '\u767B\u5F55\u4EE3\u6B21 ID' })\uFF1B\u4E0D\u8981\u4F7F\u7528 token \u539F\u6587\u3002`,
|
|
382
|
-
{ remote: remote.name }
|
|
383
|
-
);
|
|
384
|
-
}
|
|
385
|
-
if (st.sessionPromise && st.sessionKey === sessionKey) return st.sessionPromise;
|
|
386
|
-
st.controller?.abort();
|
|
387
|
-
const controller = new AbortController();
|
|
388
|
-
st.controller = controller;
|
|
389
|
-
st.sessionKey = sessionKey;
|
|
390
|
-
const prev = st.sessionPromise ? st.sessionPromise.catch(() => {
|
|
391
|
-
}) : Promise.resolve();
|
|
392
|
-
const run = (async () => {
|
|
393
|
-
await prev;
|
|
394
|
-
if (controller.signal.aborted) return;
|
|
395
|
-
await invokeLifecycleFn(remote.name, onSession, { appContext, sessionKey, signal: controller.signal }, "onSession");
|
|
396
|
-
})();
|
|
397
|
-
st.sessionPromise = run;
|
|
398
|
-
run.catch(() => {
|
|
399
|
-
if (st.sessionKey === sessionKey) {
|
|
400
|
-
st.sessionKey = void 0;
|
|
401
|
-
st.sessionPromise = void 0;
|
|
402
|
-
}
|
|
403
|
-
});
|
|
404
|
-
return run;
|
|
405
|
-
}
|
|
406
|
-
async function ensureLifecycle(remote, container) {
|
|
407
|
-
const setupKey = container?.[SETUP_META_KEY];
|
|
408
|
-
if (typeof setupKey !== "string" || setupKey === "") return;
|
|
409
|
-
const st = lifecycleOf(remote.name);
|
|
410
|
-
if (!st.setupPromise) {
|
|
411
|
-
st.setupPromise = runSetupPhase(remote, container, setupKey, st).catch((err) => {
|
|
412
|
-
st.setupPromise = void 0;
|
|
413
|
-
throw err;
|
|
414
|
-
});
|
|
415
|
-
}
|
|
416
|
-
await st.setupPromise;
|
|
417
|
-
const onSession = st.setupExports?.onSession;
|
|
418
|
-
if (typeof onSession === "function") {
|
|
419
|
-
await ensureSessionPhase(remote, st, onSession);
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
function clearSessionState2() {
|
|
423
|
-
for (const st of lifecycleStates.values()) {
|
|
424
|
-
try {
|
|
425
|
-
st.controller?.abort();
|
|
426
|
-
} catch {
|
|
427
|
-
}
|
|
428
|
-
st.sessionKey = void 0;
|
|
429
|
-
st.sessionPromise = void 0;
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
const getScope = (name) => shareScopeMap2[name] ??= /* @__PURE__ */ Object.create(null);
|
|
433
|
-
function emitError(info) {
|
|
434
|
-
try {
|
|
435
|
-
hooks.onRemoteError?.(info);
|
|
436
|
-
} catch {
|
|
437
|
-
}
|
|
438
|
-
if (typeof window !== "undefined") {
|
|
439
|
-
window.dispatchEvent(new CustomEvent("fulgurjs:error", { detail: info }));
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
function initSharing2(scopeName = "default") {
|
|
443
|
-
getScope(scopeName);
|
|
444
|
-
return shareScopeMap2;
|
|
445
|
-
}
|
|
446
|
-
function registerShare2(scopeName, name, version, get, opts = {}) {
|
|
447
|
-
const scope = getScope(scopeName || "default");
|
|
448
|
-
const own = Object.hasOwn(scope, name) ? scope[name] : void 0;
|
|
449
|
-
let byName = own && typeof own === "object" ? own : void 0;
|
|
450
|
-
if (!byName) {
|
|
451
|
-
byName = /* @__PURE__ */ Object.create(null);
|
|
452
|
-
scope[name] = byName;
|
|
453
|
-
}
|
|
454
|
-
if (Object.hasOwn(byName, version) && byName[version]) {
|
|
455
|
-
return;
|
|
456
|
-
}
|
|
457
|
-
byName[version] = { version, get, from: opts.from ?? "unknown", eager: !!opts.eager, loaded: !!opts.loaded };
|
|
458
|
-
}
|
|
459
|
-
function assertRemoteParams(r) {
|
|
460
|
-
const check = (v, name, int10) => {
|
|
461
|
-
if (v === void 0) return;
|
|
462
|
-
const ok = typeof v === "number" && (int10 ? Number.isInteger(v) && v >= 0 && v <= 10 : Number.isFinite(v) && v > 0);
|
|
463
|
-
if (!ok) {
|
|
464
|
-
throw new Error(
|
|
465
|
-
`[fulgurjs] \u8FDC\u7A0B\u5E94\u7528 "${r.name}" \u7684 ${name} \u914D\u7F6E\u65E0\u6548\uFF1A\u5F53\u524D\u4E3A ${String(v)}\uFF0C\u5E94\u4E3A${int10 ? " 0 \u5230 10 \u7684\u6574\u6570" : "\u5927\u4E8E 0 \u7684\u6709\u9650\u6570\u5B57"}\u3002\u8BF7\u4FEE\u6B63 registerRemote \u914D\u7F6E\u3002`
|
|
466
|
-
);
|
|
467
|
-
}
|
|
468
|
-
};
|
|
469
|
-
check(r.timeout, "timeout");
|
|
470
|
-
check(r.retries, "retries", true);
|
|
471
|
-
if (r.breaker) {
|
|
472
|
-
check(r.breaker.threshold, "breaker.threshold");
|
|
473
|
-
check(r.breaker.resetMs, "breaker.resetMs");
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
function registerRemotes2(list) {
|
|
477
|
-
for (const r of list) {
|
|
478
|
-
assertRemoteParams(r);
|
|
479
|
-
const prev = remotes.get(r.name);
|
|
480
|
-
remotes.set(r.name, {
|
|
481
|
-
timeout: DEFAULT_TIMEOUT,
|
|
482
|
-
retries: DEFAULT_RETRIES,
|
|
483
|
-
...prev,
|
|
484
|
-
...r,
|
|
485
|
-
// 熔断参数随最新配置刷新;计数状态(fails/openUntil)跨注册保留——半开窗口不被重置
|
|
486
|
-
breakerThreshold: r.breaker?.threshold ?? prev?.breakerThreshold ?? BREAKER_THRESHOLD,
|
|
487
|
-
breakerResetMs: r.breaker?.resetMs ?? prev?.breakerResetMs ?? BREAKER_RESET_MS,
|
|
488
|
-
state: prev?.state ?? "idle",
|
|
489
|
-
breakerState: prev?.breakerState ?? { fails: 0, openUntil: 0 },
|
|
490
|
-
entryInflight: prev?.entryInflight ?? /* @__PURE__ */ new Map(),
|
|
491
|
-
debug: prev?.debug ?? { entry: r.entry, status: "idle", setup: "none" }
|
|
492
|
-
});
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
function registerRemote2(remote) {
|
|
496
|
-
registerRemotes2([remote]);
|
|
497
|
-
}
|
|
498
|
-
function registerPlugins2(list) {
|
|
499
|
-
plugins.push(...list);
|
|
500
|
-
applyPlugins();
|
|
501
|
-
}
|
|
502
|
-
async function loadShare2(name, opts = {}) {
|
|
503
|
-
const scopeName = opts.shareScope || "default";
|
|
504
|
-
const shareKey = opts.shareKey || name;
|
|
505
|
-
const scope = getScope(scopeName);
|
|
506
|
-
const byName = scope[shareKey] || {};
|
|
507
|
-
const versions = Object.keys(byName);
|
|
508
|
-
const req = opts.requiredVersion;
|
|
509
|
-
const satisfying = versions.filter(
|
|
510
|
-
(v) => req === void 0 || req === false || satisfies(v, req)
|
|
511
|
-
);
|
|
512
|
-
let pick;
|
|
513
|
-
if (opts.singleton && versions.length > 0) {
|
|
514
|
-
const loadedVersions = versions.filter((v) => byName[v].loaded);
|
|
515
|
-
pick = [...loadedVersions.length ? loadedVersions : versions].sort(compareVersions).pop();
|
|
516
|
-
if (!satisfying.includes(pick)) {
|
|
517
|
-
const entry0 = byName[pick];
|
|
518
|
-
const msg = `\u73B0\u8C61\uFF1A\u5171\u4EAB\u5355\u4F8B "${shareKey}" \u7684\u5B9E\u9645\u7248\u672C\u4E0D\u6EE1\u8DB3\u5F53\u524D\u5E94\u7528\u8981\u6C42\u3002
|
|
519
|
-
\u539F\u56E0\uFF1A\u5E94\u7528\u8981\u6C42 ${req ?? "\u4EFB\u610F\u7248\u672C"}\uFF0C\u4F5C\u7528\u57DF\u4E2D\u6709 ${versions.join("\u3001")}\uFF1B\u4E3A\u4FDD\u8BC1\u5168\u9875\u53EA\u4F7F\u7528\u4E00\u4E2A\u5B9E\u4F8B\uFF0C\u6700\u7EC8\u590D\u7528 ${entry0.from} \u63D0\u4F9B\u7684 ${pick}\u3002
|
|
520
|
-
\u5F71\u54CD\uFF1A\u53EF\u80FD\u51FA\u73B0\u72B6\u6001\u4E0D\u4E00\u81F4\u6216\u8FD0\u884C\u9519\u8BEF\uFF0C\u5177\u4F53\u53D6\u51B3\u4E8E\u4E24\u7AEF API \u662F\u5426\u517C\u5BB9\u3002
|
|
521
|
-
\u4FEE\u6CD5\uFF1A\u7EDF\u4E00\u5BBF\u4E3B\u4E0E\u8FDC\u7A0B\u7684\u4F9D\u8D56\u7248\u672C\uFF0C\u6216\u6838\u5BF9\u540E\u8C03\u6574 shared.requiredVersion\uFF1B\u82E5\u5FC5\u987B\u62D2\u7EDD\u4E0D\u517C\u5BB9\u7248\u672C\uFF0C\u8BF7\u542F\u7528 strictVersion\u3002`;
|
|
522
|
-
if (opts.strictVersion) {
|
|
523
|
-
const err = new FgError(ErrorCodes.SHARE_STRICT_VERSION, msg, {
|
|
524
|
-
shareKey,
|
|
525
|
-
requiredVersion: req
|
|
526
|
-
});
|
|
527
|
-
emitError({ remote: entry0.from, error: err });
|
|
528
|
-
throw err;
|
|
529
|
-
}
|
|
530
|
-
const warningKey = `${scopeName}|${shareKey}|${req ?? "*"}|${pick}|${versions.join(",")}`;
|
|
531
|
-
if (!reportedSingletonSkews.has(warningKey)) {
|
|
532
|
-
reportedSingletonSkews.add(warningKey);
|
|
533
|
-
console.warn(`[fulgurjs:MFU-010] ${msg}`);
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
} else {
|
|
537
|
-
pick = [...satisfying].sort(compareVersions).pop();
|
|
538
|
-
if (!pick) {
|
|
539
|
-
if (opts.strictVersion) {
|
|
540
|
-
const err2 = new FgError(
|
|
541
|
-
ErrorCodes.SHARE_STRICT_VERSION,
|
|
542
|
-
`\u73B0\u8C61\uFF1A\u5171\u4EAB\u4F5C\u7528\u57DF "${scopeName}" \u4E2D\u627E\u4E0D\u5230\u7B26\u5408\u8981\u6C42\u7684 "${shareKey}"\u3002
|
|
543
|
-
\u539F\u56E0\uFF1A\u8981\u6C42\u7248\u672C ${req}\uFF0C\u5F53\u524D\u53EF\u7528\u7248\u672C\u4E3A ${versions.join("\u3001") || "\u65E0"}\u3002
|
|
544
|
-
\u4FEE\u6CD5\uFF1A\u7EDF\u4E00\u5BBF\u4E3B\u4E0E\u8FDC\u7A0B\u7684\u4F9D\u8D56\u7248\u672C\uFF0C\u6216\u4FEE\u6B63 shared.requiredVersion\u3002`
|
|
545
|
-
);
|
|
546
|
-
emitError({ remote: shareKey, error: err2 });
|
|
547
|
-
throw err2;
|
|
548
|
-
}
|
|
549
|
-
if (opts.fallback) return opts.fallback();
|
|
550
|
-
const err = new FgError(
|
|
551
|
-
ErrorCodes.SHARE_NOT_AVAILABLE,
|
|
552
|
-
`\u73B0\u8C61\uFF1A\u65E0\u6CD5\u52A0\u8F7D\u5171\u4EAB\u4F9D\u8D56 "${shareKey}"\u3002
|
|
553
|
-
\u539F\u56E0\uFF1A\u4F5C\u7528\u57DF "${scopeName}" \u4E2D\u6CA1\u6709\u7B26\u5408 ${req ?? "\u4EFB\u610F\u7248\u672C"} \u8981\u6C42\u7684\u7248\u672C\uFF0C\u4E14\u672A\u914D\u7F6E\u672C\u5730\u526F\u672C\u3002
|
|
554
|
-
\u4FEE\u6CD5\uFF1A\u5728\u5BBF\u4E3B\u6216\u8FDC\u7A0B\u6CE8\u518C\u8BE5\u4F9D\u8D56\uFF0C\u6216\u4E3A shared \u914D\u7F6E\u53EF\u7528\u7684\u672C\u5730\u526F\u672C\u3002`,
|
|
555
|
-
{ shareKey, requiredVersion: req }
|
|
556
|
-
);
|
|
557
|
-
emitError({ remote: shareKey, error: err });
|
|
558
|
-
throw err;
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
let entry = byName[pick];
|
|
562
|
-
if (hooks.resolveShare) {
|
|
563
|
-
const picked = await hooks.resolveShare({
|
|
564
|
-
shareKey,
|
|
565
|
-
shareScope: scopeName,
|
|
566
|
-
requiredVersion: req,
|
|
567
|
-
picked: entry,
|
|
568
|
-
available: Object.values(byName)
|
|
569
|
-
});
|
|
570
|
-
if (picked) entry = picked;
|
|
571
|
-
}
|
|
572
|
-
entry.loaded = true;
|
|
573
|
-
return entry.get();
|
|
574
|
-
}
|
|
575
|
-
function sanitizeUrl(u) {
|
|
576
|
-
try {
|
|
577
|
-
const x = new URL(u, typeof location < "u" ? location.href : "http://f.invalid");
|
|
578
|
-
return x.protocol + "//" + x.host + x.pathname;
|
|
579
|
-
} catch {
|
|
580
|
-
return String(u).replace(/[?#].*$/, "");
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
function withTimeout(p, ms, label) {
|
|
584
|
-
return new Promise((resolve, reject) => {
|
|
585
|
-
const t = setTimeout(() => reject(new Error(`\u7B49\u5F85\u8D85\u8FC7 ${ms} \u6BEB\u79D2\uFF1A${label}`)), ms);
|
|
586
|
-
p.then(
|
|
587
|
-
(v) => {
|
|
588
|
-
clearTimeout(t);
|
|
589
|
-
resolve(v);
|
|
590
|
-
},
|
|
591
|
-
(e) => {
|
|
592
|
-
clearTimeout(t);
|
|
593
|
-
reject(e);
|
|
594
|
-
}
|
|
595
|
-
);
|
|
596
|
-
});
|
|
597
|
-
}
|
|
598
|
-
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
599
|
-
function validateContainerInterface(container, remote) {
|
|
600
|
-
if (!container || typeof container.get !== "function") {
|
|
601
|
-
throw new Error(
|
|
602
|
-
`\u8FDC\u7A0B\u5E94\u7528 "${remote.name}" \u7684 remoteEntry \u672A\u5BFC\u51FA\u5BB9\u5668\u63A5\u53E3\u3002\u8BF7\u786E\u8BA4\u5165\u53E3\u5BFC\u51FA\u4E86 get()\uFF0C\u5E76\u68C0\u67E5\u8BE5\u5730\u5740\u662F\u5426\u8FD4\u56DE\u6B63\u786E\u7684\u8054\u90A6\u5165\u53E3 JS\u3002`
|
|
603
|
-
);
|
|
604
|
-
}
|
|
605
|
-
if (container.name && remote.name && container.name !== remote.name) {
|
|
606
|
-
const msg = `\u8FDC\u7A0B\u5165\u53E3\u81EA\u62A5\u540D\u79F0 "${container.name}" \u4E0E\u5BBF\u4E3B\u914D\u7F6E\u540D\u79F0 "${remote.name}" \u4E0D\u4E00\u81F4\u3002\u8BF7\u7EDF\u4E00\u4E24\u4FA7 federation({ name }) \u4E0E remotes \u7684\u540D\u79F0\u3002`;
|
|
607
|
-
if (remote.promise) {
|
|
608
|
-
console.warn(`[fulgurjs] ${msg} \u5F53\u524D\u662F\u52A8\u6001 Promise \u8FDC\u7A0B\uFF0C\u7EE7\u7EED\u52A0\u8F7D\u3002`);
|
|
609
|
-
} else {
|
|
610
|
-
throw Object.assign(new Error(msg), { code: ErrorCodes.REMOTE_NAME_MISMATCH });
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
async function importEntry(url, remote) {
|
|
615
|
-
const cached = remote.entryInflight.get(url);
|
|
616
|
-
const inflight = cached ?? import(
|
|
617
|
-
/* @vite-ignore */
|
|
618
|
-
url
|
|
619
|
-
);
|
|
620
|
-
if (!cached) {
|
|
621
|
-
remote.entryInflight.set(url, inflight);
|
|
622
|
-
inflight.catch(() => remote.entryInflight.delete(url));
|
|
623
|
-
}
|
|
624
|
-
return withTimeout(inflight, remote.timeout ?? DEFAULT_TIMEOUT, `\u52A0\u8F7D\u8FDC\u7A0B\u5165\u53E3 ${sanitizeUrl(url)}`);
|
|
625
|
-
}
|
|
626
|
-
async function acquireContainer(remote, overrides) {
|
|
627
|
-
const scopeKey = remote.shareScope || "default";
|
|
628
|
-
if (remote.container) {
|
|
629
|
-
const prevScope = containerInitScopes.get(remote.container);
|
|
630
|
-
if (prevScope && prevScope !== scopeKey) {
|
|
631
|
-
throw new FgError(
|
|
632
|
-
ErrorCodes.CONTAINER_REINIT_CONFLICT,
|
|
633
|
-
`\u8FDC\u7A0B\u5BB9\u5668 "${remote.name}" \u5DF2\u4F7F\u7528\u5171\u4EAB\u4F5C\u7528\u57DF "${prevScope}" \u521D\u59CB\u5316\uFF0C\u4E0D\u80FD\u518D\u4EE5 "${scopeKey}" \u521D\u59CB\u5316\u3002\u8BF7\u7EDF\u4E00 shareScope \u914D\u7F6E\u3002`
|
|
634
|
-
);
|
|
635
|
-
}
|
|
636
|
-
return remote.container;
|
|
637
|
-
}
|
|
638
|
-
if (remote.containerPromise) return remote.containerPromise;
|
|
639
|
-
const b = remote.breakerState;
|
|
640
|
-
if (b.openUntil > Date.now()) {
|
|
641
|
-
const err = new FgError(
|
|
642
|
-
ErrorCodes.REMOTE_LOAD_FAILED,
|
|
643
|
-
`\u8FDC\u7A0B\u5E94\u7528 "${remote.name}" \u8FDE\u7EED\u52A0\u8F7D\u5931\u8D25\uFF0C\u7194\u65AD\u5668\u5DF2\u5F00\u542F\uFF1B\u5C06\u5728 ${new Date(b.openUntil).toISOString()} \u540E\u5141\u8BB8\u91CD\u8BD5\u3002\u8BF7\u5148\u68C0\u67E5\u8FDC\u7A0B\u5165\u53E3\u670D\u52A1\u548C\u7F51\u7EDC\u3002`,
|
|
644
|
-
{ remote: remote.name }
|
|
645
|
-
);
|
|
646
|
-
emitError({ remote: remote.name, error: err });
|
|
647
|
-
throw err;
|
|
648
|
-
}
|
|
649
|
-
remote.state = "loading";
|
|
650
|
-
remote.debug.status = "loading";
|
|
651
|
-
const containerPromise = (async () => {
|
|
652
|
-
const loaders = [];
|
|
653
|
-
if (remote.promise) {
|
|
654
|
-
loaders.push(async () => {
|
|
655
|
-
const resolved = await withTimeout(
|
|
656
|
-
remote.promise(),
|
|
657
|
-
remote.timeout ?? DEFAULT_TIMEOUT,
|
|
658
|
-
`\u89E3\u6790\u52A8\u6001\u8FDC\u7A0B\u5E94\u7528 "${remote.name}"`
|
|
659
|
-
);
|
|
660
|
-
const container2 = typeof resolved === "string" ? await importEntry(resolved, remote) : resolved;
|
|
661
|
-
validateContainerInterface(container2, remote);
|
|
662
|
-
return container2;
|
|
663
|
-
});
|
|
664
|
-
} else {
|
|
665
|
-
for (const url of [remote.entry, ...remote.fallback ?? []]) {
|
|
666
|
-
loaders.push(async () => {
|
|
667
|
-
const container2 = await importEntry(url, remote);
|
|
668
|
-
validateContainerInterface(container2, remote);
|
|
669
|
-
return container2;
|
|
670
|
-
});
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
|
-
let container;
|
|
674
|
-
let lastErr;
|
|
675
|
-
let succeeded = false;
|
|
676
|
-
const maxRetries = overrides?.retries ?? remote.retries ?? DEFAULT_RETRIES;
|
|
677
|
-
for (const loader of loaders) {
|
|
678
|
-
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
679
|
-
const start = performance.now();
|
|
680
|
-
try {
|
|
681
|
-
container = await loader();
|
|
682
|
-
remote.lastLoadMs = Math.round(performance.now() - start);
|
|
683
|
-
remote.debug.lastLoadMs = remote.lastLoadMs;
|
|
684
|
-
succeeded = true;
|
|
685
|
-
break;
|
|
686
|
-
} catch (err) {
|
|
687
|
-
lastErr = err;
|
|
688
|
-
if (err?.code) throw err;
|
|
689
|
-
if (attempt < maxRetries) {
|
|
690
|
-
await sleep(Math.min(BACKOFF_MAX_MS, 200 * 2 ** attempt) * (1 - BACKOFF_JITTER * (1 - 2 * Math.random())));
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
if (succeeded) break;
|
|
695
|
-
}
|
|
696
|
-
if (!succeeded || !container) {
|
|
697
|
-
const shown = sanitizeUrl(remote.entry);
|
|
698
|
-
const hints = [];
|
|
699
|
-
if (/^https?:\/\//.test(remote.entry) && typeof location !== "undefined") {
|
|
700
|
-
hints.push(`1. \u5728\u6D4F\u89C8\u5668\u6253\u5F00 ${shown}\uFF0C\u786E\u8BA4\u8FDC\u7A0B\u5F00\u53D1\u670D\u52A1\u5DF2\u542F\u52A8\uFF0C\u5E76\u8FD4\u56DE JS \u800C\u975E HTML\u3002`);
|
|
701
|
-
hints.push(`2. \u6838\u5BF9 federation({ remotes }) \u4E2D\u7684\u5730\u5740\uFF1B\u5F00\u53D1\u548C\u751F\u4EA7\u5730\u5740\u53EF\u4EE5\u4E0D\u540C\u3002`);
|
|
702
|
-
hints.push(`3. \u82E5\u8DE8\u57DF\uFF0C\u68C0\u67E5\u8FDC\u7A0B\u5F00\u53D1\u670D\u52A1\u7684 server.cors \u914D\u7F6E\u3002`);
|
|
703
|
-
} else {
|
|
704
|
-
hints.push(`1. \u5728\u6D4F\u89C8\u5668\u6253\u5F00 ${shown}\uFF0C\u786E\u8BA4\u8FDC\u7A0B\u5E94\u7528\u5DF2\u90E8\u7F72\uFF0C\u4E14\u5165\u53E3\u8FD4\u56DE JS\u3002`);
|
|
705
|
-
hints.push(`2. \u68C0\u67E5 Nginx/CDN \u7684\u5165\u53E3\u8DEF\u5F84\u6620\u5C04\uFF1B\u8BE5\u5730\u5740\u4E0D\u80FD\u56DE\u9000\u5230 index.html\u3002`);
|
|
706
|
-
}
|
|
707
|
-
throw new FgError(
|
|
708
|
-
ErrorCodes.REMOTE_LOAD_FAILED,
|
|
709
|
-
`\u73B0\u8C61\uFF1A\u65E0\u6CD5\u4ECE ${shown} \u52A0\u8F7D\u8FDC\u7A0B\u5E94\u7528 "${remote.name}"\u3002
|
|
710
|
-
\u539F\u56E0\uFF1A${String(lastErr?.message ?? lastErr)}
|
|
711
|
-
\u4FEE\u6CD5\uFF1A
|
|
712
|
-
${hints.join("\n")}`,
|
|
713
|
-
{ remote: remote.name }
|
|
714
|
-
);
|
|
715
|
-
}
|
|
716
|
-
validateContainerInterface(container, remote);
|
|
717
|
-
const prevScope = containerInitScopes.get(container);
|
|
718
|
-
if (prevScope && prevScope !== scopeKey) {
|
|
719
|
-
throw new FgError(
|
|
720
|
-
ErrorCodes.CONTAINER_REINIT_CONFLICT,
|
|
721
|
-
`\u8FDC\u7A0B\u5BB9\u5668 "${remote.name}" \u5DF2\u4F7F\u7528\u5171\u4EAB\u4F5C\u7528\u57DF "${prevScope}" \u521D\u59CB\u5316\uFF0C\u4E0D\u80FD\u518D\u4EE5 "${scopeKey}" \u521D\u59CB\u5316\u3002\u8BF7\u7EDF\u4E00 shareScope \u914D\u7F6E\u3002`
|
|
722
|
-
);
|
|
723
|
-
}
|
|
724
|
-
if (typeof container.init === "function") {
|
|
725
|
-
await container.init(shareScopeMap2);
|
|
726
|
-
}
|
|
727
|
-
containerInitScopes.set(container, scopeKey);
|
|
728
|
-
remote.container = container;
|
|
729
|
-
remote.state = "loaded";
|
|
730
|
-
remote.debug.status = "loaded";
|
|
731
|
-
b.fails = 0;
|
|
732
|
-
return container;
|
|
733
|
-
})();
|
|
734
|
-
remote.containerPromise = containerPromise;
|
|
735
|
-
try {
|
|
736
|
-
return await containerPromise;
|
|
737
|
-
} catch (err) {
|
|
738
|
-
remote.containerPromise = void 0;
|
|
739
|
-
remote.state = "failed";
|
|
740
|
-
remote.debug.status = "failed";
|
|
741
|
-
remote.debug.error = String(err?.message ?? err);
|
|
742
|
-
b.fails += 1;
|
|
743
|
-
if (b.fails >= remote.breakerThreshold) {
|
|
744
|
-
b.openUntil = Date.now() + remote.breakerResetMs;
|
|
745
|
-
b.fails = 0;
|
|
746
|
-
}
|
|
747
|
-
if (err instanceof FgError) {
|
|
748
|
-
emitError({ remote: remote.name, error: err });
|
|
749
|
-
throw err;
|
|
750
|
-
}
|
|
751
|
-
if (err?.code) {
|
|
752
|
-
emitError({ remote: remote.name, error: err });
|
|
753
|
-
throw err;
|
|
754
|
-
}
|
|
755
|
-
const wrapped = new FgError(ErrorCodes.REMOTE_LOAD_FAILED, `\u8FDC\u7A0B\u5E94\u7528 "${remote.name}" \u52A0\u8F7D\u5931\u8D25\u3002\u5E95\u5C42\u539F\u56E0\uFF1A${String(err?.message ?? err)}\u3002\u8BF7\u68C0\u67E5\u8FDC\u7A0B\u5165\u53E3\u3001\u7F51\u7EDC\u53CA\u5171\u4EAB\u4F9D\u8D56\u3002`, {
|
|
756
|
-
remote: remote.name
|
|
757
|
-
});
|
|
758
|
-
emitError({ remote: remote.name, error: wrapped });
|
|
759
|
-
throw wrapped;
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
function parseSpec2(spec) {
|
|
763
|
-
const idx = spec.indexOf("/");
|
|
764
|
-
if (idx === -1) return { remote: spec, module: "" };
|
|
765
|
-
return { remote: spec.slice(0, idx), module: normalizeModuleName(spec.slice(idx + 1)) };
|
|
766
|
-
}
|
|
767
|
-
function normalizeModuleName(m) {
|
|
768
|
-
if (!m) return "";
|
|
769
|
-
return m.startsWith(".") ? m : `./${m}`;
|
|
770
|
-
}
|
|
771
|
-
async function loadRemote2(spec, opts) {
|
|
772
|
-
const { remote: name, module: module2 } = parseSpec2(spec);
|
|
773
|
-
if (module2 && lifecycleSyncRemote === name) {
|
|
774
|
-
throw new FgError(
|
|
775
|
-
ErrorCodes.SETUP_RECURSION,
|
|
776
|
-
`\u73B0\u8C61\uFF1A\u52A0\u8F7D "${spec}" \u65F6\uFF0C\u8FDC\u7A0B\u5E94\u7528 "${name}" \u7684 setup/onSession \u53C8\u540C\u6B65\u52A0\u8F7D\u4E86\u81EA\u8EAB\u6A21\u5757\uFF0C\u5F62\u6210\u5FAA\u73AF\u7B49\u5F85\u3002
|
|
777
|
-
\u539F\u56E0\uFF1A\u521D\u59CB\u5316\u5C1A\u672A\u5B8C\u6210\uFF0C\u4E0D\u80FD\u7B49\u5F85\u81EA\u8EAB\u7684\u521D\u59CB\u5316\u7ED3\u679C\u3002
|
|
778
|
-
\u4FEE\u6CD5\uFF1A\u4E0D\u8981\u5728 setup/onSession \u4E2D\u52A0\u8F7D\u540C\u4E00\u8FDC\u7A0B\u7684\u6A21\u5757\uFF1B\u8BF7\u5728\u9875\u9762\u7EC4\u4EF6\u4E2D\u52A0\u8F7D\uFF0C\u6216\u901A\u8FC7 context \u89E3\u8026\u3002`,
|
|
779
|
-
{ remote: name }
|
|
780
|
-
);
|
|
781
|
-
}
|
|
782
|
-
try {
|
|
783
|
-
hooks.beforeLoadRemote?.({ remote: name, module: module2 });
|
|
784
|
-
} catch (hookErr) {
|
|
785
|
-
console.warn("[fulgurjs] beforeLoadRemote \u89C2\u6D4B\u94A9\u5B50\u6267\u884C\u5931\u8D25\uFF1B\u6A21\u5757\u52A0\u8F7D\u5C06\u7EE7\u7EED\u3002\u8BF7\u68C0\u67E5\u8BE5\u94A9\u5B50\uFF1A", hookErr);
|
|
786
|
-
}
|
|
787
|
-
const remote = remotes.get(name);
|
|
788
|
-
if (!remote) {
|
|
789
|
-
throw new FgError(
|
|
790
|
-
ErrorCodes.REMOTE_UNKNOWN,
|
|
791
|
-
`\u672A\u77E5\u8FDC\u7A0B\u5E94\u7528 "${name}"\u3002\u8BF7\u5728 federation({ remotes }) \u4E2D\u914D\u7F6E\uFF0C\u6216\u5728\u52A0\u8F7D\u524D\u8C03\u7528 registerRemote()\u3002`,
|
|
792
|
-
{ remote: name }
|
|
793
|
-
);
|
|
794
|
-
}
|
|
795
|
-
let container;
|
|
796
|
-
try {
|
|
797
|
-
const stylesReady = module2 && remote.manifestUrl ? preloadRemote2(spec) : Promise.resolve();
|
|
798
|
-
[container] = await Promise.all([acquireContainer(remote, { retries: opts?.retries }), stylesReady]);
|
|
799
|
-
} catch (err) {
|
|
800
|
-
if (opts?.fallbackModule) {
|
|
801
|
-
console.error(`[fulgurjs] \u8FDC\u7A0B\u6A21\u5757 "${spec}" \u52A0\u8F7D\u5931\u8D25\uFF0C\u6B63\u5728\u4F7F\u7528\u663E\u5F0F\u914D\u7F6E\u7684 fallbackModule\uFF1B\u539F\u59CB\u9519\u8BEF\uFF1A`, err);
|
|
802
|
-
emitError({ remote: name, error: err });
|
|
803
|
-
return await opts.fallbackModule();
|
|
804
|
-
}
|
|
805
|
-
throw err;
|
|
806
|
-
}
|
|
807
|
-
if (!module2) return container;
|
|
808
|
-
await ensureLifecycle(remote, container);
|
|
809
|
-
const cacheKey = `${name}@${remote.shareScope || "default"}#${module2}`;
|
|
810
|
-
if (!loadedModules.has(cacheKey)) {
|
|
811
|
-
loadedModules.set(
|
|
812
|
-
cacheKey,
|
|
813
|
-
container.get(module2).catch((err) => {
|
|
814
|
-
loadedModules.delete(cacheKey);
|
|
815
|
-
if (err instanceof FgError || err?.code) throw err;
|
|
816
|
-
throw new FgError(
|
|
817
|
-
ErrorCodes.REMOTE_LOAD_FAILED,
|
|
818
|
-
`\u65E0\u6CD5\u4ECE\u8FDC\u7A0B\u5E94\u7528 "${name}" \u52A0\u8F7D\u6A21\u5757 "${module2}"\u3002\u5E95\u5C42\u539F\u56E0\uFF1A${String(err?.message ?? err)}\u3002\u8BF7\u6838\u5BF9 exposes \u952E\u548C\u8FDC\u7A0B\u6784\u5EFA\u4EA7\u7269\u3002`,
|
|
819
|
-
{ remote: name, module: module2 }
|
|
820
|
-
);
|
|
821
|
-
})
|
|
822
|
-
);
|
|
823
|
-
}
|
|
824
|
-
let ns;
|
|
825
|
-
try {
|
|
826
|
-
ns = await loadedModules.get(cacheKey);
|
|
827
|
-
} catch (err) {
|
|
828
|
-
if (opts?.fallbackModule) {
|
|
829
|
-
console.error(`[fulgurjs] \u8FDC\u7A0B\u6A21\u5757 "${spec}" \u52A0\u8F7D\u5931\u8D25\uFF0C\u6B63\u5728\u4F7F\u7528\u663E\u5F0F\u914D\u7F6E\u7684 fallbackModule\uFF1B\u539F\u59CB\u9519\u8BEF\uFF1A`, err);
|
|
830
|
-
emitError({ remote: name, error: err });
|
|
831
|
-
return await opts.fallbackModule();
|
|
832
|
-
}
|
|
833
|
-
throw err;
|
|
834
|
-
}
|
|
835
|
-
try {
|
|
836
|
-
hooks.afterLoadRemote?.({ remote: name, module: module2, module_ns: ns });
|
|
837
|
-
} catch (hookErr) {
|
|
838
|
-
console.warn("[fulgurjs] afterLoadRemote \u89C2\u6D4B\u94A9\u5B50\u6267\u884C\u5931\u8D25\uFF1B\u5DF2\u52A0\u8F7D\u6A21\u5757\u4ECD\u53EF\u4F7F\u7528\u3002\u8BF7\u68C0\u67E5\u8BE5\u94A9\u5B50\uFF1A", hookErr);
|
|
839
|
-
}
|
|
840
|
-
if (ns && typeof ns === "object" && Object.keys(ns).length === 0) {
|
|
841
|
-
const err = new FgError(
|
|
842
|
-
ErrorCodes.EMPTY_EXPORTS,
|
|
843
|
-
`\u8FDC\u7A0B\u5E94\u7528 "${name}" \u7684\u6A21\u5757 "${module2}" \u6CA1\u6709\u4EFB\u4F55\u5BFC\u51FA\u3002\u8BF7\u68C0\u67E5 exposes \u6307\u5411\u7684\u6587\u4EF6\u53CA\u5176 export \u58F0\u660E\u3002`,
|
|
844
|
-
{ remote: name, module: module2 }
|
|
845
|
-
);
|
|
846
|
-
emitError({ remote: name, error: err });
|
|
847
|
-
console.error(err.message);
|
|
848
|
-
}
|
|
849
|
-
return ns;
|
|
850
|
-
}
|
|
851
|
-
function getContainer2(name) {
|
|
852
|
-
const remote = remotes.get(name);
|
|
853
|
-
if (!remote) {
|
|
854
|
-
throw new FgError(ErrorCodes.REMOTE_UNKNOWN, `\u672A\u77E5\u8FDC\u7A0B\u5E94\u7528 "${name}"\u3002\u8BF7\u5148\u6CE8\u518C\u8BE5\u8FDC\u7A0B\u5E94\u7528\u3002`, { remote: name });
|
|
855
|
-
}
|
|
856
|
-
return acquireContainer(remote);
|
|
857
|
-
}
|
|
858
|
-
async function preloadRemote2(spec, opts = {}) {
|
|
859
|
-
const { remote: name, module: module2 } = parseSpec2(spec);
|
|
860
|
-
const remote = remotes.get(name);
|
|
861
|
-
if (!remote) {
|
|
862
|
-
throw new FgError(ErrorCodes.REMOTE_UNKNOWN, `\u672A\u77E5\u8FDC\u7A0B\u5E94\u7528 "${name}"\u3002\u8BF7\u5148\u6CE8\u518C\u8BE5\u8FDC\u7A0B\u5E94\u7528\u3002`, { remote: name });
|
|
863
|
-
}
|
|
864
|
-
const mode = opts.mode ?? "preload";
|
|
865
|
-
const waitForStylesheet = (link, href) => {
|
|
866
|
-
if (link.sheet) return Promise.resolve();
|
|
867
|
-
const pending = stylesheetLoads.get(link);
|
|
868
|
-
if (pending) return pending;
|
|
869
|
-
const loaded = new Promise((resolve) => {
|
|
870
|
-
const finish = () => {
|
|
871
|
-
link.removeEventListener("load", finish);
|
|
872
|
-
link.removeEventListener("error", failed);
|
|
873
|
-
resolve();
|
|
874
|
-
};
|
|
875
|
-
const failed = () => {
|
|
876
|
-
emitError({
|
|
877
|
-
remote: name,
|
|
878
|
-
error: new FgError(ErrorCodes.PRELOAD_FAILED, `\u8FDC\u7A0B\u5E94\u7528 "${name}" \u7684\u6837\u5F0F\u8D44\u6E90\u52A0\u8F7D\u5931\u8D25\uFF1A${href}\u3002\u8BF7\u68C0\u67E5\u6587\u4EF6\u662F\u5426\u5B58\u5728\u4EE5\u53CA\u8DE8\u57DF\u548C\u7F13\u5B58\u914D\u7F6E\u3002`, {
|
|
879
|
-
remote: name
|
|
880
|
-
})
|
|
881
|
-
});
|
|
882
|
-
finish();
|
|
883
|
-
};
|
|
884
|
-
link.addEventListener("load", finish, { once: true });
|
|
885
|
-
link.addEventListener("error", failed, { once: true });
|
|
886
|
-
if (link.sheet) finish();
|
|
887
|
-
});
|
|
888
|
-
stylesheetLoads.set(link, loaded);
|
|
889
|
-
return loaded;
|
|
890
|
-
};
|
|
891
|
-
const inject = (href, as) => {
|
|
892
|
-
if (typeof document === "undefined") return Promise.resolve();
|
|
893
|
-
const existing = document.querySelector(`link[href="${href}"]`);
|
|
894
|
-
if (existing) {
|
|
895
|
-
return as === "style" && mode === "preload" ? stylesheetLoads.get(existing) ?? Promise.resolve() : Promise.resolve();
|
|
896
|
-
}
|
|
897
|
-
const link = document.createElement("link");
|
|
898
|
-
link.rel = as === "style" ? "stylesheet" : "modulepreload";
|
|
899
|
-
link.href = href;
|
|
900
|
-
if (mode === "prefetch") {
|
|
901
|
-
;
|
|
902
|
-
link.fetchPriority = "low";
|
|
903
|
-
}
|
|
904
|
-
const loaded = as === "style" ? waitForStylesheet(link, href) : Promise.resolve();
|
|
905
|
-
document.head.appendChild(link);
|
|
906
|
-
return as === "style" && mode === "preload" ? loaded : Promise.resolve();
|
|
907
|
-
};
|
|
908
|
-
const resolveAssetUrl = (asset) => {
|
|
909
|
-
const pageUrl = typeof document !== "undefined" ? document.baseURI : void 0;
|
|
910
|
-
const base = new URL(remote.entry, pageUrl || "http://fulgurjs.invalid/");
|
|
911
|
-
if (!base.pathname.endsWith("/") && !base.pathname.split("/").pop().includes(".")) {
|
|
912
|
-
base.pathname += "/";
|
|
913
|
-
}
|
|
914
|
-
return new URL(asset, base).href;
|
|
915
|
-
};
|
|
916
|
-
try {
|
|
917
|
-
if (remote.manifestUrl) {
|
|
918
|
-
let manifestPromise = remoteManifests.get(remote.manifestUrl);
|
|
919
|
-
if (!manifestPromise) {
|
|
920
|
-
manifestPromise = fetch(remote.manifestUrl, {
|
|
921
|
-
cache: "no-cache",
|
|
922
|
-
signal: AbortSignal.timeout(8e3)
|
|
923
|
-
}).then((res) => res.ok ? res.json() : void 0);
|
|
924
|
-
remoteManifests.set(remote.manifestUrl, manifestPromise);
|
|
925
|
-
manifestPromise.then(
|
|
926
|
-
(manifest2) => {
|
|
927
|
-
if (!manifest2) remoteManifests.delete(remote.manifestUrl);
|
|
928
|
-
},
|
|
929
|
-
() => remoteManifests.delete(remote.manifestUrl)
|
|
930
|
-
);
|
|
931
|
-
}
|
|
932
|
-
const manifest = await manifestPromise;
|
|
933
|
-
if (manifest) {
|
|
934
|
-
const sv = manifest.schemaVersion;
|
|
935
|
-
if (typeof sv === "number" && (!Number.isInteger(sv) || sv > 1)) {
|
|
936
|
-
emitError({
|
|
937
|
-
remote: name,
|
|
938
|
-
error: new FgError(ErrorCodes.PRELOAD_FAILED, `\u8FDC\u7A0B\u5E94\u7528 "${name}" \u7684 manifest \u534F\u8BAE\u7248\u672C\u4E3A ${String(sv)}\uFF0C\u5F53\u524D\u4EC5\u652F\u6301\u7248\u672C 1\u3002\u8BF7\u7EDF\u4E00\u5BBF\u4E3B\u548C\u8FDC\u7A0B\u7684\u63D2\u4EF6\u7248\u672C\u3002`, {
|
|
939
|
-
remote: name
|
|
940
|
-
})
|
|
941
|
-
});
|
|
942
|
-
await inject(remote.entry, "modulepreload");
|
|
943
|
-
return;
|
|
944
|
-
}
|
|
945
|
-
await inject(remote.entry, "modulepreload");
|
|
946
|
-
const exposes = manifest.exposes;
|
|
947
|
-
const entries = Array.isArray(exposes) ? exposes.filter((item) => item && typeof item === "object").map((item) => [String(item.name ?? ""), item]) : exposes && typeof exposes === "object" ? Object.entries(exposes) : [];
|
|
948
|
-
const selected = module2 ? entries.filter(([key, item]) => normalizeModuleName(String(item?.name ?? key)) === module2) : entries;
|
|
949
|
-
const cssLoads = [];
|
|
950
|
-
for (const [, item] of selected) {
|
|
951
|
-
if (typeof item?.file === "string") {
|
|
952
|
-
await inject(resolveAssetUrl(item.file), "modulepreload");
|
|
953
|
-
}
|
|
954
|
-
if (Array.isArray(item?.css)) {
|
|
955
|
-
for (const css of item.css) {
|
|
956
|
-
if (typeof css !== "string") continue;
|
|
957
|
-
const loading = inject(resolveAssetUrl(css), "style");
|
|
958
|
-
if (mode === "preload") cssLoads.push(loading);
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
}
|
|
962
|
-
await Promise.all(cssLoads);
|
|
963
|
-
return;
|
|
964
|
-
}
|
|
965
|
-
}
|
|
966
|
-
await inject(remote.entry, "modulepreload");
|
|
967
|
-
} catch (err) {
|
|
968
|
-
emitError({
|
|
969
|
-
remote: name,
|
|
970
|
-
error: new FgError(ErrorCodes.PRELOAD_FAILED, `\u8FDC\u7A0B\u5E94\u7528 "${name}" \u9884\u52A0\u8F7D\u5931\u8D25\u3002\u5E95\u5C42\u539F\u56E0\uFF1A${String(err?.message ?? err)}\u3002\u8BF7\u68C0\u67E5 manifest \u548C\u8D44\u6E90\u5730\u5740\u3002`, {
|
|
971
|
-
remote: name
|
|
972
|
-
})
|
|
973
|
-
});
|
|
974
|
-
}
|
|
975
|
-
}
|
|
976
|
-
const attachDebug = () => {
|
|
977
|
-
if (typeof window === "undefined") return;
|
|
978
|
-
window.__FULGURJS_SCOPE__ = shareScopeMap2;
|
|
979
|
-
window.__FULGURJS_INFO__ = {
|
|
980
|
-
get remotes() {
|
|
981
|
-
const out = {};
|
|
982
|
-
for (const [k, v] of remotes) {
|
|
983
|
-
out[k] = { ...v.debug, entry: v.entry };
|
|
984
|
-
}
|
|
985
|
-
return out;
|
|
986
|
-
},
|
|
987
|
-
errors: []
|
|
988
|
-
};
|
|
989
|
-
};
|
|
990
|
-
attachDebug();
|
|
991
|
-
return {
|
|
992
|
-
shareScopeMap: shareScopeMap2,
|
|
993
|
-
initSharing: initSharing2,
|
|
994
|
-
registerShare: registerShare2,
|
|
995
|
-
registerRemotes: registerRemotes2,
|
|
996
|
-
registerRemote: registerRemote2,
|
|
997
|
-
registerPlugins: registerPlugins2,
|
|
998
|
-
loadShare: loadShare2,
|
|
999
|
-
loadRemote: loadRemote2,
|
|
1000
|
-
getContainer: getContainer2,
|
|
1001
|
-
preloadRemote: preloadRemote2,
|
|
1002
|
-
parseSpec: parseSpec2,
|
|
1003
|
-
clearSessionState: clearSessionState2
|
|
1004
|
-
};
|
|
1005
|
-
}
|
|
1006
|
-
var g = globalThis;
|
|
1007
|
-
var runtime = g.__FULGURJS_RUNTIME__ ?? createRuntime();
|
|
1008
|
-
g.__FULGURJS_RUNTIME__ = runtime;
|
|
1009
|
-
try {
|
|
1010
|
-
Object.freeze(runtime);
|
|
1011
|
-
} catch {
|
|
1012
|
-
}
|
|
1013
|
-
var initSharing = runtime.initSharing;
|
|
1014
|
-
var registerShare = runtime.registerShare;
|
|
1015
|
-
var registerRemotes = runtime.registerRemotes;
|
|
1016
|
-
var registerRemote = runtime.registerRemote;
|
|
1017
|
-
var registerPlugins = runtime.registerPlugins;
|
|
1018
|
-
var loadShare = runtime.loadShare;
|
|
1019
|
-
var loadRemote = runtime.loadRemote;
|
|
1020
|
-
var getContainer = runtime.getContainer;
|
|
1021
|
-
var preloadRemote = runtime.preloadRemote;
|
|
1022
|
-
var parseSpec = runtime.parseSpec;
|
|
1023
|
-
var clearSessionState = runtime.clearSessionState;
|
|
1024
|
-
var shareScopeMap = runtime.shareScopeMap;
|
|
1025
|
-
|
|
1026
|
-
// src/vue-adapter.ts
|
|
1027
|
-
var import_vue = require("vue");
|
|
1028
|
-
|
|
1029
|
-
// src/pages.ts
|
|
1030
|
-
var normSpec = (s) => s.replace(/^[./]+/, "").replace(/\/+$/, "");
|
|
1031
|
-
var hasParam = (route) => /(^|\/):[\w]+/.test(route);
|
|
1032
|
-
var segs = (route) => route.split("/").filter(Boolean);
|
|
1033
|
-
function defaultDeriveSpec(route) {
|
|
1034
|
-
return segs(route).slice(1).filter((seg) => !seg.startsWith(":")).join("/");
|
|
1035
|
-
}
|
|
1036
|
-
function shadows(earlier, later) {
|
|
1037
|
-
const a = segs(earlier);
|
|
1038
|
-
const b = segs(later);
|
|
1039
|
-
if (a.length !== b.length) return null;
|
|
1040
|
-
if (earlier === later) return "full";
|
|
1041
|
-
let hasParam2 = false;
|
|
1042
|
-
for (let i = 0; i < a.length; i++) {
|
|
1043
|
-
if (a[i] === b[i]) continue;
|
|
1044
|
-
if (a[i].startsWith(":")) {
|
|
1045
|
-
hasParam2 = true;
|
|
1046
|
-
continue;
|
|
1047
|
-
}
|
|
1048
|
-
return null;
|
|
1049
|
-
}
|
|
1050
|
-
return hasParam2 ? "param" : null;
|
|
1051
|
-
}
|
|
1052
|
-
function remoteOfRoute(route, remotes) {
|
|
1053
|
-
if (!remotes) return null;
|
|
1054
|
-
for (const [prefix, name] of Object.entries(remotes)) {
|
|
1055
|
-
if (route === prefix.replace(/\/+$/, "") || route.startsWith(prefix)) return name;
|
|
1056
|
-
}
|
|
1057
|
-
return null;
|
|
1058
|
-
}
|
|
1059
|
-
function validatePages(pages, options = {}) {
|
|
1060
|
-
const deriveSpec = options.deriveSpec ?? defaultDeriveSpec;
|
|
1061
|
-
const violations = [];
|
|
1062
|
-
const effective = pages.map((p) => normSpec(p.spec ?? deriveSpec(p.route)));
|
|
1063
|
-
pages.forEach((p, i) => {
|
|
1064
|
-
if (p.spec || !hasParam(p.route)) return;
|
|
1065
|
-
pages.forEach((q, j) => {
|
|
1066
|
-
if (i === j) return;
|
|
1067
|
-
if (effective[j] !== effective[i]) return;
|
|
1068
|
-
violations.push({
|
|
1069
|
-
rule: "R1",
|
|
1070
|
-
level: "error",
|
|
1071
|
-
message: `[R1] \u8DEF\u7531 "${p.route}" \u5265\u53C2\u63A8\u5BFC spec "${effective[i]}" \u4E0E\u8DEF\u7531 "${q.route}"${q.spec ? "\uFF08\u663E\u5F0F spec\uFF09" : ""}\u6536\u655B\u76F8\u540C\u3002
|
|
1072
|
-
\u6839\u56E0\uFF1A\u53C2\u6570\u6BB5\u5265\u79BB\u540E expose \u952E\u4E0E\u5176\u5B83\u6761\u76EE\u76F8\u540C\uFF0C\u8BE5\u8DEF\u7531\u4F1A\u9759\u9ED8\u52A0\u8F7D\u9519\u8BEF\u7EC4\u4EF6
|
|
1073
|
-
\uFF08\u771F\u5B9E\u4E8B\u6545\uFF1A\u5E26\u53C2\u52A8\u4F5C\u9875\u8BEF\u8D70\u5217\u8868/\u66F4\u65B0\u8BED\u4E49\uFF0C\u6570\u636E\u98CE\u9669\uFF09\u3002
|
|
1074
|
-
\u4FEE\u6CD5\uFF1A\u4E3A\u8BE5\u6761\u76EE\u663E\u5F0F\u58F0\u660E spec: '...'\uFF08\u6307\u5411\u5E26\u53C2\u9875\u9762\u81EA\u5DF1\u7684 expose\uFF09\uFF0C\u6216\u8C03\u6574\u8DEF\u7531\u62C6\u5206\u3002`
|
|
1075
|
-
});
|
|
1076
|
-
});
|
|
1077
|
-
});
|
|
1078
|
-
const seenSpec = /* @__PURE__ */ new Map();
|
|
1079
|
-
pages.forEach((p, i) => {
|
|
1080
|
-
const key = effective[i];
|
|
1081
|
-
if (seenSpec.has(key)) {
|
|
1082
|
-
const first = pages[seenSpec.get(key)];
|
|
1083
|
-
const bothExplicit = !!p.spec && !!first.spec;
|
|
1084
|
-
violations.push({
|
|
1085
|
-
rule: "R2",
|
|
1086
|
-
level: "warn",
|
|
1087
|
-
message: `[R2] \u8DEF\u7531 "${p.route}" \u4E0E "${first.route}" \u6709\u6548 spec \u76F8\u540C\uFF08"${key}"\uFF09\u3002${bothExplicit ? "\u4E24\u6761\u5747\u4E3A\u663E\u5F0F spec" : "\u5176\u4E2D\u542B\u63A8\u5BFC spec"}\u2014\u2014\u82E5\u4E3A\u523B\u610F\u7684\u83DC\u5355\u522B\u540D\u53EF\u5FFD\u7565\u672C\u8B66\u544A\uFF0C\u5426\u5219\u8BF7\u6838\u5BF9\u3002`
|
|
1088
|
-
});
|
|
1089
|
-
} else {
|
|
1090
|
-
seenSpec.set(key, i);
|
|
1091
|
-
}
|
|
1092
|
-
});
|
|
1093
|
-
if (options.schema && options.remotes) {
|
|
1094
|
-
pages.forEach((p, i) => {
|
|
1095
|
-
const remote = remoteOfRoute(p.route, options.remotes);
|
|
1096
|
-
if (!remote) return;
|
|
1097
|
-
const entry = options.schema[remote];
|
|
1098
|
-
if (!entry || entry.exists === false) return;
|
|
1099
|
-
const exposes = new Set((entry.exposes ?? []).map(normSpec));
|
|
1100
|
-
if (!exposes.has(effective[i])) {
|
|
1101
|
-
violations.push({
|
|
1102
|
-
rule: "R3",
|
|
1103
|
-
level: "error",
|
|
1104
|
-
message: `[R3] \u8DEF\u7531 "${p.route}" \u7684 spec "${effective[i]}" \u4E0D\u5728\u8FDC\u7A0B "${remote}" \u7684 exposes \u6E05\u5355\u4E2D\u3002
|
|
1105
|
-
\u6839\u56E0\uFF1Aspec \u62FC\u5199\u4E0E\u8FDC\u7A0B exposes \u952E\u4E0D\u4E00\u81F4\uFF08\u8FD0\u884C\u65F6\u5C06 MFU-006 \u52A0\u8F7D\u5931\u8D25\uFF09\u3002
|
|
1106
|
-
\u4FEE\u6CD5\uFF1A\u6838\u5BF9\u8FDC\u7A0B vite.config exposes \u952E\u540D\uFF0C\u6216\u4FEE\u6B63\u672C\u8868 spec\u3002
|
|
1107
|
-
\u8FDC\u7A0B\u5B9E\u9645 exposes\uFF08\u524D 10\uFF09\uFF1A${[...exposes].slice(0, 10).join("\u3001") || "\uFF08\u7A7A\uFF09"}`
|
|
1108
|
-
});
|
|
1109
|
-
}
|
|
1110
|
-
});
|
|
1111
|
-
}
|
|
1112
|
-
pages.forEach((p, i) => {
|
|
1113
|
-
pages.forEach((q, j) => {
|
|
1114
|
-
if (j <= i) return;
|
|
1115
|
-
const kind = shadows(p.route, q.route);
|
|
1116
|
-
if (!kind) return;
|
|
1117
|
-
violations.push({
|
|
1118
|
-
rule: "R4",
|
|
1119
|
-
level: "error",
|
|
1120
|
-
message: kind === "full" ? `[R4] \u8DEF\u7531\u5B8C\u5168\u91CD\u590D\uFF1A"${p.route}"\uFF08\u7B2C ${i + 1} \u6761\uFF09\u4E0E "${q.route}"\uFF08\u7B2C ${j + 1} \u6761\uFF09\u3002` : `[R4] \u8DEF\u7531 "${q.route}"\uFF08\u7B2C ${j + 1} \u6761\uFF09\u4F1A\u88AB\u66F4\u9760\u524D\u7684 "${p.route}" \u906E\u853D\uFF08\u5339\u914D\u5148\u5230\u5148\u5F97\uFF0C\u540E\u8005\u6210\u6B7B\u8DEF\u7531\uFF09\u3002
|
|
1121
|
-
\u4FEE\u6CD5\uFF1A\u8C03\u6574\u6570\u7EC4\u987A\u5E8F\uFF08\u66F4\u5177\u4F53\u7684\u9759\u6001\u8DEF\u7531\u653E\u524D\u9762\uFF09\u6216\u5408\u5E76\u6761\u76EE\u3002`
|
|
1122
|
-
});
|
|
1123
|
-
});
|
|
1124
|
-
});
|
|
1125
|
-
const seenName = /* @__PURE__ */ new Map();
|
|
1126
|
-
pages.forEach((p, i) => {
|
|
1127
|
-
const name = typeof p.name === "string" ? p.name : "";
|
|
1128
|
-
if (!name) return;
|
|
1129
|
-
if (seenName.has(name)) {
|
|
1130
|
-
violations.push({
|
|
1131
|
-
rule: "R5",
|
|
1132
|
-
level: "warn",
|
|
1133
|
-
message: `[R5] name "${name}" \u91CD\u590D\uFF08"${pages[seenName.get(name)].route}" \u4E0E "${p.route}"\uFF09\u2014\u2014vue-router \u547D\u540D\u8DF3\u8F6C push({name}) \u5C06\u547D\u4E2D\u524D\u8005\uFF0C\u8BF7\u6838\u5BF9\u3002`
|
|
1134
|
-
});
|
|
1135
|
-
} else {
|
|
1136
|
-
seenName.set(name, i);
|
|
1137
|
-
}
|
|
1138
|
-
});
|
|
1139
|
-
return violations;
|
|
1140
|
-
}
|
|
1141
|
-
function formatViolations(violations) {
|
|
1142
|
-
const errors = violations.filter((v) => v.level === "error");
|
|
1143
|
-
const warns = violations.filter((v) => v.level === "warn");
|
|
1144
|
-
let out = "";
|
|
1145
|
-
if (errors.length) {
|
|
1146
|
-
out += `[fulgurjs] \u8DEF\u7531\u8868\u6821\u9A8C\u5931\u8D25\uFF08${errors.length} \u9879\uFF0CERROR\uFF09\uFF1A
|
|
1147
|
-
` + errors.map((v) => v.message).join("\n") + "\n";
|
|
1148
|
-
}
|
|
1149
|
-
if (warns.length) {
|
|
1150
|
-
out += `[fulgurjs] \u8DEF\u7531\u8868\u6821\u9A8C\u8B66\u544A\uFF08${warns.length} \u9879\uFF0CWARN\uFF09\uFF1A
|
|
1151
|
-
` + warns.map((v) => v.message).join("\n");
|
|
1152
|
-
}
|
|
1153
|
-
return out.trim();
|
|
1154
|
-
}
|
|
1155
|
-
function definePages(pages, options = {}) {
|
|
1156
|
-
const violations = validatePages(pages, options);
|
|
1157
|
-
const errors = violations.filter((v) => v.level === "error");
|
|
1158
|
-
const warns = violations.filter((v) => v.level === "warn");
|
|
1159
|
-
const text = formatViolations(violations);
|
|
1160
|
-
if (text) {
|
|
1161
|
-
if (errors.length && options.strict !== false) {
|
|
1162
|
-
throw new Error(text);
|
|
1163
|
-
}
|
|
1164
|
-
console[errors.length ? "error" : "warn"](text);
|
|
1165
|
-
}
|
|
1166
|
-
return pages;
|
|
1167
|
-
}
|
|
1168
|
-
|
|
1169
|
-
// src/vue-adapter.ts
|
|
1170
|
-
var ERROR_STYLE = {
|
|
1171
|
-
padding: "16px",
|
|
1172
|
-
border: "1px solid #fde2e2",
|
|
1173
|
-
borderRadius: "4px",
|
|
1174
|
-
background: "#fef0f0",
|
|
1175
|
-
color: "#c45656",
|
|
1176
|
-
fontSize: "13px",
|
|
1177
|
-
lineHeight: "1.6"
|
|
1178
|
-
};
|
|
1179
|
-
var RemoteErrorPlaceholder = (0, import_vue.defineComponent)({
|
|
1180
|
-
name: "FulgurjsRemoteError",
|
|
1181
|
-
props: { error: { type: Object, default: void 0 } },
|
|
1182
|
-
setup(props) {
|
|
1183
|
-
return () => {
|
|
1184
|
-
const err = props.error;
|
|
1185
|
-
const code = err?.code ?? "UNKNOWN";
|
|
1186
|
-
const message = err?.message ?? String(props.error ?? "unknown error");
|
|
1187
|
-
return (0, import_vue.h)("div", { style: ERROR_STYLE }, [
|
|
1188
|
-
(0, import_vue.h)("p", { style: "margin:0 0 4px;font-weight:600" }, `\u8FDC\u7A0B\u7EC4\u4EF6\u52A0\u8F7D\u5931\u8D25\uFF08\u9519\u8BEF\u7801 ${code}\uFF09`),
|
|
1189
|
-
(0, import_vue.h)("p", { style: "margin:0 0 8px;word-break:break-all" }, message),
|
|
1190
|
-
(0, import_vue.h)("p", { style: "margin:0" }, "\u4FEE\u6CD5\uFF1A\u2460 \u6838\u5BF9 spec \u7684\u300C\u8FDC\u7A0B\u540D/expose \u540D\u300D\u4E0E\u8FDC\u7A0B\u5E94\u7528 exposes \u662F\u5426\u4E00\u81F4\uFF08MFU-006/008\uFF09\uFF1B\u2461 \u6838\u5BF9 remotes \u5730\u5740\u7AEF\u53E3\u4E0E\u8FDC\u7A0B\u670D\u52A1\u53EF\u8FBE\u6027\u3001remoteEntry \u662F\u5426\u53EF\u8BBF\u95EE\uFF08MFU-001\uFF09\uFF1B\u2462 \u67E5\u770B window \u7684 fulgurjs:error \u4E8B\u4EF6\u4E0E console \u540C\u6E90\u9519\u8BEF\u5B9A\u4F4D\u6839\u56E0\u3002")
|
|
1191
|
-
]);
|
|
1192
|
-
};
|
|
1193
|
-
}
|
|
1194
|
-
});
|
|
1195
|
-
function createRemoteComponent(loadRemote2) {
|
|
1196
|
-
return function remoteComponent2(spec, opts = {}) {
|
|
1197
|
-
return (0, import_vue.defineAsyncComponent)({
|
|
1198
|
-
loader: () => loadRemote2(spec, { retries: opts.retries }).then((m) => m.default ?? m),
|
|
1199
|
-
loadingComponent: opts.loadingComponent,
|
|
1200
|
-
errorComponent: opts.errorComponent ?? RemoteErrorPlaceholder,
|
|
1201
|
-
delay: opts.delay,
|
|
1202
|
-
timeout: opts.timeout
|
|
1203
|
-
});
|
|
1204
|
-
};
|
|
1205
|
-
}
|
|
1206
|
-
var cleanCompName = (spec) => "Fulgurjs_" + spec.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
1207
|
-
function defaultDeriveSpec2(route) {
|
|
1208
|
-
return route.split("/").filter(Boolean).slice(1).filter((seg) => !seg.startsWith(":")).join("/");
|
|
1209
|
-
}
|
|
1210
|
-
function createHostPages(options, load) {
|
|
1211
|
-
const { pages, remotePrefixes, deriveSpec, schema, strict, base, beforeLoad, loadingComponent, errorComponent, delay } = options;
|
|
1212
|
-
definePages(pages, { deriveSpec, remotes: remotePrefixes, schema, strict });
|
|
1213
|
-
const prefixes = Object.entries(remotePrefixes).map(([p, name]) => [p.endsWith("/") ? p : `${p}/`, name]).sort((a, b) => b[0].length - a[0].length);
|
|
1214
|
-
const remoteOf = (route) => {
|
|
1215
|
-
for (const [prefix, name] of prefixes) {
|
|
1216
|
-
if (route.startsWith(prefix) || `${route}/` === prefix) return name;
|
|
1217
|
-
}
|
|
1218
|
-
throw new Error(
|
|
1219
|
-
`[fulgurjs] \u9875\u9762\u8DEF\u7531 "${route}" \u672A\u5339\u914D\u4EFB\u4F55 remotePrefixes\uFF1A{ ${Object.entries(remotePrefixes).map(([k, v]) => `'${k}': '${v}'`).join(", ")} }
|
|
1220
|
-
\u6839\u56E0: \u9875\u9762\u8868\u6761\u76EE\u7684\u8DEF\u7531\u4E0D\u5728\u4EFB\u4F55\u5DF2\u58F0\u660E\u7684\u8FDC\u7A0B\u524D\u7F00\u4E0B\u3002
|
|
1221
|
-
\u4FEE\u6CD5: \u5728 remotePrefixes \u8865\u5145\u8BE5\u8DEF\u7531\u524D\u7F00 \u2192 \u8FDC\u7A0B\u540D\u7684\u6620\u5C04\uFF0C\u6216\u4FEE\u6B63\u9875\u9762\u8868 route\u3002`
|
|
1222
|
-
);
|
|
1223
|
-
};
|
|
1224
|
-
for (const page of pages) remoteOf(page.route);
|
|
1225
|
-
const specOf = (page) => {
|
|
1226
|
-
const s = page.spec ?? (deriveSpec ? deriveSpec(page.route) : defaultDeriveSpec2(page.route));
|
|
1227
|
-
return `${remoteOf(page.route)}/${String(s).replace(/^[./]+/, "")}`;
|
|
1228
|
-
};
|
|
1229
|
-
const baseNorm = base && base !== "/" ? base.endsWith("/") ? base : `${base}/` : "";
|
|
1230
|
-
const matchSegments = (pattern, path) => {
|
|
1231
|
-
const patSegs = pattern.split("/").filter(Boolean);
|
|
1232
|
-
const pathSegs = path.split("/").filter(Boolean);
|
|
1233
|
-
if (patSegs.length !== pathSegs.length) return null;
|
|
1234
|
-
const params = {};
|
|
1235
|
-
for (let i = 0; i < patSegs.length; i++) {
|
|
1236
|
-
const seg = patSegs[i];
|
|
1237
|
-
if (seg.startsWith(":")) {
|
|
1238
|
-
try {
|
|
1239
|
-
params[seg.slice(1)] = decodeURIComponent(pathSegs[i]);
|
|
1240
|
-
} catch {
|
|
1241
|
-
return null;
|
|
1242
|
-
}
|
|
1243
|
-
} else if (seg !== pathSegs[i]) {
|
|
1244
|
-
return null;
|
|
1245
|
-
}
|
|
1246
|
-
}
|
|
1247
|
-
return params;
|
|
1248
|
-
};
|
|
1249
|
-
let cacheSession;
|
|
1250
|
-
const compCache = /* @__PURE__ */ new Map();
|
|
1251
|
-
const resolve = (rawPath) => {
|
|
1252
|
-
let clean = String(rawPath ?? "");
|
|
1253
|
-
if (baseNorm) {
|
|
1254
|
-
if (clean === baseNorm.replace(/\/$/, "")) clean = "/";
|
|
1255
|
-
else if (clean.startsWith(baseNorm)) clean = `/${clean.slice(baseNorm.length)}`;
|
|
1256
|
-
}
|
|
1257
|
-
clean = (clean.replace(/\/+$/, "") || "/").split("?")[0].split("#")[0];
|
|
1258
|
-
for (const page of pages) {
|
|
1259
|
-
const params = matchSegments(page.route, clean);
|
|
1260
|
-
if (params) return { page, remote: remoteOf(page.route), spec: specOf(page), params };
|
|
1261
|
-
}
|
|
1262
|
-
return null;
|
|
1263
|
-
};
|
|
1264
|
-
const component = (spec) => {
|
|
1265
|
-
const sk = (globalThis.__FULGURJS_APP_CONFIG__ ?? {}).sessionKey;
|
|
1266
|
-
const sessionKey = typeof sk === "string" && sk !== "" ? sk : void 0;
|
|
1267
|
-
if (sessionKey !== void 0 && sessionKey !== cacheSession) {
|
|
1268
|
-
compCache.clear();
|
|
1269
|
-
cacheSession = sessionKey;
|
|
1270
|
-
}
|
|
1271
|
-
let comp = compCache.get(spec);
|
|
1272
|
-
if (!comp) {
|
|
1273
|
-
const name = cleanCompName(spec);
|
|
1274
|
-
const asyncComp = (0, import_vue.defineAsyncComponent)({
|
|
1275
|
-
loader: async () => {
|
|
1276
|
-
await beforeLoad?.();
|
|
1277
|
-
const mod = await load(spec);
|
|
1278
|
-
const inner = mod?.default ?? mod;
|
|
1279
|
-
if (!inner) {
|
|
1280
|
-
throw new Error(
|
|
1281
|
-
`[fulgurjs] \u8FDC\u7A0B\u6A21\u5757 "${spec}" \u6CA1\u6709\u5BFC\u51FA\u53EF\u6E32\u67D3\u7EC4\u4EF6\uFF1B\u5F53\u524D\u503C\u7C7B\u578B\u4E3A ${inner === null ? "null" : typeof inner}\u3002
|
|
1282
|
-
\u4FEE\u6CD5: \u6838\u5BF9\u8FDC\u7A0B exposes \u952E\u540D\u4E0E\u9875\u9762\u8868 spec \u662F\u5426\u4E00\u81F4\uFF08MFU-006 \u8BED\u4E49\uFF09`
|
|
1283
|
-
);
|
|
1284
|
-
}
|
|
1285
|
-
return inner;
|
|
1286
|
-
},
|
|
1287
|
-
loadingComponent,
|
|
1288
|
-
errorComponent: errorComponent ?? RemoteErrorPlaceholder,
|
|
1289
|
-
delay
|
|
1290
|
-
});
|
|
1291
|
-
asyncComp.name = name;
|
|
1292
|
-
comp = asyncComp;
|
|
1293
|
-
compCache.set(spec, comp);
|
|
1294
|
-
}
|
|
1295
|
-
return comp;
|
|
1296
|
-
};
|
|
1297
|
-
const keepAliveNames = pages.filter((p) => p.keepAlive).map((p) => cleanCompName(specOf(p)));
|
|
1298
|
-
return { pages, resolve, component, keepAliveNames };
|
|
1299
|
-
}
|
|
1300
|
-
|
|
1301
|
-
// src/vue.ts
|
|
1302
|
-
var remoteComponent = createRemoteComponent(loadRemote);
|
|
1303
|
-
function createHostPages2(options) {
|
|
1304
|
-
return createHostPages(options, loadRemote);
|
|
1305
|
-
}
|
|
1306
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
1307
|
-
0 && (module.exports = {
|
|
1308
|
-
createHostPages,
|
|
1309
|
-
remoteComponent
|
|
1310
|
-
});
|