@module-federation/vite 1.16.16 → 1.17.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 +29 -0
- package/lib/index.d.ts +12 -2
- package/lib/index.js +2157 -288
- package/lib/{pluginDts-Bo95ELmX.js → pluginDts-CGDIZCsD.js} +119 -2
- package/lib/ssrEntryLoader-D_sUES94.js +553 -0
- package/lib/{ssrVmStrategy-DtpfkCw1.js → ssrVmStrategy-By_N71Dl.js} +9 -5
- package/lib/utils/ssrEntryLoader.d.ts +5 -0
- package/lib/utils/ssrEntryLoader.js +1 -490
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as createModuleFederationError, a as getIsRolldown, b as rebaseImport, c as getPackageNameFromNodeModulePath, d as isNuxtProjectRoot, f as packageNameDecode, g as sharedCacheHelperCode, h as setPackageDetectionCwd, i as getInstalledPackageJson, l as getSharedCacheDescriptor, m as resolveImportPath, o as getPackageDetectionCwd, p as packageNameEncode, r as getInstalledPackageEntry, s as getPackageName, u as hasPackageDependency, v as mfWarn, y as normalizePathForImport } from "./pluginDts-
|
|
1
|
+
import { _ as createModuleFederationError, a as getIsRolldown, b as rebaseImport, c as getPackageNameFromNodeModulePath, d as isNuxtProjectRoot, f as packageNameDecode, g as sharedCacheHelperCode, h as setPackageDetectionCwd, i as getInstalledPackageJson, l as getSharedCacheDescriptor, m as resolveImportPath, o as getPackageDetectionCwd, p as packageNameEncode, r as getInstalledPackageEntry, s as getPackageName, u as hasPackageDependency, v as mfWarn, y as normalizePathForImport } from "./pluginDts-CGDIZCsD.js";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import * as fs$2 from "fs";
|
|
4
4
|
import { existsSync, readFileSync, realpathSync, statSync, writeFileSync } from "fs";
|
|
@@ -6,7 +6,7 @@ import { createRequire as createRequire$1 } from "module";
|
|
|
6
6
|
import * as path$1 from "node:path";
|
|
7
7
|
import path, { basename } from "node:path";
|
|
8
8
|
import { fileURLToPath, pathToFileURL } from "url";
|
|
9
|
-
import { version } from "vite";
|
|
9
|
+
import { parseAst, version } from "vite";
|
|
10
10
|
import { createHash } from "node:crypto";
|
|
11
11
|
import * as fs$1 from "node:fs";
|
|
12
12
|
import { existsSync as existsSync$1, readFileSync as readFileSync$1 } from "node:fs";
|
|
@@ -373,6 +373,10 @@ function normalizeShareItem(key, shareItem) {
|
|
|
373
373
|
const isImportFalse = typeof shareItem === "object" && shareItem.import === false;
|
|
374
374
|
const explicitVersion = typeof shareItem === "object" ? shareItem.version : void 0;
|
|
375
375
|
const inferredVersion = typeof shareItem === "object" ? inferVersionFromRequiredVersion(shareItem.requiredVersion) : void 0;
|
|
376
|
+
const treeShaking = typeof shareItem === "object" ? shareItem.treeShaking : void 0;
|
|
377
|
+
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".`);
|
|
378
|
+
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.`);
|
|
379
|
+
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.`);
|
|
376
380
|
const version = explicitVersion || searchPackageVersion(key) || inferredVersion;
|
|
377
381
|
if (typeof shareItem === "string") return {
|
|
378
382
|
name: shareItem,
|
|
@@ -382,6 +386,7 @@ function normalizeShareItem(key, shareItem) {
|
|
|
382
386
|
shareConfig: {
|
|
383
387
|
import: void 0,
|
|
384
388
|
singleton: false,
|
|
389
|
+
eager: false,
|
|
385
390
|
requiredVersion: version ? `^${version}` : "*"
|
|
386
391
|
}
|
|
387
392
|
};
|
|
@@ -393,8 +398,10 @@ function normalizeShareItem(key, shareItem) {
|
|
|
393
398
|
shareConfig: {
|
|
394
399
|
import: shareItem.import,
|
|
395
400
|
singleton: shareItem.singleton || false,
|
|
401
|
+
eager: shareItem.eager || false,
|
|
396
402
|
requiredVersion: shareItem.requiredVersion !== void 0 ? shareItem.requiredVersion : isImportFalse || shareItem.version ? "*" : version ? `^${version}` : "*",
|
|
397
|
-
strictVersion: !!shareItem.strictVersion
|
|
403
|
+
strictVersion: !!shareItem.strictVersion,
|
|
404
|
+
...treeShaking ? { treeShaking: { ...treeShaking } } : {}
|
|
398
405
|
}
|
|
399
406
|
};
|
|
400
407
|
}
|
|
@@ -519,7 +526,7 @@ function normalizeModuleFederationOptions(options) {
|
|
|
519
526
|
shareScope: options.shareScope || "default",
|
|
520
527
|
shared: normalizeShared(options.shared),
|
|
521
528
|
runtimePlugins: options.runtimePlugins || [],
|
|
522
|
-
implementation: options.implementation || resolveRuntimeImplementation(),
|
|
529
|
+
implementation: normalizePathForImport(options.implementation || resolveRuntimeImplementation()),
|
|
523
530
|
manifest: normalizeManifest(options.manifest),
|
|
524
531
|
dev: options.dev,
|
|
525
532
|
dts: options.dts,
|
|
@@ -530,6 +537,10 @@ function normalizeModuleFederationOptions(options) {
|
|
|
530
537
|
virtualModuleDir: options.virtualModuleDir || "__mf__virtual",
|
|
531
538
|
hostInitInjectLocation: options.hostInitInjectLocation || "html",
|
|
532
539
|
bundleAllCSS: options.bundleAllCSS || false,
|
|
540
|
+
treeShakingDir: options.treeShakingDir,
|
|
541
|
+
injectTreeShakingUsedExports: options.injectTreeShakingUsedExports,
|
|
542
|
+
treeShakingSharedPlugins: options.treeShakingSharedPlugins,
|
|
543
|
+
treeShakingSharedExcludePlugins: options.treeShakingSharedExcludePlugins,
|
|
533
544
|
moduleParseTimeout: options.moduleParseTimeout || 10,
|
|
534
545
|
moduleParseIdleTimeout: options.moduleParseIdleTimeout,
|
|
535
546
|
varFilename: options.varFilename,
|
|
@@ -549,11 +560,11 @@ const cacheMap = {};
|
|
|
549
560
|
const idCacheMap = {};
|
|
550
561
|
const VITE_ID_PREFIX = "/@id/";
|
|
551
562
|
const VITE_ENCODED_NULL_BYTE_PREFIX = `${VITE_ID_PREFIX}__x00__`;
|
|
552
|
-
function escapeRegExp$
|
|
563
|
+
function escapeRegExp$2(value) {
|
|
553
564
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
554
565
|
}
|
|
555
566
|
function createViteEncodedIdPrefixRegExp(sourcePrefix = "") {
|
|
556
|
-
return new RegExp(`^(?:${escapeRegExp$
|
|
567
|
+
return new RegExp(`^(?:${escapeRegExp$2(VITE_ENCODED_NULL_BYTE_PREFIX)})?${sourcePrefix}`);
|
|
557
568
|
}
|
|
558
569
|
function toViteEncodedId(id) {
|
|
559
570
|
return `${VITE_ENCODED_NULL_BYTE_PREFIX}${id}`;
|
|
@@ -928,6 +939,396 @@ ${exportStatement}
|
|
|
928
939
|
`);
|
|
929
940
|
}
|
|
930
941
|
//#endregion
|
|
942
|
+
//#region src/utils/codePositionMap.ts
|
|
943
|
+
const REGEX_PREFIX_KEYWORDS = new Set([
|
|
944
|
+
"await",
|
|
945
|
+
"case",
|
|
946
|
+
"delete",
|
|
947
|
+
"in",
|
|
948
|
+
"instanceof",
|
|
949
|
+
"new",
|
|
950
|
+
"return",
|
|
951
|
+
"throw",
|
|
952
|
+
"typeof",
|
|
953
|
+
"void",
|
|
954
|
+
"yield"
|
|
955
|
+
]);
|
|
956
|
+
function isJsxClosingTagSlash(code, slashIndex) {
|
|
957
|
+
if (code[slashIndex - 1] !== "<") return false;
|
|
958
|
+
let cursor = slashIndex + 1;
|
|
959
|
+
while (/\s/.test(code[cursor] || "")) cursor++;
|
|
960
|
+
if (code[cursor] === ">") return true;
|
|
961
|
+
const tagStart = cursor;
|
|
962
|
+
while (/[-:.$_\u200C\u200D\p{ID_Continue}]/u.test(code[cursor] || "")) cursor++;
|
|
963
|
+
if (cursor === tagStart) return false;
|
|
964
|
+
while (/\s/.test(code[cursor] || "")) cursor++;
|
|
965
|
+
return code[cursor] === ">";
|
|
966
|
+
}
|
|
967
|
+
/** Mark comments, string/template literals, and regular expressions as non-code. */
|
|
968
|
+
function createCodePositionMap(code) {
|
|
969
|
+
const positions = Array(code.length).fill(true);
|
|
970
|
+
const mask = (start, end) => {
|
|
971
|
+
for (let index = start; index < end; index++) positions[index] = false;
|
|
972
|
+
};
|
|
973
|
+
let canStartRegex = true;
|
|
974
|
+
for (let index = 0; index < code.length;) {
|
|
975
|
+
const char = code[index];
|
|
976
|
+
const next = code[index + 1];
|
|
977
|
+
if (/\s/.test(char)) {
|
|
978
|
+
index++;
|
|
979
|
+
continue;
|
|
980
|
+
}
|
|
981
|
+
if (char === "/" && next === "/") {
|
|
982
|
+
const start = index;
|
|
983
|
+
index += 2;
|
|
984
|
+
while (index < code.length && code[index] !== "\n" && code[index] !== "\r") index++;
|
|
985
|
+
mask(start, index);
|
|
986
|
+
continue;
|
|
987
|
+
}
|
|
988
|
+
if (char === "/" && next === "*") {
|
|
989
|
+
const start = index;
|
|
990
|
+
index += 2;
|
|
991
|
+
while (index < code.length && !(code[index] === "*" && code[index + 1] === "/")) index++;
|
|
992
|
+
index = Math.min(code.length, index + 2);
|
|
993
|
+
mask(start, index);
|
|
994
|
+
continue;
|
|
995
|
+
}
|
|
996
|
+
if (char === "\"" || char === "'" || char === "`") {
|
|
997
|
+
const quote = char;
|
|
998
|
+
const start = index++;
|
|
999
|
+
while (index < code.length) {
|
|
1000
|
+
if (code[index] === "\\") {
|
|
1001
|
+
index += 2;
|
|
1002
|
+
continue;
|
|
1003
|
+
}
|
|
1004
|
+
if (code[index] === quote) {
|
|
1005
|
+
index++;
|
|
1006
|
+
break;
|
|
1007
|
+
}
|
|
1008
|
+
index++;
|
|
1009
|
+
}
|
|
1010
|
+
mask(start, index);
|
|
1011
|
+
canStartRegex = false;
|
|
1012
|
+
continue;
|
|
1013
|
+
}
|
|
1014
|
+
const closesJsxTag = isJsxClosingTagSlash(code, index);
|
|
1015
|
+
if (char === "/" && canStartRegex && !closesJsxTag) {
|
|
1016
|
+
const start = index;
|
|
1017
|
+
let cursor = index + 1;
|
|
1018
|
+
let escaped = false;
|
|
1019
|
+
let inCharacterClass = false;
|
|
1020
|
+
let closed = false;
|
|
1021
|
+
for (; cursor < code.length; cursor++) {
|
|
1022
|
+
const regexChar = code[cursor];
|
|
1023
|
+
if (regexChar === "\n" || regexChar === "\r") break;
|
|
1024
|
+
if (escaped) {
|
|
1025
|
+
escaped = false;
|
|
1026
|
+
continue;
|
|
1027
|
+
}
|
|
1028
|
+
if (regexChar === "\\") {
|
|
1029
|
+
escaped = true;
|
|
1030
|
+
continue;
|
|
1031
|
+
}
|
|
1032
|
+
if (regexChar === "[") {
|
|
1033
|
+
inCharacterClass = true;
|
|
1034
|
+
continue;
|
|
1035
|
+
}
|
|
1036
|
+
if (regexChar === "]" && inCharacterClass) {
|
|
1037
|
+
inCharacterClass = false;
|
|
1038
|
+
continue;
|
|
1039
|
+
}
|
|
1040
|
+
if (regexChar === "/" && !inCharacterClass) {
|
|
1041
|
+
cursor++;
|
|
1042
|
+
while (/[$_\p{ID_Continue}]/u.test(code[cursor] || "")) cursor++;
|
|
1043
|
+
closed = true;
|
|
1044
|
+
break;
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
if (closed) {
|
|
1048
|
+
mask(start, cursor);
|
|
1049
|
+
index = cursor;
|
|
1050
|
+
canStartRegex = false;
|
|
1051
|
+
continue;
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
if (/[$_\p{ID_Start}]/u.test(char)) {
|
|
1055
|
+
const start = index++;
|
|
1056
|
+
while (/[$_\u200C\u200D\p{ID_Continue}]/u.test(code[index] || "")) index++;
|
|
1057
|
+
canStartRegex = REGEX_PREFIX_KEYWORDS.has(code.slice(start, index));
|
|
1058
|
+
continue;
|
|
1059
|
+
}
|
|
1060
|
+
if (/\d/.test(char)) {
|
|
1061
|
+
index++;
|
|
1062
|
+
while (/[\w.]/.test(code[index] || "")) index++;
|
|
1063
|
+
canStartRegex = false;
|
|
1064
|
+
continue;
|
|
1065
|
+
}
|
|
1066
|
+
if ((char === "+" || char === "-") && next === char) {
|
|
1067
|
+
index += 2;
|
|
1068
|
+
continue;
|
|
1069
|
+
}
|
|
1070
|
+
if (char === "!" && next !== "=") {
|
|
1071
|
+
index++;
|
|
1072
|
+
continue;
|
|
1073
|
+
}
|
|
1074
|
+
if (char === ")" || char === "]" || char === "}") canStartRegex = false;
|
|
1075
|
+
else if (char !== ".") canStartRegex = true;
|
|
1076
|
+
index++;
|
|
1077
|
+
}
|
|
1078
|
+
return positions;
|
|
1079
|
+
}
|
|
1080
|
+
//#endregion
|
|
1081
|
+
//#region src/utils/treeShaking.ts
|
|
1082
|
+
/**
|
|
1083
|
+
* Analysis is scoped by both the configured share key and the concrete module
|
|
1084
|
+
* request. A prefix share such as `lodash/` may materialize separate wrappers
|
|
1085
|
+
* for `lodash/get` and `lodash/debounce`; combining those export sets would
|
|
1086
|
+
* generate invalid wrappers and defeat per-subpath tree shaking.
|
|
1087
|
+
*/
|
|
1088
|
+
const inferredTreeShakingUsage = /* @__PURE__ */ new Map();
|
|
1089
|
+
let treeShakingBuildMode = false;
|
|
1090
|
+
function setTreeShakingBuildMode(enabled) {
|
|
1091
|
+
treeShakingBuildMode = enabled;
|
|
1092
|
+
}
|
|
1093
|
+
function resetTreeShakingExports() {
|
|
1094
|
+
inferredTreeShakingUsage.clear();
|
|
1095
|
+
}
|
|
1096
|
+
function getOrCreateExportRecord(sharedKey, request) {
|
|
1097
|
+
let byRequest = inferredTreeShakingUsage.get(sharedKey);
|
|
1098
|
+
if (!byRequest) {
|
|
1099
|
+
byRequest = /* @__PURE__ */ new Map();
|
|
1100
|
+
inferredTreeShakingUsage.set(sharedKey, byRequest);
|
|
1101
|
+
}
|
|
1102
|
+
let record = byRequest.get(request);
|
|
1103
|
+
if (!record) {
|
|
1104
|
+
record = {
|
|
1105
|
+
requiresFullBundle: false,
|
|
1106
|
+
usedExports: /* @__PURE__ */ new Set()
|
|
1107
|
+
};
|
|
1108
|
+
byRequest.set(request, record);
|
|
1109
|
+
}
|
|
1110
|
+
return record;
|
|
1111
|
+
}
|
|
1112
|
+
function recordTreeShakingExports(sharedKey, exports, request = sharedKey) {
|
|
1113
|
+
const record = getOrCreateExportRecord(sharedKey, request);
|
|
1114
|
+
exports.forEach((name) => record.usedExports.add(name));
|
|
1115
|
+
}
|
|
1116
|
+
function markTreeShakingPackageUnsafe(sharedKey, request = sharedKey) {
|
|
1117
|
+
getOrCreateExportRecord(sharedKey, request).requiresFullBundle = true;
|
|
1118
|
+
}
|
|
1119
|
+
function getExportRecords(sharedKey, request) {
|
|
1120
|
+
if (sharedKey) {
|
|
1121
|
+
const records = inferredTreeShakingUsage.get(sharedKey);
|
|
1122
|
+
const wildcard = records?.get("*");
|
|
1123
|
+
const exact = records?.get(request);
|
|
1124
|
+
return [wildcard, exact === wildcard ? void 0 : exact].filter((record) => !!record);
|
|
1125
|
+
}
|
|
1126
|
+
const records = [];
|
|
1127
|
+
inferredTreeShakingUsage.forEach((byRequest, configuredKey) => {
|
|
1128
|
+
const wildcard = byRequest.get("*");
|
|
1129
|
+
const exact = byRequest.get(request);
|
|
1130
|
+
const keyBase = configuredKey.endsWith("/") ? configuredKey.slice(0, -1) : configuredKey;
|
|
1131
|
+
const requestMatchesConfiguredKey = request === keyBase || request.startsWith(`${keyBase}/`);
|
|
1132
|
+
if (wildcard && requestMatchesConfiguredKey) records.push(wildcard);
|
|
1133
|
+
if (exact && exact !== wildcard) records.push(exact);
|
|
1134
|
+
});
|
|
1135
|
+
return records;
|
|
1136
|
+
}
|
|
1137
|
+
/**
|
|
1138
|
+
* Return the analyzed requirement for one concrete shared request.
|
|
1139
|
+
*
|
|
1140
|
+
* Callers that know the configured share key should pass it explicitly. The
|
|
1141
|
+
* fallback lookup across keys keeps aliases/backwards-compatible callers
|
|
1142
|
+
* working, while still keeping each concrete request's exports isolated.
|
|
1143
|
+
*/
|
|
1144
|
+
function getTreeShakingExportUsage(request, shareItem, sharedKey) {
|
|
1145
|
+
const treeShaking = shareItem?.shareConfig.treeShaking;
|
|
1146
|
+
if (!treeShaking || !treeShakingBuildMode) return void 0;
|
|
1147
|
+
const records = getExportRecords(sharedKey, request);
|
|
1148
|
+
if (records.some((record) => record.requiresFullBundle)) return { kind: "full" };
|
|
1149
|
+
const configured = treeShaking.usedExports ?? [];
|
|
1150
|
+
const result = new Set(configured);
|
|
1151
|
+
records.forEach((record) => record.usedExports.forEach((name) => result.add(name)));
|
|
1152
|
+
if (result.size > 0) return {
|
|
1153
|
+
kind: "exports",
|
|
1154
|
+
usedExports: [...result].sort()
|
|
1155
|
+
};
|
|
1156
|
+
return records.length > 0 ? {
|
|
1157
|
+
kind: "exports",
|
|
1158
|
+
usedExports: []
|
|
1159
|
+
} : { kind: "unknown" };
|
|
1160
|
+
}
|
|
1161
|
+
function getModuleSource(node) {
|
|
1162
|
+
if (!node || typeof node !== "object") return void 0;
|
|
1163
|
+
const source = node;
|
|
1164
|
+
if (source.type === "Literal" && typeof source.value === "string") return source.value;
|
|
1165
|
+
if (source.type === "StringLiteral" && typeof source.value === "string") return source.value;
|
|
1166
|
+
if (source.type !== "TemplateLiteral") return void 0;
|
|
1167
|
+
const expressions = Array.isArray(source.expressions) ? source.expressions : [];
|
|
1168
|
+
const quasis = Array.isArray(source.quasis) ? source.quasis : [];
|
|
1169
|
+
if (expressions.length > 0 || quasis.length !== 1) return void 0;
|
|
1170
|
+
const value = quasis[0]?.value;
|
|
1171
|
+
return typeof value?.cooked === "string" ? value.cooked : typeof value?.raw === "string" ? value.raw : void 0;
|
|
1172
|
+
}
|
|
1173
|
+
function getExportedName(node) {
|
|
1174
|
+
if (!node || typeof node !== "object") return void 0;
|
|
1175
|
+
const exported = node;
|
|
1176
|
+
if (exported.type === "Identifier" && typeof exported.name === "string") return exported.name;
|
|
1177
|
+
if ((exported.type === "Literal" || exported.type === "StringLiteral") && typeof exported.value === "string") return exported.value;
|
|
1178
|
+
}
|
|
1179
|
+
function isTypeOnly(node) {
|
|
1180
|
+
return node.importKind === "type" || node.exportKind === "type";
|
|
1181
|
+
}
|
|
1182
|
+
function forEachAstNode(root, visit) {
|
|
1183
|
+
const stack = [root];
|
|
1184
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1185
|
+
while (stack.length > 0) {
|
|
1186
|
+
const value = stack.pop();
|
|
1187
|
+
if (!value || typeof value !== "object") continue;
|
|
1188
|
+
if (seen.has(value)) continue;
|
|
1189
|
+
seen.add(value);
|
|
1190
|
+
if (Array.isArray(value)) {
|
|
1191
|
+
for (let index = value.length - 1; index >= 0; index--) stack.push(value[index]);
|
|
1192
|
+
continue;
|
|
1193
|
+
}
|
|
1194
|
+
const node = value;
|
|
1195
|
+
if (typeof node.type === "string") visit(node);
|
|
1196
|
+
Object.entries(node).forEach(([key, child]) => {
|
|
1197
|
+
if (key !== "parent" && key !== "loc") stack.push(child);
|
|
1198
|
+
});
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
function collectImportDeclaration(node, source, record, markUnsafe) {
|
|
1202
|
+
if (isTypeOnly(node)) return;
|
|
1203
|
+
const specifiers = Array.isArray(node.specifiers) ? node.specifiers : [];
|
|
1204
|
+
if (specifiers.length === 0) {
|
|
1205
|
+
markUnsafe(source);
|
|
1206
|
+
return;
|
|
1207
|
+
}
|
|
1208
|
+
const names = [];
|
|
1209
|
+
for (const specifier of specifiers) {
|
|
1210
|
+
if (isTypeOnly(specifier)) continue;
|
|
1211
|
+
if (specifier.type === "ImportNamespaceSpecifier") {
|
|
1212
|
+
markUnsafe(source);
|
|
1213
|
+
return;
|
|
1214
|
+
}
|
|
1215
|
+
if (specifier.type === "ImportDefaultSpecifier") {
|
|
1216
|
+
names.push("default");
|
|
1217
|
+
continue;
|
|
1218
|
+
}
|
|
1219
|
+
if (specifier.type === "ImportSpecifier") {
|
|
1220
|
+
const imported = specifier.imported;
|
|
1221
|
+
if (imported?.type === "Literal" || imported?.type === "StringLiteral") {
|
|
1222
|
+
markUnsafe(source);
|
|
1223
|
+
return;
|
|
1224
|
+
}
|
|
1225
|
+
const name = getExportedName(specifier.imported);
|
|
1226
|
+
if (!name) {
|
|
1227
|
+
markUnsafe(source);
|
|
1228
|
+
return;
|
|
1229
|
+
}
|
|
1230
|
+
names.push(name);
|
|
1231
|
+
continue;
|
|
1232
|
+
}
|
|
1233
|
+
markUnsafe(source);
|
|
1234
|
+
return;
|
|
1235
|
+
}
|
|
1236
|
+
record(names, source);
|
|
1237
|
+
}
|
|
1238
|
+
function collectReExport(node, source, record, markUnsafe) {
|
|
1239
|
+
if (isTypeOnly(node)) return;
|
|
1240
|
+
if (node.type === "ExportAllDeclaration") {
|
|
1241
|
+
markUnsafe(source);
|
|
1242
|
+
return;
|
|
1243
|
+
}
|
|
1244
|
+
const specifiers = Array.isArray(node.specifiers) ? node.specifiers : [];
|
|
1245
|
+
if (specifiers.length === 0) {
|
|
1246
|
+
markUnsafe(source);
|
|
1247
|
+
return;
|
|
1248
|
+
}
|
|
1249
|
+
const names = [];
|
|
1250
|
+
for (const specifier of specifiers) {
|
|
1251
|
+
if (isTypeOnly(specifier)) continue;
|
|
1252
|
+
if (specifier.type !== "ExportSpecifier") {
|
|
1253
|
+
markUnsafe(source);
|
|
1254
|
+
return;
|
|
1255
|
+
}
|
|
1256
|
+
const local = specifier.local;
|
|
1257
|
+
if (local?.type === "Literal" || local?.type === "StringLiteral") {
|
|
1258
|
+
markUnsafe(source);
|
|
1259
|
+
return;
|
|
1260
|
+
}
|
|
1261
|
+
const name = getExportedName(specifier.local);
|
|
1262
|
+
if (!name) {
|
|
1263
|
+
markUnsafe(source);
|
|
1264
|
+
return;
|
|
1265
|
+
}
|
|
1266
|
+
names.push(name);
|
|
1267
|
+
}
|
|
1268
|
+
record(names, source);
|
|
1269
|
+
}
|
|
1270
|
+
/**
|
|
1271
|
+
* Collect the exports required by a consumer's ESM graph.
|
|
1272
|
+
*
|
|
1273
|
+
* Parsing the module avoids treating import-looking text in comments, strings,
|
|
1274
|
+
* templates, or regular expressions as real dependencies. If parsing fails,
|
|
1275
|
+
* every configured tree-shaken share is conservatively marked as requiring its
|
|
1276
|
+
* full bundle instead of guessing from source text.
|
|
1277
|
+
*
|
|
1278
|
+
* Generated federation wrappers are excluded because their imports describe
|
|
1279
|
+
* the wrapper implementation, not the consumer's requirements.
|
|
1280
|
+
*/
|
|
1281
|
+
function collectTreeShakingImports(code, id, shared, findSharedKey, record, markUnsafe) {
|
|
1282
|
+
const normalizedId = normalizePathForImport(id);
|
|
1283
|
+
if (normalizedId.includes("__prebuild__") || normalizedId.includes("__loadShare__") || normalizedId.includes("__mf_tree_shaking_graph__")) return;
|
|
1284
|
+
let ast;
|
|
1285
|
+
try {
|
|
1286
|
+
ast = parseAst(code);
|
|
1287
|
+
} catch {
|
|
1288
|
+
Object.entries(shared).forEach(([sharedKey, shareItem]) => {
|
|
1289
|
+
if (shareItem.shareConfig.treeShaking) markUnsafe(sharedKey, "*");
|
|
1290
|
+
});
|
|
1291
|
+
return;
|
|
1292
|
+
}
|
|
1293
|
+
const matchShared = (source) => {
|
|
1294
|
+
const sharedKey = findSharedKey(source, shared);
|
|
1295
|
+
return sharedKey && shared[sharedKey]?.shareConfig.treeShaking ? sharedKey : void 0;
|
|
1296
|
+
};
|
|
1297
|
+
const recordSource = (names, source) => {
|
|
1298
|
+
const sharedKey = matchShared(source);
|
|
1299
|
+
if (sharedKey) record(sharedKey, names, source);
|
|
1300
|
+
};
|
|
1301
|
+
const markSourceUnsafe = (source) => {
|
|
1302
|
+
const sharedKey = matchShared(source);
|
|
1303
|
+
if (sharedKey) markUnsafe(sharedKey, source);
|
|
1304
|
+
};
|
|
1305
|
+
forEachAstNode(ast, (node) => {
|
|
1306
|
+
if (node.type === "ImportDeclaration") {
|
|
1307
|
+
const source = getModuleSource(node.source);
|
|
1308
|
+
if (source) collectImportDeclaration(node, source, recordSource, markSourceUnsafe);
|
|
1309
|
+
return;
|
|
1310
|
+
}
|
|
1311
|
+
if ((node.type === "ExportNamedDeclaration" || node.type === "ExportAllDeclaration") && node.source) {
|
|
1312
|
+
const source = getModuleSource(node.source);
|
|
1313
|
+
if (source) collectReExport(node, source, recordSource, markSourceUnsafe);
|
|
1314
|
+
return;
|
|
1315
|
+
}
|
|
1316
|
+
if (node.type === "ImportExpression") {
|
|
1317
|
+
const source = getModuleSource(node.source);
|
|
1318
|
+
if (source) markSourceUnsafe(source);
|
|
1319
|
+
return;
|
|
1320
|
+
}
|
|
1321
|
+
if (node.type === "CallExpression") {
|
|
1322
|
+
const callee = node.callee;
|
|
1323
|
+
const args = Array.isArray(node.arguments) ? node.arguments : [];
|
|
1324
|
+
if (callee?.type === "Identifier" && callee.name === "require" && args.length > 0) {
|
|
1325
|
+
const source = getModuleSource(args[0]);
|
|
1326
|
+
if (source) markSourceUnsafe(source);
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
});
|
|
1330
|
+
}
|
|
1331
|
+
//#endregion
|
|
931
1332
|
//#region src/virtualModules/virtualShared_preBuild.ts
|
|
932
1333
|
/**
|
|
933
1334
|
* Even the resolveId hook cannot interfere with vite pre-build,
|
|
@@ -979,17 +1380,30 @@ function getPackageEsmEntryPath(pkg) {
|
|
|
979
1380
|
resolveSubpathWithRequire: false
|
|
980
1381
|
}) || resolvePackageEntryFromProjectRoot(pkg);
|
|
981
1382
|
}
|
|
982
|
-
function
|
|
1383
|
+
function hasCodeMatch(source, regex, codePositions) {
|
|
1384
|
+
regex.lastIndex = 0;
|
|
1385
|
+
let match;
|
|
1386
|
+
while ((match = regex.exec(source)) !== null) if (codePositions[match.index]) return true;
|
|
1387
|
+
return false;
|
|
1388
|
+
}
|
|
1389
|
+
function hasCommonJsExports(source) {
|
|
1390
|
+
return hasCodeMatch(source, /\bmodule\s*(?:\.exports|\[\s*['"]exports['"]\s*\])|\bexports\s*(?:\.|\[|[,)]|=(?!=|>))/g, createCodePositionMap(source));
|
|
1391
|
+
}
|
|
1392
|
+
function inspectSharedExportsFromFile(entryPath) {
|
|
983
1393
|
try {
|
|
984
|
-
if (!entryPath) return
|
|
985
|
-
|
|
1394
|
+
if (!entryPath) return void 0;
|
|
1395
|
+
const source = readFileSync(entryPath, "utf-8");
|
|
1396
|
+
const scanState = { complete: true };
|
|
1397
|
+
const namedExports = getNamedExportsViaRegex(source, entryPath, void 0, scanState);
|
|
1398
|
+
const commonJs = hasCommonJsExports(source);
|
|
1399
|
+
return {
|
|
1400
|
+
namedExports: scanState.complete && !commonJs ? namedExports : void 0,
|
|
1401
|
+
commonJs
|
|
1402
|
+
};
|
|
986
1403
|
} catch {
|
|
987
|
-
return
|
|
1404
|
+
return;
|
|
988
1405
|
}
|
|
989
1406
|
}
|
|
990
|
-
function getEsmNamedExports(pkg) {
|
|
991
|
-
return getEsmNamedExportsFromFile(getPackageEsmEntryPath(pkg));
|
|
992
|
-
}
|
|
993
1407
|
function resolveConfiguredImportPath(importSource) {
|
|
994
1408
|
if (path$1.isAbsolute(importSource)) return resolveFileLikeModule(importSource);
|
|
995
1409
|
const projectRoot = getPackageDetectionCwd();
|
|
@@ -1070,19 +1484,156 @@ function resolveReExportModule(filePath, specifier) {
|
|
|
1070
1484
|
return;
|
|
1071
1485
|
}
|
|
1072
1486
|
}
|
|
1073
|
-
function
|
|
1487
|
+
function hasTopLevelDeclaratorComma(source, start) {
|
|
1488
|
+
let depth = 0;
|
|
1489
|
+
let quote;
|
|
1490
|
+
let escaped = false;
|
|
1491
|
+
let canStartRegex = true;
|
|
1492
|
+
for (let index = start; index < source.length; index++) {
|
|
1493
|
+
const char = source[index];
|
|
1494
|
+
if (quote) {
|
|
1495
|
+
if (escaped) escaped = false;
|
|
1496
|
+
else if (char === "\\") escaped = true;
|
|
1497
|
+
else if (char === quote) quote = void 0;
|
|
1498
|
+
continue;
|
|
1499
|
+
}
|
|
1500
|
+
if (char === "\"" || char === "'" || char === "`") {
|
|
1501
|
+
quote = char;
|
|
1502
|
+
canStartRegex = false;
|
|
1503
|
+
continue;
|
|
1504
|
+
}
|
|
1505
|
+
if (char === "/" && source[index + 1] === "/") {
|
|
1506
|
+
index = source.indexOf("\n", index + 2);
|
|
1507
|
+
if (index === -1) return false;
|
|
1508
|
+
continue;
|
|
1509
|
+
}
|
|
1510
|
+
if (char === "/" && source[index + 1] === "*") {
|
|
1511
|
+
const commentEnd = source.indexOf("*/", index + 2);
|
|
1512
|
+
if (commentEnd === -1) return true;
|
|
1513
|
+
index = commentEnd + 1;
|
|
1514
|
+
continue;
|
|
1515
|
+
}
|
|
1516
|
+
if (char === "/" && canStartRegex) {
|
|
1517
|
+
let regexEscaped = false;
|
|
1518
|
+
let inCharacterClass = false;
|
|
1519
|
+
let closed = false;
|
|
1520
|
+
for (index++; index < source.length; index++) {
|
|
1521
|
+
const regexChar = source[index];
|
|
1522
|
+
if (regexEscaped) {
|
|
1523
|
+
regexEscaped = false;
|
|
1524
|
+
continue;
|
|
1525
|
+
}
|
|
1526
|
+
if (regexChar === "\\") {
|
|
1527
|
+
regexEscaped = true;
|
|
1528
|
+
continue;
|
|
1529
|
+
}
|
|
1530
|
+
if (regexChar === "[") {
|
|
1531
|
+
inCharacterClass = true;
|
|
1532
|
+
continue;
|
|
1533
|
+
}
|
|
1534
|
+
if (regexChar === "]" && inCharacterClass) {
|
|
1535
|
+
inCharacterClass = false;
|
|
1536
|
+
continue;
|
|
1537
|
+
}
|
|
1538
|
+
if (regexChar === "/" && !inCharacterClass) {
|
|
1539
|
+
closed = true;
|
|
1540
|
+
while (/[$_\p{ID_Continue}]/u.test(source[index + 1] || "")) index++;
|
|
1541
|
+
break;
|
|
1542
|
+
}
|
|
1543
|
+
if (regexChar === "\n" || regexChar === "\r") return true;
|
|
1544
|
+
}
|
|
1545
|
+
if (!closed) return true;
|
|
1546
|
+
canStartRegex = false;
|
|
1547
|
+
continue;
|
|
1548
|
+
}
|
|
1549
|
+
if (char === "/") {
|
|
1550
|
+
canStartRegex = true;
|
|
1551
|
+
continue;
|
|
1552
|
+
}
|
|
1553
|
+
if (/[$_\p{ID_Start}]/u.test(char)) {
|
|
1554
|
+
const tokenStart = index;
|
|
1555
|
+
while (/[$_\u200C\u200D\p{ID_Continue}]/u.test(source[index + 1] || "")) index++;
|
|
1556
|
+
const token = source.slice(tokenStart, index + 1);
|
|
1557
|
+
canStartRegex = /^(?:await|case|delete|in|instanceof|new|return|throw|typeof|void|yield)$/.test(token);
|
|
1558
|
+
continue;
|
|
1559
|
+
}
|
|
1560
|
+
if (/\d/.test(char)) {
|
|
1561
|
+
while (/[\w.]/.test(source[index + 1] || "")) index++;
|
|
1562
|
+
canStartRegex = false;
|
|
1563
|
+
continue;
|
|
1564
|
+
}
|
|
1565
|
+
if ((char === "+" || char === "-") && source[index + 1] === char) {
|
|
1566
|
+
index++;
|
|
1567
|
+
continue;
|
|
1568
|
+
}
|
|
1569
|
+
if (char === "!" && source[index + 1] !== "=") continue;
|
|
1570
|
+
if (char === "(" || char === "[" || char === "{") {
|
|
1571
|
+
depth++;
|
|
1572
|
+
canStartRegex = true;
|
|
1573
|
+
continue;
|
|
1574
|
+
}
|
|
1575
|
+
if (char === ")" || char === "]" || char === "}") {
|
|
1576
|
+
depth = Math.max(0, depth - 1);
|
|
1577
|
+
canStartRegex = false;
|
|
1578
|
+
continue;
|
|
1579
|
+
}
|
|
1580
|
+
if (depth === 0 && char === ",") return true;
|
|
1581
|
+
if (depth === 0 && char === ";") return false;
|
|
1582
|
+
if (!/\s/.test(char)) canStartRegex = char !== ".";
|
|
1583
|
+
}
|
|
1584
|
+
return false;
|
|
1585
|
+
}
|
|
1586
|
+
function hasUnsupportedBindingPattern(source, start) {
|
|
1587
|
+
const opening = source[start];
|
|
1588
|
+
if (opening !== "{" && opening !== "[") return false;
|
|
1589
|
+
let depth = 0;
|
|
1590
|
+
for (let index = start; index < source.length; index++) {
|
|
1591
|
+
const char = source[index];
|
|
1592
|
+
if (char === "\"" || char === "'" || char === "`") return true;
|
|
1593
|
+
if (char === "(" || char === "/" || char === ":" && opening === "[") return true;
|
|
1594
|
+
if (char === "{" || char === "[") {
|
|
1595
|
+
depth++;
|
|
1596
|
+
if (depth > 1) return true;
|
|
1597
|
+
continue;
|
|
1598
|
+
}
|
|
1599
|
+
if (char === "}" || char === "]") {
|
|
1600
|
+
depth--;
|
|
1601
|
+
if (depth === 0) {
|
|
1602
|
+
let next = index + 1;
|
|
1603
|
+
while (/\s/.test(source[next] || "")) next++;
|
|
1604
|
+
return source[next] !== "=";
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
return true;
|
|
1609
|
+
}
|
|
1610
|
+
function getNamedExportsViaRegex(source, filePath, visited, scanState = { complete: true }) {
|
|
1074
1611
|
const names = /* @__PURE__ */ new Set();
|
|
1612
|
+
const codePositions = createCodePositionMap(source);
|
|
1613
|
+
const recognizedExportStarts = /* @__PURE__ */ new Set();
|
|
1075
1614
|
visited = visited || /* @__PURE__ */ new Set();
|
|
1076
1615
|
if (filePath) visited.add(filePath);
|
|
1077
|
-
const declRegex = new RegExp(`export\\s+(?:async\\s+)?(?:function(?:\\*\\s*|\\s+\\*?\\s*)|const\\s+|let\\s+|var\\s+|class\\s+|enum\\s+|namespace\\s+)(${JS_IDENTIFIER_PATTERN})`, "gu");
|
|
1616
|
+
const declRegex = new RegExp(`export\\s+(?:async\\s+)?(?:function(?:\\*\\s*|\\s+\\*?\\s*)|const\\s+enum\\s+|const\\s+|let\\s+|var\\s+|class\\s+|abstract\\s+class\\s+|enum\\s+|namespace\\s+|module\\s+)(${JS_IDENTIFIER_PATTERN})`, "gu");
|
|
1078
1617
|
let match;
|
|
1079
1618
|
while ((match = declRegex.exec(source)) !== null) {
|
|
1619
|
+
if (!codePositions[match.index]) continue;
|
|
1620
|
+
recognizedExportStarts.add(match.index);
|
|
1080
1621
|
const name = match[1];
|
|
1081
1622
|
if (isValidEsmExportName(name)) names.add(name);
|
|
1082
1623
|
}
|
|
1624
|
+
const exportedVariableDeclarationRegex = /export\s+(?:const|let|var)\s+/g;
|
|
1625
|
+
while ((match = exportedVariableDeclarationRegex.exec(source)) !== null) {
|
|
1626
|
+
if (!codePositions[match.index]) continue;
|
|
1627
|
+
if (hasTopLevelDeclaratorComma(source, exportedVariableDeclarationRegex.lastIndex)) scanState.complete = false;
|
|
1628
|
+
if (hasUnsupportedBindingPattern(source, exportedVariableDeclarationRegex.lastIndex)) scanState.complete = false;
|
|
1629
|
+
}
|
|
1630
|
+
if (hasCodeMatch(source, /export\s+import\s+/g, codePositions) || hasCodeMatch(source, /export\s*=/g, codePositions)) scanState.complete = false;
|
|
1631
|
+
if (hasCodeMatch(source, /export\s+@/g, codePositions)) scanState.complete = false;
|
|
1083
1632
|
const destructureRegex = /export\s+(?:const|let|var)\s+(\{[^}]*\}|\[[^\]]*\])\s*=/g;
|
|
1084
1633
|
const bindingNameRegex = new RegExp(`^(${JS_IDENTIFIER_PATTERN})`, "u");
|
|
1085
1634
|
while ((match = destructureRegex.exec(source)) !== null) {
|
|
1635
|
+
if (!codePositions[match.index]) continue;
|
|
1636
|
+
recognizedExportStarts.add(match.index);
|
|
1086
1637
|
const inner = match[1].slice(1, -1);
|
|
1087
1638
|
for (const part of inner.split(",")) {
|
|
1088
1639
|
let token = part.split("=")[0].trim();
|
|
@@ -1097,45 +1648,109 @@ function getNamedExportsViaRegex(source, filePath, visited) {
|
|
|
1097
1648
|
const typeOnlySpecifierRegex = new RegExp(`^type\\s+${JS_IDENTIFIER_PATTERN}(?:\\s+as\\s+${JS_IDENTIFIER_PATTERN})?$`, "u");
|
|
1098
1649
|
const exportSpecifierRegex = new RegExp(`(?:\\S+\\s+as\\s+)?(${JS_IDENTIFIER_PATTERN})$`, "u");
|
|
1099
1650
|
while ((match = listRegex.exec(source)) !== null) {
|
|
1651
|
+
if (!codePositions[match.index]) continue;
|
|
1652
|
+
recognizedExportStarts.add(match.index);
|
|
1100
1653
|
const specifiers = match[1].split(",");
|
|
1101
1654
|
for (const specifier of specifiers) {
|
|
1102
1655
|
const trimmed = specifier.trim();
|
|
1103
1656
|
if (typeOnlySpecifierRegex.test(trimmed)) continue;
|
|
1104
1657
|
const asMatch = trimmed.match(exportSpecifierRegex);
|
|
1105
|
-
if (!asMatch)
|
|
1658
|
+
if (!asMatch) {
|
|
1659
|
+
scanState.complete = false;
|
|
1660
|
+
continue;
|
|
1661
|
+
}
|
|
1106
1662
|
const name = asMatch[1];
|
|
1107
1663
|
if (isValidEsmExportName(name)) names.add(name);
|
|
1664
|
+
else scanState.complete = false;
|
|
1108
1665
|
}
|
|
1109
1666
|
}
|
|
1110
1667
|
const namespaceReExportRegex = new RegExp(`export\\s+\\*\\s+as\\s+(${JS_IDENTIFIER_PATTERN})\\s+from\\s+['"][^'"]+['"]`, "gu");
|
|
1111
|
-
while ((match = namespaceReExportRegex.exec(source)) !== null)
|
|
1668
|
+
while ((match = namespaceReExportRegex.exec(source)) !== null) {
|
|
1669
|
+
if (!codePositions[match.index]) continue;
|
|
1670
|
+
recognizedExportStarts.add(match.index);
|
|
1671
|
+
if (isValidEsmExportName(match[1])) names.add(match[1]);
|
|
1672
|
+
}
|
|
1673
|
+
if (hasCodeMatch(source, /export\s+\*\s+as\s+['"]/g, codePositions)) scanState.complete = false;
|
|
1112
1674
|
if (filePath) {
|
|
1113
1675
|
const starExportRegex = /export\s+\*\s+from\s+['"]([^'"]+)['"]/g;
|
|
1114
1676
|
while ((match = starExportRegex.exec(source)) !== null) {
|
|
1677
|
+
if (!codePositions[match.index]) continue;
|
|
1678
|
+
recognizedExportStarts.add(match.index);
|
|
1115
1679
|
const specifier = match[1];
|
|
1116
1680
|
const resolvedPath = resolveReExportModule(filePath, specifier);
|
|
1117
|
-
if (!resolvedPath
|
|
1681
|
+
if (!resolvedPath) {
|
|
1682
|
+
scanState.complete = false;
|
|
1683
|
+
continue;
|
|
1684
|
+
}
|
|
1685
|
+
if (visited.has(resolvedPath)) continue;
|
|
1686
|
+
if (path$1.extname(resolvedPath) === ".cjs") {
|
|
1687
|
+
scanState.complete = false;
|
|
1688
|
+
continue;
|
|
1689
|
+
}
|
|
1118
1690
|
try {
|
|
1119
|
-
const
|
|
1691
|
+
const reExportSource = readFileSync(resolvedPath, "utf-8");
|
|
1692
|
+
if (hasCommonJsExports(reExportSource)) {
|
|
1693
|
+
scanState.complete = false;
|
|
1694
|
+
continue;
|
|
1695
|
+
}
|
|
1696
|
+
const reExportNames = getNamedExportsViaRegex(reExportSource, resolvedPath, visited, scanState);
|
|
1120
1697
|
for (const name of reExportNames) names.add(name);
|
|
1121
|
-
} catch {
|
|
1698
|
+
} catch {
|
|
1699
|
+
scanState.complete = false;
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1703
|
+
const noNamedExportRegex = /export(?:\s+default\b|\s*\{\s*\}|\s+(?:type|interface|declare)\b)/g;
|
|
1704
|
+
while ((match = noNamedExportRegex.exec(source)) !== null) {
|
|
1705
|
+
if (!codePositions[match.index]) continue;
|
|
1706
|
+
recognizedExportStarts.add(match.index);
|
|
1707
|
+
}
|
|
1708
|
+
const exportKeywordRegex = /\bexport\b/g;
|
|
1709
|
+
while ((match = exportKeywordRegex.exec(source)) !== null) {
|
|
1710
|
+
if (!codePositions[match.index]) continue;
|
|
1711
|
+
if (!recognizedExportStarts.has(match.index)) {
|
|
1712
|
+
scanState.complete = false;
|
|
1713
|
+
break;
|
|
1122
1714
|
}
|
|
1123
1715
|
}
|
|
1124
1716
|
return Array.from(names);
|
|
1125
1717
|
}
|
|
1126
|
-
function
|
|
1718
|
+
function getRequiredNamedExports(specifier) {
|
|
1127
1719
|
try {
|
|
1128
|
-
const mod = createRequire$1(pathToFileURL(path$1.join(getPackageDetectionCwd(), "package.json")))(
|
|
1129
|
-
|
|
1720
|
+
const mod = createRequire$1(pathToFileURL(path$1.join(getPackageDetectionCwd(), "package.json")))(specifier);
|
|
1721
|
+
const runtimeNamedKeys = Object.keys(mod).filter((key) => key !== "default" && key !== "__esModule");
|
|
1722
|
+
if (runtimeNamedKeys.some((key) => !isValidEsmExportName(key))) return void 0;
|
|
1723
|
+
return runtimeNamedKeys;
|
|
1130
1724
|
} catch {
|
|
1131
|
-
return
|
|
1725
|
+
return;
|
|
1132
1726
|
}
|
|
1133
1727
|
}
|
|
1728
|
+
function getPackageNamedExports(pkg) {
|
|
1729
|
+
const esmEntryPath = getInstalledPackageEntry(pkg, {
|
|
1730
|
+
conditions: [
|
|
1731
|
+
"browser",
|
|
1732
|
+
"import",
|
|
1733
|
+
"module",
|
|
1734
|
+
"default"
|
|
1735
|
+
],
|
|
1736
|
+
resolveSubpathWithRequire: false
|
|
1737
|
+
});
|
|
1738
|
+
if (esmEntryPath) {
|
|
1739
|
+
const inspection = inspectSharedExportsFromFile(esmEntryPath);
|
|
1740
|
+
if (!inspection || inspection.commonJs || path$1.extname(esmEntryPath) === ".cjs") return getRequiredNamedExports(esmEntryPath);
|
|
1741
|
+
if (inspection.namedExports !== void 0) return inspection.namedExports;
|
|
1742
|
+
return;
|
|
1743
|
+
}
|
|
1744
|
+
return getRequiredNamedExports(pkg);
|
|
1745
|
+
}
|
|
1134
1746
|
function getSharedNamedExports(pkg, shareItem) {
|
|
1135
1747
|
const configuredImport = shareItem?.shareConfig.import;
|
|
1136
1748
|
if (typeof configuredImport === "string") {
|
|
1137
|
-
const
|
|
1138
|
-
|
|
1749
|
+
const configuredImportPath = resolveConfiguredImportPath(configuredImport);
|
|
1750
|
+
const inspection = inspectSharedExportsFromFile(configuredImportPath);
|
|
1751
|
+
if (configuredImportPath && (inspection?.commonJs || path$1.extname(configuredImportPath) === ".cjs")) return getRequiredNamedExports(configuredImportPath);
|
|
1752
|
+
if (inspection?.namedExports !== void 0) return inspection.namedExports;
|
|
1753
|
+
return;
|
|
1139
1754
|
}
|
|
1140
1755
|
return getPackageNamedExports(pkg);
|
|
1141
1756
|
}
|
|
@@ -1173,7 +1788,7 @@ function isWorkspaceFilePath(resolved) {
|
|
|
1173
1788
|
try {
|
|
1174
1789
|
realResolved = realpathSync.native(resolved);
|
|
1175
1790
|
} catch {}
|
|
1176
|
-
return !realResolved.includes("/node_modules/")
|
|
1791
|
+
return !normalizeNodeModulePath(realResolved).includes("/node_modules/");
|
|
1177
1792
|
}
|
|
1178
1793
|
/**
|
|
1179
1794
|
* When createRequire resolves a workspace package to a CJS entry (e.g. dist/index.cjs),
|
|
@@ -1285,10 +1900,104 @@ function getConcreteSharedImportSource(pkg, shareItem) {
|
|
|
1285
1900
|
const preBuildCacheMap = {};
|
|
1286
1901
|
const preBuildShareItemMap = {};
|
|
1287
1902
|
const PREBUILD_TAG = "__prebuild__";
|
|
1903
|
+
const treeShakingProviderCacheMap = {};
|
|
1904
|
+
const materializedTreeShakingProviders = /* @__PURE__ */ new Set();
|
|
1905
|
+
const TREE_SHAKING_PROVIDER_TAG = "__treeShakingProvider__";
|
|
1906
|
+
const TREE_SHAKING_GRAPH_QUERY = "__mf_tree_shaking_graph__";
|
|
1907
|
+
function getTreeShakingGraphToken(id) {
|
|
1908
|
+
if (!id) return void 0;
|
|
1909
|
+
const queryStart = id.indexOf("?");
|
|
1910
|
+
if (queryStart === -1) return void 0;
|
|
1911
|
+
const hashStart = id.indexOf("#", queryStart);
|
|
1912
|
+
const entry = id.slice(queryStart + 1, hashStart === -1 ? void 0 : hashStart).split("&").find((part) => part.split("=", 1)[0] === TREE_SHAKING_GRAPH_QUERY);
|
|
1913
|
+
if (!entry) return void 0;
|
|
1914
|
+
const value = entry.slice(26);
|
|
1915
|
+
try {
|
|
1916
|
+
return decodeURIComponent(value);
|
|
1917
|
+
} catch {
|
|
1918
|
+
return value;
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
function stripTreeShakingGraphQuery(id) {
|
|
1922
|
+
const queryStart = id.indexOf("?");
|
|
1923
|
+
if (queryStart === -1) return id;
|
|
1924
|
+
const hashStart = id.indexOf("#", queryStart);
|
|
1925
|
+
const pathname = id.slice(0, queryStart);
|
|
1926
|
+
const hash = hashStart === -1 ? "" : id.slice(hashStart);
|
|
1927
|
+
const remaining = id.slice(queryStart + 1, hashStart === -1 ? void 0 : hashStart).split("&").filter(Boolean).filter((part) => part.split("=", 1)[0] !== TREE_SHAKING_GRAPH_QUERY);
|
|
1928
|
+
return `${pathname}${remaining.length ? `?${remaining.join("&")}` : ""}${hash}`;
|
|
1929
|
+
}
|
|
1930
|
+
function addTreeShakingGraphQuery(id, token) {
|
|
1931
|
+
const cleanId = stripTreeShakingGraphQuery(id);
|
|
1932
|
+
const hashStart = cleanId.indexOf("#");
|
|
1933
|
+
const base = hashStart === -1 ? cleanId : cleanId.slice(0, hashStart);
|
|
1934
|
+
const hash = hashStart === -1 ? "" : cleanId.slice(hashStart);
|
|
1935
|
+
return `${base}${base.includes("?") ? "&" : "?"}${TREE_SHAKING_GRAPH_QUERY}=${encodeURIComponent(token)}${hash}`;
|
|
1936
|
+
}
|
|
1937
|
+
function getConcreteTreeShakingExportUsage(pkg, shareItem) {
|
|
1938
|
+
return getTreeShakingExportUsage(pkg, shareItem, shareItem?.name);
|
|
1939
|
+
}
|
|
1940
|
+
function getTreeShakingSharedProviderName(pkg) {
|
|
1941
|
+
const { internalName, name } = getNormalizeModuleFederationOptions();
|
|
1942
|
+
return `${internalName || name}__tree_shaking__${packageNameEncode(pkg)}`;
|
|
1943
|
+
}
|
|
1944
|
+
function getTreeShakingSharedProviderImportId(pkg) {
|
|
1945
|
+
if (!treeShakingProviderCacheMap[pkg]) treeShakingProviderCacheMap[pkg] = new VirtualModule(pkg, TREE_SHAKING_PROVIDER_TAG, ".js");
|
|
1946
|
+
return treeShakingProviderCacheMap[pkg].getImportId();
|
|
1947
|
+
}
|
|
1948
|
+
function hasTreeShakingSharedProvider(pkg, shareItem) {
|
|
1949
|
+
const usage = getConcreteTreeShakingExportUsage(pkg, shareItem);
|
|
1950
|
+
return materializedTreeShakingProviders.has(pkg) && usage?.kind === "exports";
|
|
1951
|
+
}
|
|
1952
|
+
/**
|
|
1953
|
+
* Materialize the locally optimized provider as a small ESM container.
|
|
1954
|
+
*
|
|
1955
|
+
* The normal prebuild module remains the complete fallback. This container only
|
|
1956
|
+
* retains the selected exports and is installed as `treeShaking.get` by the
|
|
1957
|
+
* generated runtime record. Keeping the two getters distinct lets the Runtime
|
|
1958
|
+
* perform its normal usedExports compatibility check and safely choose the full
|
|
1959
|
+
* provider when the optimized one is insufficient.
|
|
1960
|
+
*/
|
|
1961
|
+
function writeTreeShakingSharedProvider(pkg, shareItem) {
|
|
1962
|
+
const usage = getConcreteTreeShakingExportUsage(pkg, shareItem);
|
|
1963
|
+
if (usage?.kind !== "exports" || !usage.usedExports.length || shareItem?.shareConfig.import === false) {
|
|
1964
|
+
materializedTreeShakingProviders.delete(pkg);
|
|
1965
|
+
return;
|
|
1966
|
+
}
|
|
1967
|
+
const usedExports = usage.usedExports;
|
|
1968
|
+
const unsupportedExport = usedExports.find((name) => name !== "default" && !isValidEsmExportName(name));
|
|
1969
|
+
if (unsupportedExport) {
|
|
1970
|
+
materializedTreeShakingProviders.delete(pkg);
|
|
1971
|
+
mfWarn(`Tree-shaking shared dependency "${pkg}" was disabled because export "${unsupportedExport}" cannot be represented by the generated ESM provider.`);
|
|
1972
|
+
return;
|
|
1973
|
+
}
|
|
1974
|
+
const provider = treeShakingProviderCacheMap[pkg] || (treeShakingProviderCacheMap[pkg] = new VirtualModule(pkg, "__treeShakingProvider__", ".js"));
|
|
1975
|
+
const optimizedImportSource = addTreeShakingGraphQuery(getConcreteSharedImportSource(pkg, shareItem) || pkg, pkg);
|
|
1976
|
+
const namedExports = usedExports.filter((name) => name !== "default");
|
|
1977
|
+
const namedImports = namedExports.map((name, index) => `${name} as __mfTreeShaken_${index}`).join(", ");
|
|
1978
|
+
const importLines = [namedImports ? `import { ${namedImports} } from ${escapeGeneratedStringLiteral(optimizedImportSource)};` : "", usedExports.includes("default") ? `import __mfTreeShakenDefault from ${escapeGeneratedStringLiteral(optimizedImportSource)};` : ""].filter(Boolean).join("\n");
|
|
1979
|
+
const namespaceEntries = [...namedExports.map((name, index) => `[${JSON.stringify(name)}]: __mfTreeShaken_${index}`), ...usedExports.includes("default") ? ["default: __mfTreeShakenDefault"] : [`default: { ${namedExports.map((name, index) => `[${JSON.stringify(name)}]: __mfTreeShaken_${index}`).join(", ")} }`]];
|
|
1980
|
+
provider.writeSync(`${importLines}
|
|
1981
|
+
const __mfTreeShakenModule = { ${namespaceEntries.join(", ")} };
|
|
1982
|
+
Object.defineProperty(__mfTreeShakenModule, "__esModule", {
|
|
1983
|
+
value: true,
|
|
1984
|
+
enumerable: false,
|
|
1985
|
+
});
|
|
1986
|
+
async function init() {}
|
|
1987
|
+
function get() {
|
|
1988
|
+
return () => __mfTreeShakenModule;
|
|
1989
|
+
}
|
|
1990
|
+
const usedExports = ${JSON.stringify([...usedExports].sort())};
|
|
1991
|
+
export { get, init, usedExports };
|
|
1992
|
+
export default { get, init };
|
|
1993
|
+
`, true);
|
|
1994
|
+
materializedTreeShakingProviders.add(pkg);
|
|
1995
|
+
}
|
|
1288
1996
|
function writePreBuildLibPath(pkg, shareItem) {
|
|
1289
1997
|
if (!preBuildCacheMap[pkg]) preBuildCacheMap[pkg] = new VirtualModule(pkg, PREBUILD_TAG, ".js");
|
|
1290
1998
|
preBuildShareItemMap[pkg] = shareItem;
|
|
1291
1999
|
const importSource = getConcreteSharedImportSource(pkg, shareItem) || pkg;
|
|
2000
|
+
writeTreeShakingSharedProvider(pkg, shareItem);
|
|
1292
2001
|
if (pkg === "react/compiler-runtime") {
|
|
1293
2002
|
const reactCacheDescriptor = getSharedCacheDescriptorLiteral("react", shareItem ?? {
|
|
1294
2003
|
name: "react",
|
|
@@ -1333,7 +2042,7 @@ function writePreBuildLibPath(pkg, shareItem) {
|
|
|
1333
2042
|
`, true);
|
|
1334
2043
|
return;
|
|
1335
2044
|
}
|
|
1336
|
-
const namedExports = getSharedNamedExports(pkg, shareItem);
|
|
2045
|
+
const namedExports = getSharedNamedExports(pkg, shareItem) ?? [];
|
|
1337
2046
|
if (namedExports.length > 0) {
|
|
1338
2047
|
const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
|
|
1339
2048
|
const declarations = namedExports.map((name, i) => `const ${namedExportVars[i]} = __mfPrebuildExports[${escapeGeneratedStringLiteral(name)}];`).join("\n ");
|
|
@@ -1343,16 +2052,27 @@ function writePreBuildLibPath(pkg, shareItem) {
|
|
|
1343
2052
|
const __mfPrebuildExports = __mfPrebuildNamespace;
|
|
1344
2053
|
${declarations}
|
|
1345
2054
|
${namedExportLine}
|
|
1346
|
-
export default __mfPrebuildNamespace
|
|
2055
|
+
export default Reflect.get(__mfPrebuildNamespace, "default") ?? __mfPrebuildNamespace;
|
|
1347
2056
|
`, true);
|
|
1348
2057
|
return;
|
|
1349
2058
|
}
|
|
1350
2059
|
preBuildCacheMap[pkg].writeSync(`
|
|
1351
2060
|
import * as __mfPrebuildExports from ${escapeGeneratedStringLiteral(importSource)};
|
|
1352
2061
|
export * from ${escapeGeneratedStringLiteral(importSource)};
|
|
1353
|
-
|
|
2062
|
+
// Reflect access avoids bundler warnings for ESM packages without a
|
|
2063
|
+
// default export (for example antd/es/index.js), while preserving the
|
|
2064
|
+
// namespace fallback for packages that do provide one.
|
|
2065
|
+
export default Reflect.get(__mfPrebuildExports, "default") ?? __mfPrebuildExports;
|
|
1354
2066
|
`, true);
|
|
1355
2067
|
}
|
|
2068
|
+
/** Re-render already materialized wrappers after import analysis discovers exports. */
|
|
2069
|
+
function refreshTreeShakingModules() {
|
|
2070
|
+
for (const [pkg, shareItem] of Object.entries(preBuildShareItemMap)) {
|
|
2071
|
+
if (!shareItem?.shareConfig.treeShaking) continue;
|
|
2072
|
+
writePreBuildLibPath(pkg, shareItem);
|
|
2073
|
+
writeLoadShareModule(pkg, shareItem, "build", false);
|
|
2074
|
+
}
|
|
2075
|
+
}
|
|
1356
2076
|
function getPreBuildLibImportId(pkg) {
|
|
1357
2077
|
if (!preBuildCacheMap[pkg]) preBuildCacheMap[pkg] = new VirtualModule(pkg, PREBUILD_TAG, ".js");
|
|
1358
2078
|
return preBuildCacheMap[pkg].getImportId();
|
|
@@ -1398,49 +2118,58 @@ function materializeCachedLoadShareModule(options) {
|
|
|
1398
2118
|
options.addUsedShares(pkg);
|
|
1399
2119
|
options.writeLocalSharedImportMap();
|
|
1400
2120
|
}
|
|
1401
|
-
function
|
|
2121
|
+
function getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer) {
|
|
2122
|
+
return treeShakingConsumer ? `__mfReadTreeShakingSharedSelection(__mfModuleCache.share, ${cacheDescriptor}, ${JSON.stringify(treeShakingConsumer)})` : `__mfReadSharedCache(__mfModuleCache.share, ${cacheDescriptor})`;
|
|
2123
|
+
}
|
|
2124
|
+
function generateEagerWorkspaceSingletonExports(namedExports, importSource, cacheDescriptor, cacheOwner, treeShakingConsumer) {
|
|
1402
2125
|
const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
|
|
1403
|
-
const
|
|
2126
|
+
const declarations = namedExports.length > 0 ? ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ") : "let __mf_default;";
|
|
2127
|
+
const assignments = [...namedExports.map((name, i) => `${namedExportVars[i]} = mod[${escapeGeneratedStringLiteral(name)}];`), "__mf_default = mod.default ?? mod;"].join("\n ");
|
|
1404
2128
|
const namedExportLine = namedExports.length > 0 ? `\n export { ${namedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
|
|
1405
2129
|
return `import * as __mfLocalShare from ${escapeGeneratedStringLiteral(importSource)};
|
|
1406
|
-
let exportModule =
|
|
2130
|
+
let exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)};
|
|
1407
2131
|
if (exportModule === undefined) {
|
|
1408
2132
|
Promise.resolve().then(() => {
|
|
1409
2133
|
if (__mfReadSharedCache(__mfModuleCache.share, ${cacheDescriptor}) === undefined) {
|
|
1410
|
-
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, __mfNormalizeShareModule(__mfLocalShare));
|
|
2134
|
+
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, __mfNormalizeShareModule(__mfLocalShare), ${cacheOwner});
|
|
1411
2135
|
}
|
|
1412
2136
|
});
|
|
1413
2137
|
exportModule = __mfLocalShare;
|
|
1414
2138
|
}
|
|
1415
|
-
|
|
2139
|
+
${declarations}
|
|
2140
|
+
const __mfApplyEagerShareExports = (mod) => {
|
|
2141
|
+
${assignments}
|
|
2142
|
+
};
|
|
2143
|
+
__mfSubscribeSharedCache(__mfModuleCache.share, ${cacheDescriptor}, __mfApplyEagerShareExports);
|
|
2144
|
+
__mfApplyEagerShareExports(exportModule);
|
|
1416
2145
|
export { __mf_default as default };${namedExportLine}`;
|
|
1417
2146
|
}
|
|
1418
|
-
function generateLazyWorkspaceSingletonExports(namedExports, importSource, cacheDescriptor) {
|
|
2147
|
+
function generateLazyWorkspaceSingletonExports(namedExports, importSource, cacheDescriptor, cacheOwner, treeShakingConsumer) {
|
|
1419
2148
|
const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
|
|
1420
2149
|
const declarations = namedExports.length > 0 ? ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ") : "let __mf_default;";
|
|
1421
2150
|
const assignments = namedExports.length > 0 ? [...namedExports.map((name, i) => `${namedExportVars[i]} = mod[${escapeGeneratedStringLiteral(name)}];`), "__mf_default = mod.default ?? mod;"].join("\n ") : "__mf_default = mod.default ?? mod;";
|
|
1422
2151
|
const namedExportLine = namedExports.length > 0 ? `\n export { ${namedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
|
|
2152
|
+
const applyLocalFallback = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
2153
|
+
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});`;
|
|
1423
2154
|
return `${declarations}
|
|
1424
2155
|
const __mfApplyLazyShareExports = (mod) => {
|
|
1425
2156
|
${assignments}
|
|
1426
2157
|
};
|
|
1427
|
-
|
|
2158
|
+
__mfSubscribeSharedCache(__mfModuleCache.share, ${cacheDescriptor}, __mfApplyLazyShareExports);
|
|
2159
|
+
let exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)};
|
|
1428
2160
|
if (exportModule === undefined) {
|
|
1429
2161
|
if (import.meta.env.SSR) {
|
|
1430
|
-
${
|
|
1431
|
-
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule);
|
|
1432
|
-
__mfApplyLazyShareExports(exportModule);`}
|
|
2162
|
+
${applyLocalFallback}
|
|
1433
2163
|
} else {
|
|
1434
2164
|
(__mfModuleCache.pendingShareLoads ||= []).push(initPromise.then(() => {
|
|
1435
|
-
exportModule =
|
|
2165
|
+
exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)};
|
|
1436
2166
|
if (exportModule !== undefined) {
|
|
1437
2167
|
__mfApplyLazyShareExports(exportModule);
|
|
1438
2168
|
return;
|
|
1439
2169
|
}
|
|
1440
2170
|
return import(${escapeGeneratedStringLiteral(importSource)}).then((mod) => {
|
|
1441
2171
|
exportModule = __mfNormalizeShareModule(mod);
|
|
1442
|
-
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule);
|
|
1443
|
-
__mfApplyLazyShareExports(exportModule);
|
|
2172
|
+
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});
|
|
1444
2173
|
});
|
|
1445
2174
|
}));
|
|
1446
2175
|
}
|
|
@@ -1459,16 +2188,19 @@ function prependWorkspaceSingletonSsrImport(code) {
|
|
|
1459
2188
|
const quote = importMatch[1];
|
|
1460
2189
|
return `import * as __mfLocalShare from ${quote}${importMatch[2]}${quote};\n${code}`;
|
|
1461
2190
|
}
|
|
1462
|
-
function generateDeferredHostProvidedExports(namedExports, pkg, cacheDescriptor) {
|
|
2191
|
+
function generateDeferredHostProvidedExports(namedExports, pkg, cacheDescriptor, treeShakingConsumer) {
|
|
1463
2192
|
const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
|
|
1464
|
-
|
|
2193
|
+
const declarations = ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ");
|
|
2194
|
+
const assignments = [...namedExports.map((name, i) => `${namedExportVars[i]} = exportModule[${escapeGeneratedStringLiteral(name)}];`), "__mf_default = exportModule.default ?? exportModule;"].join("\n ");
|
|
2195
|
+
const namedExportLine = namedExports.length > 0 ? `\n export { ${namedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
|
|
2196
|
+
return `${declarations}
|
|
1465
2197
|
const __mfApplyHostProvidedExports = (exportModule) => {
|
|
1466
|
-
${
|
|
2198
|
+
${assignments}
|
|
1467
2199
|
};
|
|
1468
|
-
let exportModule =
|
|
2200
|
+
let exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)};
|
|
1469
2201
|
if (exportModule === undefined) {
|
|
1470
2202
|
(__mfModuleCache.pendingShareLoads ||= []).push(initPromise.then(() => {
|
|
1471
|
-
exportModule =
|
|
2203
|
+
exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)};
|
|
1472
2204
|
if (exportModule === undefined) {
|
|
1473
2205
|
throw new Error("[Module Federation] Shared module ${pkg} was imported before federation bootstrap finished.");
|
|
1474
2206
|
}
|
|
@@ -1477,7 +2209,7 @@ function generateDeferredHostProvidedExports(namedExports, pkg, cacheDescriptor)
|
|
|
1477
2209
|
} else {
|
|
1478
2210
|
__mfApplyHostProvidedExports(exportModule);
|
|
1479
2211
|
}
|
|
1480
|
-
export { __mf_default as default };${
|
|
2212
|
+
export { __mf_default as default };${namedExportLine}`;
|
|
1481
2213
|
}
|
|
1482
2214
|
function generateShareModuleUnwrapCode({ source, preserveNamedExports, stopWithReturn }) {
|
|
1483
2215
|
return `let current = ${source};
|
|
@@ -1500,13 +2232,16 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
|
|
|
1500
2232
|
if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = new VirtualModule(pkg, LOAD_SHARE_TAG, ".js");
|
|
1501
2233
|
let importLine = getRuntimeModuleCacheBootstrapCode();
|
|
1502
2234
|
const cacheDescriptor = getSharedCacheDescriptorLiteral(pkg, shareItem);
|
|
2235
|
+
const cacheOwner = JSON.stringify(getNormalizeModuleFederationOptions().name);
|
|
2236
|
+
const treeShakingConsumer = command === "build" && shareItem.shareConfig.treeShaking ? getNormalizeModuleFederationOptions().name : void 0;
|
|
1503
2237
|
if (shareItem.shareConfig.import === false) {
|
|
1504
|
-
const
|
|
2238
|
+
const detectedNamedExports = getPackageNamedExports(pkg);
|
|
2239
|
+
const namedExports = detectedNamedExports ?? [];
|
|
1505
2240
|
let exportLine;
|
|
1506
|
-
if (namedExports.length > 0) exportLine = generateDeferredHostProvidedExports(namedExports, pkg, cacheDescriptor);
|
|
2241
|
+
if (namedExports.length > 0) exportLine = generateDeferredHostProvidedExports(namedExports, pkg, cacheDescriptor, treeShakingConsumer);
|
|
1507
2242
|
else {
|
|
1508
|
-
mfWarn(`Shared dependency "${pkg}" has import: false but is not installed locally.\n Named imports (e.g. import { ... } from '${pkg}') will not work in production builds.\n Install it as a devDependency to enable named export detection.`);
|
|
1509
|
-
exportLine = generateDeferredHostProvidedExports([], pkg, cacheDescriptor);
|
|
2243
|
+
if (detectedNamedExports === void 0) mfWarn(`Shared dependency "${pkg}" has import: false but is not installed locally.\n Named imports (e.g. import { ... } from '${pkg}') will not work in production builds.\n Install it as a devDependency to enable named export detection.`);
|
|
2244
|
+
exportLine = generateDeferredHostProvidedExports([], pkg, cacheDescriptor, treeShakingConsumer);
|
|
1510
2245
|
}
|
|
1511
2246
|
loadShareCacheMap[pkg].writeSync(`
|
|
1512
2247
|
${getRuntimeInitPromiseBootstrapCode()}
|
|
@@ -1520,22 +2255,59 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
|
|
|
1520
2255
|
const sharedImportSource = concreteSharedImportSource || getPreBuildLibImportId(pkg);
|
|
1521
2256
|
const devImportSource = concreteSharedImportSource || pkg;
|
|
1522
2257
|
const localProviderPath = getLocalProviderImportPath(pkg);
|
|
2258
|
+
const coherentLocalSource = concreteSharedImportSource || localProviderPath || devImportSource;
|
|
1523
2259
|
const isWorkspacePackage = isWorkspacePackageEntry(pkg, localProviderPath) || isWorkspacePackageEntry(pkg, concreteSharedImportSource);
|
|
1524
2260
|
const lazyLocalFallbackSource = command !== "build" ? concreteSharedImportSource || localProviderPath || devImportSource : concreteSharedImportSource || localProviderPath || sharedImportSource;
|
|
1525
2261
|
const skipServePrebuildWarmup = command !== "build" && (pkg === "lit" || pkg.startsWith("lit/"));
|
|
2262
|
+
const detectedNamedExports = getSharedNamedExports(pkg, shareItem);
|
|
2263
|
+
const namedExports = detectedNamedExports ?? [];
|
|
2264
|
+
const hasCompleteExportCoverage = detectedNamedExports !== void 0;
|
|
1526
2265
|
const isWorkspaceSingleton = isWorkspacePackage && shareItem.shareConfig.singleton === true;
|
|
1527
2266
|
const isDefaultShareScope = shareItem.scope === void 0 || shareItem.scope === "default" || Array.isArray(shareItem.scope) && shareItem.scope[0] === "default";
|
|
1528
|
-
const usesDeferredSingletonFallback = isWorkspaceSingleton || command !== "build" && isRemoteOnlyContainer() && shareItem.shareConfig.singleton === true || command === "build" && isRemoteOnlyContainer() && shareItem.shareConfig.singleton === true && !isDefaultShareScope;
|
|
2267
|
+
const usesDeferredSingletonFallback = hasCompleteExportCoverage && (isWorkspaceSingleton || command !== "build" && isRemoteOnlyContainer() && shareItem.shareConfig.singleton === true || command === "build" && isRemoteOnlyContainer() && shareItem.shareConfig.singleton === true && !isDefaultShareScope);
|
|
1529
2268
|
const isConsumedByPeerSingleton = isSharedSingletonConsumedByPeer(pkg);
|
|
1530
|
-
const usesEntryInjectedRemoteFallback = command !== "build" && !isWorkspaceSingleton && isRemoteOnlyContainer() && shareItem.shareConfig.singleton === true && getNormalizeModuleFederationOptions().hostInitInjectLocation === "entry" && isConsumedByPeerSingleton;
|
|
1531
|
-
const usesEagerWorkspaceFallback = isWorkspaceSingleton && isConsumedByPeerSingleton;
|
|
1532
|
-
const
|
|
2269
|
+
const usesEntryInjectedRemoteFallback = hasCompleteExportCoverage && command !== "build" && !isWorkspaceSingleton && isRemoteOnlyContainer() && shareItem.shareConfig.singleton === true && getNormalizeModuleFederationOptions().hostInitInjectLocation === "entry" && isConsumedByPeerSingleton;
|
|
2270
|
+
const usesEagerWorkspaceFallback = hasCompleteExportCoverage && isWorkspaceSingleton && isConsumedByPeerSingleton;
|
|
2271
|
+
const usesDeferredTreeShakingFallback = hasCompleteExportCoverage && Boolean(treeShakingConsumer);
|
|
1533
2272
|
let exportLine;
|
|
1534
2273
|
let initBlock = "";
|
|
1535
|
-
if (
|
|
2274
|
+
if (usesDeferredTreeShakingFallback) {
|
|
2275
|
+
importLine = `${getRuntimeInitPromiseBootstrapCode()}\n ${importLine}`;
|
|
2276
|
+
exportLine = generateLazyWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer);
|
|
2277
|
+
} else if (usesEagerWorkspaceFallback || usesEntryInjectedRemoteFallback) exportLine = generateEagerWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer);
|
|
1536
2278
|
else if (usesDeferredSingletonFallback) {
|
|
1537
2279
|
importLine = `${getRuntimeInitPromiseBootstrapCode()}\n ${importLine}`;
|
|
1538
|
-
exportLine = generateLazyWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor);
|
|
2280
|
+
exportLine = generateLazyWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer);
|
|
2281
|
+
} else if (detectedNamedExports === void 0) {
|
|
2282
|
+
exportLine = `const __mfDefaultExport = (() => {
|
|
2283
|
+
${generateShareModuleUnwrapCode({
|
|
2284
|
+
source: "__mfLocalShare",
|
|
2285
|
+
preserveNamedExports: false,
|
|
2286
|
+
stopWithReturn: "defaultExport ?? current"
|
|
2287
|
+
})}
|
|
2288
|
+
})();
|
|
2289
|
+
export default __mfDefaultExport;
|
|
2290
|
+
export * from ${escapeGeneratedStringLiteral(coherentLocalSource)}`;
|
|
2291
|
+
initBlock = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
2292
|
+
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});`;
|
|
2293
|
+
} else if (namedExports.length > 0 && shareItem.shareConfig.singleton === true) {
|
|
2294
|
+
const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
|
|
2295
|
+
exportLine = `${["let __mfDefaultExport;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ")}
|
|
2296
|
+
const __mfApplySharedExports = (mod) => {
|
|
2297
|
+
${[...namedExports.map((name, i) => `${namedExportVars[i]} = mod[${escapeGeneratedStringLiteral(name)}];`), `__mfDefaultExport = (() => {
|
|
2298
|
+
${generateShareModuleUnwrapCode({
|
|
2299
|
+
source: "mod",
|
|
2300
|
+
preserveNamedExports: false,
|
|
2301
|
+
stopWithReturn: "defaultExport ?? current"
|
|
2302
|
+
})}
|
|
2303
|
+
})();`].join("\n ")}
|
|
2304
|
+
};
|
|
2305
|
+
__mfSubscribeSharedCache(__mfModuleCache.share, ${cacheDescriptor}, __mfApplySharedExports);
|
|
2306
|
+
__mfApplySharedExports(exportModule);
|
|
2307
|
+
export { __mfDefaultExport as default };
|
|
2308
|
+
${`export { ${namedExports.map((name, i) => `__mf_${i} as ${name}`).join(", ")} };`}`;
|
|
2309
|
+
initBlock = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
2310
|
+
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});`;
|
|
1539
2311
|
} else if (namedExports.length > 0) {
|
|
1540
2312
|
const destructure = `const { ${namedExports.map((name, i) => `${name}: __mf_${i}`).join(", ")} } = exportModule;`;
|
|
1541
2313
|
const namedExportLine = `export { ${namedExports.map((name, i) => `__mf_${i} as ${name}`).join(", ")} };`;
|
|
@@ -1550,15 +2322,26 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
|
|
|
1550
2322
|
${destructure}
|
|
1551
2323
|
${namedExportLine}`;
|
|
1552
2324
|
initBlock = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
1553
|
-
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule);`;
|
|
2325
|
+
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});`;
|
|
2326
|
+
} else if (shareItem.shareConfig.singleton === true) {
|
|
2327
|
+
exportLine = `let __mfDefaultExport;
|
|
2328
|
+
const __mfApplySharedDefaultExport = (mod) => {
|
|
2329
|
+
__mfDefaultExport = mod.default ?? mod;
|
|
2330
|
+
};
|
|
2331
|
+
__mfSubscribeSharedCache(__mfModuleCache.share, ${cacheDescriptor}, __mfApplySharedDefaultExport);
|
|
2332
|
+
__mfApplySharedDefaultExport(exportModule);
|
|
2333
|
+
export { __mfDefaultExport as default };
|
|
2334
|
+
export * from ${escapeGeneratedStringLiteral(sharedImportSource)}`;
|
|
2335
|
+
initBlock = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
2336
|
+
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});`;
|
|
1554
2337
|
} else {
|
|
1555
2338
|
exportLine = `export default exportModule.default ?? exportModule\n export * from ${escapeGeneratedStringLiteral(sharedImportSource)}`;
|
|
1556
2339
|
initBlock = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
1557
|
-
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule);`;
|
|
2340
|
+
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});`;
|
|
1558
2341
|
}
|
|
1559
|
-
const prebuildImportLine = usesDeferredSingletonFallback ||
|
|
1560
|
-
const devDynamicImportLine = isWorkspacePackage ? "" : usesDeferredSingletonFallback ? "" : command !== "build" && !skipServePrebuildWarmup ? `;() => import(${escapeGeneratedStringLiteral(devImportSource)}).catch(() => {});` : "";
|
|
1561
|
-
const moduleBody = usesDeferredSingletonFallback ? `
|
|
2342
|
+
const prebuildImportLine = usesDeferredSingletonFallback || usesDeferredTreeShakingFallback ? "" : `import * as __mfLocalShare from ${escapeGeneratedStringLiteral(detectedNamedExports === void 0 ? coherentLocalSource : skipServePrebuildWarmup ? devImportSource : sharedImportSource)};`;
|
|
2343
|
+
const devDynamicImportLine = isWorkspacePackage ? "" : usesDeferredSingletonFallback || usesDeferredTreeShakingFallback ? "" : command !== "build" && !skipServePrebuildWarmup ? `;() => import(${escapeGeneratedStringLiteral(devImportSource)}).catch(() => {});` : "";
|
|
2344
|
+
const moduleBody = usesDeferredSingletonFallback || usesDeferredTreeShakingFallback ? `
|
|
1562
2345
|
${prebuildImportLine}
|
|
1563
2346
|
${devDynamicImportLine}
|
|
1564
2347
|
${importLine}
|
|
@@ -1571,7 +2354,7 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
|
|
|
1571
2354
|
${importLine}
|
|
1572
2355
|
${sharedCacheHelperCode}
|
|
1573
2356
|
${normalizeLocalShareModuleCode}
|
|
1574
|
-
let exportModule =
|
|
2357
|
+
let exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)}
|
|
1575
2358
|
if (exportModule === undefined) {
|
|
1576
2359
|
${initBlock}
|
|
1577
2360
|
}
|
|
@@ -1618,14 +2401,21 @@ function getDirectSharedCacheSeedImportPath(pkg, shareItem) {
|
|
|
1618
2401
|
function generateLocalSharedImportMap() {
|
|
1619
2402
|
const useDirectReactImport = shouldUseDirectReactImport();
|
|
1620
2403
|
const options = getNormalizeModuleFederationOptions();
|
|
2404
|
+
const orderedShares = getOrderedUsedShares();
|
|
1621
2405
|
return `
|
|
1622
2406
|
import {loadShare} from "@module-federation/runtime";
|
|
2407
|
+
${orderedShares.map((pkg, index) => {
|
|
2408
|
+
const shareItem = getNormalizeShareItem(pkg);
|
|
2409
|
+
if (!shareItem?.shareConfig.eager || shareItem.shareConfig.import === false) return "";
|
|
2410
|
+
return `import * as __mfEagerShare_${index} from ${JSON.stringify(getLocalSharedPackagePath(pkg, shareItem))};`;
|
|
2411
|
+
}).filter(Boolean).join("\n")}
|
|
1623
2412
|
const importMap = {
|
|
1624
|
-
${
|
|
2413
|
+
${orderedShares.map((pkg, index) => {
|
|
1625
2414
|
const shareItem = getNormalizeShareItem(pkg);
|
|
1626
2415
|
return `
|
|
1627
2416
|
${JSON.stringify(pkg)}: async () => {
|
|
1628
|
-
${shareItem?.shareConfig.import === false ? `throw new Error(\`[Module Federation] Shared module '\${${JSON.stringify(pkg)}}' must be provided by host\`);` : `let pkg =
|
|
2417
|
+
${shareItem?.shareConfig.import === false ? `throw new Error(\`[Module Federation] Shared module '\${${JSON.stringify(pkg)}}' must be provided by host\`);` : shareItem?.shareConfig.eager ? `let pkg = __mfEagerShare_${index};
|
|
2418
|
+
return pkg;` : `let pkg = await import(${JSON.stringify(getLocalSharedPackagePath(pkg, shareItem))});
|
|
1629
2419
|
return pkg;`}
|
|
1630
2420
|
}
|
|
1631
2421
|
`;
|
|
@@ -1635,13 +2425,24 @@ function generateLocalSharedImportMap() {
|
|
|
1635
2425
|
${getOrderedUsedShares().map((key) => {
|
|
1636
2426
|
const shareItem = getNormalizeShareItem(key);
|
|
1637
2427
|
if (!shareItem) return null;
|
|
2428
|
+
const detectedNamedExports = getSharedNamedExports(key, shareItem);
|
|
2429
|
+
const canLiveRebind = shareItem.shareConfig.import === false || detectedNamedExports !== void 0;
|
|
2430
|
+
const treeShakingConfig = canLiveRebind ? shareItem.shareConfig.treeShaking : void 0;
|
|
2431
|
+
const treeShakingUsage = treeShakingConfig ? getTreeShakingExportUsage(key, shareItem, shareItem.name) : void 0;
|
|
2432
|
+
const treeShakingProviderExports = treeShakingUsage?.kind === "exports" ? treeShakingUsage.usedExports : [];
|
|
2433
|
+
const treeShakingUsedExports = options.injectTreeShakingUsedExports === false ? treeShakingConfig?.usedExports || [] : treeShakingProviderExports;
|
|
2434
|
+
const disableRuntimeInference = treeShakingConfig?.mode === "runtime-infer" && options.injectTreeShakingUsedExports === false;
|
|
2435
|
+
const treeShakingProviderImportId = treeShakingConfig && !disableRuntimeInference && hasTreeShakingSharedProvider(key, shareItem) ? getTreeShakingSharedProviderImportId(key) : void 0;
|
|
2436
|
+
const treeShakingStatus = treeShakingUsage?.kind === "full" || disableRuntimeInference || treeShakingConfig?.mode === "runtime-infer" && !treeShakingProviderImportId && shareItem.shareConfig.import !== false ? 0 : 1;
|
|
1638
2437
|
return `
|
|
1639
2438
|
${JSON.stringify(key)}: {
|
|
1640
2439
|
name: ${JSON.stringify(key)},
|
|
1641
2440
|
version: ${JSON.stringify(shareItem.version)},
|
|
1642
2441
|
scope: [${JSON.stringify(shareItem.scope)}],
|
|
1643
2442
|
loaded: false,
|
|
2443
|
+
eager: ${Boolean(shareItem.shareConfig.eager)},
|
|
1644
2444
|
from: ${JSON.stringify(options.name)},
|
|
2445
|
+
canLiveRebind: ${canLiveRebind},
|
|
1645
2446
|
async get () {
|
|
1646
2447
|
if (${shareItem.shareConfig.import === false}) {
|
|
1647
2448
|
throw new Error(\`[Module Federation] Shared module '\${${JSON.stringify(key)}}' must be provided by host\`);
|
|
@@ -1665,8 +2466,20 @@ function generateLocalSharedImportMap() {
|
|
|
1665
2466
|
singleton: ${shareItem.shareConfig.singleton},
|
|
1666
2467
|
requiredVersion: ${JSON.stringify(shareItem.shareConfig.requiredVersion)},
|
|
1667
2468
|
strictVersion: ${shareItem.shareConfig.strictVersion},
|
|
2469
|
+
eager: ${Boolean(shareItem.shareConfig.eager)},
|
|
1668
2470
|
${shareItem.shareConfig.import === false ? "import: false," : ""}
|
|
1669
|
-
}
|
|
2471
|
+
},
|
|
2472
|
+
${treeShakingConfig ? `treeShaking: {
|
|
2473
|
+
mode: ${JSON.stringify(treeShakingConfig.mode)},
|
|
2474
|
+
usedExports: ${JSON.stringify(treeShakingUsedExports)},
|
|
2475
|
+
providedExports: ${JSON.stringify(treeShakingProviderExports)},
|
|
2476
|
+
status: ${treeShakingStatus},
|
|
2477
|
+
${treeShakingProviderImportId ? `async get() {
|
|
2478
|
+
const container = await import(${JSON.stringify(treeShakingProviderImportId)});
|
|
2479
|
+
if (typeof container.init === "function") await container.init();
|
|
2480
|
+
return container.get();
|
|
2481
|
+
},` : ""}
|
|
2482
|
+
}` : ""}
|
|
1670
2483
|
}
|
|
1671
2484
|
`;
|
|
1672
2485
|
}).filter((x) => x !== null).join(",")}
|
|
@@ -1676,6 +2489,7 @@ function generateLocalSharedImportMap() {
|
|
|
1676
2489
|
if (!remote) return null;
|
|
1677
2490
|
return `
|
|
1678
2491
|
{
|
|
2492
|
+
alias: ${JSON.stringify(key)},
|
|
1679
2493
|
entryGlobalName: ${JSON.stringify(remote.entryGlobalName)},
|
|
1680
2494
|
name: ${JSON.stringify(remote.name)},
|
|
1681
2495
|
type: ${JSON.stringify(remote.type)},
|
|
@@ -1752,6 +2566,7 @@ function getShareItemForPreload(pkg) {
|
|
|
1752
2566
|
}
|
|
1753
2567
|
function generateSharedCacheSeedItem(pkg, shareItem, importPath) {
|
|
1754
2568
|
const cacheDescriptor = getSharedCacheDescriptor(pkg, shareItem);
|
|
2569
|
+
const cacheOwner = getNormalizeModuleFederationOptions().name;
|
|
1755
2570
|
return `if (__mfReadSharedCache(__mfModuleCache.share, ${JSON.stringify(cacheDescriptor)}) === undefined) {
|
|
1756
2571
|
const mod = await import(${JSON.stringify(importPath)});
|
|
1757
2572
|
${normalizeRuntimeShareCode}
|
|
@@ -1761,7 +2576,7 @@ function generateSharedCacheSeedItem(pkg, shareItem, importPath) {
|
|
|
1761
2576
|
value: true,
|
|
1762
2577
|
enumerable: false
|
|
1763
2578
|
});
|
|
1764
|
-
__mfWriteSharedCache(__mfModuleCache.share, ${JSON.stringify(cacheDescriptor)}, exportModule);
|
|
2579
|
+
__mfWriteSharedCache(__mfModuleCache.share, ${JSON.stringify(cacheDescriptor)}, exportModule, ${JSON.stringify(cacheOwner)});
|
|
1765
2580
|
}`;
|
|
1766
2581
|
}
|
|
1767
2582
|
const normalizeRuntimeShareCode = `const __mfNormalizeRuntimeShare = (mod) => {
|
|
@@ -1782,15 +2597,33 @@ const sharedProviderSelectionHelperCode = `const __mfOriginalProviderKey = Symbo
|
|
|
1782
2597
|
const selectionVersions = {};
|
|
1783
2598
|
for (const [version, provider] of Object.entries(versions)) {
|
|
1784
2599
|
selectionVersions[version] = Object.assign({}, provider, {
|
|
1785
|
-
loaded: false,
|
|
1786
|
-
loading: undefined,
|
|
1787
|
-
lib: undefined,
|
|
1788
2600
|
[__mfOriginalProviderKey]: provider
|
|
1789
2601
|
});
|
|
1790
2602
|
}
|
|
1791
2603
|
return selectionVersions;
|
|
1792
2604
|
};
|
|
1793
|
-
const
|
|
2605
|
+
const __mfFindSharedProviderEntry = (versions, provider) => {
|
|
2606
|
+
if (!provider) return undefined;
|
|
2607
|
+
const entries = Object.entries(versions || {});
|
|
2608
|
+
const registeredEntry = entries.find(([, candidate]) => candidate === provider);
|
|
2609
|
+
if (registeredEntry) {
|
|
2610
|
+
return { version: registeredEntry[0], provider, registered: true };
|
|
2611
|
+
}
|
|
2612
|
+
if (typeof provider.version === "string" && provider.version) {
|
|
2613
|
+
return { version: provider.version, provider, registered: false };
|
|
2614
|
+
}
|
|
2615
|
+
const provenanceEntries = entries.filter(([, candidate]) =>
|
|
2616
|
+
candidate === provider || Boolean(provider.from && candidate?.from === provider.from)
|
|
2617
|
+
);
|
|
2618
|
+
if (provenanceEntries.length !== 1) return undefined;
|
|
2619
|
+
return { version: provenanceEntries[0][0], provider, registered: false };
|
|
2620
|
+
};
|
|
2621
|
+
const __mfSelectSharedProvider = (
|
|
2622
|
+
versions,
|
|
2623
|
+
pkg,
|
|
2624
|
+
share,
|
|
2625
|
+
strategy
|
|
2626
|
+
) => {
|
|
1794
2627
|
if (!versions || !share) return undefined;
|
|
1795
2628
|
const scopes = Array.isArray(share.scope) ? share.scope : [share.scope || "default"];
|
|
1796
2629
|
const selectionVersions = __mfCreateProviderSelectionVersions(versions, strategy);
|
|
@@ -1806,10 +2639,103 @@ const sharedProviderSelectionHelperCode = `const __mfOriginalProviderKey = Symbo
|
|
|
1806
2639
|
)?.shared;
|
|
1807
2640
|
return selected?.[__mfOriginalProviderKey] || selected;
|
|
1808
2641
|
};`;
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
2642
|
+
const externalSharedProviderSelectionHelperCode = `const __mfSelectExternalSharedProvider = (
|
|
2643
|
+
versions,
|
|
2644
|
+
pkg,
|
|
2645
|
+
localShare,
|
|
2646
|
+
strategy
|
|
2647
|
+
) => {
|
|
2648
|
+
const isLocalProvider = (provider) => __mfMatchesSharedProvider(provider, localShare);
|
|
2649
|
+
const candidates = Object.fromEntries(
|
|
2650
|
+
Object.entries(versions || {}).filter(([, provider]) => !isLocalProvider(provider))
|
|
2651
|
+
);
|
|
2652
|
+
if (localShare?.version) {
|
|
2653
|
+
const sameVersionProvider = candidates[localShare.version];
|
|
2654
|
+
// Runtime registration keeps an existing same-version record,
|
|
2655
|
+
// even when it has only a getter and is not loaded yet. Model
|
|
2656
|
+
// that retained provider here so pre-init seeding cannot choose
|
|
2657
|
+
// the local module while loadShare() later chooses the parent.
|
|
2658
|
+
if (!sameVersionProvider) {
|
|
2659
|
+
candidates[localShare.version] = localShare;
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
const provider = __mfSelectSharedProvider(
|
|
2663
|
+
candidates,
|
|
2664
|
+
pkg,
|
|
2665
|
+
localShare,
|
|
2666
|
+
strategy
|
|
2667
|
+
);
|
|
2668
|
+
return isLocalProvider(provider) ? undefined : provider;
|
|
2669
|
+
};
|
|
2670
|
+
const __mfMatchesSharedProvider = (provider, expected) => provider === expected || Boolean(
|
|
2671
|
+
expected?.from && provider?.from === expected.from
|
|
2672
|
+
);
|
|
2673
|
+
const __mfGetScopeRootProvider = (
|
|
2674
|
+
instances,
|
|
2675
|
+
scopeRoot,
|
|
2676
|
+
shared,
|
|
2677
|
+
scopeName,
|
|
2678
|
+
pkg,
|
|
2679
|
+
version,
|
|
2680
|
+
provider,
|
|
2681
|
+
passedProvider,
|
|
2682
|
+
strategy
|
|
2683
|
+
) => {
|
|
2684
|
+
if (strategy !== "version-first" || !passedProvider) return undefined;
|
|
2685
|
+
const scopeRootProviders = scopeRoot?.options?.shared?.[pkg];
|
|
2686
|
+
const configuredScopeRootProvider = Array.isArray(scopeRootProviders)
|
|
2687
|
+
? scopeRootProviders.find((candidate) => candidate?.version === version)
|
|
2688
|
+
: undefined;
|
|
2689
|
+
const registeredScopeRootProvider = passedProvider?.from === scopeRoot?.options?.name
|
|
2690
|
+
? passedProvider
|
|
2691
|
+
: undefined;
|
|
2692
|
+
const scopeRootProvider = registeredScopeRootProvider || (
|
|
2693
|
+
__mfMatchesSharedProvider(configuredScopeRootProvider, passedProvider)
|
|
2694
|
+
? configuredScopeRootProvider
|
|
2695
|
+
// A plain Webpack/Rspack host has no enhanced-runtime instance.
|
|
2696
|
+
// Its pre-init snapshot is still authoritative when this remote's
|
|
2697
|
+
// registration rewrites the same-version provider in-place.
|
|
2698
|
+
: scopeRoot ? undefined : passedProvider
|
|
2699
|
+
);
|
|
2700
|
+
if (!scopeRootProvider) return undefined;
|
|
2701
|
+
const selectedFromLaterInstance = instances.some((instance) =>
|
|
2702
|
+
instance !== scopeRoot &&
|
|
2703
|
+
instance?.options?.name === provider?.from &&
|
|
2704
|
+
instance?.shareScopeMap?.[scopeName] === shared
|
|
2705
|
+
);
|
|
2706
|
+
return selectedFromLaterInstance ? scopeRootProvider : undefined;
|
|
2707
|
+
};
|
|
2708
|
+
const __mfResolveExternalSharedProvider = (
|
|
2709
|
+
instances,
|
|
2710
|
+
scopeRoot,
|
|
2711
|
+
shared,
|
|
2712
|
+
scopeName,
|
|
2713
|
+
pkg,
|
|
2714
|
+
providerEntry,
|
|
2715
|
+
selectedExternalProvider,
|
|
2716
|
+
passedProvider,
|
|
2717
|
+
strategy
|
|
2718
|
+
) => {
|
|
2719
|
+
const scopeRootProvider = providerEntry.registered ? __mfGetScopeRootProvider(
|
|
2720
|
+
instances,
|
|
2721
|
+
scopeRoot,
|
|
2722
|
+
shared,
|
|
2723
|
+
scopeName,
|
|
2724
|
+
pkg,
|
|
2725
|
+
providerEntry.version,
|
|
2726
|
+
providerEntry.provider,
|
|
2727
|
+
passedProvider,
|
|
2728
|
+
strategy
|
|
2729
|
+
) : undefined;
|
|
2730
|
+
const provider = scopeRootProvider || selectedExternalProvider;
|
|
2731
|
+
if (!provider) return undefined;
|
|
2732
|
+
if (
|
|
2733
|
+
providerEntry.registered &&
|
|
2734
|
+
!__mfMatchesSharedProvider(provider, passedProvider)
|
|
2735
|
+
) return undefined;
|
|
2736
|
+
return { provider, scopeRootProvider };
|
|
2737
|
+
};`;
|
|
2738
|
+
function generateRuntimeSharedCacheSeedCode(shareStrategy) {
|
|
1813
2739
|
const seedOrder = getOrderedUsedShares();
|
|
1814
2740
|
return `
|
|
1815
2741
|
const __mfSeedOrder = ${JSON.stringify(seedOrder)};
|
|
@@ -1835,30 +2761,99 @@ function generateRuntimeSharedCacheSeedCode() {
|
|
|
1835
2761
|
}
|
|
1836
2762
|
__mfSeedKeys.splice(insertIndex, 0, pkg);
|
|
1837
2763
|
}
|
|
1838
|
-
|
|
1839
|
-
const
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
2764
|
+
var __mfSeedLocalShared = async (seedKeys) => {
|
|
2765
|
+
for (const pkg of seedKeys) {
|
|
2766
|
+
const share = usedShared[pkg];
|
|
2767
|
+
const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
|
|
2768
|
+
if (
|
|
2769
|
+
share.shareConfig?.import === false ||
|
|
2770
|
+
Boolean(share.treeShaking) ||
|
|
2771
|
+
__mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) !== undefined
|
|
2772
|
+
) {
|
|
2773
|
+
continue;
|
|
2774
|
+
}
|
|
2775
|
+
const singletonCacheDescriptor = __mfGetSharedCacheDescriptor(pkg, true, share.version, share.scope);
|
|
2776
|
+
const singletonModule = __mfReadSharedCache(__mfModuleCache.share, singletonCacheDescriptor);
|
|
2777
|
+
if (singletonModule !== undefined) {
|
|
2778
|
+
__mfWriteSharedCache(
|
|
2779
|
+
__mfModuleCache.share,
|
|
2780
|
+
cacheDescriptor,
|
|
2781
|
+
singletonModule,
|
|
2782
|
+
__mfReadSharedCacheOwner(__mfModuleCache.share, singletonCacheDescriptor)
|
|
2783
|
+
);
|
|
2784
|
+
continue;
|
|
2785
|
+
}
|
|
2786
|
+
const factory = await share.get();
|
|
2787
|
+
const mod = typeof factory === "function" ? factory() : factory;
|
|
2788
|
+
const resolved = await Promise.resolve(mod);
|
|
2789
|
+
${normalizeRuntimeShareCode}
|
|
2790
|
+
const normalizedModule = __mfNormalizeRuntimeShare(resolved);
|
|
2791
|
+
const exportModule = normalizedModule === resolved ? {...resolved} : normalizedModule;
|
|
2792
|
+
Object.defineProperty(exportModule, "__esModule", {
|
|
2793
|
+
value: true,
|
|
2794
|
+
enumerable: false
|
|
2795
|
+
});
|
|
2796
|
+
__mfWriteSharedCache(__mfModuleCache.share, cacheDescriptor, exportModule, mfName);
|
|
1849
2797
|
}
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
const
|
|
1853
|
-
|
|
1854
|
-
const
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
2798
|
+
};
|
|
2799
|
+
const __mfIsRuntimeOnlySharePending = (pkg) => {
|
|
2800
|
+
const share = usedShared[pkg];
|
|
2801
|
+
if (!share.treeShaking && share.shareConfig?.import !== false) return false;
|
|
2802
|
+
const cacheDescriptor = __mfGetSharedCacheDescriptor(
|
|
2803
|
+
pkg,
|
|
2804
|
+
share.shareConfig?.singleton,
|
|
2805
|
+
share.version,
|
|
2806
|
+
share.scope
|
|
2807
|
+
);
|
|
2808
|
+
return share.treeShaking
|
|
2809
|
+
? (
|
|
2810
|
+
__mfReadTreeShakingSharedSelection(
|
|
2811
|
+
__mfModuleCache.share,
|
|
2812
|
+
cacheDescriptor,
|
|
2813
|
+
mfName
|
|
2814
|
+
) === undefined &&
|
|
2815
|
+
__mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) === undefined
|
|
2816
|
+
)
|
|
2817
|
+
: __mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) === undefined;
|
|
2818
|
+
};
|
|
2819
|
+
const __mfNeedsPreInitSeedBarrier = (pkg) => {
|
|
2820
|
+
const share = usedShared[pkg];
|
|
2821
|
+
const cacheDescriptor = __mfGetSharedCacheDescriptor(
|
|
2822
|
+
pkg,
|
|
2823
|
+
share.shareConfig?.singleton,
|
|
2824
|
+
share.version,
|
|
2825
|
+
share.scope
|
|
2826
|
+
);
|
|
2827
|
+
const cachedShare = share.treeShaking
|
|
2828
|
+
? (
|
|
2829
|
+
__mfReadTreeShakingSharedSelection(
|
|
2830
|
+
__mfModuleCache.share,
|
|
2831
|
+
cacheDescriptor,
|
|
2832
|
+
mfName
|
|
2833
|
+
) ?? __mfReadSharedCache(__mfModuleCache.share, cacheDescriptor)
|
|
2834
|
+
)
|
|
2835
|
+
: __mfReadSharedCache(__mfModuleCache.share, cacheDescriptor);
|
|
2836
|
+
if (cachedShare !== undefined) return false;
|
|
2837
|
+
if (share.treeShaking || share.shareConfig?.import === false) return true;
|
|
2838
|
+
if (!share.shareConfig?.singleton) return false;
|
|
2839
|
+
if (typeof __mfSelectExternalSharedProvider !== 'function') return false;
|
|
2840
|
+
return Boolean(__mfSelectExternalSharedProvider(
|
|
2841
|
+
initialShared[pkg],
|
|
2842
|
+
pkg,
|
|
2843
|
+
share,
|
|
2844
|
+
${JSON.stringify(shareStrategy)}
|
|
2845
|
+
));
|
|
2846
|
+
};
|
|
2847
|
+
const __mfFirstRuntimeSeedBarrierIndex = __mfSeedKeys.findIndex(
|
|
2848
|
+
__mfNeedsPreInitSeedBarrier
|
|
2849
|
+
);
|
|
2850
|
+
const __mfImmediateSeedKeys = __mfFirstRuntimeSeedBarrierIndex === -1
|
|
2851
|
+
? __mfSeedKeys
|
|
2852
|
+
: __mfSeedKeys.slice(0, __mfFirstRuntimeSeedBarrierIndex);
|
|
2853
|
+
var __mfDeferredSeedKeys = __mfFirstRuntimeSeedBarrierIndex === -1
|
|
2854
|
+
? []
|
|
2855
|
+
: __mfSeedKeys.slice(__mfFirstRuntimeSeedBarrierIndex);
|
|
2856
|
+
await __mfSeedLocalShared(__mfImmediateSeedKeys);`;
|
|
1862
2857
|
}
|
|
1863
2858
|
function getBrowserImportPath(importPath) {
|
|
1864
2859
|
if (/^(?:[a-zA-Z]:[\\/]|\/)/.test(importPath) && !importPath.startsWith("/@")) return `/@fs/${importPath}`;
|
|
@@ -1886,11 +2881,178 @@ const REMOTE_ENTRY_ID = "virtual:mf-REMOTE_ENTRY_ID";
|
|
|
1886
2881
|
function getRemoteEntryId(options) {
|
|
1887
2882
|
return `${REMOTE_ENTRY_ID}:${`${options.internalName}__${options.filename}`.replace(/[^a-zA-Z0-9_-]/g, "_")}`;
|
|
1888
2883
|
}
|
|
1889
|
-
const SSR_ONLY_PLUGIN_SPECIFIERS = new Set(["@module-federation/vite/ssrEntryLoader"]);
|
|
1890
|
-
const isSsrOnlyPlugin = (importStatement) => [...SSR_ONLY_PLUGIN_SPECIFIERS].some((s) => importStatement.includes(s));
|
|
1891
|
-
const getSsrOnlyPluginSpecifier = (importStatement) => [...SSR_ONLY_PLUGIN_SPECIFIERS].find((s) => importStatement.includes(s));
|
|
2884
|
+
const SSR_ONLY_PLUGIN_SPECIFIERS = new Set(["@module-federation/vite/ssrEntryLoader"]);
|
|
2885
|
+
const isSsrOnlyPlugin = (importStatement) => [...SSR_ONLY_PLUGIN_SPECIFIERS].some((s) => importStatement.includes(s));
|
|
2886
|
+
const getSsrOnlyPluginSpecifier = (importStatement) => [...SSR_ONLY_PLUGIN_SPECIFIERS].find((s) => importStatement.includes(s));
|
|
2887
|
+
function generateTreeShakingSharedResolutionCode(enabled) {
|
|
2888
|
+
if (!enabled) return "const __mfResolveTreeShakingShared = async () => {};";
|
|
2889
|
+
return `
|
|
2890
|
+
// Resolve tree-enabled shares through the Runtime after all providers have
|
|
2891
|
+
// registered. Partial providers are stored with their export coverage and
|
|
2892
|
+
// never occupy generic/legacy cache keys, which are reserved for complete
|
|
2893
|
+
// modules only.
|
|
2894
|
+
const __mfResolveTreeShakingShared = async (pkg, share) => {
|
|
2895
|
+
const treeShaking = share.treeShaking;
|
|
2896
|
+
if (!treeShaking) return;
|
|
2897
|
+
try {
|
|
2898
|
+
const factory = await initRes.loadShare(pkg, {
|
|
2899
|
+
customShareInfo: {
|
|
2900
|
+
shareConfig: share.shareConfig,
|
|
2901
|
+
treeShaking: {
|
|
2902
|
+
mode: treeShaking.mode,
|
|
2903
|
+
status: treeShaking.status,
|
|
2904
|
+
usedExports: treeShaking.usedExports,
|
|
2905
|
+
},
|
|
2906
|
+
},
|
|
2907
|
+
});
|
|
2908
|
+
if (factory === false) return;
|
|
2909
|
+
const mod = typeof factory === "function" ? factory() : factory;
|
|
2910
|
+
const resolved = await Promise.resolve(mod);
|
|
2911
|
+
${normalizeRuntimeShareCode}
|
|
2912
|
+
const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
|
|
2913
|
+
const normalizedShared = __mfNormalizeRuntimeShare(resolved);
|
|
2914
|
+
const providedExports = treeShaking.providedExports ?? treeShaking.usedExports ?? [];
|
|
2915
|
+
const hasPartialProvider =
|
|
2916
|
+
((treeShaking.mode === "runtime-infer" && treeShaking.status !== 0) ||
|
|
2917
|
+
treeShaking.status === 2);
|
|
2918
|
+
if (hasPartialProvider) {
|
|
2919
|
+
__mfWriteTreeShakingSharedCache(
|
|
2920
|
+
__mfModuleCache.share,
|
|
2921
|
+
cacheDescriptor,
|
|
2922
|
+
providedExports,
|
|
2923
|
+
normalizedShared
|
|
2924
|
+
);
|
|
2925
|
+
__mfWriteTreeShakingSharedSelection(
|
|
2926
|
+
__mfModuleCache.share,
|
|
2927
|
+
cacheDescriptor,
|
|
2928
|
+
mfName,
|
|
2929
|
+
normalizedShared
|
|
2930
|
+
);
|
|
2931
|
+
} else {
|
|
2932
|
+
__mfWriteSharedCache(__mfModuleCache.share, cacheDescriptor, normalizedShared);
|
|
2933
|
+
}
|
|
2934
|
+
} catch (e) {
|
|
2935
|
+
console.warn('[Module Federation] Failed to load tree-shaken shared module', pkg, e);
|
|
2936
|
+
}
|
|
2937
|
+
};`;
|
|
2938
|
+
}
|
|
2939
|
+
const treeShakingResolveShareBodyCode = `const consumerTreeShaking = args.shareInfo?.treeShaking;
|
|
2940
|
+
if (consumerTreeShaking?.mode !== "runtime-infer") return args;
|
|
2941
|
+
const requiredExports = consumerTreeShaking.usedExports;
|
|
2942
|
+
if (!Array.isArray(requiredExports)) return args;
|
|
2943
|
+
|
|
2944
|
+
const originalResolver = args.resolver;
|
|
2945
|
+
args.resolver = () => {
|
|
2946
|
+
const resolved = originalResolver();
|
|
2947
|
+
if (!resolved?.useTreesShaking) return resolved;
|
|
2948
|
+
|
|
2949
|
+
const selectedExports = resolved.shared?.treeShaking?.usedExports;
|
|
2950
|
+
const selectedMatches = Array.isArray(selectedExports) &&
|
|
2951
|
+
requiredExports.every((name) => selectedExports.includes(name));
|
|
2952
|
+
if (selectedMatches) return resolved;
|
|
2953
|
+
|
|
2954
|
+
// Runtime 2.7 prefers a tree provider by version before checking export
|
|
2955
|
+
// coverage. Prefer this consumer's own compatible provider when one is
|
|
2956
|
+
// available; otherwise retain the selected version but use its complete
|
|
2957
|
+
// top-level getter.
|
|
2958
|
+
const localExports = consumerTreeShaking.providedExports;
|
|
2959
|
+
const localMatches = typeof consumerTreeShaking.get === "function" &&
|
|
2960
|
+
Array.isArray(localExports) &&
|
|
2961
|
+
requiredExports.every((name) => localExports.includes(name));
|
|
2962
|
+
if (localMatches) {
|
|
2963
|
+
return { shared: args.shareInfo, useTreesShaking: true };
|
|
2964
|
+
}
|
|
2965
|
+
return { shared: resolved.shared, useTreesShaking: false };
|
|
2966
|
+
};
|
|
2967
|
+
return args;`;
|
|
2968
|
+
function generateTreeShakingSnapshotPluginCode(enabled) {
|
|
2969
|
+
if (!enabled) return "";
|
|
2970
|
+
return `
|
|
2971
|
+
const __mfTreeShakingSnapshotPlugin = () => ({
|
|
2972
|
+
name: "vite-tree-shaking-snapshot-plugin",
|
|
2973
|
+
resolveShare(args) {
|
|
2974
|
+
${treeShakingResolveShareBodyCode}
|
|
2975
|
+
},
|
|
2976
|
+
beforeInit(args) {
|
|
2977
|
+
const { userOptions, origin, options: registeredOptions } = args;
|
|
2978
|
+
const version = userOptions.version || registeredOptions.version;
|
|
2979
|
+
const hostSnapshot = runtimeGlobal.getGlobalSnapshotInfoByModuleInfo({
|
|
2980
|
+
name: origin.name,
|
|
2981
|
+
version,
|
|
2982
|
+
});
|
|
2983
|
+
if (!hostSnapshot || !("shared" in hostSnapshot)) return args;
|
|
2984
|
+
|
|
2985
|
+
const candidates = [];
|
|
2986
|
+
const appendShared = (records) => {
|
|
2987
|
+
for (const [pkgName, value] of Object.entries(records || {})) {
|
|
2988
|
+
const values = Array.isArray(value) ? value : [value];
|
|
2989
|
+
for (const shared of values) candidates.push([pkgName, shared]);
|
|
2990
|
+
}
|
|
2991
|
+
};
|
|
2992
|
+
appendShared(userOptions.shared);
|
|
2993
|
+
appendShared(registeredOptions.shared);
|
|
2994
|
+
|
|
2995
|
+
for (const [pkgName, shared] of candidates) {
|
|
2996
|
+
const treeShaking = shared?.treeShaking;
|
|
2997
|
+
if (!treeShaking || treeShaking.mode !== "server-calc") continue;
|
|
2998
|
+
const shareSnapshot = hostSnapshot.shared.find((item) => item.sharedName === pkgName);
|
|
2999
|
+
if (!shareSnapshot || typeof shareSnapshot.treeShakingStatus !== "number") continue;
|
|
3000
|
+
const {
|
|
3001
|
+
secondarySharedTreeShakingEntry: entry,
|
|
3002
|
+
secondarySharedTreeShakingName: name,
|
|
3003
|
+
treeShakingStatus: status,
|
|
3004
|
+
usedExports,
|
|
3005
|
+
fallbackType,
|
|
3006
|
+
} = shareSnapshot;
|
|
3007
|
+
|
|
3008
|
+
// A CALCULATED snapshot without a loadable secondary entry is not safe:
|
|
3009
|
+
// retain UNKNOWN so the Runtime chooses the complete top-level getter.
|
|
3010
|
+
if (status === 2 && (!entry || !name)) continue;
|
|
3011
|
+
if (Array.isArray(usedExports)) {
|
|
3012
|
+
treeShaking.usedExports = usedExports;
|
|
3013
|
+
treeShaking.providedExports = usedExports;
|
|
3014
|
+
}
|
|
3015
|
+
if (entry && name) {
|
|
3016
|
+
const fullFallbackGet = shared.get;
|
|
3017
|
+
treeShaking.get = async () => {
|
|
3018
|
+
try {
|
|
3019
|
+
const shareEntry = await getRemoteEntry({
|
|
3020
|
+
origin,
|
|
3021
|
+
remoteInfo: {
|
|
3022
|
+
name,
|
|
3023
|
+
entry,
|
|
3024
|
+
type: fallbackType || "global",
|
|
3025
|
+
entryGlobalName: name,
|
|
3026
|
+
shareScope: "default",
|
|
3027
|
+
},
|
|
3028
|
+
});
|
|
3029
|
+
if (!shareEntry) throw new Error("Tree-shaken shared entry did not load");
|
|
3030
|
+
if (typeof shareEntry.init === "function") {
|
|
3031
|
+
await shareEntry.init(origin);
|
|
3032
|
+
}
|
|
3033
|
+
return shareEntry.get();
|
|
3034
|
+
} catch (error) {
|
|
3035
|
+
if (typeof fullFallbackGet === "function") return fullFallbackGet();
|
|
3036
|
+
throw error;
|
|
3037
|
+
}
|
|
3038
|
+
};
|
|
3039
|
+
}
|
|
3040
|
+
treeShaking.status = status;
|
|
3041
|
+
}
|
|
3042
|
+
return args;
|
|
3043
|
+
},
|
|
3044
|
+
});`;
|
|
3045
|
+
}
|
|
1892
3046
|
function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(options), command = "build") {
|
|
1893
|
-
const needsSharedProviderSelectionHelper =
|
|
3047
|
+
const needsSharedProviderSelectionHelper = Object.keys(options.shared ?? {}).length > 0;
|
|
3048
|
+
const hasTreeShakingShared = Object.values(options.shared ?? {}).some((share) => !!share?.shareConfig.treeShaking);
|
|
3049
|
+
const hasEagerShared = Object.values(options.shared ?? {}).some((share) => share?.shareConfig.eager === true && share.shareConfig.import !== false);
|
|
3050
|
+
const runtimeImports = [
|
|
3051
|
+
"init as runtimeInit",
|
|
3052
|
+
"loadRemote",
|
|
3053
|
+
...hasTreeShakingShared ? ["getRemoteEntry"] : []
|
|
3054
|
+
].join(", ");
|
|
3055
|
+
const runtimeHelperImports = [...hasTreeShakingShared ? ["global as runtimeGlobal"] : [], ...needsSharedProviderSelectionHelper ? ["share as runtimeShare"] : []];
|
|
1894
3056
|
const pluginImportNames = options.runtimePlugins.map((p, i) => {
|
|
1895
3057
|
if (typeof p === "string") return [
|
|
1896
3058
|
`$runtimePlugin_${i}`,
|
|
@@ -1903,6 +3065,17 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
1903
3065
|
serializeRuntimeOptions(p[1])
|
|
1904
3066
|
];
|
|
1905
3067
|
});
|
|
3068
|
+
const initializeSharingCode = `try {
|
|
3069
|
+
await retrySharedInit(async () => {
|
|
3070
|
+
await Promise.all(await initRes.initializeSharing('${options.shareScope}', {
|
|
3071
|
+
strategy: '${options.shareStrategy}',
|
|
3072
|
+
from: "build",
|
|
3073
|
+
initScope
|
|
3074
|
+
}));
|
|
3075
|
+
});
|
|
3076
|
+
} catch (e) {
|
|
3077
|
+
console.error('[Module Federation]', e)
|
|
3078
|
+
}`;
|
|
1906
3079
|
return `
|
|
1907
3080
|
// Shim Vue HMR runtime for dev-compiled components loaded by a non-Vite host.
|
|
1908
3081
|
// When a remote is served by a Vite dev server, Vue's SFC compiler injects HMR
|
|
@@ -1912,8 +3085,9 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
1912
3085
|
if (typeof __VUE_HMR_RUNTIME__ === 'undefined') {
|
|
1913
3086
|
globalThis.__VUE_HMR_RUNTIME__ = { createRecord() {}, rerender() {}, reload() {} };
|
|
1914
3087
|
}
|
|
1915
|
-
import {
|
|
1916
|
-
${
|
|
3088
|
+
import {${runtimeImports}} from "@module-federation/runtime";
|
|
3089
|
+
${hasEagerShared ? `import * as __mfLocalSharedImportMap from "${getLocalSharedImportMapPath()}";` : ""}
|
|
3090
|
+
${runtimeHelperImports.length ? `import {${runtimeHelperImports.join(", ")}} from "@module-federation/runtime/helpers";` : ""}
|
|
1917
3091
|
${pluginImportNames.filter((item) => !isSsrOnlyPlugin(item[1])).map((item) => item[1]).join("\n")}
|
|
1918
3092
|
${command === "build" ? getRuntimeInitResolveBootstrapCode() : getRuntimeInitBootstrapCode() + "\n const { initResolve } = globalThis[globalKey];"}
|
|
1919
3093
|
${getRuntimeModuleCacheBootstrapCode()}
|
|
@@ -1941,14 +3115,17 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
1941
3115
|
}
|
|
1942
3116
|
}
|
|
1943
3117
|
}
|
|
3118
|
+
${generateTreeShakingSnapshotPluginCode(hasTreeShakingShared)}
|
|
1944
3119
|
${needsSharedProviderSelectionHelper ? sharedProviderSelectionHelperCode : ""}
|
|
3120
|
+
${needsSharedProviderSelectionHelper ? externalSharedProviderSelectionHelperCode : ""}
|
|
1945
3121
|
|
|
1946
3122
|
async function getLocalSharedImportMap() {
|
|
1947
|
-
|
|
3123
|
+
${hasEagerShared ? "return __mfLocalSharedImportMap;" : ""}
|
|
3124
|
+
${hasEagerShared ? "" : `if (!localSharedImportMapPromise) {
|
|
1948
3125
|
localSharedImportMapPromise = retrySharedInit(() => import("${getLocalSharedImportMapPath()}"))
|
|
1949
3126
|
.catch((e) => { localSharedImportMapPromise = undefined; throw e; });
|
|
1950
3127
|
}
|
|
1951
|
-
return localSharedImportMapPromise
|
|
3128
|
+
return localSharedImportMapPromise`}
|
|
1952
3129
|
}
|
|
1953
3130
|
|
|
1954
3131
|
async function getExposesMap() {
|
|
@@ -1962,53 +3139,32 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
1962
3139
|
|
|
1963
3140
|
async function init(shared = {}, initScope = []) {
|
|
1964
3141
|
${sharedCacheHelperCode}
|
|
1965
|
-
const
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
for (const [version, provider] of providerEntries) {
|
|
1982
|
-
if (!provider.lib) continue;
|
|
1983
|
-
const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, provider.shareConfig?.singleton, version, ${JSON.stringify(options.shareScope)});
|
|
1984
|
-
if (__mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) !== undefined) continue;
|
|
1985
|
-
const mod = typeof provider.lib === "function" ? provider.lib() : provider.lib;
|
|
1986
|
-
const resolved = await Promise.resolve(mod);
|
|
1987
|
-
const normalized = __mfNormalizeRuntimeShare(resolved);
|
|
1988
|
-
__mfWriteSharedCache(__mfModuleCache.share, cacheDescriptor, normalized);
|
|
1989
|
-
if (provider.shareConfig?.singleton && usedShare) {
|
|
1990
|
-
const usedCacheDescriptor = __mfGetSharedCacheDescriptor(pkg, usedShare.shareConfig?.singleton, usedShare.version, usedShare.scope);
|
|
1991
|
-
if (__mfReadSharedCache(__mfModuleCache.share, usedCacheDescriptor) === undefined) {
|
|
1992
|
-
__mfWriteSharedCache(__mfModuleCache.share, usedCacheDescriptor, normalized);
|
|
1993
|
-
}
|
|
1994
|
-
}
|
|
1995
|
-
}
|
|
1996
|
-
}
|
|
1997
|
-
}
|
|
1998
|
-
}
|
|
1999
|
-
} catch (e) {
|
|
2000
|
-
console.error('[Module Federation] Failed to bridge external shared modules', e)
|
|
2001
|
-
}
|
|
2002
|
-
for (const [pkg, share] of Object.entries(usedShared)) {
|
|
2003
|
-
const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
|
|
2004
|
-
if (__mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) !== undefined) continue;
|
|
2005
|
-
const singletonCacheDescriptor = __mfGetSharedCacheDescriptor(pkg, true, share.version, share.scope);
|
|
2006
|
-
const singletonModule = __mfReadSharedCache(__mfModuleCache.share, singletonCacheDescriptor);
|
|
2007
|
-
if (singletonModule !== undefined) {
|
|
2008
|
-
__mfWriteSharedCache(__mfModuleCache.share, cacheDescriptor, singletonModule);
|
|
3142
|
+
const federationInstances = globalThis.__FEDERATION__?.__INSTANCES__ || [];
|
|
3143
|
+
const initRootName = initScope.find((token) => token?.from)?.from;
|
|
3144
|
+
const scopeRoot = federationInstances.find((instance) =>
|
|
3145
|
+
instance?.options?.name === initRootName &&
|
|
3146
|
+
instance?.shareScopeMap?.['${options.shareScope}'] === shared
|
|
3147
|
+
) || federationInstances.find((instance) =>
|
|
3148
|
+
instance?.options?.name !== mfName &&
|
|
3149
|
+
instance?.shareScopeMap?.['${options.shareScope}'] === shared
|
|
3150
|
+
);
|
|
3151
|
+
const initialShared = Object.create(null);
|
|
3152
|
+
for (const [pkg, versions] of Object.entries(shared)) {
|
|
3153
|
+
const initialVersions = initialShared[pkg] = Object.create(null);
|
|
3154
|
+
for (const [version, provider] of Object.entries(versions)) {
|
|
3155
|
+
// Runtime registration mutates provider records in-place, notably their origin.
|
|
3156
|
+
// Preserve the parent-visible provider and its original provenance.
|
|
3157
|
+
initialVersions[version] = Object.assign({}, provider);
|
|
2009
3158
|
}
|
|
2010
3159
|
}
|
|
2011
|
-
|
|
3160
|
+
const {usedShared, usedRemotes} = await getLocalSharedImportMap()
|
|
3161
|
+
// handling circular init calls before an external provider can re-enter this container
|
|
3162
|
+
var initToken = initTokens[shareScopeName];
|
|
3163
|
+
if (!initToken)
|
|
3164
|
+
initToken = initTokens[shareScopeName] = { from: mfName };
|
|
3165
|
+
if (initScope.indexOf(initToken) >= 0) return;
|
|
3166
|
+
initScope.push(initToken);
|
|
3167
|
+
${normalizeRuntimeShareCode}
|
|
2012
3168
|
const __browserPlugins = [${pluginImportNames.filter((item) => !isSsrOnlyPlugin(item[1])).map((item) => `${item[0]}(${item[2]})`).join(", ")}];
|
|
2013
3169
|
const __ssrPlugins = typeof globalThis.window === 'undefined'
|
|
2014
3170
|
? await Promise.all([${pluginImportNames.filter((item) => isSsrOnlyPlugin(item[1])).map((item) => {
|
|
@@ -2017,42 +3173,592 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
2017
3173
|
return `import(${JSON.stringify(specifier)}).then(m => (m.default ?? m)(${opts}))`;
|
|
2018
3174
|
}).join(", ")}])
|
|
2019
3175
|
: [];
|
|
3176
|
+
const __mfRuntimeShareLoadIdKey = "__mf_vite_runtime_share_load_id__";
|
|
3177
|
+
let __mfRuntimeShareLoadId = 0;
|
|
3178
|
+
const __mfRuntimeShareSelections = new Map();
|
|
3179
|
+
const __mfRuntimeShareLifecycles = new Map();
|
|
2020
3180
|
const initRes = runtimeInit({
|
|
2021
3181
|
name: mfName,
|
|
2022
3182
|
remotes: ${options.shareStrategy === "loaded-first" ? "[]" : "usedRemotes"},
|
|
2023
3183
|
shared: usedShared,
|
|
2024
|
-
plugins: [...__browserPlugins, ...__ssrPlugins],
|
|
3184
|
+
plugins: [__mfSharePinLifecyclePlugin(), ${hasTreeShakingShared ? "__mfTreeShakingSnapshotPlugin()," : ""} ...__browserPlugins, ...__ssrPlugins],
|
|
2025
3185
|
${options.shareStrategy ? `shareStrategy: '${options.shareStrategy}'` : ""}
|
|
2026
3186
|
});
|
|
2027
|
-
// handling circular init calls
|
|
2028
|
-
var initToken = initTokens[shareScopeName];
|
|
2029
|
-
if (!initToken)
|
|
2030
|
-
initToken = initTokens[shareScopeName] = { from: mfName };
|
|
2031
|
-
if (initScope.indexOf(initToken) >= 0) return;
|
|
2032
|
-
initScope.push(initToken);
|
|
2033
3187
|
initRes.initShareScopeMap('${options.shareScope}', shared);
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
3188
|
+
function __mfSharePinLifecyclePlugin() {
|
|
3189
|
+
return {
|
|
3190
|
+
name: "vite-share-pin-lifecycle-plugin",
|
|
3191
|
+
resolveShare(args) {
|
|
3192
|
+
const loadId = args.shareInfo?.[__mfRuntimeShareLoadIdKey];
|
|
3193
|
+
const lifecycle = loadId === undefined
|
|
3194
|
+
? undefined
|
|
3195
|
+
: __mfRuntimeShareLifecycles.get(loadId);
|
|
3196
|
+
if (!lifecycle) return args;
|
|
3197
|
+
const defaultResolver = args.resolver;
|
|
3198
|
+
args.resolver = (...resolverArgs) => {
|
|
3199
|
+
lifecycle.pinned.reapply();
|
|
3200
|
+
return defaultResolver(...resolverArgs);
|
|
3201
|
+
};
|
|
3202
|
+
lifecycle.pinned.reveal();
|
|
3203
|
+
return args;
|
|
3204
|
+
}
|
|
3205
|
+
};
|
|
3206
|
+
}
|
|
3207
|
+
const runtimeResolveShareHook = initRes.sharedHandler.hooks.lifecycle.resolveShare;
|
|
3208
|
+
const __mfRuntimeProviderOrigins = new WeakMap();
|
|
3209
|
+
runtimeResolveShareHook.on((args) => {
|
|
3210
|
+
const loadId = args.shareInfo?.[__mfRuntimeShareLoadIdKey];
|
|
3211
|
+
const resolver = args.resolver;
|
|
3212
|
+
if (typeof resolver !== "function") return args;
|
|
3213
|
+
const instrumentedResolver = (...resolverArgs) => {
|
|
3214
|
+
const resolved = resolver(...resolverArgs);
|
|
3215
|
+
const selectedProvider = resolved?.shared;
|
|
3216
|
+
if (
|
|
3217
|
+
selectedProvider &&
|
|
3218
|
+
(typeof selectedProvider === "object" || typeof selectedProvider === "function") &&
|
|
3219
|
+
!__mfRuntimeProviderOrigins.has(selectedProvider)
|
|
3220
|
+
) {
|
|
3221
|
+
__mfRuntimeProviderOrigins.set(selectedProvider, { from: selectedProvider.from });
|
|
3222
|
+
}
|
|
3223
|
+
if (loadId !== undefined && selectedProvider) {
|
|
3224
|
+
__mfRuntimeShareSelections.set(loadId, selectedProvider);
|
|
3225
|
+
}
|
|
3226
|
+
return resolved;
|
|
3227
|
+
};
|
|
3228
|
+
args.resolver = instrumentedResolver;
|
|
3229
|
+
return args;
|
|
3230
|
+
});
|
|
3231
|
+
const __mfPinSharedProvider = (versionMap, version, currentProvider, provider) => {
|
|
3232
|
+
if (!versionMap || versionMap[version] !== currentProvider) return undefined;
|
|
3233
|
+
const pinnedProvider = Object.assign({}, provider, {
|
|
3234
|
+
version: provider.version ?? version,
|
|
3235
|
+
scope: provider.scope ?? currentProvider?.scope ?? ['${options.shareScope}'],
|
|
3236
|
+
strategy: 'loaded-first'
|
|
2041
3237
|
});
|
|
2042
|
-
|
|
2043
|
-
|
|
3238
|
+
const providerFrom = provider.from;
|
|
3239
|
+
versionMap[version] = pinnedProvider;
|
|
3240
|
+
const isCurrentProviderActive = () => currentProvider === undefined
|
|
3241
|
+
? versionMap[version] === undefined
|
|
3242
|
+
: versionMap[version] === currentProvider;
|
|
3243
|
+
return {
|
|
3244
|
+
provider: pinnedProvider,
|
|
3245
|
+
reveal() {
|
|
3246
|
+
if (versionMap[version] !== pinnedProvider) return false;
|
|
3247
|
+
if (currentProvider === undefined) delete versionMap[version];
|
|
3248
|
+
else versionMap[version] = currentProvider;
|
|
3249
|
+
return true;
|
|
3250
|
+
},
|
|
3251
|
+
reapply() {
|
|
3252
|
+
if (!isCurrentProviderActive()) return false;
|
|
3253
|
+
versionMap[version] = pinnedProvider;
|
|
3254
|
+
return true;
|
|
3255
|
+
},
|
|
3256
|
+
release(loaded, selected = true) {
|
|
3257
|
+
provider.from = providerFrom;
|
|
3258
|
+
if (versionMap[version] !== pinnedProvider) {
|
|
3259
|
+
return !selected && isCurrentProviderActive();
|
|
3260
|
+
}
|
|
3261
|
+
if (!selected) {
|
|
3262
|
+
if (currentProvider === undefined) delete versionMap[version];
|
|
3263
|
+
else versionMap[version] = currentProvider;
|
|
3264
|
+
return true;
|
|
3265
|
+
}
|
|
3266
|
+
if (!loaded) {
|
|
3267
|
+
if (currentProvider === undefined) delete versionMap[version];
|
|
3268
|
+
else versionMap[version] = currentProvider;
|
|
3269
|
+
return false;
|
|
3270
|
+
}
|
|
3271
|
+
pinnedProvider.from = providerFrom;
|
|
3272
|
+
if (loaded && pinnedProvider.lib) pinnedProvider.loaded = true;
|
|
3273
|
+
if (provider.strategy === undefined) delete pinnedProvider.strategy;
|
|
3274
|
+
else pinnedProvider.strategy = provider.strategy;
|
|
3275
|
+
return true;
|
|
3276
|
+
}
|
|
3277
|
+
};
|
|
3278
|
+
};
|
|
3279
|
+
const __mfSnapshotSharedProviders = (versionMap) => (
|
|
3280
|
+
Object.entries(versionMap || {}).map(([version, provider]) => ({
|
|
3281
|
+
provider,
|
|
3282
|
+
version,
|
|
3283
|
+
from: provider.from,
|
|
3284
|
+
registered: true
|
|
3285
|
+
}))
|
|
3286
|
+
);
|
|
3287
|
+
const __mfMatchLoadedSharedProvider = (providerSelections, factory) => {
|
|
3288
|
+
if (factory === undefined) return undefined;
|
|
3289
|
+
let match;
|
|
3290
|
+
for (const selection of providerSelections) {
|
|
3291
|
+
const provider = selection.provider;
|
|
3292
|
+
const directProvider = provider.treeShaking || provider;
|
|
3293
|
+
if (
|
|
3294
|
+
selection.loadedFactory !== factory &&
|
|
3295
|
+
provider.lib !== factory &&
|
|
3296
|
+
directProvider.lib !== factory
|
|
3297
|
+
) continue;
|
|
3298
|
+
if (match) return undefined;
|
|
3299
|
+
match = selection;
|
|
3300
|
+
}
|
|
3301
|
+
return match;
|
|
3302
|
+
};
|
|
3303
|
+
const __mfLoadRuntimeShare = async (pkg, shareConfig, pinned) => {
|
|
3304
|
+
const loadId = ++__mfRuntimeShareLoadId;
|
|
3305
|
+
__mfRuntimeShareLifecycles.set(loadId, {
|
|
3306
|
+
pinned
|
|
3307
|
+
});
|
|
3308
|
+
try {
|
|
3309
|
+
const factory = await initRes.loadShare(pkg, {
|
|
3310
|
+
customShareInfo: {
|
|
3311
|
+
shareConfig,
|
|
3312
|
+
[__mfRuntimeShareLoadIdKey]: loadId
|
|
3313
|
+
}
|
|
3314
|
+
});
|
|
3315
|
+
return {
|
|
3316
|
+
factory: factory === false ? undefined : factory,
|
|
3317
|
+
selectedProvider: __mfRuntimeShareSelections.get(loadId)
|
|
3318
|
+
};
|
|
3319
|
+
} finally {
|
|
3320
|
+
__mfRuntimeShareSelections.delete(loadId);
|
|
3321
|
+
__mfRuntimeShareLifecycles.delete(loadId);
|
|
3322
|
+
}
|
|
3323
|
+
};
|
|
3324
|
+
const __mfLoadPinnedRuntimeShare = async (
|
|
3325
|
+
pkg,
|
|
3326
|
+
shareConfig,
|
|
3327
|
+
versionMap,
|
|
3328
|
+
version,
|
|
3329
|
+
currentProvider,
|
|
3330
|
+
provider,
|
|
3331
|
+
providerRegistered = true
|
|
3332
|
+
) => {
|
|
3333
|
+
const providerFrom = provider.from;
|
|
3334
|
+
const pinned = __mfPinSharedProvider(
|
|
3335
|
+
versionMap,
|
|
3336
|
+
version,
|
|
3337
|
+
currentProvider,
|
|
3338
|
+
provider
|
|
3339
|
+
);
|
|
3340
|
+
if (!pinned) return undefined;
|
|
3341
|
+
let runtimeLoad;
|
|
3342
|
+
try {
|
|
3343
|
+
runtimeLoad = await __mfLoadRuntimeShare(pkg, shareConfig, pinned);
|
|
3344
|
+
} catch (error) {
|
|
3345
|
+
pinned.release(false);
|
|
3346
|
+
throw error;
|
|
3347
|
+
}
|
|
3348
|
+
const factory = runtimeLoad?.factory;
|
|
3349
|
+
if (factory === undefined) {
|
|
3350
|
+
pinned.release(false);
|
|
3351
|
+
return undefined;
|
|
3352
|
+
}
|
|
3353
|
+
const providerSelections = __mfSnapshotSharedProviders(versionMap);
|
|
3354
|
+
const directPinnedProvider = pinned.provider.treeShaking || pinned.provider;
|
|
3355
|
+
const pinnedMatchesFactory =
|
|
3356
|
+
pinned.provider.lib === factory || directPinnedProvider.lib === factory;
|
|
3357
|
+
if (!providerRegistered && pinnedMatchesFactory) {
|
|
3358
|
+
const pinnedSelectionIndex = providerSelections.findIndex(
|
|
3359
|
+
(selection) => selection.provider === pinned.provider
|
|
3360
|
+
);
|
|
3361
|
+
if (pinnedSelectionIndex !== -1) providerSelections.splice(pinnedSelectionIndex, 1);
|
|
3362
|
+
}
|
|
3363
|
+
if (!providerRegistered && !providerSelections.some((selection) => selection.provider === provider)) {
|
|
3364
|
+
providerSelections.push({
|
|
3365
|
+
provider,
|
|
3366
|
+
version,
|
|
3367
|
+
from: providerFrom,
|
|
3368
|
+
registered: false,
|
|
3369
|
+
loadedFactory: pinnedMatchesFactory ? factory : undefined
|
|
3370
|
+
});
|
|
3371
|
+
}
|
|
3372
|
+
const runtimeSelectedProvider =
|
|
3373
|
+
!providerRegistered &&
|
|
3374
|
+
runtimeLoad.selectedProvider === pinned.provider &&
|
|
3375
|
+
pinnedMatchesFactory
|
|
3376
|
+
? provider
|
|
3377
|
+
: runtimeLoad.selectedProvider;
|
|
3378
|
+
if (
|
|
3379
|
+
runtimeSelectedProvider &&
|
|
3380
|
+
!providerSelections.some((selection) => selection.provider === runtimeSelectedProvider)
|
|
3381
|
+
) {
|
|
3382
|
+
const runtimeProviderOrigin = __mfRuntimeProviderOrigins.get(runtimeSelectedProvider);
|
|
3383
|
+
const selectedVersion = typeof runtimeSelectedProvider.version === "string" && runtimeSelectedProvider.version
|
|
3384
|
+
? runtimeSelectedProvider.version
|
|
3385
|
+
: version;
|
|
3386
|
+
providerSelections.push({
|
|
3387
|
+
provider: runtimeSelectedProvider,
|
|
3388
|
+
version: selectedVersion,
|
|
3389
|
+
from: runtimeProviderOrigin ? runtimeProviderOrigin.from : runtimeSelectedProvider.from,
|
|
3390
|
+
registered: versionMap?.[selectedVersion] === runtimeSelectedProvider,
|
|
3391
|
+
loadedFactory: factory
|
|
3392
|
+
});
|
|
3393
|
+
}
|
|
3394
|
+
const selection = providerSelections.find(
|
|
3395
|
+
(candidate) => candidate.provider === runtimeSelectedProvider
|
|
3396
|
+
) ?? __mfMatchLoadedSharedProvider(providerSelections, factory);
|
|
3397
|
+
const providerStayedActive = pinned.release(
|
|
3398
|
+
true,
|
|
3399
|
+
selection?.provider === pinned.provider
|
|
3400
|
+
);
|
|
3401
|
+
if (!providerStayedActive || !selection) return undefined;
|
|
3402
|
+
const runtimeProviderOrigin = __mfRuntimeProviderOrigins.get(selection.provider);
|
|
3403
|
+
selection.from = selection.provider === provider
|
|
3404
|
+
? providerFrom
|
|
3405
|
+
: runtimeProviderOrigin
|
|
3406
|
+
? runtimeProviderOrigin.from
|
|
3407
|
+
: selection.provider.from;
|
|
3408
|
+
if (runtimeProviderOrigin) selection.provider.from = runtimeProviderOrigin.from;
|
|
3409
|
+
const mod = typeof factory === "function" ? factory() : factory;
|
|
3410
|
+
const resolved = await Promise.resolve(mod);
|
|
3411
|
+
if (selection.registered && versionMap?.[selection.version] !== selection.provider) return undefined;
|
|
3412
|
+
return { provider: selection.provider, selection, resolved };
|
|
3413
|
+
};
|
|
3414
|
+
const bridgedProviders = new Set();
|
|
3415
|
+
const bridgeSelections = new Map();
|
|
3416
|
+
const __mfBridgeMaterializedProvider = async (pkg, usedShare, versionMap) => {
|
|
3417
|
+
const singleton = Boolean(usedShare.shareConfig?.singleton);
|
|
3418
|
+
if (singleton && '${options.shareStrategy}' !== 'loaded-first') return;
|
|
3419
|
+
if (usedShare.canLiveRebind === false) return;
|
|
3420
|
+
try {
|
|
3421
|
+
const provider = __mfSelectExternalSharedProvider(
|
|
3422
|
+
versionMap,
|
|
3423
|
+
pkg,
|
|
3424
|
+
usedShare,
|
|
3425
|
+
'${options.shareStrategy}'
|
|
3426
|
+
);
|
|
3427
|
+
const providerEntry = __mfFindSharedProviderEntry(versionMap, provider);
|
|
3428
|
+
if (!providerEntry) return;
|
|
3429
|
+
const { version } = providerEntry;
|
|
3430
|
+
if (!singleton && version !== usedShare.version) return;
|
|
3431
|
+
if (
|
|
3432
|
+
!provider.lib &&
|
|
3433
|
+
!provider.loading &&
|
|
3434
|
+
!(provider.loaded && typeof provider.get === 'function')
|
|
3435
|
+
) return;
|
|
3436
|
+
const usedCacheDescriptor = __mfGetSharedCacheDescriptor(
|
|
3437
|
+
pkg,
|
|
3438
|
+
singleton,
|
|
3439
|
+
usedShare.version,
|
|
3440
|
+
usedShare.scope
|
|
3441
|
+
);
|
|
3442
|
+
if (__mfReadSharedCache(__mfModuleCache.share, usedCacheDescriptor) !== undefined) return;
|
|
3443
|
+
const liveVersionMap = shared[pkg];
|
|
3444
|
+
const liveProvider = liveVersionMap?.[version];
|
|
3445
|
+
if (providerEntry.registered && !__mfMatchesSharedProvider(liveProvider, provider)) return;
|
|
3446
|
+
let loadedShare;
|
|
3447
|
+
${options.shareStrategy === "loaded-first" ? `loadedShare = await __mfLoadPinnedRuntimeShare(
|
|
3448
|
+
pkg,
|
|
3449
|
+
usedShare.shareConfig,
|
|
3450
|
+
liveVersionMap,
|
|
3451
|
+
version,
|
|
3452
|
+
liveProvider,
|
|
3453
|
+
provider,
|
|
3454
|
+
providerEntry.registered
|
|
3455
|
+
);` : `// Runtime loadShare() implicitly initializes version-first remotes without
|
|
3456
|
+
// this container's outer initScope. Materialized providers are already active,
|
|
3457
|
+
// so resolve them directly and keep remote initialization on the guarded path.
|
|
3458
|
+
let directFactory = provider.lib;
|
|
3459
|
+
if (!directFactory && provider.loading) directFactory = await provider.loading;
|
|
3460
|
+
if (!directFactory && provider.loaded && typeof provider.get === 'function') {
|
|
3461
|
+
directFactory = await provider.get();
|
|
3462
|
+
}
|
|
3463
|
+
if (!directFactory) return;
|
|
3464
|
+
const directModule = typeof directFactory === "function" ? directFactory() : directFactory;
|
|
3465
|
+
const directResolved = await Promise.resolve(directModule);
|
|
3466
|
+
const directProvider = providerEntry.registered ? liveProvider : provider;
|
|
3467
|
+
loadedShare = {
|
|
3468
|
+
provider: directProvider,
|
|
3469
|
+
selection: {
|
|
3470
|
+
provider: directProvider,
|
|
3471
|
+
version,
|
|
3472
|
+
from: provider.from,
|
|
3473
|
+
registered: providerEntry.registered
|
|
3474
|
+
},
|
|
3475
|
+
resolved: directResolved
|
|
3476
|
+
};`}
|
|
3477
|
+
const actualProvider = loadedShare?.provider;
|
|
3478
|
+
const actualSelection = loadedShare?.selection;
|
|
3479
|
+
if (!actualSelection) return;
|
|
3480
|
+
const resolved = loadedShare?.resolved;
|
|
3481
|
+
if (resolved === undefined) return;
|
|
3482
|
+
if (__mfReadSharedCache(__mfModuleCache.share, usedCacheDescriptor) !== undefined) return;
|
|
3483
|
+
${options.shareStrategy === "loaded-first" ? `if (
|
|
3484
|
+
actualSelection.registered &&
|
|
3485
|
+
liveVersionMap?.[actualSelection.version] !== actualProvider
|
|
3486
|
+
) return;` : `if (
|
|
3487
|
+
actualSelection.registered &&
|
|
3488
|
+
liveVersionMap?.[actualSelection.version] !== actualProvider
|
|
3489
|
+
) return;`}
|
|
3490
|
+
__mfWriteSharedCache(
|
|
3491
|
+
__mfModuleCache.share,
|
|
3492
|
+
usedCacheDescriptor,
|
|
3493
|
+
__mfNormalizeRuntimeShare(resolved),
|
|
3494
|
+
actualSelection.from
|
|
3495
|
+
);
|
|
3496
|
+
bridgedProviders.add(actualProvider);
|
|
3497
|
+
} catch (e) {
|
|
3498
|
+
console.error('[Module Federation] Failed to bridge materialized shared module "' + pkg + '"', e)
|
|
3499
|
+
}
|
|
3500
|
+
};
|
|
3501
|
+
const __mfBridgeExternalSharedProvider = async (
|
|
3502
|
+
pkg,
|
|
3503
|
+
usedShare,
|
|
3504
|
+
versionMap,
|
|
3505
|
+
passedVersionMap,
|
|
3506
|
+
expectedSelection
|
|
3507
|
+
) => {
|
|
3508
|
+
try {
|
|
3509
|
+
const usedCacheDescriptor = __mfGetSharedCacheDescriptor(pkg, usedShare.shareConfig?.singleton, usedShare.version, usedShare.scope);
|
|
3510
|
+
const cachedShare = __mfReadSharedCache(__mfModuleCache.share, usedCacheDescriptor);
|
|
3511
|
+
const cachedShareOwner = __mfReadSharedCacheOwner(__mfModuleCache.share, usedCacheDescriptor);
|
|
3512
|
+
const selectedExternalProvider = __mfSelectExternalSharedProvider(
|
|
3513
|
+
versionMap,
|
|
3514
|
+
pkg,
|
|
3515
|
+
usedShare,
|
|
3516
|
+
'${options.shareStrategy}'
|
|
3517
|
+
);
|
|
3518
|
+
const selectedRuntimeProvider = selectedExternalProvider ||
|
|
3519
|
+
__mfSelectSharedProvider(versionMap, pkg, usedShare, '${options.shareStrategy}') ||
|
|
3520
|
+
usedShare;
|
|
3521
|
+
const providerEntry = __mfFindSharedProviderEntry(versionMap, selectedRuntimeProvider);
|
|
3522
|
+
if (!providerEntry) return;
|
|
3523
|
+
const selectedLocalProvider = __mfMatchesSharedProvider(selectedRuntimeProvider, usedShare);
|
|
3524
|
+
const { version } = providerEntry;
|
|
3525
|
+
const passedProvider = passedVersionMap?.[version];
|
|
3526
|
+
const resolvedExternalProvider = __mfResolveExternalSharedProvider(
|
|
3527
|
+
federationInstances,
|
|
3528
|
+
scopeRoot,
|
|
3529
|
+
shared,
|
|
3530
|
+
'${options.shareScope}',
|
|
3531
|
+
pkg,
|
|
3532
|
+
providerEntry,
|
|
3533
|
+
selectedExternalProvider,
|
|
3534
|
+
passedProvider,
|
|
3535
|
+
'${options.shareStrategy}'
|
|
3536
|
+
);
|
|
3537
|
+
if (!resolvedExternalProvider && !selectedLocalProvider) return;
|
|
3538
|
+
const { provider, scopeRootProvider } = resolvedExternalProvider || {
|
|
3539
|
+
provider: selectedRuntimeProvider,
|
|
3540
|
+
scopeRootProvider: undefined
|
|
3541
|
+
};
|
|
3542
|
+
// Non-singleton proxies may have already snapshotted their local exports while
|
|
3543
|
+
// seeding shared dependencies. Late cache replacement is safe only for the
|
|
3544
|
+
// live-bound singleton proxies.
|
|
3545
|
+
if (!usedShare.shareConfig?.singleton) return;
|
|
3546
|
+
if (usedShare.canLiveRebind === false) return;
|
|
3547
|
+
// Preserve a singleton already selected by another container. The bridge may
|
|
3548
|
+
// only replace the provisional local fallback seeded by this container.
|
|
3549
|
+
if (cachedShare !== undefined && cachedShareOwner !== mfName) return;
|
|
3550
|
+
// Registration can replace an unloaded same-version root provider in-place.
|
|
3551
|
+
// Pin the chosen provider while loadShare() runs its implicit registration.
|
|
3552
|
+
const liveVersionMap = shared[pkg];
|
|
3553
|
+
const liveProvider = liveVersionMap?.[version];
|
|
3554
|
+
if (
|
|
3555
|
+
providerEntry.registered &&
|
|
3556
|
+
!scopeRootProvider &&
|
|
3557
|
+
!__mfMatchesSharedProvider(liveProvider, provider)
|
|
3558
|
+
) return;
|
|
3559
|
+
const loadedShare = await __mfLoadPinnedRuntimeShare(
|
|
3560
|
+
pkg,
|
|
3561
|
+
usedShare.shareConfig,
|
|
3562
|
+
liveVersionMap,
|
|
3563
|
+
version,
|
|
3564
|
+
liveProvider,
|
|
3565
|
+
provider,
|
|
3566
|
+
providerEntry.registered && !selectedLocalProvider
|
|
3567
|
+
);
|
|
3568
|
+
const actualProvider = loadedShare?.provider;
|
|
3569
|
+
const actualSelection = loadedShare?.selection;
|
|
3570
|
+
if (!actualSelection) return;
|
|
3571
|
+
if (__mfMatchesSharedProvider(actualProvider, usedShare)) return;
|
|
3572
|
+
if (expectedSelection) {
|
|
3573
|
+
if (
|
|
3574
|
+
expectedSelection.version !== actualSelection.version ||
|
|
3575
|
+
!__mfMatchesSharedProvider({ from: actualSelection.from }, expectedSelection.provider)
|
|
3576
|
+
) return;
|
|
3577
|
+
}
|
|
3578
|
+
if (bridgedProviders.has(actualProvider)) return;
|
|
3579
|
+
const resolved = loadedShare?.resolved;
|
|
3580
|
+
if (resolved === undefined) return;
|
|
3581
|
+
const latestCachedShare = __mfReadSharedCache(__mfModuleCache.share, usedCacheDescriptor);
|
|
3582
|
+
const latestCachedShareOwner = __mfReadSharedCacheOwner(__mfModuleCache.share, usedCacheDescriptor);
|
|
3583
|
+
if (latestCachedShare !== undefined && latestCachedShareOwner !== mfName) return;
|
|
3584
|
+
if (
|
|
3585
|
+
actualSelection.registered &&
|
|
3586
|
+
liveVersionMap?.[actualSelection.version] !== actualProvider
|
|
3587
|
+
) return;
|
|
3588
|
+
if (!expectedSelection) {
|
|
3589
|
+
bridgeSelections.set(pkg, {
|
|
3590
|
+
version: actualSelection.version,
|
|
3591
|
+
provider: { from: actualSelection.from }
|
|
3592
|
+
});
|
|
3593
|
+
}
|
|
3594
|
+
bridgedProviders.add(actualProvider);
|
|
3595
|
+
const normalized = __mfNormalizeRuntimeShare(resolved);
|
|
3596
|
+
__mfWriteSharedCache(
|
|
3597
|
+
__mfModuleCache.share,
|
|
3598
|
+
usedCacheDescriptor,
|
|
3599
|
+
normalized,
|
|
3600
|
+
actualSelection.from
|
|
3601
|
+
);
|
|
3602
|
+
} catch (e) {
|
|
3603
|
+
console.error('[Module Federation] Failed to bridge external shared module "' + pkg + '"', e)
|
|
3604
|
+
}
|
|
3605
|
+
};
|
|
3606
|
+
for (const [pkg, usedShare] of Object.entries(usedShared)) {
|
|
3607
|
+
if (usedShare.treeShaking) continue;
|
|
3608
|
+
await __mfBridgeMaterializedProvider(pkg, usedShare, initialShared[pkg]);
|
|
2044
3609
|
}
|
|
2045
3610
|
for (const [pkg, share] of Object.entries(usedShared)) {
|
|
3611
|
+
if (share.treeShaking) continue;
|
|
3612
|
+
const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
|
|
3613
|
+
if (__mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) !== undefined) continue;
|
|
3614
|
+
const singletonCacheDescriptor = __mfGetSharedCacheDescriptor(pkg, true, share.version, share.scope);
|
|
3615
|
+
const singletonModule = __mfReadSharedCache(__mfModuleCache.share, singletonCacheDescriptor);
|
|
3616
|
+
if (singletonModule !== undefined) {
|
|
3617
|
+
__mfWriteSharedCache(
|
|
3618
|
+
__mfModuleCache.share,
|
|
3619
|
+
cacheDescriptor,
|
|
3620
|
+
singletonModule,
|
|
3621
|
+
__mfReadSharedCacheOwner(__mfModuleCache.share, singletonCacheDescriptor)
|
|
3622
|
+
);
|
|
3623
|
+
}
|
|
3624
|
+
}
|
|
3625
|
+
${generateRuntimeSharedCacheSeedCode(options.shareStrategy)}
|
|
3626
|
+
${initializeSharingCode}
|
|
3627
|
+
// Calling provider.get() marks a provider as loaded. Wait until the Runtime has
|
|
3628
|
+
// finalized normal same-version precedence before materializing an external share.
|
|
3629
|
+
for (const [pkg, usedShare] of Object.entries(usedShared)) {
|
|
3630
|
+
if (usedShare.treeShaking) continue;
|
|
3631
|
+
await __mfBridgeExternalSharedProvider(
|
|
3632
|
+
pkg,
|
|
3633
|
+
usedShare,
|
|
3634
|
+
shared[pkg],
|
|
3635
|
+
initialShared[pkg],
|
|
3636
|
+
undefined
|
|
3637
|
+
);
|
|
3638
|
+
}
|
|
3639
|
+
try {
|
|
3640
|
+
const allInstances = globalThis.__FEDERATION__?.__SHARE__;
|
|
3641
|
+
const globalVersionsByPackage = Object.create(null);
|
|
3642
|
+
if (allInstances) {
|
|
3643
|
+
for (const [, scopes] of Object.entries(allInstances)) {
|
|
3644
|
+
const scopeShare = scopes?.['${options.shareScope}'];
|
|
3645
|
+
if (!scopeShare) continue;
|
|
3646
|
+
for (const [pkg, versionMap] of Object.entries(scopeShare)) {
|
|
3647
|
+
const usedShare = usedShared?.[pkg];
|
|
3648
|
+
const passedVersions = initialShared[pkg];
|
|
3649
|
+
const bridgeSelection = bridgeSelections.get(pkg);
|
|
3650
|
+
if (!usedShare) continue;
|
|
3651
|
+
if (!passedVersions) continue;
|
|
3652
|
+
if (!bridgeSelection) continue;
|
|
3653
|
+
if (usedShare.treeShaking) continue;
|
|
3654
|
+
const globalVersions = globalVersionsByPackage[pkg] || (globalVersionsByPackage[pkg] = Object.create(null));
|
|
3655
|
+
for (const [version, provider] of Object.entries(versionMap)) {
|
|
3656
|
+
if (!provider.lib) continue;
|
|
3657
|
+
if (bridgeSelection.version !== version) continue;
|
|
3658
|
+
if (!__mfMatchesSharedProvider(provider, bridgeSelection.provider)) continue;
|
|
3659
|
+
const passedProvider = passedVersions[version];
|
|
3660
|
+
const matchesPassedProvider = provider === passedProvider || (
|
|
3661
|
+
passedProvider?.from && provider.from === passedProvider.from
|
|
3662
|
+
);
|
|
3663
|
+
if (!matchesPassedProvider) continue;
|
|
3664
|
+
if (provider === usedShare || (usedShare.from && provider.from === usedShare.from)) continue;
|
|
3665
|
+
if (globalVersions[version] === undefined) globalVersions[version] = provider;
|
|
3666
|
+
}
|
|
3667
|
+
}
|
|
3668
|
+
}
|
|
3669
|
+
}
|
|
3670
|
+
for (const [pkg, versionMap] of Object.entries(globalVersionsByPackage)) {
|
|
3671
|
+
await __mfBridgeExternalSharedProvider(
|
|
3672
|
+
pkg,
|
|
3673
|
+
usedShared[pkg],
|
|
3674
|
+
versionMap,
|
|
3675
|
+
initialShared[pkg],
|
|
3676
|
+
bridgeSelections.get(pkg)
|
|
3677
|
+
);
|
|
3678
|
+
}
|
|
3679
|
+
} catch (e) {
|
|
3680
|
+
console.error('[Module Federation] Failed to bridge external shared modules', e)
|
|
3681
|
+
}
|
|
3682
|
+
${generateTreeShakingSharedResolutionCode(hasTreeShakingShared)}
|
|
3683
|
+
const __mfResolveImportFalseShared = async (pkg, share) => {
|
|
2046
3684
|
const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
|
|
2047
|
-
|
|
3685
|
+
const cachedShare = share.treeShaking
|
|
3686
|
+
? __mfReadTreeShakingSharedSelection(__mfModuleCache.share, cacheDescriptor, mfName)
|
|
3687
|
+
: __mfReadSharedCache(__mfModuleCache.share, cacheDescriptor);
|
|
3688
|
+
if (share.shareConfig?.import !== false || cachedShare !== undefined) return;
|
|
2048
3689
|
${normalizeRuntimeShareCode}
|
|
2049
|
-
const
|
|
2050
|
-
const provider = __mfSelectSharedProvider(
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
3690
|
+
const versionMap = shared?.[pkg];
|
|
3691
|
+
const provider = __mfSelectSharedProvider(
|
|
3692
|
+
versionMap,
|
|
3693
|
+
pkg,
|
|
3694
|
+
share,
|
|
3695
|
+
'${options.shareStrategy}'
|
|
3696
|
+
) || share;
|
|
3697
|
+
const providerEntry = __mfFindSharedProviderEntry(versionMap, provider);
|
|
3698
|
+
if (!providerEntry) return;
|
|
3699
|
+
const { version } = providerEntry;
|
|
3700
|
+
const currentProvider = versionMap?.[version];
|
|
3701
|
+
const loadedShare = await __mfLoadPinnedRuntimeShare(
|
|
3702
|
+
pkg,
|
|
3703
|
+
share.shareConfig,
|
|
3704
|
+
versionMap,
|
|
3705
|
+
version,
|
|
3706
|
+
currentProvider,
|
|
3707
|
+
provider,
|
|
3708
|
+
providerEntry.registered && !__mfMatchesSharedProvider(provider, share)
|
|
3709
|
+
);
|
|
3710
|
+
const providerSelection = loadedShare?.selection;
|
|
3711
|
+
const actualProvider = loadedShare?.provider;
|
|
3712
|
+
const resolved = loadedShare?.resolved;
|
|
3713
|
+
if (!providerSelection) return;
|
|
3714
|
+
if (__mfMatchesSharedProvider(actualProvider, share)) return;
|
|
3715
|
+
if (resolved === undefined) return;
|
|
3716
|
+
const latestCachedShare = share.treeShaking
|
|
3717
|
+
? __mfReadTreeShakingSharedSelection(__mfModuleCache.share, cacheDescriptor, mfName)
|
|
3718
|
+
: __mfReadSharedCache(__mfModuleCache.share, cacheDescriptor);
|
|
3719
|
+
if (latestCachedShare !== undefined) return;
|
|
3720
|
+
if (
|
|
3721
|
+
providerSelection.registered &&
|
|
3722
|
+
versionMap?.[providerSelection.version] !== actualProvider
|
|
3723
|
+
) return;
|
|
3724
|
+
const normalizedShared = __mfNormalizeRuntimeShare(resolved);
|
|
3725
|
+
if (share.treeShaking) {
|
|
3726
|
+
const providedExports = share.treeShaking.providedExports ?? share.treeShaking.usedExports ?? [];
|
|
3727
|
+
__mfWriteTreeShakingSharedCache(
|
|
3728
|
+
__mfModuleCache.share,
|
|
3729
|
+
cacheDescriptor,
|
|
3730
|
+
providedExports,
|
|
3731
|
+
normalizedShared
|
|
3732
|
+
);
|
|
3733
|
+
__mfWriteTreeShakingSharedSelection(
|
|
3734
|
+
__mfModuleCache.share,
|
|
3735
|
+
cacheDescriptor,
|
|
3736
|
+
mfName,
|
|
3737
|
+
normalizedShared
|
|
3738
|
+
);
|
|
3739
|
+
} else {
|
|
3740
|
+
__mfWriteSharedCache(
|
|
3741
|
+
__mfModuleCache.share,
|
|
3742
|
+
cacheDescriptor,
|
|
3743
|
+
normalizedShared,
|
|
3744
|
+
providerSelection.from
|
|
3745
|
+
);
|
|
3746
|
+
}
|
|
3747
|
+
};
|
|
3748
|
+
// Resolve runtime-only dependencies and seed local fallbacks in dependency
|
|
3749
|
+
// order. Stop at an unresolved provider so its consumers cannot capture an
|
|
3750
|
+
// undefined or provisional singleton.
|
|
3751
|
+
for (const pkg of __mfDeferredSeedKeys) {
|
|
3752
|
+
const share = usedShared[pkg];
|
|
3753
|
+
if (__mfIsRuntimeOnlySharePending(pkg)) {
|
|
3754
|
+
if (share.treeShaking) {
|
|
3755
|
+
await __mfResolveTreeShakingShared(pkg, share);
|
|
3756
|
+
} else if (share.shareConfig?.import === false) {
|
|
3757
|
+
await __mfResolveImportFalseShared(pkg, share);
|
|
3758
|
+
}
|
|
3759
|
+
}
|
|
3760
|
+
if (__mfIsRuntimeOnlySharePending(pkg)) break;
|
|
3761
|
+
await __mfSeedLocalShared([pkg]);
|
|
2056
3762
|
}
|
|
2057
3763
|
initResolve(initRes)
|
|
2058
3764
|
return initRes
|
|
@@ -2078,6 +3784,7 @@ let currentHostAutoInitCommand = "build";
|
|
|
2078
3784
|
function generateHostAutoInitCode(remoteEntryImport, _command = "build") {
|
|
2079
3785
|
const shouldPreloadShares = getNormalizeModuleFederationOptions().shareStrategy !== "loaded-first";
|
|
2080
3786
|
const hostInitShareOrder = JSON.stringify(getOrderedUsedShares());
|
|
3787
|
+
const cacheOwner = JSON.stringify(getNormalizeModuleFederationOptions().name);
|
|
2081
3788
|
return `
|
|
2082
3789
|
${getRuntimeModuleCacheBootstrapCode()}
|
|
2083
3790
|
let hostInitPromise;
|
|
@@ -2096,6 +3803,10 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build") {
|
|
|
2096
3803
|
for (const pkg of __mfHostInitShareOrder) {
|
|
2097
3804
|
const share = usedShared[pkg];
|
|
2098
3805
|
if (!share) continue;
|
|
3806
|
+
// remoteEntry.init resolves tree-enabled shares into the
|
|
3807
|
+
// coverage-aware cache. Never republish that selected partial under
|
|
3808
|
+
// a generic full-module key here.
|
|
3809
|
+
if (share.treeShaking) continue;
|
|
2099
3810
|
const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
|
|
2100
3811
|
if (__mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) !== undefined) {
|
|
2101
3812
|
continue;
|
|
@@ -2105,7 +3816,12 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build") {
|
|
|
2105
3816
|
}).then((factory) => {
|
|
2106
3817
|
const mod = typeof factory === "function" ? factory() : factory;
|
|
2107
3818
|
return Promise.resolve(mod).then((resolved) => {
|
|
2108
|
-
__mfWriteSharedCache(
|
|
3819
|
+
__mfWriteSharedCache(
|
|
3820
|
+
__mfModuleCache.share,
|
|
3821
|
+
cacheDescriptor,
|
|
3822
|
+
__mfNormalizeRuntimeShare(resolved),
|
|
3823
|
+
${cacheOwner}
|
|
3824
|
+
);
|
|
2109
3825
|
});
|
|
2110
3826
|
});
|
|
2111
3827
|
}
|
|
@@ -2158,9 +3874,8 @@ function addUsedRemote(remoteKey, remoteModule) {
|
|
|
2158
3874
|
function getUsedRemotesMap() {
|
|
2159
3875
|
return usedRemotesMap;
|
|
2160
3876
|
}
|
|
2161
|
-
function
|
|
2162
|
-
|
|
2163
|
-
return remoteName ? remotes[remoteName] : void 0;
|
|
3877
|
+
function getRemoteAliasFromId(id, remotes) {
|
|
3878
|
+
return Object.keys(remotes).filter((name) => id === name || id.startsWith(name + "/")).sort((a, b) => b.length - a.length)[0];
|
|
2164
3879
|
}
|
|
2165
3880
|
function resolveRemoteInitMode(shareStrategy, consumer) {
|
|
2166
3881
|
if (shareStrategy !== "loaded-first") return "eager";
|
|
@@ -2316,10 +4031,12 @@ function generateRemotes(id, command, enableSsrInit = false, consumer = "unified
|
|
|
2316
4031
|
const isLoadedFirst = options.shareStrategy === "loaded-first";
|
|
2317
4032
|
const initMode = resolveRemoteInitMode(options.shareStrategy, consumer);
|
|
2318
4033
|
const deferRemoteLoad = shouldDeferRemoteLoad(initMode);
|
|
2319
|
-
const
|
|
4034
|
+
const remoteAlias = getRemoteAliasFromId(id, options.remotes);
|
|
4035
|
+
const remote = remoteAlias ? options.remotes[remoteAlias] : void 0;
|
|
2320
4036
|
const registerRemoteCode = isLoadedFirst && remote ? `runtime.registerRemotes([${JSON.stringify({
|
|
2321
4037
|
entryGlobalName: remote.entryGlobalName,
|
|
2322
4038
|
name: remote.name,
|
|
4039
|
+
alias: remoteAlias,
|
|
2323
4040
|
type: remote.type,
|
|
2324
4041
|
entry: remote.entry,
|
|
2325
4042
|
shareScope: remote.shareScope ?? "default"
|
|
@@ -2391,7 +4108,7 @@ function generateRemotes(id, command, enableSsrInit = false, consumer = "unified
|
|
|
2391
4108
|
const HOST_INIT_PRELOAD_CHUNKS = [
|
|
2392
4109
|
(name) => name === "hostInit",
|
|
2393
4110
|
(name) => name === "remoteEntry",
|
|
2394
|
-
(name) => name.startsWith("_virtual_mf"),
|
|
4111
|
+
(name) => name.startsWith("_virtual_mf") && !name.includes("__prebuild__"),
|
|
2395
4112
|
(name) => name === "index"
|
|
2396
4113
|
];
|
|
2397
4114
|
function escapeHtmlAttr(value) {
|
|
@@ -2593,7 +4310,7 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
|
|
|
2593
4310
|
return decodeViteId(id).replace(/^\0/, "");
|
|
2594
4311
|
}
|
|
2595
4312
|
function normalizeModuleId(id) {
|
|
2596
|
-
return id.split("?")[0]
|
|
4313
|
+
return normalizePathForImport(id.split("?")[0]);
|
|
2597
4314
|
}
|
|
2598
4315
|
function resolveProjectId(id) {
|
|
2599
4316
|
if (id.startsWith("\0") || id.startsWith("virtual:")) return normalizeModuleId(id);
|
|
@@ -2630,8 +4347,8 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
|
|
|
2630
4347
|
const resolvedEntryPath = getEntryPath();
|
|
2631
4348
|
if (resolvedEntryPath.startsWith("virtual:mf")) devEntryPath = config.base + VITE_ID_PREFIX.slice(1) + resolvedEntryPath;
|
|
2632
4349
|
else {
|
|
2633
|
-
const normalized = resolvedEntryPath
|
|
2634
|
-
const root = config.root
|
|
4350
|
+
const normalized = normalizePathForImport(resolvedEntryPath);
|
|
4351
|
+
const root = normalizePathForImport(config.root).replace(/\/$/, "");
|
|
2635
4352
|
const relativePath = normalized.startsWith(root + "/") ? normalized.slice(root.length) : "/" + normalized.replace(/^[A-Za-z]:[\\/]/, "");
|
|
2636
4353
|
devEntryPath = config.base + relativePath.replace(/^\//, "");
|
|
2637
4354
|
}
|
|
@@ -3382,7 +5099,7 @@ function initVirtualModules(command, remoteEntryId, enableSsrInit = false) {
|
|
|
3382
5099
|
function isOutputChunk$1(chunk) {
|
|
3383
5100
|
return chunk.type === "chunk";
|
|
3384
5101
|
}
|
|
3385
|
-
function escapeRegExp(value) {
|
|
5102
|
+
function escapeRegExp$1(value) {
|
|
3386
5103
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3387
5104
|
}
|
|
3388
5105
|
function getProxyBaseName(fileName) {
|
|
@@ -3474,7 +5191,7 @@ function rewriteEsmProxyConsumers(code, proxyChunks) {
|
|
|
3474
5191
|
const claimedLocals = /* @__PURE__ */ new Set();
|
|
3475
5192
|
for (const [proxyFileName, proxyInfo] of Array.from(proxyChunks.entries())) {
|
|
3476
5193
|
const proxyBaseName = getProxyBaseName(proxyFileName);
|
|
3477
|
-
const importMatch = new RegExp(`import\\s*\\{([^}]+)\\}\\s*from\\s*["']([^"']*${escapeRegExp(proxyBaseName)}[^"']*)["']\\s*;?`).exec(nextCode);
|
|
5194
|
+
const importMatch = new RegExp(`import\\s*\\{([^}]+)\\}\\s*from\\s*["']([^"']*${escapeRegExp$1(proxyBaseName)}[^"']*)["']\\s*;?`).exec(nextCode);
|
|
3478
5195
|
if (!importMatch) continue;
|
|
3479
5196
|
const fullImport = importMatch[0];
|
|
3480
5197
|
const bindings = importMatch[1].split(",").map((s) => {
|
|
@@ -3531,7 +5248,7 @@ function rewriteSystemProxyConsumers(code, systemProxyInfo) {
|
|
|
3531
5248
|
let nextCode = code;
|
|
3532
5249
|
for (const [proxyFileName, proxyInfo] of Array.from(systemProxyInfo.entries())) {
|
|
3533
5250
|
const proxyBaseName = getProxyBaseName(proxyFileName);
|
|
3534
|
-
const depMatch = new RegExp(`["']([^"']*${escapeRegExp(proxyBaseName)}[^"']*)["']`).exec(nextCode);
|
|
5251
|
+
const depMatch = new RegExp(`["']([^"']*${escapeRegExp$1(proxyBaseName)}[^"']*)["']`).exec(nextCode);
|
|
3535
5252
|
if (!depMatch) continue;
|
|
3536
5253
|
let setterIndex = 0;
|
|
3537
5254
|
const depListMatch = nextCode.match(/System\.register\(\[([\s\S]*?)\]/);
|
|
@@ -3890,10 +5607,28 @@ function createRemoteEntryAssetMap(fileName) {
|
|
|
3890
5607
|
}
|
|
3891
5608
|
};
|
|
3892
5609
|
}
|
|
5610
|
+
function isTreeShakingProviderChunk(file) {
|
|
5611
|
+
if (file.type !== "chunk") return false;
|
|
5612
|
+
if (file.facadeModuleId?.includes("__treeShakingProvider__")) return true;
|
|
5613
|
+
return Object.keys(file.modules || {}).some((id) => id.includes("__treeShakingProvider__") || id.includes("__mf_tree_shaking_graph__"));
|
|
5614
|
+
}
|
|
5615
|
+
function getTreeShakingBuildInfo(options) {
|
|
5616
|
+
if (!(Object.values(options.shared || {}).some((share) => !!share.shareConfig.treeShaking) || !!options.treeShakingSharedPlugins?.length || !!options.treeShakingSharedExcludePlugins?.length)) return {};
|
|
5617
|
+
return {
|
|
5618
|
+
target: [options.target || "web"],
|
|
5619
|
+
...options.treeShakingSharedPlugins?.length ? { plugins: [...options.treeShakingSharedPlugins] } : {},
|
|
5620
|
+
...options.treeShakingSharedExcludePlugins?.length ? { excludePlugins: [...options.treeShakingSharedExcludePlugins] } : {}
|
|
5621
|
+
};
|
|
5622
|
+
}
|
|
5623
|
+
function getRemoteContainerName(remoteKey, remote) {
|
|
5624
|
+
const entryGlobalName = remote.entryGlobalName;
|
|
5625
|
+
if (entryGlobalName && entryGlobalName !== remoteKey && entryGlobalName !== remote.entry) return entryGlobalName;
|
|
5626
|
+
return remote.name;
|
|
5627
|
+
}
|
|
3893
5628
|
const Manifest = () => {
|
|
3894
5629
|
const mfOptions = getNormalizeModuleFederationOptions();
|
|
3895
5630
|
const { name, filename, getPublicPath, manifest: manifestOptions, varFilename } = mfOptions;
|
|
3896
|
-
let mfManifestName = manifestOptions === true ? "mf-manifest.json" : typeof manifestOptions === "object" ? path$1.join(manifestOptions?.filePath || "", manifestOptions?.fileName || "mf-manifest.json") : void 0;
|
|
5631
|
+
let mfManifestName = manifestOptions === true ? "mf-manifest.json" : typeof manifestOptions === "object" ? normalizePathForImport(path$1.join(manifestOptions?.filePath || "", manifestOptions?.fileName || "mf-manifest.json")) : void 0;
|
|
3897
5632
|
let mfManifestStatsName = mfManifestName ? getStatsFileName(mfManifestName) : void 0;
|
|
3898
5633
|
const isConsumerProject = Object.keys(mfOptions.exposes).length === 0;
|
|
3899
5634
|
let disableAssetsAnalyze = false;
|
|
@@ -3942,7 +5677,8 @@ const Manifest = () => {
|
|
|
3942
5677
|
type: "app",
|
|
3943
5678
|
buildInfo: {
|
|
3944
5679
|
buildVersion: getBuildVersion(),
|
|
3945
|
-
buildName: name
|
|
5680
|
+
buildName: name,
|
|
5681
|
+
...getTreeShakingBuildInfo(mfOptions)
|
|
3946
5682
|
},
|
|
3947
5683
|
remoteEntry: {
|
|
3948
5684
|
name: devRemoteEntryFile,
|
|
@@ -3997,6 +5733,16 @@ const Manifest = () => {
|
|
|
3997
5733
|
if (foundRemoteEntryFile) remoteEntryFile = foundRemoteEntryFile;
|
|
3998
5734
|
ssrRemoteEntryFile = foundSsrRemoteEntryFile || (_command === "serve" ? getSsrRemoteEntryFileName(resolveDevRemoteEntryFileName(mfOptions.filename)) : expectedSsrRemoteEntryFile);
|
|
3999
5735
|
const allCssAssets = mfOptions.bundleAllCSS && !disableAssetsAnalyze ? collectCssAssets(bundle) : /* @__PURE__ */ new Set();
|
|
5736
|
+
if (allCssAssets.size > 0) {
|
|
5737
|
+
const secondaryCss = /* @__PURE__ */ new Set();
|
|
5738
|
+
const primaryCss = /* @__PURE__ */ new Set();
|
|
5739
|
+
for (const file of Object.values(bundle)) {
|
|
5740
|
+
if (file.type !== "chunk") continue;
|
|
5741
|
+
const target = isTreeShakingProviderChunk(file) ? secondaryCss : primaryCss;
|
|
5742
|
+
for (const css of file.viteMetadata?.importedCss || []) target.add(css);
|
|
5743
|
+
}
|
|
5744
|
+
for (const css of secondaryCss) if (!primaryCss.has(css)) allCssAssets.delete(css);
|
|
5745
|
+
}
|
|
4000
5746
|
if (!disableAssetsAnalyze) {
|
|
4001
5747
|
const exposesModules = Object.keys(mfOptions.exposes).map((item) => mfOptions.exposes[item].import);
|
|
4002
5748
|
processModuleAssets(bundle, filesMap, (modulePath) => {
|
|
@@ -4008,7 +5754,7 @@ const Manifest = () => {
|
|
|
4008
5754
|
stripKnownJsExtensions: true
|
|
4009
5755
|
});
|
|
4010
5756
|
const fileToShareKey = await buildFileToShareKeyMap(getUsedShares(), this.resolve.bind(this));
|
|
4011
|
-
processModuleAssets(bundle, filesMap, (modulePath) => fileToShareKey.get(modulePath));
|
|
5757
|
+
processModuleAssets(Object.fromEntries(Object.entries(bundle).filter(([, file]) => !isTreeShakingProviderChunk(file))), filesMap, (modulePath) => fileToShareKey.get(modulePath));
|
|
4012
5758
|
if (mfOptions.bundleAllCSS) addCssAssetsToAllExports(filesMap, allCssAssets);
|
|
4013
5759
|
filesMap = deduplicateAssets(filesMap);
|
|
4014
5760
|
}
|
|
@@ -4052,22 +5798,37 @@ const Manifest = () => {
|
|
|
4052
5798
|
path: "",
|
|
4053
5799
|
type: "var"
|
|
4054
5800
|
} : void 0;
|
|
4055
|
-
const remotes = Array.from(Object.entries(getUsedRemotesMap())).flatMap(([remoteKey, modules]) =>
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
5801
|
+
const remotes = Array.from(Object.entries(getUsedRemotesMap())).flatMap(([remoteKey, modules]) => {
|
|
5802
|
+
const remote = options.remotes[remoteKey];
|
|
5803
|
+
return Array.from(modules).map((moduleKey) => ({
|
|
5804
|
+
federationContainerName: getRemoteContainerName(remoteKey, remote),
|
|
5805
|
+
moduleName: moduleKey.replace(remoteKey, "").replace("/", ""),
|
|
5806
|
+
alias: remoteKey,
|
|
5807
|
+
entry: "*"
|
|
5808
|
+
}));
|
|
5809
|
+
});
|
|
4061
5810
|
const shared = Array.from(getUsedShares()).flatMap((shareKey) => {
|
|
4062
5811
|
const shareItem = getNormalizeShareItem(shareKey);
|
|
4063
5812
|
if (!shareItem) return [];
|
|
4064
5813
|
const assets = preloadMap[shareKey] || (_command === "serve" && resolvedRemoteEntryFile ? createRemoteEntryAssetMap(resolvedRemoteEntryFile) : createEmptyAssetMap());
|
|
5814
|
+
const treeShakingUsage = getTreeShakingExportUsage(shareKey, shareItem, shareItem.name);
|
|
5815
|
+
const treeShakingUsedExports = treeShakingUsage?.kind === "exports" ? treeShakingUsage.usedExports : [];
|
|
5816
|
+
const treeShakingStatus = treeShakingUsage?.kind === "full" ? 0 : 1;
|
|
4065
5817
|
return [{
|
|
4066
5818
|
id: `${name}:${shareKey}`,
|
|
4067
5819
|
name: shareKey,
|
|
4068
5820
|
version: shareItem.version,
|
|
4069
5821
|
singleton: shareItem.shareConfig.singleton,
|
|
4070
5822
|
requiredVersion: shareItem.shareConfig.requiredVersion,
|
|
5823
|
+
...shareItem.shareConfig.treeShaking ? {
|
|
5824
|
+
usedExports: treeShakingUsedExports,
|
|
5825
|
+
referenceExports: treeShakingUsedExports,
|
|
5826
|
+
treeShaking: {
|
|
5827
|
+
mode: shareItem.shareConfig.treeShaking.mode,
|
|
5828
|
+
...treeShakingUsage?.kind === "exports" ? { usedExports: treeShakingUsedExports } : {},
|
|
5829
|
+
status: treeShakingStatus
|
|
5830
|
+
}
|
|
5831
|
+
} : {},
|
|
4071
5832
|
assets: {
|
|
4072
5833
|
js: {
|
|
4073
5834
|
async: assets.js.async,
|
|
@@ -4107,7 +5868,8 @@ const Manifest = () => {
|
|
|
4107
5868
|
type: "app",
|
|
4108
5869
|
buildInfo: {
|
|
4109
5870
|
buildVersion: getBuildVersion(),
|
|
4110
|
-
buildName: name
|
|
5871
|
+
buildName: name,
|
|
5872
|
+
...getTreeShakingBuildInfo(options)
|
|
4111
5873
|
},
|
|
4112
5874
|
remoteEntry,
|
|
4113
5875
|
ssrRemoteEntry,
|
|
@@ -4152,32 +5914,41 @@ function getStatsFileName(manifestFileName) {
|
|
|
4152
5914
|
const fileExt = parsed.ext || ".json";
|
|
4153
5915
|
const baseName = parsed.ext ? parsed.name : parsed.base;
|
|
4154
5916
|
const fileName = `${baseName === "mf-manifest" ? "mf" : baseName}-stats${fileExt}`;
|
|
4155
|
-
return parsed.dir ? path$1.join(parsed.dir, fileName) : fileName;
|
|
5917
|
+
return parsed.dir ? normalizePathForImport(path$1.join(parsed.dir, fileName)) : fileName;
|
|
4156
5918
|
}
|
|
4157
5919
|
//#endregion
|
|
4158
5920
|
//#region src/plugins/pluginModuleParseEnd.ts
|
|
4159
5921
|
let _resolve = null;
|
|
4160
5922
|
let _parseTimeout = null;
|
|
5923
|
+
let _settleTimeout = null;
|
|
4161
5924
|
let parsePromise = Promise.resolve(1);
|
|
4162
|
-
let exposesParseEnd = false;
|
|
4163
|
-
let expectsExposesParseEnd = false;
|
|
4164
5925
|
let parseStartSet = /* @__PURE__ */ new Set();
|
|
4165
5926
|
let parseEndSet = /* @__PURE__ */ new Set();
|
|
5927
|
+
let lastLoadedModule = "";
|
|
5928
|
+
let lastParsedModule = "";
|
|
4166
5929
|
function clearParseTimeout() {
|
|
4167
5930
|
if (_parseTimeout) {
|
|
4168
5931
|
clearTimeout(_parseTimeout);
|
|
4169
5932
|
_parseTimeout = null;
|
|
4170
5933
|
}
|
|
4171
5934
|
}
|
|
5935
|
+
function clearSettleTimeout() {
|
|
5936
|
+
if (_settleTimeout) {
|
|
5937
|
+
clearTimeout(_settleTimeout);
|
|
5938
|
+
_settleTimeout = null;
|
|
5939
|
+
}
|
|
5940
|
+
}
|
|
4172
5941
|
function resetParseState() {
|
|
4173
5942
|
clearParseTimeout();
|
|
4174
|
-
|
|
4175
|
-
expectsExposesParseEnd = false;
|
|
5943
|
+
clearSettleTimeout();
|
|
4176
5944
|
parseStartSet = /* @__PURE__ */ new Set();
|
|
4177
5945
|
parseEndSet = /* @__PURE__ */ new Set();
|
|
5946
|
+
lastLoadedModule = "";
|
|
5947
|
+
lastParsedModule = "";
|
|
4178
5948
|
parsePromise = new Promise((resolve) => {
|
|
4179
5949
|
_resolve = (v) => {
|
|
4180
5950
|
clearParseTimeout();
|
|
5951
|
+
clearSettleTimeout();
|
|
4181
5952
|
resolve(v);
|
|
4182
5953
|
};
|
|
4183
5954
|
});
|
|
@@ -4191,10 +5962,18 @@ function setParseTimeout(timeout) {
|
|
|
4191
5962
|
function resetIdleTimeout(timeout) {
|
|
4192
5963
|
clearParseTimeout();
|
|
4193
5964
|
_parseTimeout = setTimeout(() => {
|
|
4194
|
-
|
|
5965
|
+
const pendingModules = Array.from(parseStartSet).filter((moduleId) => !parseEndSet.has(moduleId));
|
|
5966
|
+
mfWarn(`moduleParseIdleTimeout: no module activity for ${timeout}s, forcing resolve. Some shared/remote dependencies may be missing. Consider increasing moduleParseIdleTimeout. Tracked modules: ${parseEndSet.size}/${parseStartSet.size}.` + (lastLoadedModule ? ` Last loaded: ${lastLoadedModule}.` : "") + (lastParsedModule ? ` Last parsed: ${lastParsedModule}.` : "") + (pendingModules.length ? ` Pending modules: ${pendingModules.slice(0, 10).join(", ")}` : ""));
|
|
4195
5967
|
_resolve?.(1);
|
|
4196
5968
|
}, timeout * 1e3);
|
|
4197
5969
|
}
|
|
5970
|
+
function scheduleParseCompletionCheck() {
|
|
5971
|
+
clearSettleTimeout();
|
|
5972
|
+
_settleTimeout = setTimeout(() => {
|
|
5973
|
+
_settleTimeout = null;
|
|
5974
|
+
if (parseStartSet.size > 0 && Array.from(parseStartSet).every((moduleId) => parseEndSet.has(moduleId))) _resolve?.(1);
|
|
5975
|
+
}, 10);
|
|
5976
|
+
}
|
|
4198
5977
|
function pluginModuleParseEnd_default(excludeFn, options) {
|
|
4199
5978
|
const idleTimeout = options.moduleParseIdleTimeout ?? options.moduleParseTimeout;
|
|
4200
5979
|
return [
|
|
@@ -4209,14 +5988,20 @@ function pluginModuleParseEnd_default(excludeFn, options) {
|
|
|
4209
5988
|
enforce: "pre",
|
|
4210
5989
|
name: "parseStart",
|
|
4211
5990
|
apply: "build",
|
|
4212
|
-
buildStart() {
|
|
5991
|
+
async buildStart() {
|
|
4213
5992
|
resetParseState();
|
|
4214
5993
|
if (idleTimeout) resetIdleTimeout(idleTimeout);
|
|
4215
|
-
else setParseTimeout(options.moduleParseTimeout);
|
|
5994
|
+
else if (options.moduleParseTimeout) setParseTimeout(options.moduleParseTimeout);
|
|
5995
|
+
for (const importSource of options.exposedModuleImports || []) {
|
|
5996
|
+
const resolved = await this.resolve(importSource);
|
|
5997
|
+
if (resolved && !resolved.external && !excludeFn(resolved.id)) parseStartSet.add(resolved.id);
|
|
5998
|
+
}
|
|
4216
5999
|
},
|
|
4217
6000
|
load(id) {
|
|
6001
|
+
lastLoadedModule = id;
|
|
4218
6002
|
if (excludeFn(id)) return;
|
|
4219
|
-
|
|
6003
|
+
clearSettleTimeout();
|
|
6004
|
+
if (idleTimeout) resetIdleTimeout(idleTimeout);
|
|
4220
6005
|
parseStartSet.add(id);
|
|
4221
6006
|
}
|
|
4222
6007
|
},
|
|
@@ -4225,12 +6010,18 @@ function pluginModuleParseEnd_default(excludeFn, options) {
|
|
|
4225
6010
|
name: "parseEnd",
|
|
4226
6011
|
apply: "build",
|
|
4227
6012
|
moduleParsed(module) {
|
|
6013
|
+
clearSettleTimeout();
|
|
4228
6014
|
const id = module.id;
|
|
4229
|
-
|
|
6015
|
+
lastParsedModule = id;
|
|
4230
6016
|
if (idleTimeout) resetIdleTimeout(idleTimeout);
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
6017
|
+
const parsedModule = module;
|
|
6018
|
+
const addPendingResolutions = (resolutions) => {
|
|
6019
|
+
for (const resolution of resolutions || []) if (!resolution.external && !excludeFn(resolution.id)) parseStartSet.add(resolution.id);
|
|
6020
|
+
};
|
|
6021
|
+
addPendingResolutions(parsedModule.importedIdResolutions);
|
|
6022
|
+
addPendingResolutions(parsedModule.dynamicallyImportedIdResolutions);
|
|
6023
|
+
if (!excludeFn(id)) parseEndSet.add(id);
|
|
6024
|
+
scheduleParseCompletionCheck();
|
|
4234
6025
|
},
|
|
4235
6026
|
buildEnd() {
|
|
4236
6027
|
_resolve?.(1);
|
|
@@ -4249,6 +6040,9 @@ function resolveDevHashEntryFileName(fileName) {
|
|
|
4249
6040
|
function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposesId }) {
|
|
4250
6041
|
let viteConfig, _command, root;
|
|
4251
6042
|
let exposeRemoteDependencies = {};
|
|
6043
|
+
let exposeRemoteDependenciesDirty = true;
|
|
6044
|
+
let refreshPromise;
|
|
6045
|
+
let dependencyInvalidationVersion = 0;
|
|
4252
6046
|
function isRemoteImport(source) {
|
|
4253
6047
|
return Object.keys(options.remotes).some((name) => source === name || source.startsWith(name + "/"));
|
|
4254
6048
|
}
|
|
@@ -4287,12 +6081,26 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
4287
6081
|
return Array.from(dependencies).sort();
|
|
4288
6082
|
}
|
|
4289
6083
|
async function refreshExposeRemoteDependencies(ctx) {
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
const
|
|
4293
|
-
|
|
6084
|
+
if (!exposeRemoteDependenciesDirty) return;
|
|
6085
|
+
if (!refreshPromise) {
|
|
6086
|
+
const refreshVersion = dependencyInvalidationVersion;
|
|
6087
|
+
refreshPromise = (async () => {
|
|
6088
|
+
const next = {};
|
|
6089
|
+
for (const [exposeKey, expose] of Object.entries(options.exposes)) {
|
|
6090
|
+
const resolved = await ctx.resolve(expose.import);
|
|
6091
|
+
next[exposeKey] = resolved?.id ? await collectRemoteDependencies(ctx, resolved.id) : [];
|
|
6092
|
+
}
|
|
6093
|
+
exposeRemoteDependencies = next;
|
|
6094
|
+
if (refreshVersion === dependencyInvalidationVersion) exposeRemoteDependenciesDirty = false;
|
|
6095
|
+
})().finally(() => {
|
|
6096
|
+
refreshPromise = void 0;
|
|
6097
|
+
});
|
|
4294
6098
|
}
|
|
4295
|
-
|
|
6099
|
+
await refreshPromise;
|
|
6100
|
+
}
|
|
6101
|
+
function invalidateExposeRemoteDependencies() {
|
|
6102
|
+
exposeRemoteDependenciesDirty = true;
|
|
6103
|
+
dependencyInvalidationVersion += 1;
|
|
4296
6104
|
}
|
|
4297
6105
|
return {
|
|
4298
6106
|
name: "proxyRemoteEntry",
|
|
@@ -4315,6 +6123,12 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
4315
6123
|
});
|
|
4316
6124
|
}
|
|
4317
6125
|
},
|
|
6126
|
+
watchChange() {
|
|
6127
|
+
invalidateExposeRemoteDependencies();
|
|
6128
|
+
},
|
|
6129
|
+
handleHotUpdate() {
|
|
6130
|
+
invalidateExposeRemoteDependencies();
|
|
6131
|
+
},
|
|
4318
6132
|
async resolveId(id, importer) {
|
|
4319
6133
|
if (id === remoteEntryId) return remoteEntryId;
|
|
4320
6134
|
if (id === virtualExposesId) return virtualExposesId;
|
|
@@ -4325,16 +6139,22 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
4325
6139
|
if (resolved) return resolved;
|
|
4326
6140
|
}
|
|
4327
6141
|
},
|
|
4328
|
-
load(id) {
|
|
6142
|
+
async load(id) {
|
|
4329
6143
|
if (id === remoteEntryId) return parsePromise.then((_) => generateRemoteEntry(options, virtualExposesId, _command));
|
|
4330
|
-
if (id === virtualExposesId)
|
|
6144
|
+
if (id === virtualExposesId) {
|
|
6145
|
+
await refreshExposeRemoteDependencies(this);
|
|
6146
|
+
return generateExposes(options, exposeRemoteDependencies, _command);
|
|
6147
|
+
}
|
|
4331
6148
|
if (_command === "serve" && id.includes(getHostAutoInitPath())) return id;
|
|
4332
6149
|
},
|
|
4333
|
-
transform(code, id) {
|
|
4334
|
-
return mapCodeToCodeWithSourcemap((() => {
|
|
6150
|
+
async transform(code, id) {
|
|
6151
|
+
return mapCodeToCodeWithSourcemap(await (async () => {
|
|
4335
6152
|
if (!filterId(id)) return;
|
|
4336
6153
|
if (id.includes(remoteEntryId)) return parsePromise.then((_) => generateRemoteEntry(options, virtualExposesId, _command));
|
|
4337
|
-
if (id === virtualExposesId)
|
|
6154
|
+
if (id === virtualExposesId) {
|
|
6155
|
+
await refreshExposeRemoteDependencies(this);
|
|
6156
|
+
return generateExposes(options, exposeRemoteDependencies, _command);
|
|
6157
|
+
}
|
|
4338
6158
|
if (id.includes(getHostAutoInitPath())) {
|
|
4339
6159
|
if (_command === "serve") {
|
|
4340
6160
|
const host = typeof viteConfig.server?.host === "string" && viteConfig.server.host !== "0.0.0.0" ? viteConfig.server.host : "localhost";
|
|
@@ -4409,6 +6229,9 @@ function resolveRemoteConsumer(ctx, hasMultiEnvironment) {
|
|
|
4409
6229
|
function isNodeModulesImporter(importer) {
|
|
4410
6230
|
return importer?.includes("/node_modules/") || importer?.includes("\\node_modules\\");
|
|
4411
6231
|
}
|
|
6232
|
+
function escapeRegExp(value) {
|
|
6233
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6234
|
+
}
|
|
4412
6235
|
function appendAlias(config, alias) {
|
|
4413
6236
|
config.resolve ??= {};
|
|
4414
6237
|
const existingAlias = config.resolve.alias;
|
|
@@ -4451,10 +6274,9 @@ function pluginProxyRemotes_default(options) {
|
|
|
4451
6274
|
config(config, { command: _command }) {
|
|
4452
6275
|
command = _command;
|
|
4453
6276
|
root = config.root || process.cwd();
|
|
4454
|
-
Object.keys(remotes).forEach((
|
|
4455
|
-
const remote = remotes[key];
|
|
6277
|
+
Object.keys(remotes).forEach((remoteAlias) => {
|
|
4456
6278
|
appendAlias(config, {
|
|
4457
|
-
find: new RegExp(`^(${
|
|
6279
|
+
find: new RegExp(`^(${escapeRegExp(remoteAlias)}(\/.*|$))`),
|
|
4458
6280
|
replacement: "$1"
|
|
4459
6281
|
});
|
|
4460
6282
|
});
|
|
@@ -4465,9 +6287,9 @@ function pluginProxyRemotes_default(options) {
|
|
|
4465
6287
|
},
|
|
4466
6288
|
resolveId(source, importer) {
|
|
4467
6289
|
if (!filterId(source)) return;
|
|
4468
|
-
for (const
|
|
4469
|
-
if (source !==
|
|
4470
|
-
return resolveRemoteId(this, source, importer,
|
|
6290
|
+
for (const remoteAlias of Object.keys(remotes)) {
|
|
6291
|
+
if (source !== remoteAlias && !source.startsWith(`${remoteAlias}/`)) continue;
|
|
6292
|
+
return resolveRemoteId(this, source, importer, remoteAlias);
|
|
4471
6293
|
}
|
|
4472
6294
|
}
|
|
4473
6295
|
};
|
|
@@ -4625,6 +6447,36 @@ function proxySharedModule(options) {
|
|
|
4625
6447
|
const savePrebuild = new PromiseStore();
|
|
4626
6448
|
let devServer;
|
|
4627
6449
|
const materializedLoadShareSources = /* @__PURE__ */ new Set();
|
|
6450
|
+
const emittedTreeShakingProviders = /* @__PURE__ */ new Set();
|
|
6451
|
+
const normalizeTreeShakingOutputPath = (value) => {
|
|
6452
|
+
const normalized = normalizePathForImport(value);
|
|
6453
|
+
if (path$1.posix.isAbsolute(normalized) || /^[A-Za-z]:\//.test(normalized) || normalized.split("/").includes("..")) throw new Error(`Invalid treeShakingDir "${value}": absolute paths and parent segments are not allowed.`);
|
|
6454
|
+
let start = normalized.startsWith("./") ? 2 : 0;
|
|
6455
|
+
let end = normalized.length;
|
|
6456
|
+
while (start < end && normalized.charCodeAt(start) === 47) start++;
|
|
6457
|
+
while (end > start && normalized.charCodeAt(end - 1) === 47) end--;
|
|
6458
|
+
return normalized.slice(start, end);
|
|
6459
|
+
};
|
|
6460
|
+
const getTreeShakingProviderFileName = (pkg, shareItem) => {
|
|
6461
|
+
if (!shareItem.shareConfig.treeShaking) return void 0;
|
|
6462
|
+
const normalizedOptions = getNormalizeModuleFederationOptions();
|
|
6463
|
+
const outputDir = normalizedOptions.treeShakingDir ? normalizeTreeShakingOutputPath(normalizedOptions.treeShakingDir) : void 0;
|
|
6464
|
+
const fileName = outputDir ? path$1.posix.join(outputDir, `${getTreeShakingSharedProviderName(pkg)}.js`) : void 0;
|
|
6465
|
+
if (!fileName) return void 0;
|
|
6466
|
+
return fileName;
|
|
6467
|
+
};
|
|
6468
|
+
const emitTreeShakingProvider = (context, pkg, shareItem) => {
|
|
6469
|
+
if (_command !== "build" || emittedTreeShakingProviders.has(pkg)) return;
|
|
6470
|
+
if (!hasTreeShakingSharedProvider(pkg, shareItem)) return;
|
|
6471
|
+
const fileName = getTreeShakingProviderFileName(pkg, shareItem);
|
|
6472
|
+
context.emitFile({
|
|
6473
|
+
type: "chunk",
|
|
6474
|
+
id: getTreeShakingSharedProviderImportId(pkg),
|
|
6475
|
+
name: getTreeShakingSharedProviderName(pkg),
|
|
6476
|
+
...fileName ? { fileName } : {}
|
|
6477
|
+
});
|
|
6478
|
+
emittedTreeShakingProviders.add(pkg);
|
|
6479
|
+
};
|
|
4628
6480
|
return [
|
|
4629
6481
|
{
|
|
4630
6482
|
name: "generateLocalSharedImportMap",
|
|
@@ -4640,7 +6492,16 @@ function proxySharedModule(options) {
|
|
|
4640
6492
|
if (source === getLocalSharedImportMapPath()) return getResolvedLocalSharedImportMapId();
|
|
4641
6493
|
},
|
|
4642
6494
|
load(id) {
|
|
4643
|
-
if (id === getResolvedLocalSharedImportMapId()) return parsePromise.then((_) =>
|
|
6495
|
+
if (id === getResolvedLocalSharedImportMapId()) return parsePromise.then((_) => {
|
|
6496
|
+
refreshTreeShakingModules();
|
|
6497
|
+
const providerPackages = new Set([...Object.keys(shared).filter((pkg) => !pkg.endsWith("/")), ...getUsedShares()]);
|
|
6498
|
+
for (const pkg of providerPackages) {
|
|
6499
|
+
const sharedKey = findSharedKeyForSource(pkg, shared);
|
|
6500
|
+
const shareItem = shared[pkg] || (sharedKey ? shared[sharedKey] : void 0);
|
|
6501
|
+
if (shareItem) emitTreeShakingProvider(this, pkg, shareItem);
|
|
6502
|
+
}
|
|
6503
|
+
return generateLocalSharedImportMap();
|
|
6504
|
+
});
|
|
4644
6505
|
},
|
|
4645
6506
|
closeBundle() {
|
|
4646
6507
|
if (devServer) return;
|
|
@@ -4652,6 +6513,9 @@ function proxySharedModule(options) {
|
|
|
4652
6513
|
enforce: "post",
|
|
4653
6514
|
config(config, { command }) {
|
|
4654
6515
|
setPackageDetectionCwd(config.root || process.cwd());
|
|
6516
|
+
setTreeShakingBuildMode(command === "build");
|
|
6517
|
+
resetTreeShakingExports();
|
|
6518
|
+
emittedTreeShakingProviders.clear();
|
|
4655
6519
|
const isVinext = hasPackageDependency("vinext");
|
|
4656
6520
|
const isAstro = hasPackageDependency("astro");
|
|
4657
6521
|
const isRolldown = getIsRolldown(this);
|
|
@@ -4675,12 +6539,62 @@ function proxySharedModule(options) {
|
|
|
4675
6539
|
});
|
|
4676
6540
|
writeLocalSharedImportMap();
|
|
4677
6541
|
refreshHostAutoInit();
|
|
6542
|
+
},
|
|
6543
|
+
buildStart() {
|
|
6544
|
+
if (_command !== "build") return;
|
|
6545
|
+
resetTreeShakingExports();
|
|
6546
|
+
emittedTreeShakingProviders.clear();
|
|
6547
|
+
refreshTreeShakingModules();
|
|
6548
|
+
},
|
|
6549
|
+
shouldTransformCachedModule() {
|
|
6550
|
+
return _command === "build" && Object.values(shared).some((share) => !!share.shareConfig.treeShaking);
|
|
6551
|
+
},
|
|
6552
|
+
transform(code, id) {
|
|
6553
|
+
if (_command !== "build" || !Object.keys(shared).some((key) => shared[key].shareConfig.treeShaking)) return;
|
|
6554
|
+
collectTreeShakingImports(code, id, shared, findSharedKeyForSource, recordTreeShakingExports, markTreeShakingPackageUnsafe);
|
|
6555
|
+
refreshTreeShakingModules();
|
|
6556
|
+
}
|
|
6557
|
+
},
|
|
6558
|
+
{
|
|
6559
|
+
name: "proxyPreBuildShared:tree-shaking-graph",
|
|
6560
|
+
enforce: "pre",
|
|
6561
|
+
apply: "build",
|
|
6562
|
+
async resolveId(source, importer, resolveOptions) {
|
|
6563
|
+
const sourceToken = getTreeShakingGraphToken(source);
|
|
6564
|
+
const importerToken = getTreeShakingGraphToken(importer);
|
|
6565
|
+
const token = sourceToken || importerToken;
|
|
6566
|
+
if (!token) return;
|
|
6567
|
+
const cleanSource = normalizePathForImport(stripTreeShakingGraphQuery(source));
|
|
6568
|
+
const cleanImporter = importer ? normalizePathForImport(stripTreeShakingGraphQuery(importer)) : void 0;
|
|
6569
|
+
if (!sourceToken && importerToken) {
|
|
6570
|
+
const nestedSharedKey = findSharedKeyForSource(cleanSource, shared);
|
|
6571
|
+
if (nestedSharedKey && getPackageName(nestedSharedKey) !== getPackageName(importerToken)) return this.resolve(cleanSource, cleanImporter, {
|
|
6572
|
+
...resolveOptions,
|
|
6573
|
+
skipSelf: true
|
|
6574
|
+
});
|
|
6575
|
+
}
|
|
6576
|
+
const projectResolvedSource = sourceToken ? tryResolveFromProjectRoot(cleanSource) || cleanSource : cleanSource;
|
|
6577
|
+
const resolved = await this.resolve(projectResolvedSource, cleanImporter, {
|
|
6578
|
+
...resolveOptions,
|
|
6579
|
+
custom: {
|
|
6580
|
+
...resolveOptions.custom,
|
|
6581
|
+
__mfTreeShakingGraph: true
|
|
6582
|
+
},
|
|
6583
|
+
skipSelf: true
|
|
6584
|
+
});
|
|
6585
|
+
if (!resolved || resolved.external) return resolved;
|
|
6586
|
+
if (resolved.id.startsWith("\0")) return resolved;
|
|
6587
|
+
return {
|
|
6588
|
+
...resolved,
|
|
6589
|
+
id: addTreeShakingGraphQuery(normalizePathForImport(resolved.id), token)
|
|
6590
|
+
};
|
|
4678
6591
|
}
|
|
4679
6592
|
},
|
|
4680
6593
|
{
|
|
4681
6594
|
name: "proxyPreBuildShared:resolve-shared-loadShare",
|
|
4682
6595
|
enforce: "pre",
|
|
4683
|
-
async resolveId(source, importer) {
|
|
6596
|
+
async resolveId(source, importer, resolveOptions) {
|
|
6597
|
+
if (resolveOptions.custom?.__mfTreeShakingGraph) return;
|
|
4684
6598
|
function shouldSkipTaggedImporterProxy(sharedKey, tag) {
|
|
4685
6599
|
if (!importer?.includes(tag)) return false;
|
|
4686
6600
|
const taggedModule = VirtualModule.findModule(tag, importer);
|
|
@@ -4977,50 +6891,6 @@ function collectFromRegex(code, isRemoteImport) {
|
|
|
4977
6891
|
}
|
|
4978
6892
|
return result.length > 0 ? result : void 0;
|
|
4979
6893
|
}
|
|
4980
|
-
function createCodePositionMap(code) {
|
|
4981
|
-
const positions = Array(code.length).fill(true);
|
|
4982
|
-
function mask(start, end) {
|
|
4983
|
-
for (let i = start; i < end; i++) positions[i] = false;
|
|
4984
|
-
}
|
|
4985
|
-
for (let i = 0; i < code.length;) {
|
|
4986
|
-
const char = code[i];
|
|
4987
|
-
const next = code[i + 1];
|
|
4988
|
-
if (char === "/" && next === "/") {
|
|
4989
|
-
const start = i;
|
|
4990
|
-
i += 2;
|
|
4991
|
-
while (i < code.length && code[i] !== "\n" && code[i] !== "\r") i++;
|
|
4992
|
-
mask(start, i);
|
|
4993
|
-
continue;
|
|
4994
|
-
}
|
|
4995
|
-
if (char === "/" && next === "*") {
|
|
4996
|
-
const start = i;
|
|
4997
|
-
i += 2;
|
|
4998
|
-
while (i < code.length && !(code[i] === "*" && code[i + 1] === "/")) i++;
|
|
4999
|
-
i = Math.min(code.length, i + 2);
|
|
5000
|
-
mask(start, i);
|
|
5001
|
-
continue;
|
|
5002
|
-
}
|
|
5003
|
-
if (char === "\"" || char === "'" || char === "`") {
|
|
5004
|
-
const quote = char;
|
|
5005
|
-
const start = i++;
|
|
5006
|
-
while (i < code.length) {
|
|
5007
|
-
if (code[i] === "\\") {
|
|
5008
|
-
i += 2;
|
|
5009
|
-
continue;
|
|
5010
|
-
}
|
|
5011
|
-
if (code[i] === quote) {
|
|
5012
|
-
i++;
|
|
5013
|
-
break;
|
|
5014
|
-
}
|
|
5015
|
-
i++;
|
|
5016
|
-
}
|
|
5017
|
-
mask(start, i);
|
|
5018
|
-
continue;
|
|
5019
|
-
}
|
|
5020
|
-
i++;
|
|
5021
|
-
}
|
|
5022
|
-
return positions;
|
|
5023
|
-
}
|
|
5024
6894
|
function pluginRemoteNamedExports(options) {
|
|
5025
6895
|
const remoteNames = Object.keys(options.remotes);
|
|
5026
6896
|
const isNodeModulesId = (id) => id.includes("/node_modules/") || id.includes("\\node_modules\\");
|
|
@@ -5637,15 +7507,12 @@ function appendResolveAlias(config, alias) {
|
|
|
5637
7507
|
replacement
|
|
5638
7508
|
})), alias];
|
|
5639
7509
|
}
|
|
5640
|
-
function hasImportFalseShared(options) {
|
|
5641
|
-
return Object.values(options.shared ?? {}).some((share) => share?.shareConfig?.import === false);
|
|
5642
|
-
}
|
|
5643
7510
|
function getRuntimeHelpersImplementation(runtimeImplementation) {
|
|
5644
7511
|
const indexEntryMatch = runtimeImplementation.match(/^(.*[\\/])index(\.[cm]?js)$/);
|
|
5645
|
-
if (indexEntryMatch) return `${indexEntryMatch[1]}helpers${indexEntryMatch[2]}
|
|
7512
|
+
if (indexEntryMatch) return normalizePathForImport(`${indexEntryMatch[1]}helpers${indexEntryMatch[2]}`);
|
|
5646
7513
|
const extension = path$1.extname(runtimeImplementation);
|
|
5647
|
-
if (extension) return path$1.join(path$1.dirname(runtimeImplementation), `helpers${extension}`);
|
|
5648
|
-
if (path$1.isAbsolute(runtimeImplementation) || runtimeImplementation.startsWith(".")) return path$1.join(runtimeImplementation, "helpers");
|
|
7514
|
+
if (extension) return normalizePathForImport(path$1.join(path$1.dirname(runtimeImplementation), `helpers${extension}`));
|
|
7515
|
+
if (path$1.isAbsolute(runtimeImplementation) || runtimeImplementation.startsWith(".")) return normalizePathForImport(path$1.join(runtimeImplementation, "helpers"));
|
|
5649
7516
|
return `${runtimeImplementation.replace(/\/$/, "")}/helpers`;
|
|
5650
7517
|
}
|
|
5651
7518
|
const UNSAFE_JS_SOURCE_CHAR_MAP = {
|
|
@@ -5828,7 +7695,7 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
5828
7695
|
const optimizeDeps = config.optimizeDeps ??= {};
|
|
5829
7696
|
optimizeDeps.include ??= [];
|
|
5830
7697
|
optimizeDeps.exclude ??= [];
|
|
5831
|
-
const shouldBypassOptimizeDep = isLitShare(key)
|
|
7698
|
+
const shouldBypassOptimizeDep = isLitShare(key);
|
|
5832
7699
|
if (optimizeDeps.include.includes(key)) optimizeDeps.exclude = optimizeDeps.exclude.filter((dep) => dep !== key);
|
|
5833
7700
|
else if (shouldBypassOptimizeDep) optimizeDeps.exclude.push(key);
|
|
5834
7701
|
else optimizeDeps.include.push(key);
|
|
@@ -5883,13 +7750,14 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
5883
7750
|
const SSR_ONLY_PLUGINS = new Set(["@module-federation/vite/ssrEntryLoader"]);
|
|
5884
7751
|
function loadPluginDts(options) {
|
|
5885
7752
|
if (options.dts === false) return [];
|
|
5886
|
-
return [import("./pluginDts-
|
|
7753
|
+
return [import("./pluginDts-CGDIZCsD.js").then((n) => n.n).then(({ default: pluginDts }) => pluginDts(options))];
|
|
5887
7754
|
}
|
|
5888
7755
|
function federation(mfUserOptions) {
|
|
5889
7756
|
if (isTestEnv()) return [];
|
|
5890
7757
|
const options = normalizeModuleFederationOptions(mfUserOptions);
|
|
5891
7758
|
const isVinext = hasPackageDependency("vinext");
|
|
5892
7759
|
const { name, shared, filename, hostInitInjectLocation } = options;
|
|
7760
|
+
const hasTreeShakingShared = Object.values(shared).some((share) => !!share.shareConfig.treeShaking);
|
|
5893
7761
|
if (!name) throw createModuleFederationError("name is required");
|
|
5894
7762
|
const remoteEntryId = getRemoteEntryId(options);
|
|
5895
7763
|
const virtualExposesId = getVirtualExposesId(options);
|
|
@@ -5995,11 +7863,11 @@ function federation(mfUserOptions) {
|
|
|
5995
7863
|
pluginProxyRemotes_default(options),
|
|
5996
7864
|
pluginRemoteNamedExports(options),
|
|
5997
7865
|
...pluginModuleParseEnd_default((id) => {
|
|
5998
|
-
return id.includes(getHostAutoInitImportId()) || id.includes(remoteEntryId) || id.includes(virtualExposesId) || id.includes(getLocalSharedImportMapPath()) || id.includes("__loadShare__") || id.includes("__prebuild__");
|
|
7866
|
+
return id.includes(getHostAutoInitImportId()) || id.includes(remoteEntryId) || id.includes(virtualExposesId) || id.includes(getLocalSharedImportMapPath()) || id.includes("__loadShare__") || id.includes("__prebuild__") || id.includes("__treeShakingProvider__") || id.includes("__mf_tree_shaking_graph__");
|
|
5999
7867
|
}, {
|
|
6000
7868
|
moduleParseTimeout: options.moduleParseTimeout,
|
|
6001
7869
|
moduleParseIdleTimeout: options.moduleParseIdleTimeout,
|
|
6002
|
-
|
|
7870
|
+
exposedModuleImports: Object.values(options.exposes).map((expose) => expose.import)
|
|
6003
7871
|
}),
|
|
6004
7872
|
...proxySharedModule({ shared }),
|
|
6005
7873
|
{
|
|
@@ -6021,7 +7889,8 @@ function federation(mfUserOptions) {
|
|
|
6021
7889
|
if (context.hostType === "js" && (hostFile === options.filename || hostFile.includes("hostInit") || hostFile.includes("virtualExposes") || hostFile.includes("localSharedImportMap"))) return [];
|
|
6022
7890
|
const hasFederationHtmlDeps = context.hostType === "html" && resolvedDeps.some((dep) => isFederationHtmlPreloadDependency(dep));
|
|
6023
7891
|
const hasFederationJsDeps = context.hostType === "js" && resolvedDeps.some((dep) => isFederationHtmlPreloadDependency(dep));
|
|
6024
|
-
|
|
7892
|
+
const treeShakingFallbackDeps = hasTreeShakingShared ? (dep) => dep.includes("__prebuild__") : () => false;
|
|
7893
|
+
return hasFederationHtmlDeps || hasFederationJsDeps ? resolvedDeps.filter((dep) => !isFederationHtmlPreloadDependency(dep, true) && !treeShakingFallbackDeps(dep)) : resolvedDeps.filter((dep) => !treeShakingFallbackDeps(dep));
|
|
6025
7894
|
}
|
|
6026
7895
|
};
|
|
6027
7896
|
}
|
|
@@ -6195,8 +8064,8 @@ function federation(mfUserOptions) {
|
|
|
6195
8064
|
config(config, { command: _command }) {
|
|
6196
8065
|
const isRolldown = getIsRolldown(this);
|
|
6197
8066
|
isSsrBuild = _command === "build" && config.build?.ssr === true;
|
|
6198
|
-
const
|
|
6199
|
-
if (
|
|
8067
|
+
const needsRuntimeHelpers = Object.keys(options.shared ?? {}).length > 0;
|
|
8068
|
+
if (needsRuntimeHelpers) appendResolveAlias(config, {
|
|
6200
8069
|
find: /^@module-federation\/runtime\/helpers$/,
|
|
6201
8070
|
replacement: getRuntimeHelpersImplementation(options.implementation)
|
|
6202
8071
|
});
|
|
@@ -6210,7 +8079,7 @@ function federation(mfUserOptions) {
|
|
|
6210
8079
|
config.optimizeDeps ||= {};
|
|
6211
8080
|
config.optimizeDeps.include ||= [];
|
|
6212
8081
|
config.optimizeDeps.include.push("@module-federation/runtime");
|
|
6213
|
-
if (
|
|
8082
|
+
if (needsRuntimeHelpers) config.optimizeDeps.include.push("@module-federation/runtime/helpers");
|
|
6214
8083
|
options.runtimePlugins.forEach((p) => {
|
|
6215
8084
|
const pluginPath = typeof p === "string" ? p : p[0];
|
|
6216
8085
|
if (SSR_ONLY_PLUGINS.has(pluginPath)) return;
|