@module-federation/vite 1.19.1 → 1.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -0
- package/lib/index.d.ts +26 -4
- package/lib/index.js +2028 -284
- package/lib/{ssrEntryLoader-CuZVKlRm.js → ssrEntryLoader-Bw423jj_.js} +11 -4
- package/lib/{ssrVmStrategy-Dpw20xiw.js → ssrVmStrategy-7HAPa-Vc.js} +1 -1
- package/lib/utils/injectExternalRuntimeCorePlugin.d.ts +21 -0
- package/lib/utils/injectExternalRuntimeCorePlugin.js +54 -0
- package/lib/utils/ssrEntryLoader.d.ts +1 -4
- package/lib/utils/ssrEntryLoader.js +1 -1
- package/package.json +18 -11
- package/lib/pluginDts-9RTNVO8v.js +0 -839
package/lib/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { _ as createModuleFederationError, a as getIsRolldown, b as rebaseImport, c as getPackageNameFromNodeModulePath, d as isNuxtProjectRoot, f as packageNameDecode, g as sharedCacheHelperCode, h as setPackageDetectionCwd, i as getInstalledPackageJson, l as getSharedCacheDescriptor, m as resolveImportPath, o as getPackageDetectionCwd, p as packageNameEncode, r as getInstalledPackageEntry, s as getPackageName, u as hasPackageDependency, v as mfWarn, y as normalizePathForImport } from "./pluginDts-9RTNVO8v.js";
|
|
2
1
|
import { createRequire } from "node:module";
|
|
3
2
|
import * as fs$2 from "fs";
|
|
4
|
-
import { existsSync, readFileSync, realpathSync, statSync, writeFileSync } from "fs";
|
|
3
|
+
import fs, { existsSync, readFileSync, readdirSync, realpathSync, statSync, writeFileSync } from "fs";
|
|
5
4
|
import { createRequire as createRequire$1 } from "module";
|
|
6
5
|
import * as path$1 from "node:path";
|
|
7
6
|
import path, { basename } from "node:path";
|
|
@@ -11,9 +10,71 @@ import { createHash } from "node:crypto";
|
|
|
11
10
|
import * as fs$1 from "node:fs";
|
|
12
11
|
import { existsSync as existsSync$1, readFileSync as readFileSync$1 } from "node:fs";
|
|
13
12
|
import { pathToFileURL as pathToFileURL$1 } from "node:url";
|
|
13
|
+
import { normalizeOptions } from "@module-federation/sdk";
|
|
14
|
+
import { consumeTypesAPI, generateTypesAPI, isTSProject, normalizeConsumeTypesOptions, normalizeDtsOptions, normalizeGenerateTypesOptions } from "@module-federation/dts-plugin";
|
|
15
|
+
import { rpc } from "@module-federation/dts-plugin/core";
|
|
16
|
+
//#region \0rolldown/runtime.js
|
|
17
|
+
var __defProp = Object.defineProperty;
|
|
18
|
+
var __exportAll = (all, no_symbols) => {
|
|
19
|
+
let target = {};
|
|
20
|
+
for (var name in all) __defProp(target, name, {
|
|
21
|
+
get: all[name],
|
|
22
|
+
enumerable: true
|
|
23
|
+
});
|
|
24
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
25
|
+
return target;
|
|
26
|
+
};
|
|
27
|
+
//#endregion
|
|
28
|
+
//#region src/utils/buildPaths.ts
|
|
29
|
+
/**
|
|
30
|
+
* Rebase an import path for a bootstrap file that moved from root into `dir`.
|
|
31
|
+
*
|
|
32
|
+
* When entryFileNames places entries in a subdirectory (e.g. `static/js/`),
|
|
33
|
+
* the bootstrap file moves there too. Paths that resolved from the HTML root
|
|
34
|
+
* must resolve from the new directory instead.
|
|
35
|
+
*
|
|
36
|
+
* Cases: `/static/js/hostInit.js` → `./hostInit.js` (strip dir prefix)
|
|
37
|
+
* `./src/main.tsx` → `../../src/main.tsx` (climb back up for each dir level)
|
|
38
|
+
* `https://cdn.example.com` → unchanged (absolute URL)
|
|
39
|
+
*/
|
|
40
|
+
function rebaseImport(importSrc, dir) {
|
|
41
|
+
if (!dir) return importSrc;
|
|
42
|
+
if (isAbsoluteUrl(importSrc)) return importSrc;
|
|
43
|
+
const normalizedDir = dir.replace(/^\/+|\/+$/g, "");
|
|
44
|
+
if (!normalizedDir) return importSrc;
|
|
45
|
+
const stripDirPrefix = (src, prefix) => {
|
|
46
|
+
if (src === prefix) return "";
|
|
47
|
+
if (src.startsWith(prefix + "/")) return src.slice(prefix.length);
|
|
48
|
+
};
|
|
49
|
+
const absoluteRemainder = stripDirPrefix(importSrc, "/" + normalizedDir);
|
|
50
|
+
if (absoluteRemainder !== void 0) {
|
|
51
|
+
const remainder = absoluteRemainder.replace(/^\/+/, "");
|
|
52
|
+
return remainder ? "./" + remainder : "./";
|
|
53
|
+
}
|
|
54
|
+
const relativeRemainder = stripDirPrefix(importSrc, normalizedDir);
|
|
55
|
+
if (relativeRemainder !== void 0) {
|
|
56
|
+
const remainder = relativeRemainder.replace(/^\/+/, "");
|
|
57
|
+
return remainder ? "./" + remainder : "./";
|
|
58
|
+
}
|
|
59
|
+
const upLevels = normalizedDir.split("/").filter(Boolean).length;
|
|
60
|
+
const prefix = upLevels > 0 ? "../".repeat(upLevels) : "./";
|
|
61
|
+
if (importSrc.startsWith("./")) return prefix + importSrc.slice(2);
|
|
62
|
+
if (importSrc.startsWith("/")) return prefix + importSrc.slice(1);
|
|
63
|
+
return prefix + importSrc;
|
|
64
|
+
}
|
|
65
|
+
function normalizePathForImport(path) {
|
|
66
|
+
return path.replace(/\\/g, "/");
|
|
67
|
+
}
|
|
68
|
+
const EXTERNAL_URL_RE = /^(?:[a-z]+:|\/\/)/i;
|
|
69
|
+
function isAbsoluteUrl(src) {
|
|
70
|
+
if (/^[a-z]:[\\/]/i.test(src)) return false;
|
|
71
|
+
return EXTERNAL_URL_RE.test(src);
|
|
72
|
+
}
|
|
73
|
+
//#endregion
|
|
14
74
|
//#region src/utils/codeRewriter.ts
|
|
15
75
|
const BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
16
76
|
var CodeRewriter = class {
|
|
77
|
+
original;
|
|
17
78
|
replacements = [];
|
|
18
79
|
constructor(original) {
|
|
19
80
|
this.original = original;
|
|
@@ -148,7 +209,156 @@ async function mapCodeToCodeWithSourcemap(code) {
|
|
|
148
209
|
};
|
|
149
210
|
}
|
|
150
211
|
//#endregion
|
|
212
|
+
//#region src/utils/codePositionMap.ts
|
|
213
|
+
const REGEX_PREFIX_KEYWORDS = /* @__PURE__ */ new Set([
|
|
214
|
+
"await",
|
|
215
|
+
"case",
|
|
216
|
+
"delete",
|
|
217
|
+
"in",
|
|
218
|
+
"instanceof",
|
|
219
|
+
"new",
|
|
220
|
+
"return",
|
|
221
|
+
"throw",
|
|
222
|
+
"typeof",
|
|
223
|
+
"void",
|
|
224
|
+
"yield"
|
|
225
|
+
]);
|
|
226
|
+
function isJsxClosingTagSlash(code, slashIndex) {
|
|
227
|
+
if (code[slashIndex - 1] !== "<") return false;
|
|
228
|
+
let cursor = slashIndex + 1;
|
|
229
|
+
while (/\s/.test(code[cursor] || "")) cursor++;
|
|
230
|
+
if (code[cursor] === ">") return true;
|
|
231
|
+
const tagStart = cursor;
|
|
232
|
+
while (/[-:.$_\u200C\u200D\p{ID_Continue}]/u.test(code[cursor] || "")) cursor++;
|
|
233
|
+
if (cursor === tagStart) return false;
|
|
234
|
+
while (/\s/.test(code[cursor] || "")) cursor++;
|
|
235
|
+
return code[cursor] === ">";
|
|
236
|
+
}
|
|
237
|
+
/** Mark comments, string/template literals, and regular expressions as non-code. */
|
|
238
|
+
function createCodePositionMap(code) {
|
|
239
|
+
const positions = Array(code.length).fill(true);
|
|
240
|
+
const mask = (start, end) => {
|
|
241
|
+
for (let index = start; index < end; index++) positions[index] = false;
|
|
242
|
+
};
|
|
243
|
+
let canStartRegex = true;
|
|
244
|
+
for (let index = 0; index < code.length;) {
|
|
245
|
+
const char = code[index];
|
|
246
|
+
const next = code[index + 1];
|
|
247
|
+
if (/\s/.test(char)) {
|
|
248
|
+
index++;
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
if (char === "/" && next === "/") {
|
|
252
|
+
const start = index;
|
|
253
|
+
index += 2;
|
|
254
|
+
while (index < code.length && code[index] !== "\n" && code[index] !== "\r") index++;
|
|
255
|
+
mask(start, index);
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
if (char === "/" && next === "*") {
|
|
259
|
+
const start = index;
|
|
260
|
+
index += 2;
|
|
261
|
+
while (index < code.length && !(code[index] === "*" && code[index + 1] === "/")) index++;
|
|
262
|
+
index = Math.min(code.length, index + 2);
|
|
263
|
+
mask(start, index);
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
if (char === "\"" || char === "'" || char === "`") {
|
|
267
|
+
const quote = char;
|
|
268
|
+
const start = index++;
|
|
269
|
+
while (index < code.length) {
|
|
270
|
+
if (code[index] === "\\") {
|
|
271
|
+
index += 2;
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
if (code[index] === quote) {
|
|
275
|
+
index++;
|
|
276
|
+
break;
|
|
277
|
+
}
|
|
278
|
+
index++;
|
|
279
|
+
}
|
|
280
|
+
mask(start, index);
|
|
281
|
+
canStartRegex = false;
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
const closesJsxTag = isJsxClosingTagSlash(code, index);
|
|
285
|
+
if (char === "/" && canStartRegex && !closesJsxTag) {
|
|
286
|
+
const start = index;
|
|
287
|
+
let cursor = index + 1;
|
|
288
|
+
let escaped = false;
|
|
289
|
+
let inCharacterClass = false;
|
|
290
|
+
let closed = false;
|
|
291
|
+
for (; cursor < code.length; cursor++) {
|
|
292
|
+
const regexChar = code[cursor];
|
|
293
|
+
if (regexChar === "\n" || regexChar === "\r") break;
|
|
294
|
+
if (escaped) {
|
|
295
|
+
escaped = false;
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
if (regexChar === "\\") {
|
|
299
|
+
escaped = true;
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
if (regexChar === "[") {
|
|
303
|
+
inCharacterClass = true;
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
if (regexChar === "]" && inCharacterClass) {
|
|
307
|
+
inCharacterClass = false;
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
if (regexChar === "/" && !inCharacterClass) {
|
|
311
|
+
cursor++;
|
|
312
|
+
while (/[$_\p{ID_Continue}]/u.test(code[cursor] || "")) cursor++;
|
|
313
|
+
closed = true;
|
|
314
|
+
break;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
if (closed) {
|
|
318
|
+
mask(start, cursor);
|
|
319
|
+
index = cursor;
|
|
320
|
+
canStartRegex = false;
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
if (/[$_\p{ID_Start}]/u.test(char)) {
|
|
325
|
+
const start = index++;
|
|
326
|
+
while (/[$_\u200C\u200D\p{ID_Continue}]/u.test(code[index] || "")) index++;
|
|
327
|
+
canStartRegex = REGEX_PREFIX_KEYWORDS.has(code.slice(start, index));
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
if (/\d/.test(char)) {
|
|
331
|
+
index++;
|
|
332
|
+
while (/[\w.]/.test(code[index] || "")) index++;
|
|
333
|
+
canStartRegex = false;
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
if ((char === "+" || char === "-") && next === char) {
|
|
337
|
+
index += 2;
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
if (char === "!" && next !== "=") {
|
|
341
|
+
index++;
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
if (char === ")" || char === "]" || char === "}") canStartRegex = false;
|
|
345
|
+
else if (char !== ".") canStartRegex = true;
|
|
346
|
+
index++;
|
|
347
|
+
}
|
|
348
|
+
return positions;
|
|
349
|
+
}
|
|
350
|
+
//#endregion
|
|
151
351
|
//#region src/utils/htmlEntryUtils.ts
|
|
352
|
+
function findModuleImportSources(code) {
|
|
353
|
+
const codePositions = createCodePositionMap(code);
|
|
354
|
+
const sources = /* @__PURE__ */ new Set();
|
|
355
|
+
for (const pattern of [
|
|
356
|
+
/\b(?:import|export)\s+[^;]*?\bfrom\s*["']([^"']+)["']/g,
|
|
357
|
+
/\bimport\s*\(\s*["']([^"']+)["']/g,
|
|
358
|
+
/\bimport\s*["']([^"']+)["']/g
|
|
359
|
+
]) for (const match of code.matchAll(pattern)) if (codePositions[match.index]) sources.add(match[1]);
|
|
360
|
+
return Array.from(sources);
|
|
361
|
+
}
|
|
152
362
|
function sanitizeDevEntryPath(devEntryPath) {
|
|
153
363
|
return devEntryPath.replace(/\\\\?/g, "/");
|
|
154
364
|
}
|
|
@@ -172,6 +382,475 @@ function injectEntryScript(html, initSrc) {
|
|
|
172
382
|
return html.replace("<head>", `<head><script type="module" src=${JSON.stringify(src)}><\/script>`);
|
|
173
383
|
}
|
|
174
384
|
//#endregion
|
|
385
|
+
//#region src/utils/logger.ts
|
|
386
|
+
const MODULE_FEDERATION_LOG_PREFIX = "[Module Federation]";
|
|
387
|
+
function formatModuleFederationMessage(message) {
|
|
388
|
+
return `${MODULE_FEDERATION_LOG_PREFIX} ${message}`;
|
|
389
|
+
}
|
|
390
|
+
function createModuleFederationError(message) {
|
|
391
|
+
return new Error(formatModuleFederationMessage(message));
|
|
392
|
+
}
|
|
393
|
+
function toConsoleArgs(message, rest = []) {
|
|
394
|
+
if (typeof message === "string") return [formatModuleFederationMessage(message), ...rest];
|
|
395
|
+
if (message === void 0) return [MODULE_FEDERATION_LOG_PREFIX, ...rest];
|
|
396
|
+
return [
|
|
397
|
+
MODULE_FEDERATION_LOG_PREFIX,
|
|
398
|
+
message,
|
|
399
|
+
...rest
|
|
400
|
+
];
|
|
401
|
+
}
|
|
402
|
+
const moduleFederationConsole = {
|
|
403
|
+
log(message, ...rest) {
|
|
404
|
+
console.log(...toConsoleArgs(message, rest));
|
|
405
|
+
},
|
|
406
|
+
warn(message, ...rest) {
|
|
407
|
+
console.warn(...toConsoleArgs(message, rest));
|
|
408
|
+
},
|
|
409
|
+
error(message, ...rest) {
|
|
410
|
+
console.error(...toConsoleArgs(message, rest));
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
moduleFederationConsole.log;
|
|
414
|
+
const mfWarn = moduleFederationConsole.warn;
|
|
415
|
+
const mfError = moduleFederationConsole.error;
|
|
416
|
+
//#endregion
|
|
417
|
+
//#region src/utils/packageUtils.ts
|
|
418
|
+
const dependencyPresenceCache = /* @__PURE__ */ new Map();
|
|
419
|
+
let packageDetectionCwd;
|
|
420
|
+
function getDependencyCacheKey(cwd, dependencyName) {
|
|
421
|
+
return `${cwd}:${dependencyName}`;
|
|
422
|
+
}
|
|
423
|
+
const installedPackageJsonCache = /* @__PURE__ */ new Map();
|
|
424
|
+
function setPackageDetectionCwd(cwd) {
|
|
425
|
+
packageDetectionCwd = cwd;
|
|
426
|
+
}
|
|
427
|
+
function getPackageDetectionCwd() {
|
|
428
|
+
return packageDetectionCwd || process.cwd();
|
|
429
|
+
}
|
|
430
|
+
function resolveImportPath(specifier) {
|
|
431
|
+
const resolved = import.meta.resolve(specifier);
|
|
432
|
+
if (!resolved.startsWith("file:")) return resolved;
|
|
433
|
+
const filePath = fileURLToPath(resolved);
|
|
434
|
+
if (!existsSync(filePath)) {
|
|
435
|
+
const error = /* @__PURE__ */ new Error(`Cannot find module '${specifier}'`);
|
|
436
|
+
error.code = "MODULE_NOT_FOUND";
|
|
437
|
+
throw error;
|
|
438
|
+
}
|
|
439
|
+
return filePath;
|
|
440
|
+
}
|
|
441
|
+
const DEFAULT_EXPORT_CONDITIONS = [
|
|
442
|
+
"browser",
|
|
443
|
+
"import",
|
|
444
|
+
"module",
|
|
445
|
+
"default"
|
|
446
|
+
];
|
|
447
|
+
function resolveExportsEntry(exportsField, conditions = DEFAULT_EXPORT_CONDITIONS) {
|
|
448
|
+
return resolveExportsEntryWithConditions(exportsField, new Set(conditions));
|
|
449
|
+
}
|
|
450
|
+
function resolveExportsEntryWithConditions(exportsField, conditions) {
|
|
451
|
+
if (typeof exportsField === "string") return exportsField;
|
|
452
|
+
if (!exportsField || typeof exportsField !== "object") return void 0;
|
|
453
|
+
if (Array.isArray(exportsField)) {
|
|
454
|
+
for (const target of exportsField) {
|
|
455
|
+
const resolved = resolveExportsEntryWithConditions(target, conditions);
|
|
456
|
+
if (resolved) return resolved;
|
|
457
|
+
}
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
const record = exportsField;
|
|
461
|
+
const rootExport = record["."];
|
|
462
|
+
if (rootExport) return resolveExportsEntryWithConditions(rootExport, conditions);
|
|
463
|
+
for (const [condition, value] of Object.entries(record)) {
|
|
464
|
+
if (condition !== "default" && !conditions.has(condition)) continue;
|
|
465
|
+
const target = resolveExportsEntryWithConditions(value, conditions);
|
|
466
|
+
if (target) return target;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
function substituteExportsWildcard(target, patternMatch) {
|
|
470
|
+
if (typeof target === "string") return target.split("*").join(patternMatch);
|
|
471
|
+
if (Array.isArray(target)) return target.map((entry) => substituteExportsWildcard(entry, patternMatch));
|
|
472
|
+
if (target && typeof target === "object") {
|
|
473
|
+
const source = target;
|
|
474
|
+
const out = {};
|
|
475
|
+
for (const key of Object.keys(source)) out[key] = substituteExportsWildcard(source[key], patternMatch);
|
|
476
|
+
return out;
|
|
477
|
+
}
|
|
478
|
+
return target;
|
|
479
|
+
}
|
|
480
|
+
function matchExportsSubpath(record, subpath) {
|
|
481
|
+
if (subpath in record) return record[subpath];
|
|
482
|
+
let bestKey;
|
|
483
|
+
let bestBaseLength = -1;
|
|
484
|
+
let bestKeyLength = -1;
|
|
485
|
+
for (const key of Object.keys(record)) {
|
|
486
|
+
const wildcardIndex = key.indexOf("*");
|
|
487
|
+
if (wildcardIndex === -1) continue;
|
|
488
|
+
const patternBase = key.slice(0, wildcardIndex);
|
|
489
|
+
const patternTrailer = key.slice(wildcardIndex + 1);
|
|
490
|
+
if (patternTrailer.includes("*")) continue;
|
|
491
|
+
if (!subpath.startsWith(patternBase) || !subpath.endsWith(patternTrailer)) continue;
|
|
492
|
+
if (subpath.length <= patternBase.length + patternTrailer.length) continue;
|
|
493
|
+
if (patternBase.length > bestBaseLength || patternBase.length === bestBaseLength && key.length > bestKeyLength) {
|
|
494
|
+
bestKey = key;
|
|
495
|
+
bestBaseLength = patternBase.length;
|
|
496
|
+
bestKeyLength = key.length;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
if (bestKey === void 0) return void 0;
|
|
500
|
+
const patternTrailer = bestKey.slice(bestKey.indexOf("*") + 1);
|
|
501
|
+
const patternMatch = subpath.slice(bestBaseLength, subpath.length - patternTrailer.length);
|
|
502
|
+
return substituteExportsWildcard(record[bestKey], patternMatch);
|
|
503
|
+
}
|
|
504
|
+
function getPackageExportsTarget(pkg, packageName, exportsField) {
|
|
505
|
+
if (typeof exportsField === "string") return pkg === packageName ? exportsField : void 0;
|
|
506
|
+
if (!exportsField || typeof exportsField !== "object") return void 0;
|
|
507
|
+
const record = exportsField;
|
|
508
|
+
const subpath = pkg === packageName ? "." : `.${pkg.slice(packageName.length)}`;
|
|
509
|
+
if (subpath !== ".") return matchExportsSubpath(record, subpath);
|
|
510
|
+
return record["."] ?? (!Object.keys(record).some((key) => key.startsWith(".")) ? record : void 0);
|
|
511
|
+
}
|
|
512
|
+
/**
|
|
513
|
+
* Escaping rules:
|
|
514
|
+
* Convert using the format __${mapping}__, where _ and $ are not allowed in npm package names but can be used in variable names.
|
|
515
|
+
* @ => 1
|
|
516
|
+
* / => 2
|
|
517
|
+
* - => 3
|
|
518
|
+
* . => 4
|
|
519
|
+
*/
|
|
520
|
+
/**
|
|
521
|
+
* Encodes a package name into a valid file name.
|
|
522
|
+
* @param {string} name - The package name, e.g., "@scope/xx-xx.xx".
|
|
523
|
+
* @returns {string} - The encoded file name.
|
|
524
|
+
*/
|
|
525
|
+
function packageNameEncode(name) {
|
|
526
|
+
if (typeof name !== "string") throw createModuleFederationError("A string package name is required");
|
|
527
|
+
return name.replace(/@/g, "_mf_0_").replace(/\//g, "_mf_1_").replace(/-/g, "_mf_2_").replace(/\./g, "_mf_3_");
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* Decodes an encoded file name back to the original package name.
|
|
531
|
+
* @param {string} encoded - The encoded file name, e.g., "_mf_0_scope_mf_1_xx_mf_2_xx_mf_3_xx".
|
|
532
|
+
* @returns {string} - The decoded package name.
|
|
533
|
+
*/
|
|
534
|
+
function packageNameDecode(encoded) {
|
|
535
|
+
if (typeof encoded !== "string") throw createModuleFederationError("A string encoded file name is required");
|
|
536
|
+
return encoded.replace(/_mf_0_/g, "@").replace(/_mf_1_/g, "/").replace(/_mf_2_/g, "-").replace(/_mf_3_/g, ".");
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Removes any subpath from an npm package specifier and returns the package name only.
|
|
540
|
+
* @param {string} packageString - The package specifier, e.g., "@scope/pkg/runtime" or "react/jsx-runtime".
|
|
541
|
+
* @returns {string} - The base npm package name.
|
|
542
|
+
*/
|
|
543
|
+
function getPackageName(packageString) {
|
|
544
|
+
const match = packageString.match(/^(?:@[^/]+\/)?[^/]+/);
|
|
545
|
+
return match ? match[0] : packageString;
|
|
546
|
+
}
|
|
547
|
+
function getPackageNameFromNodeModulePath(source) {
|
|
548
|
+
const normalized = source.replace(/\\/g, "/");
|
|
549
|
+
const nodeModulesIndex = normalized.lastIndexOf("/node_modules/");
|
|
550
|
+
if (nodeModulesIndex < 0) return;
|
|
551
|
+
const parts = normalized.slice(nodeModulesIndex + 14).split("/");
|
|
552
|
+
if (!parts[0]) return;
|
|
553
|
+
if (parts[0].startsWith("@")) return parts[1] ? `${parts[0]}/${parts[1]}` : void 0;
|
|
554
|
+
return parts[0];
|
|
555
|
+
}
|
|
556
|
+
function getSharedCacheKeyParts(input) {
|
|
557
|
+
const scope = (Array.isArray(input.scope) ? input.scope[0] : input.scope) || "default";
|
|
558
|
+
const id = input.singleton || !input.version ? input.pkg : `${input.pkg}@${input.version}`;
|
|
559
|
+
return {
|
|
560
|
+
scope,
|
|
561
|
+
id,
|
|
562
|
+
key: `${scope}:${id}`
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
function getSharedCacheDescriptor(pkg, shareItem) {
|
|
566
|
+
const parts = getSharedCacheKeyParts({
|
|
567
|
+
pkg,
|
|
568
|
+
singleton: shareItem.shareConfig.singleton,
|
|
569
|
+
version: shareItem.version,
|
|
570
|
+
scope: shareItem.scope
|
|
571
|
+
});
|
|
572
|
+
return {
|
|
573
|
+
canonical: parts.key,
|
|
574
|
+
...parts.scope === "default" ? { aliases: [parts.id] } : {}
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
const sharedCacheHelperCode = `const __mfGetSharedCacheDescriptor = (pkg, singleton, version, scope) => {
|
|
578
|
+
const normalizedScope = Array.isArray(scope) ? scope[0] : scope;
|
|
579
|
+
const scopeName = normalizedScope || "default";
|
|
580
|
+
const id = singleton || !version ? pkg : pkg + "@" + version;
|
|
581
|
+
const descriptor = { canonical: scopeName + ":" + id };
|
|
582
|
+
if (scopeName === "default") descriptor.aliases = [id];
|
|
583
|
+
return descriptor;
|
|
584
|
+
};
|
|
585
|
+
const __mfReadSharedCache = (cache, descriptor) => {
|
|
586
|
+
const value = cache[descriptor.canonical];
|
|
587
|
+
if (value !== undefined) return value;
|
|
588
|
+
const aliases = descriptor.aliases || [];
|
|
589
|
+
for (const alias of aliases) {
|
|
590
|
+
if (!Object.prototype.hasOwnProperty.call(cache, alias)) continue;
|
|
591
|
+
const aliasValue = cache[alias];
|
|
592
|
+
if (aliasValue !== undefined) {
|
|
593
|
+
cache[descriptor.canonical] = aliasValue;
|
|
594
|
+
return aliasValue;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
return undefined;
|
|
598
|
+
};
|
|
599
|
+
const __mfSharedCacheListenersKey = Symbol.for("module-federation.shared-cache-listeners");
|
|
600
|
+
const __mfGetSharedCacheListeners = (cache) => {
|
|
601
|
+
let listeners = cache[__mfSharedCacheListenersKey];
|
|
602
|
+
if (listeners === undefined) {
|
|
603
|
+
listeners = Object.create(null);
|
|
604
|
+
Object.defineProperty(cache, __mfSharedCacheListenersKey, {
|
|
605
|
+
value: listeners,
|
|
606
|
+
enumerable: false,
|
|
607
|
+
configurable: false,
|
|
608
|
+
writable: false
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
return listeners;
|
|
612
|
+
};
|
|
613
|
+
const __mfSubscribeSharedCache = (cache, descriptor, listener) => {
|
|
614
|
+
const listeners = __mfGetSharedCacheListeners(cache);
|
|
615
|
+
(listeners[descriptor.canonical] ||= new Set()).add(listener);
|
|
616
|
+
};
|
|
617
|
+
const __mfSharedCacheOwnersKey = Symbol.for("module-federation.shared-cache-owners");
|
|
618
|
+
const __mfGetSharedCacheOwners = (cache) => {
|
|
619
|
+
let owners = cache[__mfSharedCacheOwnersKey];
|
|
620
|
+
if (owners === undefined) {
|
|
621
|
+
owners = Object.create(null);
|
|
622
|
+
Object.defineProperty(cache, __mfSharedCacheOwnersKey, {
|
|
623
|
+
value: owners,
|
|
624
|
+
enumerable: false,
|
|
625
|
+
configurable: false,
|
|
626
|
+
writable: false
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
return owners;
|
|
630
|
+
};
|
|
631
|
+
const __mfReadSharedCacheOwner = (cache, descriptor) =>
|
|
632
|
+
cache[__mfSharedCacheOwnersKey]?.[descriptor.canonical];
|
|
633
|
+
const __mfWriteSharedCache = (cache, descriptor, value, owner) => {
|
|
634
|
+
cache[descriptor.canonical] = value;
|
|
635
|
+
const aliases = descriptor.aliases || [];
|
|
636
|
+
for (const alias of aliases) {
|
|
637
|
+
Object.defineProperty(cache, alias, {
|
|
638
|
+
value,
|
|
639
|
+
enumerable: true,
|
|
640
|
+
configurable: true,
|
|
641
|
+
writable: true
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
const owners = cache[__mfSharedCacheOwnersKey];
|
|
645
|
+
if (owner === undefined) {
|
|
646
|
+
if (owners) delete owners[descriptor.canonical];
|
|
647
|
+
} else {
|
|
648
|
+
__mfGetSharedCacheOwners(cache)[descriptor.canonical] = owner;
|
|
649
|
+
}
|
|
650
|
+
const listeners = cache[__mfSharedCacheListenersKey]?.[descriptor.canonical];
|
|
651
|
+
if (listeners) {
|
|
652
|
+
for (const listener of listeners) listener(value);
|
|
653
|
+
}
|
|
654
|
+
return value;
|
|
655
|
+
};
|
|
656
|
+
const __mfTreeShakingSharedCacheKey = Symbol.for("module-federation.tree-shaking-shared-cache");
|
|
657
|
+
const __mfGetTreeShakingSharedCache = (cache) => {
|
|
658
|
+
let metadata = cache[__mfTreeShakingSharedCacheKey];
|
|
659
|
+
if (metadata === undefined) {
|
|
660
|
+
metadata = Object.create(null);
|
|
661
|
+
Object.defineProperty(cache, __mfTreeShakingSharedCacheKey, {
|
|
662
|
+
value: metadata,
|
|
663
|
+
enumerable: false,
|
|
664
|
+
configurable: false,
|
|
665
|
+
writable: false
|
|
666
|
+
});
|
|
667
|
+
}
|
|
668
|
+
return metadata;
|
|
669
|
+
};
|
|
670
|
+
const __mfReadTreeShakingSharedCache = (cache, descriptor, requiredExports) => {
|
|
671
|
+
const fullModule = __mfReadSharedCache(cache, descriptor);
|
|
672
|
+
if (fullModule !== undefined) return fullModule;
|
|
673
|
+
if (!Array.isArray(requiredExports)) return undefined;
|
|
674
|
+
const metadata = cache[__mfTreeShakingSharedCacheKey];
|
|
675
|
+
const entries = metadata?.[descriptor.canonical] || [];
|
|
676
|
+
let compatibleEntry;
|
|
677
|
+
for (const entry of entries) {
|
|
678
|
+
if (!requiredExports.every((name) => entry.providedExports.includes(name))) continue;
|
|
679
|
+
if (!compatibleEntry || entry.providedExports.length < compatibleEntry.providedExports.length) {
|
|
680
|
+
compatibleEntry = entry;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
return compatibleEntry?.value;
|
|
684
|
+
};
|
|
685
|
+
const __mfWriteTreeShakingSharedCache = (cache, descriptor, providedExports, value) => {
|
|
686
|
+
if (!Array.isArray(providedExports)) return value;
|
|
687
|
+
const normalizedExports = [...new Set(providedExports)].sort();
|
|
688
|
+
const metadata = __mfGetTreeShakingSharedCache(cache);
|
|
689
|
+
const entries = (metadata[descriptor.canonical] ||= []);
|
|
690
|
+
const existing = entries.find((entry) =>
|
|
691
|
+
entry.providedExports.length === normalizedExports.length &&
|
|
692
|
+
entry.providedExports.every((name, index) => name === normalizedExports[index])
|
|
693
|
+
);
|
|
694
|
+
if (existing) existing.value = value;
|
|
695
|
+
else entries.push({ providedExports: normalizedExports, value });
|
|
696
|
+
return value;
|
|
697
|
+
};
|
|
698
|
+
const __mfTreeShakingSelectionCacheKey = Symbol.for("module-federation.tree-shaking-shared-selection-cache");
|
|
699
|
+
const __mfGetTreeShakingSelectionCache = (cache) => {
|
|
700
|
+
let selections = cache[__mfTreeShakingSelectionCacheKey];
|
|
701
|
+
if (selections === undefined) {
|
|
702
|
+
selections = Object.create(null);
|
|
703
|
+
Object.defineProperty(cache, __mfTreeShakingSelectionCacheKey, {
|
|
704
|
+
value: selections,
|
|
705
|
+
enumerable: false,
|
|
706
|
+
configurable: false,
|
|
707
|
+
writable: false
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
return selections;
|
|
711
|
+
};
|
|
712
|
+
const __mfReadTreeShakingSharedSelection = (cache, descriptor, consumer) => {
|
|
713
|
+
const fullModule = __mfReadSharedCache(cache, descriptor);
|
|
714
|
+
if (fullModule !== undefined) return fullModule;
|
|
715
|
+
return cache[__mfTreeShakingSelectionCacheKey]?.[descriptor.canonical]?.[consumer];
|
|
716
|
+
};
|
|
717
|
+
const __mfWriteTreeShakingSharedSelection = (cache, descriptor, consumer, value) => {
|
|
718
|
+
const selections = __mfGetTreeShakingSelectionCache(cache);
|
|
719
|
+
const byConsumer = (selections[descriptor.canonical] ||= Object.create(null));
|
|
720
|
+
byConsumer[consumer] = value;
|
|
721
|
+
return value;
|
|
722
|
+
};`;
|
|
723
|
+
function getInstalledPackageJson(pkg, opts) {
|
|
724
|
+
const cwd = opts?.cwd || getPackageDetectionCwd();
|
|
725
|
+
const packageName = opts?.packageName || getPackageName(pkg);
|
|
726
|
+
const cacheKey = `${cwd}\0${pkg}\0${packageName}\0${opts?.fromResolvedEntry ?? ""}`;
|
|
727
|
+
if (installedPackageJsonCache.has(cacheKey)) return installedPackageJsonCache.get(cacheKey);
|
|
728
|
+
const result = resolveInstalledPackageJson(pkg, cwd, packageName, opts);
|
|
729
|
+
installedPackageJsonCache.set(cacheKey, result);
|
|
730
|
+
return result;
|
|
731
|
+
}
|
|
732
|
+
function resolveInstalledPackageJson(pkg, cwd, packageName, opts) {
|
|
733
|
+
const tryReadPackageJson = (packageJsonPath) => {
|
|
734
|
+
if (!existsSync(packageJsonPath)) return void 0;
|
|
735
|
+
try {
|
|
736
|
+
return {
|
|
737
|
+
path: packageJsonPath,
|
|
738
|
+
dir: path$1.dirname(packageJsonPath),
|
|
739
|
+
packageJson: JSON.parse(readFileSync(packageJsonPath, "utf-8"))
|
|
740
|
+
};
|
|
741
|
+
} catch {
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
744
|
+
};
|
|
745
|
+
const findPackageInPnpmStore = (startDir) => {
|
|
746
|
+
let currentDir = startDir;
|
|
747
|
+
const rootDir = path$1.parse(currentDir).root;
|
|
748
|
+
while (true) {
|
|
749
|
+
const pnpmStoreDir = path$1.join(currentDir, "node_modules", ".pnpm");
|
|
750
|
+
if (existsSync(pnpmStoreDir)) try {
|
|
751
|
+
for (const entry of readdirSync(pnpmStoreDir, { withFileTypes: true })) {
|
|
752
|
+
if (!entry.isDirectory()) continue;
|
|
753
|
+
const candidate = tryReadPackageJson(path$1.join(pnpmStoreDir, entry.name, "node_modules", packageName, "package.json"));
|
|
754
|
+
if (candidate?.packageJson.name === packageName) return candidate;
|
|
755
|
+
}
|
|
756
|
+
} catch {}
|
|
757
|
+
if (currentDir === rootDir) break;
|
|
758
|
+
currentDir = path$1.dirname(currentDir);
|
|
759
|
+
}
|
|
760
|
+
};
|
|
761
|
+
try {
|
|
762
|
+
const projectRequire = createRequire$1(pathToFileURL(path$1.join(cwd, "package.json")));
|
|
763
|
+
let resolvedPath;
|
|
764
|
+
if (opts?.fromResolvedEntry) resolvedPath = opts.fromResolvedEntry;
|
|
765
|
+
else try {
|
|
766
|
+
resolvedPath = projectRequire.resolve(pkg);
|
|
767
|
+
} catch {
|
|
768
|
+
resolvedPath = projectRequire.resolve(packageName);
|
|
769
|
+
}
|
|
770
|
+
let currentDir = path$1.dirname(resolvedPath);
|
|
771
|
+
const rootDir = path$1.parse(currentDir).root;
|
|
772
|
+
while (true) {
|
|
773
|
+
const packageJsonPath = path$1.join(currentDir, "package.json");
|
|
774
|
+
if (existsSync(packageJsonPath)) {
|
|
775
|
+
const packageJsonContent = readFileSync(packageJsonPath, "utf-8");
|
|
776
|
+
try {
|
|
777
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
778
|
+
if (packageJson.name === packageName) return {
|
|
779
|
+
path: packageJsonPath,
|
|
780
|
+
dir: currentDir,
|
|
781
|
+
packageJson
|
|
782
|
+
};
|
|
783
|
+
} catch (error) {
|
|
784
|
+
if (!(error instanceof SyntaxError)) throw error;
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
if (currentDir === rootDir) break;
|
|
788
|
+
currentDir = path$1.dirname(currentDir);
|
|
789
|
+
}
|
|
790
|
+
} catch {
|
|
791
|
+
let currentDir = cwd;
|
|
792
|
+
const rootDir = path$1.parse(currentDir).root;
|
|
793
|
+
while (true) {
|
|
794
|
+
const directCandidate = tryReadPackageJson(path$1.join(currentDir, "node_modules", packageName, "package.json"));
|
|
795
|
+
if (directCandidate?.packageJson.name === packageName) return directCandidate;
|
|
796
|
+
if (currentDir === rootDir) break;
|
|
797
|
+
currentDir = path$1.dirname(currentDir);
|
|
798
|
+
}
|
|
799
|
+
return findPackageInPnpmStore(cwd);
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
function getInstalledPackageEntry(pkg, opts) {
|
|
803
|
+
const installed = getInstalledPackageJson(pkg, opts);
|
|
804
|
+
if (!installed) return void 0;
|
|
805
|
+
const cwd = opts?.cwd || getPackageDetectionCwd();
|
|
806
|
+
const packageName = opts?.packageName || getPackageName(pkg);
|
|
807
|
+
const packageJson = installed.packageJson;
|
|
808
|
+
if (pkg !== packageName && (opts?.resolveSubpathWithRequire !== false || packageJson.exports === void 0)) try {
|
|
809
|
+
return createRequire$1(pathToFileURL(path$1.join(cwd, "package.json"))).resolve(pkg);
|
|
810
|
+
} catch {}
|
|
811
|
+
const explicitEntry = resolveExportsEntry(getPackageExportsTarget(pkg, packageName, packageJson.exports), opts?.conditions) || (typeof packageJson.module === "string" ? packageJson.module : void 0) || (typeof packageJson.main === "string" ? packageJson.main : void 0) || "index.js";
|
|
812
|
+
return path$1.join(installed.dir, explicitEntry);
|
|
813
|
+
}
|
|
814
|
+
/**
|
|
815
|
+
* Detect whether the current runtime is Vite 8+ by checking for a Vite version flag
|
|
816
|
+
* on the plugin hook context, with Rolldown metadata kept as a compatibility fallback.
|
|
817
|
+
*/
|
|
818
|
+
function getIsRolldown(ctx) {
|
|
819
|
+
const viteVersion = ctx?.meta?.viteVersion;
|
|
820
|
+
const viteMajor = Number(String(viteVersion ?? "").split(".")[0]);
|
|
821
|
+
return Number.isFinite(viteMajor) && viteMajor >= 8 || !!ctx?.meta?.rolldownVersion;
|
|
822
|
+
}
|
|
823
|
+
/** Walk up from Vite `config.root` (Nuxt may point at `.nuxt` cache dirs). */
|
|
824
|
+
function isNuxtProjectRoot(root) {
|
|
825
|
+
let dir = root;
|
|
826
|
+
for (let i = 0; i < 8; i++) {
|
|
827
|
+
if (hasPackageDependency("nuxt", dir) || hasPackageDependency("nuxt-nightly", dir)) return true;
|
|
828
|
+
const parent = path$1.dirname(dir);
|
|
829
|
+
if (parent === dir) break;
|
|
830
|
+
dir = parent;
|
|
831
|
+
}
|
|
832
|
+
return false;
|
|
833
|
+
}
|
|
834
|
+
function hasPackageDependency(dependencyName, cwd = packageDetectionCwd || process.cwd()) {
|
|
835
|
+
const cacheKey = getDependencyCacheKey(cwd, dependencyName);
|
|
836
|
+
const cached = dependencyPresenceCache.get(cacheKey);
|
|
837
|
+
if (cached !== void 0) return cached;
|
|
838
|
+
try {
|
|
839
|
+
const packageJson = JSON.parse(readFileSync(path$1.join(cwd, "package.json"), "utf8"));
|
|
840
|
+
const hasDependency = [
|
|
841
|
+
packageJson.dependencies,
|
|
842
|
+
packageJson.devDependencies,
|
|
843
|
+
packageJson.peerDependencies,
|
|
844
|
+
packageJson.optionalDependencies
|
|
845
|
+
].some((deps) => !!deps?.[dependencyName]);
|
|
846
|
+
dependencyPresenceCache.set(cacheKey, hasDependency);
|
|
847
|
+
return hasDependency;
|
|
848
|
+
} catch {
|
|
849
|
+
dependencyPresenceCache.set(cacheKey, false);
|
|
850
|
+
return false;
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
//#endregion
|
|
175
854
|
//#region src/utils/pathNormalization.ts
|
|
176
855
|
const COMMON_SHARED_SUBPATHS = {
|
|
177
856
|
react: [
|
|
@@ -247,11 +926,11 @@ function removeTrailingSlash(value) {
|
|
|
247
926
|
function ensureTrailingSlash(value) {
|
|
248
927
|
return `${removeTrailingSlash(value)}/`;
|
|
249
928
|
}
|
|
250
|
-
function getBasePath$
|
|
929
|
+
function getBasePath$2(base) {
|
|
251
930
|
return removeTrailingSlash(base || "/");
|
|
252
931
|
}
|
|
253
932
|
function isNuxtClientBase(base) {
|
|
254
|
-
return getBasePath$
|
|
933
|
+
return getBasePath$2(base).endsWith("/_nuxt");
|
|
255
934
|
}
|
|
256
935
|
function normalizeNodeModulePath(source) {
|
|
257
936
|
return source.replace(/\\/g, "/").replace(/\?.*$/, "");
|
|
@@ -492,6 +1171,13 @@ function normalizeManifest(manifest) {
|
|
|
492
1171
|
fileName: manifest.fileName || "mf-manifest.json"
|
|
493
1172
|
};
|
|
494
1173
|
}
|
|
1174
|
+
function normalizeExperiments(experiments) {
|
|
1175
|
+
return {
|
|
1176
|
+
externalRuntime: experiments?.externalRuntime === true,
|
|
1177
|
+
provideExternalRuntime: experiments?.provideExternalRuntime === true,
|
|
1178
|
+
ssrMode: experiments?.ssrMode === "ISLAND" ? "ISLAND" : void 0
|
|
1179
|
+
};
|
|
1180
|
+
}
|
|
495
1181
|
let config;
|
|
496
1182
|
let explicitSharedKeys = /* @__PURE__ */ new Set();
|
|
497
1183
|
const explicitSharedKeysByOptions = /* @__PURE__ */ new WeakMap();
|
|
@@ -551,8 +1237,10 @@ function normalizeModuleFederationOptions(options) {
|
|
|
551
1237
|
target: options.target,
|
|
552
1238
|
disableRemote: options.disableRemote,
|
|
553
1239
|
disableShared: options.disableShared,
|
|
554
|
-
disableSnapshot: options.disableSnapshot
|
|
1240
|
+
disableSnapshot: options.disableSnapshot,
|
|
1241
|
+
experiments: normalizeExperiments(options.experiments)
|
|
555
1242
|
};
|
|
1243
|
+
if (normalized.experiments.ssrMode === "ISLAND" && Object.prototype.hasOwnProperty.call(normalized.shared, "react")) mfWarn("Island expose generation is disabled because experiments.ssrMode is \"ISLAND\" and React is configured as shared. Remove \"react\" from shared to generate island exposes, or remove ssrMode to use standard shared rendering.");
|
|
556
1244
|
explicitSharedKeysByOptions.set(normalized, new Set(explicitSharedKeys));
|
|
557
1245
|
return config = normalized;
|
|
558
1246
|
}
|
|
@@ -569,6 +1257,7 @@ const cacheMap = {};
|
|
|
569
1257
|
const idCacheMap = {};
|
|
570
1258
|
const VITE_ID_PREFIX = "/@id/";
|
|
571
1259
|
const VITE_ENCODED_NULL_BYTE_PREFIX = `${VITE_ID_PREFIX}__x00__`;
|
|
1260
|
+
const MF_OWNER_INFIX = "__mf_owner__";
|
|
572
1261
|
function escapeRegExp$2(value) {
|
|
573
1262
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
574
1263
|
}
|
|
@@ -717,6 +1406,245 @@ function serializeRuntimeOptions(options) {
|
|
|
717
1406
|
return `{${topLevelProps.join(", ")}}`;
|
|
718
1407
|
}
|
|
719
1408
|
//#endregion
|
|
1409
|
+
//#region src/utils/reactIsland.ts
|
|
1410
|
+
const SOURCE_EXTENSIONS = [
|
|
1411
|
+
".tsx",
|
|
1412
|
+
".jsx",
|
|
1413
|
+
".ts",
|
|
1414
|
+
".js",
|
|
1415
|
+
".mts",
|
|
1416
|
+
".mjs",
|
|
1417
|
+
".cts",
|
|
1418
|
+
".cjs"
|
|
1419
|
+
];
|
|
1420
|
+
function stripQueryAndHash$2(id) {
|
|
1421
|
+
return id.split(/[?#]/, 1)[0];
|
|
1422
|
+
}
|
|
1423
|
+
function resolveSourceFile(importPath, root) {
|
|
1424
|
+
const cleanImport = stripQueryAndHash$2(importPath);
|
|
1425
|
+
if (!cleanImport.startsWith(".") && !path$1.isAbsolute(cleanImport)) return;
|
|
1426
|
+
const candidate = path$1.isAbsolute(cleanImport) ? cleanImport : path$1.resolve(root, cleanImport);
|
|
1427
|
+
return [
|
|
1428
|
+
candidate,
|
|
1429
|
+
...SOURCE_EXTENSIONS.map((extension) => `${candidate}${extension}`),
|
|
1430
|
+
...SOURCE_EXTENSIONS.map((extension) => path$1.join(candidate, `index${extension}`))
|
|
1431
|
+
].find((filePath) => {
|
|
1432
|
+
try {
|
|
1433
|
+
return fs$1.statSync(filePath).isFile();
|
|
1434
|
+
} catch {
|
|
1435
|
+
return false;
|
|
1436
|
+
}
|
|
1437
|
+
});
|
|
1438
|
+
}
|
|
1439
|
+
function localDefaultReexport(source) {
|
|
1440
|
+
const match = source.match(/export\s*{\s*(?:default(?:\s+as\s+default)?|[A-Za-z_$][\w$]*\s+as\s+default)\s*}\s*from\s*["']([^"']+)["']/);
|
|
1441
|
+
return match?.[1]?.startsWith(".") ? match[1] : void 0;
|
|
1442
|
+
}
|
|
1443
|
+
function isReactComponentSource(source, filePath = "component.tsx") {
|
|
1444
|
+
if (!(/\bexport\s+default\b/.test(source) || /\bexport\s*{[^}]*\bdefault\b[^}]*}(?:\s*from\s*["'][^"']+["'])?/.test(source))) return false;
|
|
1445
|
+
const extension = path$1.extname(stripQueryAndHash$2(filePath)).toLowerCase();
|
|
1446
|
+
const canContainJsx = extension === ".tsx" || extension === ".jsx";
|
|
1447
|
+
const hasJsx = /<>|<\s*[A-Za-z][\w.:-]*(?:\s[^<>]*?)?\s*\/?>/.test(source);
|
|
1448
|
+
const importsReact = /\bfrom\s*["']react["']|\brequire\(\s*["']react["']\s*\)/.test(source);
|
|
1449
|
+
const usesReactApi = /\b(?:React\.)?(?:createElement|jsx|jsxs)\s*\(/.test(source);
|
|
1450
|
+
const isClientModule = /^\s*["']use client["']\s*;?/m.test(source);
|
|
1451
|
+
return canContainJsx && hasJsx || importsReact && (hasJsx || usesReactApi || isClientModule);
|
|
1452
|
+
}
|
|
1453
|
+
function isReactComponentFile(filePath, seen = /* @__PURE__ */ new Set()) {
|
|
1454
|
+
const normalizedPath = path$1.resolve(filePath);
|
|
1455
|
+
if (seen.has(normalizedPath)) return false;
|
|
1456
|
+
seen.add(normalizedPath);
|
|
1457
|
+
let source;
|
|
1458
|
+
try {
|
|
1459
|
+
source = fs$1.readFileSync(normalizedPath, "utf8");
|
|
1460
|
+
} catch {
|
|
1461
|
+
return false;
|
|
1462
|
+
}
|
|
1463
|
+
if (isReactComponentSource(source, normalizedPath)) return true;
|
|
1464
|
+
const reexport = localDefaultReexport(source);
|
|
1465
|
+
if (!reexport) return false;
|
|
1466
|
+
const reexportPath = resolveSourceFile(reexport, path$1.dirname(normalizedPath));
|
|
1467
|
+
return reexportPath ? isReactComponentFile(reexportPath, seen) : false;
|
|
1468
|
+
}
|
|
1469
|
+
/**
|
|
1470
|
+
* React is shared by the normal MF runtime when explicitly configured. When it
|
|
1471
|
+
* is local, UI exposes can safely advertise an island capability in addition
|
|
1472
|
+
* to their unchanged default export.
|
|
1473
|
+
*/
|
|
1474
|
+
function getReactIslandExposes(options, root) {
|
|
1475
|
+
if (options.experiments.ssrMode !== "ISLAND") return /* @__PURE__ */ new Set();
|
|
1476
|
+
if (Object.prototype.hasOwnProperty.call(options.shared, "react")) return /* @__PURE__ */ new Set();
|
|
1477
|
+
const islandExposes = /* @__PURE__ */ new Set();
|
|
1478
|
+
for (const [key, expose] of Object.entries(options.exposes)) {
|
|
1479
|
+
const sourceFile = resolveSourceFile(expose.import, root);
|
|
1480
|
+
if (sourceFile && isReactComponentFile(sourceFile)) islandExposes.add(key);
|
|
1481
|
+
}
|
|
1482
|
+
return islandExposes;
|
|
1483
|
+
}
|
|
1484
|
+
function generateReactIslandBrowserDefinition(enabled) {
|
|
1485
|
+
if (!enabled) return "";
|
|
1486
|
+
return `
|
|
1487
|
+
exportModule.__mf_island = {
|
|
1488
|
+
version: 1,
|
|
1489
|
+
renderToHtml() {
|
|
1490
|
+
return Promise.reject(new Error("[Module Federation] renderToHtml is only available in the SSR remote entry"));
|
|
1491
|
+
},
|
|
1492
|
+
hydrate(element, props) {
|
|
1493
|
+
const root = element && element.hasAttribute && element.hasAttribute("data-mf-island-state")
|
|
1494
|
+
? element
|
|
1495
|
+
: element && element.querySelector
|
|
1496
|
+
? element.querySelector("[data-mf-island-state]") || element
|
|
1497
|
+
: element;
|
|
1498
|
+
if (!root) {
|
|
1499
|
+
return Promise.reject(new Error("[Module Federation] Cannot hydrate an island without a root element"));
|
|
1500
|
+
}
|
|
1501
|
+
let serverProps = {};
|
|
1502
|
+
const encodedState = root.getAttribute && root.getAttribute("data-mf-island-state");
|
|
1503
|
+
if (encodedState) {
|
|
1504
|
+
try {
|
|
1505
|
+
serverProps = JSON.parse(decodeURIComponent(encodedState));
|
|
1506
|
+
} catch {
|
|
1507
|
+
serverProps = {};
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
const finalProps = Object.assign({}, serverProps, props || {});
|
|
1511
|
+
return Promise.all([import("react"), import("react-dom/client")]).then(([React, ReactDOMClient]) => {
|
|
1512
|
+
if (typeof ReactDOMClient.hydrateRoot !== "function") {
|
|
1513
|
+
throw new Error("[Module Federation] react-dom/client does not provide hydrateRoot");
|
|
1514
|
+
}
|
|
1515
|
+
return ReactDOMClient.hydrateRoot(
|
|
1516
|
+
root,
|
|
1517
|
+
React.createElement(importModule.default, finalProps)
|
|
1518
|
+
);
|
|
1519
|
+
});
|
|
1520
|
+
}
|
|
1521
|
+
}`;
|
|
1522
|
+
}
|
|
1523
|
+
function generateReactIslandSSRDefinition(enabled) {
|
|
1524
|
+
if (!enabled) return "";
|
|
1525
|
+
return `
|
|
1526
|
+
exportModule.__mf_island = {
|
|
1527
|
+
version: 1,
|
|
1528
|
+
async renderToHtml(props) {
|
|
1529
|
+
if (typeof importModule.default !== "function" && typeof importModule.default !== "object") {
|
|
1530
|
+
throw new Error("[Module Federation] A React island expose must have a default component export");
|
|
1531
|
+
}
|
|
1532
|
+
const loadedProps = typeof importModule.load === "function" ? await importModule.load() : {};
|
|
1533
|
+
const finalProps = Object.assign({}, loadedProps || {}, props || {});
|
|
1534
|
+
const [React, ReactDOMServer] = await Promise.all([
|
|
1535
|
+
import("react"),
|
|
1536
|
+
import("react-dom/server")
|
|
1537
|
+
]);
|
|
1538
|
+
const body = ReactDOMServer.renderToString(
|
|
1539
|
+
React.createElement(importModule.default, finalProps)
|
|
1540
|
+
);
|
|
1541
|
+
const state = encodeURIComponent(JSON.stringify(finalProps));
|
|
1542
|
+
return '<div data-mf-island-state="' + state + '">' + body + '</div>';
|
|
1543
|
+
},
|
|
1544
|
+
hydrate() {
|
|
1545
|
+
return Promise.reject(new Error("[Module Federation] hydrate is only available in the browser remote entry"));
|
|
1546
|
+
}
|
|
1547
|
+
}`;
|
|
1548
|
+
}
|
|
1549
|
+
const REACT_ISLAND_CLIENT_ID_PREFIX = "virtual:mf-react-island-client:";
|
|
1550
|
+
const REACT_ISLAND_SERVER_ID_PREFIX = "virtual:mf-react-island-server:";
|
|
1551
|
+
const RESOLVED_REACT_ISLAND_CLIENT_ID_PREFIX = `\0${REACT_ISLAND_CLIENT_ID_PREFIX}`;
|
|
1552
|
+
const RESOLVED_REACT_ISLAND_SERVER_ID_PREFIX = `\0${REACT_ISLAND_SERVER_ID_PREFIX}`;
|
|
1553
|
+
function encodeIslandRemoteId(remoteId) {
|
|
1554
|
+
return encodeURIComponent(remoteId);
|
|
1555
|
+
}
|
|
1556
|
+
function decodeIslandRemoteId(encodedRemoteId) {
|
|
1557
|
+
return decodeURIComponent(encodedRemoteId);
|
|
1558
|
+
}
|
|
1559
|
+
function getReactIslandImportRemoteId(source) {
|
|
1560
|
+
const queryIndex = source.indexOf("?");
|
|
1561
|
+
if (queryIndex === -1) return;
|
|
1562
|
+
if (!new URLSearchParams(source.slice(queryIndex + 1)).has("mf-island")) return;
|
|
1563
|
+
return source.slice(0, queryIndex);
|
|
1564
|
+
}
|
|
1565
|
+
function getReactIslandServerImportId(remoteId) {
|
|
1566
|
+
return `${REACT_ISLAND_SERVER_ID_PREFIX}${encodeIslandRemoteId(remoteId)}`;
|
|
1567
|
+
}
|
|
1568
|
+
function getReactIslandClientImportId(remoteId) {
|
|
1569
|
+
return `${REACT_ISLAND_CLIENT_ID_PREFIX}${encodeIslandRemoteId(remoteId)}`;
|
|
1570
|
+
}
|
|
1571
|
+
function resolveReactIslandConsumerId(id) {
|
|
1572
|
+
if (id.startsWith("virtual:mf-react-island-server:")) return `\0${id}`;
|
|
1573
|
+
if (id.startsWith("virtual:mf-react-island-client:")) return `\0${id}`;
|
|
1574
|
+
}
|
|
1575
|
+
function remoteIdFromResolvedIslandId(id, prefix) {
|
|
1576
|
+
if (!id.startsWith(prefix)) return;
|
|
1577
|
+
return decodeIslandRemoteId(id.slice(prefix.length));
|
|
1578
|
+
}
|
|
1579
|
+
/** Generates the server half of the opt-in `?mf-island` consumer component. */
|
|
1580
|
+
function generateReactIslandConsumerServer(remoteId) {
|
|
1581
|
+
const source = JSON.stringify(remoteId);
|
|
1582
|
+
return `import * as React from "react";
|
|
1583
|
+
import IslandClient from ${JSON.stringify(getReactIslandClientImportId(remoteId))};
|
|
1584
|
+
|
|
1585
|
+
const islandModulePromise = import(${source});
|
|
1586
|
+
|
|
1587
|
+
async function loadIslandModule() {
|
|
1588
|
+
const namespace = await islandModulePromise;
|
|
1589
|
+
const pending = namespace && namespace.__mf_remote_pending;
|
|
1590
|
+
if (pending && typeof pending.then === "function") return pending;
|
|
1591
|
+
return namespace && namespace.__moduleExports || namespace;
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1594
|
+
export default async function ModuleFederationIsland(props) {
|
|
1595
|
+
const remoteModule = await loadIslandModule();
|
|
1596
|
+
const shell = remoteModule && remoteModule.__mf_island;
|
|
1597
|
+
if (!shell || typeof shell.renderToHtml !== "function") {
|
|
1598
|
+
throw new Error(${JSON.stringify(`[Module Federation] ${remoteId} does not expose an SSR island capability`)});
|
|
1599
|
+
}
|
|
1600
|
+
const html = await shell.renderToHtml(props);
|
|
1601
|
+
return React.createElement(IslandClient, { html, islandProps: props });
|
|
1602
|
+
}`;
|
|
1603
|
+
}
|
|
1604
|
+
/** Generates the client boundary which hydrates with the remote-owned React. */
|
|
1605
|
+
function generateReactIslandConsumerClient(remoteId) {
|
|
1606
|
+
return `"use client";
|
|
1607
|
+
|
|
1608
|
+
import * as React from "react";
|
|
1609
|
+
|
|
1610
|
+
const islandModulePromise = import(${JSON.stringify(remoteId)});
|
|
1611
|
+
|
|
1612
|
+
async function loadIslandModule() {
|
|
1613
|
+
const namespace = await islandModulePromise;
|
|
1614
|
+
const pending = namespace && namespace.__mf_remote_pending;
|
|
1615
|
+
if (pending && typeof pending.then === "function") return pending;
|
|
1616
|
+
return namespace && namespace.__moduleExports || namespace;
|
|
1617
|
+
}
|
|
1618
|
+
|
|
1619
|
+
export default function ModuleFederationIslandClient({ html, islandProps }) {
|
|
1620
|
+
const ref = React.useRef(null);
|
|
1621
|
+
|
|
1622
|
+
React.useEffect(() => {
|
|
1623
|
+
const element = ref.current;
|
|
1624
|
+
if (!element) return;
|
|
1625
|
+
void loadIslandModule().then((remoteModule) => {
|
|
1626
|
+
const shell = remoteModule && remoteModule.__mf_island;
|
|
1627
|
+
if (!shell || typeof shell.hydrate !== "function") {
|
|
1628
|
+
throw new Error(${JSON.stringify(`[Module Federation] ${remoteId} does not expose a client island capability`)});
|
|
1629
|
+
}
|
|
1630
|
+
return shell.hydrate(element, islandProps);
|
|
1631
|
+
});
|
|
1632
|
+
}, []);
|
|
1633
|
+
|
|
1634
|
+
return React.createElement("div", {
|
|
1635
|
+
ref,
|
|
1636
|
+
suppressHydrationWarning: true,
|
|
1637
|
+
dangerouslySetInnerHTML: { __html: html },
|
|
1638
|
+
});
|
|
1639
|
+
}`;
|
|
1640
|
+
}
|
|
1641
|
+
function loadReactIslandConsumerModule(id) {
|
|
1642
|
+
const serverRemoteId = remoteIdFromResolvedIslandId(id, RESOLVED_REACT_ISLAND_SERVER_ID_PREFIX);
|
|
1643
|
+
if (serverRemoteId !== void 0) return generateReactIslandConsumerServer(serverRemoteId);
|
|
1644
|
+
const clientRemoteId = remoteIdFromResolvedIslandId(id, RESOLVED_REACT_ISLAND_CLIENT_ID_PREFIX);
|
|
1645
|
+
if (clientRemoteId !== void 0) return generateReactIslandConsumerClient(clientRemoteId);
|
|
1646
|
+
}
|
|
1647
|
+
//#endregion
|
|
720
1648
|
//#region src/virtualModules/virtualExposes.ts
|
|
721
1649
|
const EXPOSES_CSS_MAP_PLACEHOLDER = "__MF_EXPOSES_CSS_MAP__";
|
|
722
1650
|
function getExposesCssMapPlaceholder() {
|
|
@@ -725,7 +1653,7 @@ function getExposesCssMapPlaceholder() {
|
|
|
725
1653
|
function getVirtualExposesId(options) {
|
|
726
1654
|
return `virtual:mf-exposes:${`${options.internalName}__${options.filename}`.replace(/[^a-zA-Z0-9_-]/g, "_")}`;
|
|
727
1655
|
}
|
|
728
|
-
function generateExposes(options, remoteDependencyMap = {}, command = "build") {
|
|
1656
|
+
function generateExposes(options, remoteDependencyMap = {}, command = "build", reactIslandExposes = /* @__PURE__ */ new Set()) {
|
|
729
1657
|
return `
|
|
730
1658
|
const cssAssetMap = ${JSON.stringify(options.bundleAllCSS ? EXPOSES_CSS_MAP_PLACEHOLDER : {})};
|
|
731
1659
|
const injectedCssHrefs = new Set();
|
|
@@ -801,6 +1729,7 @@ function generateExposes(options, remoteDependencyMap = {}, command = "build") {
|
|
|
801
1729
|
}
|
|
802
1730
|
const exportModule = {}
|
|
803
1731
|
Object.assign(exportModule, importModule)
|
|
1732
|
+
${generateReactIslandBrowserDefinition(reactIslandExposes.has(key))}
|
|
804
1733
|
Object.defineProperty(exportModule, "__esModule", {
|
|
805
1734
|
value: true,
|
|
806
1735
|
enumerable: false
|
|
@@ -832,7 +1761,7 @@ function getRuntimeInitModule(options) {
|
|
|
832
1761
|
let runtimeInitModule = runtimeInitModules.get(options);
|
|
833
1762
|
if (!runtimeInitModule) {
|
|
834
1763
|
const ownerId = getRuntimeInitOwnerId(options);
|
|
835
|
-
runtimeInitModule = new VirtualModule("runtimeInit", "__mf_v__", "", `${options.internalName}
|
|
1764
|
+
runtimeInitModule = new VirtualModule("runtimeInit", "__mf_v__", "", `${options.internalName}${MF_OWNER_INFIX}${ownerId}`);
|
|
836
1765
|
runtimeInitModules.set(options, runtimeInitModule);
|
|
837
1766
|
}
|
|
838
1767
|
return runtimeInitModule;
|
|
@@ -845,7 +1774,7 @@ function getRuntimeRemoteCachePrefix(options) {
|
|
|
845
1774
|
}
|
|
846
1775
|
function getRuntimeRemoteAlias(alias, options) {
|
|
847
1776
|
if (!options) return alias;
|
|
848
|
-
return `${options.internalName}
|
|
1777
|
+
return `${options.internalName}${MF_OWNER_INFIX}${getRuntimeInitOwnerId(options)}__${alias}`;
|
|
849
1778
|
}
|
|
850
1779
|
function getRuntimeInitGlobalKey(ownerImportId) {
|
|
851
1780
|
return `__mf_init__${ownerImportId ?? virtualRuntimeInitStatus.getImportId()}__`;
|
|
@@ -974,154 +1903,15 @@ function getRuntimeInitResolveBootstrapCode(enableSsrInit = false, ownerImportId
|
|
|
974
1903
|
ssrRemotes
|
|
975
1904
|
});
|
|
976
1905
|
}
|
|
977
|
-
function writeRuntimeInitStatus(command, enableSsrInit = false, hostInitImportId, options, ssrRemotes = _ssrRemotes) {
|
|
978
|
-
const exportStatement = command === "build" ? `const { initPromise, initResolve, initReject, moduleCache } = globalThis[globalKey];
|
|
979
|
-
export { initPromise, initResolve, initReject, moduleCache };` : `module.exports = globalThis[globalKey];`;
|
|
980
|
-
const ownerImportId = options ? getRuntimeInitStatusImportId(options) : hostInitImportId;
|
|
981
|
-
getRuntimeInitModule(options).writeSync(`
|
|
982
|
-
${getRuntimeInitBootstrapCode(enableSsrInit, ownerImportId, ssrRemotes, hostInitImportId)}
|
|
983
|
-
${exportStatement}
|
|
984
|
-
`);
|
|
985
|
-
}
|
|
986
|
-
//#endregion
|
|
987
|
-
//#region src/utils/codePositionMap.ts
|
|
988
|
-
const REGEX_PREFIX_KEYWORDS = new Set([
|
|
989
|
-
"await",
|
|
990
|
-
"case",
|
|
991
|
-
"delete",
|
|
992
|
-
"in",
|
|
993
|
-
"instanceof",
|
|
994
|
-
"new",
|
|
995
|
-
"return",
|
|
996
|
-
"throw",
|
|
997
|
-
"typeof",
|
|
998
|
-
"void",
|
|
999
|
-
"yield"
|
|
1000
|
-
]);
|
|
1001
|
-
function isJsxClosingTagSlash(code, slashIndex) {
|
|
1002
|
-
if (code[slashIndex - 1] !== "<") return false;
|
|
1003
|
-
let cursor = slashIndex + 1;
|
|
1004
|
-
while (/\s/.test(code[cursor] || "")) cursor++;
|
|
1005
|
-
if (code[cursor] === ">") return true;
|
|
1006
|
-
const tagStart = cursor;
|
|
1007
|
-
while (/[-:.$_\u200C\u200D\p{ID_Continue}]/u.test(code[cursor] || "")) cursor++;
|
|
1008
|
-
if (cursor === tagStart) return false;
|
|
1009
|
-
while (/\s/.test(code[cursor] || "")) cursor++;
|
|
1010
|
-
return code[cursor] === ">";
|
|
1011
|
-
}
|
|
1012
|
-
/** Mark comments, string/template literals, and regular expressions as non-code. */
|
|
1013
|
-
function createCodePositionMap(code) {
|
|
1014
|
-
const positions = Array(code.length).fill(true);
|
|
1015
|
-
const mask = (start, end) => {
|
|
1016
|
-
for (let index = start; index < end; index++) positions[index] = false;
|
|
1017
|
-
};
|
|
1018
|
-
let canStartRegex = true;
|
|
1019
|
-
for (let index = 0; index < code.length;) {
|
|
1020
|
-
const char = code[index];
|
|
1021
|
-
const next = code[index + 1];
|
|
1022
|
-
if (/\s/.test(char)) {
|
|
1023
|
-
index++;
|
|
1024
|
-
continue;
|
|
1025
|
-
}
|
|
1026
|
-
if (char === "/" && next === "/") {
|
|
1027
|
-
const start = index;
|
|
1028
|
-
index += 2;
|
|
1029
|
-
while (index < code.length && code[index] !== "\n" && code[index] !== "\r") index++;
|
|
1030
|
-
mask(start, index);
|
|
1031
|
-
continue;
|
|
1032
|
-
}
|
|
1033
|
-
if (char === "/" && next === "*") {
|
|
1034
|
-
const start = index;
|
|
1035
|
-
index += 2;
|
|
1036
|
-
while (index < code.length && !(code[index] === "*" && code[index + 1] === "/")) index++;
|
|
1037
|
-
index = Math.min(code.length, index + 2);
|
|
1038
|
-
mask(start, index);
|
|
1039
|
-
continue;
|
|
1040
|
-
}
|
|
1041
|
-
if (char === "\"" || char === "'" || char === "`") {
|
|
1042
|
-
const quote = char;
|
|
1043
|
-
const start = index++;
|
|
1044
|
-
while (index < code.length) {
|
|
1045
|
-
if (code[index] === "\\") {
|
|
1046
|
-
index += 2;
|
|
1047
|
-
continue;
|
|
1048
|
-
}
|
|
1049
|
-
if (code[index] === quote) {
|
|
1050
|
-
index++;
|
|
1051
|
-
break;
|
|
1052
|
-
}
|
|
1053
|
-
index++;
|
|
1054
|
-
}
|
|
1055
|
-
mask(start, index);
|
|
1056
|
-
canStartRegex = false;
|
|
1057
|
-
continue;
|
|
1058
|
-
}
|
|
1059
|
-
const closesJsxTag = isJsxClosingTagSlash(code, index);
|
|
1060
|
-
if (char === "/" && canStartRegex && !closesJsxTag) {
|
|
1061
|
-
const start = index;
|
|
1062
|
-
let cursor = index + 1;
|
|
1063
|
-
let escaped = false;
|
|
1064
|
-
let inCharacterClass = false;
|
|
1065
|
-
let closed = false;
|
|
1066
|
-
for (; cursor < code.length; cursor++) {
|
|
1067
|
-
const regexChar = code[cursor];
|
|
1068
|
-
if (regexChar === "\n" || regexChar === "\r") break;
|
|
1069
|
-
if (escaped) {
|
|
1070
|
-
escaped = false;
|
|
1071
|
-
continue;
|
|
1072
|
-
}
|
|
1073
|
-
if (regexChar === "\\") {
|
|
1074
|
-
escaped = true;
|
|
1075
|
-
continue;
|
|
1076
|
-
}
|
|
1077
|
-
if (regexChar === "[") {
|
|
1078
|
-
inCharacterClass = true;
|
|
1079
|
-
continue;
|
|
1080
|
-
}
|
|
1081
|
-
if (regexChar === "]" && inCharacterClass) {
|
|
1082
|
-
inCharacterClass = false;
|
|
1083
|
-
continue;
|
|
1084
|
-
}
|
|
1085
|
-
if (regexChar === "/" && !inCharacterClass) {
|
|
1086
|
-
cursor++;
|
|
1087
|
-
while (/[$_\p{ID_Continue}]/u.test(code[cursor] || "")) cursor++;
|
|
1088
|
-
closed = true;
|
|
1089
|
-
break;
|
|
1090
|
-
}
|
|
1091
|
-
}
|
|
1092
|
-
if (closed) {
|
|
1093
|
-
mask(start, cursor);
|
|
1094
|
-
index = cursor;
|
|
1095
|
-
canStartRegex = false;
|
|
1096
|
-
continue;
|
|
1097
|
-
}
|
|
1098
|
-
}
|
|
1099
|
-
if (/[$_\p{ID_Start}]/u.test(char)) {
|
|
1100
|
-
const start = index++;
|
|
1101
|
-
while (/[$_\u200C\u200D\p{ID_Continue}]/u.test(code[index] || "")) index++;
|
|
1102
|
-
canStartRegex = REGEX_PREFIX_KEYWORDS.has(code.slice(start, index));
|
|
1103
|
-
continue;
|
|
1104
|
-
}
|
|
1105
|
-
if (/\d/.test(char)) {
|
|
1106
|
-
index++;
|
|
1107
|
-
while (/[\w.]/.test(code[index] || "")) index++;
|
|
1108
|
-
canStartRegex = false;
|
|
1109
|
-
continue;
|
|
1110
|
-
}
|
|
1111
|
-
if ((char === "+" || char === "-") && next === char) {
|
|
1112
|
-
index += 2;
|
|
1113
|
-
continue;
|
|
1114
|
-
}
|
|
1115
|
-
if (char === "!" && next !== "=") {
|
|
1116
|
-
index++;
|
|
1117
|
-
continue;
|
|
1118
|
-
}
|
|
1119
|
-
if (char === ")" || char === "]" || char === "}") canStartRegex = false;
|
|
1120
|
-
else if (char !== ".") canStartRegex = true;
|
|
1121
|
-
index++;
|
|
1122
|
-
}
|
|
1123
|
-
return positions;
|
|
1124
|
-
}
|
|
1906
|
+
function writeRuntimeInitStatus(command, enableSsrInit = false, hostInitImportId, options, ssrRemotes = _ssrRemotes) {
|
|
1907
|
+
const exportStatement = command === "build" ? `const { initPromise, initResolve, initReject, moduleCache } = globalThis[globalKey];
|
|
1908
|
+
export { initPromise, initResolve, initReject, moduleCache };` : `module.exports = globalThis[globalKey];`;
|
|
1909
|
+
const ownerImportId = options ? getRuntimeInitStatusImportId(options) : hostInitImportId;
|
|
1910
|
+
getRuntimeInitModule(options).writeSync(`
|
|
1911
|
+
${getRuntimeInitBootstrapCode(enableSsrInit, ownerImportId, ssrRemotes, hostInitImportId)}
|
|
1912
|
+
${exportStatement}
|
|
1913
|
+
`);
|
|
1914
|
+
}
|
|
1125
1915
|
//#endregion
|
|
1126
1916
|
//#region src/utils/treeShaking.ts
|
|
1127
1917
|
const legacyTreeShakingState = {
|
|
@@ -1385,6 +2175,79 @@ function collectTreeShakingImports(code, id, shared, findSharedKey, record, mark
|
|
|
1385
2175
|
});
|
|
1386
2176
|
}
|
|
1387
2177
|
//#endregion
|
|
2178
|
+
//#region src/utils/typeArgumentScanner.ts
|
|
2179
|
+
function getTypeArgumentStartContext(source, start) {
|
|
2180
|
+
let previous = start - 1;
|
|
2181
|
+
while (previous >= 0 && /\s/.test(source[previous])) previous--;
|
|
2182
|
+
const previousChar = source[previous] || "";
|
|
2183
|
+
const followsNamedExpression = /[$_\u200C\u200D\p{ID_Continue})\]>]/u.test(previousChar);
|
|
2184
|
+
const startsStandaloneGeneric = previousChar !== "" && "=([{,:".includes(previousChar);
|
|
2185
|
+
if (!followsNamedExpression && !startsStandaloneGeneric) return void 0;
|
|
2186
|
+
return { followsNamedExpression };
|
|
2187
|
+
}
|
|
2188
|
+
function updateTypeArgumentGroupDepth(char, state) {
|
|
2189
|
+
if (char === "(" || char === "[" || char === "{") {
|
|
2190
|
+
state.groupDepth++;
|
|
2191
|
+
return "handled";
|
|
2192
|
+
}
|
|
2193
|
+
if (char !== ")" && char !== "]" && char !== "}") return void 0;
|
|
2194
|
+
if (state.groupDepth === 0) return "invalid";
|
|
2195
|
+
state.groupDepth--;
|
|
2196
|
+
return "handled";
|
|
2197
|
+
}
|
|
2198
|
+
function updateTypeArgumentAngleDepth(source, index, state) {
|
|
2199
|
+
const char = source[index];
|
|
2200
|
+
if (char === "<") {
|
|
2201
|
+
if (source[index + 1] === "=" || source[index + 1] === "<") return "invalid";
|
|
2202
|
+
state.angleDepth++;
|
|
2203
|
+
return "handled";
|
|
2204
|
+
}
|
|
2205
|
+
if (char !== ">") return void 0;
|
|
2206
|
+
if (source[index - 1] === "=" || source[index + 1] === "=") return "handled";
|
|
2207
|
+
state.angleDepth--;
|
|
2208
|
+
return state.angleDepth === 0 ? "closed" : "handled";
|
|
2209
|
+
}
|
|
2210
|
+
function hasLikelyTypeArgumentFollower(source, end, codePositions, followsNamedExpression) {
|
|
2211
|
+
let next = end + 1;
|
|
2212
|
+
while (next < source.length && (!codePositions[next] || /\s/.test(source[next]))) next++;
|
|
2213
|
+
if (next >= source.length || /[([.!?=;,)\]}:|&]/.test(source[next])) return true;
|
|
2214
|
+
const followingToken = source.slice(next).match(/^[$_\p{ID_Start}][$_\u200C\u200D\p{ID_Continue}]*/u)?.[0];
|
|
2215
|
+
return followingToken === "as" || followingToken === "satisfies" || !followsNamedExpression && followingToken !== void 0;
|
|
2216
|
+
}
|
|
2217
|
+
function isInvalidTypeArgumentTerminator(source, index, followsNamedExpression) {
|
|
2218
|
+
const char = source[index];
|
|
2219
|
+
return char === ";" || char === "=" && source[index + 1] !== ">" && followsNamedExpression;
|
|
2220
|
+
}
|
|
2221
|
+
/**
|
|
2222
|
+
* Finds the end of a balanced, type-like angle-bracket range that contains a
|
|
2223
|
+
* comma. Ambiguous syntax returns `undefined` so callers can fail closed.
|
|
2224
|
+
*/
|
|
2225
|
+
function findLikelyTypeArgumentEnd(source, start, codePositions) {
|
|
2226
|
+
const context = getTypeArgumentStartContext(source, start);
|
|
2227
|
+
if (!context) return void 0;
|
|
2228
|
+
const state = {
|
|
2229
|
+
angleDepth: 1,
|
|
2230
|
+
groupDepth: 0,
|
|
2231
|
+
sawTypeComma: false
|
|
2232
|
+
};
|
|
2233
|
+
for (let index = start + 1; index < source.length; index++) {
|
|
2234
|
+
if (!codePositions[index]) continue;
|
|
2235
|
+
const char = source[index];
|
|
2236
|
+
const groupAction = updateTypeArgumentGroupDepth(char, state);
|
|
2237
|
+
if (groupAction === "invalid") return void 0;
|
|
2238
|
+
if (groupAction === "handled") continue;
|
|
2239
|
+
const angleAction = updateTypeArgumentAngleDepth(source, index, state);
|
|
2240
|
+
if (angleAction === "invalid") return void 0;
|
|
2241
|
+
if (angleAction === "closed") return state.sawTypeComma && hasLikelyTypeArgumentFollower(source, index, codePositions, context.followsNamedExpression) ? index : void 0;
|
|
2242
|
+
if (angleAction === "handled") continue;
|
|
2243
|
+
if (char === "," && state.groupDepth === 0) {
|
|
2244
|
+
state.sawTypeComma = true;
|
|
2245
|
+
continue;
|
|
2246
|
+
}
|
|
2247
|
+
if (state.angleDepth === 1 && state.groupDepth === 0 && isInvalidTypeArgumentTerminator(source, index, context.followsNamedExpression)) return;
|
|
2248
|
+
}
|
|
2249
|
+
}
|
|
2250
|
+
//#endregion
|
|
1388
2251
|
//#region src/virtualModules/virtualShared_preBuild.ts
|
|
1389
2252
|
/**
|
|
1390
2253
|
* Even the resolveId hook cannot interfere with vite pre-build,
|
|
@@ -1436,6 +2299,12 @@ function getPackageEsmEntryPath(pkg) {
|
|
|
1436
2299
|
resolveSubpathWithRequire: false
|
|
1437
2300
|
}) || resolvePackageEntryFromProjectRoot(pkg);
|
|
1438
2301
|
}
|
|
2302
|
+
const DEFAULT_SHARED_EXPORT_CONDITIONS = [
|
|
2303
|
+
"browser",
|
|
2304
|
+
"import",
|
|
2305
|
+
"module",
|
|
2306
|
+
"default"
|
|
2307
|
+
];
|
|
1439
2308
|
function hasCodeMatch(source, regex, codePositions) {
|
|
1440
2309
|
regex.lastIndex = 0;
|
|
1441
2310
|
let match;
|
|
@@ -1443,14 +2312,25 @@ function hasCodeMatch(source, regex, codePositions) {
|
|
|
1443
2312
|
return false;
|
|
1444
2313
|
}
|
|
1445
2314
|
function hasCommonJsExports(source) {
|
|
1446
|
-
|
|
2315
|
+
const codePositions = createCodePositionMap(source);
|
|
2316
|
+
if (hasCodeMatch(source, /\bmodule\s*(?:\.exports|\[\s*['"]exports['"]\s*\])/g, codePositions)) return true;
|
|
2317
|
+
const exportsRegex = /\bexports\s*(?:\.|\[|[,)]|=(?!=|>))/g;
|
|
2318
|
+
let match;
|
|
2319
|
+
while ((match = exportsRegex.exec(source)) !== null) {
|
|
2320
|
+
if (!codePositions[match.index]) continue;
|
|
2321
|
+
let previousCodeIndex = match.index - 1;
|
|
2322
|
+
while (previousCodeIndex >= 0 && (/\s/.test(source[previousCodeIndex]) || !codePositions[previousCodeIndex])) previousCodeIndex--;
|
|
2323
|
+
if (source[previousCodeIndex] === ".") continue;
|
|
2324
|
+
return true;
|
|
2325
|
+
}
|
|
2326
|
+
return false;
|
|
1447
2327
|
}
|
|
1448
|
-
function inspectSharedExportsFromFile(entryPath) {
|
|
2328
|
+
function inspectSharedExportsFromFile(entryPath, exportConditions = DEFAULT_SHARED_EXPORT_CONDITIONS) {
|
|
1449
2329
|
try {
|
|
1450
2330
|
if (!entryPath) return void 0;
|
|
1451
2331
|
const source = readFileSync(entryPath, "utf-8");
|
|
1452
2332
|
const scanState = { complete: true };
|
|
1453
|
-
const namedExports = getNamedExportsViaRegex(source, entryPath, void 0, scanState);
|
|
2333
|
+
const namedExports = getNamedExportsViaRegex(source, entryPath, void 0, scanState, exportConditions);
|
|
1454
2334
|
const commonJs = hasCommonJsExports(source);
|
|
1455
2335
|
return {
|
|
1456
2336
|
namedExports: scanState.complete && !commonJs ? namedExports : void 0,
|
|
@@ -1460,17 +2340,70 @@ function inspectSharedExportsFromFile(entryPath) {
|
|
|
1460
2340
|
return;
|
|
1461
2341
|
}
|
|
1462
2342
|
}
|
|
1463
|
-
function
|
|
2343
|
+
function getMutableExportsFromFile(entryPath, exportConditions = DEFAULT_SHARED_EXPORT_CONDITIONS, visited = /* @__PURE__ */ new Set()) {
|
|
2344
|
+
if (!entryPath || visited.has(entryPath)) return [];
|
|
2345
|
+
visited.add(entryPath);
|
|
2346
|
+
try {
|
|
2347
|
+
const source = readFileSync(entryPath, "utf-8");
|
|
2348
|
+
const codePositions = createCodePositionMap(source);
|
|
2349
|
+
const mutableBindings = /* @__PURE__ */ new Set();
|
|
2350
|
+
const mutableExports = /* @__PURE__ */ new Set();
|
|
2351
|
+
let match;
|
|
2352
|
+
const declarationRegex = new RegExp(`\\b(?:export\\s+)?(?:let|var)\\s+(${JS_IDENTIFIER_PATTERN})`, "gu");
|
|
2353
|
+
let declarationScanIndex = 0;
|
|
2354
|
+
let braceDepth = 0;
|
|
2355
|
+
while ((match = declarationRegex.exec(source)) !== null) {
|
|
2356
|
+
if (!codePositions[match.index]) continue;
|
|
2357
|
+
for (let index = declarationScanIndex; index < match.index; index++) {
|
|
2358
|
+
if (!codePositions[index]) continue;
|
|
2359
|
+
if (source[index] === "{") braceDepth++;
|
|
2360
|
+
else if (source[index] === "}") braceDepth--;
|
|
2361
|
+
}
|
|
2362
|
+
declarationScanIndex = match.index;
|
|
2363
|
+
if (braceDepth !== 0) continue;
|
|
2364
|
+
mutableBindings.add(match[1]);
|
|
2365
|
+
if (match[0].trimStart().startsWith("export")) mutableExports.add(match[1]);
|
|
2366
|
+
}
|
|
2367
|
+
const listRegex = /export\s*\{([^}]+)\}(?:\s*from\s*['"]([^'"]+)['"])?/g;
|
|
2368
|
+
while ((match = listRegex.exec(source)) !== null) {
|
|
2369
|
+
if (!codePositions[match.index]) continue;
|
|
2370
|
+
const reExportPath = match[2] ? resolveReExportModule(entryPath, match[2], exportConditions) : void 0;
|
|
2371
|
+
const reExportedMutable = new Set(reExportPath ? getMutableExportsFromFile(reExportPath, exportConditions, visited) : []);
|
|
2372
|
+
for (const rawSpecifier of match[1].split(",")) {
|
|
2373
|
+
const specifier = rawSpecifier.trim();
|
|
2374
|
+
if (!specifier || specifier.startsWith("type ")) continue;
|
|
2375
|
+
const parts = specifier.split(/\s+as\s+/);
|
|
2376
|
+
const local = parts[0].trim();
|
|
2377
|
+
const exported = (parts[1] || local).trim();
|
|
2378
|
+
if (isValidEsmExportName(exported) && (mutableBindings.has(local) || reExportedMutable.has(local))) mutableExports.add(exported);
|
|
2379
|
+
}
|
|
2380
|
+
}
|
|
2381
|
+
const starExportRegex = /export\s+\*\s+from\s+['"]([^'"]+)['"]/g;
|
|
2382
|
+
while ((match = starExportRegex.exec(source)) !== null) {
|
|
2383
|
+
if (!codePositions[match.index]) continue;
|
|
2384
|
+
const resolved = resolveReExportModule(entryPath, match[1], exportConditions);
|
|
2385
|
+
for (const name of getMutableExportsFromFile(resolved, exportConditions, visited)) mutableExports.add(name);
|
|
2386
|
+
}
|
|
2387
|
+
visited.delete(entryPath);
|
|
2388
|
+
return Array.from(mutableExports);
|
|
2389
|
+
} catch {
|
|
2390
|
+
visited.delete(entryPath);
|
|
2391
|
+
return [];
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2394
|
+
function getSharedMutableExports(pkg, shareItem, exportConditions = DEFAULT_SHARED_EXPORT_CONDITIONS) {
|
|
2395
|
+
const configuredImport = shareItem?.shareConfig.import;
|
|
2396
|
+
return getMutableExportsFromFile(typeof configuredImport === "string" ? resolveConfiguredImportPath(configuredImport, exportConditions) : getInstalledPackageEntry(pkg, {
|
|
2397
|
+
conditions: exportConditions,
|
|
2398
|
+
resolveSubpathWithRequire: false
|
|
2399
|
+
}), exportConditions);
|
|
2400
|
+
}
|
|
2401
|
+
function resolveConfiguredImportPath(importSource, exportConditions = DEFAULT_SHARED_EXPORT_CONDITIONS) {
|
|
1464
2402
|
if (path$1.isAbsolute(importSource)) return resolveFileLikeModule(importSource);
|
|
1465
2403
|
const projectRoot = getPackageDetectionCwd();
|
|
1466
2404
|
if (importSource.startsWith(".")) return resolveFileLikeModule(path$1.resolve(projectRoot, importSource));
|
|
1467
2405
|
const esmEntry = getInstalledPackageEntry(importSource, {
|
|
1468
|
-
conditions:
|
|
1469
|
-
"browser",
|
|
1470
|
-
"import",
|
|
1471
|
-
"module",
|
|
1472
|
-
"default"
|
|
1473
|
-
],
|
|
2406
|
+
conditions: exportConditions,
|
|
1474
2407
|
resolveSubpathWithRequire: false
|
|
1475
2408
|
});
|
|
1476
2409
|
if (esmEntry) return esmEntry;
|
|
@@ -1521,16 +2454,11 @@ function resolveRelativeModule(filePath, specifier) {
|
|
|
1521
2454
|
if (existsSync(candidate)) return candidate;
|
|
1522
2455
|
}
|
|
1523
2456
|
}
|
|
1524
|
-
function resolveReExportModule(filePath, specifier) {
|
|
2457
|
+
function resolveReExportModule(filePath, specifier, exportConditions) {
|
|
1525
2458
|
if (specifier.startsWith(".")) return resolveRelativeModule(filePath, specifier);
|
|
1526
2459
|
const esmEntry = getInstalledPackageEntry(specifier, {
|
|
1527
2460
|
cwd: path$1.dirname(filePath),
|
|
1528
|
-
conditions:
|
|
1529
|
-
"browser",
|
|
1530
|
-
"import",
|
|
1531
|
-
"module",
|
|
1532
|
-
"default"
|
|
1533
|
-
],
|
|
2461
|
+
conditions: exportConditions,
|
|
1534
2462
|
resolveSubpathWithRequire: false
|
|
1535
2463
|
});
|
|
1536
2464
|
if (esmEntry) return esmEntry;
|
|
@@ -1540,7 +2468,7 @@ function resolveReExportModule(filePath, specifier) {
|
|
|
1540
2468
|
return;
|
|
1541
2469
|
}
|
|
1542
2470
|
}
|
|
1543
|
-
function hasTopLevelDeclaratorComma(source, start) {
|
|
2471
|
+
function hasTopLevelDeclaratorComma(source, start, codePositions) {
|
|
1544
2472
|
let depth = 0;
|
|
1545
2473
|
let quote;
|
|
1546
2474
|
let escaped = false;
|
|
@@ -1623,6 +2551,14 @@ function hasTopLevelDeclaratorComma(source, start) {
|
|
|
1623
2551
|
continue;
|
|
1624
2552
|
}
|
|
1625
2553
|
if (char === "!" && source[index + 1] !== "=") continue;
|
|
2554
|
+
if (char === "<") {
|
|
2555
|
+
const typeArgumentEnd = findLikelyTypeArgumentEnd(source, index, codePositions);
|
|
2556
|
+
if (typeArgumentEnd !== void 0) {
|
|
2557
|
+
index = typeArgumentEnd;
|
|
2558
|
+
canStartRegex = false;
|
|
2559
|
+
continue;
|
|
2560
|
+
}
|
|
2561
|
+
}
|
|
1626
2562
|
if (char === "(" || char === "[" || char === "{") {
|
|
1627
2563
|
depth++;
|
|
1628
2564
|
canStartRegex = true;
|
|
@@ -1663,7 +2599,7 @@ function hasUnsupportedBindingPattern(source, start) {
|
|
|
1663
2599
|
}
|
|
1664
2600
|
return true;
|
|
1665
2601
|
}
|
|
1666
|
-
function getNamedExportsViaRegex(source, filePath, visited, scanState = { complete: true }) {
|
|
2602
|
+
function getNamedExportsViaRegex(source, filePath, visited, scanState = { complete: true }, exportConditions = DEFAULT_SHARED_EXPORT_CONDITIONS) {
|
|
1667
2603
|
const names = /* @__PURE__ */ new Set();
|
|
1668
2604
|
const codePositions = createCodePositionMap(source);
|
|
1669
2605
|
const recognizedExportStarts = /* @__PURE__ */ new Set();
|
|
@@ -1680,7 +2616,7 @@ function getNamedExportsViaRegex(source, filePath, visited, scanState = { comple
|
|
|
1680
2616
|
const exportedVariableDeclarationRegex = /export\s+(?:const|let|var)\s+/g;
|
|
1681
2617
|
while ((match = exportedVariableDeclarationRegex.exec(source)) !== null) {
|
|
1682
2618
|
if (!codePositions[match.index]) continue;
|
|
1683
|
-
if (hasTopLevelDeclaratorComma(source, exportedVariableDeclarationRegex.lastIndex)) scanState.complete = false;
|
|
2619
|
+
if (hasTopLevelDeclaratorComma(source, exportedVariableDeclarationRegex.lastIndex, codePositions)) scanState.complete = false;
|
|
1684
2620
|
if (hasUnsupportedBindingPattern(source, exportedVariableDeclarationRegex.lastIndex)) scanState.complete = false;
|
|
1685
2621
|
}
|
|
1686
2622
|
if (hasCodeMatch(source, /export\s+import\s+/g, codePositions) || hasCodeMatch(source, /export\s*=/g, codePositions)) scanState.complete = false;
|
|
@@ -1709,6 +2645,7 @@ function getNamedExportsViaRegex(source, filePath, visited, scanState = { comple
|
|
|
1709
2645
|
const specifiers = match[1].split(",");
|
|
1710
2646
|
for (const specifier of specifiers) {
|
|
1711
2647
|
const trimmed = specifier.trim();
|
|
2648
|
+
if (!trimmed) continue;
|
|
1712
2649
|
if (typeOnlySpecifierRegex.test(trimmed)) continue;
|
|
1713
2650
|
const asMatch = trimmed.match(exportSpecifierRegex);
|
|
1714
2651
|
if (!asMatch) {
|
|
@@ -1733,23 +2670,24 @@ function getNamedExportsViaRegex(source, filePath, visited, scanState = { comple
|
|
|
1733
2670
|
if (!codePositions[match.index]) continue;
|
|
1734
2671
|
recognizedExportStarts.add(match.index);
|
|
1735
2672
|
const specifier = match[1];
|
|
1736
|
-
const resolvedPath = resolveReExportModule(filePath, specifier);
|
|
2673
|
+
const resolvedPath = resolveReExportModule(filePath, specifier, exportConditions);
|
|
1737
2674
|
if (!resolvedPath) {
|
|
1738
2675
|
scanState.complete = false;
|
|
1739
2676
|
continue;
|
|
1740
2677
|
}
|
|
1741
2678
|
if (visited.has(resolvedPath)) continue;
|
|
1742
|
-
if (path$1.extname(resolvedPath) === ".cjs") {
|
|
1743
|
-
scanState.complete = false;
|
|
1744
|
-
continue;
|
|
1745
|
-
}
|
|
1746
2679
|
try {
|
|
1747
2680
|
const reExportSource = readFileSync(resolvedPath, "utf-8");
|
|
1748
|
-
if (hasCommonJsExports(reExportSource)) {
|
|
1749
|
-
|
|
2681
|
+
if (path$1.extname(resolvedPath) === ".cjs" || hasCommonJsExports(reExportSource)) {
|
|
2682
|
+
const requiredNames = getRequiredNamedExports(resolvedPath);
|
|
2683
|
+
if (!requiredNames?.length) {
|
|
2684
|
+
scanState.complete = false;
|
|
2685
|
+
continue;
|
|
2686
|
+
}
|
|
2687
|
+
for (const name of requiredNames) names.add(name);
|
|
1750
2688
|
continue;
|
|
1751
2689
|
}
|
|
1752
|
-
const reExportNames = getNamedExportsViaRegex(reExportSource, resolvedPath, visited, scanState);
|
|
2690
|
+
const reExportNames = getNamedExportsViaRegex(reExportSource, resolvedPath, visited, scanState, exportConditions);
|
|
1753
2691
|
for (const name of reExportNames) names.add(name);
|
|
1754
2692
|
} catch {
|
|
1755
2693
|
scanState.complete = false;
|
|
@@ -1781,34 +2719,29 @@ function getRequiredNamedExports(specifier) {
|
|
|
1781
2719
|
return;
|
|
1782
2720
|
}
|
|
1783
2721
|
}
|
|
1784
|
-
function getPackageNamedExports(pkg) {
|
|
2722
|
+
function getPackageNamedExports(pkg, exportConditions = DEFAULT_SHARED_EXPORT_CONDITIONS) {
|
|
1785
2723
|
const esmEntryPath = getInstalledPackageEntry(pkg, {
|
|
1786
|
-
conditions:
|
|
1787
|
-
"browser",
|
|
1788
|
-
"import",
|
|
1789
|
-
"module",
|
|
1790
|
-
"default"
|
|
1791
|
-
],
|
|
2724
|
+
conditions: exportConditions,
|
|
1792
2725
|
resolveSubpathWithRequire: false
|
|
1793
2726
|
});
|
|
1794
2727
|
if (esmEntryPath) {
|
|
1795
|
-
const inspection = inspectSharedExportsFromFile(esmEntryPath);
|
|
2728
|
+
const inspection = inspectSharedExportsFromFile(esmEntryPath, exportConditions);
|
|
1796
2729
|
if (!inspection || inspection.commonJs || path$1.extname(esmEntryPath) === ".cjs") return getRequiredNamedExports(esmEntryPath);
|
|
1797
2730
|
if (inspection.namedExports !== void 0) return inspection.namedExports;
|
|
1798
2731
|
return;
|
|
1799
2732
|
}
|
|
1800
2733
|
return getRequiredNamedExports(pkg);
|
|
1801
2734
|
}
|
|
1802
|
-
function getSharedNamedExports(pkg, shareItem) {
|
|
2735
|
+
function getSharedNamedExports(pkg, shareItem, exportConditions = DEFAULT_SHARED_EXPORT_CONDITIONS) {
|
|
1803
2736
|
const configuredImport = shareItem?.shareConfig.import;
|
|
1804
2737
|
if (typeof configuredImport === "string") {
|
|
1805
|
-
const configuredImportPath = resolveConfiguredImportPath(configuredImport);
|
|
1806
|
-
const inspection = inspectSharedExportsFromFile(configuredImportPath);
|
|
2738
|
+
const configuredImportPath = resolveConfiguredImportPath(configuredImport, exportConditions);
|
|
2739
|
+
const inspection = inspectSharedExportsFromFile(configuredImportPath, exportConditions);
|
|
1807
2740
|
if (configuredImportPath && (inspection?.commonJs || path$1.extname(configuredImportPath) === ".cjs")) return getRequiredNamedExports(configuredImportPath);
|
|
1808
2741
|
if (inspection?.namedExports !== void 0) return inspection.namedExports;
|
|
1809
2742
|
return;
|
|
1810
2743
|
}
|
|
1811
|
-
return getPackageNamedExports(pkg);
|
|
2744
|
+
return getPackageNamedExports(pkg, exportConditions);
|
|
1812
2745
|
}
|
|
1813
2746
|
function getLocalProviderImportPath(pkg) {
|
|
1814
2747
|
try {
|
|
@@ -1928,11 +2861,14 @@ function isSharedSingletonConsumedByPeer(pkg, options = getNormalizeModuleFedera
|
|
|
1928
2861
|
}
|
|
1929
2862
|
return false;
|
|
1930
2863
|
};
|
|
1931
|
-
return Array.from(sharedKeyByPackageName.values()).some((sharedPkg) => sharedPkg !== pkg && reachesPkg(sharedPkg, new Set([sharedPkg])));
|
|
2864
|
+
return Array.from(sharedKeyByPackageName.values()).some((sharedPkg) => sharedPkg !== pkg && reachesPkg(sharedPkg, /* @__PURE__ */ new Set([sharedPkg])));
|
|
1932
2865
|
}
|
|
1933
2866
|
function isRemoteOnlyContainer(options = getNormalizeModuleFederationOptions()) {
|
|
1934
2867
|
return Object.keys(options.exposes || {}).length > 0 && Object.keys(options.remotes || {}).length === 0;
|
|
1935
2868
|
}
|
|
2869
|
+
function isLocalOnlyContainer(options = getNormalizeModuleFederationOptions()) {
|
|
2870
|
+
return Object.keys(options.exposes || {}).length === 0 && Object.keys(options.remotes || {}).length === 0;
|
|
2871
|
+
}
|
|
1936
2872
|
function tryResolveImportFromPackageRoot(pkg, root) {
|
|
1937
2873
|
try {
|
|
1938
2874
|
return resolveWorkspaceEsmEntry(pkg, createRequire$1(pathToFileURL(path$1.join(root, "package.json"))).resolve(pkg), root);
|
|
@@ -1980,7 +2916,7 @@ function getSharedVirtualModuleState(options) {
|
|
|
1980
2916
|
treeShakingProviderCacheMap: {},
|
|
1981
2917
|
materializedTreeShakingProviders: /* @__PURE__ */ new Set(),
|
|
1982
2918
|
loadShareCacheMap: {},
|
|
1983
|
-
ownerKey: `${options.internalName}
|
|
2919
|
+
ownerKey: `${options.internalName}${MF_OWNER_INFIX}${nextSharedVirtualModuleOwnerId++}`
|
|
1984
2920
|
};
|
|
1985
2921
|
sharedVirtualModuleStates.set(options, state);
|
|
1986
2922
|
}
|
|
@@ -2081,7 +3017,8 @@ export default { get, init };
|
|
|
2081
3017
|
`, true);
|
|
2082
3018
|
materializedTreeShakingProviders.add(pkg);
|
|
2083
3019
|
}
|
|
2084
|
-
function writePreBuildLibPath(pkg, shareItem, options) {
|
|
3020
|
+
function writePreBuildLibPath(pkg, shareItem, options, exportConditions) {
|
|
3021
|
+
const resolvedOptions = options ?? getNormalizeModuleFederationOptions();
|
|
2085
3022
|
const { preBuildCacheMap, preBuildShareItemMap } = getSharedVirtualModuleState(options);
|
|
2086
3023
|
if (!preBuildCacheMap[pkg]) preBuildCacheMap[pkg] = createScopedSharedVirtualModule(pkg, PREBUILD_TAG, options);
|
|
2087
3024
|
preBuildShareItemMap[pkg] = shareItem;
|
|
@@ -2131,16 +3068,21 @@ function writePreBuildLibPath(pkg, shareItem, options) {
|
|
|
2131
3068
|
`, true);
|
|
2132
3069
|
return;
|
|
2133
3070
|
}
|
|
2134
|
-
const namedExports = getSharedNamedExports(pkg, shareItem) ?? [];
|
|
3071
|
+
const namedExports = getSharedNamedExports(pkg, shareItem, exportConditions) ?? [];
|
|
2135
3072
|
if (namedExports.length > 0) {
|
|
2136
|
-
const
|
|
2137
|
-
const
|
|
2138
|
-
const
|
|
3073
|
+
const mutableExports = new Set(isLocalOnlyContainer(resolvedOptions) ? getSharedMutableExports(pkg, shareItem, exportConditions) : []);
|
|
3074
|
+
const copiedExports = namedExports.filter((name) => !mutableExports.has(name));
|
|
3075
|
+
const liveExports = namedExports.filter((name) => mutableExports.has(name));
|
|
3076
|
+
const namedExportVars = copiedExports.map((_name, i) => `__mf_${i}`);
|
|
3077
|
+
const declarations = copiedExports.map((name, i) => `const ${namedExportVars[i]} = __mfPrebuildExports[${escapeGeneratedStringLiteral(name)}];`).join("\n ");
|
|
3078
|
+
const namedExportLine = copiedExports.length ? `export { ${copiedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
|
|
3079
|
+
const liveExportLine = liveExports.length ? `export { ${liveExports.join(", ")} } from ${escapeGeneratedStringLiteral(importSource)};` : "";
|
|
2139
3080
|
preBuildCacheMap[pkg].writeSync(`
|
|
2140
3081
|
import * as __mfPrebuildNamespace from ${escapeGeneratedStringLiteral(importSource)};
|
|
2141
3082
|
const __mfPrebuildExports = __mfPrebuildNamespace;
|
|
2142
3083
|
${declarations}
|
|
2143
3084
|
${namedExportLine}
|
|
3085
|
+
${liveExportLine}
|
|
2144
3086
|
export default Reflect.get(__mfPrebuildNamespace, "default") ?? __mfPrebuildNamespace;
|
|
2145
3087
|
`, true);
|
|
2146
3088
|
return;
|
|
@@ -2185,17 +3127,23 @@ function getLoadShareModulePath(pkg, isRolldown, options) {
|
|
|
2185
3127
|
if (!loadShareCacheMap[pkg]) getLoadShareImportId(pkg, isRolldown, options);
|
|
2186
3128
|
return loadShareCacheMap[pkg].getImportId();
|
|
2187
3129
|
}
|
|
2188
|
-
function
|
|
2189
|
-
if (!id.includes(
|
|
3130
|
+
function getCachedSharedVirtualPkg(id, tag) {
|
|
3131
|
+
if (!id.includes(tag)) return;
|
|
2190
3132
|
const normalized = normalizeVirtualModuleId(id);
|
|
2191
3133
|
if (!normalized.startsWith("virtual:mf:")) return;
|
|
2192
|
-
const start = normalized.indexOf(
|
|
3134
|
+
const start = normalized.indexOf(tag);
|
|
2193
3135
|
if (start === -1) return;
|
|
2194
|
-
const encodedPkgStart = start +
|
|
2195
|
-
const end = normalized.indexOf(
|
|
3136
|
+
const encodedPkgStart = start + tag.length;
|
|
3137
|
+
const end = normalized.indexOf(tag, encodedPkgStart);
|
|
2196
3138
|
if (end === -1) return;
|
|
2197
3139
|
return packageNameDecode(normalized.slice(encodedPkgStart, end));
|
|
2198
3140
|
}
|
|
3141
|
+
function getCachedPreBuildPkg(id) {
|
|
3142
|
+
return getCachedSharedVirtualPkg(id, PREBUILD_TAG);
|
|
3143
|
+
}
|
|
3144
|
+
function getCachedLoadSharePkg(id) {
|
|
3145
|
+
return getCachedSharedVirtualPkg(id, LOAD_SHARE_TAG);
|
|
3146
|
+
}
|
|
2199
3147
|
function materializeCachedLoadShareModule(options) {
|
|
2200
3148
|
const pkg = getCachedLoadSharePkg(options.id);
|
|
2201
3149
|
if (!pkg) return;
|
|
@@ -2207,14 +3155,28 @@ function materializeCachedLoadShareModule(options) {
|
|
|
2207
3155
|
options.addUsedShares(pkg);
|
|
2208
3156
|
options.writeLocalSharedImportMap();
|
|
2209
3157
|
}
|
|
3158
|
+
function findCurrentLoadShareForStaleOwnerId(id, shared, findSharedKey, options) {
|
|
3159
|
+
const pkg = getCachedLoadSharePkg(id);
|
|
3160
|
+
if (!pkg) return;
|
|
3161
|
+
const normalized = normalizeVirtualModuleId(id);
|
|
3162
|
+
if (!normalized.startsWith("virtual:mf:")) return;
|
|
3163
|
+
const encodedKey = normalized.slice(11);
|
|
3164
|
+
const ownerStart = encodedKey.indexOf(MF_OWNER_INFIX);
|
|
3165
|
+
if (ownerStart === -1) return;
|
|
3166
|
+
if (encodedKey.slice(0, ownerStart) !== packageNameEncode(options.internalName)) return;
|
|
3167
|
+
if (!findSharedKey(pkg, shared)) return;
|
|
3168
|
+
return getSharedVirtualModuleState(options).loadShareCacheMap[pkg];
|
|
3169
|
+
}
|
|
2210
3170
|
function getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer) {
|
|
2211
3171
|
return treeShakingConsumer ? `__mfReadTreeShakingSharedSelection(__mfModuleCache.share, ${cacheDescriptor}, ${JSON.stringify(treeShakingConsumer)})` : `__mfReadSharedCache(__mfModuleCache.share, ${cacheDescriptor})`;
|
|
2212
3172
|
}
|
|
2213
|
-
function generateEagerWorkspaceSingletonExports(namedExports, importSource, cacheDescriptor, cacheOwner, treeShakingConsumer) {
|
|
2214
|
-
const
|
|
3173
|
+
function generateEagerWorkspaceSingletonExports(namedExports, importSource, cacheDescriptor, cacheOwner, treeShakingConsumer, mutableExports = []) {
|
|
3174
|
+
const copiedExports = namedExports.filter((name) => !mutableExports.includes(name));
|
|
3175
|
+
const namedExportVars = copiedExports.map((_name, i) => `__mf_${i}`);
|
|
2215
3176
|
const declarations = namedExports.length > 0 ? ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ") : "let __mf_default;";
|
|
2216
|
-
const assignments = [...
|
|
2217
|
-
const namedExportLine =
|
|
3177
|
+
const assignments = [...copiedExports.map((name, i) => `${namedExportVars[i]} = mod[${escapeGeneratedStringLiteral(name)}];`), "__mf_default = mod.default ?? mod;"].join("\n ");
|
|
3178
|
+
const namedExportLine = copiedExports.length > 0 ? `\n export { ${copiedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
|
|
3179
|
+
const mutableExportLine = mutableExports.length ? `\n export { ${mutableExports.join(", ")} } from ${escapeGeneratedStringLiteral(importSource)};` : "";
|
|
2218
3180
|
return `import * as __mfLocalShare from ${escapeGeneratedStringLiteral(importSource)};
|
|
2219
3181
|
let exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)};
|
|
2220
3182
|
if (exportModule === undefined) {
|
|
@@ -2231,13 +3193,15 @@ function generateEagerWorkspaceSingletonExports(namedExports, importSource, cach
|
|
|
2231
3193
|
};
|
|
2232
3194
|
__mfSubscribeSharedCache(__mfModuleCache.share, ${cacheDescriptor}, __mfApplyEagerShareExports);
|
|
2233
3195
|
__mfApplyEagerShareExports(exportModule);
|
|
2234
|
-
export { __mf_default as default };${namedExportLine}`;
|
|
3196
|
+
export { __mf_default as default };${namedExportLine}${mutableExportLine}`;
|
|
2235
3197
|
}
|
|
2236
|
-
function generateLazyWorkspaceSingletonExports(namedExports, importSource, cacheDescriptor, cacheOwner, treeShakingConsumer, serveLocalFallback = false) {
|
|
2237
|
-
const
|
|
3198
|
+
function generateLazyWorkspaceSingletonExports(namedExports, importSource, cacheDescriptor, cacheOwner, treeShakingConsumer, serveLocalFallback = false, mutableExports = []) {
|
|
3199
|
+
const copiedExports = namedExports.filter((name) => !mutableExports.includes(name));
|
|
3200
|
+
const namedExportVars = copiedExports.map((_name, i) => `__mf_${i}`);
|
|
2238
3201
|
const declarations = namedExports.length > 0 ? ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ") : "let __mf_default;";
|
|
2239
|
-
const assignments =
|
|
2240
|
-
const namedExportLine =
|
|
3202
|
+
const assignments = copiedExports.length > 0 ? [...copiedExports.map((name, i) => `${namedExportVars[i]} = mod[${escapeGeneratedStringLiteral(name)}];`), "__mf_default = mod.default ?? mod;"].join("\n ") : "__mf_default = mod.default ?? mod;";
|
|
3203
|
+
const namedExportLine = copiedExports.length > 0 ? `\n export { ${copiedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
|
|
3204
|
+
const mutableExportLine = mutableExports.length ? `\n export { ${mutableExports.join(", ")} } from ${escapeGeneratedStringLiteral(importSource)};` : "";
|
|
2241
3205
|
const applyLocalFallback = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
2242
3206
|
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});
|
|
2243
3207
|
__mfApplyLazyShareExports(exportModule);`;
|
|
@@ -2266,7 +3230,7 @@ function generateLazyWorkspaceSingletonExports(namedExports, importSource, cache
|
|
|
2266
3230
|
} else {
|
|
2267
3231
|
__mfApplyLazyShareExports(exportModule);
|
|
2268
3232
|
}
|
|
2269
|
-
export { __mf_default as default };${namedExportLine}`;
|
|
3233
|
+
export { __mf_default as default };${namedExportLine}${mutableExportLine}`;
|
|
2270
3234
|
}
|
|
2271
3235
|
const WORKSPACE_SINGLETON_SSR_LOCAL_SHARE = "__mfNormalizeShareModule(__mfLocalShare)";
|
|
2272
3236
|
function prependWorkspaceSingletonSsrImport(code) {
|
|
@@ -2330,7 +3294,7 @@ const normalizeLocalShareModuleCode = `const __mfNormalizeShareModule = (mod) =>
|
|
|
2330
3294
|
? Object.assign({}, normalized)
|
|
2331
3295
|
: normalized;
|
|
2332
3296
|
};`;
|
|
2333
|
-
function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options) {
|
|
3297
|
+
function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options, exportConditions) {
|
|
2334
3298
|
const resolvedOptions = options ?? getNormalizeModuleFederationOptions();
|
|
2335
3299
|
const { loadShareCacheMap } = getSharedVirtualModuleState(options);
|
|
2336
3300
|
if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = createScopedSharedVirtualModule(pkg, LOAD_SHARE_TAG, options);
|
|
@@ -2340,7 +3304,7 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options) {
|
|
|
2340
3304
|
const runtimeInitOwnerImportId = options ? getRuntimeInitStatusImportId(options) : void 0;
|
|
2341
3305
|
const treeShakingConsumer = command === "build" && shareItem.shareConfig.treeShaking ? resolvedOptions.name : void 0;
|
|
2342
3306
|
if (shareItem.shareConfig.import === false) {
|
|
2343
|
-
const detectedNamedExports = getPackageNamedExports(pkg);
|
|
3307
|
+
const detectedNamedExports = getPackageNamedExports(pkg, exportConditions);
|
|
2344
3308
|
const namedExports = detectedNamedExports ?? [];
|
|
2345
3309
|
let exportLine;
|
|
2346
3310
|
if (namedExports.length > 0) exportLine = generateDeferredHostProvidedExports(namedExports, pkg, cacheDescriptor, treeShakingConsumer);
|
|
@@ -2364,8 +3328,12 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options) {
|
|
|
2364
3328
|
const isWorkspacePackage = isWorkspacePackageEntry(pkg, localProviderPath) || isWorkspacePackageEntry(pkg, concreteSharedImportSource);
|
|
2365
3329
|
const lazyLocalFallbackSource = command !== "build" ? concreteSharedImportSource || localProviderPath || devImportSource : concreteSharedImportSource || localProviderPath || sharedImportSource;
|
|
2366
3330
|
const skipServePrebuildWarmup = command !== "build" && (pkg === "lit" || pkg.startsWith("lit/"));
|
|
2367
|
-
const detectedNamedExports = getSharedNamedExports(pkg, shareItem);
|
|
3331
|
+
const detectedNamedExports = getSharedNamedExports(pkg, shareItem, exportConditions);
|
|
2368
3332
|
const namedExports = detectedNamedExports ?? [];
|
|
3333
|
+
const mutableExports = new Set(isLocalOnlyContainer(resolvedOptions) ? getSharedMutableExports(pkg, shareItem, exportConditions) : []);
|
|
3334
|
+
const copiedNamedExports = namedExports.filter((name) => !mutableExports.has(name));
|
|
3335
|
+
const liveNamedExports = namedExports.filter((name) => mutableExports.has(name));
|
|
3336
|
+
const liveNamedExportLine = liveNamedExports.length ? `export { ${liveNamedExports.join(", ")} } from ${escapeGeneratedStringLiteral(sharedImportSource)};` : "";
|
|
2369
3337
|
const hasCompleteExportCoverage = detectedNamedExports !== void 0;
|
|
2370
3338
|
const isWorkspaceSingleton = isWorkspacePackage && shareItem.shareConfig.singleton === true;
|
|
2371
3339
|
const isDefaultShareScope = shareItem.scope === void 0 || shareItem.scope === "default" || Array.isArray(shareItem.scope) && shareItem.scope[0] === "default";
|
|
@@ -2379,11 +3347,11 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options) {
|
|
|
2379
3347
|
let initBlock = "";
|
|
2380
3348
|
if (usesDeferredTreeShakingFallback) {
|
|
2381
3349
|
importLine = `${getRuntimeInitPromiseBootstrapCode(false, runtimeInitOwnerImportId)}\n ${importLine}`;
|
|
2382
|
-
exportLine = generateLazyWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, command !== "build" && (isWorkspaceSingleton || isWorkspacePackage || servesRemoteSingletonFallback));
|
|
2383
|
-
} else if (usesEagerWorkspaceFallback || usesEntryInjectedRemoteFallback) exportLine = generateEagerWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer);
|
|
3350
|
+
exportLine = generateLazyWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, command !== "build" && (isWorkspaceSingleton || isWorkspacePackage || servesRemoteSingletonFallback), liveNamedExports);
|
|
3351
|
+
} else if (usesEagerWorkspaceFallback || usesEntryInjectedRemoteFallback) exportLine = generateEagerWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, liveNamedExports);
|
|
2384
3352
|
else if (usesDeferredSingletonFallback) {
|
|
2385
3353
|
importLine = `${getRuntimeInitPromiseBootstrapCode(false, runtimeInitOwnerImportId)}\n ${importLine}`;
|
|
2386
|
-
exportLine = generateLazyWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, command !== "build" && (isWorkspaceSingleton || isWorkspacePackage || servesRemoteSingletonFallback));
|
|
3354
|
+
exportLine = generateLazyWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, command !== "build" && (isWorkspaceSingleton || isWorkspacePackage || servesRemoteSingletonFallback), liveNamedExports);
|
|
2387
3355
|
} else if (detectedNamedExports === void 0) {
|
|
2388
3356
|
exportLine = `const __mfDefaultExport = (() => {
|
|
2389
3357
|
${generateShareModuleUnwrapCode({
|
|
@@ -2397,10 +3365,10 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options) {
|
|
|
2397
3365
|
initBlock = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
2398
3366
|
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});`;
|
|
2399
3367
|
} else if (namedExports.length > 0 && shareItem.shareConfig.singleton === true) {
|
|
2400
|
-
const namedExportVars =
|
|
3368
|
+
const namedExportVars = copiedNamedExports.map((_name, i) => `__mf_${i}`);
|
|
2401
3369
|
exportLine = `${["let __mfDefaultExport;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ")}
|
|
2402
3370
|
const __mfApplySharedExports = (mod) => {
|
|
2403
|
-
${[...
|
|
3371
|
+
${[...copiedNamedExports.map((name, i) => `${namedExportVars[i]} = mod[${escapeGeneratedStringLiteral(name)}];`), `__mfDefaultExport = (() => {
|
|
2404
3372
|
${generateShareModuleUnwrapCode({
|
|
2405
3373
|
source: "mod",
|
|
2406
3374
|
preserveNamedExports: false,
|
|
@@ -2411,12 +3379,13 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options) {
|
|
|
2411
3379
|
__mfSubscribeSharedCache(__mfModuleCache.share, ${cacheDescriptor}, __mfApplySharedExports);
|
|
2412
3380
|
__mfApplySharedExports(exportModule);
|
|
2413
3381
|
export { __mfDefaultExport as default };
|
|
2414
|
-
${`export { ${
|
|
3382
|
+
${copiedNamedExports.length ? `export { ${copiedNamedExports.map((name, i) => `__mf_${i} as ${name}`).join(", ")} };` : ""}
|
|
3383
|
+
${liveNamedExportLine}`;
|
|
2415
3384
|
initBlock = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
2416
3385
|
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});`;
|
|
2417
3386
|
} else if (namedExports.length > 0) {
|
|
2418
|
-
const destructure = `const { ${
|
|
2419
|
-
const namedExportLine = `export { ${
|
|
3387
|
+
const destructure = copiedNamedExports.length ? `const { ${copiedNamedExports.map((name, i) => `${name}: __mf_${i}`).join(", ")} } = exportModule;` : "";
|
|
3388
|
+
const namedExportLine = copiedNamedExports.length ? `export { ${copiedNamedExports.map((name, i) => `__mf_${i} as ${name}`).join(", ")} };` : "";
|
|
2420
3389
|
exportLine = `const __mfDefaultExport = (() => {
|
|
2421
3390
|
${generateShareModuleUnwrapCode({
|
|
2422
3391
|
source: "exportModule",
|
|
@@ -2426,7 +3395,8 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options) {
|
|
|
2426
3395
|
})();
|
|
2427
3396
|
export default __mfDefaultExport;
|
|
2428
3397
|
${destructure}
|
|
2429
|
-
${namedExportLine}
|
|
3398
|
+
${namedExportLine}
|
|
3399
|
+
${liveNamedExportLine}`;
|
|
2430
3400
|
initBlock = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
2431
3401
|
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});`;
|
|
2432
3402
|
} else if (shareItem.shareConfig.singleton === true) {
|
|
@@ -2497,11 +3467,12 @@ function getLocalOwnerKey(options) {
|
|
|
2497
3467
|
ownerId = nextLocalOwnerId++;
|
|
2498
3468
|
localOwnerIds.set(options, ownerId);
|
|
2499
3469
|
}
|
|
2500
|
-
return `${options.internalName}
|
|
3470
|
+
return `${options.internalName}${MF_OWNER_INFIX}${ownerId}`;
|
|
2501
3471
|
}
|
|
2502
3472
|
function getLocalSharedImportMapPath(options) {
|
|
2503
3473
|
const resolvedOptions = options ?? getNormalizeModuleFederationOptions();
|
|
2504
|
-
|
|
3474
|
+
const ownerName = options ? getLocalOwnerKey(resolvedOptions) : resolvedOptions.internalName || resolvedOptions.name;
|
|
3475
|
+
return `${LOCAL_SHARED_IMPORT_MAP_ID}:${packageNameEncode(ownerName)}`;
|
|
2505
3476
|
}
|
|
2506
3477
|
function getResolvedLocalSharedImportMapId(options) {
|
|
2507
3478
|
return `\0${getLocalSharedImportMapPath(options)}`;
|
|
@@ -3019,9 +3990,10 @@ function generateHostAutoInitSharedCacheSeedCode(command = "build", options) {
|
|
|
3019
3990
|
}
|
|
3020
3991
|
const REMOTE_ENTRY_ID = "virtual:mf-REMOTE_ENTRY_ID";
|
|
3021
3992
|
function getRemoteEntryId(options) {
|
|
3022
|
-
|
|
3993
|
+
const scopedKey = `${options.internalName}__${options.filename}`.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
3994
|
+
return `${REMOTE_ENTRY_ID}:${scopedKey}`;
|
|
3023
3995
|
}
|
|
3024
|
-
const SSR_ONLY_PLUGIN_SPECIFIERS = new Set(["@module-federation/vite/ssrEntryLoader"]);
|
|
3996
|
+
const SSR_ONLY_PLUGIN_SPECIFIERS = /* @__PURE__ */ new Set(["@module-federation/vite/ssrEntryLoader"]);
|
|
3025
3997
|
const isSsrOnlyPlugin = (importStatement) => [...SSR_ONLY_PLUGIN_SPECIFIERS].some((s) => importStatement.includes(s));
|
|
3026
3998
|
const getSsrOnlyPluginSpecifier = (importStatement) => [...SSR_ONLY_PLUGIN_SPECIFIERS].find((s) => importStatement.includes(s));
|
|
3027
3999
|
function generateTreeShakingSharedResolutionCode(enabled) {
|
|
@@ -3987,8 +4959,9 @@ function getHostAutoInitState(options) {
|
|
|
3987
4959
|
if (!options) return legacyHostAutoInitState;
|
|
3988
4960
|
let state = hostAutoInitStates.get(options);
|
|
3989
4961
|
if (!state) {
|
|
4962
|
+
const ownerKey = getLocalOwnerKey(options);
|
|
3990
4963
|
state = {
|
|
3991
|
-
module: new VirtualModule("hostAutoInit", HOST_AUTO_INIT_TAG, "",
|
|
4964
|
+
module: new VirtualModule("hostAutoInit", HOST_AUTO_INIT_TAG, "", ownerKey),
|
|
3992
4965
|
remoteEntryId: REMOTE_ENTRY_ID,
|
|
3993
4966
|
command: "build"
|
|
3994
4967
|
};
|
|
@@ -4093,7 +5066,7 @@ function getRemoteVirtualModule(remote, command, enableSsrInit = false, consumer
|
|
|
4093
5066
|
}
|
|
4094
5067
|
const cacheKey = `${remote}__${command}__${options.shareStrategy}__${consumer}__${enableSsrInit ? "ssr-init" : "no-ssr-init"}`;
|
|
4095
5068
|
if (!instanceCache.has(cacheKey)) {
|
|
4096
|
-
const virtual = new VirtualModule(`${consumer === "unified" ? remote : `${remote}__mf_consumer__${consumer}`}
|
|
5069
|
+
const virtual = new VirtualModule(`${consumer === "unified" ? remote : `${remote}__mf_consumer__${consumer}`}${MF_OWNER_INFIX}${getRemoteOptionsId(options)}`, LOAD_REMOTE_TAG, ".js", options.internalName);
|
|
4097
5070
|
virtual.writeSync(generateRemotes(remote, command, enableSsrInit, consumer, options));
|
|
4098
5071
|
instanceCache.set(cacheKey, virtual);
|
|
4099
5072
|
}
|
|
@@ -4418,6 +5391,9 @@ function getFirstHtmlEntryFile(entryFiles) {
|
|
|
4418
5391
|
function stripQueryAndHash$1(file) {
|
|
4419
5392
|
return file.split(/[?#]/)[0];
|
|
4420
5393
|
}
|
|
5394
|
+
function isReactRouterClientRouteInput(file) {
|
|
5395
|
+
return /[?&]__react-router-build-client-route(?:[=&]|$)/.test(file);
|
|
5396
|
+
}
|
|
4421
5397
|
function resolveDevHashEntryFileName$1(fileName) {
|
|
4422
5398
|
if (!fileName.includes("[hash")) return fileName;
|
|
4423
5399
|
const normalized = fileName.replace(/(?:[._-]?\[hash(?::\d+)?\])/g, "");
|
|
@@ -4536,7 +5512,11 @@ const __mfCurrentScript = document.currentScript;
|
|
|
4536
5512
|
: import(src);
|
|
4537
5513
|
` : "";
|
|
4538
5514
|
const importExpression = (src) => useSystemImportFallback ? `__mfImport(${JSON.stringify(src)})` : `import(${JSON.stringify(src)})`;
|
|
4539
|
-
const
|
|
5515
|
+
const isEncodedVirtualEntry = entrySrc.startsWith(VITE_ENCODED_NULL_BYTE_PREFIX);
|
|
5516
|
+
const entryImportDeclaration = isEncodedVirtualEntry ? `const __mfEntryUrl = ${JSON.stringify(entrySrc)};
|
|
5517
|
+
` : "";
|
|
5518
|
+
const entryImportExpression = isEncodedVirtualEntry ? "import(/* @vite-ignore */ __mfEntryUrl)" : importExpression(entrySrc);
|
|
5519
|
+
const remotePreloads = !options?.skipRemotePreload && (federationOptions ?? getNormalizeModuleFederationOptions())?.shareStrategy !== "loaded-first" ? Object.entries(getUsedRemotesMap(federationOptions)).flatMap(([, remotes]) => Array.from(remotes)).sort().map((remote) => `__mfPreloadRemote(${JSON.stringify(getRuntimeRemoteId(remote, (federationOptions ?? getNormalizeModuleFederationOptions()).remotes, federationOptions))}, ${JSON.stringify(remote)})`).join(",") : "";
|
|
4540
5520
|
const remoteCachePrefix = getRuntimeRemoteCachePrefix(federationOptions);
|
|
4541
5521
|
const preloadBlock = remotePreloads ? `
|
|
4542
5522
|
const runtime = await initHost();
|
|
@@ -4568,11 +5548,12 @@ const __mfCurrentScript = document.currentScript;
|
|
|
4568
5548
|
if (__mfModuleCache.pendingShareLoads) {
|
|
4569
5549
|
await Promise.all(__mfModuleCache.pendingShareLoads);
|
|
4570
5550
|
}
|
|
4571
|
-
})().then(() => ${
|
|
5551
|
+
})().then(() => ${entryImportExpression});
|
|
4572
5552
|
`;
|
|
4573
5553
|
return [
|
|
4574
5554
|
getRuntimeModuleCacheBootstrapCode(),
|
|
4575
5555
|
importHelper,
|
|
5556
|
+
entryImportDeclaration,
|
|
4576
5557
|
importCode
|
|
4577
5558
|
].join("\n");
|
|
4578
5559
|
}
|
|
@@ -4616,6 +5597,16 @@ const __mfCurrentScript = document.currentScript;
|
|
|
4616
5597
|
addEntryFile(scriptSrc.startsWith("/") ? path$1.resolve(viteConfig.root, scriptSrc.slice(1)) : path$1.resolve(path$1.dirname(htmlPath), scriptSrc));
|
|
4617
5598
|
}
|
|
4618
5599
|
}
|
|
5600
|
+
function addEntryRemoteImports(entrySrc) {
|
|
5601
|
+
if (!federationOptions || /^(?:[a-z]+:)?\/\//i.test(entrySrc)) return;
|
|
5602
|
+
const file = path$1.resolve(viteConfig.root, stripQueryAndHash$1(entrySrc).replace(/^\//, ""));
|
|
5603
|
+
if (!fs$2.existsSync(file)) return;
|
|
5604
|
+
const code = fs$2.readFileSync(file, "utf-8");
|
|
5605
|
+
for (const source of findModuleImportSources(code)) {
|
|
5606
|
+
const remote = Object.keys(federationOptions.remotes).find((name) => source === name || source.startsWith(`${name}/`));
|
|
5607
|
+
if (remote) addUsedRemote(remote, source, federationOptions);
|
|
5608
|
+
}
|
|
5609
|
+
}
|
|
4619
5610
|
return [{
|
|
4620
5611
|
name: "add-entry",
|
|
4621
5612
|
apply: "serve",
|
|
@@ -4643,9 +5634,10 @@ const __mfCurrentScript = document.currentScript;
|
|
|
4643
5634
|
const initSrc = params.get("init");
|
|
4644
5635
|
const entrySrc = params.get("entry");
|
|
4645
5636
|
if (initSrc && entrySrc) {
|
|
5637
|
+
const withBase = (src) => viteConfig.base + src.replace(/^\//, "");
|
|
4646
5638
|
res.statusCode = 200;
|
|
4647
5639
|
res.setHeader("Content-Type", "application/javascript");
|
|
4648
|
-
res.end(getBootstrapSource(initSrc, entrySrc));
|
|
5640
|
+
res.end(getBootstrapSource(withBase(initSrc), withBase(entrySrc)));
|
|
4649
5641
|
return;
|
|
4650
5642
|
}
|
|
4651
5643
|
}
|
|
@@ -4668,10 +5660,14 @@ const __mfCurrentScript = document.currentScript;
|
|
|
4668
5660
|
const base = viteConfig.base.replace(/\/$/, "");
|
|
4669
5661
|
const stripBase = (p) => base && p.startsWith(base + "/") ? p.slice(base.length) : p;
|
|
4670
5662
|
const html = rewriteEntryScripts(c, (originalSrc) => {
|
|
4671
|
-
|
|
5663
|
+
const entrySrc = stripBase(originalSrc);
|
|
5664
|
+
addEntryRemoteImports(entrySrc);
|
|
5665
|
+
const resolvedEntrySrc = entrySrc.startsWith("virtual:") ? toViteEncodedId(entrySrc) : entrySrc;
|
|
5666
|
+
const query = new URLSearchParams({
|
|
4672
5667
|
init: sanitizeDevEntryPath(stripBase(devEntryPath)),
|
|
4673
|
-
entry: sanitizeDevEntryPath(
|
|
4674
|
-
}).toString()
|
|
5668
|
+
entry: sanitizeDevEntryPath(resolvedEntrySrc)
|
|
5669
|
+
}).toString();
|
|
5670
|
+
return toViteEncodedId(`${DEV_HTML_PROXY_PREFIX}${query}`);
|
|
4675
5671
|
});
|
|
4676
5672
|
return html === c ? injectEntryScript(c, stripBase(devEntryPath)) : html;
|
|
4677
5673
|
}
|
|
@@ -4710,8 +5706,8 @@ const __mfCurrentScript = document.currentScript;
|
|
|
4710
5706
|
const inputOptions = getBuildInput(config);
|
|
4711
5707
|
if (!inputOptions) htmlFilePath = path$1.resolve(config.root, "index.html");
|
|
4712
5708
|
else if (typeof inputOptions === "string") entryFiles = [resolveProjectId(inputOptions)];
|
|
4713
|
-
else if (Array.isArray(inputOptions)) entryFiles = inputOptions.map(resolveProjectId);
|
|
4714
|
-
else if (typeof inputOptions === "object") entryFiles = Object.values(inputOptions).map((input) => resolveProjectId(String(input)));
|
|
5709
|
+
else if (Array.isArray(inputOptions)) entryFiles = inputOptions.filter((input) => !isReactRouterClientRouteInput(String(input))).map(resolveProjectId);
|
|
5710
|
+
else if (typeof inputOptions === "object") entryFiles = Object.values(inputOptions).filter((input) => !isReactRouterClientRouteInput(String(input))).map((input) => resolveProjectId(String(input)));
|
|
4715
5711
|
if (entryFiles.length > 0) htmlFilePath = getFirstHtmlEntryFile(entryFiles);
|
|
4716
5712
|
if (htmlFilePath) addHtmlScriptEntries(htmlFilePath);
|
|
4717
5713
|
},
|
|
@@ -4898,6 +5894,7 @@ function checkAliasConflicts(options) {
|
|
|
4898
5894
|
//#region src/plugins/hmr/react.ts
|
|
4899
5895
|
const REACT_REFRESH_PATH = "/@react-refresh";
|
|
4900
5896
|
const LOCAL_REACT_REFRESH_PATH = "/@mf-react-refresh-local";
|
|
5897
|
+
const HOST_REACT_REFRESH_URL = "__MF_REACT_REFRESH_URL__";
|
|
4901
5898
|
function stripQuery(url) {
|
|
4902
5899
|
return url?.replace(/\?.*$/, "");
|
|
4903
5900
|
}
|
|
@@ -4923,7 +5920,7 @@ function resolveReactRefreshRuntime(root) {
|
|
|
4923
5920
|
*/
|
|
4924
5921
|
const REACT_REFRESH_PROXY_MODULE = [
|
|
4925
5922
|
`const __remoteUrl = new URL(import.meta.url);`,
|
|
4926
|
-
`const __target = window.location.origin === __remoteUrl.origin ? new URL('.${LOCAL_REACT_REFRESH_PATH}', __remoteUrl).href : window.location.origin + '${REACT_REFRESH_PATH}';`,
|
|
5923
|
+
`const __target = window.location.origin === __remoteUrl.origin ? new URL('.${LOCAL_REACT_REFRESH_PATH}', __remoteUrl).href : globalThis.${HOST_REACT_REFRESH_URL} || window.location.origin + '${REACT_REFRESH_PATH}';`,
|
|
4927
5924
|
`const __rt = await import(__target);`,
|
|
4928
5925
|
`export const injectIntoGlobalHook = __rt.injectIntoGlobalHook;`,
|
|
4929
5926
|
`export const register = __rt.register;`,
|
|
@@ -4936,6 +5933,14 @@ const REACT_REFRESH_PROXY_MODULE = [
|
|
|
4936
5933
|
const reactAdapter = {
|
|
4937
5934
|
name: "react",
|
|
4938
5935
|
pluginNames: ["vite:react-refresh", "vite:react-swc"],
|
|
5936
|
+
host: { transformIndexHtml({ server }) {
|
|
5937
|
+
const refreshPath = `${server.config.base.replace(/\/$/, "")}${REACT_REFRESH_PATH}`;
|
|
5938
|
+
return [{
|
|
5939
|
+
tag: "script",
|
|
5940
|
+
children: `globalThis.${HOST_REACT_REFRESH_URL} = new URL(${JSON.stringify(refreshPath)}, window.location.origin).href;`,
|
|
5941
|
+
injectTo: "head-prepend"
|
|
5942
|
+
}];
|
|
5943
|
+
} },
|
|
4939
5944
|
remote: { configureServer({ server }) {
|
|
4940
5945
|
let reactRefreshRuntime;
|
|
4941
5946
|
server.middlewares.use((req, res, next) => {
|
|
@@ -5048,7 +6053,7 @@ const REMOTE_HMR_ENDPOINT = "__mf_hmr";
|
|
|
5048
6053
|
const REMOTE_HMR_EVENT = "mf:remote-update";
|
|
5049
6054
|
const REMOTE_HMR_CONNECT_RETRY_DELAY_MS = 1e3;
|
|
5050
6055
|
const REMOTE_HMR_CONNECT_MAX_RETRIES = 10;
|
|
5051
|
-
function getBasePath(base) {
|
|
6056
|
+
function getBasePath$1(base) {
|
|
5052
6057
|
if (!base) return "/";
|
|
5053
6058
|
if (base.startsWith("http://") || base.startsWith("https://")) try {
|
|
5054
6059
|
return new URL(base).pathname || "/";
|
|
@@ -5058,11 +6063,11 @@ function getBasePath(base) {
|
|
|
5058
6063
|
return base;
|
|
5059
6064
|
}
|
|
5060
6065
|
function getRemoteHmrPath(base) {
|
|
5061
|
-
return `${getBasePath(base).replace(/\/?$/, "/")}${REMOTE_HMR_ENDPOINT}`.replace(/\/{2,}/g, "/");
|
|
6066
|
+
return `${getBasePath$1(base).replace(/\/?$/, "/")}${REMOTE_HMR_ENDPOINT}`.replace(/\/{2,}/g, "/");
|
|
5062
6067
|
}
|
|
5063
6068
|
function getHmrWsPath(base, hmrPath) {
|
|
5064
|
-
const normalizedBase = getBasePath(base);
|
|
5065
|
-
const normalizedPath = getBasePath(hmrPath || "");
|
|
6069
|
+
const normalizedBase = getBasePath$1(base);
|
|
6070
|
+
const normalizedPath = getBasePath$1(hmrPath || "");
|
|
5066
6071
|
if (!normalizedPath || normalizedPath === "/") return normalizedBase;
|
|
5067
6072
|
return `${normalizedBase.endsWith("/") ? normalizedBase.slice(0, -1) : normalizedBase}/${normalizedPath.startsWith("/") ? normalizedPath.slice(1) : normalizedPath}`;
|
|
5068
6073
|
}
|
|
@@ -5368,6 +6373,203 @@ function pluginDevRemoteHmr(options) {
|
|
|
5368
6373
|
};
|
|
5369
6374
|
}
|
|
5370
6375
|
//#endregion
|
|
6376
|
+
//#region src/plugins/pluginExternalRuntimeCore.ts
|
|
6377
|
+
const EXTERNAL_RUNTIME_CORE_VIRTUAL_ID = "\0virtual:mf-external-runtime-core";
|
|
6378
|
+
/** Package remotes import — rewritten to the host global shim. */
|
|
6379
|
+
const RUNTIME_CORE_PACKAGE = "@module-federation/runtime-core";
|
|
6380
|
+
/**
|
|
6381
|
+
* Already depended on via `@module-federation/runtime`. Prefer this for Node
|
|
6382
|
+
* introspection so we do not need a direct `runtime-core` dependency.
|
|
6383
|
+
*/
|
|
6384
|
+
const RUNTIME_CORE_INTROSPECT_PACKAGE = "@module-federation/runtime/core";
|
|
6385
|
+
function isRuntimeCoreId(id) {
|
|
6386
|
+
return id === "@module-federation/runtime-core" || id === `@module-federation/runtime-core/`;
|
|
6387
|
+
}
|
|
6388
|
+
/** True when the importer is part of an SSR remote graph (skip browser shim). */
|
|
6389
|
+
function isSsrRemoteRuntimeImporter(importer) {
|
|
6390
|
+
if (!importer) return false;
|
|
6391
|
+
return importer.includes("virtual:mf-REMOTE_ENTRY_SSR_ID") || importer.includes("virtual:mf-exposes-ssr:") || importer.includes("/__mf_ssr__/");
|
|
6392
|
+
}
|
|
6393
|
+
function collectRuntimeCoreExportShapes(runtimeCoreModule) {
|
|
6394
|
+
return Object.keys(runtimeCoreModule).filter((key) => key !== "default" && key !== "__esModule").sort().map((name) => ({
|
|
6395
|
+
name,
|
|
6396
|
+
callable: typeof runtimeCoreModule[name] === "function"
|
|
6397
|
+
}));
|
|
6398
|
+
}
|
|
6399
|
+
/**
|
|
6400
|
+
* Builds a shim that defers reading `globalThis._FEDERATION_RUNTIME_CORE` until
|
|
6401
|
+
* an export is accessed. Vite dev does not guarantee host `beforeInit` runs
|
|
6402
|
+
* before remote graph modules evaluate, so an eager throw at import time can
|
|
6403
|
+
* fail even when `provideExternalRuntime` is correctly configured.
|
|
6404
|
+
*/
|
|
6405
|
+
function buildExternalRuntimeCoreShimCode(exportShapes) {
|
|
6406
|
+
return `${[
|
|
6407
|
+
"function __mfGetExternalRuntimeCore() {",
|
|
6408
|
+
" const mod = globalThis._FEDERATION_RUNTIME_CORE;",
|
|
6409
|
+
" if (!mod) {",
|
|
6410
|
+
" throw new Error(\"[Module Federation] experiments.externalRuntime is enabled, but globalThis._FEDERATION_RUNTIME_CORE is missing. Enable experiments.provideExternalRuntime on the host consumer.\");",
|
|
6411
|
+
" }",
|
|
6412
|
+
" return mod;",
|
|
6413
|
+
"}",
|
|
6414
|
+
"function __mfCreateLazyRuntimeCoreFunction(exportName) {",
|
|
6415
|
+
" const target = function (...args) {",
|
|
6416
|
+
" return Reflect.apply(__mfGetExternalRuntimeCore()[exportName], this, args);",
|
|
6417
|
+
" };",
|
|
6418
|
+
" return new Proxy(target, {",
|
|
6419
|
+
" get(_target, prop) {",
|
|
6420
|
+
" if (prop === \"__mf_is_external_runtime_core_export\") return true;",
|
|
6421
|
+
" // Avoid thenable detection / introspection throwing before host init.",
|
|
6422
|
+
" if (prop === \"then\") return undefined;",
|
|
6423
|
+
" const value = __mfGetExternalRuntimeCore()[exportName];",
|
|
6424
|
+
" if (prop === \"prototype\") return value?.prototype;",
|
|
6425
|
+
" if (prop === Symbol.hasInstance) {",
|
|
6426
|
+
" return (instance) => instance instanceof value;",
|
|
6427
|
+
" }",
|
|
6428
|
+
" if (value == null) return value;",
|
|
6429
|
+
" const inner = Reflect.get(value, prop, value);",
|
|
6430
|
+
" return typeof inner === \"function\" ? inner.bind(value) : inner;",
|
|
6431
|
+
" },",
|
|
6432
|
+
" set(_target, prop, nextValue) {",
|
|
6433
|
+
" __mfGetExternalRuntimeCore()[exportName][prop] = nextValue;",
|
|
6434
|
+
" return true;",
|
|
6435
|
+
" },",
|
|
6436
|
+
" has(_target, prop) {",
|
|
6437
|
+
" if (prop === \"then\" || prop === \"__mf_is_external_runtime_core_export\") {",
|
|
6438
|
+
" return prop === \"__mf_is_external_runtime_core_export\";",
|
|
6439
|
+
" }",
|
|
6440
|
+
" const mod = globalThis._FEDERATION_RUNTIME_CORE;",
|
|
6441
|
+
" if (!mod) return false;",
|
|
6442
|
+
" return prop in Object(mod[exportName]);",
|
|
6443
|
+
" },",
|
|
6444
|
+
" ownKeys() {",
|
|
6445
|
+
" const mod = globalThis._FEDERATION_RUNTIME_CORE;",
|
|
6446
|
+
" if (!mod) return [];",
|
|
6447
|
+
" return Reflect.ownKeys(Object(mod[exportName]));",
|
|
6448
|
+
" },",
|
|
6449
|
+
" getOwnPropertyDescriptor(_target, prop) {",
|
|
6450
|
+
" if (prop === \"then\") return undefined;",
|
|
6451
|
+
" const mod = globalThis._FEDERATION_RUNTIME_CORE;",
|
|
6452
|
+
" if (!mod) return undefined;",
|
|
6453
|
+
" return Object.getOwnPropertyDescriptor(Object(mod[exportName]), prop);",
|
|
6454
|
+
" },",
|
|
6455
|
+
" apply(_target, thisArg, args) {",
|
|
6456
|
+
" return Reflect.apply(__mfGetExternalRuntimeCore()[exportName], thisArg, args);",
|
|
6457
|
+
" },",
|
|
6458
|
+
" construct(_target, args) {",
|
|
6459
|
+
" const Ctor = __mfGetExternalRuntimeCore()[exportName];",
|
|
6460
|
+
" return new Ctor(...args);",
|
|
6461
|
+
" },",
|
|
6462
|
+
" });",
|
|
6463
|
+
"}",
|
|
6464
|
+
"function __mfCreateLazyRuntimeCoreObject(exportName) {",
|
|
6465
|
+
" return new Proxy(Object.create(null), {",
|
|
6466
|
+
" get(_target, prop) {",
|
|
6467
|
+
" if (prop === \"__mf_is_external_runtime_core_export\") return true;",
|
|
6468
|
+
" if (prop === \"then\") return undefined;",
|
|
6469
|
+
" const value = __mfGetExternalRuntimeCore()[exportName];",
|
|
6470
|
+
" const inner = Reflect.get(value, prop, value);",
|
|
6471
|
+
" return typeof inner === \"function\" ? inner.bind(value) : inner;",
|
|
6472
|
+
" },",
|
|
6473
|
+
" set(_target, prop, nextValue) {",
|
|
6474
|
+
" __mfGetExternalRuntimeCore()[exportName][prop] = nextValue;",
|
|
6475
|
+
" return true;",
|
|
6476
|
+
" },",
|
|
6477
|
+
" has(_target, prop) {",
|
|
6478
|
+
" if (prop === \"then\" || prop === \"__mf_is_external_runtime_core_export\") {",
|
|
6479
|
+
" return prop === \"__mf_is_external_runtime_core_export\";",
|
|
6480
|
+
" }",
|
|
6481
|
+
" const mod = globalThis._FEDERATION_RUNTIME_CORE;",
|
|
6482
|
+
" return !!mod && prop in Object(mod[exportName]);",
|
|
6483
|
+
" },",
|
|
6484
|
+
" ownKeys() {",
|
|
6485
|
+
" const mod = globalThis._FEDERATION_RUNTIME_CORE;",
|
|
6486
|
+
" return mod ? Reflect.ownKeys(Object(mod[exportName])) : [];",
|
|
6487
|
+
" },",
|
|
6488
|
+
" getOwnPropertyDescriptor(_target, prop) {",
|
|
6489
|
+
" if (prop === \"then\") return undefined;",
|
|
6490
|
+
" const mod = globalThis._FEDERATION_RUNTIME_CORE;",
|
|
6491
|
+
" if (!mod) return undefined;",
|
|
6492
|
+
" const descriptor = Object.getOwnPropertyDescriptor(Object(mod[exportName]), prop);",
|
|
6493
|
+
" return descriptor && { ...descriptor, configurable: true };",
|
|
6494
|
+
" },",
|
|
6495
|
+
" });",
|
|
6496
|
+
"}",
|
|
6497
|
+
"export default /*#__PURE__*/ new Proxy(Object.create(null), {",
|
|
6498
|
+
" get(_target, prop) {",
|
|
6499
|
+
" if (prop === \"__esModule\") return true;",
|
|
6500
|
+
" if (prop === \"then\") return undefined;",
|
|
6501
|
+
" const mod = __mfGetExternalRuntimeCore();",
|
|
6502
|
+
" const resolved = mod.default ?? mod;",
|
|
6503
|
+
" const value = resolved[prop];",
|
|
6504
|
+
" return typeof value === \"function\" ? value.bind(resolved) : value;",
|
|
6505
|
+
" },",
|
|
6506
|
+
" has(_target, prop) {",
|
|
6507
|
+
" if (prop === \"then\") return false;",
|
|
6508
|
+
" if (prop === \"__esModule\") return true;",
|
|
6509
|
+
" const mod = globalThis._FEDERATION_RUNTIME_CORE;",
|
|
6510
|
+
" if (!mod) return false;",
|
|
6511
|
+
" const resolved = mod.default ?? mod;",
|
|
6512
|
+
" return prop in Object(resolved);",
|
|
6513
|
+
" },",
|
|
6514
|
+
"});",
|
|
6515
|
+
exportShapes.map(({ name, callable }) => `export const ${name} = /*#__PURE__*/ ${callable ? "__mfCreateLazyRuntimeCoreFunction" : "__mfCreateLazyRuntimeCoreObject"}(${JSON.stringify(name)});`).join("\n")
|
|
6516
|
+
].filter(Boolean).join("\n")}\n`;
|
|
6517
|
+
}
|
|
6518
|
+
let cachedExportShapes;
|
|
6519
|
+
async function importRuntimeCoreForIntrospection(packageName) {
|
|
6520
|
+
try {
|
|
6521
|
+
return await import(pathToFileURL$1(resolveImportPath(packageName)).href);
|
|
6522
|
+
} catch {
|
|
6523
|
+
return await import(packageName);
|
|
6524
|
+
}
|
|
6525
|
+
}
|
|
6526
|
+
async function resolveRuntimeCoreExportShapes() {
|
|
6527
|
+
if (cachedExportShapes) return cachedExportShapes;
|
|
6528
|
+
try {
|
|
6529
|
+
cachedExportShapes = collectRuntimeCoreExportShapes(await importRuntimeCoreForIntrospection(RUNTIME_CORE_INTROSPECT_PACKAGE));
|
|
6530
|
+
} catch {
|
|
6531
|
+
try {
|
|
6532
|
+
cachedExportShapes = collectRuntimeCoreExportShapes(await importRuntimeCoreForIntrospection(RUNTIME_CORE_PACKAGE));
|
|
6533
|
+
} catch {
|
|
6534
|
+
cachedExportShapes = [];
|
|
6535
|
+
}
|
|
6536
|
+
}
|
|
6537
|
+
return cachedExportShapes;
|
|
6538
|
+
}
|
|
6539
|
+
/**
|
|
6540
|
+
* Replaces `@module-federation/runtime-core` with a virtual module that reads
|
|
6541
|
+
* `globalThis._FEDERATION_RUNTIME_CORE` (webpack/Rspack `externalRuntime` parity).
|
|
6542
|
+
*/
|
|
6543
|
+
function pluginExternalRuntimeCore() {
|
|
6544
|
+
let shimCodePromise;
|
|
6545
|
+
const getShimCode = () => {
|
|
6546
|
+
if (!shimCodePromise) shimCodePromise = resolveRuntimeCoreExportShapes().then((shapes) => {
|
|
6547
|
+
if (shapes.length === 0) throw createModuleFederationError(`Unable to introspect exports from ${RUNTIME_CORE_INTROSPECT_PACKAGE} for experiments.externalRuntime.`);
|
|
6548
|
+
return buildExternalRuntimeCoreShimCode(shapes);
|
|
6549
|
+
});
|
|
6550
|
+
return shimCodePromise;
|
|
6551
|
+
};
|
|
6552
|
+
return {
|
|
6553
|
+
name: "module-federation-external-runtime-core",
|
|
6554
|
+
enforce: "pre",
|
|
6555
|
+
config(config) {
|
|
6556
|
+
config.optimizeDeps ??= {};
|
|
6557
|
+
config.optimizeDeps.exclude ??= [];
|
|
6558
|
+
if (!config.optimizeDeps.exclude.includes("@module-federation/runtime-core")) config.optimizeDeps.exclude.push(RUNTIME_CORE_PACKAGE);
|
|
6559
|
+
if (Array.isArray(config.optimizeDeps.include)) config.optimizeDeps.include = config.optimizeDeps.include.filter((dep) => dep !== "@module-federation/runtime-core" && !String(dep).startsWith(`@module-federation/runtime-core/`));
|
|
6560
|
+
},
|
|
6561
|
+
resolveId(source, importer) {
|
|
6562
|
+
if (!isRuntimeCoreId(source)) return;
|
|
6563
|
+
if (isSsrRemoteRuntimeImporter(importer)) return;
|
|
6564
|
+
return EXTERNAL_RUNTIME_CORE_VIRTUAL_ID;
|
|
6565
|
+
},
|
|
6566
|
+
async load(id) {
|
|
6567
|
+
if (id !== "\0virtual:mf-external-runtime-core") return;
|
|
6568
|
+
return getShimCode();
|
|
6569
|
+
}
|
|
6570
|
+
};
|
|
6571
|
+
}
|
|
6572
|
+
//#endregion
|
|
5371
6573
|
//#region src/virtualModules/index.ts
|
|
5372
6574
|
function initVirtualModules(command, remoteEntryId, enableSsrInit = false, options) {
|
|
5373
6575
|
writeLocalSharedImportMap(options);
|
|
@@ -5761,7 +6963,7 @@ function getVirtualExposesSSRId(options) {
|
|
|
5761
6963
|
* build so Node resolves them via its own module cache — this is what
|
|
5762
6964
|
* guarantees the React singleton is shared with react-dom/server.
|
|
5763
6965
|
*/
|
|
5764
|
-
function generateExposesSSR(options) {
|
|
6966
|
+
function generateExposesSSR(options, reactIslandExposes = /* @__PURE__ */ new Set()) {
|
|
5765
6967
|
return `
|
|
5766
6968
|
export default {
|
|
5767
6969
|
${Object.keys(options.exposes).map((key) => {
|
|
@@ -5770,6 +6972,7 @@ function generateExposesSSR(options) {
|
|
|
5770
6972
|
const importModule = await import(${JSON.stringify(options.exposes[key].import)})
|
|
5771
6973
|
const exportModule = {}
|
|
5772
6974
|
Object.assign(exportModule, importModule)
|
|
6975
|
+
${generateReactIslandSSRDefinition(reactIslandExposes.has(key))}
|
|
5773
6976
|
Object.defineProperty(exportModule, "__esModule", {
|
|
5774
6977
|
value: true,
|
|
5775
6978
|
enumerable: false
|
|
@@ -5785,7 +6988,8 @@ function generateExposesSSR(options) {
|
|
|
5785
6988
|
//#region src/virtualModules/virtualRemoteEntrySSR.ts
|
|
5786
6989
|
const REMOTE_ENTRY_SSR_ID = "virtual:mf-REMOTE_ENTRY_SSR_ID";
|
|
5787
6990
|
function getRemoteEntrySSRId(options) {
|
|
5788
|
-
|
|
6991
|
+
const scopedKey = `${options.internalName}__${options.filename}`.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
6992
|
+
return `${REMOTE_ENTRY_SSR_ID}:${scopedKey}`;
|
|
5789
6993
|
}
|
|
5790
6994
|
function getSsrRemoteEntryFileName(browserFilename) {
|
|
5791
6995
|
const ext = browserFilename.match(/\.[^.]+$/)?.[0] || ".js";
|
|
@@ -5863,6 +7067,318 @@ function generateRemoteEntrySSR(options) {
|
|
|
5863
7067
|
`;
|
|
5864
7068
|
}
|
|
5865
7069
|
//#endregion
|
|
7070
|
+
//#region src/plugins/pluginDts.ts
|
|
7071
|
+
var pluginDts_exports = /* @__PURE__ */ __exportAll({
|
|
7072
|
+
DEFAULT_PUBLIC_TYPES_FOLDER: () => DEFAULT_PUBLIC_TYPES_FOLDER,
|
|
7073
|
+
createDevDtsAssetMiddleware: () => createDevDtsAssetMiddleware,
|
|
7074
|
+
default: () => pluginDts,
|
|
7075
|
+
getDevDtsAssetPaths: () => getDevDtsAssetPaths,
|
|
7076
|
+
resolveDtsPluginOptions: () => resolveDtsPluginOptions
|
|
7077
|
+
});
|
|
7078
|
+
const DEFAULT_DEV_OPTIONS = {
|
|
7079
|
+
disableLiveReload: true,
|
|
7080
|
+
disableHotTypesReload: false,
|
|
7081
|
+
disableDynamicRemoteTypeHints: false
|
|
7082
|
+
};
|
|
7083
|
+
const DYNAMIC_HINTS_PLUGIN = "@module-federation/dts-plugin/dynamic-remote-type-hints-plugin";
|
|
7084
|
+
const getIPv4 = () => process.env["FEDERATION_IPV4"] || "127.0.0.1";
|
|
7085
|
+
const DEV_TYPES_FOLDER = ".dev-server";
|
|
7086
|
+
const DEFAULT_PUBLIC_TYPES_FOLDER = "@mf-types";
|
|
7087
|
+
const forkDevWorkerPath = (() => {
|
|
7088
|
+
return resolveImportPath("@module-federation/dts-plugin/dist/fork-dev-worker.js");
|
|
7089
|
+
})();
|
|
7090
|
+
var DevWorker = class {
|
|
7091
|
+
worker = rpc.createRpcWorker(forkDevWorkerPath, {}, void 0, false);
|
|
7092
|
+
constructor(options) {
|
|
7093
|
+
this.worker.connect(options);
|
|
7094
|
+
}
|
|
7095
|
+
update() {
|
|
7096
|
+
this.worker.process?.send?.({
|
|
7097
|
+
type: rpc.RpcGMCallTypes.CALL,
|
|
7098
|
+
id: this.worker.id,
|
|
7099
|
+
args: [void 0, "update"]
|
|
7100
|
+
});
|
|
7101
|
+
}
|
|
7102
|
+
exit() {
|
|
7103
|
+
this.worker.terminate();
|
|
7104
|
+
}
|
|
7105
|
+
};
|
|
7106
|
+
const normalizeDevOptions = (dev) => {
|
|
7107
|
+
if (dev === false) return false;
|
|
7108
|
+
if (dev === true || typeof dev === "undefined") return { ...DEFAULT_DEV_OPTIONS };
|
|
7109
|
+
return {
|
|
7110
|
+
...DEFAULT_DEV_OPTIONS,
|
|
7111
|
+
...dev
|
|
7112
|
+
};
|
|
7113
|
+
};
|
|
7114
|
+
const buildDtsModuleFederationConfig = (options) => {
|
|
7115
|
+
const exposes = {};
|
|
7116
|
+
Object.entries(options.exposes).forEach(([key, value]) => {
|
|
7117
|
+
if (value.import) exposes[key] = value.import;
|
|
7118
|
+
});
|
|
7119
|
+
const remotes = {};
|
|
7120
|
+
Object.entries(options.remotes).forEach(([key, remote]) => {
|
|
7121
|
+
if (!remote.entry) return;
|
|
7122
|
+
const entryGlobalName = remote.entryGlobalName?.startsWith("http") || remote.entryGlobalName?.includes(".json") ? remote.name || key : remote.entryGlobalName || remote.name || key;
|
|
7123
|
+
remotes[key] = `${entryGlobalName}@${remote.entry}`;
|
|
7124
|
+
});
|
|
7125
|
+
return {
|
|
7126
|
+
...options,
|
|
7127
|
+
exposes,
|
|
7128
|
+
remotes
|
|
7129
|
+
};
|
|
7130
|
+
};
|
|
7131
|
+
const resolveOutputDir = (config) => {
|
|
7132
|
+
const { outDir } = config.build;
|
|
7133
|
+
if (path$1.isAbsolute(outDir)) return normalizePathForImport(path$1.relative(config.root, outDir));
|
|
7134
|
+
return outDir;
|
|
7135
|
+
};
|
|
7136
|
+
const ensureRuntimePlugin = (options, pluginId) => {
|
|
7137
|
+
if (!options.runtimePlugins.some((plugin) => {
|
|
7138
|
+
if (typeof plugin === "string") return plugin === pluginId;
|
|
7139
|
+
return plugin[0] === pluginId;
|
|
7140
|
+
})) options.runtimePlugins.push(pluginId);
|
|
7141
|
+
};
|
|
7142
|
+
const getExposeImportPaths = (options) => {
|
|
7143
|
+
return Object.values(options.exposes).map((value) => {
|
|
7144
|
+
return value.import;
|
|
7145
|
+
}).filter((value) => Boolean(value));
|
|
7146
|
+
};
|
|
7147
|
+
const usesVueSfcExposes = (options) => {
|
|
7148
|
+
return getExposeImportPaths(options).some((value) => value.endsWith(".vue"));
|
|
7149
|
+
};
|
|
7150
|
+
const resolveDtsPluginOptions = (dts, options, context) => {
|
|
7151
|
+
if (dts === false) return false;
|
|
7152
|
+
const inferredGenerateTypesDefaults = { generateAPITypes: true };
|
|
7153
|
+
if (usesVueSfcExposes(options) && hasPackageDependency("vue-tsc", context)) inferredGenerateTypesDefaults.compilerInstance = "vue-tsc";
|
|
7154
|
+
if (dts === true || typeof dts === "undefined") return { generateTypes: inferredGenerateTypesDefaults };
|
|
7155
|
+
const generateTypes = dts.generateTypes;
|
|
7156
|
+
return {
|
|
7157
|
+
...dts,
|
|
7158
|
+
generateTypes: generateTypes === false ? false : {
|
|
7159
|
+
...inferredGenerateTypesDefaults,
|
|
7160
|
+
...generateTypes === true || typeof generateTypes === "undefined" ? {} : generateTypes
|
|
7161
|
+
}
|
|
7162
|
+
};
|
|
7163
|
+
};
|
|
7164
|
+
const getBasePath = (base) => {
|
|
7165
|
+
if (base.startsWith("http://") || base.startsWith("https://")) return new URL(base).pathname.replace(/\/$/, "") || "/";
|
|
7166
|
+
return base.replace(/\/$/, "") || "/";
|
|
7167
|
+
};
|
|
7168
|
+
const joinBaseAndAsset = (base, assetFileName) => {
|
|
7169
|
+
const basePath = getBasePath(base);
|
|
7170
|
+
return `${basePath === "/" ? "" : basePath}/${assetFileName}`.replace(/\/{2,}/g, "/");
|
|
7171
|
+
};
|
|
7172
|
+
const getDevDtsAssetPaths = (options) => {
|
|
7173
|
+
const { outputDir, publicTypesFolder, root, base } = options;
|
|
7174
|
+
return {
|
|
7175
|
+
apiFilePath: path$1.resolve(root, outputDir, `${DEV_TYPES_FOLDER}.d.ts`),
|
|
7176
|
+
apiRequestPath: joinBaseAndAsset(base, `${publicTypesFolder}.d.ts`),
|
|
7177
|
+
zipFilePath: path$1.resolve(root, outputDir, `${DEV_TYPES_FOLDER}.zip`),
|
|
7178
|
+
zipRequestPath: joinBaseAndAsset(base, `${publicTypesFolder}.zip`)
|
|
7179
|
+
};
|
|
7180
|
+
};
|
|
7181
|
+
const createDevDtsAssetMiddleware = (assetPaths) => {
|
|
7182
|
+
return (req, res, next) => {
|
|
7183
|
+
const requestPath = req.url?.split("?")[0];
|
|
7184
|
+
const isZipRequest = requestPath === assetPaths.zipRequestPath;
|
|
7185
|
+
const isApiRequest = requestPath === assetPaths.apiRequestPath;
|
|
7186
|
+
if (!isZipRequest && !isApiRequest) {
|
|
7187
|
+
next();
|
|
7188
|
+
return;
|
|
7189
|
+
}
|
|
7190
|
+
const filePath = isZipRequest ? assetPaths.zipFilePath : assetPaths.apiFilePath;
|
|
7191
|
+
if (!fs.existsSync(filePath)) {
|
|
7192
|
+
res.statusCode = 404;
|
|
7193
|
+
res.end();
|
|
7194
|
+
return;
|
|
7195
|
+
}
|
|
7196
|
+
res.statusCode = 200;
|
|
7197
|
+
res.setHeader("Content-Type", isZipRequest ? "application/x-gzip" : "application/typescript");
|
|
7198
|
+
if (req.method === "HEAD") {
|
|
7199
|
+
res.end();
|
|
7200
|
+
return;
|
|
7201
|
+
}
|
|
7202
|
+
const stream = fs.createReadStream(filePath);
|
|
7203
|
+
stream.on("error", () => {
|
|
7204
|
+
if (!res.headersSent) res.statusCode = 500;
|
|
7205
|
+
res.end();
|
|
7206
|
+
});
|
|
7207
|
+
res.on("close", () => {
|
|
7208
|
+
stream.destroy();
|
|
7209
|
+
});
|
|
7210
|
+
stream.pipe(res);
|
|
7211
|
+
};
|
|
7212
|
+
};
|
|
7213
|
+
const normalizeDevDtsOptions = (dts, context) => {
|
|
7214
|
+
return normalizeOptions(isTSProject(dts, context), {
|
|
7215
|
+
generateTypes: { compileInChildProcess: true },
|
|
7216
|
+
consumeTypes: { consumeAPITypes: true },
|
|
7217
|
+
extraOptions: {},
|
|
7218
|
+
displayErrorInTerminal: typeof dts === "object" && dts ? dts.displayErrorInTerminal : void 0
|
|
7219
|
+
}, "mfOptions.dts")(dts);
|
|
7220
|
+
};
|
|
7221
|
+
const logDtsError = (error, dtsOptions) => {
|
|
7222
|
+
if (dtsOptions === false) return;
|
|
7223
|
+
if (typeof dtsOptions === "object" && dtsOptions && dtsOptions.displayErrorInTerminal === false) return;
|
|
7224
|
+
mfError(error);
|
|
7225
|
+
};
|
|
7226
|
+
function pluginDts(options) {
|
|
7227
|
+
if (options.dts === false) return [];
|
|
7228
|
+
const baseDtsModuleFederationConfig = buildDtsModuleFederationConfig(options);
|
|
7229
|
+
const getDtsModuleFederationConfig = (context) => ({
|
|
7230
|
+
...baseDtsModuleFederationConfig,
|
|
7231
|
+
dts: resolveDtsPluginOptions(options.dts, options, context)
|
|
7232
|
+
});
|
|
7233
|
+
let resolvedConfig;
|
|
7234
|
+
let devWorker;
|
|
7235
|
+
let normalizedDevOptions;
|
|
7236
|
+
let hasGeneratedBundle = false;
|
|
7237
|
+
return [{
|
|
7238
|
+
name: "module-federation-dts-dev",
|
|
7239
|
+
apply: "serve",
|
|
7240
|
+
config(config) {
|
|
7241
|
+
normalizedDevOptions = normalizeDevOptions(options.dev);
|
|
7242
|
+
if (!normalizedDevOptions) return;
|
|
7243
|
+
if (normalizedDevOptions.disableDynamicRemoteTypeHints) return;
|
|
7244
|
+
ensureRuntimePlugin(options, DYNAMIC_HINTS_PLUGIN);
|
|
7245
|
+
const define = config.define ? { ...config.define } : {};
|
|
7246
|
+
if (!("FEDERATION_IPV4" in define)) define.FEDERATION_IPV4 = JSON.stringify(getIPv4());
|
|
7247
|
+
config.define = define;
|
|
7248
|
+
},
|
|
7249
|
+
configResolved(config) {
|
|
7250
|
+
resolvedConfig = config;
|
|
7251
|
+
},
|
|
7252
|
+
configureServer(server) {
|
|
7253
|
+
if (!normalizedDevOptions || !resolvedConfig) return;
|
|
7254
|
+
const devOptions = normalizedDevOptions;
|
|
7255
|
+
if (devOptions.disableDynamicRemoteTypeHints && devOptions.disableHotTypesReload && devOptions.disableLiveReload) return;
|
|
7256
|
+
if (!options.name) throw createModuleFederationError("name is required if you want to enable dev server!");
|
|
7257
|
+
const outputDir = resolveOutputDir(resolvedConfig);
|
|
7258
|
+
const dtsModuleFederationConfig = getDtsModuleFederationConfig(resolvedConfig.root);
|
|
7259
|
+
const normalizedDtsOptions = normalizeDevDtsOptions(dtsModuleFederationConfig.dts, resolvedConfig.root);
|
|
7260
|
+
if (typeof normalizedDtsOptions !== "object") return;
|
|
7261
|
+
const normalizedGenerateTypes = normalizeOptions(Boolean(normalizedDtsOptions), { compileInChildProcess: true }, "mfOptions.dts.generateTypes")(normalizedDtsOptions.generateTypes);
|
|
7262
|
+
const remote = normalizedGenerateTypes === false ? void 0 : {
|
|
7263
|
+
implementation: normalizedDtsOptions.implementation,
|
|
7264
|
+
context: resolvedConfig.root,
|
|
7265
|
+
outputDir,
|
|
7266
|
+
moduleFederationConfig: { ...dtsModuleFederationConfig },
|
|
7267
|
+
hostRemoteTypesFolder: normalizedGenerateTypes.typesFolder || "@mf-types",
|
|
7268
|
+
...normalizedGenerateTypes,
|
|
7269
|
+
typesFolder: DEV_TYPES_FOLDER
|
|
7270
|
+
};
|
|
7271
|
+
if (remote) server.middlewares.use(createDevDtsAssetMiddleware(getDevDtsAssetPaths({
|
|
7272
|
+
outputDir,
|
|
7273
|
+
publicTypesFolder: remote.hostRemoteTypesFolder || "@mf-types",
|
|
7274
|
+
root: resolvedConfig.root,
|
|
7275
|
+
base: resolvedConfig.base
|
|
7276
|
+
})));
|
|
7277
|
+
if (remote && !remote.tsConfigPath && normalizedDtsOptions.tsConfigPath) remote.tsConfigPath = normalizedDtsOptions.tsConfigPath;
|
|
7278
|
+
const normalizedConsumeTypes = normalizeOptions(Boolean(normalizedDtsOptions), { consumeAPITypes: true }, "mfOptions.dts.consumeTypes")(normalizedDtsOptions.consumeTypes);
|
|
7279
|
+
const host = normalizedConsumeTypes === false ? void 0 : {
|
|
7280
|
+
implementation: normalizedDtsOptions.implementation,
|
|
7281
|
+
context: resolvedConfig.root,
|
|
7282
|
+
moduleFederationConfig: dtsModuleFederationConfig,
|
|
7283
|
+
typesFolder: normalizedConsumeTypes.typesFolder || "@mf-types",
|
|
7284
|
+
abortOnError: false,
|
|
7285
|
+
...normalizedConsumeTypes
|
|
7286
|
+
};
|
|
7287
|
+
const extraOptions = normalizedDtsOptions.extraOptions || {};
|
|
7288
|
+
if (!remote && !host && devOptions.disableLiveReload) return;
|
|
7289
|
+
const startDevWorker = async () => {
|
|
7290
|
+
let remoteTypeUrls;
|
|
7291
|
+
if (host) remoteTypeUrls = await new Promise((resolve) => {
|
|
7292
|
+
consumeTypesAPI({
|
|
7293
|
+
host,
|
|
7294
|
+
extraOptions,
|
|
7295
|
+
displayErrorInTerminal: normalizedDtsOptions.displayErrorInTerminal
|
|
7296
|
+
}, resolve);
|
|
7297
|
+
});
|
|
7298
|
+
devWorker = new DevWorker({
|
|
7299
|
+
name: options.name,
|
|
7300
|
+
remote,
|
|
7301
|
+
host: host ? {
|
|
7302
|
+
...host,
|
|
7303
|
+
remoteTypeUrls
|
|
7304
|
+
} : void 0,
|
|
7305
|
+
extraOptions,
|
|
7306
|
+
disableLiveReload: devOptions.disableLiveReload,
|
|
7307
|
+
disableHotTypesReload: devOptions.disableHotTypesReload
|
|
7308
|
+
});
|
|
7309
|
+
const update = () => devWorker?.update();
|
|
7310
|
+
server.watcher.on("change", update);
|
|
7311
|
+
server.watcher.on("add", update);
|
|
7312
|
+
server.watcher.on("unlink", update);
|
|
7313
|
+
server.httpServer?.once("close", () => {
|
|
7314
|
+
devWorker?.exit();
|
|
7315
|
+
server.watcher.off("change", update);
|
|
7316
|
+
server.watcher.off("add", update);
|
|
7317
|
+
server.watcher.off("unlink", update);
|
|
7318
|
+
});
|
|
7319
|
+
};
|
|
7320
|
+
startDevWorker().catch((error) => {
|
|
7321
|
+
logDtsError(error, normalizedDtsOptions);
|
|
7322
|
+
});
|
|
7323
|
+
}
|
|
7324
|
+
}, {
|
|
7325
|
+
name: "module-federation-dts-build",
|
|
7326
|
+
apply: "build",
|
|
7327
|
+
configResolved(config) {
|
|
7328
|
+
resolvedConfig = config;
|
|
7329
|
+
},
|
|
7330
|
+
async generateBundle() {
|
|
7331
|
+
if (hasGeneratedBundle) return;
|
|
7332
|
+
hasGeneratedBundle = true;
|
|
7333
|
+
if (!resolvedConfig) return;
|
|
7334
|
+
let normalizedDtsOptions;
|
|
7335
|
+
try {
|
|
7336
|
+
normalizedDtsOptions = normalizeDtsOptions(getDtsModuleFederationConfig(resolvedConfig.root), resolvedConfig.root);
|
|
7337
|
+
} catch (error) {
|
|
7338
|
+
logDtsError(error, options.dts);
|
|
7339
|
+
return;
|
|
7340
|
+
}
|
|
7341
|
+
if (typeof normalizedDtsOptions !== "object") return;
|
|
7342
|
+
const context = resolvedConfig.root;
|
|
7343
|
+
const outputDir = resolveOutputDir(resolvedConfig);
|
|
7344
|
+
let consumeOptions;
|
|
7345
|
+
try {
|
|
7346
|
+
consumeOptions = normalizeConsumeTypesOptions({
|
|
7347
|
+
context,
|
|
7348
|
+
dtsOptions: normalizedDtsOptions,
|
|
7349
|
+
pluginOptions: getDtsModuleFederationConfig(resolvedConfig.root)
|
|
7350
|
+
});
|
|
7351
|
+
} catch (error) {
|
|
7352
|
+
logDtsError(error, normalizedDtsOptions);
|
|
7353
|
+
return;
|
|
7354
|
+
}
|
|
7355
|
+
if (consumeOptions?.host?.typesOnBuild) try {
|
|
7356
|
+
await consumeTypesAPI(consumeOptions);
|
|
7357
|
+
} catch (error) {
|
|
7358
|
+
logDtsError(error, normalizedDtsOptions);
|
|
7359
|
+
}
|
|
7360
|
+
let generateOptions;
|
|
7361
|
+
try {
|
|
7362
|
+
generateOptions = normalizeGenerateTypesOptions({
|
|
7363
|
+
context,
|
|
7364
|
+
outputDir,
|
|
7365
|
+
dtsOptions: normalizedDtsOptions,
|
|
7366
|
+
pluginOptions: getDtsModuleFederationConfig(resolvedConfig.root)
|
|
7367
|
+
});
|
|
7368
|
+
} catch (error) {
|
|
7369
|
+
logDtsError(error, normalizedDtsOptions);
|
|
7370
|
+
return;
|
|
7371
|
+
}
|
|
7372
|
+
if (!generateOptions) return;
|
|
7373
|
+
try {
|
|
7374
|
+
await generateTypesAPI({ dtsManagerOptions: generateOptions });
|
|
7375
|
+
} catch (error) {
|
|
7376
|
+
logDtsError(error, normalizedDtsOptions);
|
|
7377
|
+
}
|
|
7378
|
+
}
|
|
7379
|
+
}];
|
|
7380
|
+
}
|
|
7381
|
+
//#endregion
|
|
5866
7382
|
//#region src/plugins/pluginMFManifest.ts
|
|
5867
7383
|
/**
|
|
5868
7384
|
* Resolves the build version for the module federation manifest.
|
|
@@ -5965,9 +7481,20 @@ const Manifest = (providedOptions) => {
|
|
|
5965
7481
|
return [{
|
|
5966
7482
|
name: "module-federation-manifest",
|
|
5967
7483
|
apply: "serve",
|
|
7484
|
+
/**
|
|
7485
|
+
* Stores resolved Vite config for later use
|
|
7486
|
+
*/
|
|
7487
|
+
/**
|
|
7488
|
+
* Finalizes configuration after all plugins are resolved
|
|
7489
|
+
* @param config - Fully resolved Vite config
|
|
7490
|
+
*/
|
|
5968
7491
|
configResolved(config) {
|
|
5969
7492
|
viteConfig = config;
|
|
5970
7493
|
},
|
|
7494
|
+
/**
|
|
7495
|
+
* Configures dev server middleware to handle manifest requests
|
|
7496
|
+
* @param server - Vite dev server instance
|
|
7497
|
+
*/
|
|
5971
7498
|
configureServer(server) {
|
|
5972
7499
|
server.middlewares.use((req, res, next) => {
|
|
5973
7500
|
const devRemoteEntryFile = resolveDevRemoteEntryFileName(filename);
|
|
@@ -6025,6 +7552,11 @@ const Manifest = (providedOptions) => {
|
|
|
6025
7552
|
}, {
|
|
6026
7553
|
name: "module-federation-manifest",
|
|
6027
7554
|
enforce: "post",
|
|
7555
|
+
/**
|
|
7556
|
+
* Initial plugin configuration
|
|
7557
|
+
* @param config - Vite config object
|
|
7558
|
+
* @param command - Current Vite command (serve/build)
|
|
7559
|
+
*/
|
|
6028
7560
|
config(config, { command }) {
|
|
6029
7561
|
_command = command;
|
|
6030
7562
|
if (!config.build) config.build = {};
|
|
@@ -6039,6 +7571,11 @@ const Manifest = (providedOptions) => {
|
|
|
6039
7571
|
if (_command === "serve") base = (config.server.origin || "") + config.base;
|
|
6040
7572
|
publicPath = mfOptions.publicPath === "auto" ? "auto" : resolvePublicPath(mfOptions, base, _originalConfigBase);
|
|
6041
7573
|
},
|
|
7574
|
+
/**
|
|
7575
|
+
* Generates the module federation manifest file
|
|
7576
|
+
* @param options - Rollup output options
|
|
7577
|
+
* @param bundle - Generated bundle assets
|
|
7578
|
+
*/
|
|
6042
7579
|
async generateBundle(_options, bundle) {
|
|
6043
7580
|
if (!mfManifestName) return;
|
|
6044
7581
|
if (this.environment?.name === "ssr") return;
|
|
@@ -6354,12 +7891,16 @@ function resolveDevHashEntryFileName(fileName) {
|
|
|
6354
7891
|
return path$1.extname(baseName) ? normalized : `${normalized}.js`;
|
|
6355
7892
|
}
|
|
6356
7893
|
function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposesId }) {
|
|
6357
|
-
let viteConfig, _command, root;
|
|
7894
|
+
let viteConfig, _command, root, originalConfigBase;
|
|
6358
7895
|
let exposeRemoteDependencies = {};
|
|
6359
7896
|
let exposeRemoteDependenciesDirty = true;
|
|
6360
7897
|
let refreshPromise;
|
|
6361
7898
|
let dependencyInvalidationVersion = 0;
|
|
6362
|
-
|
|
7899
|
+
let reactIslandExposes = /* @__PURE__ */ new Set();
|
|
7900
|
+
const isHostAutoInitId = (id) => {
|
|
7901
|
+
const cleanId = id.split("?")[0];
|
|
7902
|
+
return cleanId.includes(getHostAutoInitPath(options)) || cleanId.includes(getHostAutoInitPath());
|
|
7903
|
+
};
|
|
6363
7904
|
function isRemoteImport(source) {
|
|
6364
7905
|
return Object.keys(options.remotes).some((name) => source === name || source.startsWith(name + "/"));
|
|
6365
7906
|
}
|
|
@@ -6425,9 +7966,11 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
6425
7966
|
configResolved(config) {
|
|
6426
7967
|
viteConfig = config;
|
|
6427
7968
|
root = config.root;
|
|
7969
|
+
reactIslandExposes = getReactIslandExposes(options, root);
|
|
6428
7970
|
},
|
|
6429
|
-
config(
|
|
7971
|
+
config(config, { command }) {
|
|
6430
7972
|
_command = command;
|
|
7973
|
+
originalConfigBase = config.base;
|
|
6431
7974
|
},
|
|
6432
7975
|
async buildStart() {
|
|
6433
7976
|
await refreshExposeRemoteDependencies(this);
|
|
@@ -6460,7 +8003,7 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
6460
8003
|
if (id === remoteEntryId) return parsePromise.then((_) => generateRemoteEntry(options, virtualExposesId, _command));
|
|
6461
8004
|
if (id === virtualExposesId) {
|
|
6462
8005
|
await refreshExposeRemoteDependencies(this);
|
|
6463
|
-
return generateExposes(options, exposeRemoteDependencies, _command);
|
|
8006
|
+
return generateExposes(options, exposeRemoteDependencies, _command, reactIslandExposes);
|
|
6464
8007
|
}
|
|
6465
8008
|
if (_command === "serve" && isHostAutoInitId(id)) return id;
|
|
6466
8009
|
},
|
|
@@ -6470,12 +8013,12 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
6470
8013
|
if (id.includes(remoteEntryId)) return parsePromise.then((_) => generateRemoteEntry(options, virtualExposesId, _command));
|
|
6471
8014
|
if (id === virtualExposesId) {
|
|
6472
8015
|
await refreshExposeRemoteDependencies(this);
|
|
6473
|
-
return generateExposes(options, exposeRemoteDependencies, _command);
|
|
8016
|
+
return generateExposes(options, exposeRemoteDependencies, _command, reactIslandExposes);
|
|
6474
8017
|
}
|
|
6475
8018
|
if (isHostAutoInitId(id)) {
|
|
6476
8019
|
if (_command === "serve") {
|
|
6477
8020
|
const host = typeof viteConfig.server?.host === "string" && viteConfig.server.host !== "0.0.0.0" ? viteConfig.server.host : "localhost";
|
|
6478
|
-
const resolvedPublicPath = resolvePublicPath(options, viteConfig.base);
|
|
8021
|
+
const resolvedPublicPath = resolvePublicPath(options, viteConfig.base, originalConfigBase);
|
|
6479
8022
|
const publicPath = JSON.stringify((resolvedPublicPath === "auto" ? "/" : resolvedPublicPath) + resolveDevHashEntryFileName(options.filename));
|
|
6480
8023
|
const fallbackOrigin = `//${host}:${viteConfig.server?.port}`;
|
|
6481
8024
|
const ssrRemoteEntry = "data:text/javascript," + encodeURIComponent("export async function init(){return {loadRemote:async()=>({}),loadShare:async()=>({})}}");
|
|
@@ -6603,11 +8146,23 @@ function pluginProxyRemotes_default(options) {
|
|
|
6603
8146
|
enableSsrInit = getSsrCapabilities(parseInt(version, 10), command, Object.keys(remotes).length > 0).enableSsrInitBootstrap;
|
|
6604
8147
|
},
|
|
6605
8148
|
resolveId(source, importer) {
|
|
8149
|
+
const resolvedIslandConsumerId = resolveReactIslandConsumerId(source);
|
|
8150
|
+
if (resolvedIslandConsumerId) return resolvedIslandConsumerId;
|
|
8151
|
+
const islandRemoteId = getReactIslandImportRemoteId(source);
|
|
8152
|
+
if (islandRemoteId) for (const remoteAlias of Object.keys(remotes)) {
|
|
8153
|
+
if (islandRemoteId !== remoteAlias && !islandRemoteId.startsWith(`${remoteAlias}/`)) continue;
|
|
8154
|
+
addUsedRemote(remoteAlias, islandRemoteId, options);
|
|
8155
|
+
refreshHostAutoInit(options);
|
|
8156
|
+
return `\0${getReactIslandServerImportId(islandRemoteId)}`;
|
|
8157
|
+
}
|
|
6606
8158
|
if (!filterId(source)) return;
|
|
6607
8159
|
for (const remoteAlias of Object.keys(remotes)) {
|
|
6608
8160
|
if (source !== remoteAlias && !source.startsWith(`${remoteAlias}/`)) continue;
|
|
6609
8161
|
return resolveRemoteId(this, source, importer, remoteAlias);
|
|
6610
8162
|
}
|
|
8163
|
+
},
|
|
8164
|
+
load(id) {
|
|
8165
|
+
return loadReactIslandConsumerModule(id);
|
|
6611
8166
|
}
|
|
6612
8167
|
};
|
|
6613
8168
|
}
|
|
@@ -6811,7 +8366,7 @@ function proxySharedModule(options) {
|
|
|
6811
8366
|
load(id) {
|
|
6812
8367
|
if (id === getResolvedLocalSharedImportMapId(federationOptions)) return parsePromise.then((_) => {
|
|
6813
8368
|
refreshTreeShakingModules(federationOptions);
|
|
6814
|
-
const providerPackages = new Set([...Object.keys(shared).filter((pkg) => !pkg.endsWith("/")), ...getUsedShares(federationOptions)]);
|
|
8369
|
+
const providerPackages = /* @__PURE__ */ new Set([...Object.keys(shared).filter((pkg) => !pkg.endsWith("/")), ...getUsedShares(federationOptions)]);
|
|
6815
8370
|
for (const pkg of providerPackages) {
|
|
6816
8371
|
const sharedKey = findSharedKeyForSource(pkg, shared);
|
|
6817
8372
|
const shareItem = shared[pkg] || (sharedKey ? shared[sharedKey] : void 0);
|
|
@@ -7243,14 +8798,14 @@ function pluginRemoteNamedExports(options) {
|
|
|
7243
8798
|
//#region src/plugins/pluginSSRRemoteEntry.ts
|
|
7244
8799
|
const MAX_RUNNER_BODY_BYTES = 1024 * 1024;
|
|
7245
8800
|
const MAX_RUNNER_START_OFFSET = 1024 * 1024;
|
|
7246
|
-
const ALLOWED_RUNNER_INVOKE_NAMES = new Set(["fetchModule", "getBuiltins"]);
|
|
8801
|
+
const ALLOWED_RUNNER_INVOKE_NAMES = /* @__PURE__ */ new Set(["fetchModule", "getBuiltins"]);
|
|
7247
8802
|
const VITE_FS_PREFIX = "/@fs/";
|
|
7248
8803
|
function isPlainObject(value) {
|
|
7249
8804
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
7250
8805
|
}
|
|
7251
8806
|
function isSafeRunnerFetchModuleOptions(value) {
|
|
7252
8807
|
if (!isPlainObject(value)) return false;
|
|
7253
|
-
const allowedKeys = new Set([
|
|
8808
|
+
const allowedKeys = /* @__PURE__ */ new Set([
|
|
7254
8809
|
"cached",
|
|
7255
8810
|
"startOffset",
|
|
7256
8811
|
"inlineSourceMap"
|
|
@@ -7388,11 +8943,12 @@ function pluginSSRRemoteEntry(options) {
|
|
|
7388
8943
|
...options.ssrExternals ?? []
|
|
7389
8944
|
];
|
|
7390
8945
|
const ssrOnlyExternalPattern = new RegExp(`^(${ssrOnlyExternals.map((e) => e.replace(/[/\\^$*+?.()|[\]{}]/g, "\\$&")).join("|")})(\\/.*)?$`);
|
|
7391
|
-
const ssrModuleIds = new Set([remoteEntrySSRId, virtualExposesSSRId]);
|
|
8946
|
+
const ssrModuleIds = /* @__PURE__ */ new Set([remoteEntrySSRId, virtualExposesSSRId]);
|
|
7392
8947
|
const resolvedAbsToPackage = /* @__PURE__ */ new Map();
|
|
7393
8948
|
let isServe = false;
|
|
7394
8949
|
let viteConfig;
|
|
7395
8950
|
let isNuxtProject = false;
|
|
8951
|
+
let reactIslandExposes = /* @__PURE__ */ new Set();
|
|
7396
8952
|
const findNuxtExposesChunk = (bundle) => {
|
|
7397
8953
|
const exposeKeys = Object.keys(options.exposes);
|
|
7398
8954
|
if (exposeKeys.length === 0) return;
|
|
@@ -7436,10 +8992,11 @@ function pluginSSRRemoteEntry(options) {
|
|
|
7436
8992
|
configResolved(config) {
|
|
7437
8993
|
viteConfig = config;
|
|
7438
8994
|
isNuxtProject = isNuxtProjectRoot(config.root);
|
|
8995
|
+
reactIslandExposes = getReactIslandExposes(options, config.root);
|
|
7439
8996
|
},
|
|
7440
8997
|
configureServer(server) {
|
|
7441
8998
|
const base = "/__mf_ssr__";
|
|
7442
|
-
const basePath = getBasePath$
|
|
8999
|
+
const basePath = getBasePath$2(viteConfig?.base);
|
|
7443
9000
|
const ssrEntryFileName = getSsrRemoteEntryFileName(options.filename);
|
|
7444
9001
|
if (isNuxtProject || isNuxtClientBase(basePath)) server.middlewares.use((req, _res, next) => {
|
|
7445
9002
|
if (req.url?.replace(/\?.*/, "") === `${basePath}/${ssrEntryFileName}`) req.url = `${basePath}/__mf_ssr__/${ssrEntryFileName}`;
|
|
@@ -7503,7 +9060,7 @@ function pluginSSRRemoteEntry(options) {
|
|
|
7503
9060
|
server.middlewares.use(exposesPath, (_req, res) => {
|
|
7504
9061
|
res.setHeader("Content-Type", "application/javascript");
|
|
7505
9062
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
7506
|
-
res.end(generateExposesSSR(options));
|
|
9063
|
+
res.end(generateExposesSSR(options, reactIslandExposes));
|
|
7507
9064
|
});
|
|
7508
9065
|
},
|
|
7509
9066
|
resolveId(id) {
|
|
@@ -7514,7 +9071,7 @@ function pluginSSRRemoteEntry(options) {
|
|
|
7514
9071
|
},
|
|
7515
9072
|
load(id) {
|
|
7516
9073
|
if (id === remoteEntrySSRId || id.startsWith(remoteEntrySSRId)) return generateRemoteEntrySSR(options);
|
|
7517
|
-
if (id === virtualExposesSSRId || id.startsWith(virtualExposesSSRId)) return generateExposesSSR(options);
|
|
9074
|
+
if (id === virtualExposesSSRId || id.startsWith(virtualExposesSSRId)) return generateExposesSSR(options, reactIslandExposes);
|
|
7518
9075
|
},
|
|
7519
9076
|
buildStart() {
|
|
7520
9077
|
if (isServe) return;
|
|
@@ -7583,7 +9140,7 @@ function collectEntryOutputFiles(bundle, entryFileName) {
|
|
|
7583
9140
|
const file = bundle[fileName];
|
|
7584
9141
|
if (!file) return;
|
|
7585
9142
|
files.add(fileName);
|
|
7586
|
-
const dependencies = new Set([
|
|
9143
|
+
const dependencies = /* @__PURE__ */ new Set([
|
|
7587
9144
|
...file.imports || [],
|
|
7588
9145
|
...file.dynamicImports || [],
|
|
7589
9146
|
...file.implicitlyLoadedBefore || [],
|
|
@@ -7612,9 +9169,20 @@ const VarRemoteEntry = (providedOptions) => {
|
|
|
7612
9169
|
return [{
|
|
7613
9170
|
name: "module-federation-var-remote-entry",
|
|
7614
9171
|
apply: "serve",
|
|
9172
|
+
/**
|
|
9173
|
+
* Stores resolved Vite config for later use
|
|
9174
|
+
*/
|
|
9175
|
+
/**
|
|
9176
|
+
* Finalizes configuration after all plugins are resolved
|
|
9177
|
+
* @param config - Fully resolved Vite config
|
|
9178
|
+
*/
|
|
7615
9179
|
configResolved(config) {
|
|
7616
9180
|
viteConfig = config;
|
|
7617
9181
|
},
|
|
9182
|
+
/**
|
|
9183
|
+
* Configures dev server middleware to handle varRemoteEntry requests
|
|
9184
|
+
* @param server - Vite dev server instance
|
|
9185
|
+
*/
|
|
7618
9186
|
configureServer(server) {
|
|
7619
9187
|
server.middlewares.use((req, res, next) => {
|
|
7620
9188
|
if (!varFilename) {
|
|
@@ -7631,12 +9199,22 @@ const VarRemoteEntry = (providedOptions) => {
|
|
|
7631
9199
|
}, {
|
|
7632
9200
|
name: "module-federation-var-remote-entry",
|
|
7633
9201
|
enforce: "post",
|
|
9202
|
+
/**
|
|
9203
|
+
* Initial plugin configuration
|
|
9204
|
+
* @param config - Vite config object
|
|
9205
|
+
* @param command - Current Vite command (serve/build)
|
|
9206
|
+
*/
|
|
7634
9207
|
config(config) {
|
|
7635
9208
|
if (!config.build) config.build = {};
|
|
7636
9209
|
},
|
|
7637
9210
|
configResolved(config) {
|
|
7638
9211
|
viteConfig = config;
|
|
7639
9212
|
},
|
|
9213
|
+
/**
|
|
9214
|
+
* Generates the module federation "var" remote entry file
|
|
9215
|
+
* @param options - Rollup output options
|
|
9216
|
+
* @param bundle - Generated bundle assets
|
|
9217
|
+
*/
|
|
7640
9218
|
async generateBundle(_options, bundle) {
|
|
7641
9219
|
if (!varFilename) return;
|
|
7642
9220
|
if (!isValidVarName(name)) mfWarn(`Provided remote name "${name}" is not valid for "var" remoteEntry type, thus it's placed in globalThis['${name}'].\nIt may cause problems, so you would better want to use valid var name (see https://www.w3schools.com/js/js_variables.asp).`);
|
|
@@ -7766,6 +9344,42 @@ function isTestEnv() {
|
|
|
7766
9344
|
return process.env.NODE_ENV === "test" || process.env.VITEST != null || process.env.JEST_WORKER_ID != null;
|
|
7767
9345
|
}
|
|
7768
9346
|
//#endregion
|
|
9347
|
+
//#region src/utils/sharedExportConditions.ts
|
|
9348
|
+
const DEFAULT_CLIENT_EXPORT_CONDITIONS = [
|
|
9349
|
+
"browser",
|
|
9350
|
+
"import",
|
|
9351
|
+
"module",
|
|
9352
|
+
"default"
|
|
9353
|
+
];
|
|
9354
|
+
const DEFAULT_NODE_SSR_EXPORT_CONDITIONS = [
|
|
9355
|
+
"node",
|
|
9356
|
+
"import",
|
|
9357
|
+
"module",
|
|
9358
|
+
"default"
|
|
9359
|
+
];
|
|
9360
|
+
const DEFAULT_WEBWORKER_SSR_EXPORT_CONDITIONS = [
|
|
9361
|
+
"worker",
|
|
9362
|
+
"browser",
|
|
9363
|
+
"import",
|
|
9364
|
+
"module",
|
|
9365
|
+
"default"
|
|
9366
|
+
];
|
|
9367
|
+
const VITE_DEV_PROD_CONDITION = "development|production";
|
|
9368
|
+
function appendConditions(conditions, fallbackConditions) {
|
|
9369
|
+
return [.../* @__PURE__ */ new Set([...conditions, ...fallbackConditions])];
|
|
9370
|
+
}
|
|
9371
|
+
function resolveViteModeCondition(conditions, isProduction) {
|
|
9372
|
+
const modeCondition = isProduction ? "production" : "development";
|
|
9373
|
+
return [...new Set(conditions.map((condition) => condition === VITE_DEV_PROD_CONDITION ? modeCondition : condition))];
|
|
9374
|
+
}
|
|
9375
|
+
function getSharedExportConditions({ environmentConditions, isProduction, isSsr, rootConditions, ssrConditions, ssrTarget = "node" }) {
|
|
9376
|
+
if (environmentConditions !== void 0) return resolveViteModeCondition(appendConditions(environmentConditions, ["import", "default"]), isProduction);
|
|
9377
|
+
const defaultConditions = isSsr ? ssrTarget === "webworker" ? DEFAULT_WEBWORKER_SSR_EXPORT_CONDITIONS : DEFAULT_NODE_SSR_EXPORT_CONDITIONS : DEFAULT_CLIENT_EXPORT_CONDITIONS;
|
|
9378
|
+
const configuredConditions = isSsr ? ssrConditions ?? rootConditions : rootConditions;
|
|
9379
|
+
if (configuredConditions !== void 0) return resolveViteModeCondition(appendConditions(configuredConditions, defaultConditions), isProduction);
|
|
9380
|
+
return [...defaultConditions];
|
|
9381
|
+
}
|
|
9382
|
+
//#endregion
|
|
7769
9383
|
//#region src/utils/normalizeOptimizeDeps.ts
|
|
7770
9384
|
var normalizeOptimizeDeps_default = {
|
|
7771
9385
|
name: "normalizeOptimizeDeps",
|
|
@@ -7857,6 +9471,9 @@ function isSharedResolverInternalImporter(importer) {
|
|
|
7857
9471
|
function isCommonJsImporter(importer) {
|
|
7858
9472
|
return !!importer && (importer.endsWith(".cjs") || importer.includes("/cjs/"));
|
|
7859
9473
|
}
|
|
9474
|
+
function isReactDomSelfReference(source, importer) {
|
|
9475
|
+
return source === "react-dom" && getPackageNameFromNodeModulePath(importer ?? "") === "react-dom";
|
|
9476
|
+
}
|
|
7860
9477
|
function isOutputChunk(chunk) {
|
|
7861
9478
|
return chunk.type === "chunk";
|
|
7862
9479
|
}
|
|
@@ -7911,10 +9528,57 @@ function isFederationHtmlPreloadDependency(dep, includeSharedRuntime = false) {
|
|
|
7911
9528
|
function canResolveSharedSubpath(subpath, projectRoot) {
|
|
7912
9529
|
try {
|
|
7913
9530
|
return isViteOptimizableEntry(createRequire$1(pathToFileURL(path$1.join(projectRoot, "package.json"))).resolve(subpath));
|
|
7914
|
-
} catch {
|
|
9531
|
+
} catch (error) {
|
|
9532
|
+
if (error?.code === "ERR_PACKAGE_PATH_NOT_EXPORTED" && !isBarePackageSubpath(subpath)) {
|
|
9533
|
+
const entry = resolveViteImportPackageEntry(subpath, projectRoot);
|
|
9534
|
+
return entry !== void 0 && existsSync(entry) && isViteOptimizableEntry(entry);
|
|
9535
|
+
}
|
|
7915
9536
|
return false;
|
|
7916
9537
|
}
|
|
7917
9538
|
}
|
|
9539
|
+
const VITE_DEV_IMPORT_CONDITIONS = /* @__PURE__ */ new Set([
|
|
9540
|
+
"browser",
|
|
9541
|
+
"development",
|
|
9542
|
+
"import",
|
|
9543
|
+
"module",
|
|
9544
|
+
"default"
|
|
9545
|
+
]);
|
|
9546
|
+
function resolveConditionalExportTarget(target) {
|
|
9547
|
+
if (typeof target === "string") return target;
|
|
9548
|
+
if (Array.isArray(target)) {
|
|
9549
|
+
for (const candidate of target) {
|
|
9550
|
+
const resolved = resolveConditionalExportTarget(candidate);
|
|
9551
|
+
if (resolved) return resolved;
|
|
9552
|
+
}
|
|
9553
|
+
return;
|
|
9554
|
+
}
|
|
9555
|
+
if (!target || typeof target !== "object") return void 0;
|
|
9556
|
+
for (const [condition, candidate] of Object.entries(target)) {
|
|
9557
|
+
if (!VITE_DEV_IMPORT_CONDITIONS.has(condition)) continue;
|
|
9558
|
+
const resolved = resolveConditionalExportTarget(candidate);
|
|
9559
|
+
if (resolved) return resolved;
|
|
9560
|
+
}
|
|
9561
|
+
}
|
|
9562
|
+
function resolveViteImportPackageEntry(packageName, projectRoot) {
|
|
9563
|
+
const installed = getInstalledPackageJson(packageName, { cwd: projectRoot });
|
|
9564
|
+
if (!installed) return void 0;
|
|
9565
|
+
const exportsField = installed.packageJson.exports;
|
|
9566
|
+
let rootExport = exportsField;
|
|
9567
|
+
if (exportsField && typeof exportsField === "object" && !Array.isArray(exportsField)) {
|
|
9568
|
+
const exportsRecord = exportsField;
|
|
9569
|
+
if (Object.keys(exportsRecord).some((key) => key.startsWith("."))) rootExport = exportsRecord["."];
|
|
9570
|
+
}
|
|
9571
|
+
const target = resolveConditionalExportTarget(rootExport);
|
|
9572
|
+
if (!target?.startsWith("./")) return void 0;
|
|
9573
|
+
const resolved = path$1.resolve(installed.dir, target);
|
|
9574
|
+
const relative = path$1.relative(installed.dir, resolved);
|
|
9575
|
+
if (relative.startsWith(`..${path$1.sep}`) || path$1.isAbsolute(relative)) return void 0;
|
|
9576
|
+
return resolved;
|
|
9577
|
+
}
|
|
9578
|
+
function isBarePackageSubpath(specifier) {
|
|
9579
|
+
const segments = specifier.split("/");
|
|
9580
|
+
return specifier.startsWith("@") ? segments.length > 2 : segments.length > 1;
|
|
9581
|
+
}
|
|
7918
9582
|
/**
|
|
7919
9583
|
* Vite's dependency scanner cannot see through the virtual loadShare modules
|
|
7920
9584
|
* generated for shared packages. As a result, dependencies of a linked/shared
|
|
@@ -7990,8 +9654,10 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
7990
9654
|
optimizeDeps.rolldownOptions.plugins.push({
|
|
7991
9655
|
name: "module-federation:optimize-shared-resolver",
|
|
7992
9656
|
load(id) {
|
|
7993
|
-
if (id
|
|
7994
|
-
const
|
|
9657
|
+
if (!id.startsWith("module-federation:optimized-require-")) return;
|
|
9658
|
+
const sourcePackage = id.slice(36);
|
|
9659
|
+
if (sourcePackage !== "react" && sourcePackage !== "react-dom") return;
|
|
9660
|
+
const loadSharePath = getLoadShareModulePath(sourcePackage, isRolldown, options);
|
|
7995
9661
|
const source = JSON.stringify(loadSharePath);
|
|
7996
9662
|
return "import * as __mfShared from " + source + ";\nexport * from " + source + ";\nexport default __mfShared.default ?? __mfShared;";
|
|
7997
9663
|
},
|
|
@@ -8007,13 +9673,14 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
8007
9673
|
const shareItem = shared[key];
|
|
8008
9674
|
const isReactSingleton = source === "react" && key === "react" && shareItem.shareConfig?.singleton === true;
|
|
8009
9675
|
const isReactRequire = resolveOptions?.kind?.startsWith("require") && isReactSingleton;
|
|
8010
|
-
|
|
8011
|
-
if (
|
|
8012
|
-
if (
|
|
9676
|
+
const isReactDomRequire = resolveOptions?.kind?.startsWith("require") && isReactDomSelfReference(source, importer);
|
|
9677
|
+
if (resolveOptions?.kind?.startsWith("require") && !isReactRequire && !isReactDomRequire) return;
|
|
9678
|
+
if (isCommonJsImporter(importer) && !isReactSingleton && !isReactDomRequire) return;
|
|
9679
|
+
if (isReactRequire || isReactDomRequire) {
|
|
8013
9680
|
writeLoadShareModule(source, shareItem, _command, isRolldown, options);
|
|
8014
9681
|
if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(source, shareItem, options);
|
|
8015
9682
|
addUsedShares(source, options);
|
|
8016
|
-
return { id:
|
|
9683
|
+
return { id: `module-federation:optimized-require-${source}` };
|
|
8017
9684
|
}
|
|
8018
9685
|
const loadSharePath = getLoadShareModulePath(source, isRolldown, options);
|
|
8019
9686
|
writeLoadShareModule(source, shareItem, _command, isRolldown, options);
|
|
@@ -8040,7 +9707,7 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
8040
9707
|
if (!args.importer || args.namespace === "mf-shared") return;
|
|
8041
9708
|
if (isSharedResolverInternalImporter(args.importer)) return;
|
|
8042
9709
|
if (!findSharedKey(args.path, shared) || isAssetLikeImport(args.path)) return;
|
|
8043
|
-
if (getPackageNameFromNodeModulePath(args.importer) === getPackageName(args.path)) return;
|
|
9710
|
+
if (getPackageNameFromNodeModulePath(args.importer) === getPackageName(args.path) && !isReactDomSelfReference(args.path, args.importer)) return;
|
|
8044
9711
|
return {
|
|
8045
9712
|
path: args.path,
|
|
8046
9713
|
namespace: "mf-shared"
|
|
@@ -8110,8 +9777,10 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
8110
9777
|
writeLoadShareModule(subpath, shareItem, _command, isRolldown, options);
|
|
8111
9778
|
writePreBuildLibPath(subpath, shareItem, options);
|
|
8112
9779
|
addUsedShares(subpath, options);
|
|
8113
|
-
if (canResolveSubpath)
|
|
8114
|
-
|
|
9780
|
+
if (canResolveSubpath) {
|
|
9781
|
+
optimizeDeps.include.push(subpath);
|
|
9782
|
+
if (key === "react-dom") optimizeDeps.include.push(`${key} > ${subpath}`);
|
|
9783
|
+
} else optimizeDeps.exclude.push(subpath);
|
|
8115
9784
|
}
|
|
8116
9785
|
}
|
|
8117
9786
|
}
|
|
@@ -8157,7 +9826,7 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
8157
9826
|
}
|
|
8158
9827
|
};
|
|
8159
9828
|
}
|
|
8160
|
-
const SSR_ONLY_PLUGINS = new Set(["@module-federation/vite/ssrEntryLoader"]);
|
|
9829
|
+
const SSR_ONLY_PLUGINS = /* @__PURE__ */ new Set(["@module-federation/vite/ssrEntryLoader"]);
|
|
8161
9830
|
function applyBuildTimeRuntimeDefines(define, options, { target, isAstro, defaultDisableSnapshot }) {
|
|
8162
9831
|
const envTargetDefineValue = !options.target && isAstro ? "undefined" : JSON.stringify(target);
|
|
8163
9832
|
if (!("ENV_TARGET" in define)) define.ENV_TARGET = envTargetDefineValue;
|
|
@@ -8169,11 +9838,39 @@ function applyBuildTimeRuntimeDefines(define, options, { target, isAstro, defaul
|
|
|
8169
9838
|
}
|
|
8170
9839
|
function loadPluginDts(options) {
|
|
8171
9840
|
if (options.dts === false) return [];
|
|
8172
|
-
return [
|
|
9841
|
+
return [Promise.resolve().then(() => pluginDts_exports).then(({ default: pluginDts }) => pluginDts(options))];
|
|
9842
|
+
}
|
|
9843
|
+
const INJECT_EXTERNAL_RUNTIME_CORE_PLUGIN = "@module-federation/vite/injectExternalRuntimeCorePlugin";
|
|
9844
|
+
function isInjectExternalRuntimeCorePlugin(specifier) {
|
|
9845
|
+
return specifier === INJECT_EXTERNAL_RUNTIME_CORE_PLUGIN || specifier.includes("injectExternalRuntimeCorePlugin") || specifier.includes("inject-external-runtime-core-plugin");
|
|
9846
|
+
}
|
|
9847
|
+
function hasInjectExternalRuntimeCorePlugin(runtimePlugins) {
|
|
9848
|
+
return runtimePlugins.some((plugin) => {
|
|
9849
|
+
return isInjectExternalRuntimeCorePlugin(typeof plugin === "string" ? plugin : plugin[0]);
|
|
9850
|
+
});
|
|
9851
|
+
}
|
|
9852
|
+
function resolveInjectExternalRuntimeCorePlugin() {
|
|
9853
|
+
try {
|
|
9854
|
+
return normalizePathForImport(resolveImportPath(INJECT_EXTERNAL_RUNTIME_CORE_PLUGIN));
|
|
9855
|
+
} catch {
|
|
9856
|
+
for (const rel of ["./utils/injectExternalRuntimeCorePlugin.js", "./utils/injectExternalRuntimeCorePlugin.ts"]) {
|
|
9857
|
+
const candidate = fileURLToPath(new URL(rel, import.meta.url));
|
|
9858
|
+
if (existsSync(candidate)) return normalizePathForImport(candidate);
|
|
9859
|
+
}
|
|
9860
|
+
return INJECT_EXTERNAL_RUNTIME_CORE_PLUGIN;
|
|
9861
|
+
}
|
|
9862
|
+
}
|
|
9863
|
+
function applyExternalRuntimeExperiments(options) {
|
|
9864
|
+
const { experiments } = options;
|
|
9865
|
+
if (experiments.provideExternalRuntime) {
|
|
9866
|
+
if (Object.keys(options.exposes).length > 0) throw createModuleFederationError("You can only set provideExternalRuntime: true in pure consumer which not expose modules.");
|
|
9867
|
+
if (!hasInjectExternalRuntimeCorePlugin(options.runtimePlugins)) options.runtimePlugins = options.runtimePlugins.concat(resolveInjectExternalRuntimeCorePlugin());
|
|
9868
|
+
}
|
|
8173
9869
|
}
|
|
8174
9870
|
function federation(mfUserOptions) {
|
|
8175
9871
|
if (isTestEnv()) return [];
|
|
8176
9872
|
const options = normalizeModuleFederationOptions(mfUserOptions);
|
|
9873
|
+
applyExternalRuntimeExperiments(options);
|
|
8177
9874
|
const isVinext = hasPackageDependency("vinext");
|
|
8178
9875
|
const { name, shared, filename, hostInitInjectLocation } = options;
|
|
8179
9876
|
const hasTreeShakingShared = Object.values(shared).some((share) => !!share.shareConfig.treeShaking);
|
|
@@ -8183,7 +9880,45 @@ function federation(mfUserOptions) {
|
|
|
8183
9880
|
let command;
|
|
8184
9881
|
let desiredRolldownOutput;
|
|
8185
9882
|
let isSsrBuild = false;
|
|
9883
|
+
let isProduction = false;
|
|
9884
|
+
let rootResolveConditions;
|
|
9885
|
+
let ssrResolveConditions;
|
|
9886
|
+
let ssrTarget = "node";
|
|
8186
9887
|
const emittedRuntimeCapabilityWarnings = /* @__PURE__ */ new Set();
|
|
9888
|
+
const getLoadHookExportConditions = (context, loadOptions) => {
|
|
9889
|
+
const environment = context.environment;
|
|
9890
|
+
const isSsr = loadOptions?.ssr === true || isSsrBuild || environment?.config?.consumer === "server" || Boolean(environment?.config?.build?.ssr) || environment?.name === "ssr" || environment?.name === "server";
|
|
9891
|
+
return getSharedExportConditions({
|
|
9892
|
+
environmentConditions: environment?.config?.resolve?.conditions,
|
|
9893
|
+
isProduction: environment?.config?.isProduction ?? isProduction,
|
|
9894
|
+
isSsr,
|
|
9895
|
+
rootConditions: rootResolveConditions,
|
|
9896
|
+
ssrConditions: ssrResolveConditions,
|
|
9897
|
+
ssrTarget
|
|
9898
|
+
});
|
|
9899
|
+
};
|
|
9900
|
+
const refreshPreBuildModuleForEnvironment = (id, context, loadOptions) => {
|
|
9901
|
+
const pkg = getCachedPreBuildPkg(id);
|
|
9902
|
+
if (!pkg) return "not-applicable";
|
|
9903
|
+
const key = findSharedKey(pkg, shared);
|
|
9904
|
+
if (!key) return "not-applicable";
|
|
9905
|
+
const requestedModule = VirtualModule.findById(id);
|
|
9906
|
+
const ownedModule = VirtualModule.findById(getPreBuildLibImportId(pkg, options));
|
|
9907
|
+
if (!requestedModule || requestedModule !== ownedModule) return "not-owned";
|
|
9908
|
+
writePreBuildLibPath(pkg, shared[key], options, getLoadHookExportConditions(context, loadOptions));
|
|
9909
|
+
return "refreshed";
|
|
9910
|
+
};
|
|
9911
|
+
const refreshLoadShareModuleForEnvironment = (id, context, loadOptions) => {
|
|
9912
|
+
const pkg = getCachedLoadSharePkg(id);
|
|
9913
|
+
if (!pkg) return "not-applicable";
|
|
9914
|
+
const key = findSharedKey(pkg, shared);
|
|
9915
|
+
if (!key) return "not-applicable";
|
|
9916
|
+
const requestedModule = VirtualModule.findById(id);
|
|
9917
|
+
const ownedModule = VirtualModule.findById(getLoadShareModulePath(pkg, false, options));
|
|
9918
|
+
if (!requestedModule || requestedModule !== ownedModule) return "not-owned";
|
|
9919
|
+
writeLoadShareModule(pkg, shared[key], command, getIsRolldown(context), options, getLoadHookExportConditions(context, loadOptions));
|
|
9920
|
+
return "refreshed";
|
|
9921
|
+
};
|
|
8187
9922
|
return [
|
|
8188
9923
|
{
|
|
8189
9924
|
name: "vite:module-federation-virtual-modules",
|
|
@@ -8201,18 +9936,21 @@ function federation(mfUserOptions) {
|
|
|
8201
9936
|
writeLocalSharedImportMap: () => writeLocalSharedImportMap(options),
|
|
8202
9937
|
federationOptions: options
|
|
8203
9938
|
});
|
|
8204
|
-
virtualModule = VirtualModule.findById(id);
|
|
9939
|
+
virtualModule = VirtualModule.findById(id) ?? findCurrentLoadShareForStaleOwnerId(id, options.shared, findSharedKey, options);
|
|
8205
9940
|
}
|
|
8206
9941
|
if (!virtualModule) return;
|
|
8207
9942
|
return virtualModule.getResolvedId();
|
|
8208
9943
|
},
|
|
8209
|
-
load(id) {
|
|
9944
|
+
load(id, loadOptions) {
|
|
9945
|
+
if (command !== "build" && id.includes("__loadShare__") && refreshLoadShareModuleForEnvironment(id, this, loadOptions) === "not-owned") return;
|
|
9946
|
+
if (id.includes("__prebuild__") && refreshPreBuildModuleForEnvironment(id, this, loadOptions) === "not-owned") return;
|
|
8210
9947
|
const virtualModule = VirtualModule.findById(id);
|
|
8211
9948
|
if (!virtualModule) return;
|
|
8212
9949
|
if (command === "build" && (id.includes("__loadShare__") || id.includes("__loadRemote__"))) return;
|
|
8213
9950
|
return virtualModule.code;
|
|
8214
9951
|
}
|
|
8215
9952
|
},
|
|
9953
|
+
...options.experiments.externalRuntime ? [pluginExternalRuntimeCore()] : [],
|
|
8216
9954
|
createEarlyVirtualModulesPlugin(options),
|
|
8217
9955
|
...isVinext ? [{
|
|
8218
9956
|
name: "module-federation-vinext-react-server-build-alias",
|
|
@@ -8238,7 +9976,11 @@ function federation(mfUserOptions) {
|
|
|
8238
9976
|
config(_config, env) {
|
|
8239
9977
|
command = env.command;
|
|
8240
9978
|
},
|
|
8241
|
-
configResolved() {
|
|
9979
|
+
configResolved(config) {
|
|
9980
|
+
rootResolveConditions = config.resolve?.conditions ? [...config.resolve.conditions] : void 0;
|
|
9981
|
+
ssrResolveConditions = config.ssr?.resolve?.conditions ? [...config.ssr.resolve.conditions] : void 0;
|
|
9982
|
+
ssrTarget = config.ssr?.target ?? "node";
|
|
9983
|
+
isProduction = config.isProduction;
|
|
8242
9984
|
const ssrCapabilities = getSsrCapabilities(parseInt(version, 10), command, Object.keys(options.remotes).length > 0);
|
|
8243
9985
|
initVirtualModules(command, remoteEntryId, ssrCapabilities.enableSsrInitBootstrap, options);
|
|
8244
9986
|
}
|
|
@@ -8302,7 +10044,7 @@ function federation(mfUserOptions) {
|
|
|
8302
10044
|
enforce: "pre",
|
|
8303
10045
|
apply: "build",
|
|
8304
10046
|
config(config) {
|
|
8305
|
-
isSsrBuild = config.build?.ssr
|
|
10047
|
+
isSsrBuild = Boolean(config.build?.ssr);
|
|
8306
10048
|
const runtimeInitId = getRuntimeInitStatusImportId(options);
|
|
8307
10049
|
config.build = config.build || {};
|
|
8308
10050
|
if (config.build.modulePreload !== false) {
|
|
@@ -8422,8 +10164,9 @@ function federation(mfUserOptions) {
|
|
|
8422
10164
|
};
|
|
8423
10165
|
}
|
|
8424
10166
|
},
|
|
8425
|
-
load(id) {
|
|
10167
|
+
load(id, loadOptions) {
|
|
8426
10168
|
if (id.includes("__loadShare__") || id.includes("__loadRemote__")) {
|
|
10169
|
+
if (id.includes("__loadShare__") && refreshLoadShareModuleForEnvironment(id, this, loadOptions) === "not-owned") return;
|
|
8427
10170
|
const virtualModule = VirtualModule.findById(id);
|
|
8428
10171
|
if (!virtualModule?.code) return null;
|
|
8429
10172
|
let code = virtualModule.code;
|
|
@@ -8490,7 +10233,7 @@ function federation(mfUserOptions) {
|
|
|
8490
10233
|
_options: options,
|
|
8491
10234
|
config(config, { command: _command }) {
|
|
8492
10235
|
const isRolldown = getIsRolldown(this);
|
|
8493
|
-
isSsrBuild = _command === "build" && config.build?.ssr
|
|
10236
|
+
isSsrBuild = _command === "build" && Boolean(config.build?.ssr);
|
|
8494
10237
|
const needsRuntimeHelpers = Object.keys(options.shared ?? {}).length > 0;
|
|
8495
10238
|
if (needsRuntimeHelpers) appendResolveAlias(config, {
|
|
8496
10239
|
find: /^@module-federation\/runtime\/helpers$/,
|
|
@@ -8575,7 +10318,8 @@ function federation(mfUserOptions) {
|
|
|
8575
10318
|
};
|
|
8576
10319
|
res.end = (chunk, ...args) => {
|
|
8577
10320
|
if (chunk) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
8578
|
-
|
|
10321
|
+
const body = normalizeVinextRscPreloadHints(Buffer.concat(chunks).toString());
|
|
10322
|
+
return end(body, ...args);
|
|
8579
10323
|
};
|
|
8580
10324
|
next();
|
|
8581
10325
|
});
|