@module-federation/vite 1.16.16 → 1.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -0
- package/lib/index.d.ts +12 -2
- package/lib/index.js +893 -104
- package/lib/{pluginDts-Bo95ELmX.js → pluginDts-BcvLBYP3.js} +67 -0
- 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-BcvLBYP3.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,257 @@ ${exportStatement}
|
|
|
928
939
|
`);
|
|
929
940
|
}
|
|
930
941
|
//#endregion
|
|
942
|
+
//#region src/utils/treeShaking.ts
|
|
943
|
+
/**
|
|
944
|
+
* Analysis is scoped by both the configured share key and the concrete module
|
|
945
|
+
* request. A prefix share such as `lodash/` may materialize separate wrappers
|
|
946
|
+
* for `lodash/get` and `lodash/debounce`; combining those export sets would
|
|
947
|
+
* generate invalid wrappers and defeat per-subpath tree shaking.
|
|
948
|
+
*/
|
|
949
|
+
const inferredTreeShakingUsage = /* @__PURE__ */ new Map();
|
|
950
|
+
let treeShakingBuildMode = false;
|
|
951
|
+
function setTreeShakingBuildMode(enabled) {
|
|
952
|
+
treeShakingBuildMode = enabled;
|
|
953
|
+
}
|
|
954
|
+
function resetTreeShakingExports() {
|
|
955
|
+
inferredTreeShakingUsage.clear();
|
|
956
|
+
}
|
|
957
|
+
function getOrCreateExportRecord(sharedKey, request) {
|
|
958
|
+
let byRequest = inferredTreeShakingUsage.get(sharedKey);
|
|
959
|
+
if (!byRequest) {
|
|
960
|
+
byRequest = /* @__PURE__ */ new Map();
|
|
961
|
+
inferredTreeShakingUsage.set(sharedKey, byRequest);
|
|
962
|
+
}
|
|
963
|
+
let record = byRequest.get(request);
|
|
964
|
+
if (!record) {
|
|
965
|
+
record = {
|
|
966
|
+
requiresFullBundle: false,
|
|
967
|
+
usedExports: /* @__PURE__ */ new Set()
|
|
968
|
+
};
|
|
969
|
+
byRequest.set(request, record);
|
|
970
|
+
}
|
|
971
|
+
return record;
|
|
972
|
+
}
|
|
973
|
+
function recordTreeShakingExports(sharedKey, exports, request = sharedKey) {
|
|
974
|
+
const record = getOrCreateExportRecord(sharedKey, request);
|
|
975
|
+
exports.forEach((name) => record.usedExports.add(name));
|
|
976
|
+
}
|
|
977
|
+
function markTreeShakingPackageUnsafe(sharedKey, request = sharedKey) {
|
|
978
|
+
getOrCreateExportRecord(sharedKey, request).requiresFullBundle = true;
|
|
979
|
+
}
|
|
980
|
+
function getExportRecords(sharedKey, request) {
|
|
981
|
+
if (sharedKey) {
|
|
982
|
+
const records = inferredTreeShakingUsage.get(sharedKey);
|
|
983
|
+
const wildcard = records?.get("*");
|
|
984
|
+
const exact = records?.get(request);
|
|
985
|
+
return [wildcard, exact === wildcard ? void 0 : exact].filter((record) => !!record);
|
|
986
|
+
}
|
|
987
|
+
const records = [];
|
|
988
|
+
inferredTreeShakingUsage.forEach((byRequest, configuredKey) => {
|
|
989
|
+
const wildcard = byRequest.get("*");
|
|
990
|
+
const exact = byRequest.get(request);
|
|
991
|
+
const keyBase = configuredKey.endsWith("/") ? configuredKey.slice(0, -1) : configuredKey;
|
|
992
|
+
const requestMatchesConfiguredKey = request === keyBase || request.startsWith(`${keyBase}/`);
|
|
993
|
+
if (wildcard && requestMatchesConfiguredKey) records.push(wildcard);
|
|
994
|
+
if (exact && exact !== wildcard) records.push(exact);
|
|
995
|
+
});
|
|
996
|
+
return records;
|
|
997
|
+
}
|
|
998
|
+
/**
|
|
999
|
+
* Return the analyzed requirement for one concrete shared request.
|
|
1000
|
+
*
|
|
1001
|
+
* Callers that know the configured share key should pass it explicitly. The
|
|
1002
|
+
* fallback lookup across keys keeps aliases/backwards-compatible callers
|
|
1003
|
+
* working, while still keeping each concrete request's exports isolated.
|
|
1004
|
+
*/
|
|
1005
|
+
function getTreeShakingExportUsage(request, shareItem, sharedKey) {
|
|
1006
|
+
const treeShaking = shareItem?.shareConfig.treeShaking;
|
|
1007
|
+
if (!treeShaking || !treeShakingBuildMode) return void 0;
|
|
1008
|
+
const records = getExportRecords(sharedKey, request);
|
|
1009
|
+
if (records.some((record) => record.requiresFullBundle)) return { kind: "full" };
|
|
1010
|
+
const configured = treeShaking.usedExports ?? [];
|
|
1011
|
+
const result = new Set(configured);
|
|
1012
|
+
records.forEach((record) => record.usedExports.forEach((name) => result.add(name)));
|
|
1013
|
+
if (result.size > 0) return {
|
|
1014
|
+
kind: "exports",
|
|
1015
|
+
usedExports: [...result].sort()
|
|
1016
|
+
};
|
|
1017
|
+
return records.length > 0 ? {
|
|
1018
|
+
kind: "exports",
|
|
1019
|
+
usedExports: []
|
|
1020
|
+
} : { kind: "unknown" };
|
|
1021
|
+
}
|
|
1022
|
+
function getModuleSource(node) {
|
|
1023
|
+
if (!node || typeof node !== "object") return void 0;
|
|
1024
|
+
const source = node;
|
|
1025
|
+
if (source.type === "Literal" && typeof source.value === "string") return source.value;
|
|
1026
|
+
if (source.type === "StringLiteral" && typeof source.value === "string") return source.value;
|
|
1027
|
+
if (source.type !== "TemplateLiteral") return void 0;
|
|
1028
|
+
const expressions = Array.isArray(source.expressions) ? source.expressions : [];
|
|
1029
|
+
const quasis = Array.isArray(source.quasis) ? source.quasis : [];
|
|
1030
|
+
if (expressions.length > 0 || quasis.length !== 1) return void 0;
|
|
1031
|
+
const value = quasis[0]?.value;
|
|
1032
|
+
return typeof value?.cooked === "string" ? value.cooked : typeof value?.raw === "string" ? value.raw : void 0;
|
|
1033
|
+
}
|
|
1034
|
+
function getExportedName(node) {
|
|
1035
|
+
if (!node || typeof node !== "object") return void 0;
|
|
1036
|
+
const exported = node;
|
|
1037
|
+
if (exported.type === "Identifier" && typeof exported.name === "string") return exported.name;
|
|
1038
|
+
if ((exported.type === "Literal" || exported.type === "StringLiteral") && typeof exported.value === "string") return exported.value;
|
|
1039
|
+
}
|
|
1040
|
+
function isTypeOnly(node) {
|
|
1041
|
+
return node.importKind === "type" || node.exportKind === "type";
|
|
1042
|
+
}
|
|
1043
|
+
function forEachAstNode(root, visit) {
|
|
1044
|
+
const stack = [root];
|
|
1045
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1046
|
+
while (stack.length > 0) {
|
|
1047
|
+
const value = stack.pop();
|
|
1048
|
+
if (!value || typeof value !== "object") continue;
|
|
1049
|
+
if (seen.has(value)) continue;
|
|
1050
|
+
seen.add(value);
|
|
1051
|
+
if (Array.isArray(value)) {
|
|
1052
|
+
for (let index = value.length - 1; index >= 0; index--) stack.push(value[index]);
|
|
1053
|
+
continue;
|
|
1054
|
+
}
|
|
1055
|
+
const node = value;
|
|
1056
|
+
if (typeof node.type === "string") visit(node);
|
|
1057
|
+
Object.entries(node).forEach(([key, child]) => {
|
|
1058
|
+
if (key !== "parent" && key !== "loc") stack.push(child);
|
|
1059
|
+
});
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
function collectImportDeclaration(node, source, record, markUnsafe) {
|
|
1063
|
+
if (isTypeOnly(node)) return;
|
|
1064
|
+
const specifiers = Array.isArray(node.specifiers) ? node.specifiers : [];
|
|
1065
|
+
if (specifiers.length === 0) {
|
|
1066
|
+
markUnsafe(source);
|
|
1067
|
+
return;
|
|
1068
|
+
}
|
|
1069
|
+
const names = [];
|
|
1070
|
+
for (const specifier of specifiers) {
|
|
1071
|
+
if (isTypeOnly(specifier)) continue;
|
|
1072
|
+
if (specifier.type === "ImportNamespaceSpecifier") {
|
|
1073
|
+
markUnsafe(source);
|
|
1074
|
+
return;
|
|
1075
|
+
}
|
|
1076
|
+
if (specifier.type === "ImportDefaultSpecifier") {
|
|
1077
|
+
names.push("default");
|
|
1078
|
+
continue;
|
|
1079
|
+
}
|
|
1080
|
+
if (specifier.type === "ImportSpecifier") {
|
|
1081
|
+
const imported = specifier.imported;
|
|
1082
|
+
if (imported?.type === "Literal" || imported?.type === "StringLiteral") {
|
|
1083
|
+
markUnsafe(source);
|
|
1084
|
+
return;
|
|
1085
|
+
}
|
|
1086
|
+
const name = getExportedName(specifier.imported);
|
|
1087
|
+
if (!name) {
|
|
1088
|
+
markUnsafe(source);
|
|
1089
|
+
return;
|
|
1090
|
+
}
|
|
1091
|
+
names.push(name);
|
|
1092
|
+
continue;
|
|
1093
|
+
}
|
|
1094
|
+
markUnsafe(source);
|
|
1095
|
+
return;
|
|
1096
|
+
}
|
|
1097
|
+
record(names, source);
|
|
1098
|
+
}
|
|
1099
|
+
function collectReExport(node, source, record, markUnsafe) {
|
|
1100
|
+
if (isTypeOnly(node)) return;
|
|
1101
|
+
if (node.type === "ExportAllDeclaration") {
|
|
1102
|
+
markUnsafe(source);
|
|
1103
|
+
return;
|
|
1104
|
+
}
|
|
1105
|
+
const specifiers = Array.isArray(node.specifiers) ? node.specifiers : [];
|
|
1106
|
+
if (specifiers.length === 0) {
|
|
1107
|
+
markUnsafe(source);
|
|
1108
|
+
return;
|
|
1109
|
+
}
|
|
1110
|
+
const names = [];
|
|
1111
|
+
for (const specifier of specifiers) {
|
|
1112
|
+
if (isTypeOnly(specifier)) continue;
|
|
1113
|
+
if (specifier.type !== "ExportSpecifier") {
|
|
1114
|
+
markUnsafe(source);
|
|
1115
|
+
return;
|
|
1116
|
+
}
|
|
1117
|
+
const local = specifier.local;
|
|
1118
|
+
if (local?.type === "Literal" || local?.type === "StringLiteral") {
|
|
1119
|
+
markUnsafe(source);
|
|
1120
|
+
return;
|
|
1121
|
+
}
|
|
1122
|
+
const name = getExportedName(specifier.local);
|
|
1123
|
+
if (!name) {
|
|
1124
|
+
markUnsafe(source);
|
|
1125
|
+
return;
|
|
1126
|
+
}
|
|
1127
|
+
names.push(name);
|
|
1128
|
+
}
|
|
1129
|
+
record(names, source);
|
|
1130
|
+
}
|
|
1131
|
+
/**
|
|
1132
|
+
* Collect the exports required by a consumer's ESM graph.
|
|
1133
|
+
*
|
|
1134
|
+
* Parsing the module avoids treating import-looking text in comments, strings,
|
|
1135
|
+
* templates, or regular expressions as real dependencies. If parsing fails,
|
|
1136
|
+
* every configured tree-shaken share is conservatively marked as requiring its
|
|
1137
|
+
* full bundle instead of guessing from source text.
|
|
1138
|
+
*
|
|
1139
|
+
* Generated federation wrappers are excluded because their imports describe
|
|
1140
|
+
* the wrapper implementation, not the consumer's requirements.
|
|
1141
|
+
*/
|
|
1142
|
+
function collectTreeShakingImports(code, id, shared, findSharedKey, record, markUnsafe) {
|
|
1143
|
+
const normalizedId = normalizePathForImport(id);
|
|
1144
|
+
if (normalizedId.includes("__prebuild__") || normalizedId.includes("__loadShare__") || normalizedId.includes("__mf_tree_shaking_graph__")) return;
|
|
1145
|
+
let ast;
|
|
1146
|
+
try {
|
|
1147
|
+
ast = parseAst(code);
|
|
1148
|
+
} catch {
|
|
1149
|
+
Object.entries(shared).forEach(([sharedKey, shareItem]) => {
|
|
1150
|
+
if (shareItem.shareConfig.treeShaking) markUnsafe(sharedKey, "*");
|
|
1151
|
+
});
|
|
1152
|
+
return;
|
|
1153
|
+
}
|
|
1154
|
+
const matchShared = (source) => {
|
|
1155
|
+
const sharedKey = findSharedKey(source, shared);
|
|
1156
|
+
return sharedKey && shared[sharedKey]?.shareConfig.treeShaking ? sharedKey : void 0;
|
|
1157
|
+
};
|
|
1158
|
+
const recordSource = (names, source) => {
|
|
1159
|
+
const sharedKey = matchShared(source);
|
|
1160
|
+
if (sharedKey) record(sharedKey, names, source);
|
|
1161
|
+
};
|
|
1162
|
+
const markSourceUnsafe = (source) => {
|
|
1163
|
+
const sharedKey = matchShared(source);
|
|
1164
|
+
if (sharedKey) markUnsafe(sharedKey, source);
|
|
1165
|
+
};
|
|
1166
|
+
forEachAstNode(ast, (node) => {
|
|
1167
|
+
if (node.type === "ImportDeclaration") {
|
|
1168
|
+
const source = getModuleSource(node.source);
|
|
1169
|
+
if (source) collectImportDeclaration(node, source, recordSource, markSourceUnsafe);
|
|
1170
|
+
return;
|
|
1171
|
+
}
|
|
1172
|
+
if ((node.type === "ExportNamedDeclaration" || node.type === "ExportAllDeclaration") && node.source) {
|
|
1173
|
+
const source = getModuleSource(node.source);
|
|
1174
|
+
if (source) collectReExport(node, source, recordSource, markSourceUnsafe);
|
|
1175
|
+
return;
|
|
1176
|
+
}
|
|
1177
|
+
if (node.type === "ImportExpression") {
|
|
1178
|
+
const source = getModuleSource(node.source);
|
|
1179
|
+
if (source) markSourceUnsafe(source);
|
|
1180
|
+
return;
|
|
1181
|
+
}
|
|
1182
|
+
if (node.type === "CallExpression") {
|
|
1183
|
+
const callee = node.callee;
|
|
1184
|
+
const args = Array.isArray(node.arguments) ? node.arguments : [];
|
|
1185
|
+
if (callee?.type === "Identifier" && callee.name === "require" && args.length > 0) {
|
|
1186
|
+
const source = getModuleSource(args[0]);
|
|
1187
|
+
if (source) markSourceUnsafe(source);
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
});
|
|
1191
|
+
}
|
|
1192
|
+
//#endregion
|
|
931
1193
|
//#region src/virtualModules/virtualShared_preBuild.ts
|
|
932
1194
|
/**
|
|
933
1195
|
* Even the resolveId hook cannot interfere with vite pre-build,
|
|
@@ -1173,7 +1435,7 @@ function isWorkspaceFilePath(resolved) {
|
|
|
1173
1435
|
try {
|
|
1174
1436
|
realResolved = realpathSync.native(resolved);
|
|
1175
1437
|
} catch {}
|
|
1176
|
-
return !realResolved.includes("/node_modules/")
|
|
1438
|
+
return !normalizeNodeModulePath(realResolved).includes("/node_modules/");
|
|
1177
1439
|
}
|
|
1178
1440
|
/**
|
|
1179
1441
|
* When createRequire resolves a workspace package to a CJS entry (e.g. dist/index.cjs),
|
|
@@ -1285,10 +1547,104 @@ function getConcreteSharedImportSource(pkg, shareItem) {
|
|
|
1285
1547
|
const preBuildCacheMap = {};
|
|
1286
1548
|
const preBuildShareItemMap = {};
|
|
1287
1549
|
const PREBUILD_TAG = "__prebuild__";
|
|
1550
|
+
const treeShakingProviderCacheMap = {};
|
|
1551
|
+
const materializedTreeShakingProviders = /* @__PURE__ */ new Set();
|
|
1552
|
+
const TREE_SHAKING_PROVIDER_TAG = "__treeShakingProvider__";
|
|
1553
|
+
const TREE_SHAKING_GRAPH_QUERY = "__mf_tree_shaking_graph__";
|
|
1554
|
+
function getTreeShakingGraphToken(id) {
|
|
1555
|
+
if (!id) return void 0;
|
|
1556
|
+
const queryStart = id.indexOf("?");
|
|
1557
|
+
if (queryStart === -1) return void 0;
|
|
1558
|
+
const hashStart = id.indexOf("#", queryStart);
|
|
1559
|
+
const entry = id.slice(queryStart + 1, hashStart === -1 ? void 0 : hashStart).split("&").find((part) => part.split("=", 1)[0] === TREE_SHAKING_GRAPH_QUERY);
|
|
1560
|
+
if (!entry) return void 0;
|
|
1561
|
+
const value = entry.slice(26);
|
|
1562
|
+
try {
|
|
1563
|
+
return decodeURIComponent(value);
|
|
1564
|
+
} catch {
|
|
1565
|
+
return value;
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
function stripTreeShakingGraphQuery(id) {
|
|
1569
|
+
const queryStart = id.indexOf("?");
|
|
1570
|
+
if (queryStart === -1) return id;
|
|
1571
|
+
const hashStart = id.indexOf("#", queryStart);
|
|
1572
|
+
const pathname = id.slice(0, queryStart);
|
|
1573
|
+
const hash = hashStart === -1 ? "" : id.slice(hashStart);
|
|
1574
|
+
const remaining = id.slice(queryStart + 1, hashStart === -1 ? void 0 : hashStart).split("&").filter(Boolean).filter((part) => part.split("=", 1)[0] !== TREE_SHAKING_GRAPH_QUERY);
|
|
1575
|
+
return `${pathname}${remaining.length ? `?${remaining.join("&")}` : ""}${hash}`;
|
|
1576
|
+
}
|
|
1577
|
+
function addTreeShakingGraphQuery(id, token) {
|
|
1578
|
+
const cleanId = stripTreeShakingGraphQuery(id);
|
|
1579
|
+
const hashStart = cleanId.indexOf("#");
|
|
1580
|
+
const base = hashStart === -1 ? cleanId : cleanId.slice(0, hashStart);
|
|
1581
|
+
const hash = hashStart === -1 ? "" : cleanId.slice(hashStart);
|
|
1582
|
+
return `${base}${base.includes("?") ? "&" : "?"}${TREE_SHAKING_GRAPH_QUERY}=${encodeURIComponent(token)}${hash}`;
|
|
1583
|
+
}
|
|
1584
|
+
function getConcreteTreeShakingExportUsage(pkg, shareItem) {
|
|
1585
|
+
return getTreeShakingExportUsage(pkg, shareItem, shareItem?.name);
|
|
1586
|
+
}
|
|
1587
|
+
function getTreeShakingSharedProviderName(pkg) {
|
|
1588
|
+
const { internalName, name } = getNormalizeModuleFederationOptions();
|
|
1589
|
+
return `${internalName || name}__tree_shaking__${packageNameEncode(pkg)}`;
|
|
1590
|
+
}
|
|
1591
|
+
function getTreeShakingSharedProviderImportId(pkg) {
|
|
1592
|
+
if (!treeShakingProviderCacheMap[pkg]) treeShakingProviderCacheMap[pkg] = new VirtualModule(pkg, TREE_SHAKING_PROVIDER_TAG, ".js");
|
|
1593
|
+
return treeShakingProviderCacheMap[pkg].getImportId();
|
|
1594
|
+
}
|
|
1595
|
+
function hasTreeShakingSharedProvider(pkg, shareItem) {
|
|
1596
|
+
const usage = getConcreteTreeShakingExportUsage(pkg, shareItem);
|
|
1597
|
+
return materializedTreeShakingProviders.has(pkg) && usage?.kind === "exports";
|
|
1598
|
+
}
|
|
1599
|
+
/**
|
|
1600
|
+
* Materialize the locally optimized provider as a small ESM container.
|
|
1601
|
+
*
|
|
1602
|
+
* The normal prebuild module remains the complete fallback. This container only
|
|
1603
|
+
* retains the selected exports and is installed as `treeShaking.get` by the
|
|
1604
|
+
* generated runtime record. Keeping the two getters distinct lets the Runtime
|
|
1605
|
+
* perform its normal usedExports compatibility check and safely choose the full
|
|
1606
|
+
* provider when the optimized one is insufficient.
|
|
1607
|
+
*/
|
|
1608
|
+
function writeTreeShakingSharedProvider(pkg, shareItem) {
|
|
1609
|
+
const usage = getConcreteTreeShakingExportUsage(pkg, shareItem);
|
|
1610
|
+
if (usage?.kind !== "exports" || !usage.usedExports.length || shareItem?.shareConfig.import === false) {
|
|
1611
|
+
materializedTreeShakingProviders.delete(pkg);
|
|
1612
|
+
return;
|
|
1613
|
+
}
|
|
1614
|
+
const usedExports = usage.usedExports;
|
|
1615
|
+
const unsupportedExport = usedExports.find((name) => name !== "default" && !isValidEsmExportName(name));
|
|
1616
|
+
if (unsupportedExport) {
|
|
1617
|
+
materializedTreeShakingProviders.delete(pkg);
|
|
1618
|
+
mfWarn(`Tree-shaking shared dependency "${pkg}" was disabled because export "${unsupportedExport}" cannot be represented by the generated ESM provider.`);
|
|
1619
|
+
return;
|
|
1620
|
+
}
|
|
1621
|
+
const provider = treeShakingProviderCacheMap[pkg] || (treeShakingProviderCacheMap[pkg] = new VirtualModule(pkg, "__treeShakingProvider__", ".js"));
|
|
1622
|
+
const optimizedImportSource = addTreeShakingGraphQuery(getConcreteSharedImportSource(pkg, shareItem) || pkg, pkg);
|
|
1623
|
+
const namedExports = usedExports.filter((name) => name !== "default");
|
|
1624
|
+
const namedImports = namedExports.map((name, index) => `${name} as __mfTreeShaken_${index}`).join(", ");
|
|
1625
|
+
const importLines = [namedImports ? `import { ${namedImports} } from ${escapeGeneratedStringLiteral(optimizedImportSource)};` : "", usedExports.includes("default") ? `import __mfTreeShakenDefault from ${escapeGeneratedStringLiteral(optimizedImportSource)};` : ""].filter(Boolean).join("\n");
|
|
1626
|
+
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(", ")} }`]];
|
|
1627
|
+
provider.writeSync(`${importLines}
|
|
1628
|
+
const __mfTreeShakenModule = { ${namespaceEntries.join(", ")} };
|
|
1629
|
+
Object.defineProperty(__mfTreeShakenModule, "__esModule", {
|
|
1630
|
+
value: true,
|
|
1631
|
+
enumerable: false,
|
|
1632
|
+
});
|
|
1633
|
+
async function init() {}
|
|
1634
|
+
function get() {
|
|
1635
|
+
return () => __mfTreeShakenModule;
|
|
1636
|
+
}
|
|
1637
|
+
const usedExports = ${JSON.stringify([...usedExports].sort())};
|
|
1638
|
+
export { get, init, usedExports };
|
|
1639
|
+
export default { get, init };
|
|
1640
|
+
`, true);
|
|
1641
|
+
materializedTreeShakingProviders.add(pkg);
|
|
1642
|
+
}
|
|
1288
1643
|
function writePreBuildLibPath(pkg, shareItem) {
|
|
1289
1644
|
if (!preBuildCacheMap[pkg]) preBuildCacheMap[pkg] = new VirtualModule(pkg, PREBUILD_TAG, ".js");
|
|
1290
1645
|
preBuildShareItemMap[pkg] = shareItem;
|
|
1291
1646
|
const importSource = getConcreteSharedImportSource(pkg, shareItem) || pkg;
|
|
1647
|
+
writeTreeShakingSharedProvider(pkg, shareItem);
|
|
1292
1648
|
if (pkg === "react/compiler-runtime") {
|
|
1293
1649
|
const reactCacheDescriptor = getSharedCacheDescriptorLiteral("react", shareItem ?? {
|
|
1294
1650
|
name: "react",
|
|
@@ -1343,16 +1699,27 @@ function writePreBuildLibPath(pkg, shareItem) {
|
|
|
1343
1699
|
const __mfPrebuildExports = __mfPrebuildNamespace;
|
|
1344
1700
|
${declarations}
|
|
1345
1701
|
${namedExportLine}
|
|
1346
|
-
export default __mfPrebuildNamespace
|
|
1702
|
+
export default Reflect.get(__mfPrebuildNamespace, "default") ?? __mfPrebuildNamespace;
|
|
1347
1703
|
`, true);
|
|
1348
1704
|
return;
|
|
1349
1705
|
}
|
|
1350
1706
|
preBuildCacheMap[pkg].writeSync(`
|
|
1351
1707
|
import * as __mfPrebuildExports from ${escapeGeneratedStringLiteral(importSource)};
|
|
1352
1708
|
export * from ${escapeGeneratedStringLiteral(importSource)};
|
|
1353
|
-
|
|
1709
|
+
// Reflect access avoids bundler warnings for ESM packages without a
|
|
1710
|
+
// default export (for example antd/es/index.js), while preserving the
|
|
1711
|
+
// namespace fallback for packages that do provide one.
|
|
1712
|
+
export default Reflect.get(__mfPrebuildExports, "default") ?? __mfPrebuildExports;
|
|
1354
1713
|
`, true);
|
|
1355
1714
|
}
|
|
1715
|
+
/** Re-render already materialized wrappers after import analysis discovers exports. */
|
|
1716
|
+
function refreshTreeShakingModules() {
|
|
1717
|
+
for (const [pkg, shareItem] of Object.entries(preBuildShareItemMap)) {
|
|
1718
|
+
if (!shareItem?.shareConfig.treeShaking) continue;
|
|
1719
|
+
writePreBuildLibPath(pkg, shareItem);
|
|
1720
|
+
writeLoadShareModule(pkg, shareItem, "build", false);
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1356
1723
|
function getPreBuildLibImportId(pkg) {
|
|
1357
1724
|
if (!preBuildCacheMap[pkg]) preBuildCacheMap[pkg] = new VirtualModule(pkg, PREBUILD_TAG, ".js");
|
|
1358
1725
|
return preBuildCacheMap[pkg].getImportId();
|
|
@@ -1398,12 +1765,15 @@ function materializeCachedLoadShareModule(options) {
|
|
|
1398
1765
|
options.addUsedShares(pkg);
|
|
1399
1766
|
options.writeLocalSharedImportMap();
|
|
1400
1767
|
}
|
|
1401
|
-
function
|
|
1768
|
+
function getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer) {
|
|
1769
|
+
return treeShakingConsumer ? `__mfReadTreeShakingSharedSelection(__mfModuleCache.share, ${cacheDescriptor}, ${JSON.stringify(treeShakingConsumer)})` : `__mfReadSharedCache(__mfModuleCache.share, ${cacheDescriptor})`;
|
|
1770
|
+
}
|
|
1771
|
+
function generateEagerWorkspaceSingletonExports(namedExports, importSource, cacheDescriptor, treeShakingConsumer) {
|
|
1402
1772
|
const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
|
|
1403
1773
|
const namedExportAssignments = namedExports.length > 0 ? `\n ${namedExports.map((name, i) => `const ${namedExportVars[i]} = exportModule[${escapeGeneratedStringLiteral(name)}];`).join("\n ")}` : "";
|
|
1404
1774
|
const namedExportLine = namedExports.length > 0 ? `\n export { ${namedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
|
|
1405
1775
|
return `import * as __mfLocalShare from ${escapeGeneratedStringLiteral(importSource)};
|
|
1406
|
-
let exportModule =
|
|
1776
|
+
let exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)};
|
|
1407
1777
|
if (exportModule === undefined) {
|
|
1408
1778
|
Promise.resolve().then(() => {
|
|
1409
1779
|
if (__mfReadSharedCache(__mfModuleCache.share, ${cacheDescriptor}) === undefined) {
|
|
@@ -1415,24 +1785,25 @@ function generateEagerWorkspaceSingletonExports(namedExports, importSource, cach
|
|
|
1415
1785
|
const __mf_default = exportModule.default ?? exportModule;${namedExportAssignments}
|
|
1416
1786
|
export { __mf_default as default };${namedExportLine}`;
|
|
1417
1787
|
}
|
|
1418
|
-
function generateLazyWorkspaceSingletonExports(namedExports, importSource, cacheDescriptor) {
|
|
1788
|
+
function generateLazyWorkspaceSingletonExports(namedExports, importSource, cacheDescriptor, treeShakingConsumer) {
|
|
1419
1789
|
const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
|
|
1420
1790
|
const declarations = namedExports.length > 0 ? ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ") : "let __mf_default;";
|
|
1421
1791
|
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
1792
|
const namedExportLine = namedExports.length > 0 ? `\n export { ${namedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
|
|
1793
|
+
const applyLocalFallback = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
1794
|
+
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule);
|
|
1795
|
+
__mfApplyLazyShareExports(exportModule);`;
|
|
1423
1796
|
return `${declarations}
|
|
1424
1797
|
const __mfApplyLazyShareExports = (mod) => {
|
|
1425
1798
|
${assignments}
|
|
1426
1799
|
};
|
|
1427
|
-
let exportModule =
|
|
1800
|
+
let exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)};
|
|
1428
1801
|
if (exportModule === undefined) {
|
|
1429
1802
|
if (import.meta.env.SSR) {
|
|
1430
|
-
${
|
|
1431
|
-
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule);
|
|
1432
|
-
__mfApplyLazyShareExports(exportModule);`}
|
|
1803
|
+
${applyLocalFallback}
|
|
1433
1804
|
} else {
|
|
1434
1805
|
(__mfModuleCache.pendingShareLoads ||= []).push(initPromise.then(() => {
|
|
1435
|
-
exportModule =
|
|
1806
|
+
exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)};
|
|
1436
1807
|
if (exportModule !== undefined) {
|
|
1437
1808
|
__mfApplyLazyShareExports(exportModule);
|
|
1438
1809
|
return;
|
|
@@ -1459,16 +1830,19 @@ function prependWorkspaceSingletonSsrImport(code) {
|
|
|
1459
1830
|
const quote = importMatch[1];
|
|
1460
1831
|
return `import * as __mfLocalShare from ${quote}${importMatch[2]}${quote};\n${code}`;
|
|
1461
1832
|
}
|
|
1462
|
-
function generateDeferredHostProvidedExports(namedExports, pkg, cacheDescriptor) {
|
|
1833
|
+
function generateDeferredHostProvidedExports(namedExports, pkg, cacheDescriptor, treeShakingConsumer) {
|
|
1463
1834
|
const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
|
|
1464
|
-
|
|
1835
|
+
const declarations = ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ");
|
|
1836
|
+
const assignments = [...namedExports.map((name, i) => `${namedExportVars[i]} = exportModule[${escapeGeneratedStringLiteral(name)}];`), "__mf_default = exportModule.default ?? exportModule;"].join("\n ");
|
|
1837
|
+
const namedExportLine = namedExports.length > 0 ? `\n export { ${namedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
|
|
1838
|
+
return `${declarations}
|
|
1465
1839
|
const __mfApplyHostProvidedExports = (exportModule) => {
|
|
1466
|
-
${
|
|
1840
|
+
${assignments}
|
|
1467
1841
|
};
|
|
1468
|
-
let exportModule =
|
|
1842
|
+
let exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)};
|
|
1469
1843
|
if (exportModule === undefined) {
|
|
1470
1844
|
(__mfModuleCache.pendingShareLoads ||= []).push(initPromise.then(() => {
|
|
1471
|
-
exportModule =
|
|
1845
|
+
exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)};
|
|
1472
1846
|
if (exportModule === undefined) {
|
|
1473
1847
|
throw new Error("[Module Federation] Shared module ${pkg} was imported before federation bootstrap finished.");
|
|
1474
1848
|
}
|
|
@@ -1477,7 +1851,7 @@ function generateDeferredHostProvidedExports(namedExports, pkg, cacheDescriptor)
|
|
|
1477
1851
|
} else {
|
|
1478
1852
|
__mfApplyHostProvidedExports(exportModule);
|
|
1479
1853
|
}
|
|
1480
|
-
export { __mf_default as default };${
|
|
1854
|
+
export { __mf_default as default };${namedExportLine}`;
|
|
1481
1855
|
}
|
|
1482
1856
|
function generateShareModuleUnwrapCode({ source, preserveNamedExports, stopWithReturn }) {
|
|
1483
1857
|
return `let current = ${source};
|
|
@@ -1500,13 +1874,14 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
|
|
|
1500
1874
|
if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = new VirtualModule(pkg, LOAD_SHARE_TAG, ".js");
|
|
1501
1875
|
let importLine = getRuntimeModuleCacheBootstrapCode();
|
|
1502
1876
|
const cacheDescriptor = getSharedCacheDescriptorLiteral(pkg, shareItem);
|
|
1877
|
+
const treeShakingConsumer = command === "build" && shareItem.shareConfig.treeShaking ? getNormalizeModuleFederationOptions().name : void 0;
|
|
1503
1878
|
if (shareItem.shareConfig.import === false) {
|
|
1504
1879
|
const namedExports = getPackageNamedExports(pkg);
|
|
1505
1880
|
let exportLine;
|
|
1506
|
-
if (namedExports.length > 0) exportLine = generateDeferredHostProvidedExports(namedExports, pkg, cacheDescriptor);
|
|
1881
|
+
if (namedExports.length > 0) exportLine = generateDeferredHostProvidedExports(namedExports, pkg, cacheDescriptor, treeShakingConsumer);
|
|
1507
1882
|
else {
|
|
1508
1883
|
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);
|
|
1884
|
+
exportLine = generateDeferredHostProvidedExports([], pkg, cacheDescriptor, treeShakingConsumer);
|
|
1510
1885
|
}
|
|
1511
1886
|
loadShareCacheMap[pkg].writeSync(`
|
|
1512
1887
|
${getRuntimeInitPromiseBootstrapCode()}
|
|
@@ -1529,13 +1904,17 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
|
|
|
1529
1904
|
const isConsumedByPeerSingleton = isSharedSingletonConsumedByPeer(pkg);
|
|
1530
1905
|
const usesEntryInjectedRemoteFallback = command !== "build" && !isWorkspaceSingleton && isRemoteOnlyContainer() && shareItem.shareConfig.singleton === true && getNormalizeModuleFederationOptions().hostInitInjectLocation === "entry" && isConsumedByPeerSingleton;
|
|
1531
1906
|
const usesEagerWorkspaceFallback = isWorkspaceSingleton && isConsumedByPeerSingleton;
|
|
1907
|
+
const usesDeferredTreeShakingFallback = Boolean(treeShakingConsumer);
|
|
1532
1908
|
const namedExports = getSharedNamedExports(pkg, shareItem);
|
|
1533
1909
|
let exportLine;
|
|
1534
1910
|
let initBlock = "";
|
|
1535
|
-
if (
|
|
1911
|
+
if (usesDeferredTreeShakingFallback) {
|
|
1912
|
+
importLine = `${getRuntimeInitPromiseBootstrapCode()}\n ${importLine}`;
|
|
1913
|
+
exportLine = generateLazyWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor, treeShakingConsumer);
|
|
1914
|
+
} else if (usesEagerWorkspaceFallback || usesEntryInjectedRemoteFallback) exportLine = generateEagerWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor, treeShakingConsumer);
|
|
1536
1915
|
else if (usesDeferredSingletonFallback) {
|
|
1537
1916
|
importLine = `${getRuntimeInitPromiseBootstrapCode()}\n ${importLine}`;
|
|
1538
|
-
exportLine = generateLazyWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor);
|
|
1917
|
+
exportLine = generateLazyWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor, treeShakingConsumer);
|
|
1539
1918
|
} else if (namedExports.length > 0) {
|
|
1540
1919
|
const destructure = `const { ${namedExports.map((name, i) => `${name}: __mf_${i}`).join(", ")} } = exportModule;`;
|
|
1541
1920
|
const namedExportLine = `export { ${namedExports.map((name, i) => `__mf_${i} as ${name}`).join(", ")} };`;
|
|
@@ -1556,9 +1935,9 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
|
|
|
1556
1935
|
initBlock = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
1557
1936
|
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule);`;
|
|
1558
1937
|
}
|
|
1559
|
-
const prebuildImportLine = usesDeferredSingletonFallback || isWorkspacePackage && command !== "build" ? "" : `import * as __mfLocalShare from ${escapeGeneratedStringLiteral(skipServePrebuildWarmup ? devImportSource : sharedImportSource)};`;
|
|
1560
|
-
const devDynamicImportLine = isWorkspacePackage ? "" : usesDeferredSingletonFallback ? "" : command !== "build" && !skipServePrebuildWarmup ? `;() => import(${escapeGeneratedStringLiteral(devImportSource)}).catch(() => {});` : "";
|
|
1561
|
-
const moduleBody = usesDeferredSingletonFallback ? `
|
|
1938
|
+
const prebuildImportLine = usesDeferredSingletonFallback || usesDeferredTreeShakingFallback || isWorkspacePackage && command !== "build" ? "" : `import * as __mfLocalShare from ${escapeGeneratedStringLiteral(skipServePrebuildWarmup ? devImportSource : sharedImportSource)};`;
|
|
1939
|
+
const devDynamicImportLine = isWorkspacePackage ? "" : usesDeferredSingletonFallback || usesDeferredTreeShakingFallback ? "" : command !== "build" && !skipServePrebuildWarmup ? `;() => import(${escapeGeneratedStringLiteral(devImportSource)}).catch(() => {});` : "";
|
|
1940
|
+
const moduleBody = usesDeferredSingletonFallback || usesDeferredTreeShakingFallback ? `
|
|
1562
1941
|
${prebuildImportLine}
|
|
1563
1942
|
${devDynamicImportLine}
|
|
1564
1943
|
${importLine}
|
|
@@ -1571,7 +1950,7 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
|
|
|
1571
1950
|
${importLine}
|
|
1572
1951
|
${sharedCacheHelperCode}
|
|
1573
1952
|
${normalizeLocalShareModuleCode}
|
|
1574
|
-
let exportModule =
|
|
1953
|
+
let exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)}
|
|
1575
1954
|
if (exportModule === undefined) {
|
|
1576
1955
|
${initBlock}
|
|
1577
1956
|
}
|
|
@@ -1618,14 +1997,21 @@ function getDirectSharedCacheSeedImportPath(pkg, shareItem) {
|
|
|
1618
1997
|
function generateLocalSharedImportMap() {
|
|
1619
1998
|
const useDirectReactImport = shouldUseDirectReactImport();
|
|
1620
1999
|
const options = getNormalizeModuleFederationOptions();
|
|
2000
|
+
const orderedShares = getOrderedUsedShares();
|
|
1621
2001
|
return `
|
|
1622
2002
|
import {loadShare} from "@module-federation/runtime";
|
|
2003
|
+
${orderedShares.map((pkg, index) => {
|
|
2004
|
+
const shareItem = getNormalizeShareItem(pkg);
|
|
2005
|
+
if (!shareItem?.shareConfig.eager || shareItem.shareConfig.import === false) return "";
|
|
2006
|
+
return `import * as __mfEagerShare_${index} from ${JSON.stringify(getLocalSharedPackagePath(pkg, shareItem))};`;
|
|
2007
|
+
}).filter(Boolean).join("\n")}
|
|
1623
2008
|
const importMap = {
|
|
1624
|
-
${
|
|
2009
|
+
${orderedShares.map((pkg, index) => {
|
|
1625
2010
|
const shareItem = getNormalizeShareItem(pkg);
|
|
1626
2011
|
return `
|
|
1627
2012
|
${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 =
|
|
2013
|
+
${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};
|
|
2014
|
+
return pkg;` : `let pkg = await import(${JSON.stringify(getLocalSharedPackagePath(pkg, shareItem))});
|
|
1629
2015
|
return pkg;`}
|
|
1630
2016
|
}
|
|
1631
2017
|
`;
|
|
@@ -1635,12 +2021,19 @@ function generateLocalSharedImportMap() {
|
|
|
1635
2021
|
${getOrderedUsedShares().map((key) => {
|
|
1636
2022
|
const shareItem = getNormalizeShareItem(key);
|
|
1637
2023
|
if (!shareItem) return null;
|
|
2024
|
+
const treeShakingUsage = getTreeShakingExportUsage(key, shareItem, shareItem.name);
|
|
2025
|
+
const treeShakingProviderExports = treeShakingUsage?.kind === "exports" ? treeShakingUsage.usedExports : [];
|
|
2026
|
+
const treeShakingUsedExports = options.injectTreeShakingUsedExports === false ? shareItem.shareConfig.treeShaking?.usedExports || [] : treeShakingProviderExports;
|
|
2027
|
+
const disableRuntimeInference = shareItem.shareConfig.treeShaking?.mode === "runtime-infer" && options.injectTreeShakingUsedExports === false;
|
|
2028
|
+
const treeShakingProviderImportId = !disableRuntimeInference && hasTreeShakingSharedProvider(key, shareItem) ? getTreeShakingSharedProviderImportId(key) : void 0;
|
|
2029
|
+
const treeShakingStatus = treeShakingUsage?.kind === "full" || disableRuntimeInference || shareItem.shareConfig.treeShaking?.mode === "runtime-infer" && !treeShakingProviderImportId && shareItem.shareConfig.import !== false ? 0 : 1;
|
|
1638
2030
|
return `
|
|
1639
2031
|
${JSON.stringify(key)}: {
|
|
1640
2032
|
name: ${JSON.stringify(key)},
|
|
1641
2033
|
version: ${JSON.stringify(shareItem.version)},
|
|
1642
2034
|
scope: [${JSON.stringify(shareItem.scope)}],
|
|
1643
2035
|
loaded: false,
|
|
2036
|
+
eager: ${Boolean(shareItem.shareConfig.eager)},
|
|
1644
2037
|
from: ${JSON.stringify(options.name)},
|
|
1645
2038
|
async get () {
|
|
1646
2039
|
if (${shareItem.shareConfig.import === false}) {
|
|
@@ -1665,8 +2058,20 @@ function generateLocalSharedImportMap() {
|
|
|
1665
2058
|
singleton: ${shareItem.shareConfig.singleton},
|
|
1666
2059
|
requiredVersion: ${JSON.stringify(shareItem.shareConfig.requiredVersion)},
|
|
1667
2060
|
strictVersion: ${shareItem.shareConfig.strictVersion},
|
|
2061
|
+
eager: ${Boolean(shareItem.shareConfig.eager)},
|
|
1668
2062
|
${shareItem.shareConfig.import === false ? "import: false," : ""}
|
|
1669
|
-
}
|
|
2063
|
+
},
|
|
2064
|
+
${shareItem.shareConfig.treeShaking ? `treeShaking: {
|
|
2065
|
+
mode: ${JSON.stringify(shareItem.shareConfig.treeShaking.mode)},
|
|
2066
|
+
usedExports: ${JSON.stringify(treeShakingUsedExports)},
|
|
2067
|
+
providedExports: ${JSON.stringify(treeShakingProviderExports)},
|
|
2068
|
+
status: ${treeShakingStatus},
|
|
2069
|
+
${treeShakingProviderImportId ? `async get() {
|
|
2070
|
+
const container = await import(${JSON.stringify(treeShakingProviderImportId)});
|
|
2071
|
+
if (typeof container.init === "function") await container.init();
|
|
2072
|
+
return container.get();
|
|
2073
|
+
},` : ""}
|
|
2074
|
+
}` : ""}
|
|
1670
2075
|
}
|
|
1671
2076
|
`;
|
|
1672
2077
|
}).filter((x) => x !== null).join(",")}
|
|
@@ -1676,6 +2081,7 @@ function generateLocalSharedImportMap() {
|
|
|
1676
2081
|
if (!remote) return null;
|
|
1677
2082
|
return `
|
|
1678
2083
|
{
|
|
2084
|
+
alias: ${JSON.stringify(key)},
|
|
1679
2085
|
entryGlobalName: ${JSON.stringify(remote.entryGlobalName)},
|
|
1680
2086
|
name: ${JSON.stringify(remote.name)},
|
|
1681
2087
|
type: ${JSON.stringify(remote.type)},
|
|
@@ -1838,7 +2244,11 @@ function generateRuntimeSharedCacheSeedCode() {
|
|
|
1838
2244
|
for (const pkg of __mfSeedKeys) {
|
|
1839
2245
|
const share = usedShared[pkg];
|
|
1840
2246
|
const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
|
|
1841
|
-
if (
|
|
2247
|
+
if (
|
|
2248
|
+
share.shareConfig?.import === false ||
|
|
2249
|
+
Boolean(share.treeShaking) ||
|
|
2250
|
+
__mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) !== undefined
|
|
2251
|
+
) {
|
|
1842
2252
|
continue;
|
|
1843
2253
|
}
|
|
1844
2254
|
const singletonCacheDescriptor = __mfGetSharedCacheDescriptor(pkg, true, share.version, share.scope);
|
|
@@ -1889,8 +2299,176 @@ function getRemoteEntryId(options) {
|
|
|
1889
2299
|
const SSR_ONLY_PLUGIN_SPECIFIERS = new Set(["@module-federation/vite/ssrEntryLoader"]);
|
|
1890
2300
|
const isSsrOnlyPlugin = (importStatement) => [...SSR_ONLY_PLUGIN_SPECIFIERS].some((s) => importStatement.includes(s));
|
|
1891
2301
|
const getSsrOnlyPluginSpecifier = (importStatement) => [...SSR_ONLY_PLUGIN_SPECIFIERS].find((s) => importStatement.includes(s));
|
|
2302
|
+
function generateTreeShakingSharedResolutionCode(enabled) {
|
|
2303
|
+
if (!enabled) return "";
|
|
2304
|
+
return `
|
|
2305
|
+
// Resolve tree-enabled shares through the Runtime after all providers have
|
|
2306
|
+
// registered. Partial providers are stored with their export coverage and
|
|
2307
|
+
// never occupy generic/legacy cache keys, which are reserved for complete
|
|
2308
|
+
// modules only.
|
|
2309
|
+
for (const [pkg, share] of Object.entries(usedShared)) {
|
|
2310
|
+
const treeShaking = share.treeShaking;
|
|
2311
|
+
if (!treeShaking) continue;
|
|
2312
|
+
try {
|
|
2313
|
+
const factory = await initRes.loadShare(pkg, {
|
|
2314
|
+
customShareInfo: {
|
|
2315
|
+
shareConfig: share.shareConfig,
|
|
2316
|
+
treeShaking: {
|
|
2317
|
+
mode: treeShaking.mode,
|
|
2318
|
+
status: treeShaking.status,
|
|
2319
|
+
usedExports: treeShaking.usedExports,
|
|
2320
|
+
},
|
|
2321
|
+
},
|
|
2322
|
+
});
|
|
2323
|
+
if (factory === false) continue;
|
|
2324
|
+
const mod = typeof factory === "function" ? factory() : factory;
|
|
2325
|
+
const resolved = await Promise.resolve(mod);
|
|
2326
|
+
${normalizeRuntimeShareCode}
|
|
2327
|
+
const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
|
|
2328
|
+
const normalizedShared = __mfNormalizeRuntimeShare(resolved);
|
|
2329
|
+
const hasPartialProvider =
|
|
2330
|
+
Array.isArray(treeShaking.providedExports) &&
|
|
2331
|
+
treeShaking.providedExports.length > 0 &&
|
|
2332
|
+
((treeShaking.mode === "runtime-infer" && treeShaking.status !== 0) ||
|
|
2333
|
+
treeShaking.status === 2);
|
|
2334
|
+
if (hasPartialProvider) {
|
|
2335
|
+
__mfWriteTreeShakingSharedCache(
|
|
2336
|
+
__mfModuleCache.share,
|
|
2337
|
+
cacheDescriptor,
|
|
2338
|
+
treeShaking.providedExports,
|
|
2339
|
+
normalizedShared
|
|
2340
|
+
);
|
|
2341
|
+
__mfWriteTreeShakingSharedSelection(
|
|
2342
|
+
__mfModuleCache.share,
|
|
2343
|
+
cacheDescriptor,
|
|
2344
|
+
mfName,
|
|
2345
|
+
normalizedShared
|
|
2346
|
+
);
|
|
2347
|
+
} else {
|
|
2348
|
+
__mfWriteSharedCache(__mfModuleCache.share, cacheDescriptor, normalizedShared);
|
|
2349
|
+
}
|
|
2350
|
+
} catch (e) {
|
|
2351
|
+
console.warn('[Module Federation] Failed to load tree-shaken shared module', pkg, e);
|
|
2352
|
+
}
|
|
2353
|
+
}`;
|
|
2354
|
+
}
|
|
2355
|
+
const treeShakingResolveShareBodyCode = `const originalResolver = args.resolver;
|
|
2356
|
+
args.resolver = () => {
|
|
2357
|
+
const resolved = originalResolver();
|
|
2358
|
+
if (!resolved?.useTreesShaking) return resolved;
|
|
2359
|
+
|
|
2360
|
+
const consumerTreeShaking = args.shareInfo?.treeShaking;
|
|
2361
|
+
if (consumerTreeShaking?.mode !== "runtime-infer") return resolved;
|
|
2362
|
+
const requiredExports = consumerTreeShaking.usedExports;
|
|
2363
|
+
if (!Array.isArray(requiredExports)) return resolved;
|
|
2364
|
+
|
|
2365
|
+
const selectedExports = resolved.shared?.treeShaking?.usedExports;
|
|
2366
|
+
const selectedMatches = Array.isArray(selectedExports) &&
|
|
2367
|
+
requiredExports.every((name) => selectedExports.includes(name));
|
|
2368
|
+
if (selectedMatches) return resolved;
|
|
2369
|
+
|
|
2370
|
+
// Runtime 2.7 prefers a tree provider by version before checking export
|
|
2371
|
+
// coverage. Prefer this consumer's own compatible provider when one is
|
|
2372
|
+
// available; otherwise retain the selected version but use its complete
|
|
2373
|
+
// top-level getter.
|
|
2374
|
+
const localExports = consumerTreeShaking.providedExports;
|
|
2375
|
+
const localMatches = typeof consumerTreeShaking.get === "function" &&
|
|
2376
|
+
Array.isArray(localExports) &&
|
|
2377
|
+
requiredExports.every((name) => localExports.includes(name));
|
|
2378
|
+
if (localMatches) {
|
|
2379
|
+
return { shared: args.shareInfo, useTreesShaking: true };
|
|
2380
|
+
}
|
|
2381
|
+
return { shared: resolved.shared, useTreesShaking: false };
|
|
2382
|
+
};
|
|
2383
|
+
return args;`;
|
|
2384
|
+
function generateTreeShakingSnapshotPluginCode(enabled) {
|
|
2385
|
+
if (!enabled) return "";
|
|
2386
|
+
return `
|
|
2387
|
+
const __mfTreeShakingSnapshotPlugin = () => ({
|
|
2388
|
+
name: "vite-tree-shaking-snapshot-plugin",
|
|
2389
|
+
resolveShare(args) {
|
|
2390
|
+
${treeShakingResolveShareBodyCode}
|
|
2391
|
+
},
|
|
2392
|
+
beforeInit(args) {
|
|
2393
|
+
const { userOptions, origin, options: registeredOptions } = args;
|
|
2394
|
+
const version = userOptions.version || registeredOptions.version;
|
|
2395
|
+
const hostSnapshot = runtimeGlobal.getGlobalSnapshotInfoByModuleInfo({
|
|
2396
|
+
name: origin.name,
|
|
2397
|
+
version,
|
|
2398
|
+
});
|
|
2399
|
+
if (!hostSnapshot || !("shared" in hostSnapshot)) return args;
|
|
2400
|
+
|
|
2401
|
+
const candidates = [];
|
|
2402
|
+
const appendShared = (records) => {
|
|
2403
|
+
for (const [pkgName, value] of Object.entries(records || {})) {
|
|
2404
|
+
const values = Array.isArray(value) ? value : [value];
|
|
2405
|
+
for (const shared of values) candidates.push([pkgName, shared]);
|
|
2406
|
+
}
|
|
2407
|
+
};
|
|
2408
|
+
appendShared(userOptions.shared);
|
|
2409
|
+
appendShared(registeredOptions.shared);
|
|
2410
|
+
|
|
2411
|
+
for (const [pkgName, shared] of candidates) {
|
|
2412
|
+
const treeShaking = shared?.treeShaking;
|
|
2413
|
+
if (!treeShaking || treeShaking.mode !== "server-calc") continue;
|
|
2414
|
+
const shareSnapshot = hostSnapshot.shared.find((item) => item.sharedName === pkgName);
|
|
2415
|
+
if (!shareSnapshot || typeof shareSnapshot.treeShakingStatus !== "number") continue;
|
|
2416
|
+
const {
|
|
2417
|
+
secondarySharedTreeShakingEntry: entry,
|
|
2418
|
+
secondarySharedTreeShakingName: name,
|
|
2419
|
+
treeShakingStatus: status,
|
|
2420
|
+
usedExports,
|
|
2421
|
+
fallbackType,
|
|
2422
|
+
} = shareSnapshot;
|
|
2423
|
+
|
|
2424
|
+
// A CALCULATED snapshot without a loadable secondary entry is not safe:
|
|
2425
|
+
// retain UNKNOWN so the Runtime chooses the complete top-level getter.
|
|
2426
|
+
if (status === 2 && (!entry || !name)) continue;
|
|
2427
|
+
if (Array.isArray(usedExports)) {
|
|
2428
|
+
treeShaking.usedExports = usedExports;
|
|
2429
|
+
treeShaking.providedExports = usedExports;
|
|
2430
|
+
}
|
|
2431
|
+
if (entry && name) {
|
|
2432
|
+
const fullFallbackGet = shared.get;
|
|
2433
|
+
treeShaking.get = async () => {
|
|
2434
|
+
try {
|
|
2435
|
+
const shareEntry = await getRemoteEntry({
|
|
2436
|
+
origin,
|
|
2437
|
+
remoteInfo: {
|
|
2438
|
+
name,
|
|
2439
|
+
entry,
|
|
2440
|
+
type: fallbackType || "global",
|
|
2441
|
+
entryGlobalName: name,
|
|
2442
|
+
shareScope: "default",
|
|
2443
|
+
},
|
|
2444
|
+
});
|
|
2445
|
+
if (!shareEntry) throw new Error("Tree-shaken shared entry did not load");
|
|
2446
|
+
if (typeof shareEntry.init === "function") {
|
|
2447
|
+
await shareEntry.init(origin);
|
|
2448
|
+
}
|
|
2449
|
+
return shareEntry.get();
|
|
2450
|
+
} catch (error) {
|
|
2451
|
+
if (typeof fullFallbackGet === "function") return fullFallbackGet();
|
|
2452
|
+
throw error;
|
|
2453
|
+
}
|
|
2454
|
+
};
|
|
2455
|
+
}
|
|
2456
|
+
treeShaking.status = status;
|
|
2457
|
+
}
|
|
2458
|
+
return args;
|
|
2459
|
+
},
|
|
2460
|
+
});`;
|
|
2461
|
+
}
|
|
1892
2462
|
function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(options), command = "build") {
|
|
1893
2463
|
const needsSharedProviderSelectionHelper = hasImportFalseShared$1(options);
|
|
2464
|
+
const hasTreeShakingShared = Object.values(options.shared ?? {}).some((share) => !!share?.shareConfig.treeShaking);
|
|
2465
|
+
const hasEagerShared = Object.values(options.shared ?? {}).some((share) => share?.shareConfig.eager === true && share.shareConfig.import !== false);
|
|
2466
|
+
const runtimeImports = [
|
|
2467
|
+
"init as runtimeInit",
|
|
2468
|
+
"loadRemote",
|
|
2469
|
+
...hasTreeShakingShared ? ["getRemoteEntry"] : []
|
|
2470
|
+
].join(", ");
|
|
2471
|
+
const runtimeHelperImports = [...hasTreeShakingShared ? ["global as runtimeGlobal"] : [], ...needsSharedProviderSelectionHelper ? ["share as runtimeShare"] : []];
|
|
1894
2472
|
const pluginImportNames = options.runtimePlugins.map((p, i) => {
|
|
1895
2473
|
if (typeof p === "string") return [
|
|
1896
2474
|
`$runtimePlugin_${i}`,
|
|
@@ -1912,8 +2490,9 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
1912
2490
|
if (typeof __VUE_HMR_RUNTIME__ === 'undefined') {
|
|
1913
2491
|
globalThis.__VUE_HMR_RUNTIME__ = { createRecord() {}, rerender() {}, reload() {} };
|
|
1914
2492
|
}
|
|
1915
|
-
import {
|
|
1916
|
-
${
|
|
2493
|
+
import {${runtimeImports}} from "@module-federation/runtime";
|
|
2494
|
+
${hasEagerShared ? `import * as __mfLocalSharedImportMap from "${getLocalSharedImportMapPath()}";` : ""}
|
|
2495
|
+
${runtimeHelperImports.length ? `import {${runtimeHelperImports.join(", ")}} from "@module-federation/runtime/helpers";` : ""}
|
|
1917
2496
|
${pluginImportNames.filter((item) => !isSsrOnlyPlugin(item[1])).map((item) => item[1]).join("\n")}
|
|
1918
2497
|
${command === "build" ? getRuntimeInitResolveBootstrapCode() : getRuntimeInitBootstrapCode() + "\n const { initResolve } = globalThis[globalKey];"}
|
|
1919
2498
|
${getRuntimeModuleCacheBootstrapCode()}
|
|
@@ -1941,14 +2520,16 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
1941
2520
|
}
|
|
1942
2521
|
}
|
|
1943
2522
|
}
|
|
2523
|
+
${generateTreeShakingSnapshotPluginCode(hasTreeShakingShared)}
|
|
1944
2524
|
${needsSharedProviderSelectionHelper ? sharedProviderSelectionHelperCode : ""}
|
|
1945
2525
|
|
|
1946
2526
|
async function getLocalSharedImportMap() {
|
|
1947
|
-
|
|
2527
|
+
${hasEagerShared ? "return __mfLocalSharedImportMap;" : ""}
|
|
2528
|
+
${hasEagerShared ? "" : `if (!localSharedImportMapPromise) {
|
|
1948
2529
|
localSharedImportMapPromise = retrySharedInit(() => import("${getLocalSharedImportMapPath()}"))
|
|
1949
2530
|
.catch((e) => { localSharedImportMapPromise = undefined; throw e; });
|
|
1950
2531
|
}
|
|
1951
|
-
return localSharedImportMapPromise
|
|
2532
|
+
return localSharedImportMapPromise`}
|
|
1952
2533
|
}
|
|
1953
2534
|
|
|
1954
2535
|
async function getExposesMap() {
|
|
@@ -2021,7 +2602,7 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
2021
2602
|
name: mfName,
|
|
2022
2603
|
remotes: ${options.shareStrategy === "loaded-first" ? "[]" : "usedRemotes"},
|
|
2023
2604
|
shared: usedShared,
|
|
2024
|
-
plugins: [...__browserPlugins, ...__ssrPlugins],
|
|
2605
|
+
plugins: [${hasTreeShakingShared ? "__mfTreeShakingSnapshotPlugin()," : ""} ...__browserPlugins, ...__ssrPlugins],
|
|
2025
2606
|
${options.shareStrategy ? `shareStrategy: '${options.shareStrategy}'` : ""}
|
|
2026
2607
|
});
|
|
2027
2608
|
// handling circular init calls
|
|
@@ -2042,9 +2623,13 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
2042
2623
|
} catch (e) {
|
|
2043
2624
|
console.error('[Module Federation]', e)
|
|
2044
2625
|
}
|
|
2626
|
+
${generateTreeShakingSharedResolutionCode(hasTreeShakingShared)}
|
|
2045
2627
|
for (const [pkg, share] of Object.entries(usedShared)) {
|
|
2046
2628
|
const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
|
|
2047
|
-
|
|
2629
|
+
const cachedShare = share.treeShaking
|
|
2630
|
+
? __mfReadTreeShakingSharedSelection(__mfModuleCache.share, cacheDescriptor, mfName)
|
|
2631
|
+
: __mfReadSharedCache(__mfModuleCache.share, cacheDescriptor);
|
|
2632
|
+
if (share.shareConfig?.import !== false || cachedShare !== undefined) continue;
|
|
2048
2633
|
${normalizeRuntimeShareCode}
|
|
2049
2634
|
const versions = shared?.[pkg];
|
|
2050
2635
|
const provider = __mfSelectSharedProvider(versions, pkg, share, '${options.shareStrategy}');
|
|
@@ -2096,6 +2681,10 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build") {
|
|
|
2096
2681
|
for (const pkg of __mfHostInitShareOrder) {
|
|
2097
2682
|
const share = usedShared[pkg];
|
|
2098
2683
|
if (!share) continue;
|
|
2684
|
+
// remoteEntry.init resolves tree-enabled shares into the
|
|
2685
|
+
// coverage-aware cache. Never republish that selected partial under
|
|
2686
|
+
// a generic full-module key here.
|
|
2687
|
+
if (share.treeShaking) continue;
|
|
2099
2688
|
const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
|
|
2100
2689
|
if (__mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) !== undefined) {
|
|
2101
2690
|
continue;
|
|
@@ -2158,9 +2747,8 @@ function addUsedRemote(remoteKey, remoteModule) {
|
|
|
2158
2747
|
function getUsedRemotesMap() {
|
|
2159
2748
|
return usedRemotesMap;
|
|
2160
2749
|
}
|
|
2161
|
-
function
|
|
2162
|
-
|
|
2163
|
-
return remoteName ? remotes[remoteName] : void 0;
|
|
2750
|
+
function getRemoteAliasFromId(id, remotes) {
|
|
2751
|
+
return Object.keys(remotes).filter((name) => id === name || id.startsWith(name + "/")).sort((a, b) => b.length - a.length)[0];
|
|
2164
2752
|
}
|
|
2165
2753
|
function resolveRemoteInitMode(shareStrategy, consumer) {
|
|
2166
2754
|
if (shareStrategy !== "loaded-first") return "eager";
|
|
@@ -2316,10 +2904,12 @@ function generateRemotes(id, command, enableSsrInit = false, consumer = "unified
|
|
|
2316
2904
|
const isLoadedFirst = options.shareStrategy === "loaded-first";
|
|
2317
2905
|
const initMode = resolveRemoteInitMode(options.shareStrategy, consumer);
|
|
2318
2906
|
const deferRemoteLoad = shouldDeferRemoteLoad(initMode);
|
|
2319
|
-
const
|
|
2907
|
+
const remoteAlias = getRemoteAliasFromId(id, options.remotes);
|
|
2908
|
+
const remote = remoteAlias ? options.remotes[remoteAlias] : void 0;
|
|
2320
2909
|
const registerRemoteCode = isLoadedFirst && remote ? `runtime.registerRemotes([${JSON.stringify({
|
|
2321
2910
|
entryGlobalName: remote.entryGlobalName,
|
|
2322
2911
|
name: remote.name,
|
|
2912
|
+
alias: remoteAlias,
|
|
2323
2913
|
type: remote.type,
|
|
2324
2914
|
entry: remote.entry,
|
|
2325
2915
|
shareScope: remote.shareScope ?? "default"
|
|
@@ -2391,7 +2981,7 @@ function generateRemotes(id, command, enableSsrInit = false, consumer = "unified
|
|
|
2391
2981
|
const HOST_INIT_PRELOAD_CHUNKS = [
|
|
2392
2982
|
(name) => name === "hostInit",
|
|
2393
2983
|
(name) => name === "remoteEntry",
|
|
2394
|
-
(name) => name.startsWith("_virtual_mf"),
|
|
2984
|
+
(name) => name.startsWith("_virtual_mf") && !name.includes("__prebuild__"),
|
|
2395
2985
|
(name) => name === "index"
|
|
2396
2986
|
];
|
|
2397
2987
|
function escapeHtmlAttr(value) {
|
|
@@ -2593,7 +3183,7 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
|
|
|
2593
3183
|
return decodeViteId(id).replace(/^\0/, "");
|
|
2594
3184
|
}
|
|
2595
3185
|
function normalizeModuleId(id) {
|
|
2596
|
-
return id.split("?")[0]
|
|
3186
|
+
return normalizePathForImport(id.split("?")[0]);
|
|
2597
3187
|
}
|
|
2598
3188
|
function resolveProjectId(id) {
|
|
2599
3189
|
if (id.startsWith("\0") || id.startsWith("virtual:")) return normalizeModuleId(id);
|
|
@@ -2630,8 +3220,8 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
|
|
|
2630
3220
|
const resolvedEntryPath = getEntryPath();
|
|
2631
3221
|
if (resolvedEntryPath.startsWith("virtual:mf")) devEntryPath = config.base + VITE_ID_PREFIX.slice(1) + resolvedEntryPath;
|
|
2632
3222
|
else {
|
|
2633
|
-
const normalized = resolvedEntryPath
|
|
2634
|
-
const root = config.root
|
|
3223
|
+
const normalized = normalizePathForImport(resolvedEntryPath);
|
|
3224
|
+
const root = normalizePathForImport(config.root).replace(/\/$/, "");
|
|
2635
3225
|
const relativePath = normalized.startsWith(root + "/") ? normalized.slice(root.length) : "/" + normalized.replace(/^[A-Za-z]:[\\/]/, "");
|
|
2636
3226
|
devEntryPath = config.base + relativePath.replace(/^\//, "");
|
|
2637
3227
|
}
|
|
@@ -3382,7 +3972,7 @@ function initVirtualModules(command, remoteEntryId, enableSsrInit = false) {
|
|
|
3382
3972
|
function isOutputChunk$1(chunk) {
|
|
3383
3973
|
return chunk.type === "chunk";
|
|
3384
3974
|
}
|
|
3385
|
-
function escapeRegExp(value) {
|
|
3975
|
+
function escapeRegExp$1(value) {
|
|
3386
3976
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3387
3977
|
}
|
|
3388
3978
|
function getProxyBaseName(fileName) {
|
|
@@ -3474,7 +4064,7 @@ function rewriteEsmProxyConsumers(code, proxyChunks) {
|
|
|
3474
4064
|
const claimedLocals = /* @__PURE__ */ new Set();
|
|
3475
4065
|
for (const [proxyFileName, proxyInfo] of Array.from(proxyChunks.entries())) {
|
|
3476
4066
|
const proxyBaseName = getProxyBaseName(proxyFileName);
|
|
3477
|
-
const importMatch = new RegExp(`import\\s*\\{([^}]+)\\}\\s*from\\s*["']([^"']*${escapeRegExp(proxyBaseName)}[^"']*)["']\\s*;?`).exec(nextCode);
|
|
4067
|
+
const importMatch = new RegExp(`import\\s*\\{([^}]+)\\}\\s*from\\s*["']([^"']*${escapeRegExp$1(proxyBaseName)}[^"']*)["']\\s*;?`).exec(nextCode);
|
|
3478
4068
|
if (!importMatch) continue;
|
|
3479
4069
|
const fullImport = importMatch[0];
|
|
3480
4070
|
const bindings = importMatch[1].split(",").map((s) => {
|
|
@@ -3531,7 +4121,7 @@ function rewriteSystemProxyConsumers(code, systemProxyInfo) {
|
|
|
3531
4121
|
let nextCode = code;
|
|
3532
4122
|
for (const [proxyFileName, proxyInfo] of Array.from(systemProxyInfo.entries())) {
|
|
3533
4123
|
const proxyBaseName = getProxyBaseName(proxyFileName);
|
|
3534
|
-
const depMatch = new RegExp(`["']([^"']*${escapeRegExp(proxyBaseName)}[^"']*)["']`).exec(nextCode);
|
|
4124
|
+
const depMatch = new RegExp(`["']([^"']*${escapeRegExp$1(proxyBaseName)}[^"']*)["']`).exec(nextCode);
|
|
3535
4125
|
if (!depMatch) continue;
|
|
3536
4126
|
let setterIndex = 0;
|
|
3537
4127
|
const depListMatch = nextCode.match(/System\.register\(\[([\s\S]*?)\]/);
|
|
@@ -3890,10 +4480,28 @@ function createRemoteEntryAssetMap(fileName) {
|
|
|
3890
4480
|
}
|
|
3891
4481
|
};
|
|
3892
4482
|
}
|
|
4483
|
+
function isTreeShakingProviderChunk(file) {
|
|
4484
|
+
if (file.type !== "chunk") return false;
|
|
4485
|
+
if (file.facadeModuleId?.includes("__treeShakingProvider__")) return true;
|
|
4486
|
+
return Object.keys(file.modules || {}).some((id) => id.includes("__treeShakingProvider__") || id.includes("__mf_tree_shaking_graph__"));
|
|
4487
|
+
}
|
|
4488
|
+
function getTreeShakingBuildInfo(options) {
|
|
4489
|
+
if (!(Object.values(options.shared || {}).some((share) => !!share.shareConfig.treeShaking) || !!options.treeShakingSharedPlugins?.length || !!options.treeShakingSharedExcludePlugins?.length)) return {};
|
|
4490
|
+
return {
|
|
4491
|
+
target: [options.target || "web"],
|
|
4492
|
+
...options.treeShakingSharedPlugins?.length ? { plugins: [...options.treeShakingSharedPlugins] } : {},
|
|
4493
|
+
...options.treeShakingSharedExcludePlugins?.length ? { excludePlugins: [...options.treeShakingSharedExcludePlugins] } : {}
|
|
4494
|
+
};
|
|
4495
|
+
}
|
|
4496
|
+
function getRemoteContainerName(remoteKey, remote) {
|
|
4497
|
+
const entryGlobalName = remote.entryGlobalName;
|
|
4498
|
+
if (entryGlobalName && entryGlobalName !== remoteKey && entryGlobalName !== remote.entry) return entryGlobalName;
|
|
4499
|
+
return remote.name;
|
|
4500
|
+
}
|
|
3893
4501
|
const Manifest = () => {
|
|
3894
4502
|
const mfOptions = getNormalizeModuleFederationOptions();
|
|
3895
4503
|
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;
|
|
4504
|
+
let mfManifestName = manifestOptions === true ? "mf-manifest.json" : typeof manifestOptions === "object" ? normalizePathForImport(path$1.join(manifestOptions?.filePath || "", manifestOptions?.fileName || "mf-manifest.json")) : void 0;
|
|
3897
4505
|
let mfManifestStatsName = mfManifestName ? getStatsFileName(mfManifestName) : void 0;
|
|
3898
4506
|
const isConsumerProject = Object.keys(mfOptions.exposes).length === 0;
|
|
3899
4507
|
let disableAssetsAnalyze = false;
|
|
@@ -3942,7 +4550,8 @@ const Manifest = () => {
|
|
|
3942
4550
|
type: "app",
|
|
3943
4551
|
buildInfo: {
|
|
3944
4552
|
buildVersion: getBuildVersion(),
|
|
3945
|
-
buildName: name
|
|
4553
|
+
buildName: name,
|
|
4554
|
+
...getTreeShakingBuildInfo(mfOptions)
|
|
3946
4555
|
},
|
|
3947
4556
|
remoteEntry: {
|
|
3948
4557
|
name: devRemoteEntryFile,
|
|
@@ -3997,6 +4606,16 @@ const Manifest = () => {
|
|
|
3997
4606
|
if (foundRemoteEntryFile) remoteEntryFile = foundRemoteEntryFile;
|
|
3998
4607
|
ssrRemoteEntryFile = foundSsrRemoteEntryFile || (_command === "serve" ? getSsrRemoteEntryFileName(resolveDevRemoteEntryFileName(mfOptions.filename)) : expectedSsrRemoteEntryFile);
|
|
3999
4608
|
const allCssAssets = mfOptions.bundleAllCSS && !disableAssetsAnalyze ? collectCssAssets(bundle) : /* @__PURE__ */ new Set();
|
|
4609
|
+
if (allCssAssets.size > 0) {
|
|
4610
|
+
const secondaryCss = /* @__PURE__ */ new Set();
|
|
4611
|
+
const primaryCss = /* @__PURE__ */ new Set();
|
|
4612
|
+
for (const file of Object.values(bundle)) {
|
|
4613
|
+
if (file.type !== "chunk") continue;
|
|
4614
|
+
const target = isTreeShakingProviderChunk(file) ? secondaryCss : primaryCss;
|
|
4615
|
+
for (const css of file.viteMetadata?.importedCss || []) target.add(css);
|
|
4616
|
+
}
|
|
4617
|
+
for (const css of secondaryCss) if (!primaryCss.has(css)) allCssAssets.delete(css);
|
|
4618
|
+
}
|
|
4000
4619
|
if (!disableAssetsAnalyze) {
|
|
4001
4620
|
const exposesModules = Object.keys(mfOptions.exposes).map((item) => mfOptions.exposes[item].import);
|
|
4002
4621
|
processModuleAssets(bundle, filesMap, (modulePath) => {
|
|
@@ -4008,7 +4627,7 @@ const Manifest = () => {
|
|
|
4008
4627
|
stripKnownJsExtensions: true
|
|
4009
4628
|
});
|
|
4010
4629
|
const fileToShareKey = await buildFileToShareKeyMap(getUsedShares(), this.resolve.bind(this));
|
|
4011
|
-
processModuleAssets(bundle, filesMap, (modulePath) => fileToShareKey.get(modulePath));
|
|
4630
|
+
processModuleAssets(Object.fromEntries(Object.entries(bundle).filter(([, file]) => !isTreeShakingProviderChunk(file))), filesMap, (modulePath) => fileToShareKey.get(modulePath));
|
|
4012
4631
|
if (mfOptions.bundleAllCSS) addCssAssetsToAllExports(filesMap, allCssAssets);
|
|
4013
4632
|
filesMap = deduplicateAssets(filesMap);
|
|
4014
4633
|
}
|
|
@@ -4052,22 +4671,37 @@ const Manifest = () => {
|
|
|
4052
4671
|
path: "",
|
|
4053
4672
|
type: "var"
|
|
4054
4673
|
} : void 0;
|
|
4055
|
-
const remotes = Array.from(Object.entries(getUsedRemotesMap())).flatMap(([remoteKey, modules]) =>
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4674
|
+
const remotes = Array.from(Object.entries(getUsedRemotesMap())).flatMap(([remoteKey, modules]) => {
|
|
4675
|
+
const remote = options.remotes[remoteKey];
|
|
4676
|
+
return Array.from(modules).map((moduleKey) => ({
|
|
4677
|
+
federationContainerName: getRemoteContainerName(remoteKey, remote),
|
|
4678
|
+
moduleName: moduleKey.replace(remoteKey, "").replace("/", ""),
|
|
4679
|
+
alias: remoteKey,
|
|
4680
|
+
entry: "*"
|
|
4681
|
+
}));
|
|
4682
|
+
});
|
|
4061
4683
|
const shared = Array.from(getUsedShares()).flatMap((shareKey) => {
|
|
4062
4684
|
const shareItem = getNormalizeShareItem(shareKey);
|
|
4063
4685
|
if (!shareItem) return [];
|
|
4064
4686
|
const assets = preloadMap[shareKey] || (_command === "serve" && resolvedRemoteEntryFile ? createRemoteEntryAssetMap(resolvedRemoteEntryFile) : createEmptyAssetMap());
|
|
4687
|
+
const treeShakingUsage = getTreeShakingExportUsage(shareKey, shareItem, shareItem.name);
|
|
4688
|
+
const treeShakingUsedExports = treeShakingUsage?.kind === "exports" ? treeShakingUsage.usedExports : [];
|
|
4689
|
+
const treeShakingStatus = treeShakingUsage?.kind === "full" ? 0 : 1;
|
|
4065
4690
|
return [{
|
|
4066
4691
|
id: `${name}:${shareKey}`,
|
|
4067
4692
|
name: shareKey,
|
|
4068
4693
|
version: shareItem.version,
|
|
4069
4694
|
singleton: shareItem.shareConfig.singleton,
|
|
4070
4695
|
requiredVersion: shareItem.shareConfig.requiredVersion,
|
|
4696
|
+
...shareItem.shareConfig.treeShaking ? {
|
|
4697
|
+
usedExports: treeShakingUsedExports,
|
|
4698
|
+
referenceExports: treeShakingUsedExports,
|
|
4699
|
+
treeShaking: {
|
|
4700
|
+
mode: shareItem.shareConfig.treeShaking.mode,
|
|
4701
|
+
...treeShakingUsage?.kind === "exports" ? { usedExports: treeShakingUsedExports } : {},
|
|
4702
|
+
status: treeShakingStatus
|
|
4703
|
+
}
|
|
4704
|
+
} : {},
|
|
4071
4705
|
assets: {
|
|
4072
4706
|
js: {
|
|
4073
4707
|
async: assets.js.async,
|
|
@@ -4107,7 +4741,8 @@ const Manifest = () => {
|
|
|
4107
4741
|
type: "app",
|
|
4108
4742
|
buildInfo: {
|
|
4109
4743
|
buildVersion: getBuildVersion(),
|
|
4110
|
-
buildName: name
|
|
4744
|
+
buildName: name,
|
|
4745
|
+
...getTreeShakingBuildInfo(options)
|
|
4111
4746
|
},
|
|
4112
4747
|
remoteEntry,
|
|
4113
4748
|
ssrRemoteEntry,
|
|
@@ -4152,32 +4787,41 @@ function getStatsFileName(manifestFileName) {
|
|
|
4152
4787
|
const fileExt = parsed.ext || ".json";
|
|
4153
4788
|
const baseName = parsed.ext ? parsed.name : parsed.base;
|
|
4154
4789
|
const fileName = `${baseName === "mf-manifest" ? "mf" : baseName}-stats${fileExt}`;
|
|
4155
|
-
return parsed.dir ? path$1.join(parsed.dir, fileName) : fileName;
|
|
4790
|
+
return parsed.dir ? normalizePathForImport(path$1.join(parsed.dir, fileName)) : fileName;
|
|
4156
4791
|
}
|
|
4157
4792
|
//#endregion
|
|
4158
4793
|
//#region src/plugins/pluginModuleParseEnd.ts
|
|
4159
4794
|
let _resolve = null;
|
|
4160
4795
|
let _parseTimeout = null;
|
|
4796
|
+
let _settleTimeout = null;
|
|
4161
4797
|
let parsePromise = Promise.resolve(1);
|
|
4162
|
-
let exposesParseEnd = false;
|
|
4163
|
-
let expectsExposesParseEnd = false;
|
|
4164
4798
|
let parseStartSet = /* @__PURE__ */ new Set();
|
|
4165
4799
|
let parseEndSet = /* @__PURE__ */ new Set();
|
|
4800
|
+
let lastLoadedModule = "";
|
|
4801
|
+
let lastParsedModule = "";
|
|
4166
4802
|
function clearParseTimeout() {
|
|
4167
4803
|
if (_parseTimeout) {
|
|
4168
4804
|
clearTimeout(_parseTimeout);
|
|
4169
4805
|
_parseTimeout = null;
|
|
4170
4806
|
}
|
|
4171
4807
|
}
|
|
4808
|
+
function clearSettleTimeout() {
|
|
4809
|
+
if (_settleTimeout) {
|
|
4810
|
+
clearTimeout(_settleTimeout);
|
|
4811
|
+
_settleTimeout = null;
|
|
4812
|
+
}
|
|
4813
|
+
}
|
|
4172
4814
|
function resetParseState() {
|
|
4173
4815
|
clearParseTimeout();
|
|
4174
|
-
|
|
4175
|
-
expectsExposesParseEnd = false;
|
|
4816
|
+
clearSettleTimeout();
|
|
4176
4817
|
parseStartSet = /* @__PURE__ */ new Set();
|
|
4177
4818
|
parseEndSet = /* @__PURE__ */ new Set();
|
|
4819
|
+
lastLoadedModule = "";
|
|
4820
|
+
lastParsedModule = "";
|
|
4178
4821
|
parsePromise = new Promise((resolve) => {
|
|
4179
4822
|
_resolve = (v) => {
|
|
4180
4823
|
clearParseTimeout();
|
|
4824
|
+
clearSettleTimeout();
|
|
4181
4825
|
resolve(v);
|
|
4182
4826
|
};
|
|
4183
4827
|
});
|
|
@@ -4191,10 +4835,18 @@ function setParseTimeout(timeout) {
|
|
|
4191
4835
|
function resetIdleTimeout(timeout) {
|
|
4192
4836
|
clearParseTimeout();
|
|
4193
4837
|
_parseTimeout = setTimeout(() => {
|
|
4194
|
-
|
|
4838
|
+
const pendingModules = Array.from(parseStartSet).filter((moduleId) => !parseEndSet.has(moduleId));
|
|
4839
|
+
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
4840
|
_resolve?.(1);
|
|
4196
4841
|
}, timeout * 1e3);
|
|
4197
4842
|
}
|
|
4843
|
+
function scheduleParseCompletionCheck() {
|
|
4844
|
+
clearSettleTimeout();
|
|
4845
|
+
_settleTimeout = setTimeout(() => {
|
|
4846
|
+
_settleTimeout = null;
|
|
4847
|
+
if (parseStartSet.size > 0 && Array.from(parseStartSet).every((moduleId) => parseEndSet.has(moduleId))) _resolve?.(1);
|
|
4848
|
+
}, 10);
|
|
4849
|
+
}
|
|
4198
4850
|
function pluginModuleParseEnd_default(excludeFn, options) {
|
|
4199
4851
|
const idleTimeout = options.moduleParseIdleTimeout ?? options.moduleParseTimeout;
|
|
4200
4852
|
return [
|
|
@@ -4209,14 +4861,20 @@ function pluginModuleParseEnd_default(excludeFn, options) {
|
|
|
4209
4861
|
enforce: "pre",
|
|
4210
4862
|
name: "parseStart",
|
|
4211
4863
|
apply: "build",
|
|
4212
|
-
buildStart() {
|
|
4864
|
+
async buildStart() {
|
|
4213
4865
|
resetParseState();
|
|
4214
4866
|
if (idleTimeout) resetIdleTimeout(idleTimeout);
|
|
4215
|
-
else setParseTimeout(options.moduleParseTimeout);
|
|
4867
|
+
else if (options.moduleParseTimeout) setParseTimeout(options.moduleParseTimeout);
|
|
4868
|
+
for (const importSource of options.exposedModuleImports || []) {
|
|
4869
|
+
const resolved = await this.resolve(importSource);
|
|
4870
|
+
if (resolved && !resolved.external && !excludeFn(resolved.id)) parseStartSet.add(resolved.id);
|
|
4871
|
+
}
|
|
4216
4872
|
},
|
|
4217
4873
|
load(id) {
|
|
4874
|
+
lastLoadedModule = id;
|
|
4218
4875
|
if (excludeFn(id)) return;
|
|
4219
|
-
|
|
4876
|
+
clearSettleTimeout();
|
|
4877
|
+
if (idleTimeout) resetIdleTimeout(idleTimeout);
|
|
4220
4878
|
parseStartSet.add(id);
|
|
4221
4879
|
}
|
|
4222
4880
|
},
|
|
@@ -4225,12 +4883,18 @@ function pluginModuleParseEnd_default(excludeFn, options) {
|
|
|
4225
4883
|
name: "parseEnd",
|
|
4226
4884
|
apply: "build",
|
|
4227
4885
|
moduleParsed(module) {
|
|
4886
|
+
clearSettleTimeout();
|
|
4228
4887
|
const id = module.id;
|
|
4229
|
-
|
|
4888
|
+
lastParsedModule = id;
|
|
4230
4889
|
if (idleTimeout) resetIdleTimeout(idleTimeout);
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4890
|
+
const parsedModule = module;
|
|
4891
|
+
const addPendingResolutions = (resolutions) => {
|
|
4892
|
+
for (const resolution of resolutions || []) if (!resolution.external && !excludeFn(resolution.id)) parseStartSet.add(resolution.id);
|
|
4893
|
+
};
|
|
4894
|
+
addPendingResolutions(parsedModule.importedIdResolutions);
|
|
4895
|
+
addPendingResolutions(parsedModule.dynamicallyImportedIdResolutions);
|
|
4896
|
+
if (!excludeFn(id)) parseEndSet.add(id);
|
|
4897
|
+
scheduleParseCompletionCheck();
|
|
4234
4898
|
},
|
|
4235
4899
|
buildEnd() {
|
|
4236
4900
|
_resolve?.(1);
|
|
@@ -4249,6 +4913,9 @@ function resolveDevHashEntryFileName(fileName) {
|
|
|
4249
4913
|
function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposesId }) {
|
|
4250
4914
|
let viteConfig, _command, root;
|
|
4251
4915
|
let exposeRemoteDependencies = {};
|
|
4916
|
+
let exposeRemoteDependenciesDirty = true;
|
|
4917
|
+
let refreshPromise;
|
|
4918
|
+
let dependencyInvalidationVersion = 0;
|
|
4252
4919
|
function isRemoteImport(source) {
|
|
4253
4920
|
return Object.keys(options.remotes).some((name) => source === name || source.startsWith(name + "/"));
|
|
4254
4921
|
}
|
|
@@ -4287,12 +4954,26 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
4287
4954
|
return Array.from(dependencies).sort();
|
|
4288
4955
|
}
|
|
4289
4956
|
async function refreshExposeRemoteDependencies(ctx) {
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
const
|
|
4293
|
-
|
|
4957
|
+
if (!exposeRemoteDependenciesDirty) return;
|
|
4958
|
+
if (!refreshPromise) {
|
|
4959
|
+
const refreshVersion = dependencyInvalidationVersion;
|
|
4960
|
+
refreshPromise = (async () => {
|
|
4961
|
+
const next = {};
|
|
4962
|
+
for (const [exposeKey, expose] of Object.entries(options.exposes)) {
|
|
4963
|
+
const resolved = await ctx.resolve(expose.import);
|
|
4964
|
+
next[exposeKey] = resolved?.id ? await collectRemoteDependencies(ctx, resolved.id) : [];
|
|
4965
|
+
}
|
|
4966
|
+
exposeRemoteDependencies = next;
|
|
4967
|
+
if (refreshVersion === dependencyInvalidationVersion) exposeRemoteDependenciesDirty = false;
|
|
4968
|
+
})().finally(() => {
|
|
4969
|
+
refreshPromise = void 0;
|
|
4970
|
+
});
|
|
4294
4971
|
}
|
|
4295
|
-
|
|
4972
|
+
await refreshPromise;
|
|
4973
|
+
}
|
|
4974
|
+
function invalidateExposeRemoteDependencies() {
|
|
4975
|
+
exposeRemoteDependenciesDirty = true;
|
|
4976
|
+
dependencyInvalidationVersion += 1;
|
|
4296
4977
|
}
|
|
4297
4978
|
return {
|
|
4298
4979
|
name: "proxyRemoteEntry",
|
|
@@ -4315,6 +4996,12 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
4315
4996
|
});
|
|
4316
4997
|
}
|
|
4317
4998
|
},
|
|
4999
|
+
watchChange() {
|
|
5000
|
+
invalidateExposeRemoteDependencies();
|
|
5001
|
+
},
|
|
5002
|
+
handleHotUpdate() {
|
|
5003
|
+
invalidateExposeRemoteDependencies();
|
|
5004
|
+
},
|
|
4318
5005
|
async resolveId(id, importer) {
|
|
4319
5006
|
if (id === remoteEntryId) return remoteEntryId;
|
|
4320
5007
|
if (id === virtualExposesId) return virtualExposesId;
|
|
@@ -4325,16 +5012,22 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
4325
5012
|
if (resolved) return resolved;
|
|
4326
5013
|
}
|
|
4327
5014
|
},
|
|
4328
|
-
load(id) {
|
|
5015
|
+
async load(id) {
|
|
4329
5016
|
if (id === remoteEntryId) return parsePromise.then((_) => generateRemoteEntry(options, virtualExposesId, _command));
|
|
4330
|
-
if (id === virtualExposesId)
|
|
5017
|
+
if (id === virtualExposesId) {
|
|
5018
|
+
await refreshExposeRemoteDependencies(this);
|
|
5019
|
+
return generateExposes(options, exposeRemoteDependencies, _command);
|
|
5020
|
+
}
|
|
4331
5021
|
if (_command === "serve" && id.includes(getHostAutoInitPath())) return id;
|
|
4332
5022
|
},
|
|
4333
|
-
transform(code, id) {
|
|
4334
|
-
return mapCodeToCodeWithSourcemap((() => {
|
|
5023
|
+
async transform(code, id) {
|
|
5024
|
+
return mapCodeToCodeWithSourcemap(await (async () => {
|
|
4335
5025
|
if (!filterId(id)) return;
|
|
4336
5026
|
if (id.includes(remoteEntryId)) return parsePromise.then((_) => generateRemoteEntry(options, virtualExposesId, _command));
|
|
4337
|
-
if (id === virtualExposesId)
|
|
5027
|
+
if (id === virtualExposesId) {
|
|
5028
|
+
await refreshExposeRemoteDependencies(this);
|
|
5029
|
+
return generateExposes(options, exposeRemoteDependencies, _command);
|
|
5030
|
+
}
|
|
4338
5031
|
if (id.includes(getHostAutoInitPath())) {
|
|
4339
5032
|
if (_command === "serve") {
|
|
4340
5033
|
const host = typeof viteConfig.server?.host === "string" && viteConfig.server.host !== "0.0.0.0" ? viteConfig.server.host : "localhost";
|
|
@@ -4409,6 +5102,9 @@ function resolveRemoteConsumer(ctx, hasMultiEnvironment) {
|
|
|
4409
5102
|
function isNodeModulesImporter(importer) {
|
|
4410
5103
|
return importer?.includes("/node_modules/") || importer?.includes("\\node_modules\\");
|
|
4411
5104
|
}
|
|
5105
|
+
function escapeRegExp(value) {
|
|
5106
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
5107
|
+
}
|
|
4412
5108
|
function appendAlias(config, alias) {
|
|
4413
5109
|
config.resolve ??= {};
|
|
4414
5110
|
const existingAlias = config.resolve.alias;
|
|
@@ -4451,10 +5147,9 @@ function pluginProxyRemotes_default(options) {
|
|
|
4451
5147
|
config(config, { command: _command }) {
|
|
4452
5148
|
command = _command;
|
|
4453
5149
|
root = config.root || process.cwd();
|
|
4454
|
-
Object.keys(remotes).forEach((
|
|
4455
|
-
const remote = remotes[key];
|
|
5150
|
+
Object.keys(remotes).forEach((remoteAlias) => {
|
|
4456
5151
|
appendAlias(config, {
|
|
4457
|
-
find: new RegExp(`^(${
|
|
5152
|
+
find: new RegExp(`^(${escapeRegExp(remoteAlias)}(\/.*|$))`),
|
|
4458
5153
|
replacement: "$1"
|
|
4459
5154
|
});
|
|
4460
5155
|
});
|
|
@@ -4465,9 +5160,9 @@ function pluginProxyRemotes_default(options) {
|
|
|
4465
5160
|
},
|
|
4466
5161
|
resolveId(source, importer) {
|
|
4467
5162
|
if (!filterId(source)) return;
|
|
4468
|
-
for (const
|
|
4469
|
-
if (source !==
|
|
4470
|
-
return resolveRemoteId(this, source, importer,
|
|
5163
|
+
for (const remoteAlias of Object.keys(remotes)) {
|
|
5164
|
+
if (source !== remoteAlias && !source.startsWith(`${remoteAlias}/`)) continue;
|
|
5165
|
+
return resolveRemoteId(this, source, importer, remoteAlias);
|
|
4471
5166
|
}
|
|
4472
5167
|
}
|
|
4473
5168
|
};
|
|
@@ -4625,6 +5320,36 @@ function proxySharedModule(options) {
|
|
|
4625
5320
|
const savePrebuild = new PromiseStore();
|
|
4626
5321
|
let devServer;
|
|
4627
5322
|
const materializedLoadShareSources = /* @__PURE__ */ new Set();
|
|
5323
|
+
const emittedTreeShakingProviders = /* @__PURE__ */ new Set();
|
|
5324
|
+
const normalizeTreeShakingOutputPath = (value) => {
|
|
5325
|
+
const normalized = normalizePathForImport(value);
|
|
5326
|
+
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.`);
|
|
5327
|
+
let start = normalized.startsWith("./") ? 2 : 0;
|
|
5328
|
+
let end = normalized.length;
|
|
5329
|
+
while (start < end && normalized.charCodeAt(start) === 47) start++;
|
|
5330
|
+
while (end > start && normalized.charCodeAt(end - 1) === 47) end--;
|
|
5331
|
+
return normalized.slice(start, end);
|
|
5332
|
+
};
|
|
5333
|
+
const getTreeShakingProviderFileName = (pkg, shareItem) => {
|
|
5334
|
+
if (!shareItem.shareConfig.treeShaking) return void 0;
|
|
5335
|
+
const normalizedOptions = getNormalizeModuleFederationOptions();
|
|
5336
|
+
const outputDir = normalizedOptions.treeShakingDir ? normalizeTreeShakingOutputPath(normalizedOptions.treeShakingDir) : void 0;
|
|
5337
|
+
const fileName = outputDir ? path$1.posix.join(outputDir, `${getTreeShakingSharedProviderName(pkg)}.js`) : void 0;
|
|
5338
|
+
if (!fileName) return void 0;
|
|
5339
|
+
return fileName;
|
|
5340
|
+
};
|
|
5341
|
+
const emitTreeShakingProvider = (context, pkg, shareItem) => {
|
|
5342
|
+
if (_command !== "build" || emittedTreeShakingProviders.has(pkg)) return;
|
|
5343
|
+
if (!hasTreeShakingSharedProvider(pkg, shareItem)) return;
|
|
5344
|
+
const fileName = getTreeShakingProviderFileName(pkg, shareItem);
|
|
5345
|
+
context.emitFile({
|
|
5346
|
+
type: "chunk",
|
|
5347
|
+
id: getTreeShakingSharedProviderImportId(pkg),
|
|
5348
|
+
name: getTreeShakingSharedProviderName(pkg),
|
|
5349
|
+
...fileName ? { fileName } : {}
|
|
5350
|
+
});
|
|
5351
|
+
emittedTreeShakingProviders.add(pkg);
|
|
5352
|
+
};
|
|
4628
5353
|
return [
|
|
4629
5354
|
{
|
|
4630
5355
|
name: "generateLocalSharedImportMap",
|
|
@@ -4640,7 +5365,16 @@ function proxySharedModule(options) {
|
|
|
4640
5365
|
if (source === getLocalSharedImportMapPath()) return getResolvedLocalSharedImportMapId();
|
|
4641
5366
|
},
|
|
4642
5367
|
load(id) {
|
|
4643
|
-
if (id === getResolvedLocalSharedImportMapId()) return parsePromise.then((_) =>
|
|
5368
|
+
if (id === getResolvedLocalSharedImportMapId()) return parsePromise.then((_) => {
|
|
5369
|
+
refreshTreeShakingModules();
|
|
5370
|
+
const providerPackages = new Set([...Object.keys(shared).filter((pkg) => !pkg.endsWith("/")), ...getUsedShares()]);
|
|
5371
|
+
for (const pkg of providerPackages) {
|
|
5372
|
+
const sharedKey = findSharedKeyForSource(pkg, shared);
|
|
5373
|
+
const shareItem = shared[pkg] || (sharedKey ? shared[sharedKey] : void 0);
|
|
5374
|
+
if (shareItem) emitTreeShakingProvider(this, pkg, shareItem);
|
|
5375
|
+
}
|
|
5376
|
+
return generateLocalSharedImportMap();
|
|
5377
|
+
});
|
|
4644
5378
|
},
|
|
4645
5379
|
closeBundle() {
|
|
4646
5380
|
if (devServer) return;
|
|
@@ -4652,6 +5386,9 @@ function proxySharedModule(options) {
|
|
|
4652
5386
|
enforce: "post",
|
|
4653
5387
|
config(config, { command }) {
|
|
4654
5388
|
setPackageDetectionCwd(config.root || process.cwd());
|
|
5389
|
+
setTreeShakingBuildMode(command === "build");
|
|
5390
|
+
resetTreeShakingExports();
|
|
5391
|
+
emittedTreeShakingProviders.clear();
|
|
4655
5392
|
const isVinext = hasPackageDependency("vinext");
|
|
4656
5393
|
const isAstro = hasPackageDependency("astro");
|
|
4657
5394
|
const isRolldown = getIsRolldown(this);
|
|
@@ -4675,12 +5412,62 @@ function proxySharedModule(options) {
|
|
|
4675
5412
|
});
|
|
4676
5413
|
writeLocalSharedImportMap();
|
|
4677
5414
|
refreshHostAutoInit();
|
|
5415
|
+
},
|
|
5416
|
+
buildStart() {
|
|
5417
|
+
if (_command !== "build") return;
|
|
5418
|
+
resetTreeShakingExports();
|
|
5419
|
+
emittedTreeShakingProviders.clear();
|
|
5420
|
+
refreshTreeShakingModules();
|
|
5421
|
+
},
|
|
5422
|
+
shouldTransformCachedModule() {
|
|
5423
|
+
return _command === "build" && Object.values(shared).some((share) => !!share.shareConfig.treeShaking);
|
|
5424
|
+
},
|
|
5425
|
+
transform(code, id) {
|
|
5426
|
+
if (_command !== "build" || !Object.keys(shared).some((key) => shared[key].shareConfig.treeShaking)) return;
|
|
5427
|
+
collectTreeShakingImports(code, id, shared, findSharedKeyForSource, recordTreeShakingExports, markTreeShakingPackageUnsafe);
|
|
5428
|
+
refreshTreeShakingModules();
|
|
5429
|
+
}
|
|
5430
|
+
},
|
|
5431
|
+
{
|
|
5432
|
+
name: "proxyPreBuildShared:tree-shaking-graph",
|
|
5433
|
+
enforce: "pre",
|
|
5434
|
+
apply: "build",
|
|
5435
|
+
async resolveId(source, importer, resolveOptions) {
|
|
5436
|
+
const sourceToken = getTreeShakingGraphToken(source);
|
|
5437
|
+
const importerToken = getTreeShakingGraphToken(importer);
|
|
5438
|
+
const token = sourceToken || importerToken;
|
|
5439
|
+
if (!token) return;
|
|
5440
|
+
const cleanSource = normalizePathForImport(stripTreeShakingGraphQuery(source));
|
|
5441
|
+
const cleanImporter = importer ? normalizePathForImport(stripTreeShakingGraphQuery(importer)) : void 0;
|
|
5442
|
+
if (!sourceToken && importerToken) {
|
|
5443
|
+
const nestedSharedKey = findSharedKeyForSource(cleanSource, shared);
|
|
5444
|
+
if (nestedSharedKey && getPackageName(nestedSharedKey) !== getPackageName(importerToken)) return this.resolve(cleanSource, cleanImporter, {
|
|
5445
|
+
...resolveOptions,
|
|
5446
|
+
skipSelf: true
|
|
5447
|
+
});
|
|
5448
|
+
}
|
|
5449
|
+
const projectResolvedSource = sourceToken ? tryResolveFromProjectRoot(cleanSource) || cleanSource : cleanSource;
|
|
5450
|
+
const resolved = await this.resolve(projectResolvedSource, cleanImporter, {
|
|
5451
|
+
...resolveOptions,
|
|
5452
|
+
custom: {
|
|
5453
|
+
...resolveOptions.custom,
|
|
5454
|
+
__mfTreeShakingGraph: true
|
|
5455
|
+
},
|
|
5456
|
+
skipSelf: true
|
|
5457
|
+
});
|
|
5458
|
+
if (!resolved || resolved.external) return resolved;
|
|
5459
|
+
if (resolved.id.startsWith("\0")) return resolved;
|
|
5460
|
+
return {
|
|
5461
|
+
...resolved,
|
|
5462
|
+
id: addTreeShakingGraphQuery(normalizePathForImport(resolved.id), token)
|
|
5463
|
+
};
|
|
4678
5464
|
}
|
|
4679
5465
|
},
|
|
4680
5466
|
{
|
|
4681
5467
|
name: "proxyPreBuildShared:resolve-shared-loadShare",
|
|
4682
5468
|
enforce: "pre",
|
|
4683
|
-
async resolveId(source, importer) {
|
|
5469
|
+
async resolveId(source, importer, resolveOptions) {
|
|
5470
|
+
if (resolveOptions.custom?.__mfTreeShakingGraph) return;
|
|
4684
5471
|
function shouldSkipTaggedImporterProxy(sharedKey, tag) {
|
|
4685
5472
|
if (!importer?.includes(tag)) return false;
|
|
4686
5473
|
const taggedModule = VirtualModule.findModule(tag, importer);
|
|
@@ -5642,10 +6429,10 @@ function hasImportFalseShared(options) {
|
|
|
5642
6429
|
}
|
|
5643
6430
|
function getRuntimeHelpersImplementation(runtimeImplementation) {
|
|
5644
6431
|
const indexEntryMatch = runtimeImplementation.match(/^(.*[\\/])index(\.[cm]?js)$/);
|
|
5645
|
-
if (indexEntryMatch) return `${indexEntryMatch[1]}helpers${indexEntryMatch[2]}
|
|
6432
|
+
if (indexEntryMatch) return normalizePathForImport(`${indexEntryMatch[1]}helpers${indexEntryMatch[2]}`);
|
|
5646
6433
|
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");
|
|
6434
|
+
if (extension) return normalizePathForImport(path$1.join(path$1.dirname(runtimeImplementation), `helpers${extension}`));
|
|
6435
|
+
if (path$1.isAbsolute(runtimeImplementation) || runtimeImplementation.startsWith(".")) return normalizePathForImport(path$1.join(runtimeImplementation, "helpers"));
|
|
5649
6436
|
return `${runtimeImplementation.replace(/\/$/, "")}/helpers`;
|
|
5650
6437
|
}
|
|
5651
6438
|
const UNSAFE_JS_SOURCE_CHAR_MAP = {
|
|
@@ -5828,7 +6615,7 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
5828
6615
|
const optimizeDeps = config.optimizeDeps ??= {};
|
|
5829
6616
|
optimizeDeps.include ??= [];
|
|
5830
6617
|
optimizeDeps.exclude ??= [];
|
|
5831
|
-
const shouldBypassOptimizeDep = isLitShare(key)
|
|
6618
|
+
const shouldBypassOptimizeDep = isLitShare(key);
|
|
5832
6619
|
if (optimizeDeps.include.includes(key)) optimizeDeps.exclude = optimizeDeps.exclude.filter((dep) => dep !== key);
|
|
5833
6620
|
else if (shouldBypassOptimizeDep) optimizeDeps.exclude.push(key);
|
|
5834
6621
|
else optimizeDeps.include.push(key);
|
|
@@ -5883,13 +6670,14 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
5883
6670
|
const SSR_ONLY_PLUGINS = new Set(["@module-federation/vite/ssrEntryLoader"]);
|
|
5884
6671
|
function loadPluginDts(options) {
|
|
5885
6672
|
if (options.dts === false) return [];
|
|
5886
|
-
return [import("./pluginDts-
|
|
6673
|
+
return [import("./pluginDts-BcvLBYP3.js").then((n) => n.n).then(({ default: pluginDts }) => pluginDts(options))];
|
|
5887
6674
|
}
|
|
5888
6675
|
function federation(mfUserOptions) {
|
|
5889
6676
|
if (isTestEnv()) return [];
|
|
5890
6677
|
const options = normalizeModuleFederationOptions(mfUserOptions);
|
|
5891
6678
|
const isVinext = hasPackageDependency("vinext");
|
|
5892
6679
|
const { name, shared, filename, hostInitInjectLocation } = options;
|
|
6680
|
+
const hasTreeShakingShared = Object.values(shared).some((share) => !!share.shareConfig.treeShaking);
|
|
5893
6681
|
if (!name) throw createModuleFederationError("name is required");
|
|
5894
6682
|
const remoteEntryId = getRemoteEntryId(options);
|
|
5895
6683
|
const virtualExposesId = getVirtualExposesId(options);
|
|
@@ -5995,11 +6783,11 @@ function federation(mfUserOptions) {
|
|
|
5995
6783
|
pluginProxyRemotes_default(options),
|
|
5996
6784
|
pluginRemoteNamedExports(options),
|
|
5997
6785
|
...pluginModuleParseEnd_default((id) => {
|
|
5998
|
-
return id.includes(getHostAutoInitImportId()) || id.includes(remoteEntryId) || id.includes(virtualExposesId) || id.includes(getLocalSharedImportMapPath()) || id.includes("__loadShare__") || id.includes("__prebuild__");
|
|
6786
|
+
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
6787
|
}, {
|
|
6000
6788
|
moduleParseTimeout: options.moduleParseTimeout,
|
|
6001
6789
|
moduleParseIdleTimeout: options.moduleParseIdleTimeout,
|
|
6002
|
-
|
|
6790
|
+
exposedModuleImports: Object.values(options.exposes).map((expose) => expose.import)
|
|
6003
6791
|
}),
|
|
6004
6792
|
...proxySharedModule({ shared }),
|
|
6005
6793
|
{
|
|
@@ -6021,7 +6809,8 @@ function federation(mfUserOptions) {
|
|
|
6021
6809
|
if (context.hostType === "js" && (hostFile === options.filename || hostFile.includes("hostInit") || hostFile.includes("virtualExposes") || hostFile.includes("localSharedImportMap"))) return [];
|
|
6022
6810
|
const hasFederationHtmlDeps = context.hostType === "html" && resolvedDeps.some((dep) => isFederationHtmlPreloadDependency(dep));
|
|
6023
6811
|
const hasFederationJsDeps = context.hostType === "js" && resolvedDeps.some((dep) => isFederationHtmlPreloadDependency(dep));
|
|
6024
|
-
|
|
6812
|
+
const treeShakingFallbackDeps = hasTreeShakingShared ? (dep) => dep.includes("__prebuild__") : () => false;
|
|
6813
|
+
return hasFederationHtmlDeps || hasFederationJsDeps ? resolvedDeps.filter((dep) => !isFederationHtmlPreloadDependency(dep, true) && !treeShakingFallbackDeps(dep)) : resolvedDeps.filter((dep) => !treeShakingFallbackDeps(dep));
|
|
6025
6814
|
}
|
|
6026
6815
|
};
|
|
6027
6816
|
}
|
|
@@ -6195,8 +6984,8 @@ function federation(mfUserOptions) {
|
|
|
6195
6984
|
config(config, { command: _command }) {
|
|
6196
6985
|
const isRolldown = getIsRolldown(this);
|
|
6197
6986
|
isSsrBuild = _command === "build" && config.build?.ssr === true;
|
|
6198
|
-
const
|
|
6199
|
-
if (
|
|
6987
|
+
const needsRuntimeHelpers = hasImportFalseShared(options) || Object.values(options.shared ?? {}).some((share) => !!share?.shareConfig.treeShaking);
|
|
6988
|
+
if (needsRuntimeHelpers) appendResolveAlias(config, {
|
|
6200
6989
|
find: /^@module-federation\/runtime\/helpers$/,
|
|
6201
6990
|
replacement: getRuntimeHelpersImplementation(options.implementation)
|
|
6202
6991
|
});
|
|
@@ -6210,7 +6999,7 @@ function federation(mfUserOptions) {
|
|
|
6210
6999
|
config.optimizeDeps ||= {};
|
|
6211
7000
|
config.optimizeDeps.include ||= [];
|
|
6212
7001
|
config.optimizeDeps.include.push("@module-federation/runtime");
|
|
6213
|
-
if (
|
|
7002
|
+
if (needsRuntimeHelpers) config.optimizeDeps.include.push("@module-federation/runtime/helpers");
|
|
6214
7003
|
options.runtimePlugins.forEach((p) => {
|
|
6215
7004
|
const pluginPath = typeof p === "string" ? p : p[0];
|
|
6216
7005
|
if (SSR_ONLY_PLUGINS.has(pluginPath)) return;
|