@module-federation/vite 1.22.1 → 1.23.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 +19 -0
- package/lib/{dtsConstants-dDsHZFC1.js → dtsConstants-Bs4FukGL.js} +231 -89
- package/lib/index.d.ts +14 -1
- package/lib/index.js +1145 -664
- package/lib/logger--uKHOVjR.js +366 -0
- package/lib/{pluginDts-CQ088qGF.js → pluginDts-DxgS2FEd.js} +2 -2
- package/lib/{sharedKeyMatcher-BRzBCbuR.js → sharedKeyMatcher-Od_nYxJA.js} +39 -10
- package/lib/{ssrEntryLoader-BUXUQi0P.js → ssrEntryLoader-DmqLXUmm.js} +206 -49
- package/lib/{ssrVmStrategy-Ud06y3Xf.js → ssrVmStrategy-B_e3yqa2.js} +75 -6
- package/lib/utils/ssrEntryLoader.js +1 -1
- package/package.json +4 -4
- package/lib/buildPaths-BoaQTkxt.js +0 -66
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { _ as
|
|
2
|
-
import {
|
|
3
|
-
import { _ as
|
|
1
|
+
import { _ as resolvePublicPath, a as matchesSharedSource, c as filterId, d as getNodeModulesSuffix, f as isAssetLikeImport, g as normalizeNodeModulePath, h as isViteOptimizableEntry, i as invalidateSharedKeyMatcher, l as getBasePath$1, m as isNuxtClientBase, n as getSharedRequest, p as isNodeModulePath, r as getSharedRuntimeKey, s as ensureTrailingSlash, t as findSharedKey, u as getCommonSharedSubpaths, v as stripQueryAndHash, y as stripViteFsPrefix } from "./sharedKeyMatcher-Od_nYxJA.js";
|
|
2
|
+
import { a as CodeRewriter, c as normalizePathForImport, i as createCodePositionMap, l as rebaseImport, o as createSourceMap, r as mfWarn, t as createModuleFederationError, u as resolveHashPlaceholderFileName } from "./logger--uKHOVjR.js";
|
|
3
|
+
import { C as isReactCoreShare, S as REACT_DOM_CLIENT_SHARE, _ as resolveModulePath, a as getIsRolldown, b as supportsCodeSplittingGroupDebugName, c as getPackageNameFromNodeModulePath, d as isNuxtProjectRoot, f as isPackageExportAvailable, g as resolveImportPath, h as packageNameEncode, i as getInstalledPackageJson, l as getSharedCacheDescriptor, m as packageNameDecode, n as getDependencyNames, o as getPackageDetectionCwd, p as isPackageInstalled, r as getInstalledPackageEntry, s as getPackageName, u as hasPackageDependency, v as setPackageDetectionCwd, x as REACT_CLIENT_INTERNALS_KEY, y as sharedCacheHelperCode } from "./dtsConstants-Bs4FukGL.js";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import * as fs$2 from "fs";
|
|
6
6
|
import { existsSync, readFileSync, readdirSync, realpathSync, statSync, writeFileSync } from "fs";
|
|
@@ -8,6 +8,7 @@ import { createRequire as createRequire$1, isBuiltin } from "module";
|
|
|
8
8
|
import * as path$1 from "node:path";
|
|
9
9
|
import path, { basename } from "node:path";
|
|
10
10
|
import { fileURLToPath, pathToFileURL } from "url";
|
|
11
|
+
import * as vite from "vite";
|
|
11
12
|
import { parseAst, version } from "vite";
|
|
12
13
|
import { createHash } from "node:crypto";
|
|
13
14
|
import * as fs$1 from "node:fs";
|
|
@@ -235,134 +236,6 @@ function findRemoteEntryFile(filename, bundle) {
|
|
|
235
236
|
return fallback;
|
|
236
237
|
}
|
|
237
238
|
//#endregion
|
|
238
|
-
//#region src/utils/codeRewriter.ts
|
|
239
|
-
const BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
240
|
-
var CodeRewriter = class {
|
|
241
|
-
original;
|
|
242
|
-
replacements = [];
|
|
243
|
-
constructor(original) {
|
|
244
|
-
this.original = original;
|
|
245
|
-
}
|
|
246
|
-
overwrite(start, end, content) {
|
|
247
|
-
if (start < 0 || end < start || end > this.original.length) throw new Error(`Invalid overwrite range: ${start}-${end}`);
|
|
248
|
-
this.replacements.push({
|
|
249
|
-
start,
|
|
250
|
-
end,
|
|
251
|
-
content
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
toString() {
|
|
255
|
-
return applyReplacements(this.original, this.getSortedReplacements()).code;
|
|
256
|
-
}
|
|
257
|
-
generateMap(source = "") {
|
|
258
|
-
const { code, replacements } = applyReplacements(this.original, this.getSortedReplacements());
|
|
259
|
-
return {
|
|
260
|
-
version: 3,
|
|
261
|
-
sources: [source],
|
|
262
|
-
sourcesContent: [this.original],
|
|
263
|
-
names: [],
|
|
264
|
-
mappings: generateLineMappings(code, this.original, replacements)
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
getSortedReplacements() {
|
|
268
|
-
return [...this.replacements].sort((a, b) => a.start - b.start || a.end - b.end);
|
|
269
|
-
}
|
|
270
|
-
};
|
|
271
|
-
function createSourceMap(code, source = "") {
|
|
272
|
-
return {
|
|
273
|
-
version: 3,
|
|
274
|
-
sources: [source],
|
|
275
|
-
sourcesContent: [code],
|
|
276
|
-
names: [],
|
|
277
|
-
mappings: generateLineMappings(code, code, [])
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
function applyReplacements(original, replacements) {
|
|
281
|
-
let code = "";
|
|
282
|
-
let cursor = 0;
|
|
283
|
-
let delta = 0;
|
|
284
|
-
const applied = [];
|
|
285
|
-
for (const replacement of replacements) {
|
|
286
|
-
if (replacement.start < cursor) throw new Error("Overlapping overwrite ranges are not supported");
|
|
287
|
-
code += original.slice(cursor, replacement.start);
|
|
288
|
-
const generatedStart = replacement.start + delta;
|
|
289
|
-
code += replacement.content;
|
|
290
|
-
const generatedEnd = generatedStart + replacement.content.length;
|
|
291
|
-
applied.push({
|
|
292
|
-
...replacement,
|
|
293
|
-
generatedStart,
|
|
294
|
-
generatedEnd
|
|
295
|
-
});
|
|
296
|
-
cursor = replacement.end;
|
|
297
|
-
delta += replacement.content.length - (replacement.end - replacement.start);
|
|
298
|
-
}
|
|
299
|
-
code += original.slice(cursor);
|
|
300
|
-
return {
|
|
301
|
-
code,
|
|
302
|
-
replacements: applied
|
|
303
|
-
};
|
|
304
|
-
}
|
|
305
|
-
function generateLineMappings(generated, original, replacements) {
|
|
306
|
-
const generatedLineStarts = getLineStarts(generated);
|
|
307
|
-
const originalLineStarts = getLineStarts(original);
|
|
308
|
-
let previousOriginalLine = 0;
|
|
309
|
-
let previousOriginalColumn = 0;
|
|
310
|
-
let mappings = "";
|
|
311
|
-
generatedLineStarts.forEach((generatedOffset, lineIndex) => {
|
|
312
|
-
if (lineIndex > 0) mappings += ";";
|
|
313
|
-
const originalOffset = generatedOffsetToOriginalOffset(generatedOffset, replacements);
|
|
314
|
-
const originalLine = findLine(originalLineStarts, originalOffset);
|
|
315
|
-
const originalColumn = originalOffset - originalLineStarts[originalLine];
|
|
316
|
-
mappings += encodeSegment([
|
|
317
|
-
0,
|
|
318
|
-
0,
|
|
319
|
-
originalLine - previousOriginalLine,
|
|
320
|
-
originalColumn - previousOriginalColumn
|
|
321
|
-
]);
|
|
322
|
-
previousOriginalLine = originalLine;
|
|
323
|
-
previousOriginalColumn = originalColumn;
|
|
324
|
-
});
|
|
325
|
-
return mappings;
|
|
326
|
-
}
|
|
327
|
-
function generatedOffsetToOriginalOffset(offset, replacements) {
|
|
328
|
-
let delta = 0;
|
|
329
|
-
for (const replacement of replacements) {
|
|
330
|
-
if (offset < replacement.generatedStart) break;
|
|
331
|
-
if (offset < replacement.generatedEnd) return replacement.start;
|
|
332
|
-
delta += replacement.content.length - (replacement.end - replacement.start);
|
|
333
|
-
}
|
|
334
|
-
return offset - delta;
|
|
335
|
-
}
|
|
336
|
-
function getLineStarts(code) {
|
|
337
|
-
const starts = [0];
|
|
338
|
-
for (let i = 0; i < code.length; i++) if (code.charCodeAt(i) === 10) starts.push(i + 1);
|
|
339
|
-
return starts;
|
|
340
|
-
}
|
|
341
|
-
function findLine(lineStarts, offset) {
|
|
342
|
-
let low = 0;
|
|
343
|
-
let high = lineStarts.length - 1;
|
|
344
|
-
while (low <= high) {
|
|
345
|
-
const mid = low + high >> 1;
|
|
346
|
-
if (lineStarts[mid] <= offset) low = mid + 1;
|
|
347
|
-
else high = mid - 1;
|
|
348
|
-
}
|
|
349
|
-
return Math.max(0, high);
|
|
350
|
-
}
|
|
351
|
-
function encodeSegment(values) {
|
|
352
|
-
return values.map(encodeVlq).join("");
|
|
353
|
-
}
|
|
354
|
-
function encodeVlq(value) {
|
|
355
|
-
let vlq = value < 0 ? (-value << 1) + 1 : value << 1;
|
|
356
|
-
let encoded = "";
|
|
357
|
-
do {
|
|
358
|
-
let digit = vlq & 31;
|
|
359
|
-
vlq >>>= 5;
|
|
360
|
-
if (vlq > 0) digit |= 32;
|
|
361
|
-
encoded += BASE64_CHARS[digit];
|
|
362
|
-
} while (vlq > 0);
|
|
363
|
-
return encoded;
|
|
364
|
-
}
|
|
365
|
-
//#endregion
|
|
366
239
|
//#region src/utils/mapCodeToCodeWithSourcemap.ts
|
|
367
240
|
async function mapCodeToCodeWithSourcemap(code) {
|
|
368
241
|
const resolvedCode = await code;
|
|
@@ -400,152 +273,21 @@ function resolveEnvironmentConsumerTarget(ctx) {
|
|
|
400
273
|
function isClientEnvironment(ctx) {
|
|
401
274
|
return resolveEnvironmentConsumerTarget(ctx) !== "server";
|
|
402
275
|
}
|
|
276
|
+
/**
|
|
277
|
+
* Whether a build hook runs for a server graph. Vite 6+ hooks carry an
|
|
278
|
+
* environment; Vite 5 (and hooks invoked before `configResolved`) fall back to
|
|
279
|
+
* the legacy root `build.ssr` flag.
|
|
280
|
+
*/
|
|
281
|
+
function isServerBuildContext(ctx, config) {
|
|
282
|
+
const target = resolveEnvironmentConsumerTarget(ctx);
|
|
283
|
+
if (target) return target === "server";
|
|
284
|
+
return Boolean(config?.build?.ssr);
|
|
285
|
+
}
|
|
403
286
|
function resolveRemoteConsumer(ctx, hasMultiEnvironment) {
|
|
404
287
|
if (!hasMultiEnvironment) return "unified";
|
|
405
288
|
return resolveEnvironmentConsumerTarget(ctx) ?? "client";
|
|
406
289
|
}
|
|
407
290
|
//#endregion
|
|
408
|
-
//#region src/utils/codePositionMap.ts
|
|
409
|
-
const REGEX_PREFIX_KEYWORDS = /* @__PURE__ */ new Set([
|
|
410
|
-
"await",
|
|
411
|
-
"case",
|
|
412
|
-
"delete",
|
|
413
|
-
"in",
|
|
414
|
-
"instanceof",
|
|
415
|
-
"new",
|
|
416
|
-
"return",
|
|
417
|
-
"throw",
|
|
418
|
-
"typeof",
|
|
419
|
-
"void",
|
|
420
|
-
"yield"
|
|
421
|
-
]);
|
|
422
|
-
function isJsxClosingTagSlash(code, slashIndex) {
|
|
423
|
-
if (code[slashIndex - 1] !== "<") return false;
|
|
424
|
-
let cursor = slashIndex + 1;
|
|
425
|
-
while (/\s/.test(code[cursor] || "")) cursor++;
|
|
426
|
-
if (code[cursor] === ">") return true;
|
|
427
|
-
const tagStart = cursor;
|
|
428
|
-
while (/[-:.$_\u200C\u200D\p{ID_Continue}]/u.test(code[cursor] || "")) cursor++;
|
|
429
|
-
if (cursor === tagStart) return false;
|
|
430
|
-
while (/\s/.test(code[cursor] || "")) cursor++;
|
|
431
|
-
return code[cursor] === ">";
|
|
432
|
-
}
|
|
433
|
-
/** Mark comments, string/template literals, and regular expressions as non-code. */
|
|
434
|
-
function createCodePositionMap(code, onComment) {
|
|
435
|
-
const positions = Array(code.length).fill(true);
|
|
436
|
-
const mask = (start, end) => {
|
|
437
|
-
for (let index = start; index < end; index++) positions[index] = false;
|
|
438
|
-
};
|
|
439
|
-
let canStartRegex = true;
|
|
440
|
-
for (let index = 0; index < code.length;) {
|
|
441
|
-
const char = code[index];
|
|
442
|
-
const next = code[index + 1];
|
|
443
|
-
if (/\s/.test(char)) {
|
|
444
|
-
index++;
|
|
445
|
-
continue;
|
|
446
|
-
}
|
|
447
|
-
if (char === "/" && next === "/") {
|
|
448
|
-
const start = index;
|
|
449
|
-
index += 2;
|
|
450
|
-
while (index < code.length && code[index] !== "\n" && code[index] !== "\r") index++;
|
|
451
|
-
mask(start, index);
|
|
452
|
-
onComment?.(start, index);
|
|
453
|
-
continue;
|
|
454
|
-
}
|
|
455
|
-
if (char === "/" && next === "*") {
|
|
456
|
-
const start = index;
|
|
457
|
-
index += 2;
|
|
458
|
-
while (index < code.length && !(code[index] === "*" && code[index + 1] === "/")) index++;
|
|
459
|
-
index = Math.min(code.length, index + 2);
|
|
460
|
-
mask(start, index);
|
|
461
|
-
onComment?.(start, index);
|
|
462
|
-
continue;
|
|
463
|
-
}
|
|
464
|
-
if (char === "\"" || char === "'" || char === "`") {
|
|
465
|
-
const quote = char;
|
|
466
|
-
const start = index++;
|
|
467
|
-
while (index < code.length) {
|
|
468
|
-
if (code[index] === "\\") {
|
|
469
|
-
index += 2;
|
|
470
|
-
continue;
|
|
471
|
-
}
|
|
472
|
-
if (code[index] === quote) {
|
|
473
|
-
index++;
|
|
474
|
-
break;
|
|
475
|
-
}
|
|
476
|
-
index++;
|
|
477
|
-
}
|
|
478
|
-
mask(start, index);
|
|
479
|
-
canStartRegex = false;
|
|
480
|
-
continue;
|
|
481
|
-
}
|
|
482
|
-
const closesJsxTag = isJsxClosingTagSlash(code, index);
|
|
483
|
-
if (char === "/" && canStartRegex && !closesJsxTag) {
|
|
484
|
-
const start = index;
|
|
485
|
-
let cursor = index + 1;
|
|
486
|
-
let escaped = false;
|
|
487
|
-
let inCharacterClass = false;
|
|
488
|
-
let closed = false;
|
|
489
|
-
for (; cursor < code.length; cursor++) {
|
|
490
|
-
const regexChar = code[cursor];
|
|
491
|
-
if (regexChar === "\n" || regexChar === "\r") break;
|
|
492
|
-
if (escaped) {
|
|
493
|
-
escaped = false;
|
|
494
|
-
continue;
|
|
495
|
-
}
|
|
496
|
-
if (regexChar === "\\") {
|
|
497
|
-
escaped = true;
|
|
498
|
-
continue;
|
|
499
|
-
}
|
|
500
|
-
if (regexChar === "[") {
|
|
501
|
-
inCharacterClass = true;
|
|
502
|
-
continue;
|
|
503
|
-
}
|
|
504
|
-
if (regexChar === "]" && inCharacterClass) {
|
|
505
|
-
inCharacterClass = false;
|
|
506
|
-
continue;
|
|
507
|
-
}
|
|
508
|
-
if (regexChar === "/" && !inCharacterClass) {
|
|
509
|
-
cursor++;
|
|
510
|
-
while (/[$_\p{ID_Continue}]/u.test(code[cursor] || "")) cursor++;
|
|
511
|
-
closed = true;
|
|
512
|
-
break;
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
if (closed) {
|
|
516
|
-
mask(start, cursor);
|
|
517
|
-
index = cursor;
|
|
518
|
-
canStartRegex = false;
|
|
519
|
-
continue;
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
if (/[$_\p{ID_Start}]/u.test(char)) {
|
|
523
|
-
const start = index++;
|
|
524
|
-
while (/[$_\u200C\u200D\p{ID_Continue}]/u.test(code[index] || "")) index++;
|
|
525
|
-
canStartRegex = REGEX_PREFIX_KEYWORDS.has(code.slice(start, index));
|
|
526
|
-
continue;
|
|
527
|
-
}
|
|
528
|
-
if (/\d/.test(char)) {
|
|
529
|
-
index++;
|
|
530
|
-
while (/[\w.]/.test(code[index] || "")) index++;
|
|
531
|
-
canStartRegex = false;
|
|
532
|
-
continue;
|
|
533
|
-
}
|
|
534
|
-
if ((char === "+" || char === "-") && next === char) {
|
|
535
|
-
index += 2;
|
|
536
|
-
continue;
|
|
537
|
-
}
|
|
538
|
-
if (char === "!" && next !== "=") {
|
|
539
|
-
index++;
|
|
540
|
-
continue;
|
|
541
|
-
}
|
|
542
|
-
if (char === ")" || char === "]" || char === "}") canStartRegex = false;
|
|
543
|
-
else if (char !== ".") canStartRegex = true;
|
|
544
|
-
index++;
|
|
545
|
-
}
|
|
546
|
-
return positions;
|
|
547
|
-
}
|
|
548
|
-
//#endregion
|
|
549
291
|
//#region src/utils/htmlEntryUtils.ts
|
|
550
292
|
const IDENTIFIER = String.raw`[$_\p{ID_Start}][$_\u200C\u200D\p{ID_Continue}]*`;
|
|
551
293
|
const NAMED_SPECIFIERS = String.raw`\{[^{}]*\}`;
|
|
@@ -711,18 +453,18 @@ function normalizeExposes(exposes) {
|
|
|
711
453
|
});
|
|
712
454
|
return res;
|
|
713
455
|
}
|
|
714
|
-
function normalizeRemotes(remotes) {
|
|
456
|
+
function normalizeRemotes(remotes, defaultShareScope = "default") {
|
|
715
457
|
if (!remotes) return {};
|
|
716
458
|
const result = {};
|
|
717
459
|
if (typeof remotes === "object") Object.keys(remotes).forEach((key) => {
|
|
718
|
-
result[key] = normalizeRemoteItem(key, remotes[key]);
|
|
460
|
+
result[key] = normalizeRemoteItem(key, remotes[key], defaultShareScope);
|
|
719
461
|
});
|
|
720
462
|
return result;
|
|
721
463
|
}
|
|
722
464
|
function warnOmittedObjectRemoteType(remoteKey) {
|
|
723
465
|
mfWarn(`Remote "${remoteKey}" omits type and defaults to 'var'. Set type: 'module' for Vite ESM remotes, or type: 'var' explicitly to silence this warning.`);
|
|
724
466
|
}
|
|
725
|
-
function normalizeRemoteItem(key, remote) {
|
|
467
|
+
function normalizeRemoteItem(key, remote, defaultShareScope) {
|
|
726
468
|
warnOnReservedInternalNamePrefix(key, "remoteAlias");
|
|
727
469
|
if (typeof remote === "string") {
|
|
728
470
|
const separatorIndex = remote.startsWith("@") ? remote.indexOf("@", 1) : remote.indexOf("@");
|
|
@@ -741,7 +483,7 @@ function normalizeRemoteItem(key, remote) {
|
|
|
741
483
|
internalName: toInternalModuleFederationName(key),
|
|
742
484
|
entry,
|
|
743
485
|
entryGlobalName,
|
|
744
|
-
shareScope:
|
|
486
|
+
shareScope: defaultShareScope
|
|
745
487
|
};
|
|
746
488
|
}
|
|
747
489
|
const typeOmitted = remote.type === void 0 || remote.type === null || remote.type === "";
|
|
@@ -750,7 +492,7 @@ function normalizeRemoteItem(key, remote) {
|
|
|
750
492
|
type: "var",
|
|
751
493
|
name: key,
|
|
752
494
|
internalName: toInternalModuleFederationName(key),
|
|
753
|
-
shareScope:
|
|
495
|
+
shareScope: defaultShareScope,
|
|
754
496
|
entryGlobalName: key
|
|
755
497
|
}, {
|
|
756
498
|
...remote,
|
|
@@ -858,10 +600,15 @@ function resolveSharedVersions(shared, root) {
|
|
|
858
600
|
item.shareConfig.requiredVersion = requiredVersion;
|
|
859
601
|
}
|
|
860
602
|
}
|
|
861
|
-
function normalizeShareItem(key, shareItem) {
|
|
603
|
+
function normalizeShareItem(key, shareItem, defaultShareScope) {
|
|
862
604
|
const treeShaking = typeof shareItem === "object" ? shareItem.treeShaking : void 0;
|
|
863
605
|
if (treeShaking && treeShaking.mode !== "server-calc" && treeShaking.mode !== "runtime-infer") throw createModuleFederationError(`Invalid shared config for "${key}": treeShaking.mode must be either "server-calc" or "runtime-infer".`);
|
|
864
606
|
if (treeShaking && typeof shareItem === "object" && shareItem.eager) throw createModuleFederationError(`Invalid shared config for "${key}": cannot use both "eager: true" and "treeShaking.mode" simultaneously. Choose one strategy.`);
|
|
607
|
+
if (typeof shareItem === "object") {
|
|
608
|
+
const request = typeof shareItem.request === "string" ? shareItem.request : key;
|
|
609
|
+
const shareKey = typeof shareItem.shareKey === "string" ? shareItem.shareKey : key;
|
|
610
|
+
if (request.endsWith("/") !== shareKey.endsWith("/")) throw createModuleFederationError(`Invalid shared config for "${key}": "request" and "shareKey" must both end with "/" for a prefix share, or neither. Got request "${request}" and shareKey "${shareKey}".`);
|
|
611
|
+
}
|
|
865
612
|
if (treeShaking?.mode === "runtime-infer" && typeof shareItem === "object" && shareItem.singleton) mfWarn(`Shared singleton "${key}" uses runtime-infer tree shaking, which may load both a tree-shaken bundle and a full bundle when consumers require different exports. Prefer server-calc for singleton dependencies. If runtime-infer is required, expand usedExports to reduce this risk.`);
|
|
866
613
|
const config = typeof shareItem === "object" ? shareItem : {};
|
|
867
614
|
const { version, requiredVersion } = resolveSharedVersion(key, config, getPackageDetectionCwd());
|
|
@@ -869,7 +616,7 @@ function normalizeShareItem(key, shareItem) {
|
|
|
869
616
|
const result = {
|
|
870
617
|
name: shareItem,
|
|
871
618
|
version,
|
|
872
|
-
scope:
|
|
619
|
+
scope: defaultShareScope,
|
|
873
620
|
from: "",
|
|
874
621
|
shareConfig: {
|
|
875
622
|
import: void 0,
|
|
@@ -885,13 +632,16 @@ function normalizeShareItem(key, shareItem) {
|
|
|
885
632
|
name: key,
|
|
886
633
|
from: "",
|
|
887
634
|
version,
|
|
888
|
-
scope: shareItem.shareScope ||
|
|
635
|
+
scope: shareItem.shareScope || defaultShareScope,
|
|
889
636
|
shareConfig: {
|
|
890
637
|
import: shareItem.import,
|
|
891
638
|
singleton: shareItem.singleton || false,
|
|
892
639
|
eager: shareItem.eager || false,
|
|
893
640
|
requiredVersion,
|
|
894
641
|
strictVersion: !!shareItem.strictVersion,
|
|
642
|
+
...shareItem.request !== void 0 ? { request: shareItem.request } : {},
|
|
643
|
+
...shareItem.shareKey !== void 0 ? { shareKey: shareItem.shareKey } : {},
|
|
644
|
+
...shareItem.allowNodeModulesSuffixMatch !== void 0 ? { allowNodeModulesSuffixMatch: shareItem.allowNodeModulesSuffixMatch } : {},
|
|
895
645
|
...shareItem.suppressMissingImportWarning ? { suppressMissingImportWarning: true } : {},
|
|
896
646
|
...treeShaking ? { treeShaking: { ...treeShaking } } : {}
|
|
897
647
|
}
|
|
@@ -921,7 +671,7 @@ function normalizeSharedKey(key) {
|
|
|
921
671
|
if (baseKey === "react") return key;
|
|
922
672
|
return getCommonSharedSubpaths(baseKey).length > 0 ? baseKey : key;
|
|
923
673
|
}
|
|
924
|
-
function normalizeShared(shared) {
|
|
674
|
+
function normalizeShared(shared, defaultShareScope = "default") {
|
|
925
675
|
explicitSharedKeys = /* @__PURE__ */ new Set();
|
|
926
676
|
if (!shared) return {};
|
|
927
677
|
const result = {};
|
|
@@ -930,7 +680,7 @@ function normalizeShared(shared) {
|
|
|
930
680
|
if (isModuleFederationRuntimePackage(key)) return;
|
|
931
681
|
const normalizedKey = normalizeSharedKey(key);
|
|
932
682
|
const hadConfiguredPackageSubpath = (result[normalizedKey]?.shareConfig)?.__mfConfiguredPackageSubpath === true;
|
|
933
|
-
result[normalizedKey] = normalizeShareItem(normalizedKey, normalizedKey);
|
|
683
|
+
result[normalizedKey] = normalizeShareItem(normalizedKey, normalizedKey, defaultShareScope);
|
|
934
684
|
if (key.endsWith("/") || hadConfiguredPackageSubpath) result[normalizedKey].shareConfig.__mfConfiguredPackageSubpath = true;
|
|
935
685
|
explicitSharedKeys.add(normalizedKey);
|
|
936
686
|
sourceEntries.push([normalizedKey, normalizedKey]);
|
|
@@ -940,15 +690,16 @@ function normalizeShared(shared) {
|
|
|
940
690
|
const normalizedKey = normalizeSharedKey(key);
|
|
941
691
|
const value = shared[key];
|
|
942
692
|
const hadConfiguredPackageSubpath = (result[normalizedKey]?.shareConfig)?.__mfConfiguredPackageSubpath === true;
|
|
943
|
-
result[normalizedKey] = normalizeShareItem(normalizedKey, value);
|
|
944
|
-
|
|
693
|
+
result[normalizedKey] = normalizeShareItem(normalizedKey, value, defaultShareScope);
|
|
694
|
+
const requestIsPrefix = typeof value?.request === "string" && value.request.endsWith("/");
|
|
695
|
+
if (key.endsWith("/") || requestIsPrefix || hadConfiguredPackageSubpath) result[normalizedKey].shareConfig.__mfConfiguredPackageSubpath = true;
|
|
945
696
|
explicitSharedKeys.add(normalizedKey);
|
|
946
697
|
sourceEntries.push([normalizedKey, value]);
|
|
947
698
|
});
|
|
948
699
|
sourceEntries.forEach(([key, value]) => {
|
|
949
700
|
for (const subpathShare of getLitExportSubpathShares(key)) {
|
|
950
701
|
if (result[subpathShare]) continue;
|
|
951
|
-
result[subpathShare] = normalizeShareItem(subpathShare, value);
|
|
702
|
+
result[subpathShare] = normalizeShareItem(subpathShare, value, defaultShareScope);
|
|
952
703
|
}
|
|
953
704
|
});
|
|
954
705
|
return result;
|
|
@@ -1018,21 +769,28 @@ function isExplicitSharedKey(key, options) {
|
|
|
1018
769
|
}
|
|
1019
770
|
function getNormalizeShareItem(key, options = getNormalizeModuleFederationOptions()) {
|
|
1020
771
|
const matchedKey = findSharedKey(key, options.shared);
|
|
1021
|
-
|
|
772
|
+
const shareItem = options.shared[key] || (matchedKey ? options.shared[matchedKey] : void 0) || options.shared[getPackageName(key)] || options.shared[getPackageName(key) + "/"];
|
|
773
|
+
if (shareItem) return shareItem;
|
|
774
|
+
return Object.entries(options.shared).find(([sharedKey, item]) => {
|
|
775
|
+
const runtimeKey = typeof item.shareConfig.shareKey === "string" ? item.shareConfig.shareKey : sharedKey;
|
|
776
|
+
return runtimeKey.endsWith("/") ? key === runtimeKey.slice(0, -1) || key.startsWith(runtimeKey) : runtimeKey === key;
|
|
777
|
+
})?.[1];
|
|
1022
778
|
}
|
|
1023
779
|
function normalizeModuleFederationOptions(options) {
|
|
1024
780
|
warnOnReservedInternalNamePrefix(options.name, "containerName");
|
|
1025
781
|
if (options.virtualModuleDir && options.virtualModuleDir.includes("/")) throw createModuleFederationError(`Invalid virtualModuleDir: "${options.virtualModuleDir}". The virtualModuleDir option cannot contain slashes (/). Please use a single directory name like '__mf__virtual__your_app_name'.`);
|
|
782
|
+
const defaultShareScope = typeof options.shareScope === "string" ? options.shareScope : "default";
|
|
1026
783
|
const normalized = {
|
|
1027
784
|
exposes: normalizeExposes(options.exposes),
|
|
1028
785
|
filename: options.filename || "remoteEntry-[hash]",
|
|
786
|
+
ssrFilename: options.ssrFilename || void 0,
|
|
1029
787
|
internalName: toInternalModuleFederationName(options.name),
|
|
1030
788
|
library: normalizeLibrary(options.library),
|
|
1031
789
|
name: options.name,
|
|
1032
|
-
remotes: normalizeRemotes(options.remotes),
|
|
790
|
+
remotes: normalizeRemotes(options.remotes, defaultShareScope),
|
|
1033
791
|
runtime: options.runtime,
|
|
1034
792
|
shareScope: options.shareScope || "default",
|
|
1035
|
-
shared: normalizeShared(options.shared),
|
|
793
|
+
shared: normalizeShared(options.shared, defaultShareScope),
|
|
1036
794
|
runtimePlugins: options.runtimePlugins || [],
|
|
1037
795
|
implementation: normalizePathForImport(options.implementation || resolveRuntimeImplementation()),
|
|
1038
796
|
manifest: normalizeManifest(options.manifest),
|
|
@@ -1131,6 +889,10 @@ var VirtualModule = class VirtualModule {
|
|
|
1131
889
|
if (!cacheMap[this.tag]) cacheMap[this.tag] = {};
|
|
1132
890
|
cacheMap[this.tag][this.name] = this;
|
|
1133
891
|
}
|
|
892
|
+
/** The federation scope this module was created under, if it was scoped. */
|
|
893
|
+
getScopeName() {
|
|
894
|
+
return this.scopeName;
|
|
895
|
+
}
|
|
1134
896
|
getImportId() {
|
|
1135
897
|
const mfName = this.scopeName ?? getNormalizeModuleFederationOptions().internalName;
|
|
1136
898
|
const importIdKey = `${mfName}${this.tag}${this.name}${this.tag}`;
|
|
@@ -1162,17 +924,38 @@ const SERVER_ENV_GUARD = "import.meta.env.SSR";
|
|
|
1162
924
|
const SSR_ENTRY_LOADER_SPECIFIER = "@module-federation/vite/ssrEntryLoader";
|
|
1163
925
|
const SSR_ONLY_RUNTIME_PLUGINS = /* @__PURE__ */ new Set([SSR_ENTRY_LOADER_SPECIFIER]);
|
|
1164
926
|
/**
|
|
927
|
+
* Whether a Vite environment builds a server graph.
|
|
928
|
+
*
|
|
929
|
+
* Vite 6+ sets `consumer` on the environment config; `build.ssr` covers the
|
|
930
|
+
* legacy `vite build --ssr` flag. Environment names are user-defined, so `ssr`
|
|
931
|
+
* and `server` are only a fallback for configs that carry neither field.
|
|
932
|
+
*/
|
|
933
|
+
function isServerEnvironment(name, config) {
|
|
934
|
+
return config?.consumer === "server" || Boolean(config?.build?.ssr) || name === "ssr" || name === "server";
|
|
935
|
+
}
|
|
936
|
+
/**
|
|
937
|
+
* Whether a resolved Vite config includes a server graph: the legacy
|
|
938
|
+
* `build.ssr` flag, or any server environment. Vite always registers an `ssr`
|
|
939
|
+
* environment for `serve`, so this only gates builds.
|
|
940
|
+
*/
|
|
941
|
+
function isSsrConfig(config) {
|
|
942
|
+
if (Boolean(config.build?.ssr)) return true;
|
|
943
|
+
return Object.entries(config.environments ?? {}).some(([name, environment]) => isServerEnvironment(name, environment));
|
|
944
|
+
}
|
|
945
|
+
/**
|
|
1165
946
|
* Single source of truth for SSR-related feature gates.
|
|
1166
947
|
*
|
|
1167
|
-
* - Vite 8+
|
|
1168
|
-
*
|
|
948
|
+
* - Vite 8+ server environments: ModuleRunner + FetchableDevEnvironment for
|
|
949
|
+
* `/__mf_ssr__/` entries.
|
|
950
|
+
* - SSR builds on any Vite major: HTTP fetch + temp-file import via
|
|
951
|
+
* ssrEntryLoader.
|
|
1169
952
|
*/
|
|
1170
|
-
function getSsrCapabilities(viteMajor, command, hasRemotes) {
|
|
953
|
+
function getSsrCapabilities(viteMajor, command, hasRemotes, isSsr = false) {
|
|
1171
954
|
if (!hasRemotes) return {
|
|
1172
955
|
enableSsrInitBootstrap: false,
|
|
1173
956
|
injectSsrEntryLoader: false
|
|
1174
957
|
};
|
|
1175
|
-
const supported = command === "build" || command === "serve" && viteMajor >= 8;
|
|
958
|
+
const supported = isSsr && (command === "build" || command === "serve" && viteMajor >= 8);
|
|
1176
959
|
return {
|
|
1177
960
|
enableSsrInitBootstrap: supported,
|
|
1178
961
|
injectSsrEntryLoader: supported
|
|
@@ -1276,106 +1059,48 @@ function isParsableExpression(source) {
|
|
|
1276
1059
|
}
|
|
1277
1060
|
}
|
|
1278
1061
|
//#endregion
|
|
1279
|
-
//#region src/utils/
|
|
1280
|
-
function
|
|
1281
|
-
return
|
|
1062
|
+
//#region src/utils/runtimePluginSpecifier.ts
|
|
1063
|
+
function getRuntimePluginSpecifier(plugin) {
|
|
1064
|
+
return typeof plugin === "string" ? plugin : plugin[0];
|
|
1282
1065
|
}
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
const treeShakingStates = /* @__PURE__ */ new WeakMap();
|
|
1288
|
-
function getTreeShakingState(options) {
|
|
1289
|
-
if (!options) return legacyTreeShakingState;
|
|
1290
|
-
let state = treeShakingStates.get(options);
|
|
1291
|
-
if (!state) {
|
|
1292
|
-
state = {
|
|
1293
|
-
inferredUsage: /* @__PURE__ */ new Map(),
|
|
1294
|
-
buildMode: false
|
|
1295
|
-
};
|
|
1296
|
-
treeShakingStates.set(options, state);
|
|
1297
|
-
}
|
|
1298
|
-
return state;
|
|
1299
|
-
}
|
|
1300
|
-
function setTreeShakingBuildMode(enabled, options) {
|
|
1301
|
-
getTreeShakingState(options).buildMode = enabled;
|
|
1302
|
-
}
|
|
1303
|
-
function resetTreeShakingExports(options) {
|
|
1304
|
-
getTreeShakingState(options).inferredUsage.clear();
|
|
1305
|
-
}
|
|
1306
|
-
function getOrCreateExportRecord(sharedKey, request, options) {
|
|
1307
|
-
const inferredUsage = getTreeShakingState(options).inferredUsage;
|
|
1308
|
-
let byRequest = inferredUsage.get(sharedKey);
|
|
1309
|
-
if (!byRequest) {
|
|
1310
|
-
byRequest = /* @__PURE__ */ new Map();
|
|
1311
|
-
inferredUsage.set(sharedKey, byRequest);
|
|
1312
|
-
}
|
|
1313
|
-
let record = byRequest.get(request);
|
|
1314
|
-
if (!record) {
|
|
1315
|
-
record = {
|
|
1316
|
-
requiresFullBundle: false,
|
|
1317
|
-
usedExports: /* @__PURE__ */ new Set()
|
|
1318
|
-
};
|
|
1319
|
-
byRequest.set(request, record);
|
|
1320
|
-
}
|
|
1321
|
-
return record;
|
|
1322
|
-
}
|
|
1323
|
-
function recordTreeShakingExports(sharedKey, exports, request = sharedKey, options) {
|
|
1324
|
-
const record = getOrCreateExportRecord(sharedKey, request, options);
|
|
1325
|
-
exports.forEach((name) => record.usedExports.add(name));
|
|
1326
|
-
}
|
|
1327
|
-
function markTreeShakingPackageUnsafe(sharedKey, request = sharedKey, options) {
|
|
1328
|
-
getOrCreateExportRecord(sharedKey, request, options).requiresFullBundle = true;
|
|
1329
|
-
}
|
|
1330
|
-
function getExportRecords(sharedKey, request, options) {
|
|
1331
|
-
const inferredUsage = getTreeShakingState(options).inferredUsage;
|
|
1332
|
-
if (sharedKey) {
|
|
1333
|
-
const records = inferredUsage.get(sharedKey);
|
|
1334
|
-
const wildcard = records?.get("*");
|
|
1335
|
-
const exact = records?.get(request);
|
|
1336
|
-
return [wildcard, exact === wildcard ? void 0 : exact].filter((record) => !!record);
|
|
1337
|
-
}
|
|
1338
|
-
const records = [];
|
|
1339
|
-
inferredUsage.forEach((byRequest, configuredKey) => {
|
|
1340
|
-
const wildcard = byRequest.get("*");
|
|
1341
|
-
const exact = byRequest.get(request);
|
|
1342
|
-
const keyBase = configuredKey.endsWith("/") ? configuredKey.slice(0, -1) : configuredKey;
|
|
1343
|
-
const requestMatchesConfiguredKey = request === keyBase || request.startsWith(`${keyBase}/`);
|
|
1344
|
-
if (wildcard && requestMatchesConfiguredKey) records.push(wildcard);
|
|
1345
|
-
if (exact && exact !== wildcard) records.push(exact);
|
|
1346
|
-
});
|
|
1347
|
-
return records;
|
|
1066
|
+
/** Drop SSR-only plugins from a client graph; a server graph keeps them all. */
|
|
1067
|
+
function filterRuntimePluginsForTarget(runtimePlugins, ssrOnlySpecifiers, isServer) {
|
|
1068
|
+
if (isServer) return [...runtimePlugins];
|
|
1069
|
+
return runtimePlugins.filter((plugin) => !ssrOnlySpecifiers.has(getRuntimePluginSpecifier(plugin)));
|
|
1348
1070
|
}
|
|
1071
|
+
//#endregion
|
|
1072
|
+
//#region src/utils/importAnalysis.ts
|
|
1073
|
+
const analysisByBuild = /* @__PURE__ */ new WeakMap();
|
|
1349
1074
|
/**
|
|
1350
|
-
*
|
|
1351
|
-
*
|
|
1352
|
-
*
|
|
1353
|
-
* fallback lookup across keys keeps aliases/backwards-compatible callers
|
|
1354
|
-
* working, while still keeping each concrete request's exports isolated.
|
|
1075
|
+
* Share source analysis within one build environment. Callers still resolve
|
|
1076
|
+
* requests and apply their own sharing configuration. Clear at buildStart and
|
|
1077
|
+
* buildEnd so watch rebuilds start fresh and completed builds release source.
|
|
1355
1078
|
*/
|
|
1356
|
-
function
|
|
1357
|
-
|
|
1358
|
-
if (!
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1079
|
+
function getImportAnalysis(build) {
|
|
1080
|
+
let analysis = analysisByBuild.get(build);
|
|
1081
|
+
if (!analysis) {
|
|
1082
|
+
const importsByCode = /* @__PURE__ */ new Map();
|
|
1083
|
+
analysis = {
|
|
1084
|
+
analyze(code) {
|
|
1085
|
+
const cached = importsByCode.get(code);
|
|
1086
|
+
if (cached !== void 0) return cached;
|
|
1087
|
+
const imports = analyzeImports(code);
|
|
1088
|
+
importsByCode.set(code, imports);
|
|
1089
|
+
return imports;
|
|
1090
|
+
},
|
|
1091
|
+
clear() {
|
|
1092
|
+
importsByCode.clear();
|
|
1093
|
+
}
|
|
1094
|
+
};
|
|
1095
|
+
analysisByBuild.set(build, analysis);
|
|
1096
|
+
}
|
|
1097
|
+
return analysis;
|
|
1372
1098
|
}
|
|
1373
|
-
function
|
|
1374
|
-
|
|
1375
|
-
return getSharedExportUsage(request, shareItem, sharedKey, options);
|
|
1099
|
+
function isRecord(value) {
|
|
1100
|
+
return value !== null && typeof value === "object";
|
|
1376
1101
|
}
|
|
1377
1102
|
function getModuleSource(node) {
|
|
1378
|
-
if (!node
|
|
1103
|
+
if (!isRecord(node)) return void 0;
|
|
1379
1104
|
const source = node;
|
|
1380
1105
|
if (source.type === "Literal" && typeof source.value === "string") return source.value;
|
|
1381
1106
|
if (source.type === "StringLiteral" && typeof source.value === "string") return source.value;
|
|
@@ -1383,11 +1108,13 @@ function getModuleSource(node) {
|
|
|
1383
1108
|
const expressions = Array.isArray(source.expressions) ? source.expressions : [];
|
|
1384
1109
|
const quasis = Array.isArray(source.quasis) ? source.quasis : [];
|
|
1385
1110
|
if (expressions.length > 0 || quasis.length !== 1) return void 0;
|
|
1386
|
-
const
|
|
1387
|
-
|
|
1111
|
+
const quasi = quasis[0];
|
|
1112
|
+
if (!isRecord(quasi) || !isRecord(quasi.value)) return void 0;
|
|
1113
|
+
const value = quasi.value;
|
|
1114
|
+
return typeof value.cooked === "string" ? value.cooked : typeof value.raw === "string" ? value.raw : void 0;
|
|
1388
1115
|
}
|
|
1389
1116
|
function getExportedName(node) {
|
|
1390
|
-
if (!node
|
|
1117
|
+
if (!isRecord(node)) return void 0;
|
|
1391
1118
|
const exported = node;
|
|
1392
1119
|
if (exported.type === "Identifier" && typeof exported.name === "string") return exported.name;
|
|
1393
1120
|
if ((exported.type === "Literal" || exported.type === "StringLiteral") && typeof exported.value === "string") return exported.value;
|
|
@@ -1400,7 +1127,7 @@ function forEachAstNode(root, visit) {
|
|
|
1400
1127
|
const seen = /* @__PURE__ */ new Set();
|
|
1401
1128
|
while (stack.length > 0) {
|
|
1402
1129
|
const value = stack.pop();
|
|
1403
|
-
if (!value
|
|
1130
|
+
if (!isRecord(value)) continue;
|
|
1404
1131
|
if (seen.has(value)) continue;
|
|
1405
1132
|
seen.add(value);
|
|
1406
1133
|
if (Array.isArray(value)) {
|
|
@@ -1414,18 +1141,22 @@ function forEachAstNode(root, visit) {
|
|
|
1414
1141
|
});
|
|
1415
1142
|
}
|
|
1416
1143
|
}
|
|
1417
|
-
function collectImportDeclaration(node, source, record,
|
|
1144
|
+
function collectImportDeclaration(node, source, record, requireAllExports) {
|
|
1418
1145
|
if (isTypeOnly(node)) return;
|
|
1419
1146
|
const specifiers = Array.isArray(node.specifiers) ? node.specifiers : [];
|
|
1420
1147
|
if (specifiers.length === 0) {
|
|
1421
|
-
|
|
1148
|
+
requireAllExports(source);
|
|
1422
1149
|
return;
|
|
1423
1150
|
}
|
|
1424
1151
|
const names = [];
|
|
1425
1152
|
for (const specifier of specifiers) {
|
|
1153
|
+
if (!isRecord(specifier)) {
|
|
1154
|
+
requireAllExports(source);
|
|
1155
|
+
return;
|
|
1156
|
+
}
|
|
1426
1157
|
if (isTypeOnly(specifier)) continue;
|
|
1427
1158
|
if (specifier.type === "ImportNamespaceSpecifier") {
|
|
1428
|
-
|
|
1159
|
+
requireAllExports(source);
|
|
1429
1160
|
return;
|
|
1430
1161
|
}
|
|
1431
1162
|
if (specifier.type === "ImportDefaultSpecifier") {
|
|
@@ -1434,118 +1165,246 @@ function collectImportDeclaration(node, source, record, markUnsafe) {
|
|
|
1434
1165
|
}
|
|
1435
1166
|
if (specifier.type === "ImportSpecifier") {
|
|
1436
1167
|
const imported = specifier.imported;
|
|
1437
|
-
if (imported
|
|
1438
|
-
|
|
1168
|
+
if (isRecord(imported) && (imported.type === "Literal" || imported.type === "StringLiteral")) {
|
|
1169
|
+
requireAllExports(source);
|
|
1439
1170
|
return;
|
|
1440
1171
|
}
|
|
1441
1172
|
const name = getExportedName(specifier.imported);
|
|
1442
1173
|
if (!name) {
|
|
1443
|
-
|
|
1174
|
+
requireAllExports(source);
|
|
1444
1175
|
return;
|
|
1445
1176
|
}
|
|
1446
1177
|
names.push(name);
|
|
1447
1178
|
continue;
|
|
1448
1179
|
}
|
|
1449
|
-
|
|
1180
|
+
requireAllExports(source);
|
|
1450
1181
|
return;
|
|
1451
1182
|
}
|
|
1452
1183
|
record(names, source);
|
|
1453
1184
|
}
|
|
1454
|
-
function collectReExport(node, source, record,
|
|
1185
|
+
function collectReExport(node, source, record, requireAllExports) {
|
|
1455
1186
|
if (isTypeOnly(node)) return;
|
|
1456
1187
|
if (node.type === "ExportAllDeclaration") {
|
|
1457
|
-
|
|
1188
|
+
requireAllExports(source);
|
|
1458
1189
|
return;
|
|
1459
1190
|
}
|
|
1460
1191
|
const specifiers = Array.isArray(node.specifiers) ? node.specifiers : [];
|
|
1461
1192
|
if (specifiers.length === 0) {
|
|
1462
|
-
|
|
1193
|
+
requireAllExports(source);
|
|
1463
1194
|
return;
|
|
1464
1195
|
}
|
|
1465
1196
|
const names = [];
|
|
1466
1197
|
for (const specifier of specifiers) {
|
|
1198
|
+
if (!isRecord(specifier)) {
|
|
1199
|
+
requireAllExports(source);
|
|
1200
|
+
return;
|
|
1201
|
+
}
|
|
1467
1202
|
if (isTypeOnly(specifier)) continue;
|
|
1468
1203
|
if (specifier.type !== "ExportSpecifier") {
|
|
1469
|
-
|
|
1204
|
+
requireAllExports(source);
|
|
1470
1205
|
return;
|
|
1471
1206
|
}
|
|
1472
1207
|
const local = specifier.local;
|
|
1473
|
-
if (local
|
|
1474
|
-
|
|
1208
|
+
if (isRecord(local) && (local.type === "Literal" || local.type === "StringLiteral")) {
|
|
1209
|
+
requireAllExports(source);
|
|
1475
1210
|
return;
|
|
1476
1211
|
}
|
|
1477
1212
|
const name = getExportedName(specifier.local);
|
|
1478
1213
|
if (!name) {
|
|
1479
|
-
|
|
1214
|
+
requireAllExports(source);
|
|
1480
1215
|
return;
|
|
1481
1216
|
}
|
|
1482
1217
|
names.push(name);
|
|
1483
1218
|
}
|
|
1484
1219
|
record(names, source);
|
|
1485
1220
|
}
|
|
1221
|
+
function analyzeImports(code) {
|
|
1222
|
+
let ast;
|
|
1223
|
+
try {
|
|
1224
|
+
ast = vite.parseAst(code);
|
|
1225
|
+
} catch {
|
|
1226
|
+
return null;
|
|
1227
|
+
}
|
|
1228
|
+
const imports = [];
|
|
1229
|
+
const recordSource = (names, source) => imports.push({
|
|
1230
|
+
source,
|
|
1231
|
+
usedExports: names
|
|
1232
|
+
});
|
|
1233
|
+
const requireAllExports = (source) => imports.push({
|
|
1234
|
+
source,
|
|
1235
|
+
usedExports: null
|
|
1236
|
+
});
|
|
1237
|
+
const collectImport = (node) => {
|
|
1238
|
+
if (node.type === "ImportDeclaration") {
|
|
1239
|
+
const source = getModuleSource(node.source);
|
|
1240
|
+
if (source) collectImportDeclaration(node, source, recordSource, requireAllExports);
|
|
1241
|
+
return;
|
|
1242
|
+
}
|
|
1243
|
+
if ((node.type === "ExportNamedDeclaration" || node.type === "ExportAllDeclaration") && node.source) {
|
|
1244
|
+
const source = getModuleSource(node.source);
|
|
1245
|
+
if (source) collectReExport(node, source, recordSource, requireAllExports);
|
|
1246
|
+
return;
|
|
1247
|
+
}
|
|
1248
|
+
if (node.type === "ImportExpression") {
|
|
1249
|
+
const source = getModuleSource(node.source);
|
|
1250
|
+
if (source) requireAllExports(source);
|
|
1251
|
+
return;
|
|
1252
|
+
}
|
|
1253
|
+
if (node.type === "CallExpression") {
|
|
1254
|
+
const callee = node.callee;
|
|
1255
|
+
const args = Array.isArray(node.arguments) ? node.arguments : [];
|
|
1256
|
+
if (isRecord(callee) && callee.type === "Identifier" && callee.name === "require" && args.length > 0) {
|
|
1257
|
+
const source = getModuleSource(args[0]);
|
|
1258
|
+
if (source) requireAllExports(source);
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
};
|
|
1262
|
+
if ("Visitor" in vite && typeof vite.Visitor === "function") {
|
|
1263
|
+
const visit = (node) => {
|
|
1264
|
+
if (isRecord(node)) collectImport(node);
|
|
1265
|
+
};
|
|
1266
|
+
try {
|
|
1267
|
+
new vite.Visitor({
|
|
1268
|
+
ImportDeclaration: visit,
|
|
1269
|
+
ExportNamedDeclaration: visit,
|
|
1270
|
+
ExportAllDeclaration: visit,
|
|
1271
|
+
ImportExpression: visit,
|
|
1272
|
+
CallExpression: visit
|
|
1273
|
+
}).visit(ast);
|
|
1274
|
+
return imports;
|
|
1275
|
+
} catch {
|
|
1276
|
+
imports.length = 0;
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
forEachAstNode(ast, collectImport);
|
|
1280
|
+
return imports;
|
|
1281
|
+
}
|
|
1282
|
+
//#endregion
|
|
1283
|
+
//#region src/utils/treeShaking.ts
|
|
1284
|
+
function shouldAnalyzeSharedExports(shareItem) {
|
|
1285
|
+
return !!(shareItem && (shareItem.shareConfig.treeShaking || shareItem.shareConfig.import === false));
|
|
1286
|
+
}
|
|
1287
|
+
const legacyTreeShakingState = {
|
|
1288
|
+
inferredUsage: /* @__PURE__ */ new Map(),
|
|
1289
|
+
buildMode: false
|
|
1290
|
+
};
|
|
1291
|
+
const treeShakingStates = /* @__PURE__ */ new WeakMap();
|
|
1292
|
+
function getTreeShakingState(options) {
|
|
1293
|
+
if (!options) return legacyTreeShakingState;
|
|
1294
|
+
let state = treeShakingStates.get(options);
|
|
1295
|
+
if (!state) {
|
|
1296
|
+
state = {
|
|
1297
|
+
inferredUsage: /* @__PURE__ */ new Map(),
|
|
1298
|
+
buildMode: false
|
|
1299
|
+
};
|
|
1300
|
+
treeShakingStates.set(options, state);
|
|
1301
|
+
}
|
|
1302
|
+
return state;
|
|
1303
|
+
}
|
|
1304
|
+
function setTreeShakingBuildMode(enabled, options) {
|
|
1305
|
+
getTreeShakingState(options).buildMode = enabled;
|
|
1306
|
+
}
|
|
1307
|
+
function resetTreeShakingExports(options) {
|
|
1308
|
+
getTreeShakingState(options).inferredUsage.clear();
|
|
1309
|
+
}
|
|
1310
|
+
function getOrCreateExportRecord(sharedKey, request, options) {
|
|
1311
|
+
const inferredUsage = getTreeShakingState(options).inferredUsage;
|
|
1312
|
+
let byRequest = inferredUsage.get(sharedKey);
|
|
1313
|
+
if (!byRequest) {
|
|
1314
|
+
byRequest = /* @__PURE__ */ new Map();
|
|
1315
|
+
inferredUsage.set(sharedKey, byRequest);
|
|
1316
|
+
}
|
|
1317
|
+
let record = byRequest.get(request);
|
|
1318
|
+
if (!record) {
|
|
1319
|
+
record = {
|
|
1320
|
+
requiresFullBundle: false,
|
|
1321
|
+
usedExports: /* @__PURE__ */ new Set()
|
|
1322
|
+
};
|
|
1323
|
+
byRequest.set(request, record);
|
|
1324
|
+
}
|
|
1325
|
+
return record;
|
|
1326
|
+
}
|
|
1327
|
+
function recordTreeShakingExports(sharedKey, exports, request = sharedKey, options) {
|
|
1328
|
+
const record = getOrCreateExportRecord(sharedKey, request, options);
|
|
1329
|
+
exports.forEach((name) => record.usedExports.add(name));
|
|
1330
|
+
}
|
|
1331
|
+
function markTreeShakingPackageUnsafe(sharedKey, request = sharedKey, options) {
|
|
1332
|
+
getOrCreateExportRecord(sharedKey, request, options).requiresFullBundle = true;
|
|
1333
|
+
}
|
|
1334
|
+
function getExportRecords(sharedKey, request, options) {
|
|
1335
|
+
const inferredUsage = getTreeShakingState(options).inferredUsage;
|
|
1336
|
+
if (sharedKey) {
|
|
1337
|
+
const records = inferredUsage.get(sharedKey);
|
|
1338
|
+
const wildcard = records?.get("*");
|
|
1339
|
+
const exact = records?.get(request);
|
|
1340
|
+
return [wildcard, exact === wildcard ? void 0 : exact].filter((record) => !!record);
|
|
1341
|
+
}
|
|
1342
|
+
const records = [];
|
|
1343
|
+
inferredUsage.forEach((byRequest, configuredKey) => {
|
|
1344
|
+
const wildcard = byRequest.get("*");
|
|
1345
|
+
const exact = byRequest.get(request);
|
|
1346
|
+
const configuredRequest = getSharedRequest(configuredKey, options?.shared?.[configuredKey]);
|
|
1347
|
+
const keyBase = configuredRequest.endsWith("/") ? configuredRequest.slice(0, -1) : configuredRequest;
|
|
1348
|
+
const requestMatchesConfiguredKey = request === keyBase || request.startsWith(`${keyBase}/`);
|
|
1349
|
+
if (wildcard && requestMatchesConfiguredKey) records.push(wildcard);
|
|
1350
|
+
if (exact && exact !== wildcard) records.push(exact);
|
|
1351
|
+
});
|
|
1352
|
+
return records;
|
|
1353
|
+
}
|
|
1354
|
+
/**
|
|
1355
|
+
* Return the analyzed requirement for one concrete shared request.
|
|
1356
|
+
*
|
|
1357
|
+
* Callers that know the configured share key should pass it explicitly. The
|
|
1358
|
+
* fallback lookup across keys keeps aliases/backwards-compatible callers
|
|
1359
|
+
* working, while still keeping each concrete request's exports isolated.
|
|
1360
|
+
*/
|
|
1361
|
+
function getSharedExportUsage(request, shareItem, sharedKey, options) {
|
|
1362
|
+
const treeShaking = shareItem?.shareConfig.treeShaking;
|
|
1363
|
+
if (!shouldAnalyzeSharedExports(shareItem) || !getTreeShakingState(options).buildMode) return;
|
|
1364
|
+
const records = getExportRecords(sharedKey, request, options);
|
|
1365
|
+
if (records.some((record) => record.requiresFullBundle)) return { kind: "full" };
|
|
1366
|
+
const configured = treeShaking?.usedExports ?? [];
|
|
1367
|
+
const result = new Set(configured);
|
|
1368
|
+
records.forEach((record) => record.usedExports.forEach((name) => result.add(name)));
|
|
1369
|
+
if (result.size > 0) return {
|
|
1370
|
+
kind: "exports",
|
|
1371
|
+
usedExports: [...result].sort()
|
|
1372
|
+
};
|
|
1373
|
+
return records.length > 0 ? {
|
|
1374
|
+
kind: "exports",
|
|
1375
|
+
usedExports: []
|
|
1376
|
+
} : { kind: "unknown" };
|
|
1377
|
+
}
|
|
1378
|
+
function getTreeShakingExportUsage(request, shareItem, sharedKey, options) {
|
|
1379
|
+
if (!shareItem?.shareConfig.treeShaking) return void 0;
|
|
1380
|
+
return getSharedExportUsage(request, shareItem, sharedKey, options);
|
|
1381
|
+
}
|
|
1486
1382
|
/**
|
|
1487
|
-
*
|
|
1488
|
-
*
|
|
1489
|
-
*
|
|
1490
|
-
* templates, or regular expressions as real dependencies. If parsing fails,
|
|
1491
|
-
* every configured share whose exports are analyzed is conservatively marked
|
|
1492
|
-
* as requiring its full export surface instead of guessing from source text.
|
|
1493
|
-
*
|
|
1494
|
-
* Generated federation wrappers are excluded because their imports describe
|
|
1495
|
-
* the wrapper implementation, not the consumer's requirements.
|
|
1383
|
+
* Record consumer imports against this instance's sharing configuration.
|
|
1384
|
+
* Generated wrappers do not contribute consumer usage. If parsing fails,
|
|
1385
|
+
* every share enabled for analysis requires all of its exports.
|
|
1496
1386
|
*/
|
|
1497
|
-
async function collectTreeShakingImports(code, id, shared, findSharedKey, record, markUnsafe) {
|
|
1387
|
+
async function collectTreeShakingImports(code, id, shared, findSharedKey, record, markUnsafe, analysis = getImportAnalysis(shared)) {
|
|
1498
1388
|
const normalizedId = normalizePathForImport(id);
|
|
1499
1389
|
if (normalizedId.includes("__prebuild__") || normalizedId.includes("__loadShare__") || normalizedId.includes("__mf_tree_shaking_graph__")) return;
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
ast = parseAst(code);
|
|
1503
|
-
} catch {
|
|
1390
|
+
const imports = analysis.analyze(code);
|
|
1391
|
+
if (imports === null) {
|
|
1504
1392
|
Object.entries(shared).forEach(([sharedKey, shareItem]) => {
|
|
1505
1393
|
if (shouldAnalyzeSharedExports(shareItem)) markUnsafe(sharedKey, "*");
|
|
1506
1394
|
});
|
|
1507
1395
|
return;
|
|
1508
1396
|
}
|
|
1509
1397
|
const pending = [];
|
|
1510
|
-
const
|
|
1398
|
+
for (const { source, usedExports } of imports) {
|
|
1511
1399
|
const apply = (key) => {
|
|
1512
|
-
if (key
|
|
1400
|
+
if (!key || !shouldAnalyzeSharedExports(shared[key])) return;
|
|
1401
|
+
if (usedExports === null) markUnsafe(key, source);
|
|
1402
|
+
else record(key, usedExports, source);
|
|
1513
1403
|
};
|
|
1514
1404
|
const key = findSharedKey(source, shared);
|
|
1515
1405
|
if (key instanceof Promise) pending.push(key.then(apply));
|
|
1516
1406
|
else apply(key);
|
|
1517
|
-
}
|
|
1518
|
-
const recordSource = (names, source) => {
|
|
1519
|
-
withSharedSource(source, (key) => record(key, names, source));
|
|
1520
|
-
};
|
|
1521
|
-
const markSourceUnsafe = (source) => {
|
|
1522
|
-
withSharedSource(source, (key) => markUnsafe(key, source));
|
|
1523
|
-
};
|
|
1524
|
-
forEachAstNode(ast, (node) => {
|
|
1525
|
-
if (node.type === "ImportDeclaration") {
|
|
1526
|
-
const source = getModuleSource(node.source);
|
|
1527
|
-
if (source) collectImportDeclaration(node, source, recordSource, markSourceUnsafe);
|
|
1528
|
-
return;
|
|
1529
|
-
}
|
|
1530
|
-
if ((node.type === "ExportNamedDeclaration" || node.type === "ExportAllDeclaration") && node.source) {
|
|
1531
|
-
const source = getModuleSource(node.source);
|
|
1532
|
-
if (source) collectReExport(node, source, recordSource, markSourceUnsafe);
|
|
1533
|
-
return;
|
|
1534
|
-
}
|
|
1535
|
-
if (node.type === "ImportExpression") {
|
|
1536
|
-
const source = getModuleSource(node.source);
|
|
1537
|
-
if (source) markSourceUnsafe(source);
|
|
1538
|
-
return;
|
|
1539
|
-
}
|
|
1540
|
-
if (node.type === "CallExpression") {
|
|
1541
|
-
const callee = node.callee;
|
|
1542
|
-
const args = Array.isArray(node.arguments) ? node.arguments : [];
|
|
1543
|
-
if (callee?.type === "Identifier" && callee.name === "require" && args.length > 0) {
|
|
1544
|
-
const source = getModuleSource(args[0]);
|
|
1545
|
-
if (source) markSourceUnsafe(source);
|
|
1546
|
-
}
|
|
1547
|
-
}
|
|
1548
|
-
});
|
|
1407
|
+
}
|
|
1549
1408
|
await Promise.all(pending);
|
|
1550
1409
|
}
|
|
1551
1410
|
//#endregion
|
|
@@ -2162,7 +2021,7 @@ ${exportStatement}
|
|
|
2162
2021
|
//#endregion
|
|
2163
2022
|
//#region src/plugins/pluginReactMixedModeGuard.ts
|
|
2164
2023
|
function createReactMixedModeRuntimeGuard() {
|
|
2165
|
-
return `const __mfReactInternals = mod[
|
|
2024
|
+
return `const __mfReactInternals = mod[${JSON.stringify(REACT_CLIENT_INTERNALS_KEY)}];
|
|
2166
2025
|
if (__mfReactInternals && "A" in __mfReactInternals) {
|
|
2167
2026
|
let __mfReactDispatcher = __mfReactInternals.A;
|
|
2168
2027
|
Object.defineProperty(__mfReactInternals, "A", {
|
|
@@ -2252,6 +2111,77 @@ function findLikelyTypeArgumentEnd(source, start, codePositions) {
|
|
|
2252
2111
|
}
|
|
2253
2112
|
}
|
|
2254
2113
|
//#endregion
|
|
2114
|
+
//#region src/virtualModules/shareTags.ts
|
|
2115
|
+
const LOAD_SHARE_TAG = "__loadShare__";
|
|
2116
|
+
/** A share's local copy. Reachable only through `import()`, so it stays lazy. */
|
|
2117
|
+
const PREBUILD_TAG = "__prebuild__";
|
|
2118
|
+
//#endregion
|
|
2119
|
+
//#region src/virtualModules/loadShareSharedChunk.ts
|
|
2120
|
+
const HELPERS_MODULE_NAME = "loadShareHelpers";
|
|
2121
|
+
const HELPERS_MODULE_TAG = "__mf_v__";
|
|
2122
|
+
const HELPERS_MODULE_MARKER = `${HELPERS_MODULE_TAG}${HELPERS_MODULE_NAME}${HELPERS_MODULE_TAG}`;
|
|
2123
|
+
const SHARED_CHUNK_SUFFIX = `${LOAD_SHARE_TAG}shared`;
|
|
2124
|
+
const HELPER_EXPORT_LIST = [
|
|
2125
|
+
"__mfGetSharedCacheDescriptor",
|
|
2126
|
+
"__mfReadSharedCache",
|
|
2127
|
+
"__mfSharedCacheListenersKey",
|
|
2128
|
+
"__mfGetSharedCacheListeners",
|
|
2129
|
+
"__mfSubscribeSharedCache",
|
|
2130
|
+
"__mfSharedCacheOwnersKey",
|
|
2131
|
+
"__mfGetSharedCacheOwners",
|
|
2132
|
+
"__mfReadSharedCacheOwner",
|
|
2133
|
+
"__mfGetSharedModuleIdentity",
|
|
2134
|
+
"__mfIsSameSharedModule",
|
|
2135
|
+
"__mfWriteSharedCache",
|
|
2136
|
+
"__mfTreeShakingSharedCacheKey",
|
|
2137
|
+
"__mfGetTreeShakingSharedCache",
|
|
2138
|
+
"__mfReadTreeShakingSharedCache",
|
|
2139
|
+
"__mfWriteTreeShakingSharedCache",
|
|
2140
|
+
"__mfTreeShakingSelectionCacheKey",
|
|
2141
|
+
"__mfGetTreeShakingSelectionCache",
|
|
2142
|
+
"__mfReadTreeShakingSharedSelection",
|
|
2143
|
+
"__mfWriteTreeShakingSharedSelection"
|
|
2144
|
+
].join(", ");
|
|
2145
|
+
const helperModules = /* @__PURE__ */ new WeakMap();
|
|
2146
|
+
function getSharedCacheHelpersModule(options) {
|
|
2147
|
+
let module = helperModules.get(options);
|
|
2148
|
+
if (!module) {
|
|
2149
|
+
module = new VirtualModule(HELPERS_MODULE_NAME, HELPERS_MODULE_TAG, "", getFederationScopeKey(options));
|
|
2150
|
+
module.writeSync(`${sharedCacheHelperCode}\nexport { ${HELPER_EXPORT_LIST} };`);
|
|
2151
|
+
helperModules.set(options, module);
|
|
2152
|
+
}
|
|
2153
|
+
return module;
|
|
2154
|
+
}
|
|
2155
|
+
function getSharedCacheHelpersImportCode(options) {
|
|
2156
|
+
const importId = getSharedCacheHelpersModule(options).getImportId();
|
|
2157
|
+
return `import { ${HELPER_EXPORT_LIST} } from ${JSON.stringify(importId)};`;
|
|
2158
|
+
}
|
|
2159
|
+
function isSharedCacheHelpersId(id) {
|
|
2160
|
+
return id.includes(HELPERS_MODULE_MARKER);
|
|
2161
|
+
}
|
|
2162
|
+
function getSharedChunkName(id) {
|
|
2163
|
+
const ownerTag = isSharedCacheHelpersId(id) ? HELPERS_MODULE_MARKER : LOAD_SHARE_TAG;
|
|
2164
|
+
return `${id.slice(0, id.indexOf(ownerTag))}${SHARED_CHUNK_SUFFIX}`;
|
|
2165
|
+
}
|
|
2166
|
+
function isSharedChunk(chunk) {
|
|
2167
|
+
return chunk.name?.endsWith(SHARED_CHUNK_SUFFIX) ?? false;
|
|
2168
|
+
}
|
|
2169
|
+
/**
|
|
2170
|
+
* Fallbacks inlined into a shared chunk, which means they are no longer lazy.
|
|
2171
|
+
* Only inlined modules count: a shared chunk also imports fallback chunks with
|
|
2172
|
+
* the experiment off, because Rolldown hoists its runtime helpers into whichever
|
|
2173
|
+
* chunk first uses them.
|
|
2174
|
+
*/
|
|
2175
|
+
function findEagerFallbacksInSharedChunk(bundle) {
|
|
2176
|
+
const offenders = /* @__PURE__ */ new Map();
|
|
2177
|
+
for (const [fileName, chunk] of Object.entries(bundle)) {
|
|
2178
|
+
if (chunk.type !== "chunk" || !isSharedChunk(chunk)) continue;
|
|
2179
|
+
const inlined = Object.keys(chunk.modules ?? {}).filter((id) => id.includes(PREBUILD_TAG));
|
|
2180
|
+
if (inlined.length > 0) offenders.set(fileName, inlined);
|
|
2181
|
+
}
|
|
2182
|
+
return offenders;
|
|
2183
|
+
}
|
|
2184
|
+
//#endregion
|
|
2255
2185
|
//#region src/virtualModules/virtualShared_preBuild.ts
|
|
2256
2186
|
/**
|
|
2257
2187
|
* Even the resolveId hook cannot interfere with vite pre-build,
|
|
@@ -2287,7 +2217,7 @@ function isValidEsmExportName(name) {
|
|
|
2287
2217
|
const JS_IDENTIFIER_PATTERN = `[\$_\\p{ID_Start}][\$_\\u200C\\u200D\\p{ID_Continue}]*`;
|
|
2288
2218
|
function resolvePackageEntryFromProjectRoot(pkg) {
|
|
2289
2219
|
try {
|
|
2290
|
-
return
|
|
2220
|
+
return resolveModulePath(pkg, path$1.join(getPackageDetectionCwd(), "package.json"));
|
|
2291
2221
|
} catch {
|
|
2292
2222
|
return;
|
|
2293
2223
|
}
|
|
@@ -2445,7 +2375,7 @@ function resolveConfiguredImportPath(importSource, exportConditions = DEFAULT_SH
|
|
|
2445
2375
|
});
|
|
2446
2376
|
if (esmEntry) return esmEntry;
|
|
2447
2377
|
try {
|
|
2448
|
-
return
|
|
2378
|
+
return resolveModulePath(importSource, path$1.join(projectRoot, "package.json"));
|
|
2449
2379
|
} catch {
|
|
2450
2380
|
return;
|
|
2451
2381
|
}
|
|
@@ -2473,6 +2403,11 @@ function resolveRelativeModule(filePath, specifier) {
|
|
|
2473
2403
|
const dir = path$1.dirname(filePath);
|
|
2474
2404
|
const exact = path$1.resolve(dir, specifier);
|
|
2475
2405
|
if (existsSync(exact) && !statSync(exact).isDirectory()) return exact;
|
|
2406
|
+
const sourceExtensions = specifier.endsWith(".mjs") ? [".mts"] : specifier.endsWith(".cjs") ? [".cts"] : /\.jsx?$/.test(specifier) ? [".ts", ".tsx"] : [];
|
|
2407
|
+
for (const ext of sourceExtensions) {
|
|
2408
|
+
const candidate = exact.replace(/\.[cm]?jsx?$/, ext);
|
|
2409
|
+
if (existsSync(candidate) && !statSync(candidate).isDirectory()) return candidate;
|
|
2410
|
+
}
|
|
2476
2411
|
const extensions = [
|
|
2477
2412
|
".ts",
|
|
2478
2413
|
".tsx",
|
|
@@ -2500,7 +2435,7 @@ function resolveReExportModule(filePath, specifier, exportConditions) {
|
|
|
2500
2435
|
});
|
|
2501
2436
|
if (esmEntry) return esmEntry;
|
|
2502
2437
|
try {
|
|
2503
|
-
return resolveFileLikeModule(
|
|
2438
|
+
return resolveFileLikeModule(resolveModulePath(specifier, filePath));
|
|
2504
2439
|
} catch {
|
|
2505
2440
|
return;
|
|
2506
2441
|
}
|
|
@@ -2828,7 +2763,8 @@ function getRequiredNamedExports(specifier) {
|
|
|
2828
2763
|
const getActiveHandles = process._getActiveHandles;
|
|
2829
2764
|
const handlesBeforeRequire = typeof getActiveHandles === "function" ? new Set(getActiveHandles.call(process)) : void 0;
|
|
2830
2765
|
try {
|
|
2831
|
-
const
|
|
2766
|
+
const projectPackageJson = path$1.join(getPackageDetectionCwd(), "package.json");
|
|
2767
|
+
const mod = createRequire$1(pathToFileURL(projectPackageJson))(resolveModulePath(specifier, projectPackageJson));
|
|
2832
2768
|
const runtimeNamedKeys = Object.keys(mod).filter((key) => key !== "default" && key !== "__esModule");
|
|
2833
2769
|
if (runtimeNamedKeys.some((key) => !isValidEsmExportName(key))) return void 0;
|
|
2834
2770
|
return runtimeNamedKeys;
|
|
@@ -2871,7 +2807,7 @@ function getSharedNamedExports(pkg, shareItem, exportConditions = DEFAULT_SHARED
|
|
|
2871
2807
|
}
|
|
2872
2808
|
function getLocalProviderImportPath(pkg) {
|
|
2873
2809
|
try {
|
|
2874
|
-
const resolved = resolveWorkspaceEsmEntry(pkg,
|
|
2810
|
+
const resolved = resolveWorkspaceEsmEntry(pkg, resolveModulePath(pkg, path$1.join(getPackageDetectionCwd(), "package.json")));
|
|
2875
2811
|
return isWorkspaceFilePath(resolved) ? resolved : void 0;
|
|
2876
2812
|
} catch {
|
|
2877
2813
|
const resolved = getInstalledPackageEntry(pkg, {
|
|
@@ -2892,7 +2828,7 @@ function getProjectResolvedImportPath(pkg) {
|
|
|
2892
2828
|
if (esmEntry) return esmEntry;
|
|
2893
2829
|
}
|
|
2894
2830
|
try {
|
|
2895
|
-
return resolveWorkspaceEsmEntry(pkg,
|
|
2831
|
+
return resolveWorkspaceEsmEntry(pkg, resolveModulePath(pkg, path$1.join(getPackageDetectionCwd(), "package.json")));
|
|
2896
2832
|
} catch {
|
|
2897
2833
|
return;
|
|
2898
2834
|
}
|
|
@@ -2948,25 +2884,11 @@ function getSharedDependencyGraphPackageJson(pkg) {
|
|
|
2948
2884
|
const installedPackageJson = getInstalledPackageJson(pkg, { packageName: getPackageName(pkg) })?.packageJson;
|
|
2949
2885
|
if (installedPackageJson) return installedPackageJson;
|
|
2950
2886
|
try {
|
|
2951
|
-
const packageJsonPath =
|
|
2887
|
+
const packageJsonPath = resolveModulePath(`${getPackageName(pkg)}/package.json`, path$1.join(getPackageDetectionCwd(), "package.json"));
|
|
2952
2888
|
return JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
2953
2889
|
} catch {}
|
|
2954
2890
|
return getWorkspacePackageJson(pkg);
|
|
2955
2891
|
}
|
|
2956
|
-
function getDependencyNames(packageJson) {
|
|
2957
|
-
if (!packageJson) return [];
|
|
2958
|
-
const names = /* @__PURE__ */ new Set();
|
|
2959
|
-
for (const field of [
|
|
2960
|
-
"dependencies",
|
|
2961
|
-
"peerDependencies",
|
|
2962
|
-
"optionalDependencies"
|
|
2963
|
-
]) {
|
|
2964
|
-
const deps = packageJson[field];
|
|
2965
|
-
if (!deps || typeof deps !== "object") continue;
|
|
2966
|
-
for (const dep of Object.keys(deps)) names.add(dep);
|
|
2967
|
-
}
|
|
2968
|
-
return Array.from(names);
|
|
2969
|
-
}
|
|
2970
2892
|
function isSharedSingletonConsumedByPeer(pkg, options = getNormalizeModuleFederationOptions(), requireFederationRuntimeDependency = false) {
|
|
2971
2893
|
const shared = options?.shared || {};
|
|
2972
2894
|
if (!requireFederationRuntimeDependency && Object.entries(shared).some(([key, item]) => key !== pkg && key.startsWith(`${pkg}/`) && item.shareConfig.singleton === true)) return true;
|
|
@@ -2975,25 +2897,39 @@ function isSharedSingletonConsumedByPeer(pkg, options = getNormalizeModuleFedera
|
|
|
2975
2897
|
const packageName = getPackageName(key);
|
|
2976
2898
|
if (!sharedKeyByPackageName.get(packageName) || key === packageName) sharedKeyByPackageName.set(packageName, key);
|
|
2977
2899
|
});
|
|
2978
|
-
const
|
|
2900
|
+
const runtimeDependencyCache = /* @__PURE__ */ new Map();
|
|
2901
|
+
const reachesFederationRuntime = (current, seen) => {
|
|
2902
|
+
if (runtimeDependencyCache.has(current)) return runtimeDependencyCache.get(current);
|
|
2903
|
+
const result = getDependencyNames(getSharedDependencyGraphPackageJson(current)).some((dependency) => {
|
|
2904
|
+
if (dependency === "@module-federation/enhanced" || dependency === "@module-federation/runtime" || dependency === "@module-federation/runtime-core") return true;
|
|
2905
|
+
if (seen.has(dependency)) return false;
|
|
2906
|
+
seen.add(dependency);
|
|
2907
|
+
const reachable = reachesFederationRuntime(dependency, seen);
|
|
2908
|
+
seen.delete(dependency);
|
|
2909
|
+
return reachable;
|
|
2910
|
+
});
|
|
2911
|
+
runtimeDependencyCache.set(current, result);
|
|
2912
|
+
return result;
|
|
2913
|
+
};
|
|
2914
|
+
const reachesPkg = (current, seen) => {
|
|
2979
2915
|
const dependencies = getDependencyNames(getSharedDependencyGraphPackageJson(current));
|
|
2980
|
-
const usesFederationRuntime = dependencies.some((dependency) => dependency === "@module-federation/enhanced" || dependency === "@module-federation/runtime" || dependency === "@module-federation/runtime-core");
|
|
2981
|
-
const runtimeIsReachable = hasFederationRuntimeDependency || usesFederationRuntime;
|
|
2982
2916
|
for (const dependency of dependencies) {
|
|
2983
2917
|
const sharedDependency = sharedKeyByPackageName.get(dependency);
|
|
2984
|
-
if (
|
|
2985
|
-
if (sharedDependency
|
|
2986
|
-
|
|
2987
|
-
seen.
|
|
2988
|
-
|
|
2918
|
+
if (sharedDependency === pkg) return true;
|
|
2919
|
+
if (!sharedDependency && !requireFederationRuntimeDependency) continue;
|
|
2920
|
+
const next = sharedDependency || dependency;
|
|
2921
|
+
if (seen.has(next)) continue;
|
|
2922
|
+
seen.add(next);
|
|
2923
|
+
if (reachesPkg(next, seen)) return true;
|
|
2924
|
+
seen.delete(next);
|
|
2989
2925
|
}
|
|
2990
2926
|
return false;
|
|
2991
2927
|
};
|
|
2992
|
-
return Array.from(sharedKeyByPackageName.values()).some((sharedPkg) => sharedPkg !== pkg && reachesPkg(sharedPkg, /* @__PURE__ */ new Set([sharedPkg])));
|
|
2928
|
+
return Array.from(sharedKeyByPackageName.values()).some((sharedPkg) => sharedPkg !== pkg && (!requireFederationRuntimeDependency || reachesFederationRuntime(sharedPkg, /* @__PURE__ */ new Set([sharedPkg]))) && reachesPkg(sharedPkg, /* @__PURE__ */ new Set([sharedPkg])));
|
|
2993
2929
|
}
|
|
2994
2930
|
function tryResolveImportFromPackageRoot(pkg, root) {
|
|
2995
2931
|
try {
|
|
2996
|
-
return resolveWorkspaceEsmEntry(pkg,
|
|
2932
|
+
return resolveWorkspaceEsmEntry(pkg, resolveModulePath(pkg, path$1.join(root, "package.json")), root);
|
|
2997
2933
|
} catch {
|
|
2998
2934
|
return;
|
|
2999
2935
|
}
|
|
@@ -3026,9 +2962,11 @@ function resolveConcreteSharedImportSource(pkg, projectRoot) {
|
|
|
3026
2962
|
if (resolved) return resolved;
|
|
3027
2963
|
currentDir = path$1.dirname(currentDir);
|
|
3028
2964
|
}
|
|
3029
|
-
return tryResolveImportFromPackageRoot(pkg, currentDir)
|
|
2965
|
+
return tryResolveImportFromPackageRoot(pkg, currentDir) ?? getInstalledPackageEntry(pkg, {
|
|
2966
|
+
conditions: DEFAULT_SHARED_EXPORT_CONDITIONS,
|
|
2967
|
+
resolveSubpathWithRequire: false
|
|
2968
|
+
});
|
|
3030
2969
|
}
|
|
3031
|
-
const PREBUILD_TAG = "__prebuild__";
|
|
3032
2970
|
const TREE_SHAKING_PROVIDER_TAG = "__treeShakingProvider__";
|
|
3033
2971
|
const TREE_SHAKING_GRAPH_QUERY = "__mf_tree_shaking_graph__";
|
|
3034
2972
|
const legacySharedVirtualModuleState = {
|
|
@@ -3037,9 +2975,11 @@ const legacySharedVirtualModuleState = {
|
|
|
3037
2975
|
treeShakingProviderCacheMap: {},
|
|
3038
2976
|
materializedTreeShakingProviders: /* @__PURE__ */ new Set(),
|
|
3039
2977
|
loadShareCacheMap: {},
|
|
3040
|
-
warnedMissingImportFalse: /* @__PURE__ */ new Set()
|
|
2978
|
+
warnedMissingImportFalse: /* @__PURE__ */ new Set(),
|
|
2979
|
+
coalescableLoadShares: /* @__PURE__ */ new Set()
|
|
3041
2980
|
};
|
|
3042
2981
|
const sharedVirtualModuleStates = /* @__PURE__ */ new WeakMap();
|
|
2982
|
+
const sharedVirtualModuleStatesByOwner = /* @__PURE__ */ new Map();
|
|
3043
2983
|
function getSharedVirtualModuleState(options) {
|
|
3044
2984
|
if (!options) try {
|
|
3045
2985
|
const currentOptions = getNormalizeModuleFederationOptions();
|
|
@@ -3056,12 +2996,19 @@ function getSharedVirtualModuleState(options) {
|
|
|
3056
2996
|
materializedTreeShakingProviders: /* @__PURE__ */ new Set(),
|
|
3057
2997
|
loadShareCacheMap: {},
|
|
3058
2998
|
warnedMissingImportFalse: /* @__PURE__ */ new Set(),
|
|
2999
|
+
coalescableLoadShares: /* @__PURE__ */ new Set(),
|
|
3059
3000
|
ownerKey: getFederationScopeKey(options)
|
|
3060
3001
|
};
|
|
3061
3002
|
sharedVirtualModuleStates.set(options, state);
|
|
3003
|
+
if (state.ownerKey !== void 0) sharedVirtualModuleStatesByOwner.set(state.ownerKey, state);
|
|
3062
3004
|
}
|
|
3063
3005
|
return state;
|
|
3064
3006
|
}
|
|
3007
|
+
/** State of the instance that owns a scoped virtual id; `options` covers unscoped ids. */
|
|
3008
|
+
function getSharedVirtualModuleStateForId(id, options) {
|
|
3009
|
+
const ownerKey = id === void 0 ? void 0 : VirtualModule.findById(id)?.getScopeName();
|
|
3010
|
+
return (ownerKey !== void 0 ? sharedVirtualModuleStatesByOwner.get(ownerKey) : void 0) ?? getSharedVirtualModuleState(options);
|
|
3011
|
+
}
|
|
3065
3012
|
function createScopedSharedVirtualModule(pkg, tag, options) {
|
|
3066
3013
|
return new VirtualModule(pkg, tag, ".js", getSharedVirtualModuleState(options).ownerKey);
|
|
3067
3014
|
}
|
|
@@ -3178,7 +3125,7 @@ function writePreBuildLibPath(pkg, shareItem, options, exportConditions) {
|
|
|
3178
3125
|
const cache = globalThis[__mfCacheGlobalKey]?.share;
|
|
3179
3126
|
const sharedReact = cache && __mfReadSharedCache(cache, ${reactCacheDescriptor});
|
|
3180
3127
|
const reactExports = sharedReact?.default ?? sharedReact;
|
|
3181
|
-
const internals = reactExports?.
|
|
3128
|
+
const internals = reactExports?.[${JSON.stringify(REACT_CLIENT_INTERNALS_KEY)}];
|
|
3182
3129
|
return internals?.H?.useMemoCache(size);
|
|
3183
3130
|
};
|
|
3184
3131
|
export default { c };
|
|
@@ -3256,7 +3203,6 @@ function getPreBuildShareItem(pkg, options) {
|
|
|
3256
3203
|
function getSharedImportSource(pkg, shareItem, options) {
|
|
3257
3204
|
return getConcreteSharedImportSource(pkg, shareItem) || getPreBuildLibImportId(pkg, options);
|
|
3258
3205
|
}
|
|
3259
|
-
const LOAD_SHARE_TAG = "__loadShare__";
|
|
3260
3206
|
function getLoadShareImportId(pkg, _isRolldown, options) {
|
|
3261
3207
|
const { loadShareCacheMap } = getSharedVirtualModuleState(options);
|
|
3262
3208
|
if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = createScopedSharedVirtualModule(pkg, LOAD_SHARE_TAG, options);
|
|
@@ -3316,14 +3262,14 @@ function getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer) {
|
|
|
3316
3262
|
* a merged chunk, TDZ bindings otherwise), so the exports stay unassigned until the deferred cache write
|
|
3317
3263
|
* re-applies them; a host-provided copy re-applies them through the cache subscription as before.
|
|
3318
3264
|
*/
|
|
3319
|
-
function generateEagerWorkspaceSingletonExports(namedExports, importSource, cacheDescriptor, cacheOwner, treeShakingConsumer, mutableExports = []) {
|
|
3265
|
+
function generateEagerWorkspaceSingletonExports(edges, namedExports, importSource, cacheDescriptor, cacheOwner, treeShakingConsumer, mutableExports = []) {
|
|
3320
3266
|
const copiedExports = namedExports.filter((name) => !mutableExports.includes(name));
|
|
3321
3267
|
const namedExportVars = copiedExports.map((_name, i) => `__mf_${i}`);
|
|
3322
3268
|
const declarations = namedExports.length > 0 ? ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ") : "let __mf_default;";
|
|
3323
3269
|
const assignments = [...copiedExports.map((name, i) => `${namedExportVars[i]} = mod[${escapeGeneratedStringLiteral(name)}];`), "__mf_default = mod.default ?? mod;"].join("\n ");
|
|
3324
3270
|
const namedExportLine = copiedExports.length > 0 ? `\n export { ${copiedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
|
|
3325
|
-
const mutableExportLine = mutableExports.length ? `\n
|
|
3326
|
-
return
|
|
3271
|
+
const mutableExportLine = mutableExports.length ? `\n ${edges.reExportNames(mutableExports, importSource)}` : "";
|
|
3272
|
+
return `${edges.importNamespace(importSource)}
|
|
3327
3273
|
let exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)};
|
|
3328
3274
|
if (exportModule === undefined) {
|
|
3329
3275
|
Promise.resolve().then(() => {
|
|
@@ -3351,28 +3297,26 @@ function generateEagerWorkspaceSingletonExports(namedExports, importSource, cach
|
|
|
3351
3297
|
__mfApplyEagerShareExportsWhenReady(exportModule);
|
|
3352
3298
|
export { __mf_default as default };${namedExportLine}${mutableExportLine}`;
|
|
3353
3299
|
}
|
|
3354
|
-
function generateLazyWorkspaceSingletonExports(namedExports, importSource, cacheDescriptor, cacheOwner, treeShakingConsumer, serveLocalFallback = false, mutableExports = []) {
|
|
3300
|
+
function generateLazyWorkspaceSingletonExports(edges, namedExports, importSource, cacheDescriptor, cacheOwner, treeShakingConsumer, serveLocalFallback = false, mutableExports = [], deferredEntryFallback = false) {
|
|
3355
3301
|
const copiedExports = namedExports.filter((name) => !mutableExports.includes(name));
|
|
3356
3302
|
const namedExportVars = copiedExports.map((_name, i) => `__mf_${i}`);
|
|
3357
3303
|
const declarations = namedExports.length > 0 ? ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ") : "let __mf_default;";
|
|
3358
3304
|
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;";
|
|
3359
3305
|
const namedExportLine = copiedExports.length > 0 ? `\n export { ${copiedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
|
|
3360
|
-
const mutableExportLine = mutableExports.length ? `\n
|
|
3306
|
+
const mutableExportLine = mutableExports.length ? `\n ${edges.reExportNames(mutableExports, importSource)}` : "";
|
|
3361
3307
|
const applyLocalFallback = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
3362
3308
|
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});
|
|
3363
3309
|
__mfApplyLazyShareExports(exportModule);`;
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
__mfTrackPendingShareLoad(initPromise.then(() => {
|
|
3375
|
-
exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)};
|
|
3310
|
+
const readDeferredShare = getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer);
|
|
3311
|
+
const deferredEntryLoad = `Promise.race([
|
|
3312
|
+
initPromise.then(() => ${readDeferredShare}),
|
|
3313
|
+
new Promise((resolve) => {
|
|
3314
|
+
const current = ${readDeferredShare};
|
|
3315
|
+
if (current !== undefined) resolve(current);
|
|
3316
|
+
else __mfSubscribeSharedCache(__mfModuleCache.share, ${cacheDescriptor}, resolve);
|
|
3317
|
+
})
|
|
3318
|
+
]).then((cached) => {
|
|
3319
|
+
exportModule = cached;
|
|
3376
3320
|
if (exportModule !== undefined) {
|
|
3377
3321
|
__mfApplyLazyShareExports(exportModule);
|
|
3378
3322
|
return;
|
|
@@ -3381,8 +3325,32 @@ function generateLazyWorkspaceSingletonExports(namedExports, importSource, cache
|
|
|
3381
3325
|
exportModule = __mfNormalizeShareModule(mod);
|
|
3382
3326
|
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});
|
|
3383
3327
|
});
|
|
3384
|
-
})
|
|
3385
|
-
|
|
3328
|
+
})`;
|
|
3329
|
+
const deferredInitLoad = `initPromise.then(() => {
|
|
3330
|
+
exportModule = ${readDeferredShare};
|
|
3331
|
+
if (exportModule !== undefined) {
|
|
3332
|
+
__mfApplyLazyShareExports(exportModule);
|
|
3333
|
+
return;
|
|
3334
|
+
}
|
|
3335
|
+
return import(${escapeGeneratedStringLiteral(importSource)}).then((mod) => {
|
|
3336
|
+
exportModule = __mfNormalizeShareModule(mod);
|
|
3337
|
+
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});
|
|
3338
|
+
});
|
|
3339
|
+
})`;
|
|
3340
|
+
const synchronousFallbackConditions = [...deferredEntryFallback ? [] : ["import.meta.env.SSR"], ...serveLocalFallback ? ["(import.meta.env.DEV && typeof __mfLocalShare !== 'undefined')"] : []];
|
|
3341
|
+
const trackPendingLoad = `__mfTrackPendingShareLoad(${deferredEntryFallback ? deferredEntryLoad : deferredInitLoad});`;
|
|
3342
|
+
return `${declarations}
|
|
3343
|
+
const __mfApplyLazyShareExports = (mod) => {
|
|
3344
|
+
${assignments}
|
|
3345
|
+
};
|
|
3346
|
+
__mfSubscribeSharedCache(__mfModuleCache.share, ${cacheDescriptor}, __mfApplyLazyShareExports);
|
|
3347
|
+
let exportModule = ${readDeferredShare};
|
|
3348
|
+
if (exportModule === undefined) {
|
|
3349
|
+
${synchronousFallbackConditions.length > 0 ? `if (${synchronousFallbackConditions.join(" || ")}) {
|
|
3350
|
+
${applyLocalFallback}
|
|
3351
|
+
} else {
|
|
3352
|
+
${trackPendingLoad}
|
|
3353
|
+
}` : trackPendingLoad}
|
|
3386
3354
|
} else {
|
|
3387
3355
|
__mfApplyLazyShareExports(exportModule);
|
|
3388
3356
|
}
|
|
@@ -3418,6 +3386,14 @@ function generateDeferredHostProvidedExports(namedExports, pkg, cacheDescriptor,
|
|
|
3418
3386
|
if (exportModule === undefined) {
|
|
3419
3387
|
__mfTrackPendingShareLoad(initPromise.then(() => {
|
|
3420
3388
|
exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)};
|
|
3389
|
+
// A share init() left to its dynamic import is normally bridged before that import runs;
|
|
3390
|
+
// bridge it here when this wrapper is reached another way.
|
|
3391
|
+
if (exportModule === undefined && typeof __mfPromiseState.loadLazyShares === "function") {
|
|
3392
|
+
return __mfPromiseState.loadLazyShares([${escapeGeneratedStringLiteral(pkg)}]).then(() => {
|
|
3393
|
+
exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)};
|
|
3394
|
+
});
|
|
3395
|
+
}
|
|
3396
|
+
}).then(() => {
|
|
3421
3397
|
if (exportModule === undefined) {
|
|
3422
3398
|
throw new Error("[Module Federation] Shared module ${pkg} was imported before federation bootstrap finished.");
|
|
3423
3399
|
}
|
|
@@ -3426,7 +3402,7 @@ function generateDeferredHostProvidedExports(namedExports, pkg, cacheDescriptor,
|
|
|
3426
3402
|
} else {
|
|
3427
3403
|
__mfApplyHostProvidedExports(exportModule);
|
|
3428
3404
|
}
|
|
3429
|
-
export { __mf_default as default };${namedExportLine}`;
|
|
3405
|
+
export { __mf_default as default, exportModule as __moduleExports };${namedExportLine}`;
|
|
3430
3406
|
}
|
|
3431
3407
|
function selectImportFalseNamedExports(detectedNamedExports, usage) {
|
|
3432
3408
|
if (!detectedNamedExports || usage?.kind !== "exports") return detectedNamedExports ?? [];
|
|
@@ -3465,9 +3441,49 @@ const initializedLocalShareModuleCode = `const __mfInitializedLocalShare = (mod)
|
|
|
3465
3441
|
throw error;
|
|
3466
3442
|
}
|
|
3467
3443
|
};`;
|
|
3444
|
+
function createLocalPayloadEdges() {
|
|
3445
|
+
let edges = 0;
|
|
3446
|
+
return {
|
|
3447
|
+
importNamespace(source) {
|
|
3448
|
+
edges++;
|
|
3449
|
+
return `import * as __mfLocalShare from ${escapeGeneratedStringLiteral(source)};`;
|
|
3450
|
+
},
|
|
3451
|
+
reExportAll(source) {
|
|
3452
|
+
edges++;
|
|
3453
|
+
return `export * from ${escapeGeneratedStringLiteral(source)}`;
|
|
3454
|
+
},
|
|
3455
|
+
reExportNames(names, source) {
|
|
3456
|
+
if (names.length === 0) return "";
|
|
3457
|
+
edges++;
|
|
3458
|
+
return `export { ${names.join(", ")} } from ${escapeGeneratedStringLiteral(source)};`;
|
|
3459
|
+
},
|
|
3460
|
+
get none() {
|
|
3461
|
+
return edges === 0;
|
|
3462
|
+
}
|
|
3463
|
+
};
|
|
3464
|
+
}
|
|
3465
|
+
function recordCoalescability(pkg, hasNoLocalPayloadEdge, command, shareConfig, coalescableLoadShares) {
|
|
3466
|
+
const coalescable = command === "build" && shareConfig.eager !== true && shareConfig.import !== false && hasNoLocalPayloadEdge;
|
|
3467
|
+
if (coalescable) coalescableLoadShares.add(pkg);
|
|
3468
|
+
else coalescableLoadShares.delete(pkg);
|
|
3469
|
+
return coalescable;
|
|
3470
|
+
}
|
|
3471
|
+
/**
|
|
3472
|
+
* `prependWorkspaceSingletonSsrImport` adds a local-payload edge in the server
|
|
3473
|
+
* build's load hook, after this module has generated the wrapper. `id` names
|
|
3474
|
+
* the owning instance when the hook belongs to a different one.
|
|
3475
|
+
*/
|
|
3476
|
+
function markLoadShareWrapperNotCoalescable(pkg, options, id) {
|
|
3477
|
+
getSharedVirtualModuleStateForId(id, options).coalescableLoadShares.delete(pkg);
|
|
3478
|
+
}
|
|
3479
|
+
/** With `id`, answers from the owning instance's state, whichever instance asks. */
|
|
3480
|
+
function isCoalescableLoadShareWrapper(pkg, options, id) {
|
|
3481
|
+
return getSharedVirtualModuleStateForId(id, options).coalescableLoadShares.has(pkg);
|
|
3482
|
+
}
|
|
3468
3483
|
function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options, exportConditions, importFalseExportUsage) {
|
|
3469
3484
|
const resolvedOptions = options ?? getNormalizeModuleFederationOptions();
|
|
3470
|
-
const { loadShareCacheMap } = getSharedVirtualModuleState(options);
|
|
3485
|
+
const { loadShareCacheMap, coalescableLoadShares } = getSharedVirtualModuleState(options);
|
|
3486
|
+
const edges = createLocalPayloadEdges();
|
|
3471
3487
|
if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = createScopedSharedVirtualModule(pkg, LOAD_SHARE_TAG, options);
|
|
3472
3488
|
let importLine = getRuntimeModuleCacheBootstrapCode(exportConditions);
|
|
3473
3489
|
const cacheDescriptor = getSharedCacheDescriptorLiteral(pkg, shareItem);
|
|
@@ -3487,6 +3503,7 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options, exp
|
|
|
3487
3503
|
}
|
|
3488
3504
|
exportLine = generateDeferredHostProvidedExports([], pkg, cacheDescriptor, treeShakingConsumer);
|
|
3489
3505
|
}
|
|
3506
|
+
recordCoalescability(pkg, edges.none, command, shareItem.shareConfig, coalescableLoadShares);
|
|
3490
3507
|
loadShareCacheMap[pkg].writeSync(`
|
|
3491
3508
|
${getRuntimeInitPromiseBootstrapCode(false, runtimeInitOwnerImportId)}
|
|
3492
3509
|
${importLine}
|
|
@@ -3508,13 +3525,14 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options, exp
|
|
|
3508
3525
|
const mutableExports = new Set(isLocalOnlyContainer(resolvedOptions) ? getSharedMutableExports(pkg, shareItem, exportConditions) : []);
|
|
3509
3526
|
const copiedNamedExports = namedExports.filter((name) => !mutableExports.has(name));
|
|
3510
3527
|
const liveNamedExports = namedExports.filter((name) => mutableExports.has(name));
|
|
3511
|
-
const liveNamedExportLine =
|
|
3528
|
+
const liveNamedExportLine = edges.reExportNames(liveNamedExports, sharedImportSource);
|
|
3512
3529
|
const hasCompleteExportCoverage = detectedNamedExports !== void 0;
|
|
3513
3530
|
const isWorkspaceSingleton = isWorkspacePackage && shareItem.shareConfig.singleton === true;
|
|
3514
3531
|
const usesDeferredSingletonFallback = hasCompleteExportCoverage && shareItem.shareConfig.eager !== true && (isWorkspacePackage || command !== "build" && isRemoteOnlyContainer(resolvedOptions) && shareItem.shareConfig.singleton === true || command === "build" && isRemoteContainer(resolvedOptions) && !isSharedSingletonConsumedByPeer(pkg, resolvedOptions, true));
|
|
3515
3532
|
const servesRemoteSingletonFallback = command !== "build" && isRemoteOnlyContainer(resolvedOptions) && shareItem.shareConfig.singleton === true;
|
|
3516
3533
|
const isConsumedByPeerSingleton = isSharedSingletonConsumedByPeer(pkg, resolvedOptions);
|
|
3517
3534
|
const usesEntryInjectedRemoteFallback = hasCompleteExportCoverage && !isWorkspaceSingleton && isRemoteContainer(resolvedOptions) && shareItem.shareConfig.singleton === true && resolvedOptions.hostInitInjectLocation === "entry" && (command === "build" || isConsumedByPeerSingleton);
|
|
3535
|
+
const usesDeferredEntryInjectedSingletonFallback = usesEntryInjectedRemoteFallback && !isReactCoreShare(pkg) && (pkg === "react-dom/client" || shareItem.shareConfig.eager !== true && !isSharedSingletonConsumedByPeer(pkg, resolvedOptions, true));
|
|
3518
3536
|
const usesEagerWorkspaceFallback = hasCompleteExportCoverage && isWorkspaceSingleton && !servesRemoteSingletonFallback && (isConsumedByPeerSingleton || shareItem.shareConfig.eager === true);
|
|
3519
3537
|
const usesDeferredTreeShakingFallback = hasCompleteExportCoverage && Boolean(treeShakingConsumer);
|
|
3520
3538
|
const reactMixedModeGuard = pkg === "react" ? createReactMixedModeRuntimeGuard() : "";
|
|
@@ -3522,11 +3540,14 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options, exp
|
|
|
3522
3540
|
let initBlock = "";
|
|
3523
3541
|
if (usesDeferredTreeShakingFallback) {
|
|
3524
3542
|
importLine = `${getRuntimeInitPromiseBootstrapCode(false, runtimeInitOwnerImportId)}\n ${importLine}`;
|
|
3525
|
-
exportLine = generateLazyWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, command !== "build" && !servesRemoteSingletonFallback && (isWorkspaceSingleton || isWorkspacePackage), liveNamedExports);
|
|
3526
|
-
} else if (
|
|
3543
|
+
exportLine = generateLazyWorkspaceSingletonExports(edges, namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, command !== "build" && !servesRemoteSingletonFallback && (isWorkspaceSingleton || isWorkspacePackage), liveNamedExports);
|
|
3544
|
+
} else if (usesDeferredEntryInjectedSingletonFallback) {
|
|
3545
|
+
importLine = `${getRuntimeInitPromiseBootstrapCode(false, runtimeInitOwnerImportId)}\n ${importLine}`;
|
|
3546
|
+
exportLine = generateLazyWorkspaceSingletonExports(edges, namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, false, liveNamedExports, true);
|
|
3547
|
+
} else if (usesEagerWorkspaceFallback || usesEntryInjectedRemoteFallback) exportLine = generateEagerWorkspaceSingletonExports(edges, namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, liveNamedExports);
|
|
3527
3548
|
else if (usesDeferredSingletonFallback) {
|
|
3528
3549
|
importLine = `${getRuntimeInitPromiseBootstrapCode(false, runtimeInitOwnerImportId)}\n ${importLine}`;
|
|
3529
|
-
exportLine = generateLazyWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, command !== "build" && !servesRemoteSingletonFallback && (isWorkspaceSingleton || isWorkspacePackage), liveNamedExports);
|
|
3550
|
+
exportLine = generateLazyWorkspaceSingletonExports(edges, namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, command !== "build" && !servesRemoteSingletonFallback && (isWorkspaceSingleton || isWorkspacePackage), liveNamedExports);
|
|
3530
3551
|
} else if (detectedNamedExports === void 0) {
|
|
3531
3552
|
exportLine = `const __mfDefaultExport = (() => {
|
|
3532
3553
|
${generateShareModuleUnwrapCode({
|
|
@@ -3536,7 +3557,7 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options, exp
|
|
|
3536
3557
|
})}
|
|
3537
3558
|
})();
|
|
3538
3559
|
export default __mfDefaultExport;
|
|
3539
|
-
|
|
3560
|
+
${edges.reExportAll(coherentLocalSource)}`;
|
|
3540
3561
|
initBlock = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
3541
3562
|
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});`;
|
|
3542
3563
|
} else if (namedExports.length > 0 && shareItem.shareConfig.singleton === true) {
|
|
@@ -3587,21 +3608,23 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options, exp
|
|
|
3587
3608
|
__mfSubscribeSharedCache(__mfModuleCache.share, ${cacheDescriptor}, __mfApplySharedDefaultExport);
|
|
3588
3609
|
__mfApplySharedDefaultExport(exportModule);
|
|
3589
3610
|
export { __mfDefaultExport as default };
|
|
3590
|
-
|
|
3611
|
+
${edges.reExportAll(sharedImportSource)}`;
|
|
3591
3612
|
initBlock = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
3592
3613
|
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});`;
|
|
3593
3614
|
} else {
|
|
3594
|
-
exportLine = `export default exportModule.default ?? exportModule\n
|
|
3615
|
+
exportLine = `export default exportModule.default ?? exportModule\n ${edges.reExportAll(sharedImportSource)}`;
|
|
3595
3616
|
initBlock = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
3596
3617
|
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});`;
|
|
3597
3618
|
}
|
|
3598
|
-
const
|
|
3599
|
-
const
|
|
3600
|
-
const
|
|
3601
|
-
|
|
3619
|
+
const staticLocalShareSource = detectedNamedExports === void 0 ? coherentLocalSource : skipServePrebuildWarmup ? devImportSource : sharedImportSource;
|
|
3620
|
+
const prebuildImportLine = usesEagerWorkspaceFallback || usesEntryInjectedRemoteFallback ? "" : usesDeferredSingletonFallback || usesDeferredTreeShakingFallback ? !servesRemoteSingletonFallback && usesDeferredSingletonFallback && command !== "build" && (isWorkspaceSingleton || isWorkspacePackage) ? edges.importNamespace(lazyLocalFallbackSource) : "" : edges.importNamespace(staticLocalShareSource);
|
|
3621
|
+
const devDynamicImportLine = isWorkspacePackage ? "" : usesDeferredSingletonFallback || usesDeferredTreeShakingFallback || usesDeferredEntryInjectedSingletonFallback ? "" : command !== "build" && !skipServePrebuildWarmup ? `;() => import(${escapeGeneratedStringLiteral(devImportSource)}).catch(() => {});` : "";
|
|
3622
|
+
const cacheHelpers = recordCoalescability(pkg, edges.none, command, shareItem.shareConfig, coalescableLoadShares) ? getSharedCacheHelpersImportCode(resolvedOptions) : sharedCacheHelperCode;
|
|
3623
|
+
const moduleBody = usesDeferredSingletonFallback || usesDeferredTreeShakingFallback || usesDeferredEntryInjectedSingletonFallback || usesEagerWorkspaceFallback || usesEntryInjectedRemoteFallback ? `
|
|
3624
|
+
${usesDeferredEntryInjectedSingletonFallback ? "" : prebuildImportLine}
|
|
3602
3625
|
${devDynamicImportLine}
|
|
3603
3626
|
${importLine}
|
|
3604
|
-
${
|
|
3627
|
+
${cacheHelpers}
|
|
3605
3628
|
${normalizeLocalShareModuleCode}
|
|
3606
3629
|
${initializedLocalShareModuleCode}
|
|
3607
3630
|
${exportLine}
|
|
@@ -3609,7 +3632,7 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options, exp
|
|
|
3609
3632
|
${prebuildImportLine}
|
|
3610
3633
|
${devDynamicImportLine}
|
|
3611
3634
|
${importLine}
|
|
3612
|
-
${
|
|
3635
|
+
${cacheHelpers}
|
|
3613
3636
|
${normalizeLocalShareModuleCode}
|
|
3614
3637
|
let exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)}
|
|
3615
3638
|
if (exportModule === undefined) {
|
|
@@ -3653,6 +3676,7 @@ function addConfiguredShare(pkg, options) {
|
|
|
3653
3676
|
if (options) getScopedUsedShares(options).add(pkg);
|
|
3654
3677
|
}
|
|
3655
3678
|
const LOCAL_SHARED_IMPORT_MAP_ID = "virtual:mf-localSharedImportMap";
|
|
3679
|
+
const LAZY_CONSUME_ONLY_SHARES_PLACEHOLDER = "__MF_LAZY_CONSUME_ONLY_SHARES__";
|
|
3656
3680
|
const localOwnerIds = /* @__PURE__ */ new WeakMap();
|
|
3657
3681
|
let nextLocalOwnerId = 1;
|
|
3658
3682
|
function getLocalOwnerKey(options) {
|
|
@@ -3690,6 +3714,10 @@ function getLocalSharedPackagePath(pkg, shareItem, options) {
|
|
|
3690
3714
|
if (shouldUseDirectReactImport() && pkg === "react") return "react";
|
|
3691
3715
|
return getConcreteSharedImportSource(pkg, shareItem) || getLocalProviderImportPath(pkg) || getSharedImportSource(pkg, shareItem, options);
|
|
3692
3716
|
}
|
|
3717
|
+
function getCanonicalSharedKey(pkg, shareItem) {
|
|
3718
|
+
const { request, shareKey } = shareItem.shareConfig;
|
|
3719
|
+
return request !== void 0 || shareKey !== void 0 ? getSharedRuntimeKey(pkg, shareItem) : pkg;
|
|
3720
|
+
}
|
|
3693
3721
|
function getDirectSharedCacheSeedImportPath(pkg, shareItem) {
|
|
3694
3722
|
return getConcreteSharedImportSource(pkg, shareItem) || getProjectResolvedImportPath(pkg) || getLocalProviderImportPath(pkg) || pkg;
|
|
3695
3723
|
}
|
|
@@ -3703,7 +3731,7 @@ function generateLocalSharedImportMap(options) {
|
|
|
3703
3731
|
import {loadShare} from "@module-federation/runtime";
|
|
3704
3732
|
${orderedShares.map((pkg, index) => {
|
|
3705
3733
|
const shareItem = getNormalizeShareItem(pkg, resolvedOptions);
|
|
3706
|
-
if (!shareItem
|
|
3734
|
+
if (!shareItem || !shareItem.shareConfig.eager || shareItem.shareConfig.import === false) return "";
|
|
3707
3735
|
return `import * as __mfEagerShare_${index} from ${toSafeJsLiteral(getLocalSharedPackagePath(pkg, shareItem, options))};`;
|
|
3708
3736
|
}).filter(Boolean).join("\n")}
|
|
3709
3737
|
${normalizeRuntimeShareCode}
|
|
@@ -3728,12 +3756,17 @@ function generateLocalSharedImportMap(options) {
|
|
|
3728
3756
|
const __mfHostOnly = (name) => async () => {
|
|
3729
3757
|
throw new Error(\`[Module Federation] Shared module '\${name}' must be provided by host\`);
|
|
3730
3758
|
};
|
|
3759
|
+
// Replaced by the lazy consume-only share plugin with the keys that only a dynamic
|
|
3760
|
+
// import() reaches, so init() leaves them to that import; an unreplaced string matches no key.
|
|
3761
|
+
const __mfLazyShares = ${JSON.stringify(LAZY_CONSUME_ONLY_SHARES_PLACEHOLDER)};
|
|
3762
|
+
const __mfIsLazyShare = (name) => Array.isArray(__mfLazyShares) && __mfLazyShares.includes(name);
|
|
3731
3763
|
const __mfConsumeOnly = (name, version, scope, materialize, shareConfig) => ({
|
|
3732
3764
|
name,
|
|
3733
3765
|
version,
|
|
3734
3766
|
scope: [scope],
|
|
3735
3767
|
loaded: false,
|
|
3736
|
-
materialize,
|
|
3768
|
+
materialize: materialize && !__mfIsLazyShare(name),
|
|
3769
|
+
lazy: __mfIsLazyShare(name),
|
|
3737
3770
|
eager: shareConfig.eager,
|
|
3738
3771
|
from: ${toSafeJsLiteral(resolvedOptions.name)},
|
|
3739
3772
|
canLiveRebind: true,
|
|
@@ -3743,7 +3776,8 @@ function generateLocalSharedImportMap(options) {
|
|
|
3743
3776
|
const importMap = {
|
|
3744
3777
|
${orderedShares.map((pkg, index) => {
|
|
3745
3778
|
const shareItem = getNormalizeShareItem(pkg, resolvedOptions);
|
|
3746
|
-
if (shareItem
|
|
3779
|
+
if (!shareItem) return "";
|
|
3780
|
+
if (shareItem.shareConfig.import === false) return `
|
|
3747
3781
|
${toSafeJsLiteral(pkg)}: __mfHostOnly(${toSafeJsLiteral(pkg)})`;
|
|
3748
3782
|
return `
|
|
3749
3783
|
${toSafeJsLiteral(pkg)}: async () => {
|
|
@@ -3759,7 +3793,7 @@ function generateLocalSharedImportMap(options) {
|
|
|
3759
3793
|
const shareItem = getNormalizeShareItem(key, resolvedOptions);
|
|
3760
3794
|
if (!shareItem) return null;
|
|
3761
3795
|
const isReactFamily = key.startsWith("react/") || key === "react-dom/client";
|
|
3762
|
-
const cacheKeys = [key, ...key === "react-dom/client" ? [
|
|
3796
|
+
const cacheKeys = [key, ...key === "react-dom/client" ? [getPackageName(REACT_DOM_CLIENT_SHARE)] : []].flatMap((pkg) => {
|
|
3763
3797
|
const descriptor = getSharedCacheDescriptor(pkg, shareItem);
|
|
3764
3798
|
return [descriptor.canonical, ...descriptor.aliases ?? []];
|
|
3765
3799
|
});
|
|
@@ -3771,7 +3805,7 @@ function generateLocalSharedImportMap(options) {
|
|
|
3771
3805
|
const canLiveRebind = shareItem.shareConfig.import === false || detectedNamedExports !== void 0;
|
|
3772
3806
|
const treeShakingConfig = canLiveRebind ? shareItem.shareConfig.treeShaking : void 0;
|
|
3773
3807
|
if (shareItem.shareConfig.import === false && !treeShakingConfig) return `
|
|
3774
|
-
${toSafeJsLiteral(key)}: __mfConsumeOnly(${toSafeJsLiteral(key)}, ${toSafeJsLiteral(shareItem.version)}, ${toSafeJsLiteral(shareItem.scope)}, ${sharesToMaterialize.has(key)}, {singleton: ${shareItem.shareConfig.singleton}, requiredVersion: ${toSafeJsLiteral(shareItem.shareConfig.requiredVersion)}, strictVersion: ${shareItem.shareConfig.strictVersion}, eager: ${Boolean(shareItem.shareConfig.eager)}})`;
|
|
3808
|
+
${toSafeJsLiteral(key)}: __mfConsumeOnly(${toSafeJsLiteral(key)}, ${toSafeJsLiteral(shareItem.version)}, ${toSafeJsLiteral(shareItem.scope)}, ${sharesToMaterialize.has(key)}, {singleton: ${shareItem.shareConfig.singleton}, requiredVersion: ${toSafeJsLiteral(shareItem.shareConfig.requiredVersion)}, strictVersion: ${shareItem.shareConfig.strictVersion}, eager: ${Boolean(shareItem.shareConfig.eager)}, ${shareItem.shareConfig.request !== void 0 ? `request: ${toSafeJsLiteral(shareItem.shareConfig.request)},` : ""} ${shareItem.shareConfig.shareKey !== void 0 ? `shareKey: ${toSafeJsLiteral(shareItem.shareConfig.shareKey)},` : ""}})`;
|
|
3775
3809
|
const treeShakingUsage = treeShakingConfig ? getTreeShakingExportUsage(key, shareItem, shareItem.name, options) : void 0;
|
|
3776
3810
|
const treeShakingProviderExports = treeShakingUsage?.kind === "exports" ? treeShakingUsage.usedExports : [];
|
|
3777
3811
|
const treeShakingUsedExports = resolvedOptions.injectTreeShakingUsedExports === false ? treeShakingConfig?.usedExports || [] : treeShakingProviderExports;
|
|
@@ -3842,6 +3876,8 @@ function generateLocalSharedImportMap(options) {
|
|
|
3842
3876
|
requiredVersion: ${toSafeJsLiteral(shareItem.shareConfig.requiredVersion)},
|
|
3843
3877
|
strictVersion: ${shareItem.shareConfig.strictVersion},
|
|
3844
3878
|
eager: ${Boolean(shareItem.shareConfig.eager)},
|
|
3879
|
+
${shareItem.shareConfig.request !== void 0 ? `request: ${toSafeJsLiteral(shareItem.shareConfig.request)},` : ""}
|
|
3880
|
+
${shareItem.shareConfig.shareKey !== void 0 ? `shareKey: ${toSafeJsLiteral(shareItem.shareConfig.shareKey)},` : ""}
|
|
3845
3881
|
${shareItem.shareConfig.import === false ? "import: false," : ""}
|
|
3846
3882
|
},
|
|
3847
3883
|
${treeShakingConfig ? `treeShaking: {
|
|
@@ -3894,11 +3930,17 @@ function expandSharedPrefixKey(prefixKey, used) {
|
|
|
3894
3930
|
function getOrderedUsedShares(options) {
|
|
3895
3931
|
const resolvedOptions = options ?? getNormalizeModuleFederationOptions();
|
|
3896
3932
|
const used = getUsedShares(options);
|
|
3897
|
-
const shares = new Set(
|
|
3933
|
+
const shares = /* @__PURE__ */ new Set();
|
|
3934
|
+
const addShare = (pkg) => {
|
|
3935
|
+
const shareItem = getNormalizeShareItem(pkg, resolvedOptions);
|
|
3936
|
+
shares.add(shareItem ? getCanonicalSharedKey(pkg, shareItem) : pkg);
|
|
3937
|
+
};
|
|
3938
|
+
used.forEach(addShare);
|
|
3898
3939
|
Object.keys(resolvedOptions.shared ?? {}).forEach((pkg) => {
|
|
3899
|
-
|
|
3940
|
+
const share = resolvedOptions.shared?.[pkg];
|
|
3941
|
+
if (share && !getSharedRequest(pkg, share).endsWith("/")) addShare(pkg);
|
|
3900
3942
|
});
|
|
3901
|
-
for (const [pkg, share] of Object.entries(resolvedOptions.shared ?? {})) if (pkg.endsWith("/")
|
|
3943
|
+
for (const [pkg, share] of Object.entries(resolvedOptions.shared ?? {})) if (share.shareConfig?.eager && getSharedRequest(pkg, share).endsWith("/")) for (const concrete of expandSharedPrefixKey(getSharedRequest(pkg, share), used)) addShare(concrete);
|
|
3902
3944
|
return orderSharedDependenciesFirst(Array.from(shares).sort((a, b) => {
|
|
3903
3945
|
const priority = (pkg) => pkg === "react" ? 0 : pkg === "react-dom" ? 1 : pkg.startsWith("react/") ? 2 : 3;
|
|
3904
3946
|
return priority(a) - priority(b) || a.localeCompare(b);
|
|
@@ -3911,7 +3953,8 @@ function getMaterializedShares(options) {
|
|
|
3911
3953
|
const usedForEager = options ? usedSharesByOptions.get(options) ?? [] : usedShares;
|
|
3912
3954
|
for (const [pkg, share] of Object.entries(resolvedOptions.shared ?? {})) {
|
|
3913
3955
|
if (!share.shareConfig?.eager) continue;
|
|
3914
|
-
|
|
3956
|
+
const request = getSharedRequest(pkg, share);
|
|
3957
|
+
if (request.endsWith("/")) for (const concrete of expandSharedPrefixKey(request, usedForEager)) shares.add(concrete);
|
|
3915
3958
|
else shares.add(pkg);
|
|
3916
3959
|
}
|
|
3917
3960
|
const configured = /* @__PURE__ */ new Map();
|
|
@@ -3939,10 +3982,14 @@ function getMaterializedShares(options) {
|
|
|
3939
3982
|
}
|
|
3940
3983
|
}
|
|
3941
3984
|
}
|
|
3942
|
-
|
|
3985
|
+
const sorted = [...shares].sort((a, b) => {
|
|
3943
3986
|
const priority = (pkg) => pkg === "react" ? 0 : pkg === "react-dom" ? 1 : pkg.startsWith("react/") ? 2 : 3;
|
|
3944
3987
|
return priority(a) - priority(b) || a.localeCompare(b);
|
|
3945
|
-
})
|
|
3988
|
+
});
|
|
3989
|
+
return orderSharedDependenciesFirst([...new Set(sorted.map((pkg) => {
|
|
3990
|
+
const shareItem = getNormalizeShareItem(pkg, resolvedOptions);
|
|
3991
|
+
return shareItem ? getCanonicalSharedKey(pkg, shareItem) : pkg;
|
|
3992
|
+
}))]);
|
|
3946
3993
|
}
|
|
3947
3994
|
/** Shared keys a share's package.json depends on (roots stand in for their subpaths, subpaths for their root), keyed by share. */
|
|
3948
3995
|
function getSharePrerequisites(ordered) {
|
|
@@ -4030,9 +4077,30 @@ function orderSharedDependenciesFirst(sharedPackages) {
|
|
|
4030
4077
|
}
|
|
4031
4078
|
function getShareItemForPreload(pkg, options = getNormalizeModuleFederationOptions()) {
|
|
4032
4079
|
const shared = options.shared;
|
|
4033
|
-
const
|
|
4080
|
+
const packageName = getPackageName(pkg);
|
|
4081
|
+
const wildcardKey = `${packageName}/`;
|
|
4034
4082
|
if (isExplicitSharedKey(pkg, options)) return shared[pkg];
|
|
4035
4083
|
if (isExplicitSharedKey(wildcardKey, options)) return shared[wildcardKey];
|
|
4084
|
+
if (pkg !== packageName && isExplicitSharedKey(packageName, options) && shared[packageName]?.shareConfig.import !== false && getCommonSharedSubpaths(packageName).includes(pkg)) return shared[packageName];
|
|
4085
|
+
const shareItem = getNormalizeShareItem(pkg, options);
|
|
4086
|
+
if (!shareItem) return void 0;
|
|
4087
|
+
if (shareItem.shareConfig.request === void 0 && shareItem.shareConfig.shareKey === void 0) return;
|
|
4088
|
+
const runtimeKey = getSharedRuntimeKey(pkg, shareItem);
|
|
4089
|
+
if (runtimeKey === pkg || runtimeKey.endsWith("/") && (pkg === runtimeKey.slice(0, -1) || pkg.startsWith(runtimeKey))) return shareItem;
|
|
4090
|
+
}
|
|
4091
|
+
/**
|
|
4092
|
+
* Entry-injected renderer wrappers (see `REACT_DOM_CLIENT_SHARE`) assign
|
|
4093
|
+
* `createRoot` only after `initPromise` and a dynamic import, so a standalone
|
|
4094
|
+
* remote must evaluate that wrapper before the app entry. The subpath is often
|
|
4095
|
+
* absent from `getMaterializedShares()` when pending shares is emitted:
|
|
4096
|
+
* `react-dom/` collapses to `react-dom`, and the entry import may not be
|
|
4097
|
+
* recorded yet.
|
|
4098
|
+
*/
|
|
4099
|
+
function shouldPreloadEntryDeferredReactDomClient(options) {
|
|
4100
|
+
if (options.hostInitInjectLocation !== "entry" || !isRemoteContainer(options)) return false;
|
|
4101
|
+
const shareItem = getShareItemForPreload(REACT_DOM_CLIENT_SHARE, options);
|
|
4102
|
+
if (!shareItem || shareItem.shareConfig.singleton !== true) return false;
|
|
4103
|
+
return shareItem.shareConfig.import !== false && !shareItem.shareConfig.treeShaking;
|
|
4036
4104
|
}
|
|
4037
4105
|
function generateSharedCacheSeedItem(pkg, shareItem, importPath, options = getNormalizeModuleFederationOptions()) {
|
|
4038
4106
|
const cacheDescriptor = getSharedCacheDescriptor(pkg, shareItem);
|
|
@@ -4054,6 +4122,9 @@ const normalizeRuntimeShareCode = `const __mfNormalizeRuntimeShare = (mod) => {
|
|
|
4054
4122
|
for (let i = 0; i < 5; i++) {
|
|
4055
4123
|
const defaultExport = current?.default;
|
|
4056
4124
|
if (!defaultExport || typeof defaultExport !== "object" || Object.keys(defaultExport).length === 0) break;
|
|
4125
|
+
// Only unwrap plain CJS namespaces; spreading a class instance would drop its prototype.
|
|
4126
|
+
const proto = Object.getPrototypeOf(defaultExport);
|
|
4127
|
+
if (proto !== null && proto !== Object.prototype) break;
|
|
4057
4128
|
const namedValues = Object.keys(current).filter((key) => key !== "default").map((key) => current[key]);
|
|
4058
4129
|
if (namedValues.length > 0 && namedValues.some((value) => value !== undefined)) break;
|
|
4059
4130
|
current = defaultExport;
|
|
@@ -4217,7 +4288,28 @@ const externalSharedProviderSelectionHelperCode = `const __mfSelectExternalShare
|
|
|
4217
4288
|
) return undefined;
|
|
4218
4289
|
return { provider, scopeRootProvider };
|
|
4219
4290
|
};`;
|
|
4220
|
-
|
|
4291
|
+
/**
|
|
4292
|
+
* A consume-only stub never outranks a provider: when registering this container's
|
|
4293
|
+
* `import: false` share replaces an unloaded provider of the same version (#1311),
|
|
4294
|
+
* the `afterRegisterShare` hook restores the provider. Registered once per instance.
|
|
4295
|
+
*/
|
|
4296
|
+
function generateKeepProvidersOverStubsCode(runtimeVar) {
|
|
4297
|
+
return `if (!${runtimeVar}.__mfKeepAdoptedProviders) {
|
|
4298
|
+
${runtimeVar}.__mfKeepAdoptedProviders = true;
|
|
4299
|
+
${runtimeVar}.sharedHandler?.hooks?.lifecycle?.afterRegisterShare?.on?.((args) => {
|
|
4300
|
+
const { shared, previousShared, registeredShared } = args || {};
|
|
4301
|
+
if (
|
|
4302
|
+
shared?.shareConfig?.import !== false ||
|
|
4303
|
+
registeredShared !== shared ||
|
|
4304
|
+
!previousShared ||
|
|
4305
|
+
previousShared.shareConfig?.import === false
|
|
4306
|
+
) return;
|
|
4307
|
+
const versions = ${runtimeVar}.shareScopeMap?.[args.scope]?.[args.pkgName];
|
|
4308
|
+
if (versions && versions[shared.version] === shared) versions[shared.version] = previousShared;
|
|
4309
|
+
});
|
|
4310
|
+
}`;
|
|
4311
|
+
}
|
|
4312
|
+
function generateRuntimeSharedCacheSeedCode(shareStrategy, options, command = "build") {
|
|
4221
4313
|
const seedBatches = getShareBatches(options, false);
|
|
4222
4314
|
const seedOrder = seedBatches.flat();
|
|
4223
4315
|
const seedIndex = new Map(seedOrder.map((pkg, index) => [pkg, index]));
|
|
@@ -4231,7 +4323,7 @@ function generateRuntimeSharedCacheSeedCode(shareStrategy, options) {
|
|
|
4231
4323
|
// import and set materialize. An import:false share has no local fallback
|
|
4232
4324
|
// though, so on a cold request (materialize not set yet) it must still be
|
|
4233
4325
|
// attempted here, or it is never seeded and its consumer reads it undefined.
|
|
4234
|
-
const __mfSeedKeys = __mfSeedOrder.filter((pkg) => usedShared[pkg] && (usedShared[pkg].materialize !== false || usedShared[pkg].shareConfig?.import === false));
|
|
4326
|
+
const __mfSeedKeys = __mfSeedOrder.filter((pkg) => usedShared[pkg] && (usedShared[pkg].materialize !== false || (usedShared[pkg].shareConfig?.import === false && !usedShared[pkg].lazy)));
|
|
4235
4327
|
__mfModuleCache.providerInit ||= new Map();
|
|
4236
4328
|
const __mfInitializeProviderOnce = (key, initialize) => {
|
|
4237
4329
|
const existing = __mfModuleCache.providerInit.get(key);
|
|
@@ -4264,6 +4356,16 @@ function generateRuntimeSharedCacheSeedCode(shareStrategy, options) {
|
|
|
4264
4356
|
);
|
|
4265
4357
|
return;
|
|
4266
4358
|
}
|
|
4359
|
+
${command === "serve" ? `// A pending webpack provider for this share, or for its package when this
|
|
4360
|
+
// is a subpath, is only bridged after init(). Seeding the local fallback now
|
|
4361
|
+
// would evaluate the package's dev proxy, which snapshots its exports, before
|
|
4362
|
+
// the bridge runs and pin a second copy. The proxy seeds itself on first import.
|
|
4363
|
+
if (
|
|
4364
|
+
typeof __mfGetPendingExternalSharedProvider === 'function' &&
|
|
4365
|
+
__mfGetPendingExternalSharedProvider(pkg, share)
|
|
4366
|
+
) {
|
|
4367
|
+
return;
|
|
4368
|
+
}` : ""}
|
|
4267
4369
|
const externalProvider = typeof __mfGetExternalSharedProvider === 'function'
|
|
4268
4370
|
? __mfGetExternalSharedProvider(pkg, share)
|
|
4269
4371
|
: undefined;
|
|
@@ -4283,8 +4385,9 @@ function generateRuntimeSharedCacheSeedCode(shareStrategy, options) {
|
|
|
4283
4385
|
__mfNormalizeRuntimeShare(externalResolved),
|
|
4284
4386
|
externalProvider.from
|
|
4285
4387
|
);
|
|
4388
|
+
return;
|
|
4286
4389
|
}
|
|
4287
|
-
return;
|
|
4390
|
+
if (typeof isWebpackProvider === 'function' && isWebpackProvider(externalProvider)) return;
|
|
4288
4391
|
}
|
|
4289
4392
|
const providerKey = cacheDescriptor.canonical;
|
|
4290
4393
|
const resolved = await __mfInitializeProviderOnce(providerKey, async () => {
|
|
@@ -4292,6 +4395,12 @@ function generateRuntimeSharedCacheSeedCode(shareStrategy, options) {
|
|
|
4292
4395
|
const mod = typeof factory === "function" ? factory() : factory;
|
|
4293
4396
|
return Promise.resolve(mod);
|
|
4294
4397
|
});
|
|
4398
|
+
// The seeded local copy is what this container's consumers are bound to.
|
|
4399
|
+
// Flag the Runtime's provider as eager so a same-version sibling cannot
|
|
4400
|
+
// take over the share scope slot via the Runtime's name tie-break.
|
|
4401
|
+
for (const provider of initRes.options.shared?.[pkg] || []) {
|
|
4402
|
+
if (provider.get === share.get) provider.eager = true;
|
|
4403
|
+
}
|
|
4295
4404
|
${normalizeRuntimeShareCode}
|
|
4296
4405
|
const normalizedModule = __mfNormalizeRuntimeShare(resolved);
|
|
4297
4406
|
const exportModule = normalizedModule === resolved ? {...resolved} : normalizedModule;
|
|
@@ -4564,7 +4673,7 @@ function generateTreeShakingSnapshotPluginCode(enabled) {
|
|
|
4564
4673
|
},
|
|
4565
4674
|
});`;
|
|
4566
4675
|
}
|
|
4567
|
-
function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(options), command = "build", exportConditions) {
|
|
4676
|
+
function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(options), command = "build", exportConditions, isSsrBuild = false) {
|
|
4568
4677
|
const needsSharedProviderSelectionHelper = hasShared(options);
|
|
4569
4678
|
const hasTreeShakingShared = Object.values(options.shared ?? {}).some((share) => !!share?.shareConfig.treeShaking);
|
|
4570
4679
|
const hasMultipleShareScopes = Array.isArray(options.shareScope);
|
|
@@ -4576,7 +4685,7 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
4576
4685
|
...hasTreeShakingShared ? ["getRemoteEntry"] : []
|
|
4577
4686
|
].join(", ");
|
|
4578
4687
|
const runtimeHelperImports = [...hasTreeShakingShared ? ["global as runtimeGlobal"] : [], ...needsSharedProviderSelectionHelper ? ["share as runtimeShare"] : []];
|
|
4579
|
-
const pluginImportNames = options.runtimePlugins.map((p, i) => {
|
|
4688
|
+
const pluginImportNames = filterRuntimePluginsForTarget(options.runtimePlugins, SSR_ONLY_RUNTIME_PLUGINS, isSsrBuild).map((p, i) => {
|
|
4580
4689
|
if (typeof p === "string") return [
|
|
4581
4690
|
`$runtimePlugin_${i}`,
|
|
4582
4691
|
`import $runtimePlugin_${i} from "${p}";`,
|
|
@@ -4899,13 +5008,36 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
4899
5008
|
};
|
|
4900
5009
|
}
|
|
4901
5010
|
const runtimeResolveShareHook = initRes.sharedHandler.hooks.lifecycle.resolveShare;
|
|
5011
|
+
// Registering this container's shares lets its consume-only stub displace the parent's
|
|
5012
|
+
// unloaded same-version provider whenever this container's name sorts after the parent's
|
|
5013
|
+
// (the Runtime keeps the higher name). Nothing can be loaded from a stub, so put the
|
|
5014
|
+
// provider back; a share bridged later, e.g. from a lazy import(), still finds it.
|
|
5015
|
+
${generateKeepProvidersOverStubsCode("initRes")}
|
|
4902
5016
|
const __mfRuntimeProviderOrigins = new WeakMap();
|
|
4903
5017
|
runtimeResolveShareHook.on((args) => {
|
|
4904
5018
|
const loadId = args.shareInfo?.[__mfRuntimeShareLoadIdKey];
|
|
4905
5019
|
const resolver = args.resolver;
|
|
4906
5020
|
if (typeof resolver !== "function") return args;
|
|
4907
5021
|
const instrumentedResolver = (...resolverArgs) => {
|
|
4908
|
-
|
|
5022
|
+
let resolved = resolver(...resolverArgs);
|
|
5023
|
+
// A consume-only stub can never be loaded. The Runtime still settles on one when
|
|
5024
|
+
// it carries the highest version, e.g. a parent that registers its provider under
|
|
5025
|
+
// "0.0.0"; hand back the provider this container selects for itself instead.
|
|
5026
|
+
if (
|
|
5027
|
+
resolved?.shared?.shareConfig?.import === false &&
|
|
5028
|
+
typeof __mfSelectSharedProvider === "function" &&
|
|
5029
|
+
usedShared[args.pkgName]
|
|
5030
|
+
) {
|
|
5031
|
+
const provider = __mfSelectSharedProvider(
|
|
5032
|
+
args.shareScopeMap?.[args.scope]?.[args.pkgName],
|
|
5033
|
+
args.pkgName,
|
|
5034
|
+
usedShared[args.pkgName],
|
|
5035
|
+
'${options.shareStrategy}'
|
|
5036
|
+
);
|
|
5037
|
+
if (provider && provider.shareConfig?.import !== false) {
|
|
5038
|
+
resolved = { shared: provider, useTreesShaking: resolved.useTreesShaking };
|
|
5039
|
+
}
|
|
5040
|
+
}
|
|
4909
5041
|
const selectedProvider = resolved?.shared;
|
|
4910
5042
|
if (
|
|
4911
5043
|
selectedProvider &&
|
|
@@ -5318,7 +5450,7 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
5318
5450
|
);
|
|
5319
5451
|
}
|
|
5320
5452
|
}
|
|
5321
|
-
${generateRuntimeSharedCacheSeedCode(options.shareStrategy, options)}
|
|
5453
|
+
${generateRuntimeSharedCacheSeedCode(options.shareStrategy, options, command)}
|
|
5322
5454
|
${initializeSharingCode}
|
|
5323
5455
|
__mfRestoreForeignSharedProviders();
|
|
5324
5456
|
// Calling provider.get() marks a provider as loaded. Wait until the Runtime has
|
|
@@ -5336,9 +5468,13 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
5336
5468
|
);
|
|
5337
5469
|
}));
|
|
5338
5470
|
};
|
|
5339
|
-
await __mfBridgeSharedProviders();
|
|
5340
5471
|
if (__mfUsesWebpackShareScope) {
|
|
5472
|
+
// A webpack host's loadShare() awaits initializeSharing(), which awaits this
|
|
5473
|
+
// init(). Bridging here would call the host's provider.get() and re-enter
|
|
5474
|
+
// loadShare(), so both promises wait on each other forever (#1326).
|
|
5341
5475
|
__mfLateBridgeShared = __mfBridgeSharedProviders;
|
|
5476
|
+
} else {
|
|
5477
|
+
await __mfBridgeSharedProviders();
|
|
5342
5478
|
}
|
|
5343
5479
|
try {
|
|
5344
5480
|
const allInstances = globalThis.__FEDERATION__?.__SHARE__;
|
|
@@ -5492,6 +5628,29 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
5492
5628
|
(pkg) => !__mfBlockedSeedKeys.has(__mfSeedIndex.get(pkg))
|
|
5493
5629
|
));
|
|
5494
5630
|
await __mfSeedLocalShared(__mfReadyDeferredSeedKeys);
|
|
5631
|
+
${command === "build" ? `// A consume-only share reached only through import() is bridged when that import runs
|
|
5632
|
+
// (see pluginLazyConsumeOnlyShares), through the same provider selection init() uses.
|
|
5633
|
+
const __mfLazyShareLoads = new Map();
|
|
5634
|
+
__mfResolveState.loadLazyShares = async (names) => {
|
|
5635
|
+
const requested = new Set(names);
|
|
5636
|
+
for (const batch of __mfMaterializedShareBatches) await Promise.all(batch.filter((pkg) => requested.has(pkg)).map((pkg) => {
|
|
5637
|
+
const share = usedShared[pkg];
|
|
5638
|
+
if (!share || !share.lazy || !__mfIsRuntimeOnlySharePending(pkg)) return;
|
|
5639
|
+
let load = __mfLazyShareLoads.get(pkg);
|
|
5640
|
+
if (!load) {
|
|
5641
|
+
load = __mfBridgeExternalSharedProvider(
|
|
5642
|
+
pkg,
|
|
5643
|
+
share,
|
|
5644
|
+
${hasMultipleShareScopes ? "getShareVersions(pkg, share)" : "shared[pkg]"},
|
|
5645
|
+
initialShared[pkg],
|
|
5646
|
+
undefined
|
|
5647
|
+
).then(() => __mfIsRuntimeOnlySharePending(pkg) ? __mfResolveImportFalseShared(pkg, share) : undefined);
|
|
5648
|
+
load.catch(() => __mfLazyShareLoads.delete(pkg));
|
|
5649
|
+
__mfLazyShareLoads.set(pkg, load);
|
|
5650
|
+
}
|
|
5651
|
+
return load;
|
|
5652
|
+
}));
|
|
5653
|
+
};` : ""}
|
|
5495
5654
|
initResolve(initRes)
|
|
5496
5655
|
return initRes
|
|
5497
5656
|
}
|
|
@@ -5508,8 +5667,13 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
5508
5667
|
${guardHostAutoInit ? `let __mfInitPromise;
|
|
5509
5668
|
function __mfGuardedInit(shared, initScope, remoteEntryInitOptions) {
|
|
5510
5669
|
if (shared === undefined && __mfInitPromise) return __mfInitPromise;
|
|
5511
|
-
|
|
5512
|
-
|
|
5670
|
+
// A call skipped by the circular-init guard resolves to undefined and must not
|
|
5671
|
+
// replace the cached result of the call that actually initialized the container.
|
|
5672
|
+
const prev = __mfInitPromise;
|
|
5673
|
+
const next = init(shared, initScope, remoteEntryInitOptions);
|
|
5674
|
+
__mfInitPromise = prev ? next.then((res) => (res === undefined ? prev : res)) : next;
|
|
5675
|
+
if (prev) __mfInitPromise.catch(() => {});
|
|
5676
|
+
return next;
|
|
5513
5677
|
}
|
|
5514
5678
|
export { __mfGuardedInit as init, getExposes as get }` : `export { init, getExposes as get }`}
|
|
5515
5679
|
`;
|
|
@@ -5590,7 +5754,8 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build", options
|
|
|
5590
5754
|
for (const __mfHostInitShareBatch of __mfHostInitShareBatches) {
|
|
5591
5755
|
await Promise.all(__mfHostInitShareBatch.map(async (pkg) => {
|
|
5592
5756
|
const share = usedShared[pkg];
|
|
5593
|
-
|
|
5757
|
+
// A standalone container has no dynamic-import boundary to load a lazy share behind.
|
|
5758
|
+
if (!share || (share.materialize === false && !share.lazy)) return;
|
|
5594
5759
|
// remoteEntry.init resolves tree-enabled shares into the
|
|
5595
5760
|
// coverage-aware cache. Never republish that selected partial under
|
|
5596
5761
|
// a generic full-module key here.
|
|
@@ -5621,20 +5786,7 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build", options
|
|
|
5621
5786
|
// container's own stub and lets it displace an unloaded adopted
|
|
5622
5787
|
// provider whenever this container's name sorts after the provider's
|
|
5623
5788
|
// (#1311). Put the provider back: a stub never outranks a provider.
|
|
5624
|
-
|
|
5625
|
-
runtime.__mfKeepAdoptedProviders = true;
|
|
5626
|
-
runtime.sharedHandler?.hooks?.lifecycle?.afterRegisterShare?.on?.((args) => {
|
|
5627
|
-
const { shared, previousShared, registeredShared } = args || {};
|
|
5628
|
-
if (
|
|
5629
|
-
shared?.shareConfig?.import !== false ||
|
|
5630
|
-
registeredShared !== shared ||
|
|
5631
|
-
!previousShared ||
|
|
5632
|
-
previousShared.shareConfig?.import === false
|
|
5633
|
-
) return;
|
|
5634
|
-
const versions = runtime.shareScopeMap?.[args.scope]?.[args.pkgName];
|
|
5635
|
-
if (versions && versions[shared.version] === shared) versions[shared.version] = previousShared;
|
|
5636
|
-
});
|
|
5637
|
-
}
|
|
5789
|
+
${generateKeepProvidersOverStubsCode("runtime")}
|
|
5638
5790
|
for (const instance of globalThis.__FEDERATION__?.__INSTANCES__ || []) {
|
|
5639
5791
|
for (const scopeName of __mfScopeNames) {
|
|
5640
5792
|
const versions = instance?.shareScopeMap?.[scopeName]?.[pkg];
|
|
@@ -5734,22 +5886,32 @@ function getPendingSharesState(options) {
|
|
|
5734
5886
|
}
|
|
5735
5887
|
function generatePendingSharesCode(command = "build", options) {
|
|
5736
5888
|
const resolvedOptions = options ?? getNormalizeModuleFederationOptions();
|
|
5737
|
-
const
|
|
5889
|
+
const pendingSharePkgs = command === "build" ? getMaterializedShares(options).filter((pkg) => {
|
|
5738
5890
|
const shareItem = getShareItemForPreload(pkg, resolvedOptions);
|
|
5739
5891
|
if (!shareItem || pkg.endsWith("/")) return false;
|
|
5740
5892
|
if (shareItem.shareConfig.eager) return false;
|
|
5741
5893
|
return shareItem.shareConfig.import !== false && !shareItem.shareConfig.treeShaking;
|
|
5742
|
-
})
|
|
5894
|
+
}) : [];
|
|
5895
|
+
if (command === "build" && shouldPreloadEntryDeferredReactDomClient(resolvedOptions) && !pendingSharePkgs.includes("react-dom/client")) pendingSharePkgs.push(REACT_DOM_CLIENT_SHARE);
|
|
5896
|
+
const pendingShareImports = pendingSharePkgs.map((pkg) => `[${toSafeJsLiteral(pkg)}, () => import(${toSafeJsLiteral(getLoadShareModulePath(pkg, false, options))})]`);
|
|
5743
5897
|
return `
|
|
5744
5898
|
${getRuntimeModuleCacheBootstrapCode()}
|
|
5745
5899
|
${sharedCacheHelperCode}
|
|
5746
5900
|
const __mfPendingShareImports = [${pendingShareImports.join(", ")}];
|
|
5747
5901
|
export async function preloadPendingShares() {
|
|
5748
5902
|
if (__mfPendingShareImports.length === 0) return;
|
|
5903
|
+
const __mfRendererShare = ${toSafeJsLiteral(REACT_DOM_CLIENT_SHARE)};
|
|
5904
|
+
const __mfRendererParent = ${toSafeJsLiteral(getPackageName(REACT_DOM_CLIENT_SHARE))};
|
|
5749
5905
|
const {usedShared} = await import("${getLocalSharedImportMapPath(options)}");
|
|
5750
5906
|
await Promise.all(__mfPendingShareImports.map(async ([pkg, load]) => {
|
|
5751
|
-
const
|
|
5752
|
-
|
|
5907
|
+
const exactShare = usedShared[pkg];
|
|
5908
|
+
const share = exactShare ?? (pkg === __mfRendererShare ? usedShared[__mfRendererParent] : undefined);
|
|
5909
|
+
if (!share || share.treeShaking || share.shareConfig?.import === false) return;
|
|
5910
|
+
// The collapsed parent does not mark the renderer subpath materialized until the entry
|
|
5911
|
+
// imports it, and that import map can be emitted first. The deferred renderer wrapper
|
|
5912
|
+
// still has to run before a standalone entry reads createRoot. A cache hit (the host
|
|
5913
|
+
// renderer) skips load(), so a nested leaf does not import its own client.
|
|
5914
|
+
if (exactShare && exactShare.materialize === false && pkg !== __mfRendererShare) return;
|
|
5753
5915
|
const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
|
|
5754
5916
|
if (__mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) !== undefined) return;
|
|
5755
5917
|
await load().catch((err) => console.warn("[module-federation] shared preload failed:", pkg, err));
|
|
@@ -6413,7 +6575,7 @@ for (const __mfRemoteEntryPrefetchUrl of __mfRemoteEntryPrefetchUrls) {
|
|
|
6413
6575
|
}
|
|
6414
6576
|
` : "";
|
|
6415
6577
|
const sharedPreloadSources = _command === "serve" && waitsForInit && isRemoteOnlyContainer(normalizedOptions) && federationOptions ? Array.from(getUsedShares(federationOptions)).filter((pkg) => !pkg.endsWith("/")).filter((pkg) => {
|
|
6416
|
-
const shareItem =
|
|
6578
|
+
const shareItem = getNormalizeShareItem(pkg, federationOptions);
|
|
6417
6579
|
const isExplicitShare = Object.hasOwn(federationOptions.shared, pkg);
|
|
6418
6580
|
return shareItem?.shareConfig?.singleton === true && shareItem?.shareConfig?.import !== false && !shareItem?.shareConfig?.treeShaking && (isExplicitShare || typeof shareItem?.shareConfig?.import === "string" || Boolean(getProjectResolvedImportPath(pkg)));
|
|
6419
6581
|
}).map((pkg) => toViteEncodedId(getLoadShareModulePath(pkg, false, federationOptions))) : [];
|
|
@@ -6546,6 +6708,19 @@ for (const __mfRemoteEntryPrefetchUrl of __mfRemoteEntryPrefetchUrls) {
|
|
|
6546
6708
|
apply: "serve",
|
|
6547
6709
|
config(_config, { command }) {
|
|
6548
6710
|
_command = command;
|
|
6711
|
+
const isRemoteEntry = entryName === "remoteEntry" && federationOptions !== void 0 && isRemoteContainer(federationOptions);
|
|
6712
|
+
if (command === "serve" && _config.experimental?.bundledDev && isRemoteEntry) {
|
|
6713
|
+
_config.experimental = {
|
|
6714
|
+
..._config.experimental,
|
|
6715
|
+
bundledDev: false
|
|
6716
|
+
};
|
|
6717
|
+
_config.environments ??= {};
|
|
6718
|
+
_config.environments.client ??= {};
|
|
6719
|
+
if (_config.environments.client.isBundled !== false) {
|
|
6720
|
+
_config.environments.client.isBundled = false;
|
|
6721
|
+
mfWarn("Vite bundledDev is disabled for the client environment of a Module Federation remote container so its remoteEntry keeps the standard init/get contract.");
|
|
6722
|
+
}
|
|
6723
|
+
}
|
|
6549
6724
|
},
|
|
6550
6725
|
configResolved(config) {
|
|
6551
6726
|
viteConfig = config;
|
|
@@ -6842,17 +7017,20 @@ function checkAliasConflicts(options) {
|
|
|
6842
7017
|
}
|
|
6843
7018
|
return false;
|
|
6844
7019
|
};
|
|
6845
|
-
for (const sharedKey of sharedKeys)
|
|
6846
|
-
const
|
|
6847
|
-
|
|
6848
|
-
|
|
6849
|
-
|
|
6850
|
-
if (
|
|
6851
|
-
|
|
6852
|
-
|
|
6853
|
-
|
|
6854
|
-
|
|
6855
|
-
|
|
7020
|
+
for (const sharedKey of sharedKeys) {
|
|
7021
|
+
const request = getSharedRequest(sharedKey, shared[sharedKey]);
|
|
7022
|
+
for (const aliasEntry of userAliases) {
|
|
7023
|
+
const replacement = aliasEntry.replacement;
|
|
7024
|
+
if (!matchesSharedKey(aliasEntry, request)) continue;
|
|
7025
|
+
if (replacement === "$1") break;
|
|
7026
|
+
if (typeof replacement === "string") {
|
|
7027
|
+
if (getPackageNameFromNodeModulePath(replacement) === (request.endsWith("/") ? request.slice(0, -1) : request)) continue;
|
|
7028
|
+
conflicts.push({
|
|
7029
|
+
sharedModule: sharedKey,
|
|
7030
|
+
alias: String(aliasEntry.find),
|
|
7031
|
+
target: replacement
|
|
7032
|
+
});
|
|
7033
|
+
}
|
|
6856
7034
|
}
|
|
6857
7035
|
}
|
|
6858
7036
|
if (conflicts.length > 0) {
|
|
@@ -7567,9 +7745,6 @@ function pluginExternalRuntimeCore() {
|
|
|
7567
7745
|
};
|
|
7568
7746
|
}
|
|
7569
7747
|
//#endregion
|
|
7570
|
-
//#region package.json
|
|
7571
|
-
var version$1 = "1.22.1";
|
|
7572
|
-
//#endregion
|
|
7573
7748
|
//#region src/virtualModules/index.ts
|
|
7574
7749
|
function initVirtualModules(command, remoteEntryId, enableSsrInit = false, options) {
|
|
7575
7750
|
writeLocalSharedImportMap(options);
|
|
@@ -7587,6 +7762,11 @@ const JS_EXTENSIONS = [
|
|
|
7587
7762
|
".mjs",
|
|
7588
7763
|
".cjs"
|
|
7589
7764
|
];
|
|
7765
|
+
/** A module path without its JS extension, so `./src/App` matches `/root/src/App.tsx`. */
|
|
7766
|
+
const stripKnownJsExtension = (file) => {
|
|
7767
|
+
const ext = path$1.extname(file);
|
|
7768
|
+
return JS_EXTENSIONS.includes(ext) ? path$1.join(path$1.dirname(file), path$1.basename(file, ext)) : file;
|
|
7769
|
+
};
|
|
7590
7770
|
/**
|
|
7591
7771
|
* Creates an empty asset map structure for tracking JS and CSS assets
|
|
7592
7772
|
* @returns Initialized asset map with sync/async arrays for JS and CSS
|
|
@@ -7705,8 +7885,8 @@ const processModuleAssets = (bundle, filesMap, moduleMatcher, options = {}) => {
|
|
|
7705
7885
|
const comparableModulePath = options.root ? path$1.resolve(options.root, modulePath) : modulePath;
|
|
7706
7886
|
const comparableModulePaths = [comparableModulePath];
|
|
7707
7887
|
if (options.stripKnownJsExtensions) {
|
|
7708
|
-
const
|
|
7709
|
-
if (
|
|
7888
|
+
const stripped = stripKnownJsExtension(comparableModulePath);
|
|
7889
|
+
if (stripped !== comparableModulePath) comparableModulePaths.push(stripped);
|
|
7710
7890
|
}
|
|
7711
7891
|
const matchKey = comparableModulePaths.map(moduleMatcher).find(Boolean);
|
|
7712
7892
|
if (!matchKey) continue;
|
|
@@ -7767,6 +7947,119 @@ const buildFileToShareKeyMap = async (shareKeys, resolveFn, options) => {
|
|
|
7767
7947
|
return fileToShareKey;
|
|
7768
7948
|
};
|
|
7769
7949
|
//#endregion
|
|
7950
|
+
//#region src/plugins/pluginLazyConsumeOnlyShares.ts
|
|
7951
|
+
const chunkModuleIds = (chunk) => [...chunk.facadeModuleId ? [chunk.facadeModuleId] : [], ...chunk.moduleIds ?? Object.keys(chunk.modules ?? {})];
|
|
7952
|
+
function buildLazyShareGraph(chunks, wrapperShares, exposeModules) {
|
|
7953
|
+
const sharesInChunk = /* @__PURE__ */ new Map();
|
|
7954
|
+
const startupRoots = [];
|
|
7955
|
+
for (const [fileName, chunk] of Object.entries(chunks)) {
|
|
7956
|
+
if (chunk.type !== "chunk") continue;
|
|
7957
|
+
const moduleIds = chunkModuleIds(chunk);
|
|
7958
|
+
sharesInChunk.set(fileName, new Set(moduleIds.map((id) => wrapperShares.get(normalizeVirtualModuleId(id))).filter((share) => share !== void 0)));
|
|
7959
|
+
if (chunk.isEntry || moduleIds.some((id) => exposeModules.has(stripKnownJsExtension(id)))) startupRoots.push(fileName);
|
|
7960
|
+
}
|
|
7961
|
+
const sharesInClosure = (roots) => new Set(collectStaticChunks(chunks, roots).flatMap((chunk) => [...sharesInChunk.get(chunk.fileName) ?? []]));
|
|
7962
|
+
const lazyShares = new Set([...sharesInChunk.values()].flatMap((shares) => [...shares]));
|
|
7963
|
+
for (const share of sharesInClosure(startupRoots)) lazyShares.delete(share);
|
|
7964
|
+
const sharesByChunk = /* @__PURE__ */ new Map();
|
|
7965
|
+
if (lazyShares.size > 0) for (const fileName of sharesInChunk.keys()) {
|
|
7966
|
+
const shares = [...sharesInClosure([fileName])].filter((share) => lazyShares.has(share));
|
|
7967
|
+
if (shares.length > 0) sharesByChunk.set(fileName, shares.sort());
|
|
7968
|
+
}
|
|
7969
|
+
return {
|
|
7970
|
+
lazyShares,
|
|
7971
|
+
sharesByChunk
|
|
7972
|
+
};
|
|
7973
|
+
}
|
|
7974
|
+
const COMMENTS = String.raw`(?:\s|\/\*[\s\S]*?\*\/|\/\/[^\n]*\n)*`;
|
|
7975
|
+
const DYNAMIC_IMPORT_REGEX = new RegExp(String.raw`\bimport\(${COMMENTS}(["'` + "`" + String.raw`])([^"'` + "`" + String.raw`\n]+)\1${COMMENTS}\)`, "g");
|
|
7976
|
+
const QUOTES = [
|
|
7977
|
+
"\"",
|
|
7978
|
+
"'",
|
|
7979
|
+
"`"
|
|
7980
|
+
];
|
|
7981
|
+
/**
|
|
7982
|
+
* A consume-only (`import: false`) share that only a dynamic `import()` reaches is
|
|
7983
|
+
* left out of `init()` and bridged when that import runs: the import expression is
|
|
7984
|
+
* wrapped so the share is in the cache before the chunk evaluates. There is no
|
|
7985
|
+
* other async boundary in an ESM graph without top-level await, so a wrapper
|
|
7986
|
+
* reached statically from an entry or an expose keeps loading during `init()`.
|
|
7987
|
+
*/
|
|
7988
|
+
function pluginLazyConsumeOnlyShares(options) {
|
|
7989
|
+
let viteConfig;
|
|
7990
|
+
const graphs = /* @__PURE__ */ new WeakMap();
|
|
7991
|
+
const helperName = `__mfLoadLazyShares_${options.internalName.replace(/[^A-Za-z0-9_$]/g, "_")}`;
|
|
7992
|
+
return {
|
|
7993
|
+
name: "module-federation:lazy-consume-only-shares",
|
|
7994
|
+
apply: "build",
|
|
7995
|
+
configResolved(config) {
|
|
7996
|
+
viteConfig = config;
|
|
7997
|
+
},
|
|
7998
|
+
renderChunk(code, chunk, _outputOptions, meta) {
|
|
7999
|
+
const renderedChunk = chunk;
|
|
8000
|
+
const chunks = meta?.chunks;
|
|
8001
|
+
if (!chunks || Object.keys(options.exposes).length === 0) return null;
|
|
8002
|
+
if (isServerBuildContext(this, viteConfig)) return null;
|
|
8003
|
+
let graph = graphs.get(chunks);
|
|
8004
|
+
if (!graph) {
|
|
8005
|
+
const isRolldown = getIsRolldown(this);
|
|
8006
|
+
const wrapperShares = /* @__PURE__ */ new Map();
|
|
8007
|
+
for (const shareKey of getUsedShares(options)) {
|
|
8008
|
+
const shareConfig = getNormalizeShareItem(shareKey, options)?.shareConfig;
|
|
8009
|
+
if (shareConfig?.import !== false || shareConfig.eager || shareConfig.treeShaking) continue;
|
|
8010
|
+
wrapperShares.set(normalizeVirtualModuleId(getLoadShareModulePath(shareKey, isRolldown, options)), shareKey);
|
|
8011
|
+
}
|
|
8012
|
+
const root = viteConfig?.root ?? process.cwd();
|
|
8013
|
+
graph = buildLazyShareGraph(chunks, wrapperShares, new Set(Object.values(options.exposes).map((expose) => stripKnownJsExtension(path$1.resolve(root, expose.import)))));
|
|
8014
|
+
graphs.set(chunks, graph);
|
|
8015
|
+
}
|
|
8016
|
+
if (graph.lazyShares.size === 0) return null;
|
|
8017
|
+
const rewriter = new CodeRewriter(code);
|
|
8018
|
+
let edited = false;
|
|
8019
|
+
const importMapId = normalizeVirtualModuleId(getLocalSharedImportMapPath(options));
|
|
8020
|
+
const isImportMapChunk = chunkModuleIds(renderedChunk).some((id) => normalizeVirtualModuleId(id) === importMapId);
|
|
8021
|
+
if (isImportMapChunk) for (const quote of QUOTES) {
|
|
8022
|
+
const literal = `${quote}${LAZY_CONSUME_ONLY_SHARES_PLACEHOLDER}${quote}`;
|
|
8023
|
+
const start = code.indexOf(literal);
|
|
8024
|
+
if (start === -1) continue;
|
|
8025
|
+
rewriter.overwrite(start, start + literal.length, JSON.stringify([...graph.lazyShares].sort()));
|
|
8026
|
+
edited = true;
|
|
8027
|
+
break;
|
|
8028
|
+
}
|
|
8029
|
+
const chunkDir = path$1.posix.dirname(renderedChunk.fileName);
|
|
8030
|
+
const codePositions = createCodePositionMap(code);
|
|
8031
|
+
let usesHelper = false;
|
|
8032
|
+
for (const match of isImportMapChunk ? [] : code.matchAll(DYNAMIC_IMPORT_REGEX)) {
|
|
8033
|
+
const [expression, , specifier] = match;
|
|
8034
|
+
const start = match.index;
|
|
8035
|
+
if (!codePositions[start]) continue;
|
|
8036
|
+
const target = path$1.posix.normalize(path$1.posix.join(chunkDir, specifier));
|
|
8037
|
+
const shares = graph.sharesByChunk.get(target);
|
|
8038
|
+
if (!shares || !renderedChunk.dynamicImports.includes(target)) continue;
|
|
8039
|
+
rewriter.overwrite(start, start + expression.length, `${helperName}(${JSON.stringify(shares)}).then(() => ${expression})`);
|
|
8040
|
+
usesHelper = edited = true;
|
|
8041
|
+
}
|
|
8042
|
+
if (!edited) return null;
|
|
8043
|
+
if (usesHelper) {
|
|
8044
|
+
const stateKey = JSON.stringify(getRuntimeInitGlobalKey(getRuntimeInitStatusImportId(options)));
|
|
8045
|
+
rewriter.overwrite(code.length, code.length, `
|
|
8046
|
+
function ${helperName}(names) {
|
|
8047
|
+
const state = globalThis[${stateKey}];
|
|
8048
|
+
return state ? state.initPromise.then(() => (typeof state.loadLazyShares === "function" ? state.loadLazyShares(names) : undefined)) : Promise.resolve();
|
|
8049
|
+
}
|
|
8050
|
+
`);
|
|
8051
|
+
}
|
|
8052
|
+
return {
|
|
8053
|
+
code: rewriter.toString(),
|
|
8054
|
+
map: rewriter.generateMap(renderedChunk.fileName)
|
|
8055
|
+
};
|
|
8056
|
+
}
|
|
8057
|
+
};
|
|
8058
|
+
}
|
|
8059
|
+
//#endregion
|
|
8060
|
+
//#region package.json
|
|
8061
|
+
var version$1 = "1.23.1";
|
|
8062
|
+
//#endregion
|
|
7770
8063
|
//#region src/virtualModules/virtualExposesSSR.ts
|
|
7771
8064
|
/**
|
|
7772
8065
|
* Virtual module ID for the SSR exposes map.
|
|
@@ -7821,7 +8114,8 @@ function getSsrFileNameParts(browserFilename) {
|
|
|
7821
8114
|
ext
|
|
7822
8115
|
};
|
|
7823
8116
|
}
|
|
7824
|
-
function getSsrRemoteEntryFileName(browserFilename) {
|
|
8117
|
+
function getSsrRemoteEntryFileName(options, browserFilename = options.filename) {
|
|
8118
|
+
if (options.ssrFilename) return options.ssrFilename;
|
|
7825
8119
|
const { base, ext } = getSsrFileNameParts(browserFilename);
|
|
7826
8120
|
return `${base}.ssr${ext ?? ".js"}`;
|
|
7827
8121
|
}
|
|
@@ -7835,14 +8129,15 @@ function getSsrSharedSingletons(options) {
|
|
|
7835
8129
|
const result = {};
|
|
7836
8130
|
for (const [pkg, share] of Object.entries(options.shared)) {
|
|
7837
8131
|
if (!share.shareConfig.singleton) continue;
|
|
7838
|
-
|
|
7839
|
-
|
|
8132
|
+
const request = getSharedRequest(pkg, share);
|
|
8133
|
+
if (request.endsWith("/")) {
|
|
8134
|
+
for (const concrete of expandSharedPrefixKey(request, used)) result[getSharedRuntimeKey(concrete, share)] = {
|
|
7840
8135
|
...share,
|
|
7841
8136
|
name: concrete
|
|
7842
8137
|
};
|
|
7843
8138
|
continue;
|
|
7844
8139
|
}
|
|
7845
|
-
result[pkg] = share;
|
|
8140
|
+
result[getSharedRuntimeKey(pkg, share)] = share;
|
|
7846
8141
|
}
|
|
7847
8142
|
return result;
|
|
7848
8143
|
}
|
|
@@ -8187,7 +8482,7 @@ const Manifest = (providedOptions) => {
|
|
|
8187
8482
|
type: "module"
|
|
8188
8483
|
},
|
|
8189
8484
|
ssrRemoteEntry: {
|
|
8190
|
-
name: getSsrRemoteEntryFileName(devRemoteEntryFile),
|
|
8485
|
+
name: getSsrRemoteEntryFileName(mfOptions, devRemoteEntryFile),
|
|
8191
8486
|
path: "/__mf_ssr__/",
|
|
8192
8487
|
type: "module"
|
|
8193
8488
|
},
|
|
@@ -8230,6 +8525,33 @@ const Manifest = (providedOptions) => {
|
|
|
8230
8525
|
publicPath = mfOptions.publicPath === "auto" ? "auto" : resolvePublicPath(mfOptions, base, _originalConfigBase);
|
|
8231
8526
|
},
|
|
8232
8527
|
/**
|
|
8528
|
+
* A standalone `vite build --ssr` may run with its own `filename`, e.g.
|
|
8529
|
+
* `defineConfig(({ isSsrBuild }) => ...)`. The manifest written by the
|
|
8530
|
+
* earlier client build then advertises an SSR entry derived from the
|
|
8531
|
+
* browser filename, which is not the file this build emitted. Point the
|
|
8532
|
+
* manifest and stats on disk at the emitted SSR entry.
|
|
8533
|
+
*/
|
|
8534
|
+
writeBundle(outputOptions) {
|
|
8535
|
+
if (!mfManifestName || _command !== "build" || isConsumerProject) return;
|
|
8536
|
+
const environment = this.environment;
|
|
8537
|
+
if (!(environment ? environment.name === "ssr" : Boolean(viteConfig?.build?.ssr))) return;
|
|
8538
|
+
const ssrEntryName = getSsrRemoteEntryFileName(mfOptions);
|
|
8539
|
+
const outDirs = [...new Set([outputOptions.dir, viteConfig?.environments?.client?.build?.outDir].filter((dir) => typeof dir === "string").map((dir) => path$1.resolve(root, dir)))];
|
|
8540
|
+
if (!outDirs.some((dir) => fs$1.existsSync(path$1.resolve(dir, ssrEntryName)))) return;
|
|
8541
|
+
for (const dir of outDirs) for (const fileName of [mfManifestName, mfManifestStatsName]) {
|
|
8542
|
+
if (!fileName) continue;
|
|
8543
|
+
const file = path$1.resolve(dir, fileName);
|
|
8544
|
+
if (!fs$1.existsSync(file)) continue;
|
|
8545
|
+
try {
|
|
8546
|
+
const data = JSON.parse(fs$1.readFileSync(file, "utf8"));
|
|
8547
|
+
const entry = data?.metaData?.ssrRemoteEntry;
|
|
8548
|
+
if (!entry || typeof entry !== "object" || entry.name === ssrEntryName) continue;
|
|
8549
|
+
entry.name = ssrEntryName;
|
|
8550
|
+
fs$1.writeFileSync(file, JSON.stringify(data));
|
|
8551
|
+
} catch {}
|
|
8552
|
+
}
|
|
8553
|
+
},
|
|
8554
|
+
/**
|
|
8233
8555
|
* Generates the module federation manifest file
|
|
8234
8556
|
* @param options - Rollup output options
|
|
8235
8557
|
* @param bundle - Generated bundle assets
|
|
@@ -8239,10 +8561,10 @@ const Manifest = (providedOptions) => {
|
|
|
8239
8561
|
if (this.environment?.name === "ssr") return;
|
|
8240
8562
|
let filesMap = {};
|
|
8241
8563
|
const foundRemoteEntryFile = findRemoteEntryFile(mfOptions.filename, bundle);
|
|
8242
|
-
const expectedSsrRemoteEntryFile = getSsrRemoteEntryFileName(mfOptions
|
|
8564
|
+
const expectedSsrRemoteEntryFile = getSsrRemoteEntryFileName(mfOptions);
|
|
8243
8565
|
const foundSsrRemoteEntryFile = Object.values(bundle).find((file) => file.fileName === expectedSsrRemoteEntryFile)?.fileName;
|
|
8244
8566
|
if (foundRemoteEntryFile) remoteEntryFile = foundRemoteEntryFile;
|
|
8245
|
-
ssrRemoteEntryFile = foundSsrRemoteEntryFile || (_command === "serve" ? getSsrRemoteEntryFileName(resolveHashPlaceholderFileName(mfOptions.filename)) : expectedSsrRemoteEntryFile);
|
|
8567
|
+
ssrRemoteEntryFile = foundSsrRemoteEntryFile || (_command === "serve" ? getSsrRemoteEntryFileName(mfOptions, resolveHashPlaceholderFileName(mfOptions.filename)) : expectedSsrRemoteEntryFile);
|
|
8246
8568
|
const allCssAssets = mfOptions.bundleAllCSS && !disableAssetsAnalyze ? collectCssAssets(bundle) : /* @__PURE__ */ new Set();
|
|
8247
8569
|
if (allCssAssets.size > 0) {
|
|
8248
8570
|
const secondaryCss = /* @__PURE__ */ new Set();
|
|
@@ -8319,7 +8641,7 @@ const Manifest = (providedOptions) => {
|
|
|
8319
8641
|
type: "module"
|
|
8320
8642
|
};
|
|
8321
8643
|
const ssrRemoteEntry = {
|
|
8322
|
-
name: ssrRemoteEntryFile || getSsrRemoteEntryFileName(_command === "serve" ? resolveHashPlaceholderFileName(filename) : filename),
|
|
8644
|
+
name: ssrRemoteEntryFile || getSsrRemoteEntryFileName(mfOptions, _command === "serve" ? resolveHashPlaceholderFileName(filename) : filename),
|
|
8323
8645
|
path: _command === "serve" ? "/__mf_ssr__/" : "",
|
|
8324
8646
|
type: "module"
|
|
8325
8647
|
};
|
|
@@ -8636,6 +8958,7 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
8636
8958
|
return cleanId.includes(getHostAutoInitPath(options)) || cleanId.includes(getHostAutoInitPath());
|
|
8637
8959
|
};
|
|
8638
8960
|
const getEnvironmentConditions = (context) => context.environment?.config?.resolve?.conditions;
|
|
8961
|
+
const isSsrBuild = (context) => isServerBuildContext(context, viteConfig);
|
|
8639
8962
|
function isRemoteImport(source) {
|
|
8640
8963
|
return Object.keys(options.remotes).some((name) => source === name || source.startsWith(name + "/"));
|
|
8641
8964
|
}
|
|
@@ -8671,7 +8994,12 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
8671
8994
|
if (!dynamic) dependencies.add(source);
|
|
8672
8995
|
continue;
|
|
8673
8996
|
}
|
|
8674
|
-
|
|
8997
|
+
let resolved;
|
|
8998
|
+
try {
|
|
8999
|
+
resolved = await ctx.resolve(source, id);
|
|
9000
|
+
} catch {
|
|
9001
|
+
continue;
|
|
9002
|
+
}
|
|
8675
9003
|
if (!resolved?.id || !shouldScanResolvedImport(resolved.id)) continue;
|
|
8676
9004
|
for (const dependency of await collectRemoteDependencies(ctx, resolved.id, seen)) dependencies.add(dependency);
|
|
8677
9005
|
}
|
|
@@ -8739,7 +9067,7 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
8739
9067
|
}
|
|
8740
9068
|
},
|
|
8741
9069
|
async load(id) {
|
|
8742
|
-
if (id === remoteEntryId) return getParsePromise().then((_) => generateRemoteEntry(options, virtualExposesId, _command, getEnvironmentConditions(this)));
|
|
9070
|
+
if (id === remoteEntryId) return getParsePromise().then((_) => generateRemoteEntry(options, virtualExposesId, _command, getEnvironmentConditions(this), isSsrBuild(this)));
|
|
8743
9071
|
if (id === virtualExposesId) {
|
|
8744
9072
|
await refreshExposeRemoteDependencies(this);
|
|
8745
9073
|
return generateExposes(options, exposeRemoteDependencies, _command, reactIslandExposes);
|
|
@@ -8749,7 +9077,7 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
8749
9077
|
async transform(code, id) {
|
|
8750
9078
|
return mapCodeToCodeWithSourcemap(await (async () => {
|
|
8751
9079
|
if (!filterId(id)) return;
|
|
8752
|
-
if (id.includes(remoteEntryId)) return getParsePromise().then((_) => generateRemoteEntry(options, virtualExposesId, _command, getEnvironmentConditions(this)));
|
|
9080
|
+
if (id.includes(remoteEntryId)) return getParsePromise().then((_) => generateRemoteEntry(options, virtualExposesId, _command, getEnvironmentConditions(this), isSsrBuild(this)));
|
|
8753
9081
|
if (id === virtualExposesId) {
|
|
8754
9082
|
await refreshExposeRemoteDependencies(this);
|
|
8755
9083
|
return generateExposes(options, exposeRemoteDependencies, _command, reactIslandExposes);
|
|
@@ -8847,7 +9175,7 @@ function pluginProxyRemotes_default(options) {
|
|
|
8847
9175
|
const remoteModule = getRemoteVirtualModule(source, command, enableSsrInit, consumer, options);
|
|
8848
9176
|
addUsedRemote(remoteName, source, options);
|
|
8849
9177
|
refreshHostAutoInit(options);
|
|
8850
|
-
return remoteModule.
|
|
9178
|
+
return remoteModule.getResolvedId();
|
|
8851
9179
|
}
|
|
8852
9180
|
return {
|
|
8853
9181
|
name: "proxyRemotes",
|
|
@@ -8867,7 +9195,7 @@ function pluginProxyRemotes_default(options) {
|
|
|
8867
9195
|
},
|
|
8868
9196
|
configResolved(config) {
|
|
8869
9197
|
hasMultiEnvironment = Boolean(config.environments?.ssr);
|
|
8870
|
-
enableSsrInit = getSsrCapabilities(parseInt(version, 10), command, Object.keys(remotes).length > 0).enableSsrInitBootstrap;
|
|
9198
|
+
enableSsrInit = getSsrCapabilities(parseInt(version, 10), command, Object.keys(remotes).length > 0, isSsrConfig(config)).enableSsrInitBootstrap;
|
|
8871
9199
|
},
|
|
8872
9200
|
resolveId(source, importer) {
|
|
8873
9201
|
const resolvedIslandConsumerId = resolveReactIslandConsumerId(source);
|
|
@@ -8892,6 +9220,12 @@ function pluginProxyRemotes_default(options) {
|
|
|
8892
9220
|
}
|
|
8893
9221
|
//#endregion
|
|
8894
9222
|
//#region src/utils/sharedSource.ts
|
|
9223
|
+
const pendingEntryLookups = /* @__PURE__ */ new Map();
|
|
9224
|
+
const getEntryLookupKey = (source, importer) => `${source}\0${importer}`;
|
|
9225
|
+
/** Whether a resolveId call is one of the shared source resolver's own entry lookups. */
|
|
9226
|
+
function isSharedEntryLookup(source, importer, options) {
|
|
9227
|
+
return options.custom?.__mfSharedEntryLookup === true || pendingEntryLookups.has(getEntryLookupKey(source, importer));
|
|
9228
|
+
}
|
|
8895
9229
|
/** Identify shared entries through Vite, with a cache scoped to this federation instance. */
|
|
8896
9230
|
function createSharedSourceResolver(shared, getResolutionConfig) {
|
|
8897
9231
|
const caches = /* @__PURE__ */ new Map();
|
|
@@ -8902,9 +9236,10 @@ function createSharedSourceResolver(shared, getResolutionConfig) {
|
|
|
8902
9236
|
if (findSharedKey(packageName, shared)) candidates.add(packageName);
|
|
8903
9237
|
if (findSharedKey(suffix, shared)) candidates.add(suffix);
|
|
8904
9238
|
for (const key of Object.keys(shared)) {
|
|
8905
|
-
|
|
8906
|
-
if (
|
|
8907
|
-
|
|
9239
|
+
const request = getSharedRequest(key, shared[key]);
|
|
9240
|
+
if (getPackageName(request) !== packageName) continue;
|
|
9241
|
+
if (!request.endsWith("/")) candidates.add(request);
|
|
9242
|
+
for (const subpath of getCommonSharedSubpaths(request)) if (findSharedKey(subpath, shared)) candidates.add(subpath);
|
|
8908
9243
|
}
|
|
8909
9244
|
if (candidates.size === 0) return;
|
|
8910
9245
|
const resolvedSource = await resolveEntry(source);
|
|
@@ -8912,7 +9247,8 @@ function createSharedSourceResolver(shared, getResolutionConfig) {
|
|
|
8912
9247
|
for (const candidate of candidates) {
|
|
8913
9248
|
const entry = await resolveEntry(candidate);
|
|
8914
9249
|
if (!entry) continue;
|
|
8915
|
-
|
|
9250
|
+
const allowNodeModulesSuffixMatch = shared[findSharedKey(candidate, shared) ?? candidate]?.shareConfig?.allowNodeModulesSuffixMatch === true;
|
|
9251
|
+
if (normalizeNodeModulePath(entry) === normalizeNodeModulePath(resolvedSource) || allowNodeModulesSuffixMatch && getNodeModulesSuffix(entry) === suffix) return candidate;
|
|
8916
9252
|
}
|
|
8917
9253
|
}
|
|
8918
9254
|
return {
|
|
@@ -8946,8 +9282,11 @@ function createSharedSourceResolver(shared, getResolutionConfig) {
|
|
|
8946
9282
|
cwd: root,
|
|
8947
9283
|
conditions
|
|
8948
9284
|
})) return void 0;
|
|
9285
|
+
const importer = path$1.join(root, "package.json");
|
|
9286
|
+
const lookupKey = getEntryLookupKey(request, importer);
|
|
9287
|
+
pendingEntryLookups.set(lookupKey, (pendingEntryLookups.get(lookupKey) ?? 0) + 1);
|
|
8949
9288
|
try {
|
|
8950
|
-
const resolved = await context.resolve(request,
|
|
9289
|
+
const resolved = await context.resolve(request, importer, {
|
|
8951
9290
|
...options,
|
|
8952
9291
|
skipSelf: true,
|
|
8953
9292
|
custom: {
|
|
@@ -8958,6 +9297,10 @@ function createSharedSourceResolver(shared, getResolutionConfig) {
|
|
|
8958
9297
|
return resolved && !resolved.external ? resolved.id : void 0;
|
|
8959
9298
|
} catch {
|
|
8960
9299
|
return;
|
|
9300
|
+
} finally {
|
|
9301
|
+
const remaining = pendingEntryLookups.get(lookupKey) - 1;
|
|
9302
|
+
if (remaining) pendingEntryLookups.set(lookupKey, remaining);
|
|
9303
|
+
else pendingEntryLookups.delete(lookupKey);
|
|
8961
9304
|
}
|
|
8962
9305
|
});
|
|
8963
9306
|
cache?.set(normalizedSource, result);
|
|
@@ -9006,7 +9349,7 @@ function tryResolveFromProjectRoot(source) {
|
|
|
9006
9349
|
const browserEntry = getInstalledPackageEntry(source, { cwd: getPackageDetectionCwd() });
|
|
9007
9350
|
if (browserEntry) return browserEntry;
|
|
9008
9351
|
try {
|
|
9009
|
-
return
|
|
9352
|
+
return resolveModulePath(source, path$1.join(getPackageDetectionCwd(), "package.json"));
|
|
9010
9353
|
} catch {
|
|
9011
9354
|
return;
|
|
9012
9355
|
}
|
|
@@ -9032,9 +9375,13 @@ function getPackageDependencies(pkg) {
|
|
|
9032
9375
|
*/
|
|
9033
9376
|
function excludeSharedSubDependencies(shared) {
|
|
9034
9377
|
const sharedKeys = new Set(Object.keys(shared));
|
|
9035
|
-
const
|
|
9378
|
+
const requestBase = (key) => {
|
|
9379
|
+
const request = getSharedRequest(key, shared[key]);
|
|
9380
|
+
return request.endsWith("/") ? request.slice(0, -1) : request;
|
|
9381
|
+
};
|
|
9382
|
+
const sharedKeyByBase = new Map(Object.keys(shared).map((key) => [requestBase(key), key]));
|
|
9036
9383
|
for (const parentKey of sharedKeys) {
|
|
9037
|
-
const deps = getPackageDependencies(parentKey);
|
|
9384
|
+
const deps = getPackageDependencies(requestBase(parentKey));
|
|
9038
9385
|
for (const dep of deps) {
|
|
9039
9386
|
const depKey = sharedKeyByBase.get(dep);
|
|
9040
9387
|
if (depKey && depKey !== parentKey) {
|
|
@@ -9361,6 +9708,7 @@ function isSharedPackageRuntimeDependency(sharedKey, dependency, conditions) {
|
|
|
9361
9708
|
function proxySharedModule(options) {
|
|
9362
9709
|
const { shared = {}, federationOptions, getParsePromise = () => Promise.resolve() } = options;
|
|
9363
9710
|
let _config;
|
|
9711
|
+
const getBuildImportAnalysis = (environment) => getImportAnalysis(environment ?? _config ?? options);
|
|
9364
9712
|
let _command = "serve";
|
|
9365
9713
|
let useDirectReactImport = false;
|
|
9366
9714
|
let useRolldown = false;
|
|
@@ -9378,7 +9726,7 @@ function proxySharedModule(options) {
|
|
|
9378
9726
|
const getRuntimeDependencyConditions = (context, resolveOptions) => {
|
|
9379
9727
|
const environment = context.environment;
|
|
9380
9728
|
const environmentConfig = environment?.config;
|
|
9381
|
-
const isSsr = resolveOptions.ssr === true || Boolean(_config?.build?.ssr) ||
|
|
9729
|
+
const isSsr = resolveOptions.ssr === true || Boolean(_config?.build?.ssr) || isServerEnvironment(environment?.name, environmentConfig);
|
|
9382
9730
|
return getSharedExportConditions({
|
|
9383
9731
|
environmentConditions: environmentConfig?.resolve?.conditions,
|
|
9384
9732
|
isProduction: environmentConfig?.isProduction ?? isProduction,
|
|
@@ -9434,12 +9782,13 @@ function proxySharedModule(options) {
|
|
|
9434
9782
|
}, federationOptions);
|
|
9435
9783
|
},
|
|
9436
9784
|
resolveId(source) {
|
|
9437
|
-
|
|
9785
|
+
const resolvedId = getResolvedLocalSharedImportMapId(federationOptions);
|
|
9786
|
+
if (source === getLocalSharedImportMapPath(federationOptions) || source === resolvedId) return resolvedId;
|
|
9438
9787
|
},
|
|
9439
9788
|
load(id) {
|
|
9440
9789
|
if (id === getResolvedLocalSharedImportMapId(federationOptions)) return getParsePromise().then((_) => {
|
|
9441
9790
|
refreshTreeShakingForEnvironment(this);
|
|
9442
|
-
const providerPackages = /* @__PURE__ */ new Set([...Object.keys(shared).filter((pkg) => !pkg.endsWith("/")), ...getUsedShares(federationOptions)]);
|
|
9791
|
+
const providerPackages = /* @__PURE__ */ new Set([...Object.keys(shared).filter((pkg) => !getSharedRequest(pkg, shared[pkg]).endsWith("/")), ...getUsedShares(federationOptions)]);
|
|
9443
9792
|
for (const pkg of providerPackages) {
|
|
9444
9793
|
const sharedKey = findSharedKey(pkg, shared);
|
|
9445
9794
|
const shareItem = shared[pkg] || (sharedKey ? shared[sharedKey] : void 0);
|
|
@@ -9484,14 +9833,15 @@ function proxySharedModule(options) {
|
|
|
9484
9833
|
const resolvedOptions = federationOptions ?? getNormalizeModuleFederationOptions();
|
|
9485
9834
|
const registerConfiguredShare = _command === "build" && Object.keys(resolvedOptions.exposes).length > 0 ? addUsedShares : addConfiguredShare;
|
|
9486
9835
|
Object.keys(shared).forEach((key) => {
|
|
9487
|
-
if (key.endsWith("/")) return;
|
|
9488
|
-
|
|
9489
|
-
|
|
9836
|
+
if (key.endsWith("/") || getSharedRequest(key, shared[key]).endsWith("/")) return;
|
|
9837
|
+
const runtimeKey = getSharedRuntimeKey(key, shared[key]);
|
|
9838
|
+
if (useDirectReactImport && runtimeKey === "react") {
|
|
9839
|
+
registerConfiguredShare(runtimeKey, federationOptions);
|
|
9490
9840
|
return;
|
|
9491
9841
|
}
|
|
9492
|
-
writeLoadShareModule(
|
|
9493
|
-
if (shared[key].shareConfig.import !== false) writePreBuildLibPath(
|
|
9494
|
-
registerConfiguredShare(
|
|
9842
|
+
writeLoadShareModule(runtimeKey, shared[key], _command, isRolldown, federationOptions);
|
|
9843
|
+
if (shared[key].shareConfig.import !== false) writePreBuildLibPath(runtimeKey, shared[key], federationOptions);
|
|
9844
|
+
registerConfiguredShare(runtimeKey, federationOptions);
|
|
9495
9845
|
});
|
|
9496
9846
|
writeLocalSharedImportMap(federationOptions);
|
|
9497
9847
|
refreshHostAutoInit(federationOptions);
|
|
@@ -9502,10 +9852,14 @@ function proxySharedModule(options) {
|
|
|
9502
9852
|
buildStart() {
|
|
9503
9853
|
sharedSourceResolver.clear();
|
|
9504
9854
|
if (_command !== "build") return;
|
|
9855
|
+
if (hasAnalyzableShares) getBuildImportAnalysis(this.environment).clear();
|
|
9505
9856
|
resetTreeShakingExports(federationOptions);
|
|
9506
9857
|
emittedTreeShakingProviders.clear();
|
|
9507
9858
|
refreshTreeShakingForEnvironment(this);
|
|
9508
9859
|
},
|
|
9860
|
+
buildEnd() {
|
|
9861
|
+
if (_command === "build" && hasAnalyzableShares) getBuildImportAnalysis(this.environment).clear();
|
|
9862
|
+
},
|
|
9509
9863
|
shouldTransformCachedModule() {
|
|
9510
9864
|
return _command === "build" && hasAnalyzableShares;
|
|
9511
9865
|
},
|
|
@@ -9514,7 +9868,7 @@ function proxySharedModule(options) {
|
|
|
9514
9868
|
await collectTreeShakingImports(code, id, shared, async (source, shares) => {
|
|
9515
9869
|
const request = await sharedSourceResolver.resolve(this, source, transformOptions);
|
|
9516
9870
|
return request ? findSharedKey(request, shares) : void 0;
|
|
9517
|
-
}, (sharedKey, exports, request) => recordTreeShakingExports(sharedKey, exports, request, federationOptions), (sharedKey, request) => markTreeShakingPackageUnsafe(sharedKey, request, federationOptions));
|
|
9871
|
+
}, (sharedKey, exports, request) => recordTreeShakingExports(sharedKey, exports, request, federationOptions), (sharedKey, request) => markTreeShakingPackageUnsafe(sharedKey, request, federationOptions), getBuildImportAnalysis(this.environment));
|
|
9518
9872
|
refreshTreeShakingForEnvironment(this);
|
|
9519
9873
|
}
|
|
9520
9874
|
},
|
|
@@ -9523,7 +9877,7 @@ function proxySharedModule(options) {
|
|
|
9523
9877
|
enforce: "pre",
|
|
9524
9878
|
apply: "build",
|
|
9525
9879
|
async resolveId(source, importer, resolveOptions) {
|
|
9526
|
-
if (resolveOptions
|
|
9880
|
+
if (isSharedEntryLookup(source, importer, resolveOptions)) return;
|
|
9527
9881
|
const sourceToken = getTreeShakingGraphToken(source);
|
|
9528
9882
|
const importerToken = getTreeShakingGraphToken(importer);
|
|
9529
9883
|
const token = sourceToken || importerToken;
|
|
@@ -9559,7 +9913,7 @@ function proxySharedModule(options) {
|
|
|
9559
9913
|
name: "proxyPreBuildShared:resolve-shared-loadShare",
|
|
9560
9914
|
enforce: "pre",
|
|
9561
9915
|
async resolveId(source, importer, resolveOptions) {
|
|
9562
|
-
if (resolveOptions
|
|
9916
|
+
if (isSharedEntryLookup(source, importer, resolveOptions) || resolveOptions.custom?.__mfTreeShakingGraph) return;
|
|
9563
9917
|
const sharedSource = await sharedSourceResolver.resolve(this, source, resolveOptions);
|
|
9564
9918
|
if (!sharedSource) return;
|
|
9565
9919
|
const key = findSharedKey(sharedSource, shared);
|
|
@@ -9574,8 +9928,9 @@ function proxySharedModule(options) {
|
|
|
9574
9928
|
if (importerPackage === getPackageName(key)) return;
|
|
9575
9929
|
if (importerPackage && shared[key].shareConfig.import !== false) {
|
|
9576
9930
|
const importerIsUnsharedWorkspacePackage = !isNodeModulePath(importer) && !Object.keys(shared).some((sharedKey) => getPackageName(sharedKey) === importerPackage);
|
|
9577
|
-
const
|
|
9578
|
-
|
|
9931
|
+
const request = getSharedRequest(key, shared[key]);
|
|
9932
|
+
const runtimeDependencyRequest = request.endsWith("/") && matchesSharedSource(sharedSource, key, shared[key]) ? sharedSource : request;
|
|
9933
|
+
if (importerIsUnsharedWorkspacePackage ? isSharedPackageRuntimeDependency(runtimeDependencyRequest, importerPackage, getRuntimeDependencyConditions(this, resolveOptions)) : isSharedPackageDependency(request, importerPackage)) return;
|
|
9579
9934
|
}
|
|
9580
9935
|
if (useDirectReactImport && key === "react") return;
|
|
9581
9936
|
if (isAssetLikeImport(source)) return;
|
|
@@ -9876,17 +10231,21 @@ function collectFromRegex(code, isRemoteImport) {
|
|
|
9876
10231
|
}
|
|
9877
10232
|
function pluginRemoteNamedExports(options) {
|
|
9878
10233
|
const remoteNames = Object.keys(options.remotes);
|
|
10234
|
+
let root = process.cwd();
|
|
9879
10235
|
const isNodeModulesId = (id) => id.includes("/node_modules/") || id.includes("\\node_modules\\");
|
|
9880
10236
|
function isRemoteImport(source, importerId) {
|
|
9881
10237
|
return remoteNames.some((name) => {
|
|
9882
10238
|
if (source.startsWith(name + "/")) return true;
|
|
9883
10239
|
if (source !== name) return false;
|
|
9884
|
-
return !isNodeModulesId(importerId);
|
|
10240
|
+
return !isNodeModulesId(importerId) || !getInstalledPackageEntry(source, { cwd: root });
|
|
9885
10241
|
}) || source.includes("__loadRemote__");
|
|
9886
10242
|
}
|
|
9887
10243
|
return {
|
|
9888
10244
|
name: "module-federation-remote-named-exports",
|
|
9889
10245
|
enforce: "post",
|
|
10246
|
+
configResolved(config) {
|
|
10247
|
+
root = config.root || process.cwd();
|
|
10248
|
+
},
|
|
9890
10249
|
async transform(code, id) {
|
|
9891
10250
|
if (remoteNames.length === 0) return;
|
|
9892
10251
|
if (id.includes("__loadRemote__") || id.includes("__loadShare__")) return;
|
|
@@ -10038,18 +10397,25 @@ function pluginSSRRemoteEntry(options) {
|
|
|
10038
10397
|
const remoteEntrySSRId = getRemoteEntrySSRId(options);
|
|
10039
10398
|
const virtualExposesSSRId = getVirtualExposesSSRId(options);
|
|
10040
10399
|
let cachedSsrRemoteEntrySource;
|
|
10041
|
-
const ssrOutputFilename = getSsrRemoteEntryFileName(options
|
|
10400
|
+
const ssrOutputFilename = getSsrRemoteEntryFileName(options);
|
|
10042
10401
|
const ssrExposesFileName = getSsrExposesFileName(options.filename);
|
|
10043
10402
|
let ssrOutputFiles = /* @__PURE__ */ new Set();
|
|
10044
10403
|
let ssrOutputDir = "";
|
|
10045
10404
|
let clientOutputDir = "";
|
|
10046
|
-
const
|
|
10405
|
+
const mfRuntimePackages = [
|
|
10047
10406
|
"@module-federation/runtime",
|
|
10048
10407
|
"@module-federation/runtime-core",
|
|
10049
|
-
"@module-federation/sdk"
|
|
10050
|
-
...options.ssrExternals ?? []
|
|
10408
|
+
"@module-federation/sdk"
|
|
10051
10409
|
];
|
|
10410
|
+
const ssrOnlyExternals = [...mfRuntimePackages, ...options.ssrExternals ?? []];
|
|
10052
10411
|
const ssrOnlyExternalPattern = new RegExp(`^(${ssrOnlyExternals.map((e) => e.replace(/[/\\^$*+?.()|[\]{}]/g, "\\$&")).join("|")})(\\/.*)?$`);
|
|
10412
|
+
let noExternal;
|
|
10413
|
+
const isNoExternal = (id) => {
|
|
10414
|
+
const pkg = ssrOnlyExternalPattern.exec(id)?.[1] ?? id;
|
|
10415
|
+
if (!noExternal || !mfRuntimePackages.includes(pkg)) return false;
|
|
10416
|
+
if (noExternal === true) return true;
|
|
10417
|
+
return (Array.isArray(noExternal) ? noExternal : [noExternal]).some((rule) => typeof rule === "string" ? rule === pkg : rule.test(pkg));
|
|
10418
|
+
};
|
|
10053
10419
|
const ssrModuleIds = /* @__PURE__ */ new Set([remoteEntrySSRId, virtualExposesSSRId]);
|
|
10054
10420
|
const resolvedAbsToPackage = /* @__PURE__ */ new Map();
|
|
10055
10421
|
let isServe = false;
|
|
@@ -10080,7 +10446,9 @@ function pluginSSRRemoteEntry(options) {
|
|
|
10080
10446
|
enforce: "pre",
|
|
10081
10447
|
configResolved(config) {
|
|
10082
10448
|
isServe = config.command === "serve";
|
|
10449
|
+
noExternal = config.environments?.ssr?.resolve?.noExternal ?? config.ssr?.noExternal;
|
|
10083
10450
|
for (const pkg of ssrOnlyExternals) {
|
|
10451
|
+
if (isNoExternal(pkg)) continue;
|
|
10084
10452
|
const aliasEntry = (config.resolve?.alias)?.find((a) => a.find === pkg || a.find instanceof RegExp && a.find.test(pkg));
|
|
10085
10453
|
if (aliasEntry?.replacement) resolvedAbsToPackage.set(aliasEntry.replacement, pkg);
|
|
10086
10454
|
}
|
|
@@ -10089,7 +10457,7 @@ function pluginSSRRemoteEntry(options) {
|
|
|
10089
10457
|
if (id === remoteEntrySSRId || id.startsWith(remoteEntrySSRId)) return id;
|
|
10090
10458
|
if (id === virtualExposesSSRId || id.startsWith(virtualExposesSSRId)) return id;
|
|
10091
10459
|
if (!importer || !ssrModuleIds.has(importer)) return;
|
|
10092
|
-
if (ssrOnlyExternalPattern.test(id)) return {
|
|
10460
|
+
if (ssrOnlyExternalPattern.test(id) && !isNoExternal(id)) return {
|
|
10093
10461
|
id,
|
|
10094
10462
|
external: true
|
|
10095
10463
|
};
|
|
@@ -10114,7 +10482,7 @@ function pluginSSRRemoteEntry(options) {
|
|
|
10114
10482
|
configureServer(server) {
|
|
10115
10483
|
const base = "/__mf_ssr__";
|
|
10116
10484
|
const basePath = getBasePath$1(viteConfig?.base);
|
|
10117
|
-
const ssrEntryFileName = getSsrRemoteEntryFileName(options
|
|
10485
|
+
const ssrEntryFileName = getSsrRemoteEntryFileName(options);
|
|
10118
10486
|
if (isNuxtProject || isNuxtClientBase(basePath)) server.middlewares.use((req, _res, next) => {
|
|
10119
10487
|
if (req.url?.replace(/\?.*/, "") === `${basePath}/${ssrEntryFileName}`) req.url = `${basePath}/__mf_ssr__/${ssrEntryFileName}`;
|
|
10120
10488
|
next();
|
|
@@ -10183,7 +10551,7 @@ function pluginSSRRemoteEntry(options) {
|
|
|
10183
10551
|
resolveId(id) {
|
|
10184
10552
|
if (id === remoteEntrySSRId || id.startsWith(remoteEntrySSRId)) return id;
|
|
10185
10553
|
if (id === virtualExposesSSRId || id.startsWith(virtualExposesSSRId)) return id;
|
|
10186
|
-
if (id === `/__mf_ssr__/${getSsrRemoteEntryFileName(options
|
|
10554
|
+
if (id === `/__mf_ssr__/${getSsrRemoteEntryFileName(options)}`) return remoteEntrySSRId;
|
|
10187
10555
|
if (id === `/__mf_ssr__/${ssrExposesFileName}`) return virtualExposesSSRId;
|
|
10188
10556
|
},
|
|
10189
10557
|
load(id) {
|
|
@@ -10388,6 +10756,85 @@ var aliasToArrayPlugin_default = {
|
|
|
10388
10756
|
}
|
|
10389
10757
|
};
|
|
10390
10758
|
//#endregion
|
|
10759
|
+
//#region src/utils/deferredPrebuildHelper.ts
|
|
10760
|
+
function isExportAllHelper(code, exportName) {
|
|
10761
|
+
try {
|
|
10762
|
+
const ast = parseAst(code);
|
|
10763
|
+
let localName;
|
|
10764
|
+
for (const node of ast.body) {
|
|
10765
|
+
if (node.type !== "ExportNamedDeclaration") continue;
|
|
10766
|
+
for (const specifier of node.specifiers) if (specifier.type === "ExportSpecifier" && specifier.exported.type === "Identifier" && specifier.exported.name === exportName && specifier.local.type === "Identifier") localName = specifier.local.name;
|
|
10767
|
+
}
|
|
10768
|
+
if (!localName) return false;
|
|
10769
|
+
for (const node of ast.body) {
|
|
10770
|
+
if (node.type !== "VariableDeclaration") continue;
|
|
10771
|
+
for (const declaration of node.declarations) {
|
|
10772
|
+
if (declaration.id.type !== "Identifier" || declaration.id.name !== localName) continue;
|
|
10773
|
+
const initializer = declaration.init;
|
|
10774
|
+
if (!initializer) return false;
|
|
10775
|
+
const source = code.slice(initializer.start, initializer.end);
|
|
10776
|
+
return source.includes("Symbol.toStringTag") && source.includes("Module");
|
|
10777
|
+
}
|
|
10778
|
+
}
|
|
10779
|
+
} catch {}
|
|
10780
|
+
return false;
|
|
10781
|
+
}
|
|
10782
|
+
/**
|
|
10783
|
+
* Rolldown sometimes places its shared namespace helper in a local prebuild
|
|
10784
|
+
* chunk. A loadShare wrapper then imports that helper statically, evaluating the
|
|
10785
|
+
* fallback even when a host provider is already in the cache. Inline only the
|
|
10786
|
+
* recognized Rolldown helper; leave every other prebuild import untouched.
|
|
10787
|
+
*/
|
|
10788
|
+
function inlineDeferredPrebuildNamespaceHelper(bundle) {
|
|
10789
|
+
for (const chunk of Object.values(bundle)) {
|
|
10790
|
+
if (chunk.type !== "chunk" || !chunk.fileName.includes("__loadShare__")) continue;
|
|
10791
|
+
let ast;
|
|
10792
|
+
try {
|
|
10793
|
+
ast = parseAst(chunk.code);
|
|
10794
|
+
} catch {
|
|
10795
|
+
continue;
|
|
10796
|
+
}
|
|
10797
|
+
const edits = [];
|
|
10798
|
+
const deferredSources = /* @__PURE__ */ new Set();
|
|
10799
|
+
forEachAstNode(ast, (node) => {
|
|
10800
|
+
if (node.type !== "ImportExpression") return;
|
|
10801
|
+
const source = getModuleSource(node.source);
|
|
10802
|
+
if (source) deferredSources.add(source);
|
|
10803
|
+
});
|
|
10804
|
+
const retainedImports = /* @__PURE__ */ new Set();
|
|
10805
|
+
const removedImports = /* @__PURE__ */ new Set();
|
|
10806
|
+
for (const node of ast.body) {
|
|
10807
|
+
if (node.type !== "ImportDeclaration") continue;
|
|
10808
|
+
const source = getModuleSource(node.source);
|
|
10809
|
+
if (!source) continue;
|
|
10810
|
+
const targetName = path.posix.normalize(path.posix.join(path.posix.dirname(chunk.fileName), source));
|
|
10811
|
+
const [specifier] = node.specifiers;
|
|
10812
|
+
const exported = specifier?.type === "ImportSpecifier" && specifier.imported;
|
|
10813
|
+
const target = bundle[targetName];
|
|
10814
|
+
if (!source.includes("__prebuild__") || node.specifiers.length !== 1 || !exported || exported.type !== "Identifier" || target?.type !== "chunk" || !deferredSources.has(source) || !Object.keys(target.modules ?? {}).some((id) => id.includes("rolldown/runtime.js")) || !isExportAllHelper(target.code, exported.name)) {
|
|
10815
|
+
retainedImports.add(targetName);
|
|
10816
|
+
continue;
|
|
10817
|
+
}
|
|
10818
|
+
removedImports.add(targetName);
|
|
10819
|
+
edits.push({
|
|
10820
|
+
start: node.start,
|
|
10821
|
+
end: node.end,
|
|
10822
|
+
replacement: `const ${specifier.local.name} = (all, noSymbols) => {
|
|
10823
|
+
const namespace = {};
|
|
10824
|
+
for (const name in all) Object.defineProperty(namespace, name, {
|
|
10825
|
+
get: all[name], enumerable: true,
|
|
10826
|
+
});
|
|
10827
|
+
if (!noSymbols) Object.defineProperty(namespace, Symbol.toStringTag, { value: 'Module' });
|
|
10828
|
+
return namespace;
|
|
10829
|
+
};`
|
|
10830
|
+
});
|
|
10831
|
+
}
|
|
10832
|
+
if (edits.length === 0) continue;
|
|
10833
|
+
for (const edit of edits.reverse()) chunk.code = chunk.code.slice(0, edit.start) + edit.replacement + chunk.code.slice(edit.end);
|
|
10834
|
+
if (chunk.imports) chunk.imports = chunk.imports.filter((imported) => !removedImports.has(imported) || retainedImports.has(imported));
|
|
10835
|
+
}
|
|
10836
|
+
}
|
|
10837
|
+
//#endregion
|
|
10391
10838
|
//#region src/utils/controlChunkSanitizer.ts
|
|
10392
10839
|
const FEDERATION_CONTROL_CHUNK_HINTS = ["hostInit", "localSharedImportMap"];
|
|
10393
10840
|
function stripEmptyPreloadCalls(code) {
|
|
@@ -10605,7 +11052,7 @@ function isFederationHtmlPreloadDependency(dep, includeSharedRuntime = false) {
|
|
|
10605
11052
|
}
|
|
10606
11053
|
function canResolveSharedSubpath(subpath, projectRoot) {
|
|
10607
11054
|
try {
|
|
10608
|
-
return isViteOptimizableEntry(
|
|
11055
|
+
return isViteOptimizableEntry(resolveModulePath(subpath, path$1.join(projectRoot, "package.json")));
|
|
10609
11056
|
} catch (error) {
|
|
10610
11057
|
if (error?.code === "ERR_PACKAGE_PATH_NOT_EXPORTED" && !isBarePackageSubpath(subpath)) {
|
|
10611
11058
|
const entry = resolveViteImportPackageEntry(subpath, projectRoot);
|
|
@@ -10788,17 +11235,20 @@ function registerEntryImports(options, projectRoot, recordShared = true, entryFi
|
|
|
10788
11235
|
addUsedRemote(remoteKey, request, options);
|
|
10789
11236
|
markStaticRemote(request, options);
|
|
10790
11237
|
markPreloadRemote(request, options);
|
|
10791
|
-
} else if (sharedKey && recordShared)
|
|
11238
|
+
} else if (sharedKey && recordShared) materializeSharedRequest(options, request);
|
|
10792
11239
|
else if (request && !typeOnly) enqueue(request, file, preloadRemotes && isStatic);
|
|
10793
11240
|
}
|
|
10794
11241
|
}
|
|
10795
11242
|
return hasJsxSource;
|
|
10796
11243
|
}
|
|
11244
|
+
function materializeSharedRequest(options, request) {
|
|
11245
|
+
addUsedShares(request, options);
|
|
11246
|
+
const packageName = getPackageName(request);
|
|
11247
|
+
if (packageName !== request && findSharedKey(packageName, options.shared)) addUsedShares(packageName, options);
|
|
11248
|
+
}
|
|
10797
11249
|
function materializeAutomaticJsxRuntime(options, runtime) {
|
|
10798
11250
|
if (!findSharedKey(runtime, options.shared)) return false;
|
|
10799
|
-
|
|
10800
|
-
const packageName = getPackageName(runtime);
|
|
10801
|
-
if (packageName !== runtime && findSharedKey(packageName, options.shared)) addUsedShares(packageName, options);
|
|
11251
|
+
materializeSharedRequest(options, runtime);
|
|
10802
11252
|
return true;
|
|
10803
11253
|
}
|
|
10804
11254
|
/**
|
|
@@ -10843,11 +11293,21 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
10843
11293
|
config.optimizeDeps = config.optimizeDeps || {};
|
|
10844
11294
|
config.optimizeDeps.include = config.optimizeDeps.include || [];
|
|
10845
11295
|
const optimizeDeps = config.optimizeDeps;
|
|
11296
|
+
const preparedShares = /* @__PURE__ */ new Map();
|
|
11297
|
+
const writeSharedModules = (source, shareItem) => {
|
|
11298
|
+
if (preparedShares.get(source) === shareItem) return;
|
|
11299
|
+
writeLoadShareModule(source, shareItem, _command, isRolldown, options);
|
|
11300
|
+
if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(source, shareItem, options);
|
|
11301
|
+
preparedShares.set(source, shareItem);
|
|
11302
|
+
};
|
|
10846
11303
|
if (isRolldown) {
|
|
10847
11304
|
optimizeDeps.rolldownOptions ??= {};
|
|
10848
11305
|
optimizeDeps.rolldownOptions.plugins ??= [];
|
|
10849
11306
|
optimizeDeps.rolldownOptions.plugins.push({
|
|
10850
11307
|
name: "module-federation:optimize-shared-resolver",
|
|
11308
|
+
buildStart() {
|
|
11309
|
+
preparedShares.clear();
|
|
11310
|
+
},
|
|
10851
11311
|
load(id) {
|
|
10852
11312
|
if (!id.startsWith("module-federation:optimized-require-")) return;
|
|
10853
11313
|
const sourcePackage = id.slice(36);
|
|
@@ -10875,13 +11335,11 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
10875
11335
|
if (isCommonJsImporter(importer) && !isReactSingleton && !isReactDomRequire) return;
|
|
10876
11336
|
if (resolveOptions?.kind !== "entry-point") addUsedShares(source, options);
|
|
10877
11337
|
if (isReactRequire || isReactDomRequire) {
|
|
10878
|
-
|
|
10879
|
-
if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(source, shareItem, options);
|
|
11338
|
+
writeSharedModules(source, shareItem);
|
|
10880
11339
|
return { id: `module-federation:optimized-require-${source}` };
|
|
10881
11340
|
}
|
|
10882
11341
|
const loadSharePath = getLoadShareModulePath(source, isRolldown, options);
|
|
10883
|
-
|
|
10884
|
-
if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(source, shareItem, options);
|
|
11342
|
+
writeSharedModules(source, shareItem);
|
|
10885
11343
|
return {
|
|
10886
11344
|
id: loadSharePath,
|
|
10887
11345
|
external: true
|
|
@@ -10894,6 +11352,9 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
10894
11352
|
optimizeDeps.esbuildOptions.plugins.push({
|
|
10895
11353
|
name: "module-federation:optimize-shared-proxy",
|
|
10896
11354
|
setup(build) {
|
|
11355
|
+
build.onStart(() => {
|
|
11356
|
+
preparedShares.clear();
|
|
11357
|
+
});
|
|
10897
11358
|
build.onResolve({ filter: createViteEncodedIdPrefixRegExp("virtual:mf:") }, (args) => ({
|
|
10898
11359
|
path: args.path,
|
|
10899
11360
|
external: true
|
|
@@ -10911,8 +11372,7 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
10911
11372
|
if (args.kind === "import-statement" || args.kind === "dynamic-import") {
|
|
10912
11373
|
const shareItem = shared[key];
|
|
10913
11374
|
const loadSharePath = getLoadShareModulePath(args.path, isRolldown, options);
|
|
10914
|
-
|
|
10915
|
-
if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(args.path, shareItem, options);
|
|
11375
|
+
writeSharedModules(args.path, shareItem);
|
|
10916
11376
|
return {
|
|
10917
11377
|
path: loadSharePath,
|
|
10918
11378
|
external: true
|
|
@@ -10931,8 +11391,7 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
10931
11391
|
if (!key) return;
|
|
10932
11392
|
const shareItem = shared[key];
|
|
10933
11393
|
const loadSharePath = getLoadShareModulePath(args.path, isRolldown, options);
|
|
10934
|
-
|
|
10935
|
-
if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(args.path, shareItem, options);
|
|
11394
|
+
writeSharedModules(args.path, shareItem);
|
|
10936
11395
|
return {
|
|
10937
11396
|
loader: "js",
|
|
10938
11397
|
resolveDir: root,
|
|
@@ -10947,12 +11406,14 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
10947
11406
|
}
|
|
10948
11407
|
for (const key of Object.keys(shared)) {
|
|
10949
11408
|
const shareItem = shared[key];
|
|
10950
|
-
|
|
11409
|
+
const request = getSharedRequest(key, shareItem);
|
|
11410
|
+
const runtimeKey = getSharedRuntimeKey(key, shareItem);
|
|
11411
|
+
if (key.endsWith("/") || request.endsWith("/") || runtimeKey.endsWith("/")) {
|
|
10951
11412
|
if (_command === "serve" && shareItem.shareConfig?.import !== false) {
|
|
10952
11413
|
const optimizeDeps = config.optimizeDeps ??= {};
|
|
10953
11414
|
optimizeDeps.include ??= [];
|
|
10954
11415
|
optimizeDeps.exclude ??= [];
|
|
10955
|
-
for (const subpath of getCommonSharedSubpaths(
|
|
11416
|
+
for (const subpath of getCommonSharedSubpaths(request)) {
|
|
10956
11417
|
writePreBuildLibPath(subpath, shareItem, options);
|
|
10957
11418
|
if (canResolveSharedSubpath(subpath, root)) optimizeDeps.include.push(subpath);
|
|
10958
11419
|
else optimizeDeps.exclude.push(subpath);
|
|
@@ -10960,23 +11421,24 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
10960
11421
|
}
|
|
10961
11422
|
continue;
|
|
10962
11423
|
}
|
|
10963
|
-
if (isVinext &&
|
|
10964
|
-
addConfiguredShare(
|
|
11424
|
+
if (isVinext && runtimeKey === "react") {
|
|
11425
|
+
addConfiguredShare(runtimeKey, options);
|
|
10965
11426
|
continue;
|
|
10966
11427
|
}
|
|
10967
|
-
getLoadShareModulePath(
|
|
10968
|
-
writeLoadShareModule(
|
|
10969
|
-
if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(
|
|
10970
|
-
addConfiguredShare(
|
|
11428
|
+
getLoadShareModulePath(runtimeKey, isRolldown, options);
|
|
11429
|
+
writeLoadShareModule(runtimeKey, shareItem, _command, isRolldown, options);
|
|
11430
|
+
if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(runtimeKey, shareItem, options);
|
|
11431
|
+
addConfiguredShare(runtimeKey, options);
|
|
10971
11432
|
if (_command === "serve" && shareItem.shareConfig?.import !== false) {
|
|
10972
11433
|
const optimizeDeps = config.optimizeDeps ??= {};
|
|
10973
11434
|
optimizeDeps.include ??= [];
|
|
10974
11435
|
optimizeDeps.exclude ??= [];
|
|
10975
|
-
const shouldBypassOptimizeDep = isLitShare(
|
|
10976
|
-
if (optimizeDeps.include.includes(
|
|
10977
|
-
else if (shouldBypassOptimizeDep || optimizeDeps.exclude.includes(
|
|
10978
|
-
else optimizeDeps.include.push(
|
|
10979
|
-
|
|
11436
|
+
const shouldBypassOptimizeDep = isLitShare(runtimeKey) || !canResolveSharedSubpath(runtimeKey, root);
|
|
11437
|
+
if (optimizeDeps.include.includes(runtimeKey)) optimizeDeps.exclude = optimizeDeps.exclude.filter((dep) => dep !== runtimeKey);
|
|
11438
|
+
else if (shouldBypassOptimizeDep || optimizeDeps.exclude.includes(runtimeKey)) optimizeDeps.exclude.push(runtimeKey);
|
|
11439
|
+
else optimizeDeps.include.push(runtimeKey);
|
|
11440
|
+
const commonSubpaths = shareItem.shareConfig.request === void 0 && shareItem.shareConfig.shareKey === void 0 ? getCommonSharedSubpaths(runtimeKey) : [];
|
|
11441
|
+
for (const subpath of commonSubpaths) {
|
|
10980
11442
|
const canResolveSubpath = canResolveSharedSubpath(subpath, root);
|
|
10981
11443
|
if ([
|
|
10982
11444
|
"react/compiler-runtime",
|
|
@@ -10992,7 +11454,7 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
10992
11454
|
addConfiguredShare(subpath, options);
|
|
10993
11455
|
if (canResolveSubpath) {
|
|
10994
11456
|
optimizeDeps.include.push(subpath);
|
|
10995
|
-
if (
|
|
11457
|
+
if (runtimeKey === "react-dom") optimizeDeps.include.push(`${runtimeKey} > ${subpath}`);
|
|
10996
11458
|
} else optimizeDeps.exclude.push(subpath);
|
|
10997
11459
|
}
|
|
10998
11460
|
}
|
|
@@ -11010,10 +11472,8 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
11010
11472
|
const automaticJsxRuntime = getAutomaticJsxRuntime(config);
|
|
11011
11473
|
if (automaticJsxRuntime && materializeAutomaticJsxRuntime(options, automaticJsxRuntime)) writeLocalSharedImportMap(options);
|
|
11012
11474
|
}
|
|
11013
|
-
if (!getSsrCapabilities(parseInt(version, 10), config.command, hasRemotes(options)).injectSsrEntryLoader) return;
|
|
11014
|
-
if (options.runtimePlugins.some((p) =>
|
|
11015
|
-
return (typeof p === "string" ? p : p[0]) === "@module-federation/vite/ssrEntryLoader";
|
|
11016
|
-
})) return;
|
|
11475
|
+
if (!getSsrCapabilities(parseInt(version, 10), config.command, hasRemotes(options), isSsrConfig(config)).injectSsrEntryLoader) return;
|
|
11476
|
+
if (options.runtimePlugins.some((p) => getRuntimePluginSpecifier(p) === "@module-federation/vite/ssrEntryLoader")) return;
|
|
11017
11477
|
const projectRequire = createRequire$1(pathToFileURL(path$1.join(config.root, "package.json")));
|
|
11018
11478
|
const sharedKeys = Object.keys(options.shared ?? {});
|
|
11019
11479
|
const commonSharedPkgs = [
|
|
@@ -11056,16 +11516,14 @@ function applyBuildTimeRuntimeDefines(define, options, { target, isAstro, defaul
|
|
|
11056
11516
|
}
|
|
11057
11517
|
function loadPluginDts(options) {
|
|
11058
11518
|
if (options.dts === false) return [];
|
|
11059
|
-
return [import("./pluginDts-
|
|
11519
|
+
return [import("./pluginDts-DxgS2FEd.js").then(({ default: pluginDts }) => pluginDts(options))];
|
|
11060
11520
|
}
|
|
11061
11521
|
const INJECT_EXTERNAL_RUNTIME_CORE_PLUGIN = "@module-federation/vite/injectExternalRuntimeCorePlugin";
|
|
11062
11522
|
function isInjectExternalRuntimeCorePlugin(specifier) {
|
|
11063
11523
|
return specifier === INJECT_EXTERNAL_RUNTIME_CORE_PLUGIN || specifier.includes("injectExternalRuntimeCorePlugin") || specifier.includes("inject-external-runtime-core-plugin");
|
|
11064
11524
|
}
|
|
11065
11525
|
function hasInjectExternalRuntimeCorePlugin(runtimePlugins) {
|
|
11066
|
-
return runtimePlugins.some((plugin) =>
|
|
11067
|
-
return isInjectExternalRuntimeCorePlugin(typeof plugin === "string" ? plugin : plugin[0]);
|
|
11068
|
-
});
|
|
11526
|
+
return runtimePlugins.some((plugin) => isInjectExternalRuntimeCorePlugin(getRuntimePluginSpecifier(plugin)));
|
|
11069
11527
|
}
|
|
11070
11528
|
function resolveInjectExternalRuntimeCorePlugin() {
|
|
11071
11529
|
try {
|
|
@@ -11112,7 +11570,7 @@ function federation(mfUserOptions) {
|
|
|
11112
11570
|
const emittedRuntimeCapabilityWarnings = /* @__PURE__ */ new Set();
|
|
11113
11571
|
const getLoadHookExportConditions = (context, loadOptions) => {
|
|
11114
11572
|
const environment = context.environment;
|
|
11115
|
-
const isSsr = loadOptions?.ssr === true || isSsrBuild || environment?.
|
|
11573
|
+
const isSsr = loadOptions?.ssr === true || isSsrBuild || isServerEnvironment(environment?.name, environment?.config);
|
|
11116
11574
|
return getSharedExportConditions({
|
|
11117
11575
|
environmentConditions: environment?.config?.resolve?.conditions,
|
|
11118
11576
|
isProduction: environment?.config?.isProduction ?? isProduction,
|
|
@@ -11236,7 +11694,7 @@ function federation(mfUserOptions) {
|
|
|
11236
11694
|
ssrResolveConditions = config.ssr?.resolve?.conditions ? [...config.ssr.resolve.conditions] : void 0;
|
|
11237
11695
|
ssrTarget = config.ssr?.target ?? "node";
|
|
11238
11696
|
isProduction = config.isProduction;
|
|
11239
|
-
const ssrCapabilities = getSsrCapabilities(parseInt(version, 10), command, Object.keys(options.remotes).length > 0);
|
|
11697
|
+
const ssrCapabilities = getSsrCapabilities(parseInt(version, 10), command, Object.keys(options.remotes).length > 0, isSsrConfig(config));
|
|
11240
11698
|
resolveSharedVersions(shared, config.root);
|
|
11241
11699
|
initVirtualModules(command, remoteEntryId, ssrCapabilities.enableSsrInitBootstrap, options);
|
|
11242
11700
|
}
|
|
@@ -11286,6 +11744,7 @@ function federation(mfUserOptions) {
|
|
|
11286
11744
|
federationOptions: options,
|
|
11287
11745
|
getParsePromise: () => moduleParseController.parsePromise
|
|
11288
11746
|
}),
|
|
11747
|
+
pluginLazyConsumeOnlyShares(options),
|
|
11289
11748
|
{
|
|
11290
11749
|
name: "module-federation-esm-shims",
|
|
11291
11750
|
enforce: "pre",
|
|
@@ -11337,6 +11796,7 @@ function federation(mfUserOptions) {
|
|
|
11337
11796
|
priority: USER_GROUP_MAX_PRIORITY
|
|
11338
11797
|
};
|
|
11339
11798
|
};
|
|
11799
|
+
const federationGroupDebugName = supportsCodeSplittingGroupDebugName(this) ? { debugName: "module-federation" } : {};
|
|
11340
11800
|
let warnedAboutManualChunks = false;
|
|
11341
11801
|
let warnedAboutObjectManualChunks = false;
|
|
11342
11802
|
const applyManualChunks = (output, useCodeSplitting) => {
|
|
@@ -11344,11 +11804,13 @@ function federation(mfUserOptions) {
|
|
|
11344
11804
|
const isPatchedByPlugin = typeof output.manualChunks === "function" && patchedManualChunks.has(output.manualChunks);
|
|
11345
11805
|
const mfChunkName = function(id) {
|
|
11346
11806
|
if (id.includes(runtimeInitId) || id.includes("__mf_v__runtimeInit__mf_v__")) return "runtimeInit";
|
|
11807
|
+
if (isSharedCacheHelpersId(id)) return getSharedChunkName(id);
|
|
11347
11808
|
if (id.includes("__loadShare__")) {
|
|
11348
11809
|
const pkg = getCachedLoadSharePkg(id);
|
|
11349
11810
|
const key = pkg && findSharedKey(pkg, shared);
|
|
11350
11811
|
if (key && shared[key].shareConfig.eager === true) return "loadShare-eager";
|
|
11351
11812
|
if (key && shared[key].shareConfig.import === false) return null;
|
|
11813
|
+
if (pkg && !id.includes("commonjs-proxy") && isCoalescableLoadShareWrapper(pkg, options, id)) return getSharedChunkName(id);
|
|
11352
11814
|
const match = id.match(/([^/\\]+__loadShare__[^/\\]+)/);
|
|
11353
11815
|
return match ? match[1] : "loadShare";
|
|
11354
11816
|
}
|
|
@@ -11385,7 +11847,8 @@ function federation(mfUserOptions) {
|
|
|
11385
11847
|
};
|
|
11386
11848
|
const mfNameGroup = {
|
|
11387
11849
|
name: mfChunkName,
|
|
11388
|
-
priority: MF_GROUP_PRIORITY
|
|
11850
|
+
priority: MF_GROUP_PRIORITY,
|
|
11851
|
+
...federationGroupDebugName
|
|
11389
11852
|
};
|
|
11390
11853
|
federationGroups.add(mfPreloadGroup);
|
|
11391
11854
|
federationGroups.add(mfNameGroup);
|
|
@@ -11458,7 +11921,14 @@ function federation(mfUserOptions) {
|
|
|
11458
11921
|
if (!virtualModule?.code) return null;
|
|
11459
11922
|
let code = virtualModule.code;
|
|
11460
11923
|
const consumerTarget = resolveEnvironmentConsumerTarget(this);
|
|
11461
|
-
if (consumerTarget === "server" || !consumerTarget && isSsrBuild)
|
|
11924
|
+
if (consumerTarget === "server" || !consumerTarget && isSsrBuild) {
|
|
11925
|
+
const withSsrImport = prependWorkspaceSingletonSsrImport(code);
|
|
11926
|
+
if (withSsrImport !== code) {
|
|
11927
|
+
const pkg = getCachedLoadSharePkg(id);
|
|
11928
|
+
if (pkg) markLoadShareWrapperNotCoalescable(pkg, options, id);
|
|
11929
|
+
code = withSsrImport;
|
|
11930
|
+
}
|
|
11931
|
+
}
|
|
11462
11932
|
code = code.replace(/import\s+["'][^"']*__prebuild__[^"']*["']\s*;?/g, "");
|
|
11463
11933
|
code = code.replace(/export\s+\*\s+from\s+["'][^"']*__prebuild__[^"']*["']\s*;?/g, "");
|
|
11464
11934
|
if (!(/\b(?:var|let|const)\s+__moduleExports\b/.test(code) || /\bexport\s+const\s+__moduleExports\b/.test(code) || /\bexport\s*\{[^}]*__moduleExports/.test(code))) {
|
|
@@ -11476,6 +11946,9 @@ function federation(mfUserOptions) {
|
|
|
11476
11946
|
return loadVirtualModule();
|
|
11477
11947
|
},
|
|
11478
11948
|
generateBundle(_outputOptions, bundle, _isWrite) {
|
|
11949
|
+
inlineDeferredPrebuildNamespaceHelper(bundle);
|
|
11950
|
+
for (const [fileName, fallbacks] of findEagerFallbacksInSharedChunk(bundle)) mfWarn(`A shared-dependency fallback was merged into the loadShare chunk ${fileName}: ${fallbacks.join(", ")}.\n That fallback is no longer lazy, so consumers download their local copy even when a peer provides the share, and the container can deadlock.
|
|
11951
|
+
Stop the shared module from statically importing another share.`);
|
|
11479
11952
|
for (const [fileName, chunk] of Object.entries(bundle)) {
|
|
11480
11953
|
if (!isOutputChunk(chunk)) continue;
|
|
11481
11954
|
if (!isFederationControlChunk(fileName, filename)) continue;
|
|
@@ -11541,7 +12014,7 @@ function federation(mfUserOptions) {
|
|
|
11541
12014
|
config.optimizeDeps.include.push("@module-federation/runtime");
|
|
11542
12015
|
if (needsRuntimeHelpers) config.optimizeDeps.include.push("@module-federation/runtime/helpers");
|
|
11543
12016
|
options.runtimePlugins.forEach((p) => {
|
|
11544
|
-
const pluginPath =
|
|
12017
|
+
const pluginPath = getRuntimePluginSpecifier(p);
|
|
11545
12018
|
if (SSR_ONLY_RUNTIME_PLUGINS.has(pluginPath)) return;
|
|
11546
12019
|
if (pluginPath && !pluginPath.startsWith(".") && !pluginPath.startsWith("/") && !pluginPath.startsWith("\0") && !pluginPath.startsWith("virtual:")) {
|
|
11547
12020
|
let optimizeDep = pluginPath;
|
|
@@ -11557,6 +12030,14 @@ function federation(mfUserOptions) {
|
|
|
11557
12030
|
config.build ??= {};
|
|
11558
12031
|
config.build.target ??= "esnext";
|
|
11559
12032
|
}
|
|
12033
|
+
const isBundledDev = Boolean(config.experimental?.bundledDev);
|
|
12034
|
+
if (isRolldown && _command === "serve" && isBundledDev) {
|
|
12035
|
+
config.build.rolldownOptions ??= {};
|
|
12036
|
+
config.build.rolldownOptions.experimental ??= {};
|
|
12037
|
+
const devMode = config.build.rolldownOptions.experimental.devMode;
|
|
12038
|
+
if (typeof devMode === "object") devMode.lazy ??= false;
|
|
12039
|
+
else if (devMode === void 0) config.build.rolldownOptions.experimental.devMode = { lazy: false };
|
|
12040
|
+
}
|
|
11560
12041
|
const isAstro = hasPackageDependency("astro");
|
|
11561
12042
|
const resolvedTarget = options.target ?? (config.build?.ssr ? "node" : "web");
|
|
11562
12043
|
if (!config.define) config.define = {};
|
|
@@ -11577,7 +12058,7 @@ function federation(mfUserOptions) {
|
|
|
11577
12058
|
if (prematureExit) prematureExit.closeBundle = void 0;
|
|
11578
12059
|
},
|
|
11579
12060
|
configEnvironment(name, config) {
|
|
11580
|
-
if (!(
|
|
12061
|
+
if (!isServerEnvironment(name, config)) return;
|
|
11581
12062
|
const isAstro = hasPackageDependency("astro");
|
|
11582
12063
|
config.define = { ...config.define ?? {} };
|
|
11583
12064
|
applyBuildTimeRuntimeDefines(config.define, options, {
|