@module-federation/vite 1.22.1 → 1.23.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 +19 -0
- package/lib/{dtsConstants-dDsHZFC1.js → dtsConstants-DEMpRfBz.js} +231 -59
- package/lib/index.d.ts +14 -1
- package/lib/index.js +1076 -366
- package/lib/{pluginDts-CQ088qGF.js → pluginDts-VSLhAx6d.js} +1 -1
- package/lib/{sharedKeyMatcher-BRzBCbuR.js → sharedKeyMatcher-Od_nYxJA.js} +39 -10
- package/lib/{ssrEntryLoader-BUXUQi0P.js → ssrEntryLoader-BvAkpCyi.js} +1 -1
- package/lib/{ssrVmStrategy-Ud06y3Xf.js → ssrVmStrategy-CDbcwMnf.js} +2 -2
- package/lib/utils/ssrEntryLoader.js +1 -1
- package/package.json +4 -4
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { _ as
|
|
1
|
+
import { _ as resolvePublicPath, a as matchesSharedSource, c as filterId, d as getNodeModulesSuffix, f as isAssetLikeImport, g as normalizeNodeModulePath, h as isViteOptimizableEntry, i as invalidateSharedKeyMatcher, l as getBasePath$1, m as isNuxtClientBase, n as getSharedRequest, p as isNodeModulePath, r as getSharedRuntimeKey, s as ensureTrailingSlash, t as findSharedKey, u as getCommonSharedSubpaths, v as stripQueryAndHash, y as stripViteFsPrefix } from "./sharedKeyMatcher-Od_nYxJA.js";
|
|
2
2
|
import { i as resolveHashPlaceholderFileName, n as normalizePathForImport, r as rebaseImport } from "./buildPaths-BoaQTkxt.js";
|
|
3
|
-
import { _ as
|
|
3
|
+
import { C as isReactCoreShare, E as mfWarn, S as REACT_DOM_CLIENT_SHARE, _ as resolveModulePath, a as getIsRolldown, b as supportsCodeSplittingGroupDebugName, c as getPackageNameFromNodeModulePath, d as isNuxtProjectRoot, f as isPackageExportAvailable, g as resolveImportPath, h as packageNameEncode, i as getInstalledPackageJson, l as getSharedCacheDescriptor, m as packageNameDecode, n as getDependencyNames, o as getPackageDetectionCwd, p as isPackageInstalled, r as getInstalledPackageEntry, s as getPackageName, u as hasPackageDependency, v as setPackageDetectionCwd, w as createModuleFederationError, x as REACT_CLIENT_INTERNALS_KEY, y as sharedCacheHelperCode } from "./dtsConstants-DEMpRfBz.js";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import * as fs$2 from "fs";
|
|
6
6
|
import { existsSync, readFileSync, readdirSync, realpathSync, statSync, writeFileSync } from "fs";
|
|
@@ -8,6 +8,7 @@ import { createRequire as createRequire$1, isBuiltin } from "module";
|
|
|
8
8
|
import * as path$1 from "node:path";
|
|
9
9
|
import path, { basename } from "node:path";
|
|
10
10
|
import { fileURLToPath, pathToFileURL } from "url";
|
|
11
|
+
import * as vite from "vite";
|
|
11
12
|
import { parseAst, version } from "vite";
|
|
12
13
|
import { createHash } from "node:crypto";
|
|
13
14
|
import * as fs$1 from "node:fs";
|
|
@@ -400,6 +401,16 @@ function resolveEnvironmentConsumerTarget(ctx) {
|
|
|
400
401
|
function isClientEnvironment(ctx) {
|
|
401
402
|
return resolveEnvironmentConsumerTarget(ctx) !== "server";
|
|
402
403
|
}
|
|
404
|
+
/**
|
|
405
|
+
* Whether a build hook runs for a server graph. Vite 6+ hooks carry an
|
|
406
|
+
* environment; Vite 5 (and hooks invoked before `configResolved`) fall back to
|
|
407
|
+
* the legacy root `build.ssr` flag.
|
|
408
|
+
*/
|
|
409
|
+
function isServerBuildContext(ctx, config) {
|
|
410
|
+
const target = resolveEnvironmentConsumerTarget(ctx);
|
|
411
|
+
if (target) return target === "server";
|
|
412
|
+
return Boolean(config?.build?.ssr);
|
|
413
|
+
}
|
|
403
414
|
function resolveRemoteConsumer(ctx, hasMultiEnvironment) {
|
|
404
415
|
if (!hasMultiEnvironment) return "unified";
|
|
405
416
|
return resolveEnvironmentConsumerTarget(ctx) ?? "client";
|
|
@@ -862,6 +873,11 @@ function normalizeShareItem(key, shareItem) {
|
|
|
862
873
|
const treeShaking = typeof shareItem === "object" ? shareItem.treeShaking : void 0;
|
|
863
874
|
if (treeShaking && treeShaking.mode !== "server-calc" && treeShaking.mode !== "runtime-infer") throw createModuleFederationError(`Invalid shared config for "${key}": treeShaking.mode must be either "server-calc" or "runtime-infer".`);
|
|
864
875
|
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.`);
|
|
876
|
+
if (typeof shareItem === "object") {
|
|
877
|
+
const request = typeof shareItem.request === "string" ? shareItem.request : key;
|
|
878
|
+
const shareKey = typeof shareItem.shareKey === "string" ? shareItem.shareKey : key;
|
|
879
|
+
if (request.endsWith("/") !== shareKey.endsWith("/")) throw createModuleFederationError(`Invalid shared config for "${key}": "request" and "shareKey" must both end with "/" for a prefix share, or neither. Got request "${request}" and shareKey "${shareKey}".`);
|
|
880
|
+
}
|
|
865
881
|
if (treeShaking?.mode === "runtime-infer" && typeof shareItem === "object" && shareItem.singleton) mfWarn(`Shared singleton "${key}" uses runtime-infer tree shaking, which may load both a tree-shaken bundle and a full bundle when consumers require different exports. Prefer server-calc for singleton dependencies. If runtime-infer is required, expand usedExports to reduce this risk.`);
|
|
866
882
|
const config = typeof shareItem === "object" ? shareItem : {};
|
|
867
883
|
const { version, requiredVersion } = resolveSharedVersion(key, config, getPackageDetectionCwd());
|
|
@@ -892,6 +908,9 @@ function normalizeShareItem(key, shareItem) {
|
|
|
892
908
|
eager: shareItem.eager || false,
|
|
893
909
|
requiredVersion,
|
|
894
910
|
strictVersion: !!shareItem.strictVersion,
|
|
911
|
+
...shareItem.request !== void 0 ? { request: shareItem.request } : {},
|
|
912
|
+
...shareItem.shareKey !== void 0 ? { shareKey: shareItem.shareKey } : {},
|
|
913
|
+
...shareItem.allowNodeModulesSuffixMatch !== void 0 ? { allowNodeModulesSuffixMatch: shareItem.allowNodeModulesSuffixMatch } : {},
|
|
895
914
|
...shareItem.suppressMissingImportWarning ? { suppressMissingImportWarning: true } : {},
|
|
896
915
|
...treeShaking ? { treeShaking: { ...treeShaking } } : {}
|
|
897
916
|
}
|
|
@@ -941,7 +960,8 @@ function normalizeShared(shared) {
|
|
|
941
960
|
const value = shared[key];
|
|
942
961
|
const hadConfiguredPackageSubpath = (result[normalizedKey]?.shareConfig)?.__mfConfiguredPackageSubpath === true;
|
|
943
962
|
result[normalizedKey] = normalizeShareItem(normalizedKey, value);
|
|
944
|
-
|
|
963
|
+
const requestIsPrefix = typeof value?.request === "string" && value.request.endsWith("/");
|
|
964
|
+
if (key.endsWith("/") || requestIsPrefix || hadConfiguredPackageSubpath) result[normalizedKey].shareConfig.__mfConfiguredPackageSubpath = true;
|
|
945
965
|
explicitSharedKeys.add(normalizedKey);
|
|
946
966
|
sourceEntries.push([normalizedKey, value]);
|
|
947
967
|
});
|
|
@@ -1018,7 +1038,12 @@ function isExplicitSharedKey(key, options) {
|
|
|
1018
1038
|
}
|
|
1019
1039
|
function getNormalizeShareItem(key, options = getNormalizeModuleFederationOptions()) {
|
|
1020
1040
|
const matchedKey = findSharedKey(key, options.shared);
|
|
1021
|
-
|
|
1041
|
+
const shareItem = options.shared[key] || (matchedKey ? options.shared[matchedKey] : void 0) || options.shared[getPackageName(key)] || options.shared[getPackageName(key) + "/"];
|
|
1042
|
+
if (shareItem) return shareItem;
|
|
1043
|
+
return Object.entries(options.shared).find(([sharedKey, item]) => {
|
|
1044
|
+
const runtimeKey = typeof item.shareConfig.shareKey === "string" ? item.shareConfig.shareKey : sharedKey;
|
|
1045
|
+
return runtimeKey.endsWith("/") ? key === runtimeKey.slice(0, -1) || key.startsWith(runtimeKey) : runtimeKey === key;
|
|
1046
|
+
})?.[1];
|
|
1022
1047
|
}
|
|
1023
1048
|
function normalizeModuleFederationOptions(options) {
|
|
1024
1049
|
warnOnReservedInternalNamePrefix(options.name, "containerName");
|
|
@@ -1026,6 +1051,7 @@ function normalizeModuleFederationOptions(options) {
|
|
|
1026
1051
|
const normalized = {
|
|
1027
1052
|
exposes: normalizeExposes(options.exposes),
|
|
1028
1053
|
filename: options.filename || "remoteEntry-[hash]",
|
|
1054
|
+
ssrFilename: options.ssrFilename || void 0,
|
|
1029
1055
|
internalName: toInternalModuleFederationName(options.name),
|
|
1030
1056
|
library: normalizeLibrary(options.library),
|
|
1031
1057
|
name: options.name,
|
|
@@ -1131,6 +1157,10 @@ var VirtualModule = class VirtualModule {
|
|
|
1131
1157
|
if (!cacheMap[this.tag]) cacheMap[this.tag] = {};
|
|
1132
1158
|
cacheMap[this.tag][this.name] = this;
|
|
1133
1159
|
}
|
|
1160
|
+
/** The federation scope this module was created under, if it was scoped. */
|
|
1161
|
+
getScopeName() {
|
|
1162
|
+
return this.scopeName;
|
|
1163
|
+
}
|
|
1134
1164
|
getImportId() {
|
|
1135
1165
|
const mfName = this.scopeName ?? getNormalizeModuleFederationOptions().internalName;
|
|
1136
1166
|
const importIdKey = `${mfName}${this.tag}${this.name}${this.tag}`;
|
|
@@ -1162,17 +1192,38 @@ const SERVER_ENV_GUARD = "import.meta.env.SSR";
|
|
|
1162
1192
|
const SSR_ENTRY_LOADER_SPECIFIER = "@module-federation/vite/ssrEntryLoader";
|
|
1163
1193
|
const SSR_ONLY_RUNTIME_PLUGINS = /* @__PURE__ */ new Set([SSR_ENTRY_LOADER_SPECIFIER]);
|
|
1164
1194
|
/**
|
|
1195
|
+
* Whether a Vite environment builds a server graph.
|
|
1196
|
+
*
|
|
1197
|
+
* Vite 6+ sets `consumer` on the environment config; `build.ssr` covers the
|
|
1198
|
+
* legacy `vite build --ssr` flag. Environment names are user-defined, so `ssr`
|
|
1199
|
+
* and `server` are only a fallback for configs that carry neither field.
|
|
1200
|
+
*/
|
|
1201
|
+
function isServerEnvironment(name, config) {
|
|
1202
|
+
return config?.consumer === "server" || Boolean(config?.build?.ssr) || name === "ssr" || name === "server";
|
|
1203
|
+
}
|
|
1204
|
+
/**
|
|
1205
|
+
* Whether a resolved Vite config includes a server graph: the legacy
|
|
1206
|
+
* `build.ssr` flag, or any server environment. Vite always registers an `ssr`
|
|
1207
|
+
* environment for `serve`, so this only gates builds.
|
|
1208
|
+
*/
|
|
1209
|
+
function isSsrConfig(config) {
|
|
1210
|
+
if (Boolean(config.build?.ssr)) return true;
|
|
1211
|
+
return Object.entries(config.environments ?? {}).some(([name, environment]) => isServerEnvironment(name, environment));
|
|
1212
|
+
}
|
|
1213
|
+
/**
|
|
1165
1214
|
* Single source of truth for SSR-related feature gates.
|
|
1166
1215
|
*
|
|
1167
|
-
* - Vite 8+
|
|
1168
|
-
*
|
|
1216
|
+
* - Vite 8+ server environments: ModuleRunner + FetchableDevEnvironment for
|
|
1217
|
+
* `/__mf_ssr__/` entries.
|
|
1218
|
+
* - SSR builds on any Vite major: HTTP fetch + temp-file import via
|
|
1219
|
+
* ssrEntryLoader.
|
|
1169
1220
|
*/
|
|
1170
|
-
function getSsrCapabilities(viteMajor, command, hasRemotes) {
|
|
1221
|
+
function getSsrCapabilities(viteMajor, command, hasRemotes, isSsr = false) {
|
|
1171
1222
|
if (!hasRemotes) return {
|
|
1172
1223
|
enableSsrInitBootstrap: false,
|
|
1173
1224
|
injectSsrEntryLoader: false
|
|
1174
1225
|
};
|
|
1175
|
-
const supported = command === "build" || command === "serve" && viteMajor >= 8;
|
|
1226
|
+
const supported = isSsr && (command === "build" || command === "serve" && viteMajor >= 8);
|
|
1176
1227
|
return {
|
|
1177
1228
|
enableSsrInitBootstrap: supported,
|
|
1178
1229
|
injectSsrEntryLoader: supported
|
|
@@ -1276,106 +1327,48 @@ function isParsableExpression(source) {
|
|
|
1276
1327
|
}
|
|
1277
1328
|
}
|
|
1278
1329
|
//#endregion
|
|
1279
|
-
//#region src/utils/
|
|
1280
|
-
function
|
|
1281
|
-
return
|
|
1330
|
+
//#region src/utils/runtimePluginSpecifier.ts
|
|
1331
|
+
function getRuntimePluginSpecifier(plugin) {
|
|
1332
|
+
return typeof plugin === "string" ? plugin : plugin[0];
|
|
1282
1333
|
}
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
const treeShakingStates = /* @__PURE__ */ new WeakMap();
|
|
1288
|
-
function getTreeShakingState(options) {
|
|
1289
|
-
if (!options) return legacyTreeShakingState;
|
|
1290
|
-
let state = treeShakingStates.get(options);
|
|
1291
|
-
if (!state) {
|
|
1292
|
-
state = {
|
|
1293
|
-
inferredUsage: /* @__PURE__ */ new Map(),
|
|
1294
|
-
buildMode: false
|
|
1295
|
-
};
|
|
1296
|
-
treeShakingStates.set(options, state);
|
|
1297
|
-
}
|
|
1298
|
-
return state;
|
|
1299
|
-
}
|
|
1300
|
-
function setTreeShakingBuildMode(enabled, options) {
|
|
1301
|
-
getTreeShakingState(options).buildMode = enabled;
|
|
1302
|
-
}
|
|
1303
|
-
function resetTreeShakingExports(options) {
|
|
1304
|
-
getTreeShakingState(options).inferredUsage.clear();
|
|
1305
|
-
}
|
|
1306
|
-
function getOrCreateExportRecord(sharedKey, request, options) {
|
|
1307
|
-
const inferredUsage = getTreeShakingState(options).inferredUsage;
|
|
1308
|
-
let byRequest = inferredUsage.get(sharedKey);
|
|
1309
|
-
if (!byRequest) {
|
|
1310
|
-
byRequest = /* @__PURE__ */ new Map();
|
|
1311
|
-
inferredUsage.set(sharedKey, byRequest);
|
|
1312
|
-
}
|
|
1313
|
-
let record = byRequest.get(request);
|
|
1314
|
-
if (!record) {
|
|
1315
|
-
record = {
|
|
1316
|
-
requiresFullBundle: false,
|
|
1317
|
-
usedExports: /* @__PURE__ */ new Set()
|
|
1318
|
-
};
|
|
1319
|
-
byRequest.set(request, record);
|
|
1320
|
-
}
|
|
1321
|
-
return record;
|
|
1322
|
-
}
|
|
1323
|
-
function recordTreeShakingExports(sharedKey, exports, request = sharedKey, options) {
|
|
1324
|
-
const record = getOrCreateExportRecord(sharedKey, request, options);
|
|
1325
|
-
exports.forEach((name) => record.usedExports.add(name));
|
|
1326
|
-
}
|
|
1327
|
-
function markTreeShakingPackageUnsafe(sharedKey, request = sharedKey, options) {
|
|
1328
|
-
getOrCreateExportRecord(sharedKey, request, options).requiresFullBundle = true;
|
|
1329
|
-
}
|
|
1330
|
-
function getExportRecords(sharedKey, request, options) {
|
|
1331
|
-
const inferredUsage = getTreeShakingState(options).inferredUsage;
|
|
1332
|
-
if (sharedKey) {
|
|
1333
|
-
const records = inferredUsage.get(sharedKey);
|
|
1334
|
-
const wildcard = records?.get("*");
|
|
1335
|
-
const exact = records?.get(request);
|
|
1336
|
-
return [wildcard, exact === wildcard ? void 0 : exact].filter((record) => !!record);
|
|
1337
|
-
}
|
|
1338
|
-
const records = [];
|
|
1339
|
-
inferredUsage.forEach((byRequest, configuredKey) => {
|
|
1340
|
-
const wildcard = byRequest.get("*");
|
|
1341
|
-
const exact = byRequest.get(request);
|
|
1342
|
-
const keyBase = configuredKey.endsWith("/") ? configuredKey.slice(0, -1) : configuredKey;
|
|
1343
|
-
const requestMatchesConfiguredKey = request === keyBase || request.startsWith(`${keyBase}/`);
|
|
1344
|
-
if (wildcard && requestMatchesConfiguredKey) records.push(wildcard);
|
|
1345
|
-
if (exact && exact !== wildcard) records.push(exact);
|
|
1346
|
-
});
|
|
1347
|
-
return records;
|
|
1334
|
+
/** Drop SSR-only plugins from a client graph; a server graph keeps them all. */
|
|
1335
|
+
function filterRuntimePluginsForTarget(runtimePlugins, ssrOnlySpecifiers, isServer) {
|
|
1336
|
+
if (isServer) return [...runtimePlugins];
|
|
1337
|
+
return runtimePlugins.filter((plugin) => !ssrOnlySpecifiers.has(getRuntimePluginSpecifier(plugin)));
|
|
1348
1338
|
}
|
|
1339
|
+
//#endregion
|
|
1340
|
+
//#region src/utils/importAnalysis.ts
|
|
1341
|
+
const analysisByBuild = /* @__PURE__ */ new WeakMap();
|
|
1349
1342
|
/**
|
|
1350
|
-
*
|
|
1351
|
-
*
|
|
1352
|
-
*
|
|
1353
|
-
* fallback lookup across keys keeps aliases/backwards-compatible callers
|
|
1354
|
-
* working, while still keeping each concrete request's exports isolated.
|
|
1343
|
+
* Share source analysis within one build environment. Callers still resolve
|
|
1344
|
+
* requests and apply their own sharing configuration. Clear at buildStart and
|
|
1345
|
+
* buildEnd so watch rebuilds start fresh and completed builds release source.
|
|
1355
1346
|
*/
|
|
1356
|
-
function
|
|
1357
|
-
|
|
1358
|
-
if (!
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1347
|
+
function getImportAnalysis(build) {
|
|
1348
|
+
let analysis = analysisByBuild.get(build);
|
|
1349
|
+
if (!analysis) {
|
|
1350
|
+
const importsByCode = /* @__PURE__ */ new Map();
|
|
1351
|
+
analysis = {
|
|
1352
|
+
analyze(code) {
|
|
1353
|
+
const cached = importsByCode.get(code);
|
|
1354
|
+
if (cached !== void 0) return cached;
|
|
1355
|
+
const imports = analyzeImports(code);
|
|
1356
|
+
importsByCode.set(code, imports);
|
|
1357
|
+
return imports;
|
|
1358
|
+
},
|
|
1359
|
+
clear() {
|
|
1360
|
+
importsByCode.clear();
|
|
1361
|
+
}
|
|
1362
|
+
};
|
|
1363
|
+
analysisByBuild.set(build, analysis);
|
|
1364
|
+
}
|
|
1365
|
+
return analysis;
|
|
1372
1366
|
}
|
|
1373
|
-
function
|
|
1374
|
-
|
|
1375
|
-
return getSharedExportUsage(request, shareItem, sharedKey, options);
|
|
1367
|
+
function isRecord(value) {
|
|
1368
|
+
return value !== null && typeof value === "object";
|
|
1376
1369
|
}
|
|
1377
1370
|
function getModuleSource(node) {
|
|
1378
|
-
if (!node
|
|
1371
|
+
if (!isRecord(node)) return void 0;
|
|
1379
1372
|
const source = node;
|
|
1380
1373
|
if (source.type === "Literal" && typeof source.value === "string") return source.value;
|
|
1381
1374
|
if (source.type === "StringLiteral" && typeof source.value === "string") return source.value;
|
|
@@ -1383,11 +1376,13 @@ function getModuleSource(node) {
|
|
|
1383
1376
|
const expressions = Array.isArray(source.expressions) ? source.expressions : [];
|
|
1384
1377
|
const quasis = Array.isArray(source.quasis) ? source.quasis : [];
|
|
1385
1378
|
if (expressions.length > 0 || quasis.length !== 1) return void 0;
|
|
1386
|
-
const
|
|
1387
|
-
|
|
1379
|
+
const quasi = quasis[0];
|
|
1380
|
+
if (!isRecord(quasi) || !isRecord(quasi.value)) return void 0;
|
|
1381
|
+
const value = quasi.value;
|
|
1382
|
+
return typeof value.cooked === "string" ? value.cooked : typeof value.raw === "string" ? value.raw : void 0;
|
|
1388
1383
|
}
|
|
1389
1384
|
function getExportedName(node) {
|
|
1390
|
-
if (!node
|
|
1385
|
+
if (!isRecord(node)) return void 0;
|
|
1391
1386
|
const exported = node;
|
|
1392
1387
|
if (exported.type === "Identifier" && typeof exported.name === "string") return exported.name;
|
|
1393
1388
|
if ((exported.type === "Literal" || exported.type === "StringLiteral") && typeof exported.value === "string") return exported.value;
|
|
@@ -1400,7 +1395,7 @@ function forEachAstNode(root, visit) {
|
|
|
1400
1395
|
const seen = /* @__PURE__ */ new Set();
|
|
1401
1396
|
while (stack.length > 0) {
|
|
1402
1397
|
const value = stack.pop();
|
|
1403
|
-
if (!value
|
|
1398
|
+
if (!isRecord(value)) continue;
|
|
1404
1399
|
if (seen.has(value)) continue;
|
|
1405
1400
|
seen.add(value);
|
|
1406
1401
|
if (Array.isArray(value)) {
|
|
@@ -1414,18 +1409,22 @@ function forEachAstNode(root, visit) {
|
|
|
1414
1409
|
});
|
|
1415
1410
|
}
|
|
1416
1411
|
}
|
|
1417
|
-
function collectImportDeclaration(node, source, record,
|
|
1412
|
+
function collectImportDeclaration(node, source, record, requireAllExports) {
|
|
1418
1413
|
if (isTypeOnly(node)) return;
|
|
1419
1414
|
const specifiers = Array.isArray(node.specifiers) ? node.specifiers : [];
|
|
1420
1415
|
if (specifiers.length === 0) {
|
|
1421
|
-
|
|
1416
|
+
requireAllExports(source);
|
|
1422
1417
|
return;
|
|
1423
1418
|
}
|
|
1424
1419
|
const names = [];
|
|
1425
1420
|
for (const specifier of specifiers) {
|
|
1421
|
+
if (!isRecord(specifier)) {
|
|
1422
|
+
requireAllExports(source);
|
|
1423
|
+
return;
|
|
1424
|
+
}
|
|
1426
1425
|
if (isTypeOnly(specifier)) continue;
|
|
1427
1426
|
if (specifier.type === "ImportNamespaceSpecifier") {
|
|
1428
|
-
|
|
1427
|
+
requireAllExports(source);
|
|
1429
1428
|
return;
|
|
1430
1429
|
}
|
|
1431
1430
|
if (specifier.type === "ImportDefaultSpecifier") {
|
|
@@ -1434,118 +1433,246 @@ function collectImportDeclaration(node, source, record, markUnsafe) {
|
|
|
1434
1433
|
}
|
|
1435
1434
|
if (specifier.type === "ImportSpecifier") {
|
|
1436
1435
|
const imported = specifier.imported;
|
|
1437
|
-
if (imported
|
|
1438
|
-
|
|
1436
|
+
if (isRecord(imported) && (imported.type === "Literal" || imported.type === "StringLiteral")) {
|
|
1437
|
+
requireAllExports(source);
|
|
1439
1438
|
return;
|
|
1440
1439
|
}
|
|
1441
1440
|
const name = getExportedName(specifier.imported);
|
|
1442
1441
|
if (!name) {
|
|
1443
|
-
|
|
1442
|
+
requireAllExports(source);
|
|
1444
1443
|
return;
|
|
1445
1444
|
}
|
|
1446
1445
|
names.push(name);
|
|
1447
1446
|
continue;
|
|
1448
1447
|
}
|
|
1449
|
-
|
|
1448
|
+
requireAllExports(source);
|
|
1450
1449
|
return;
|
|
1451
1450
|
}
|
|
1452
1451
|
record(names, source);
|
|
1453
1452
|
}
|
|
1454
|
-
function collectReExport(node, source, record,
|
|
1453
|
+
function collectReExport(node, source, record, requireAllExports) {
|
|
1455
1454
|
if (isTypeOnly(node)) return;
|
|
1456
1455
|
if (node.type === "ExportAllDeclaration") {
|
|
1457
|
-
|
|
1456
|
+
requireAllExports(source);
|
|
1458
1457
|
return;
|
|
1459
1458
|
}
|
|
1460
1459
|
const specifiers = Array.isArray(node.specifiers) ? node.specifiers : [];
|
|
1461
1460
|
if (specifiers.length === 0) {
|
|
1462
|
-
|
|
1461
|
+
requireAllExports(source);
|
|
1463
1462
|
return;
|
|
1464
1463
|
}
|
|
1465
1464
|
const names = [];
|
|
1466
1465
|
for (const specifier of specifiers) {
|
|
1466
|
+
if (!isRecord(specifier)) {
|
|
1467
|
+
requireAllExports(source);
|
|
1468
|
+
return;
|
|
1469
|
+
}
|
|
1467
1470
|
if (isTypeOnly(specifier)) continue;
|
|
1468
1471
|
if (specifier.type !== "ExportSpecifier") {
|
|
1469
|
-
|
|
1472
|
+
requireAllExports(source);
|
|
1470
1473
|
return;
|
|
1471
1474
|
}
|
|
1472
1475
|
const local = specifier.local;
|
|
1473
|
-
if (local
|
|
1474
|
-
|
|
1476
|
+
if (isRecord(local) && (local.type === "Literal" || local.type === "StringLiteral")) {
|
|
1477
|
+
requireAllExports(source);
|
|
1475
1478
|
return;
|
|
1476
1479
|
}
|
|
1477
1480
|
const name = getExportedName(specifier.local);
|
|
1478
1481
|
if (!name) {
|
|
1479
|
-
|
|
1482
|
+
requireAllExports(source);
|
|
1480
1483
|
return;
|
|
1481
1484
|
}
|
|
1482
1485
|
names.push(name);
|
|
1483
1486
|
}
|
|
1484
1487
|
record(names, source);
|
|
1485
1488
|
}
|
|
1486
|
-
|
|
1487
|
-
* Collect the exports required by a consumer's ESM graph.
|
|
1488
|
-
*
|
|
1489
|
-
* Parsing the module avoids treating import-looking text in comments, strings,
|
|
1490
|
-
* templates, or regular expressions as real dependencies. If parsing fails,
|
|
1491
|
-
* every configured share whose exports are analyzed is conservatively marked
|
|
1492
|
-
* as requiring its full export surface instead of guessing from source text.
|
|
1493
|
-
*
|
|
1494
|
-
* Generated federation wrappers are excluded because their imports describe
|
|
1495
|
-
* the wrapper implementation, not the consumer's requirements.
|
|
1496
|
-
*/
|
|
1497
|
-
async function collectTreeShakingImports(code, id, shared, findSharedKey, record, markUnsafe) {
|
|
1498
|
-
const normalizedId = normalizePathForImport(id);
|
|
1499
|
-
if (normalizedId.includes("__prebuild__") || normalizedId.includes("__loadShare__") || normalizedId.includes("__mf_tree_shaking_graph__")) return;
|
|
1489
|
+
function analyzeImports(code) {
|
|
1500
1490
|
let ast;
|
|
1501
1491
|
try {
|
|
1502
|
-
ast = parseAst(code);
|
|
1492
|
+
ast = vite.parseAst(code);
|
|
1503
1493
|
} catch {
|
|
1504
|
-
|
|
1505
|
-
if (shouldAnalyzeSharedExports(shareItem)) markUnsafe(sharedKey, "*");
|
|
1506
|
-
});
|
|
1507
|
-
return;
|
|
1494
|
+
return null;
|
|
1508
1495
|
}
|
|
1509
|
-
const
|
|
1510
|
-
const
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
};
|
|
1518
|
-
const
|
|
1519
|
-
withSharedSource(source, (key) => record(key, names, source));
|
|
1520
|
-
};
|
|
1521
|
-
const markSourceUnsafe = (source) => {
|
|
1522
|
-
withSharedSource(source, (key) => markUnsafe(key, source));
|
|
1523
|
-
};
|
|
1524
|
-
forEachAstNode(ast, (node) => {
|
|
1496
|
+
const imports = [];
|
|
1497
|
+
const recordSource = (names, source) => imports.push({
|
|
1498
|
+
source,
|
|
1499
|
+
usedExports: names
|
|
1500
|
+
});
|
|
1501
|
+
const requireAllExports = (source) => imports.push({
|
|
1502
|
+
source,
|
|
1503
|
+
usedExports: null
|
|
1504
|
+
});
|
|
1505
|
+
const collectImport = (node) => {
|
|
1525
1506
|
if (node.type === "ImportDeclaration") {
|
|
1526
1507
|
const source = getModuleSource(node.source);
|
|
1527
|
-
if (source) collectImportDeclaration(node, source, recordSource,
|
|
1508
|
+
if (source) collectImportDeclaration(node, source, recordSource, requireAllExports);
|
|
1528
1509
|
return;
|
|
1529
1510
|
}
|
|
1530
1511
|
if ((node.type === "ExportNamedDeclaration" || node.type === "ExportAllDeclaration") && node.source) {
|
|
1531
1512
|
const source = getModuleSource(node.source);
|
|
1532
|
-
if (source) collectReExport(node, source, recordSource,
|
|
1513
|
+
if (source) collectReExport(node, source, recordSource, requireAllExports);
|
|
1533
1514
|
return;
|
|
1534
1515
|
}
|
|
1535
1516
|
if (node.type === "ImportExpression") {
|
|
1536
1517
|
const source = getModuleSource(node.source);
|
|
1537
|
-
if (source)
|
|
1518
|
+
if (source) requireAllExports(source);
|
|
1538
1519
|
return;
|
|
1539
1520
|
}
|
|
1540
1521
|
if (node.type === "CallExpression") {
|
|
1541
1522
|
const callee = node.callee;
|
|
1542
1523
|
const args = Array.isArray(node.arguments) ? node.arguments : [];
|
|
1543
|
-
if (callee
|
|
1524
|
+
if (isRecord(callee) && callee.type === "Identifier" && callee.name === "require" && args.length > 0) {
|
|
1544
1525
|
const source = getModuleSource(args[0]);
|
|
1545
|
-
if (source)
|
|
1526
|
+
if (source) requireAllExports(source);
|
|
1546
1527
|
}
|
|
1547
1528
|
}
|
|
1529
|
+
};
|
|
1530
|
+
if ("Visitor" in vite && typeof vite.Visitor === "function") {
|
|
1531
|
+
const visit = (node) => {
|
|
1532
|
+
if (isRecord(node)) collectImport(node);
|
|
1533
|
+
};
|
|
1534
|
+
try {
|
|
1535
|
+
new vite.Visitor({
|
|
1536
|
+
ImportDeclaration: visit,
|
|
1537
|
+
ExportNamedDeclaration: visit,
|
|
1538
|
+
ExportAllDeclaration: visit,
|
|
1539
|
+
ImportExpression: visit,
|
|
1540
|
+
CallExpression: visit
|
|
1541
|
+
}).visit(ast);
|
|
1542
|
+
return imports;
|
|
1543
|
+
} catch {
|
|
1544
|
+
imports.length = 0;
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
forEachAstNode(ast, collectImport);
|
|
1548
|
+
return imports;
|
|
1549
|
+
}
|
|
1550
|
+
//#endregion
|
|
1551
|
+
//#region src/utils/treeShaking.ts
|
|
1552
|
+
function shouldAnalyzeSharedExports(shareItem) {
|
|
1553
|
+
return !!(shareItem && (shareItem.shareConfig.treeShaking || shareItem.shareConfig.import === false));
|
|
1554
|
+
}
|
|
1555
|
+
const legacyTreeShakingState = {
|
|
1556
|
+
inferredUsage: /* @__PURE__ */ new Map(),
|
|
1557
|
+
buildMode: false
|
|
1558
|
+
};
|
|
1559
|
+
const treeShakingStates = /* @__PURE__ */ new WeakMap();
|
|
1560
|
+
function getTreeShakingState(options) {
|
|
1561
|
+
if (!options) return legacyTreeShakingState;
|
|
1562
|
+
let state = treeShakingStates.get(options);
|
|
1563
|
+
if (!state) {
|
|
1564
|
+
state = {
|
|
1565
|
+
inferredUsage: /* @__PURE__ */ new Map(),
|
|
1566
|
+
buildMode: false
|
|
1567
|
+
};
|
|
1568
|
+
treeShakingStates.set(options, state);
|
|
1569
|
+
}
|
|
1570
|
+
return state;
|
|
1571
|
+
}
|
|
1572
|
+
function setTreeShakingBuildMode(enabled, options) {
|
|
1573
|
+
getTreeShakingState(options).buildMode = enabled;
|
|
1574
|
+
}
|
|
1575
|
+
function resetTreeShakingExports(options) {
|
|
1576
|
+
getTreeShakingState(options).inferredUsage.clear();
|
|
1577
|
+
}
|
|
1578
|
+
function getOrCreateExportRecord(sharedKey, request, options) {
|
|
1579
|
+
const inferredUsage = getTreeShakingState(options).inferredUsage;
|
|
1580
|
+
let byRequest = inferredUsage.get(sharedKey);
|
|
1581
|
+
if (!byRequest) {
|
|
1582
|
+
byRequest = /* @__PURE__ */ new Map();
|
|
1583
|
+
inferredUsage.set(sharedKey, byRequest);
|
|
1584
|
+
}
|
|
1585
|
+
let record = byRequest.get(request);
|
|
1586
|
+
if (!record) {
|
|
1587
|
+
record = {
|
|
1588
|
+
requiresFullBundle: false,
|
|
1589
|
+
usedExports: /* @__PURE__ */ new Set()
|
|
1590
|
+
};
|
|
1591
|
+
byRequest.set(request, record);
|
|
1592
|
+
}
|
|
1593
|
+
return record;
|
|
1594
|
+
}
|
|
1595
|
+
function recordTreeShakingExports(sharedKey, exports, request = sharedKey, options) {
|
|
1596
|
+
const record = getOrCreateExportRecord(sharedKey, request, options);
|
|
1597
|
+
exports.forEach((name) => record.usedExports.add(name));
|
|
1598
|
+
}
|
|
1599
|
+
function markTreeShakingPackageUnsafe(sharedKey, request = sharedKey, options) {
|
|
1600
|
+
getOrCreateExportRecord(sharedKey, request, options).requiresFullBundle = true;
|
|
1601
|
+
}
|
|
1602
|
+
function getExportRecords(sharedKey, request, options) {
|
|
1603
|
+
const inferredUsage = getTreeShakingState(options).inferredUsage;
|
|
1604
|
+
if (sharedKey) {
|
|
1605
|
+
const records = inferredUsage.get(sharedKey);
|
|
1606
|
+
const wildcard = records?.get("*");
|
|
1607
|
+
const exact = records?.get(request);
|
|
1608
|
+
return [wildcard, exact === wildcard ? void 0 : exact].filter((record) => !!record);
|
|
1609
|
+
}
|
|
1610
|
+
const records = [];
|
|
1611
|
+
inferredUsage.forEach((byRequest, configuredKey) => {
|
|
1612
|
+
const wildcard = byRequest.get("*");
|
|
1613
|
+
const exact = byRequest.get(request);
|
|
1614
|
+
const configuredRequest = getSharedRequest(configuredKey, options?.shared?.[configuredKey]);
|
|
1615
|
+
const keyBase = configuredRequest.endsWith("/") ? configuredRequest.slice(0, -1) : configuredRequest;
|
|
1616
|
+
const requestMatchesConfiguredKey = request === keyBase || request.startsWith(`${keyBase}/`);
|
|
1617
|
+
if (wildcard && requestMatchesConfiguredKey) records.push(wildcard);
|
|
1618
|
+
if (exact && exact !== wildcard) records.push(exact);
|
|
1548
1619
|
});
|
|
1620
|
+
return records;
|
|
1621
|
+
}
|
|
1622
|
+
/**
|
|
1623
|
+
* Return the analyzed requirement for one concrete shared request.
|
|
1624
|
+
*
|
|
1625
|
+
* Callers that know the configured share key should pass it explicitly. The
|
|
1626
|
+
* fallback lookup across keys keeps aliases/backwards-compatible callers
|
|
1627
|
+
* working, while still keeping each concrete request's exports isolated.
|
|
1628
|
+
*/
|
|
1629
|
+
function getSharedExportUsage(request, shareItem, sharedKey, options) {
|
|
1630
|
+
const treeShaking = shareItem?.shareConfig.treeShaking;
|
|
1631
|
+
if (!shouldAnalyzeSharedExports(shareItem) || !getTreeShakingState(options).buildMode) return;
|
|
1632
|
+
const records = getExportRecords(sharedKey, request, options);
|
|
1633
|
+
if (records.some((record) => record.requiresFullBundle)) return { kind: "full" };
|
|
1634
|
+
const configured = treeShaking?.usedExports ?? [];
|
|
1635
|
+
const result = new Set(configured);
|
|
1636
|
+
records.forEach((record) => record.usedExports.forEach((name) => result.add(name)));
|
|
1637
|
+
if (result.size > 0) return {
|
|
1638
|
+
kind: "exports",
|
|
1639
|
+
usedExports: [...result].sort()
|
|
1640
|
+
};
|
|
1641
|
+
return records.length > 0 ? {
|
|
1642
|
+
kind: "exports",
|
|
1643
|
+
usedExports: []
|
|
1644
|
+
} : { kind: "unknown" };
|
|
1645
|
+
}
|
|
1646
|
+
function getTreeShakingExportUsage(request, shareItem, sharedKey, options) {
|
|
1647
|
+
if (!shareItem?.shareConfig.treeShaking) return void 0;
|
|
1648
|
+
return getSharedExportUsage(request, shareItem, sharedKey, options);
|
|
1649
|
+
}
|
|
1650
|
+
/**
|
|
1651
|
+
* Record consumer imports against this instance's sharing configuration.
|
|
1652
|
+
* Generated wrappers do not contribute consumer usage. If parsing fails,
|
|
1653
|
+
* every share enabled for analysis requires all of its exports.
|
|
1654
|
+
*/
|
|
1655
|
+
async function collectTreeShakingImports(code, id, shared, findSharedKey, record, markUnsafe, analysis = getImportAnalysis(shared)) {
|
|
1656
|
+
const normalizedId = normalizePathForImport(id);
|
|
1657
|
+
if (normalizedId.includes("__prebuild__") || normalizedId.includes("__loadShare__") || normalizedId.includes("__mf_tree_shaking_graph__")) return;
|
|
1658
|
+
const imports = analysis.analyze(code);
|
|
1659
|
+
if (imports === null) {
|
|
1660
|
+
Object.entries(shared).forEach(([sharedKey, shareItem]) => {
|
|
1661
|
+
if (shouldAnalyzeSharedExports(shareItem)) markUnsafe(sharedKey, "*");
|
|
1662
|
+
});
|
|
1663
|
+
return;
|
|
1664
|
+
}
|
|
1665
|
+
const pending = [];
|
|
1666
|
+
for (const { source, usedExports } of imports) {
|
|
1667
|
+
const apply = (key) => {
|
|
1668
|
+
if (!key || !shouldAnalyzeSharedExports(shared[key])) return;
|
|
1669
|
+
if (usedExports === null) markUnsafe(key, source);
|
|
1670
|
+
else record(key, usedExports, source);
|
|
1671
|
+
};
|
|
1672
|
+
const key = findSharedKey(source, shared);
|
|
1673
|
+
if (key instanceof Promise) pending.push(key.then(apply));
|
|
1674
|
+
else apply(key);
|
|
1675
|
+
}
|
|
1549
1676
|
await Promise.all(pending);
|
|
1550
1677
|
}
|
|
1551
1678
|
//#endregion
|
|
@@ -2162,7 +2289,7 @@ ${exportStatement}
|
|
|
2162
2289
|
//#endregion
|
|
2163
2290
|
//#region src/plugins/pluginReactMixedModeGuard.ts
|
|
2164
2291
|
function createReactMixedModeRuntimeGuard() {
|
|
2165
|
-
return `const __mfReactInternals = mod[
|
|
2292
|
+
return `const __mfReactInternals = mod[${JSON.stringify(REACT_CLIENT_INTERNALS_KEY)}];
|
|
2166
2293
|
if (__mfReactInternals && "A" in __mfReactInternals) {
|
|
2167
2294
|
let __mfReactDispatcher = __mfReactInternals.A;
|
|
2168
2295
|
Object.defineProperty(__mfReactInternals, "A", {
|
|
@@ -2252,6 +2379,77 @@ function findLikelyTypeArgumentEnd(source, start, codePositions) {
|
|
|
2252
2379
|
}
|
|
2253
2380
|
}
|
|
2254
2381
|
//#endregion
|
|
2382
|
+
//#region src/virtualModules/shareTags.ts
|
|
2383
|
+
const LOAD_SHARE_TAG = "__loadShare__";
|
|
2384
|
+
/** A share's local copy. Reachable only through `import()`, so it stays lazy. */
|
|
2385
|
+
const PREBUILD_TAG = "__prebuild__";
|
|
2386
|
+
//#endregion
|
|
2387
|
+
//#region src/virtualModules/loadShareSharedChunk.ts
|
|
2388
|
+
const HELPERS_MODULE_NAME = "loadShareHelpers";
|
|
2389
|
+
const HELPERS_MODULE_TAG = "__mf_v__";
|
|
2390
|
+
const HELPERS_MODULE_MARKER = `${HELPERS_MODULE_TAG}${HELPERS_MODULE_NAME}${HELPERS_MODULE_TAG}`;
|
|
2391
|
+
const SHARED_CHUNK_SUFFIX = `${LOAD_SHARE_TAG}shared`;
|
|
2392
|
+
const HELPER_EXPORT_LIST = [
|
|
2393
|
+
"__mfGetSharedCacheDescriptor",
|
|
2394
|
+
"__mfReadSharedCache",
|
|
2395
|
+
"__mfSharedCacheListenersKey",
|
|
2396
|
+
"__mfGetSharedCacheListeners",
|
|
2397
|
+
"__mfSubscribeSharedCache",
|
|
2398
|
+
"__mfSharedCacheOwnersKey",
|
|
2399
|
+
"__mfGetSharedCacheOwners",
|
|
2400
|
+
"__mfReadSharedCacheOwner",
|
|
2401
|
+
"__mfGetSharedModuleIdentity",
|
|
2402
|
+
"__mfIsSameSharedModule",
|
|
2403
|
+
"__mfWriteSharedCache",
|
|
2404
|
+
"__mfTreeShakingSharedCacheKey",
|
|
2405
|
+
"__mfGetTreeShakingSharedCache",
|
|
2406
|
+
"__mfReadTreeShakingSharedCache",
|
|
2407
|
+
"__mfWriteTreeShakingSharedCache",
|
|
2408
|
+
"__mfTreeShakingSelectionCacheKey",
|
|
2409
|
+
"__mfGetTreeShakingSelectionCache",
|
|
2410
|
+
"__mfReadTreeShakingSharedSelection",
|
|
2411
|
+
"__mfWriteTreeShakingSharedSelection"
|
|
2412
|
+
].join(", ");
|
|
2413
|
+
const helperModules = /* @__PURE__ */ new WeakMap();
|
|
2414
|
+
function getSharedCacheHelpersModule(options) {
|
|
2415
|
+
let module = helperModules.get(options);
|
|
2416
|
+
if (!module) {
|
|
2417
|
+
module = new VirtualModule(HELPERS_MODULE_NAME, HELPERS_MODULE_TAG, "", getFederationScopeKey(options));
|
|
2418
|
+
module.writeSync(`${sharedCacheHelperCode}\nexport { ${HELPER_EXPORT_LIST} };`);
|
|
2419
|
+
helperModules.set(options, module);
|
|
2420
|
+
}
|
|
2421
|
+
return module;
|
|
2422
|
+
}
|
|
2423
|
+
function getSharedCacheHelpersImportCode(options) {
|
|
2424
|
+
const importId = getSharedCacheHelpersModule(options).getImportId();
|
|
2425
|
+
return `import { ${HELPER_EXPORT_LIST} } from ${JSON.stringify(importId)};`;
|
|
2426
|
+
}
|
|
2427
|
+
function isSharedCacheHelpersId(id) {
|
|
2428
|
+
return id.includes(HELPERS_MODULE_MARKER);
|
|
2429
|
+
}
|
|
2430
|
+
function getSharedChunkName(id) {
|
|
2431
|
+
const ownerTag = isSharedCacheHelpersId(id) ? HELPERS_MODULE_MARKER : LOAD_SHARE_TAG;
|
|
2432
|
+
return `${id.slice(0, id.indexOf(ownerTag))}${SHARED_CHUNK_SUFFIX}`;
|
|
2433
|
+
}
|
|
2434
|
+
function isSharedChunk(chunk) {
|
|
2435
|
+
return chunk.name?.endsWith(SHARED_CHUNK_SUFFIX) ?? false;
|
|
2436
|
+
}
|
|
2437
|
+
/**
|
|
2438
|
+
* Fallbacks inlined into a shared chunk, which means they are no longer lazy.
|
|
2439
|
+
* Only inlined modules count: a shared chunk also imports fallback chunks with
|
|
2440
|
+
* the experiment off, because Rolldown hoists its runtime helpers into whichever
|
|
2441
|
+
* chunk first uses them.
|
|
2442
|
+
*/
|
|
2443
|
+
function findEagerFallbacksInSharedChunk(bundle) {
|
|
2444
|
+
const offenders = /* @__PURE__ */ new Map();
|
|
2445
|
+
for (const [fileName, chunk] of Object.entries(bundle)) {
|
|
2446
|
+
if (chunk.type !== "chunk" || !isSharedChunk(chunk)) continue;
|
|
2447
|
+
const inlined = Object.keys(chunk.modules ?? {}).filter((id) => id.includes(PREBUILD_TAG));
|
|
2448
|
+
if (inlined.length > 0) offenders.set(fileName, inlined);
|
|
2449
|
+
}
|
|
2450
|
+
return offenders;
|
|
2451
|
+
}
|
|
2452
|
+
//#endregion
|
|
2255
2453
|
//#region src/virtualModules/virtualShared_preBuild.ts
|
|
2256
2454
|
/**
|
|
2257
2455
|
* Even the resolveId hook cannot interfere with vite pre-build,
|
|
@@ -2287,7 +2485,7 @@ function isValidEsmExportName(name) {
|
|
|
2287
2485
|
const JS_IDENTIFIER_PATTERN = `[\$_\\p{ID_Start}][\$_\\u200C\\u200D\\p{ID_Continue}]*`;
|
|
2288
2486
|
function resolvePackageEntryFromProjectRoot(pkg) {
|
|
2289
2487
|
try {
|
|
2290
|
-
return
|
|
2488
|
+
return resolveModulePath(pkg, path$1.join(getPackageDetectionCwd(), "package.json"));
|
|
2291
2489
|
} catch {
|
|
2292
2490
|
return;
|
|
2293
2491
|
}
|
|
@@ -2445,7 +2643,7 @@ function resolveConfiguredImportPath(importSource, exportConditions = DEFAULT_SH
|
|
|
2445
2643
|
});
|
|
2446
2644
|
if (esmEntry) return esmEntry;
|
|
2447
2645
|
try {
|
|
2448
|
-
return
|
|
2646
|
+
return resolveModulePath(importSource, path$1.join(projectRoot, "package.json"));
|
|
2449
2647
|
} catch {
|
|
2450
2648
|
return;
|
|
2451
2649
|
}
|
|
@@ -2500,7 +2698,7 @@ function resolveReExportModule(filePath, specifier, exportConditions) {
|
|
|
2500
2698
|
});
|
|
2501
2699
|
if (esmEntry) return esmEntry;
|
|
2502
2700
|
try {
|
|
2503
|
-
return resolveFileLikeModule(
|
|
2701
|
+
return resolveFileLikeModule(resolveModulePath(specifier, filePath));
|
|
2504
2702
|
} catch {
|
|
2505
2703
|
return;
|
|
2506
2704
|
}
|
|
@@ -2828,7 +3026,8 @@ function getRequiredNamedExports(specifier) {
|
|
|
2828
3026
|
const getActiveHandles = process._getActiveHandles;
|
|
2829
3027
|
const handlesBeforeRequire = typeof getActiveHandles === "function" ? new Set(getActiveHandles.call(process)) : void 0;
|
|
2830
3028
|
try {
|
|
2831
|
-
const
|
|
3029
|
+
const projectPackageJson = path$1.join(getPackageDetectionCwd(), "package.json");
|
|
3030
|
+
const mod = createRequire$1(pathToFileURL(projectPackageJson))(resolveModulePath(specifier, projectPackageJson));
|
|
2832
3031
|
const runtimeNamedKeys = Object.keys(mod).filter((key) => key !== "default" && key !== "__esModule");
|
|
2833
3032
|
if (runtimeNamedKeys.some((key) => !isValidEsmExportName(key))) return void 0;
|
|
2834
3033
|
return runtimeNamedKeys;
|
|
@@ -2871,7 +3070,7 @@ function getSharedNamedExports(pkg, shareItem, exportConditions = DEFAULT_SHARED
|
|
|
2871
3070
|
}
|
|
2872
3071
|
function getLocalProviderImportPath(pkg) {
|
|
2873
3072
|
try {
|
|
2874
|
-
const resolved = resolveWorkspaceEsmEntry(pkg,
|
|
3073
|
+
const resolved = resolveWorkspaceEsmEntry(pkg, resolveModulePath(pkg, path$1.join(getPackageDetectionCwd(), "package.json")));
|
|
2875
3074
|
return isWorkspaceFilePath(resolved) ? resolved : void 0;
|
|
2876
3075
|
} catch {
|
|
2877
3076
|
const resolved = getInstalledPackageEntry(pkg, {
|
|
@@ -2892,7 +3091,7 @@ function getProjectResolvedImportPath(pkg) {
|
|
|
2892
3091
|
if (esmEntry) return esmEntry;
|
|
2893
3092
|
}
|
|
2894
3093
|
try {
|
|
2895
|
-
return resolveWorkspaceEsmEntry(pkg,
|
|
3094
|
+
return resolveWorkspaceEsmEntry(pkg, resolveModulePath(pkg, path$1.join(getPackageDetectionCwd(), "package.json")));
|
|
2896
3095
|
} catch {
|
|
2897
3096
|
return;
|
|
2898
3097
|
}
|
|
@@ -2948,25 +3147,11 @@ function getSharedDependencyGraphPackageJson(pkg) {
|
|
|
2948
3147
|
const installedPackageJson = getInstalledPackageJson(pkg, { packageName: getPackageName(pkg) })?.packageJson;
|
|
2949
3148
|
if (installedPackageJson) return installedPackageJson;
|
|
2950
3149
|
try {
|
|
2951
|
-
const packageJsonPath =
|
|
3150
|
+
const packageJsonPath = resolveModulePath(`${getPackageName(pkg)}/package.json`, path$1.join(getPackageDetectionCwd(), "package.json"));
|
|
2952
3151
|
return JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
2953
3152
|
} catch {}
|
|
2954
3153
|
return getWorkspacePackageJson(pkg);
|
|
2955
3154
|
}
|
|
2956
|
-
function getDependencyNames(packageJson) {
|
|
2957
|
-
if (!packageJson) return [];
|
|
2958
|
-
const names = /* @__PURE__ */ new Set();
|
|
2959
|
-
for (const field of [
|
|
2960
|
-
"dependencies",
|
|
2961
|
-
"peerDependencies",
|
|
2962
|
-
"optionalDependencies"
|
|
2963
|
-
]) {
|
|
2964
|
-
const deps = packageJson[field];
|
|
2965
|
-
if (!deps || typeof deps !== "object") continue;
|
|
2966
|
-
for (const dep of Object.keys(deps)) names.add(dep);
|
|
2967
|
-
}
|
|
2968
|
-
return Array.from(names);
|
|
2969
|
-
}
|
|
2970
3155
|
function isSharedSingletonConsumedByPeer(pkg, options = getNormalizeModuleFederationOptions(), requireFederationRuntimeDependency = false) {
|
|
2971
3156
|
const shared = options?.shared || {};
|
|
2972
3157
|
if (!requireFederationRuntimeDependency && Object.entries(shared).some(([key, item]) => key !== pkg && key.startsWith(`${pkg}/`) && item.shareConfig.singleton === true)) return true;
|
|
@@ -2975,25 +3160,39 @@ function isSharedSingletonConsumedByPeer(pkg, options = getNormalizeModuleFedera
|
|
|
2975
3160
|
const packageName = getPackageName(key);
|
|
2976
3161
|
if (!sharedKeyByPackageName.get(packageName) || key === packageName) sharedKeyByPackageName.set(packageName, key);
|
|
2977
3162
|
});
|
|
2978
|
-
const
|
|
3163
|
+
const runtimeDependencyCache = /* @__PURE__ */ new Map();
|
|
3164
|
+
const reachesFederationRuntime = (current, seen) => {
|
|
3165
|
+
if (runtimeDependencyCache.has(current)) return runtimeDependencyCache.get(current);
|
|
3166
|
+
const result = getDependencyNames(getSharedDependencyGraphPackageJson(current)).some((dependency) => {
|
|
3167
|
+
if (dependency === "@module-federation/enhanced" || dependency === "@module-federation/runtime" || dependency === "@module-federation/runtime-core") return true;
|
|
3168
|
+
if (seen.has(dependency)) return false;
|
|
3169
|
+
seen.add(dependency);
|
|
3170
|
+
const reachable = reachesFederationRuntime(dependency, seen);
|
|
3171
|
+
seen.delete(dependency);
|
|
3172
|
+
return reachable;
|
|
3173
|
+
});
|
|
3174
|
+
runtimeDependencyCache.set(current, result);
|
|
3175
|
+
return result;
|
|
3176
|
+
};
|
|
3177
|
+
const reachesPkg = (current, seen) => {
|
|
2979
3178
|
const dependencies = getDependencyNames(getSharedDependencyGraphPackageJson(current));
|
|
2980
|
-
const usesFederationRuntime = dependencies.some((dependency) => dependency === "@module-federation/enhanced" || dependency === "@module-federation/runtime" || dependency === "@module-federation/runtime-core");
|
|
2981
|
-
const runtimeIsReachable = hasFederationRuntimeDependency || usesFederationRuntime;
|
|
2982
3179
|
for (const dependency of dependencies) {
|
|
2983
3180
|
const sharedDependency = sharedKeyByPackageName.get(dependency);
|
|
2984
|
-
if (
|
|
2985
|
-
if (sharedDependency
|
|
2986
|
-
|
|
2987
|
-
seen.
|
|
2988
|
-
|
|
3181
|
+
if (sharedDependency === pkg) return true;
|
|
3182
|
+
if (!sharedDependency && !requireFederationRuntimeDependency) continue;
|
|
3183
|
+
const next = sharedDependency || dependency;
|
|
3184
|
+
if (seen.has(next)) continue;
|
|
3185
|
+
seen.add(next);
|
|
3186
|
+
if (reachesPkg(next, seen)) return true;
|
|
3187
|
+
seen.delete(next);
|
|
2989
3188
|
}
|
|
2990
3189
|
return false;
|
|
2991
3190
|
};
|
|
2992
|
-
return Array.from(sharedKeyByPackageName.values()).some((sharedPkg) => sharedPkg !== pkg && reachesPkg(sharedPkg, /* @__PURE__ */ new Set([sharedPkg])));
|
|
3191
|
+
return Array.from(sharedKeyByPackageName.values()).some((sharedPkg) => sharedPkg !== pkg && (!requireFederationRuntimeDependency || reachesFederationRuntime(sharedPkg, /* @__PURE__ */ new Set([sharedPkg]))) && reachesPkg(sharedPkg, /* @__PURE__ */ new Set([sharedPkg])));
|
|
2993
3192
|
}
|
|
2994
3193
|
function tryResolveImportFromPackageRoot(pkg, root) {
|
|
2995
3194
|
try {
|
|
2996
|
-
return resolveWorkspaceEsmEntry(pkg,
|
|
3195
|
+
return resolveWorkspaceEsmEntry(pkg, resolveModulePath(pkg, path$1.join(root, "package.json")), root);
|
|
2997
3196
|
} catch {
|
|
2998
3197
|
return;
|
|
2999
3198
|
}
|
|
@@ -3026,9 +3225,11 @@ function resolveConcreteSharedImportSource(pkg, projectRoot) {
|
|
|
3026
3225
|
if (resolved) return resolved;
|
|
3027
3226
|
currentDir = path$1.dirname(currentDir);
|
|
3028
3227
|
}
|
|
3029
|
-
return tryResolveImportFromPackageRoot(pkg, currentDir)
|
|
3228
|
+
return tryResolveImportFromPackageRoot(pkg, currentDir) ?? getInstalledPackageEntry(pkg, {
|
|
3229
|
+
conditions: DEFAULT_SHARED_EXPORT_CONDITIONS,
|
|
3230
|
+
resolveSubpathWithRequire: false
|
|
3231
|
+
});
|
|
3030
3232
|
}
|
|
3031
|
-
const PREBUILD_TAG = "__prebuild__";
|
|
3032
3233
|
const TREE_SHAKING_PROVIDER_TAG = "__treeShakingProvider__";
|
|
3033
3234
|
const TREE_SHAKING_GRAPH_QUERY = "__mf_tree_shaking_graph__";
|
|
3034
3235
|
const legacySharedVirtualModuleState = {
|
|
@@ -3037,9 +3238,11 @@ const legacySharedVirtualModuleState = {
|
|
|
3037
3238
|
treeShakingProviderCacheMap: {},
|
|
3038
3239
|
materializedTreeShakingProviders: /* @__PURE__ */ new Set(),
|
|
3039
3240
|
loadShareCacheMap: {},
|
|
3040
|
-
warnedMissingImportFalse: /* @__PURE__ */ new Set()
|
|
3241
|
+
warnedMissingImportFalse: /* @__PURE__ */ new Set(),
|
|
3242
|
+
coalescableLoadShares: /* @__PURE__ */ new Set()
|
|
3041
3243
|
};
|
|
3042
3244
|
const sharedVirtualModuleStates = /* @__PURE__ */ new WeakMap();
|
|
3245
|
+
const sharedVirtualModuleStatesByOwner = /* @__PURE__ */ new Map();
|
|
3043
3246
|
function getSharedVirtualModuleState(options) {
|
|
3044
3247
|
if (!options) try {
|
|
3045
3248
|
const currentOptions = getNormalizeModuleFederationOptions();
|
|
@@ -3056,12 +3259,19 @@ function getSharedVirtualModuleState(options) {
|
|
|
3056
3259
|
materializedTreeShakingProviders: /* @__PURE__ */ new Set(),
|
|
3057
3260
|
loadShareCacheMap: {},
|
|
3058
3261
|
warnedMissingImportFalse: /* @__PURE__ */ new Set(),
|
|
3262
|
+
coalescableLoadShares: /* @__PURE__ */ new Set(),
|
|
3059
3263
|
ownerKey: getFederationScopeKey(options)
|
|
3060
3264
|
};
|
|
3061
3265
|
sharedVirtualModuleStates.set(options, state);
|
|
3266
|
+
if (state.ownerKey !== void 0) sharedVirtualModuleStatesByOwner.set(state.ownerKey, state);
|
|
3062
3267
|
}
|
|
3063
3268
|
return state;
|
|
3064
3269
|
}
|
|
3270
|
+
/** State of the instance that owns a scoped virtual id; `options` covers unscoped ids. */
|
|
3271
|
+
function getSharedVirtualModuleStateForId(id, options) {
|
|
3272
|
+
const ownerKey = id === void 0 ? void 0 : VirtualModule.findById(id)?.getScopeName();
|
|
3273
|
+
return (ownerKey !== void 0 ? sharedVirtualModuleStatesByOwner.get(ownerKey) : void 0) ?? getSharedVirtualModuleState(options);
|
|
3274
|
+
}
|
|
3065
3275
|
function createScopedSharedVirtualModule(pkg, tag, options) {
|
|
3066
3276
|
return new VirtualModule(pkg, tag, ".js", getSharedVirtualModuleState(options).ownerKey);
|
|
3067
3277
|
}
|
|
@@ -3178,7 +3388,7 @@ function writePreBuildLibPath(pkg, shareItem, options, exportConditions) {
|
|
|
3178
3388
|
const cache = globalThis[__mfCacheGlobalKey]?.share;
|
|
3179
3389
|
const sharedReact = cache && __mfReadSharedCache(cache, ${reactCacheDescriptor});
|
|
3180
3390
|
const reactExports = sharedReact?.default ?? sharedReact;
|
|
3181
|
-
const internals = reactExports?.
|
|
3391
|
+
const internals = reactExports?.[${JSON.stringify(REACT_CLIENT_INTERNALS_KEY)}];
|
|
3182
3392
|
return internals?.H?.useMemoCache(size);
|
|
3183
3393
|
};
|
|
3184
3394
|
export default { c };
|
|
@@ -3256,7 +3466,6 @@ function getPreBuildShareItem(pkg, options) {
|
|
|
3256
3466
|
function getSharedImportSource(pkg, shareItem, options) {
|
|
3257
3467
|
return getConcreteSharedImportSource(pkg, shareItem) || getPreBuildLibImportId(pkg, options);
|
|
3258
3468
|
}
|
|
3259
|
-
const LOAD_SHARE_TAG = "__loadShare__";
|
|
3260
3469
|
function getLoadShareImportId(pkg, _isRolldown, options) {
|
|
3261
3470
|
const { loadShareCacheMap } = getSharedVirtualModuleState(options);
|
|
3262
3471
|
if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = createScopedSharedVirtualModule(pkg, LOAD_SHARE_TAG, options);
|
|
@@ -3316,14 +3525,14 @@ function getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer) {
|
|
|
3316
3525
|
* a merged chunk, TDZ bindings otherwise), so the exports stay unassigned until the deferred cache write
|
|
3317
3526
|
* re-applies them; a host-provided copy re-applies them through the cache subscription as before.
|
|
3318
3527
|
*/
|
|
3319
|
-
function generateEagerWorkspaceSingletonExports(namedExports, importSource, cacheDescriptor, cacheOwner, treeShakingConsumer, mutableExports = []) {
|
|
3528
|
+
function generateEagerWorkspaceSingletonExports(edges, namedExports, importSource, cacheDescriptor, cacheOwner, treeShakingConsumer, mutableExports = []) {
|
|
3320
3529
|
const copiedExports = namedExports.filter((name) => !mutableExports.includes(name));
|
|
3321
3530
|
const namedExportVars = copiedExports.map((_name, i) => `__mf_${i}`);
|
|
3322
3531
|
const declarations = namedExports.length > 0 ? ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ") : "let __mf_default;";
|
|
3323
3532
|
const assignments = [...copiedExports.map((name, i) => `${namedExportVars[i]} = mod[${escapeGeneratedStringLiteral(name)}];`), "__mf_default = mod.default ?? mod;"].join("\n ");
|
|
3324
3533
|
const namedExportLine = copiedExports.length > 0 ? `\n export { ${copiedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
|
|
3325
|
-
const mutableExportLine = mutableExports.length ? `\n
|
|
3326
|
-
return
|
|
3534
|
+
const mutableExportLine = mutableExports.length ? `\n ${edges.reExportNames(mutableExports, importSource)}` : "";
|
|
3535
|
+
return `${edges.importNamespace(importSource)}
|
|
3327
3536
|
let exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)};
|
|
3328
3537
|
if (exportModule === undefined) {
|
|
3329
3538
|
Promise.resolve().then(() => {
|
|
@@ -3351,28 +3560,26 @@ function generateEagerWorkspaceSingletonExports(namedExports, importSource, cach
|
|
|
3351
3560
|
__mfApplyEagerShareExportsWhenReady(exportModule);
|
|
3352
3561
|
export { __mf_default as default };${namedExportLine}${mutableExportLine}`;
|
|
3353
3562
|
}
|
|
3354
|
-
function generateLazyWorkspaceSingletonExports(namedExports, importSource, cacheDescriptor, cacheOwner, treeShakingConsumer, serveLocalFallback = false, mutableExports = []) {
|
|
3563
|
+
function generateLazyWorkspaceSingletonExports(edges, namedExports, importSource, cacheDescriptor, cacheOwner, treeShakingConsumer, serveLocalFallback = false, mutableExports = [], deferredEntryFallback = false) {
|
|
3355
3564
|
const copiedExports = namedExports.filter((name) => !mutableExports.includes(name));
|
|
3356
3565
|
const namedExportVars = copiedExports.map((_name, i) => `__mf_${i}`);
|
|
3357
3566
|
const declarations = namedExports.length > 0 ? ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ") : "let __mf_default;";
|
|
3358
3567
|
const assignments = copiedExports.length > 0 ? [...copiedExports.map((name, i) => `${namedExportVars[i]} = mod[${escapeGeneratedStringLiteral(name)}];`), "__mf_default = mod.default ?? mod;"].join("\n ") : "__mf_default = mod.default ?? mod;";
|
|
3359
3568
|
const namedExportLine = copiedExports.length > 0 ? `\n export { ${copiedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
|
|
3360
|
-
const mutableExportLine = mutableExports.length ? `\n
|
|
3569
|
+
const mutableExportLine = mutableExports.length ? `\n ${edges.reExportNames(mutableExports, importSource)}` : "";
|
|
3361
3570
|
const applyLocalFallback = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
3362
3571
|
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});
|
|
3363
3572
|
__mfApplyLazyShareExports(exportModule);`;
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
__mfTrackPendingShareLoad(initPromise.then(() => {
|
|
3375
|
-
exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)};
|
|
3573
|
+
const readDeferredShare = getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer);
|
|
3574
|
+
const deferredEntryLoad = `Promise.race([
|
|
3575
|
+
initPromise.then(() => ${readDeferredShare}),
|
|
3576
|
+
new Promise((resolve) => {
|
|
3577
|
+
const current = ${readDeferredShare};
|
|
3578
|
+
if (current !== undefined) resolve(current);
|
|
3579
|
+
else __mfSubscribeSharedCache(__mfModuleCache.share, ${cacheDescriptor}, resolve);
|
|
3580
|
+
})
|
|
3581
|
+
]).then((cached) => {
|
|
3582
|
+
exportModule = cached;
|
|
3376
3583
|
if (exportModule !== undefined) {
|
|
3377
3584
|
__mfApplyLazyShareExports(exportModule);
|
|
3378
3585
|
return;
|
|
@@ -3381,8 +3588,32 @@ function generateLazyWorkspaceSingletonExports(namedExports, importSource, cache
|
|
|
3381
3588
|
exportModule = __mfNormalizeShareModule(mod);
|
|
3382
3589
|
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});
|
|
3383
3590
|
});
|
|
3384
|
-
})
|
|
3385
|
-
|
|
3591
|
+
})`;
|
|
3592
|
+
const deferredInitLoad = `initPromise.then(() => {
|
|
3593
|
+
exportModule = ${readDeferredShare};
|
|
3594
|
+
if (exportModule !== undefined) {
|
|
3595
|
+
__mfApplyLazyShareExports(exportModule);
|
|
3596
|
+
return;
|
|
3597
|
+
}
|
|
3598
|
+
return import(${escapeGeneratedStringLiteral(importSource)}).then((mod) => {
|
|
3599
|
+
exportModule = __mfNormalizeShareModule(mod);
|
|
3600
|
+
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});
|
|
3601
|
+
});
|
|
3602
|
+
})`;
|
|
3603
|
+
const synchronousFallbackConditions = [...deferredEntryFallback ? [] : ["import.meta.env.SSR"], ...serveLocalFallback ? ["(import.meta.env.DEV && typeof __mfLocalShare !== 'undefined')"] : []];
|
|
3604
|
+
const trackPendingLoad = `__mfTrackPendingShareLoad(${deferredEntryFallback ? deferredEntryLoad : deferredInitLoad});`;
|
|
3605
|
+
return `${declarations}
|
|
3606
|
+
const __mfApplyLazyShareExports = (mod) => {
|
|
3607
|
+
${assignments}
|
|
3608
|
+
};
|
|
3609
|
+
__mfSubscribeSharedCache(__mfModuleCache.share, ${cacheDescriptor}, __mfApplyLazyShareExports);
|
|
3610
|
+
let exportModule = ${readDeferredShare};
|
|
3611
|
+
if (exportModule === undefined) {
|
|
3612
|
+
${synchronousFallbackConditions.length > 0 ? `if (${synchronousFallbackConditions.join(" || ")}) {
|
|
3613
|
+
${applyLocalFallback}
|
|
3614
|
+
} else {
|
|
3615
|
+
${trackPendingLoad}
|
|
3616
|
+
}` : trackPendingLoad}
|
|
3386
3617
|
} else {
|
|
3387
3618
|
__mfApplyLazyShareExports(exportModule);
|
|
3388
3619
|
}
|
|
@@ -3418,6 +3649,14 @@ function generateDeferredHostProvidedExports(namedExports, pkg, cacheDescriptor,
|
|
|
3418
3649
|
if (exportModule === undefined) {
|
|
3419
3650
|
__mfTrackPendingShareLoad(initPromise.then(() => {
|
|
3420
3651
|
exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)};
|
|
3652
|
+
// A share init() left to its dynamic import is normally bridged before that import runs;
|
|
3653
|
+
// bridge it here when this wrapper is reached another way.
|
|
3654
|
+
if (exportModule === undefined && typeof __mfPromiseState.loadLazyShares === "function") {
|
|
3655
|
+
return __mfPromiseState.loadLazyShares([${escapeGeneratedStringLiteral(pkg)}]).then(() => {
|
|
3656
|
+
exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)};
|
|
3657
|
+
});
|
|
3658
|
+
}
|
|
3659
|
+
}).then(() => {
|
|
3421
3660
|
if (exportModule === undefined) {
|
|
3422
3661
|
throw new Error("[Module Federation] Shared module ${pkg} was imported before federation bootstrap finished.");
|
|
3423
3662
|
}
|
|
@@ -3426,7 +3665,7 @@ function generateDeferredHostProvidedExports(namedExports, pkg, cacheDescriptor,
|
|
|
3426
3665
|
} else {
|
|
3427
3666
|
__mfApplyHostProvidedExports(exportModule);
|
|
3428
3667
|
}
|
|
3429
|
-
export { __mf_default as default };${namedExportLine}`;
|
|
3668
|
+
export { __mf_default as default, exportModule as __moduleExports };${namedExportLine}`;
|
|
3430
3669
|
}
|
|
3431
3670
|
function selectImportFalseNamedExports(detectedNamedExports, usage) {
|
|
3432
3671
|
if (!detectedNamedExports || usage?.kind !== "exports") return detectedNamedExports ?? [];
|
|
@@ -3465,9 +3704,49 @@ const initializedLocalShareModuleCode = `const __mfInitializedLocalShare = (mod)
|
|
|
3465
3704
|
throw error;
|
|
3466
3705
|
}
|
|
3467
3706
|
};`;
|
|
3707
|
+
function createLocalPayloadEdges() {
|
|
3708
|
+
let edges = 0;
|
|
3709
|
+
return {
|
|
3710
|
+
importNamespace(source) {
|
|
3711
|
+
edges++;
|
|
3712
|
+
return `import * as __mfLocalShare from ${escapeGeneratedStringLiteral(source)};`;
|
|
3713
|
+
},
|
|
3714
|
+
reExportAll(source) {
|
|
3715
|
+
edges++;
|
|
3716
|
+
return `export * from ${escapeGeneratedStringLiteral(source)}`;
|
|
3717
|
+
},
|
|
3718
|
+
reExportNames(names, source) {
|
|
3719
|
+
if (names.length === 0) return "";
|
|
3720
|
+
edges++;
|
|
3721
|
+
return `export { ${names.join(", ")} } from ${escapeGeneratedStringLiteral(source)};`;
|
|
3722
|
+
},
|
|
3723
|
+
get none() {
|
|
3724
|
+
return edges === 0;
|
|
3725
|
+
}
|
|
3726
|
+
};
|
|
3727
|
+
}
|
|
3728
|
+
function recordCoalescability(pkg, hasNoLocalPayloadEdge, command, shareConfig, coalescableLoadShares) {
|
|
3729
|
+
const coalescable = command === "build" && shareConfig.eager !== true && shareConfig.import !== false && hasNoLocalPayloadEdge;
|
|
3730
|
+
if (coalescable) coalescableLoadShares.add(pkg);
|
|
3731
|
+
else coalescableLoadShares.delete(pkg);
|
|
3732
|
+
return coalescable;
|
|
3733
|
+
}
|
|
3734
|
+
/**
|
|
3735
|
+
* `prependWorkspaceSingletonSsrImport` adds a local-payload edge in the server
|
|
3736
|
+
* build's load hook, after this module has generated the wrapper. `id` names
|
|
3737
|
+
* the owning instance when the hook belongs to a different one.
|
|
3738
|
+
*/
|
|
3739
|
+
function markLoadShareWrapperNotCoalescable(pkg, options, id) {
|
|
3740
|
+
getSharedVirtualModuleStateForId(id, options).coalescableLoadShares.delete(pkg);
|
|
3741
|
+
}
|
|
3742
|
+
/** With `id`, answers from the owning instance's state, whichever instance asks. */
|
|
3743
|
+
function isCoalescableLoadShareWrapper(pkg, options, id) {
|
|
3744
|
+
return getSharedVirtualModuleStateForId(id, options).coalescableLoadShares.has(pkg);
|
|
3745
|
+
}
|
|
3468
3746
|
function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options, exportConditions, importFalseExportUsage) {
|
|
3469
3747
|
const resolvedOptions = options ?? getNormalizeModuleFederationOptions();
|
|
3470
|
-
const { loadShareCacheMap } = getSharedVirtualModuleState(options);
|
|
3748
|
+
const { loadShareCacheMap, coalescableLoadShares } = getSharedVirtualModuleState(options);
|
|
3749
|
+
const edges = createLocalPayloadEdges();
|
|
3471
3750
|
if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = createScopedSharedVirtualModule(pkg, LOAD_SHARE_TAG, options);
|
|
3472
3751
|
let importLine = getRuntimeModuleCacheBootstrapCode(exportConditions);
|
|
3473
3752
|
const cacheDescriptor = getSharedCacheDescriptorLiteral(pkg, shareItem);
|
|
@@ -3487,6 +3766,7 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options, exp
|
|
|
3487
3766
|
}
|
|
3488
3767
|
exportLine = generateDeferredHostProvidedExports([], pkg, cacheDescriptor, treeShakingConsumer);
|
|
3489
3768
|
}
|
|
3769
|
+
recordCoalescability(pkg, edges.none, command, shareItem.shareConfig, coalescableLoadShares);
|
|
3490
3770
|
loadShareCacheMap[pkg].writeSync(`
|
|
3491
3771
|
${getRuntimeInitPromiseBootstrapCode(false, runtimeInitOwnerImportId)}
|
|
3492
3772
|
${importLine}
|
|
@@ -3508,13 +3788,14 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options, exp
|
|
|
3508
3788
|
const mutableExports = new Set(isLocalOnlyContainer(resolvedOptions) ? getSharedMutableExports(pkg, shareItem, exportConditions) : []);
|
|
3509
3789
|
const copiedNamedExports = namedExports.filter((name) => !mutableExports.has(name));
|
|
3510
3790
|
const liveNamedExports = namedExports.filter((name) => mutableExports.has(name));
|
|
3511
|
-
const liveNamedExportLine =
|
|
3791
|
+
const liveNamedExportLine = edges.reExportNames(liveNamedExports, sharedImportSource);
|
|
3512
3792
|
const hasCompleteExportCoverage = detectedNamedExports !== void 0;
|
|
3513
3793
|
const isWorkspaceSingleton = isWorkspacePackage && shareItem.shareConfig.singleton === true;
|
|
3514
3794
|
const usesDeferredSingletonFallback = hasCompleteExportCoverage && shareItem.shareConfig.eager !== true && (isWorkspacePackage || command !== "build" && isRemoteOnlyContainer(resolvedOptions) && shareItem.shareConfig.singleton === true || command === "build" && isRemoteContainer(resolvedOptions) && !isSharedSingletonConsumedByPeer(pkg, resolvedOptions, true));
|
|
3515
3795
|
const servesRemoteSingletonFallback = command !== "build" && isRemoteOnlyContainer(resolvedOptions) && shareItem.shareConfig.singleton === true;
|
|
3516
3796
|
const isConsumedByPeerSingleton = isSharedSingletonConsumedByPeer(pkg, resolvedOptions);
|
|
3517
3797
|
const usesEntryInjectedRemoteFallback = hasCompleteExportCoverage && !isWorkspaceSingleton && isRemoteContainer(resolvedOptions) && shareItem.shareConfig.singleton === true && resolvedOptions.hostInitInjectLocation === "entry" && (command === "build" || isConsumedByPeerSingleton);
|
|
3798
|
+
const usesDeferredEntryInjectedSingletonFallback = usesEntryInjectedRemoteFallback && !isReactCoreShare(pkg) && (pkg === "react-dom/client" || shareItem.shareConfig.eager !== true && !isSharedSingletonConsumedByPeer(pkg, resolvedOptions, true));
|
|
3518
3799
|
const usesEagerWorkspaceFallback = hasCompleteExportCoverage && isWorkspaceSingleton && !servesRemoteSingletonFallback && (isConsumedByPeerSingleton || shareItem.shareConfig.eager === true);
|
|
3519
3800
|
const usesDeferredTreeShakingFallback = hasCompleteExportCoverage && Boolean(treeShakingConsumer);
|
|
3520
3801
|
const reactMixedModeGuard = pkg === "react" ? createReactMixedModeRuntimeGuard() : "";
|
|
@@ -3522,11 +3803,14 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options, exp
|
|
|
3522
3803
|
let initBlock = "";
|
|
3523
3804
|
if (usesDeferredTreeShakingFallback) {
|
|
3524
3805
|
importLine = `${getRuntimeInitPromiseBootstrapCode(false, runtimeInitOwnerImportId)}\n ${importLine}`;
|
|
3525
|
-
exportLine = generateLazyWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, command !== "build" && !servesRemoteSingletonFallback && (isWorkspaceSingleton || isWorkspacePackage), liveNamedExports);
|
|
3526
|
-
} else if (
|
|
3806
|
+
exportLine = generateLazyWorkspaceSingletonExports(edges, namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, command !== "build" && !servesRemoteSingletonFallback && (isWorkspaceSingleton || isWorkspacePackage), liveNamedExports);
|
|
3807
|
+
} else if (usesDeferredEntryInjectedSingletonFallback) {
|
|
3808
|
+
importLine = `${getRuntimeInitPromiseBootstrapCode(false, runtimeInitOwnerImportId)}\n ${importLine}`;
|
|
3809
|
+
exportLine = generateLazyWorkspaceSingletonExports(edges, namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, false, liveNamedExports, true);
|
|
3810
|
+
} else if (usesEagerWorkspaceFallback || usesEntryInjectedRemoteFallback) exportLine = generateEagerWorkspaceSingletonExports(edges, namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, liveNamedExports);
|
|
3527
3811
|
else if (usesDeferredSingletonFallback) {
|
|
3528
3812
|
importLine = `${getRuntimeInitPromiseBootstrapCode(false, runtimeInitOwnerImportId)}\n ${importLine}`;
|
|
3529
|
-
exportLine = generateLazyWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, command !== "build" && !servesRemoteSingletonFallback && (isWorkspaceSingleton || isWorkspacePackage), liveNamedExports);
|
|
3813
|
+
exportLine = generateLazyWorkspaceSingletonExports(edges, namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, command !== "build" && !servesRemoteSingletonFallback && (isWorkspaceSingleton || isWorkspacePackage), liveNamedExports);
|
|
3530
3814
|
} else if (detectedNamedExports === void 0) {
|
|
3531
3815
|
exportLine = `const __mfDefaultExport = (() => {
|
|
3532
3816
|
${generateShareModuleUnwrapCode({
|
|
@@ -3536,7 +3820,7 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options, exp
|
|
|
3536
3820
|
})}
|
|
3537
3821
|
})();
|
|
3538
3822
|
export default __mfDefaultExport;
|
|
3539
|
-
|
|
3823
|
+
${edges.reExportAll(coherentLocalSource)}`;
|
|
3540
3824
|
initBlock = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
3541
3825
|
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});`;
|
|
3542
3826
|
} else if (namedExports.length > 0 && shareItem.shareConfig.singleton === true) {
|
|
@@ -3587,21 +3871,23 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options, exp
|
|
|
3587
3871
|
__mfSubscribeSharedCache(__mfModuleCache.share, ${cacheDescriptor}, __mfApplySharedDefaultExport);
|
|
3588
3872
|
__mfApplySharedDefaultExport(exportModule);
|
|
3589
3873
|
export { __mfDefaultExport as default };
|
|
3590
|
-
|
|
3874
|
+
${edges.reExportAll(sharedImportSource)}`;
|
|
3591
3875
|
initBlock = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
3592
3876
|
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});`;
|
|
3593
3877
|
} else {
|
|
3594
|
-
exportLine = `export default exportModule.default ?? exportModule\n
|
|
3878
|
+
exportLine = `export default exportModule.default ?? exportModule\n ${edges.reExportAll(sharedImportSource)}`;
|
|
3595
3879
|
initBlock = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
|
|
3596
3880
|
__mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});`;
|
|
3597
3881
|
}
|
|
3598
|
-
const
|
|
3599
|
-
const
|
|
3600
|
-
const
|
|
3601
|
-
|
|
3882
|
+
const staticLocalShareSource = detectedNamedExports === void 0 ? coherentLocalSource : skipServePrebuildWarmup ? devImportSource : sharedImportSource;
|
|
3883
|
+
const prebuildImportLine = usesEagerWorkspaceFallback || usesEntryInjectedRemoteFallback ? "" : usesDeferredSingletonFallback || usesDeferredTreeShakingFallback ? !servesRemoteSingletonFallback && usesDeferredSingletonFallback && command !== "build" && (isWorkspaceSingleton || isWorkspacePackage) ? edges.importNamespace(lazyLocalFallbackSource) : "" : edges.importNamespace(staticLocalShareSource);
|
|
3884
|
+
const devDynamicImportLine = isWorkspacePackage ? "" : usesDeferredSingletonFallback || usesDeferredTreeShakingFallback || usesDeferredEntryInjectedSingletonFallback ? "" : command !== "build" && !skipServePrebuildWarmup ? `;() => import(${escapeGeneratedStringLiteral(devImportSource)}).catch(() => {});` : "";
|
|
3885
|
+
const cacheHelpers = recordCoalescability(pkg, edges.none, command, shareItem.shareConfig, coalescableLoadShares) ? getSharedCacheHelpersImportCode(resolvedOptions) : sharedCacheHelperCode;
|
|
3886
|
+
const moduleBody = usesDeferredSingletonFallback || usesDeferredTreeShakingFallback || usesDeferredEntryInjectedSingletonFallback || usesEagerWorkspaceFallback || usesEntryInjectedRemoteFallback ? `
|
|
3887
|
+
${usesDeferredEntryInjectedSingletonFallback ? "" : prebuildImportLine}
|
|
3602
3888
|
${devDynamicImportLine}
|
|
3603
3889
|
${importLine}
|
|
3604
|
-
${
|
|
3890
|
+
${cacheHelpers}
|
|
3605
3891
|
${normalizeLocalShareModuleCode}
|
|
3606
3892
|
${initializedLocalShareModuleCode}
|
|
3607
3893
|
${exportLine}
|
|
@@ -3609,7 +3895,7 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options, exp
|
|
|
3609
3895
|
${prebuildImportLine}
|
|
3610
3896
|
${devDynamicImportLine}
|
|
3611
3897
|
${importLine}
|
|
3612
|
-
${
|
|
3898
|
+
${cacheHelpers}
|
|
3613
3899
|
${normalizeLocalShareModuleCode}
|
|
3614
3900
|
let exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)}
|
|
3615
3901
|
if (exportModule === undefined) {
|
|
@@ -3653,6 +3939,7 @@ function addConfiguredShare(pkg, options) {
|
|
|
3653
3939
|
if (options) getScopedUsedShares(options).add(pkg);
|
|
3654
3940
|
}
|
|
3655
3941
|
const LOCAL_SHARED_IMPORT_MAP_ID = "virtual:mf-localSharedImportMap";
|
|
3942
|
+
const LAZY_CONSUME_ONLY_SHARES_PLACEHOLDER = "__MF_LAZY_CONSUME_ONLY_SHARES__";
|
|
3656
3943
|
const localOwnerIds = /* @__PURE__ */ new WeakMap();
|
|
3657
3944
|
let nextLocalOwnerId = 1;
|
|
3658
3945
|
function getLocalOwnerKey(options) {
|
|
@@ -3690,6 +3977,10 @@ function getLocalSharedPackagePath(pkg, shareItem, options) {
|
|
|
3690
3977
|
if (shouldUseDirectReactImport() && pkg === "react") return "react";
|
|
3691
3978
|
return getConcreteSharedImportSource(pkg, shareItem) || getLocalProviderImportPath(pkg) || getSharedImportSource(pkg, shareItem, options);
|
|
3692
3979
|
}
|
|
3980
|
+
function getCanonicalSharedKey(pkg, shareItem) {
|
|
3981
|
+
const { request, shareKey } = shareItem.shareConfig;
|
|
3982
|
+
return request !== void 0 || shareKey !== void 0 ? getSharedRuntimeKey(pkg, shareItem) : pkg;
|
|
3983
|
+
}
|
|
3693
3984
|
function getDirectSharedCacheSeedImportPath(pkg, shareItem) {
|
|
3694
3985
|
return getConcreteSharedImportSource(pkg, shareItem) || getProjectResolvedImportPath(pkg) || getLocalProviderImportPath(pkg) || pkg;
|
|
3695
3986
|
}
|
|
@@ -3703,7 +3994,7 @@ function generateLocalSharedImportMap(options) {
|
|
|
3703
3994
|
import {loadShare} from "@module-federation/runtime";
|
|
3704
3995
|
${orderedShares.map((pkg, index) => {
|
|
3705
3996
|
const shareItem = getNormalizeShareItem(pkg, resolvedOptions);
|
|
3706
|
-
if (!shareItem
|
|
3997
|
+
if (!shareItem || !shareItem.shareConfig.eager || shareItem.shareConfig.import === false) return "";
|
|
3707
3998
|
return `import * as __mfEagerShare_${index} from ${toSafeJsLiteral(getLocalSharedPackagePath(pkg, shareItem, options))};`;
|
|
3708
3999
|
}).filter(Boolean).join("\n")}
|
|
3709
4000
|
${normalizeRuntimeShareCode}
|
|
@@ -3728,12 +4019,17 @@ function generateLocalSharedImportMap(options) {
|
|
|
3728
4019
|
const __mfHostOnly = (name) => async () => {
|
|
3729
4020
|
throw new Error(\`[Module Federation] Shared module '\${name}' must be provided by host\`);
|
|
3730
4021
|
};
|
|
4022
|
+
// Replaced by the lazy consume-only share plugin with the keys that only a dynamic
|
|
4023
|
+
// import() reaches, so init() leaves them to that import; an unreplaced string matches no key.
|
|
4024
|
+
const __mfLazyShares = ${JSON.stringify(LAZY_CONSUME_ONLY_SHARES_PLACEHOLDER)};
|
|
4025
|
+
const __mfIsLazyShare = (name) => Array.isArray(__mfLazyShares) && __mfLazyShares.includes(name);
|
|
3731
4026
|
const __mfConsumeOnly = (name, version, scope, materialize, shareConfig) => ({
|
|
3732
4027
|
name,
|
|
3733
4028
|
version,
|
|
3734
4029
|
scope: [scope],
|
|
3735
4030
|
loaded: false,
|
|
3736
|
-
materialize,
|
|
4031
|
+
materialize: materialize && !__mfIsLazyShare(name),
|
|
4032
|
+
lazy: __mfIsLazyShare(name),
|
|
3737
4033
|
eager: shareConfig.eager,
|
|
3738
4034
|
from: ${toSafeJsLiteral(resolvedOptions.name)},
|
|
3739
4035
|
canLiveRebind: true,
|
|
@@ -3743,7 +4039,8 @@ function generateLocalSharedImportMap(options) {
|
|
|
3743
4039
|
const importMap = {
|
|
3744
4040
|
${orderedShares.map((pkg, index) => {
|
|
3745
4041
|
const shareItem = getNormalizeShareItem(pkg, resolvedOptions);
|
|
3746
|
-
if (shareItem
|
|
4042
|
+
if (!shareItem) return "";
|
|
4043
|
+
if (shareItem.shareConfig.import === false) return `
|
|
3747
4044
|
${toSafeJsLiteral(pkg)}: __mfHostOnly(${toSafeJsLiteral(pkg)})`;
|
|
3748
4045
|
return `
|
|
3749
4046
|
${toSafeJsLiteral(pkg)}: async () => {
|
|
@@ -3759,7 +4056,7 @@ function generateLocalSharedImportMap(options) {
|
|
|
3759
4056
|
const shareItem = getNormalizeShareItem(key, resolvedOptions);
|
|
3760
4057
|
if (!shareItem) return null;
|
|
3761
4058
|
const isReactFamily = key.startsWith("react/") || key === "react-dom/client";
|
|
3762
|
-
const cacheKeys = [key, ...key === "react-dom/client" ? [
|
|
4059
|
+
const cacheKeys = [key, ...key === "react-dom/client" ? [getPackageName(REACT_DOM_CLIENT_SHARE)] : []].flatMap((pkg) => {
|
|
3763
4060
|
const descriptor = getSharedCacheDescriptor(pkg, shareItem);
|
|
3764
4061
|
return [descriptor.canonical, ...descriptor.aliases ?? []];
|
|
3765
4062
|
});
|
|
@@ -3771,7 +4068,7 @@ function generateLocalSharedImportMap(options) {
|
|
|
3771
4068
|
const canLiveRebind = shareItem.shareConfig.import === false || detectedNamedExports !== void 0;
|
|
3772
4069
|
const treeShakingConfig = canLiveRebind ? shareItem.shareConfig.treeShaking : void 0;
|
|
3773
4070
|
if (shareItem.shareConfig.import === false && !treeShakingConfig) return `
|
|
3774
|
-
${toSafeJsLiteral(key)}: __mfConsumeOnly(${toSafeJsLiteral(key)}, ${toSafeJsLiteral(shareItem.version)}, ${toSafeJsLiteral(shareItem.scope)}, ${sharesToMaterialize.has(key)}, {singleton: ${shareItem.shareConfig.singleton}, requiredVersion: ${toSafeJsLiteral(shareItem.shareConfig.requiredVersion)}, strictVersion: ${shareItem.shareConfig.strictVersion}, eager: ${Boolean(shareItem.shareConfig.eager)}})`;
|
|
4071
|
+
${toSafeJsLiteral(key)}: __mfConsumeOnly(${toSafeJsLiteral(key)}, ${toSafeJsLiteral(shareItem.version)}, ${toSafeJsLiteral(shareItem.scope)}, ${sharesToMaterialize.has(key)}, {singleton: ${shareItem.shareConfig.singleton}, requiredVersion: ${toSafeJsLiteral(shareItem.shareConfig.requiredVersion)}, strictVersion: ${shareItem.shareConfig.strictVersion}, eager: ${Boolean(shareItem.shareConfig.eager)}, ${shareItem.shareConfig.request !== void 0 ? `request: ${toSafeJsLiteral(shareItem.shareConfig.request)},` : ""} ${shareItem.shareConfig.shareKey !== void 0 ? `shareKey: ${toSafeJsLiteral(shareItem.shareConfig.shareKey)},` : ""}})`;
|
|
3775
4072
|
const treeShakingUsage = treeShakingConfig ? getTreeShakingExportUsage(key, shareItem, shareItem.name, options) : void 0;
|
|
3776
4073
|
const treeShakingProviderExports = treeShakingUsage?.kind === "exports" ? treeShakingUsage.usedExports : [];
|
|
3777
4074
|
const treeShakingUsedExports = resolvedOptions.injectTreeShakingUsedExports === false ? treeShakingConfig?.usedExports || [] : treeShakingProviderExports;
|
|
@@ -3842,6 +4139,8 @@ function generateLocalSharedImportMap(options) {
|
|
|
3842
4139
|
requiredVersion: ${toSafeJsLiteral(shareItem.shareConfig.requiredVersion)},
|
|
3843
4140
|
strictVersion: ${shareItem.shareConfig.strictVersion},
|
|
3844
4141
|
eager: ${Boolean(shareItem.shareConfig.eager)},
|
|
4142
|
+
${shareItem.shareConfig.request !== void 0 ? `request: ${toSafeJsLiteral(shareItem.shareConfig.request)},` : ""}
|
|
4143
|
+
${shareItem.shareConfig.shareKey !== void 0 ? `shareKey: ${toSafeJsLiteral(shareItem.shareConfig.shareKey)},` : ""}
|
|
3845
4144
|
${shareItem.shareConfig.import === false ? "import: false," : ""}
|
|
3846
4145
|
},
|
|
3847
4146
|
${treeShakingConfig ? `treeShaking: {
|
|
@@ -3894,11 +4193,17 @@ function expandSharedPrefixKey(prefixKey, used) {
|
|
|
3894
4193
|
function getOrderedUsedShares(options) {
|
|
3895
4194
|
const resolvedOptions = options ?? getNormalizeModuleFederationOptions();
|
|
3896
4195
|
const used = getUsedShares(options);
|
|
3897
|
-
const shares = new Set(
|
|
4196
|
+
const shares = /* @__PURE__ */ new Set();
|
|
4197
|
+
const addShare = (pkg) => {
|
|
4198
|
+
const shareItem = getNormalizeShareItem(pkg, resolvedOptions);
|
|
4199
|
+
shares.add(shareItem ? getCanonicalSharedKey(pkg, shareItem) : pkg);
|
|
4200
|
+
};
|
|
4201
|
+
used.forEach(addShare);
|
|
3898
4202
|
Object.keys(resolvedOptions.shared ?? {}).forEach((pkg) => {
|
|
3899
|
-
|
|
4203
|
+
const share = resolvedOptions.shared?.[pkg];
|
|
4204
|
+
if (share && !getSharedRequest(pkg, share).endsWith("/")) addShare(pkg);
|
|
3900
4205
|
});
|
|
3901
|
-
for (const [pkg, share] of Object.entries(resolvedOptions.shared ?? {})) if (pkg.endsWith("/")
|
|
4206
|
+
for (const [pkg, share] of Object.entries(resolvedOptions.shared ?? {})) if (share.shareConfig?.eager && getSharedRequest(pkg, share).endsWith("/")) for (const concrete of expandSharedPrefixKey(getSharedRequest(pkg, share), used)) addShare(concrete);
|
|
3902
4207
|
return orderSharedDependenciesFirst(Array.from(shares).sort((a, b) => {
|
|
3903
4208
|
const priority = (pkg) => pkg === "react" ? 0 : pkg === "react-dom" ? 1 : pkg.startsWith("react/") ? 2 : 3;
|
|
3904
4209
|
return priority(a) - priority(b) || a.localeCompare(b);
|
|
@@ -3911,7 +4216,8 @@ function getMaterializedShares(options) {
|
|
|
3911
4216
|
const usedForEager = options ? usedSharesByOptions.get(options) ?? [] : usedShares;
|
|
3912
4217
|
for (const [pkg, share] of Object.entries(resolvedOptions.shared ?? {})) {
|
|
3913
4218
|
if (!share.shareConfig?.eager) continue;
|
|
3914
|
-
|
|
4219
|
+
const request = getSharedRequest(pkg, share);
|
|
4220
|
+
if (request.endsWith("/")) for (const concrete of expandSharedPrefixKey(request, usedForEager)) shares.add(concrete);
|
|
3915
4221
|
else shares.add(pkg);
|
|
3916
4222
|
}
|
|
3917
4223
|
const configured = /* @__PURE__ */ new Map();
|
|
@@ -3939,10 +4245,14 @@ function getMaterializedShares(options) {
|
|
|
3939
4245
|
}
|
|
3940
4246
|
}
|
|
3941
4247
|
}
|
|
3942
|
-
|
|
4248
|
+
const sorted = [...shares].sort((a, b) => {
|
|
3943
4249
|
const priority = (pkg) => pkg === "react" ? 0 : pkg === "react-dom" ? 1 : pkg.startsWith("react/") ? 2 : 3;
|
|
3944
4250
|
return priority(a) - priority(b) || a.localeCompare(b);
|
|
3945
|
-
})
|
|
4251
|
+
});
|
|
4252
|
+
return orderSharedDependenciesFirst([...new Set(sorted.map((pkg) => {
|
|
4253
|
+
const shareItem = getNormalizeShareItem(pkg, resolvedOptions);
|
|
4254
|
+
return shareItem ? getCanonicalSharedKey(pkg, shareItem) : pkg;
|
|
4255
|
+
}))]);
|
|
3946
4256
|
}
|
|
3947
4257
|
/** Shared keys a share's package.json depends on (roots stand in for their subpaths, subpaths for their root), keyed by share. */
|
|
3948
4258
|
function getSharePrerequisites(ordered) {
|
|
@@ -4030,9 +4340,30 @@ function orderSharedDependenciesFirst(sharedPackages) {
|
|
|
4030
4340
|
}
|
|
4031
4341
|
function getShareItemForPreload(pkg, options = getNormalizeModuleFederationOptions()) {
|
|
4032
4342
|
const shared = options.shared;
|
|
4033
|
-
const
|
|
4343
|
+
const packageName = getPackageName(pkg);
|
|
4344
|
+
const wildcardKey = `${packageName}/`;
|
|
4034
4345
|
if (isExplicitSharedKey(pkg, options)) return shared[pkg];
|
|
4035
4346
|
if (isExplicitSharedKey(wildcardKey, options)) return shared[wildcardKey];
|
|
4347
|
+
if (pkg !== packageName && isExplicitSharedKey(packageName, options) && shared[packageName]?.shareConfig.import !== false && getCommonSharedSubpaths(packageName).includes(pkg)) return shared[packageName];
|
|
4348
|
+
const shareItem = getNormalizeShareItem(pkg, options);
|
|
4349
|
+
if (!shareItem) return void 0;
|
|
4350
|
+
if (shareItem.shareConfig.request === void 0 && shareItem.shareConfig.shareKey === void 0) return;
|
|
4351
|
+
const runtimeKey = getSharedRuntimeKey(pkg, shareItem);
|
|
4352
|
+
if (runtimeKey === pkg || runtimeKey.endsWith("/") && (pkg === runtimeKey.slice(0, -1) || pkg.startsWith(runtimeKey))) return shareItem;
|
|
4353
|
+
}
|
|
4354
|
+
/**
|
|
4355
|
+
* Entry-injected renderer wrappers (see `REACT_DOM_CLIENT_SHARE`) assign
|
|
4356
|
+
* `createRoot` only after `initPromise` and a dynamic import, so a standalone
|
|
4357
|
+
* remote must evaluate that wrapper before the app entry. The subpath is often
|
|
4358
|
+
* absent from `getMaterializedShares()` when pending shares is emitted:
|
|
4359
|
+
* `react-dom/` collapses to `react-dom`, and the entry import may not be
|
|
4360
|
+
* recorded yet.
|
|
4361
|
+
*/
|
|
4362
|
+
function shouldPreloadEntryDeferredReactDomClient(options) {
|
|
4363
|
+
if (options.hostInitInjectLocation !== "entry" || !isRemoteContainer(options)) return false;
|
|
4364
|
+
const shareItem = getShareItemForPreload(REACT_DOM_CLIENT_SHARE, options);
|
|
4365
|
+
if (!shareItem || shareItem.shareConfig.singleton !== true) return false;
|
|
4366
|
+
return shareItem.shareConfig.import !== false && !shareItem.shareConfig.treeShaking;
|
|
4036
4367
|
}
|
|
4037
4368
|
function generateSharedCacheSeedItem(pkg, shareItem, importPath, options = getNormalizeModuleFederationOptions()) {
|
|
4038
4369
|
const cacheDescriptor = getSharedCacheDescriptor(pkg, shareItem);
|
|
@@ -4217,7 +4548,28 @@ const externalSharedProviderSelectionHelperCode = `const __mfSelectExternalShare
|
|
|
4217
4548
|
) return undefined;
|
|
4218
4549
|
return { provider, scopeRootProvider };
|
|
4219
4550
|
};`;
|
|
4220
|
-
|
|
4551
|
+
/**
|
|
4552
|
+
* A consume-only stub never outranks a provider: when registering this container's
|
|
4553
|
+
* `import: false` share replaces an unloaded provider of the same version (#1311),
|
|
4554
|
+
* the `afterRegisterShare` hook restores the provider. Registered once per instance.
|
|
4555
|
+
*/
|
|
4556
|
+
function generateKeepProvidersOverStubsCode(runtimeVar) {
|
|
4557
|
+
return `if (!${runtimeVar}.__mfKeepAdoptedProviders) {
|
|
4558
|
+
${runtimeVar}.__mfKeepAdoptedProviders = true;
|
|
4559
|
+
${runtimeVar}.sharedHandler?.hooks?.lifecycle?.afterRegisterShare?.on?.((args) => {
|
|
4560
|
+
const { shared, previousShared, registeredShared } = args || {};
|
|
4561
|
+
if (
|
|
4562
|
+
shared?.shareConfig?.import !== false ||
|
|
4563
|
+
registeredShared !== shared ||
|
|
4564
|
+
!previousShared ||
|
|
4565
|
+
previousShared.shareConfig?.import === false
|
|
4566
|
+
) return;
|
|
4567
|
+
const versions = ${runtimeVar}.shareScopeMap?.[args.scope]?.[args.pkgName];
|
|
4568
|
+
if (versions && versions[shared.version] === shared) versions[shared.version] = previousShared;
|
|
4569
|
+
});
|
|
4570
|
+
}`;
|
|
4571
|
+
}
|
|
4572
|
+
function generateRuntimeSharedCacheSeedCode(shareStrategy, options, command = "build") {
|
|
4221
4573
|
const seedBatches = getShareBatches(options, false);
|
|
4222
4574
|
const seedOrder = seedBatches.flat();
|
|
4223
4575
|
const seedIndex = new Map(seedOrder.map((pkg, index) => [pkg, index]));
|
|
@@ -4231,7 +4583,7 @@ function generateRuntimeSharedCacheSeedCode(shareStrategy, options) {
|
|
|
4231
4583
|
// import and set materialize. An import:false share has no local fallback
|
|
4232
4584
|
// though, so on a cold request (materialize not set yet) it must still be
|
|
4233
4585
|
// attempted here, or it is never seeded and its consumer reads it undefined.
|
|
4234
|
-
const __mfSeedKeys = __mfSeedOrder.filter((pkg) => usedShared[pkg] && (usedShared[pkg].materialize !== false || usedShared[pkg].shareConfig?.import === false));
|
|
4586
|
+
const __mfSeedKeys = __mfSeedOrder.filter((pkg) => usedShared[pkg] && (usedShared[pkg].materialize !== false || (usedShared[pkg].shareConfig?.import === false && !usedShared[pkg].lazy)));
|
|
4235
4587
|
__mfModuleCache.providerInit ||= new Map();
|
|
4236
4588
|
const __mfInitializeProviderOnce = (key, initialize) => {
|
|
4237
4589
|
const existing = __mfModuleCache.providerInit.get(key);
|
|
@@ -4264,6 +4616,16 @@ function generateRuntimeSharedCacheSeedCode(shareStrategy, options) {
|
|
|
4264
4616
|
);
|
|
4265
4617
|
return;
|
|
4266
4618
|
}
|
|
4619
|
+
${command === "serve" ? `// A pending webpack provider for this share, or for its package when this
|
|
4620
|
+
// is a subpath, is only bridged after init(). Seeding the local fallback now
|
|
4621
|
+
// would evaluate the package's dev proxy, which snapshots its exports, before
|
|
4622
|
+
// the bridge runs and pin a second copy. The proxy seeds itself on first import.
|
|
4623
|
+
if (
|
|
4624
|
+
typeof __mfGetPendingExternalSharedProvider === 'function' &&
|
|
4625
|
+
__mfGetPendingExternalSharedProvider(pkg, share)
|
|
4626
|
+
) {
|
|
4627
|
+
return;
|
|
4628
|
+
}` : ""}
|
|
4267
4629
|
const externalProvider = typeof __mfGetExternalSharedProvider === 'function'
|
|
4268
4630
|
? __mfGetExternalSharedProvider(pkg, share)
|
|
4269
4631
|
: undefined;
|
|
@@ -4292,6 +4654,12 @@ function generateRuntimeSharedCacheSeedCode(shareStrategy, options) {
|
|
|
4292
4654
|
const mod = typeof factory === "function" ? factory() : factory;
|
|
4293
4655
|
return Promise.resolve(mod);
|
|
4294
4656
|
});
|
|
4657
|
+
// The seeded local copy is what this container's consumers are bound to.
|
|
4658
|
+
// Flag the Runtime's provider as eager so a same-version sibling cannot
|
|
4659
|
+
// take over the share scope slot via the Runtime's name tie-break.
|
|
4660
|
+
for (const provider of initRes.options.shared?.[pkg] || []) {
|
|
4661
|
+
if (provider.get === share.get) provider.eager = true;
|
|
4662
|
+
}
|
|
4295
4663
|
${normalizeRuntimeShareCode}
|
|
4296
4664
|
const normalizedModule = __mfNormalizeRuntimeShare(resolved);
|
|
4297
4665
|
const exportModule = normalizedModule === resolved ? {...resolved} : normalizedModule;
|
|
@@ -4564,7 +4932,7 @@ function generateTreeShakingSnapshotPluginCode(enabled) {
|
|
|
4564
4932
|
},
|
|
4565
4933
|
});`;
|
|
4566
4934
|
}
|
|
4567
|
-
function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(options), command = "build", exportConditions) {
|
|
4935
|
+
function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(options), command = "build", exportConditions, isSsrBuild = false) {
|
|
4568
4936
|
const needsSharedProviderSelectionHelper = hasShared(options);
|
|
4569
4937
|
const hasTreeShakingShared = Object.values(options.shared ?? {}).some((share) => !!share?.shareConfig.treeShaking);
|
|
4570
4938
|
const hasMultipleShareScopes = Array.isArray(options.shareScope);
|
|
@@ -4576,7 +4944,7 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
4576
4944
|
...hasTreeShakingShared ? ["getRemoteEntry"] : []
|
|
4577
4945
|
].join(", ");
|
|
4578
4946
|
const runtimeHelperImports = [...hasTreeShakingShared ? ["global as runtimeGlobal"] : [], ...needsSharedProviderSelectionHelper ? ["share as runtimeShare"] : []];
|
|
4579
|
-
const pluginImportNames = options.runtimePlugins.map((p, i) => {
|
|
4947
|
+
const pluginImportNames = filterRuntimePluginsForTarget(options.runtimePlugins, SSR_ONLY_RUNTIME_PLUGINS, isSsrBuild).map((p, i) => {
|
|
4580
4948
|
if (typeof p === "string") return [
|
|
4581
4949
|
`$runtimePlugin_${i}`,
|
|
4582
4950
|
`import $runtimePlugin_${i} from "${p}";`,
|
|
@@ -4899,13 +5267,36 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
4899
5267
|
};
|
|
4900
5268
|
}
|
|
4901
5269
|
const runtimeResolveShareHook = initRes.sharedHandler.hooks.lifecycle.resolveShare;
|
|
5270
|
+
// Registering this container's shares lets its consume-only stub displace the parent's
|
|
5271
|
+
// unloaded same-version provider whenever this container's name sorts after the parent's
|
|
5272
|
+
// (the Runtime keeps the higher name). Nothing can be loaded from a stub, so put the
|
|
5273
|
+
// provider back; a share bridged later, e.g. from a lazy import(), still finds it.
|
|
5274
|
+
${generateKeepProvidersOverStubsCode("initRes")}
|
|
4902
5275
|
const __mfRuntimeProviderOrigins = new WeakMap();
|
|
4903
5276
|
runtimeResolveShareHook.on((args) => {
|
|
4904
5277
|
const loadId = args.shareInfo?.[__mfRuntimeShareLoadIdKey];
|
|
4905
5278
|
const resolver = args.resolver;
|
|
4906
5279
|
if (typeof resolver !== "function") return args;
|
|
4907
5280
|
const instrumentedResolver = (...resolverArgs) => {
|
|
4908
|
-
|
|
5281
|
+
let resolved = resolver(...resolverArgs);
|
|
5282
|
+
// A consume-only stub can never be loaded. The Runtime still settles on one when
|
|
5283
|
+
// it carries the highest version, e.g. a parent that registers its provider under
|
|
5284
|
+
// "0.0.0"; hand back the provider this container selects for itself instead.
|
|
5285
|
+
if (
|
|
5286
|
+
resolved?.shared?.shareConfig?.import === false &&
|
|
5287
|
+
typeof __mfSelectSharedProvider === "function" &&
|
|
5288
|
+
usedShared[args.pkgName]
|
|
5289
|
+
) {
|
|
5290
|
+
const provider = __mfSelectSharedProvider(
|
|
5291
|
+
args.shareScopeMap?.[args.scope]?.[args.pkgName],
|
|
5292
|
+
args.pkgName,
|
|
5293
|
+
usedShared[args.pkgName],
|
|
5294
|
+
'${options.shareStrategy}'
|
|
5295
|
+
);
|
|
5296
|
+
if (provider && provider.shareConfig?.import !== false) {
|
|
5297
|
+
resolved = { shared: provider, useTreesShaking: resolved.useTreesShaking };
|
|
5298
|
+
}
|
|
5299
|
+
}
|
|
4909
5300
|
const selectedProvider = resolved?.shared;
|
|
4910
5301
|
if (
|
|
4911
5302
|
selectedProvider &&
|
|
@@ -5318,7 +5709,7 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
5318
5709
|
);
|
|
5319
5710
|
}
|
|
5320
5711
|
}
|
|
5321
|
-
${generateRuntimeSharedCacheSeedCode(options.shareStrategy, options)}
|
|
5712
|
+
${generateRuntimeSharedCacheSeedCode(options.shareStrategy, options, command)}
|
|
5322
5713
|
${initializeSharingCode}
|
|
5323
5714
|
__mfRestoreForeignSharedProviders();
|
|
5324
5715
|
// Calling provider.get() marks a provider as loaded. Wait until the Runtime has
|
|
@@ -5336,9 +5727,13 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
5336
5727
|
);
|
|
5337
5728
|
}));
|
|
5338
5729
|
};
|
|
5339
|
-
await __mfBridgeSharedProviders();
|
|
5340
5730
|
if (__mfUsesWebpackShareScope) {
|
|
5731
|
+
// A webpack host's loadShare() awaits initializeSharing(), which awaits this
|
|
5732
|
+
// init(). Bridging here would call the host's provider.get() and re-enter
|
|
5733
|
+
// loadShare(), so both promises wait on each other forever (#1326).
|
|
5341
5734
|
__mfLateBridgeShared = __mfBridgeSharedProviders;
|
|
5735
|
+
} else {
|
|
5736
|
+
await __mfBridgeSharedProviders();
|
|
5342
5737
|
}
|
|
5343
5738
|
try {
|
|
5344
5739
|
const allInstances = globalThis.__FEDERATION__?.__SHARE__;
|
|
@@ -5492,6 +5887,29 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
5492
5887
|
(pkg) => !__mfBlockedSeedKeys.has(__mfSeedIndex.get(pkg))
|
|
5493
5888
|
));
|
|
5494
5889
|
await __mfSeedLocalShared(__mfReadyDeferredSeedKeys);
|
|
5890
|
+
${command === "build" ? `// A consume-only share reached only through import() is bridged when that import runs
|
|
5891
|
+
// (see pluginLazyConsumeOnlyShares), through the same provider selection init() uses.
|
|
5892
|
+
const __mfLazyShareLoads = new Map();
|
|
5893
|
+
__mfResolveState.loadLazyShares = async (names) => {
|
|
5894
|
+
const requested = new Set(names);
|
|
5895
|
+
for (const batch of __mfMaterializedShareBatches) await Promise.all(batch.filter((pkg) => requested.has(pkg)).map((pkg) => {
|
|
5896
|
+
const share = usedShared[pkg];
|
|
5897
|
+
if (!share || !share.lazy || !__mfIsRuntimeOnlySharePending(pkg)) return;
|
|
5898
|
+
let load = __mfLazyShareLoads.get(pkg);
|
|
5899
|
+
if (!load) {
|
|
5900
|
+
load = __mfBridgeExternalSharedProvider(
|
|
5901
|
+
pkg,
|
|
5902
|
+
share,
|
|
5903
|
+
${hasMultipleShareScopes ? "getShareVersions(pkg, share)" : "shared[pkg]"},
|
|
5904
|
+
initialShared[pkg],
|
|
5905
|
+
undefined
|
|
5906
|
+
).then(() => __mfIsRuntimeOnlySharePending(pkg) ? __mfResolveImportFalseShared(pkg, share) : undefined);
|
|
5907
|
+
load.catch(() => __mfLazyShareLoads.delete(pkg));
|
|
5908
|
+
__mfLazyShareLoads.set(pkg, load);
|
|
5909
|
+
}
|
|
5910
|
+
return load;
|
|
5911
|
+
}));
|
|
5912
|
+
};` : ""}
|
|
5495
5913
|
initResolve(initRes)
|
|
5496
5914
|
return initRes
|
|
5497
5915
|
}
|
|
@@ -5508,8 +5926,13 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
|
|
|
5508
5926
|
${guardHostAutoInit ? `let __mfInitPromise;
|
|
5509
5927
|
function __mfGuardedInit(shared, initScope, remoteEntryInitOptions) {
|
|
5510
5928
|
if (shared === undefined && __mfInitPromise) return __mfInitPromise;
|
|
5511
|
-
|
|
5512
|
-
|
|
5929
|
+
// A call skipped by the circular-init guard resolves to undefined and must not
|
|
5930
|
+
// replace the cached result of the call that actually initialized the container.
|
|
5931
|
+
const prev = __mfInitPromise;
|
|
5932
|
+
const next = init(shared, initScope, remoteEntryInitOptions);
|
|
5933
|
+
__mfInitPromise = prev ? next.then((res) => (res === undefined ? prev : res)) : next;
|
|
5934
|
+
if (prev) __mfInitPromise.catch(() => {});
|
|
5935
|
+
return next;
|
|
5513
5936
|
}
|
|
5514
5937
|
export { __mfGuardedInit as init, getExposes as get }` : `export { init, getExposes as get }`}
|
|
5515
5938
|
`;
|
|
@@ -5590,7 +6013,8 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build", options
|
|
|
5590
6013
|
for (const __mfHostInitShareBatch of __mfHostInitShareBatches) {
|
|
5591
6014
|
await Promise.all(__mfHostInitShareBatch.map(async (pkg) => {
|
|
5592
6015
|
const share = usedShared[pkg];
|
|
5593
|
-
|
|
6016
|
+
// A standalone container has no dynamic-import boundary to load a lazy share behind.
|
|
6017
|
+
if (!share || (share.materialize === false && !share.lazy)) return;
|
|
5594
6018
|
// remoteEntry.init resolves tree-enabled shares into the
|
|
5595
6019
|
// coverage-aware cache. Never republish that selected partial under
|
|
5596
6020
|
// a generic full-module key here.
|
|
@@ -5621,20 +6045,7 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build", options
|
|
|
5621
6045
|
// container's own stub and lets it displace an unloaded adopted
|
|
5622
6046
|
// provider whenever this container's name sorts after the provider's
|
|
5623
6047
|
// (#1311). Put the provider back: a stub never outranks a provider.
|
|
5624
|
-
|
|
5625
|
-
runtime.__mfKeepAdoptedProviders = true;
|
|
5626
|
-
runtime.sharedHandler?.hooks?.lifecycle?.afterRegisterShare?.on?.((args) => {
|
|
5627
|
-
const { shared, previousShared, registeredShared } = args || {};
|
|
5628
|
-
if (
|
|
5629
|
-
shared?.shareConfig?.import !== false ||
|
|
5630
|
-
registeredShared !== shared ||
|
|
5631
|
-
!previousShared ||
|
|
5632
|
-
previousShared.shareConfig?.import === false
|
|
5633
|
-
) return;
|
|
5634
|
-
const versions = runtime.shareScopeMap?.[args.scope]?.[args.pkgName];
|
|
5635
|
-
if (versions && versions[shared.version] === shared) versions[shared.version] = previousShared;
|
|
5636
|
-
});
|
|
5637
|
-
}
|
|
6048
|
+
${generateKeepProvidersOverStubsCode("runtime")}
|
|
5638
6049
|
for (const instance of globalThis.__FEDERATION__?.__INSTANCES__ || []) {
|
|
5639
6050
|
for (const scopeName of __mfScopeNames) {
|
|
5640
6051
|
const versions = instance?.shareScopeMap?.[scopeName]?.[pkg];
|
|
@@ -5734,22 +6145,32 @@ function getPendingSharesState(options) {
|
|
|
5734
6145
|
}
|
|
5735
6146
|
function generatePendingSharesCode(command = "build", options) {
|
|
5736
6147
|
const resolvedOptions = options ?? getNormalizeModuleFederationOptions();
|
|
5737
|
-
const
|
|
6148
|
+
const pendingSharePkgs = command === "build" ? getMaterializedShares(options).filter((pkg) => {
|
|
5738
6149
|
const shareItem = getShareItemForPreload(pkg, resolvedOptions);
|
|
5739
6150
|
if (!shareItem || pkg.endsWith("/")) return false;
|
|
5740
6151
|
if (shareItem.shareConfig.eager) return false;
|
|
5741
6152
|
return shareItem.shareConfig.import !== false && !shareItem.shareConfig.treeShaking;
|
|
5742
|
-
})
|
|
6153
|
+
}) : [];
|
|
6154
|
+
if (command === "build" && shouldPreloadEntryDeferredReactDomClient(resolvedOptions) && !pendingSharePkgs.includes("react-dom/client")) pendingSharePkgs.push(REACT_DOM_CLIENT_SHARE);
|
|
6155
|
+
const pendingShareImports = pendingSharePkgs.map((pkg) => `[${toSafeJsLiteral(pkg)}, () => import(${toSafeJsLiteral(getLoadShareModulePath(pkg, false, options))})]`);
|
|
5743
6156
|
return `
|
|
5744
6157
|
${getRuntimeModuleCacheBootstrapCode()}
|
|
5745
6158
|
${sharedCacheHelperCode}
|
|
5746
6159
|
const __mfPendingShareImports = [${pendingShareImports.join(", ")}];
|
|
5747
6160
|
export async function preloadPendingShares() {
|
|
5748
6161
|
if (__mfPendingShareImports.length === 0) return;
|
|
6162
|
+
const __mfRendererShare = ${toSafeJsLiteral(REACT_DOM_CLIENT_SHARE)};
|
|
6163
|
+
const __mfRendererParent = ${toSafeJsLiteral(getPackageName(REACT_DOM_CLIENT_SHARE))};
|
|
5749
6164
|
const {usedShared} = await import("${getLocalSharedImportMapPath(options)}");
|
|
5750
6165
|
await Promise.all(__mfPendingShareImports.map(async ([pkg, load]) => {
|
|
5751
|
-
const
|
|
5752
|
-
|
|
6166
|
+
const exactShare = usedShared[pkg];
|
|
6167
|
+
const share = exactShare ?? (pkg === __mfRendererShare ? usedShared[__mfRendererParent] : undefined);
|
|
6168
|
+
if (!share || share.treeShaking || share.shareConfig?.import === false) return;
|
|
6169
|
+
// The collapsed parent does not mark the renderer subpath materialized until the entry
|
|
6170
|
+
// imports it, and that import map can be emitted first. The deferred renderer wrapper
|
|
6171
|
+
// still has to run before a standalone entry reads createRoot. A cache hit (the host
|
|
6172
|
+
// renderer) skips load(), so a nested leaf does not import its own client.
|
|
6173
|
+
if (exactShare && exactShare.materialize === false && pkg !== __mfRendererShare) return;
|
|
5753
6174
|
const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
|
|
5754
6175
|
if (__mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) !== undefined) return;
|
|
5755
6176
|
await load().catch((err) => console.warn("[module-federation] shared preload failed:", pkg, err));
|
|
@@ -6413,7 +6834,7 @@ for (const __mfRemoteEntryPrefetchUrl of __mfRemoteEntryPrefetchUrls) {
|
|
|
6413
6834
|
}
|
|
6414
6835
|
` : "";
|
|
6415
6836
|
const sharedPreloadSources = _command === "serve" && waitsForInit && isRemoteOnlyContainer(normalizedOptions) && federationOptions ? Array.from(getUsedShares(federationOptions)).filter((pkg) => !pkg.endsWith("/")).filter((pkg) => {
|
|
6416
|
-
const shareItem =
|
|
6837
|
+
const shareItem = getNormalizeShareItem(pkg, federationOptions);
|
|
6417
6838
|
const isExplicitShare = Object.hasOwn(federationOptions.shared, pkg);
|
|
6418
6839
|
return shareItem?.shareConfig?.singleton === true && shareItem?.shareConfig?.import !== false && !shareItem?.shareConfig?.treeShaking && (isExplicitShare || typeof shareItem?.shareConfig?.import === "string" || Boolean(getProjectResolvedImportPath(pkg)));
|
|
6419
6840
|
}).map((pkg) => toViteEncodedId(getLoadShareModulePath(pkg, false, federationOptions))) : [];
|
|
@@ -6842,17 +7263,20 @@ function checkAliasConflicts(options) {
|
|
|
6842
7263
|
}
|
|
6843
7264
|
return false;
|
|
6844
7265
|
};
|
|
6845
|
-
for (const sharedKey of sharedKeys)
|
|
6846
|
-
const
|
|
6847
|
-
|
|
6848
|
-
|
|
6849
|
-
|
|
6850
|
-
if (
|
|
6851
|
-
|
|
6852
|
-
|
|
6853
|
-
|
|
6854
|
-
|
|
6855
|
-
|
|
7266
|
+
for (const sharedKey of sharedKeys) {
|
|
7267
|
+
const request = getSharedRequest(sharedKey, shared[sharedKey]);
|
|
7268
|
+
for (const aliasEntry of userAliases) {
|
|
7269
|
+
const replacement = aliasEntry.replacement;
|
|
7270
|
+
if (!matchesSharedKey(aliasEntry, request)) continue;
|
|
7271
|
+
if (replacement === "$1") break;
|
|
7272
|
+
if (typeof replacement === "string") {
|
|
7273
|
+
if (getPackageNameFromNodeModulePath(replacement) === (request.endsWith("/") ? request.slice(0, -1) : request)) continue;
|
|
7274
|
+
conflicts.push({
|
|
7275
|
+
sharedModule: sharedKey,
|
|
7276
|
+
alias: String(aliasEntry.find),
|
|
7277
|
+
target: replacement
|
|
7278
|
+
});
|
|
7279
|
+
}
|
|
6856
7280
|
}
|
|
6857
7281
|
}
|
|
6858
7282
|
if (conflicts.length > 0) {
|
|
@@ -7567,9 +7991,6 @@ function pluginExternalRuntimeCore() {
|
|
|
7567
7991
|
};
|
|
7568
7992
|
}
|
|
7569
7993
|
//#endregion
|
|
7570
|
-
//#region package.json
|
|
7571
|
-
var version$1 = "1.22.1";
|
|
7572
|
-
//#endregion
|
|
7573
7994
|
//#region src/virtualModules/index.ts
|
|
7574
7995
|
function initVirtualModules(command, remoteEntryId, enableSsrInit = false, options) {
|
|
7575
7996
|
writeLocalSharedImportMap(options);
|
|
@@ -7587,6 +8008,11 @@ const JS_EXTENSIONS = [
|
|
|
7587
8008
|
".mjs",
|
|
7588
8009
|
".cjs"
|
|
7589
8010
|
];
|
|
8011
|
+
/** A module path without its JS extension, so `./src/App` matches `/root/src/App.tsx`. */
|
|
8012
|
+
const stripKnownJsExtension = (file) => {
|
|
8013
|
+
const ext = path$1.extname(file);
|
|
8014
|
+
return JS_EXTENSIONS.includes(ext) ? path$1.join(path$1.dirname(file), path$1.basename(file, ext)) : file;
|
|
8015
|
+
};
|
|
7590
8016
|
/**
|
|
7591
8017
|
* Creates an empty asset map structure for tracking JS and CSS assets
|
|
7592
8018
|
* @returns Initialized asset map with sync/async arrays for JS and CSS
|
|
@@ -7705,8 +8131,8 @@ const processModuleAssets = (bundle, filesMap, moduleMatcher, options = {}) => {
|
|
|
7705
8131
|
const comparableModulePath = options.root ? path$1.resolve(options.root, modulePath) : modulePath;
|
|
7706
8132
|
const comparableModulePaths = [comparableModulePath];
|
|
7707
8133
|
if (options.stripKnownJsExtensions) {
|
|
7708
|
-
const
|
|
7709
|
-
if (
|
|
8134
|
+
const stripped = stripKnownJsExtension(comparableModulePath);
|
|
8135
|
+
if (stripped !== comparableModulePath) comparableModulePaths.push(stripped);
|
|
7710
8136
|
}
|
|
7711
8137
|
const matchKey = comparableModulePaths.map(moduleMatcher).find(Boolean);
|
|
7712
8138
|
if (!matchKey) continue;
|
|
@@ -7767,6 +8193,118 @@ const buildFileToShareKeyMap = async (shareKeys, resolveFn, options) => {
|
|
|
7767
8193
|
return fileToShareKey;
|
|
7768
8194
|
};
|
|
7769
8195
|
//#endregion
|
|
8196
|
+
//#region src/plugins/pluginLazyConsumeOnlyShares.ts
|
|
8197
|
+
const chunkModuleIds = (chunk) => [...chunk.facadeModuleId ? [chunk.facadeModuleId] : [], ...chunk.moduleIds ?? Object.keys(chunk.modules ?? {})];
|
|
8198
|
+
function buildLazyShareGraph(chunks, wrapperShares, exposeModules) {
|
|
8199
|
+
const sharesInChunk = /* @__PURE__ */ new Map();
|
|
8200
|
+
const startupRoots = [];
|
|
8201
|
+
for (const [fileName, chunk] of Object.entries(chunks)) {
|
|
8202
|
+
if (chunk.type !== "chunk") continue;
|
|
8203
|
+
const moduleIds = chunkModuleIds(chunk);
|
|
8204
|
+
sharesInChunk.set(fileName, new Set(moduleIds.map((id) => wrapperShares.get(normalizeVirtualModuleId(id))).filter((share) => share !== void 0)));
|
|
8205
|
+
if (chunk.isEntry || moduleIds.some((id) => exposeModules.has(stripKnownJsExtension(id)))) startupRoots.push(fileName);
|
|
8206
|
+
}
|
|
8207
|
+
const sharesInClosure = (roots) => new Set(collectStaticChunks(chunks, roots).flatMap((chunk) => [...sharesInChunk.get(chunk.fileName) ?? []]));
|
|
8208
|
+
const lazyShares = new Set([...sharesInChunk.values()].flatMap((shares) => [...shares]));
|
|
8209
|
+
for (const share of sharesInClosure(startupRoots)) lazyShares.delete(share);
|
|
8210
|
+
const sharesByChunk = /* @__PURE__ */ new Map();
|
|
8211
|
+
if (lazyShares.size > 0) for (const fileName of sharesInChunk.keys()) {
|
|
8212
|
+
const shares = [...sharesInClosure([fileName])].filter((share) => lazyShares.has(share));
|
|
8213
|
+
if (shares.length > 0) sharesByChunk.set(fileName, shares.sort());
|
|
8214
|
+
}
|
|
8215
|
+
return {
|
|
8216
|
+
lazyShares,
|
|
8217
|
+
sharesByChunk
|
|
8218
|
+
};
|
|
8219
|
+
}
|
|
8220
|
+
const COMMENTS = String.raw`(?:\s|\/\*[\s\S]*?\*\/|\/\/[^\n]*\n)*`;
|
|
8221
|
+
const DYNAMIC_IMPORT_REGEX = new RegExp(String.raw`\bimport\(${COMMENTS}(["'` + "`" + String.raw`])([^"'` + "`" + String.raw`\n]+)\1${COMMENTS}\)`, "g");
|
|
8222
|
+
const QUOTES = [
|
|
8223
|
+
"\"",
|
|
8224
|
+
"'",
|
|
8225
|
+
"`"
|
|
8226
|
+
];
|
|
8227
|
+
/**
|
|
8228
|
+
* A consume-only (`import: false`) share that only a dynamic `import()` reaches is
|
|
8229
|
+
* left out of `init()` and bridged when that import runs: the import expression is
|
|
8230
|
+
* wrapped so the share is in the cache before the chunk evaluates. There is no
|
|
8231
|
+
* other async boundary in an ESM graph without top-level await, so a wrapper
|
|
8232
|
+
* reached statically from an entry or an expose keeps loading during `init()`.
|
|
8233
|
+
*/
|
|
8234
|
+
function pluginLazyConsumeOnlyShares(options) {
|
|
8235
|
+
let viteConfig;
|
|
8236
|
+
const graphs = /* @__PURE__ */ new WeakMap();
|
|
8237
|
+
const helperName = `__mfLoadLazyShares_${options.internalName.replace(/[^A-Za-z0-9_$]/g, "_")}`;
|
|
8238
|
+
return {
|
|
8239
|
+
name: "module-federation:lazy-consume-only-shares",
|
|
8240
|
+
apply: "build",
|
|
8241
|
+
configResolved(config) {
|
|
8242
|
+
viteConfig = config;
|
|
8243
|
+
},
|
|
8244
|
+
renderChunk(code, chunk, _outputOptions, meta) {
|
|
8245
|
+
const renderedChunk = chunk;
|
|
8246
|
+
const chunks = meta?.chunks;
|
|
8247
|
+
if (!chunks || Object.keys(options.exposes).length === 0) return null;
|
|
8248
|
+
if (isServerBuildContext(this, viteConfig)) return null;
|
|
8249
|
+
let graph = graphs.get(chunks);
|
|
8250
|
+
if (!graph) {
|
|
8251
|
+
const isRolldown = getIsRolldown(this);
|
|
8252
|
+
const wrapperShares = /* @__PURE__ */ new Map();
|
|
8253
|
+
for (const shareKey of getUsedShares(options)) {
|
|
8254
|
+
const shareConfig = getNormalizeShareItem(shareKey, options)?.shareConfig;
|
|
8255
|
+
if (shareConfig?.import !== false || shareConfig.eager || shareConfig.treeShaking) continue;
|
|
8256
|
+
wrapperShares.set(normalizeVirtualModuleId(getLoadShareModulePath(shareKey, isRolldown, options)), shareKey);
|
|
8257
|
+
}
|
|
8258
|
+
const root = viteConfig?.root ?? process.cwd();
|
|
8259
|
+
graph = buildLazyShareGraph(chunks, wrapperShares, new Set(Object.values(options.exposes).map((expose) => stripKnownJsExtension(path$1.resolve(root, expose.import)))));
|
|
8260
|
+
graphs.set(chunks, graph);
|
|
8261
|
+
}
|
|
8262
|
+
if (graph.lazyShares.size === 0) return null;
|
|
8263
|
+
const rewriter = new CodeRewriter(code);
|
|
8264
|
+
let edited = false;
|
|
8265
|
+
const importMapId = normalizeVirtualModuleId(getLocalSharedImportMapPath(options));
|
|
8266
|
+
if (chunkModuleIds(renderedChunk).some((id) => normalizeVirtualModuleId(id) === importMapId)) for (const quote of QUOTES) {
|
|
8267
|
+
const literal = `${quote}${LAZY_CONSUME_ONLY_SHARES_PLACEHOLDER}${quote}`;
|
|
8268
|
+
const start = code.indexOf(literal);
|
|
8269
|
+
if (start === -1) continue;
|
|
8270
|
+
rewriter.overwrite(start, start + literal.length, JSON.stringify([...graph.lazyShares].sort()));
|
|
8271
|
+
edited = true;
|
|
8272
|
+
break;
|
|
8273
|
+
}
|
|
8274
|
+
const chunkDir = path$1.posix.dirname(renderedChunk.fileName);
|
|
8275
|
+
const codePositions = createCodePositionMap(code);
|
|
8276
|
+
let usesHelper = false;
|
|
8277
|
+
for (const match of code.matchAll(DYNAMIC_IMPORT_REGEX)) {
|
|
8278
|
+
const [expression, , specifier] = match;
|
|
8279
|
+
const start = match.index;
|
|
8280
|
+
if (!codePositions[start]) continue;
|
|
8281
|
+
const target = path$1.posix.normalize(path$1.posix.join(chunkDir, specifier));
|
|
8282
|
+
const shares = graph.sharesByChunk.get(target);
|
|
8283
|
+
if (!shares || !renderedChunk.dynamicImports.includes(target)) continue;
|
|
8284
|
+
rewriter.overwrite(start, start + expression.length, `${helperName}(${JSON.stringify(shares)}).then(() => ${expression})`);
|
|
8285
|
+
usesHelper = edited = true;
|
|
8286
|
+
}
|
|
8287
|
+
if (!edited) return null;
|
|
8288
|
+
if (usesHelper) {
|
|
8289
|
+
const stateKey = JSON.stringify(getRuntimeInitGlobalKey(getRuntimeInitStatusImportId(options)));
|
|
8290
|
+
rewriter.overwrite(code.length, code.length, `
|
|
8291
|
+
function ${helperName}(names) {
|
|
8292
|
+
const state = globalThis[${stateKey}];
|
|
8293
|
+
return state ? state.initPromise.then(() => (typeof state.loadLazyShares === "function" ? state.loadLazyShares(names) : undefined)) : Promise.resolve();
|
|
8294
|
+
}
|
|
8295
|
+
`);
|
|
8296
|
+
}
|
|
8297
|
+
return {
|
|
8298
|
+
code: rewriter.toString(),
|
|
8299
|
+
map: rewriter.generateMap(renderedChunk.fileName)
|
|
8300
|
+
};
|
|
8301
|
+
}
|
|
8302
|
+
};
|
|
8303
|
+
}
|
|
8304
|
+
//#endregion
|
|
8305
|
+
//#region package.json
|
|
8306
|
+
var version$1 = "1.23.0";
|
|
8307
|
+
//#endregion
|
|
7770
8308
|
//#region src/virtualModules/virtualExposesSSR.ts
|
|
7771
8309
|
/**
|
|
7772
8310
|
* Virtual module ID for the SSR exposes map.
|
|
@@ -7821,7 +8359,8 @@ function getSsrFileNameParts(browserFilename) {
|
|
|
7821
8359
|
ext
|
|
7822
8360
|
};
|
|
7823
8361
|
}
|
|
7824
|
-
function getSsrRemoteEntryFileName(browserFilename) {
|
|
8362
|
+
function getSsrRemoteEntryFileName(options, browserFilename = options.filename) {
|
|
8363
|
+
if (options.ssrFilename) return options.ssrFilename;
|
|
7825
8364
|
const { base, ext } = getSsrFileNameParts(browserFilename);
|
|
7826
8365
|
return `${base}.ssr${ext ?? ".js"}`;
|
|
7827
8366
|
}
|
|
@@ -7835,14 +8374,15 @@ function getSsrSharedSingletons(options) {
|
|
|
7835
8374
|
const result = {};
|
|
7836
8375
|
for (const [pkg, share] of Object.entries(options.shared)) {
|
|
7837
8376
|
if (!share.shareConfig.singleton) continue;
|
|
7838
|
-
|
|
7839
|
-
|
|
8377
|
+
const request = getSharedRequest(pkg, share);
|
|
8378
|
+
if (request.endsWith("/")) {
|
|
8379
|
+
for (const concrete of expandSharedPrefixKey(request, used)) result[getSharedRuntimeKey(concrete, share)] = {
|
|
7840
8380
|
...share,
|
|
7841
8381
|
name: concrete
|
|
7842
8382
|
};
|
|
7843
8383
|
continue;
|
|
7844
8384
|
}
|
|
7845
|
-
result[pkg] = share;
|
|
8385
|
+
result[getSharedRuntimeKey(pkg, share)] = share;
|
|
7846
8386
|
}
|
|
7847
8387
|
return result;
|
|
7848
8388
|
}
|
|
@@ -8187,7 +8727,7 @@ const Manifest = (providedOptions) => {
|
|
|
8187
8727
|
type: "module"
|
|
8188
8728
|
},
|
|
8189
8729
|
ssrRemoteEntry: {
|
|
8190
|
-
name: getSsrRemoteEntryFileName(devRemoteEntryFile),
|
|
8730
|
+
name: getSsrRemoteEntryFileName(mfOptions, devRemoteEntryFile),
|
|
8191
8731
|
path: "/__mf_ssr__/",
|
|
8192
8732
|
type: "module"
|
|
8193
8733
|
},
|
|
@@ -8230,6 +8770,33 @@ const Manifest = (providedOptions) => {
|
|
|
8230
8770
|
publicPath = mfOptions.publicPath === "auto" ? "auto" : resolvePublicPath(mfOptions, base, _originalConfigBase);
|
|
8231
8771
|
},
|
|
8232
8772
|
/**
|
|
8773
|
+
* A standalone `vite build --ssr` may run with its own `filename`, e.g.
|
|
8774
|
+
* `defineConfig(({ isSsrBuild }) => ...)`. The manifest written by the
|
|
8775
|
+
* earlier client build then advertises an SSR entry derived from the
|
|
8776
|
+
* browser filename, which is not the file this build emitted. Point the
|
|
8777
|
+
* manifest and stats on disk at the emitted SSR entry.
|
|
8778
|
+
*/
|
|
8779
|
+
writeBundle(outputOptions) {
|
|
8780
|
+
if (!mfManifestName || _command !== "build" || isConsumerProject) return;
|
|
8781
|
+
const environment = this.environment;
|
|
8782
|
+
if (!(environment ? environment.name === "ssr" : Boolean(viteConfig?.build?.ssr))) return;
|
|
8783
|
+
const ssrEntryName = getSsrRemoteEntryFileName(mfOptions);
|
|
8784
|
+
const outDirs = [...new Set([outputOptions.dir, viteConfig?.environments?.client?.build?.outDir].filter((dir) => typeof dir === "string").map((dir) => path$1.resolve(root, dir)))];
|
|
8785
|
+
if (!outDirs.some((dir) => fs$1.existsSync(path$1.resolve(dir, ssrEntryName)))) return;
|
|
8786
|
+
for (const dir of outDirs) for (const fileName of [mfManifestName, mfManifestStatsName]) {
|
|
8787
|
+
if (!fileName) continue;
|
|
8788
|
+
const file = path$1.resolve(dir, fileName);
|
|
8789
|
+
if (!fs$1.existsSync(file)) continue;
|
|
8790
|
+
try {
|
|
8791
|
+
const data = JSON.parse(fs$1.readFileSync(file, "utf8"));
|
|
8792
|
+
const entry = data?.metaData?.ssrRemoteEntry;
|
|
8793
|
+
if (!entry || typeof entry !== "object" || entry.name === ssrEntryName) continue;
|
|
8794
|
+
entry.name = ssrEntryName;
|
|
8795
|
+
fs$1.writeFileSync(file, JSON.stringify(data));
|
|
8796
|
+
} catch {}
|
|
8797
|
+
}
|
|
8798
|
+
},
|
|
8799
|
+
/**
|
|
8233
8800
|
* Generates the module federation manifest file
|
|
8234
8801
|
* @param options - Rollup output options
|
|
8235
8802
|
* @param bundle - Generated bundle assets
|
|
@@ -8239,10 +8806,10 @@ const Manifest = (providedOptions) => {
|
|
|
8239
8806
|
if (this.environment?.name === "ssr") return;
|
|
8240
8807
|
let filesMap = {};
|
|
8241
8808
|
const foundRemoteEntryFile = findRemoteEntryFile(mfOptions.filename, bundle);
|
|
8242
|
-
const expectedSsrRemoteEntryFile = getSsrRemoteEntryFileName(mfOptions
|
|
8809
|
+
const expectedSsrRemoteEntryFile = getSsrRemoteEntryFileName(mfOptions);
|
|
8243
8810
|
const foundSsrRemoteEntryFile = Object.values(bundle).find((file) => file.fileName === expectedSsrRemoteEntryFile)?.fileName;
|
|
8244
8811
|
if (foundRemoteEntryFile) remoteEntryFile = foundRemoteEntryFile;
|
|
8245
|
-
ssrRemoteEntryFile = foundSsrRemoteEntryFile || (_command === "serve" ? getSsrRemoteEntryFileName(resolveHashPlaceholderFileName(mfOptions.filename)) : expectedSsrRemoteEntryFile);
|
|
8812
|
+
ssrRemoteEntryFile = foundSsrRemoteEntryFile || (_command === "serve" ? getSsrRemoteEntryFileName(mfOptions, resolveHashPlaceholderFileName(mfOptions.filename)) : expectedSsrRemoteEntryFile);
|
|
8246
8813
|
const allCssAssets = mfOptions.bundleAllCSS && !disableAssetsAnalyze ? collectCssAssets(bundle) : /* @__PURE__ */ new Set();
|
|
8247
8814
|
if (allCssAssets.size > 0) {
|
|
8248
8815
|
const secondaryCss = /* @__PURE__ */ new Set();
|
|
@@ -8319,7 +8886,7 @@ const Manifest = (providedOptions) => {
|
|
|
8319
8886
|
type: "module"
|
|
8320
8887
|
};
|
|
8321
8888
|
const ssrRemoteEntry = {
|
|
8322
|
-
name: ssrRemoteEntryFile || getSsrRemoteEntryFileName(_command === "serve" ? resolveHashPlaceholderFileName(filename) : filename),
|
|
8889
|
+
name: ssrRemoteEntryFile || getSsrRemoteEntryFileName(mfOptions, _command === "serve" ? resolveHashPlaceholderFileName(filename) : filename),
|
|
8323
8890
|
path: _command === "serve" ? "/__mf_ssr__/" : "",
|
|
8324
8891
|
type: "module"
|
|
8325
8892
|
};
|
|
@@ -8636,6 +9203,7 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
8636
9203
|
return cleanId.includes(getHostAutoInitPath(options)) || cleanId.includes(getHostAutoInitPath());
|
|
8637
9204
|
};
|
|
8638
9205
|
const getEnvironmentConditions = (context) => context.environment?.config?.resolve?.conditions;
|
|
9206
|
+
const isSsrBuild = (context) => isServerBuildContext(context, viteConfig);
|
|
8639
9207
|
function isRemoteImport(source) {
|
|
8640
9208
|
return Object.keys(options.remotes).some((name) => source === name || source.startsWith(name + "/"));
|
|
8641
9209
|
}
|
|
@@ -8739,7 +9307,7 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
8739
9307
|
}
|
|
8740
9308
|
},
|
|
8741
9309
|
async load(id) {
|
|
8742
|
-
if (id === remoteEntryId) return getParsePromise().then((_) => generateRemoteEntry(options, virtualExposesId, _command, getEnvironmentConditions(this)));
|
|
9310
|
+
if (id === remoteEntryId) return getParsePromise().then((_) => generateRemoteEntry(options, virtualExposesId, _command, getEnvironmentConditions(this), isSsrBuild(this)));
|
|
8743
9311
|
if (id === virtualExposesId) {
|
|
8744
9312
|
await refreshExposeRemoteDependencies(this);
|
|
8745
9313
|
return generateExposes(options, exposeRemoteDependencies, _command, reactIslandExposes);
|
|
@@ -8749,7 +9317,7 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
|
|
|
8749
9317
|
async transform(code, id) {
|
|
8750
9318
|
return mapCodeToCodeWithSourcemap(await (async () => {
|
|
8751
9319
|
if (!filterId(id)) return;
|
|
8752
|
-
if (id.includes(remoteEntryId)) return getParsePromise().then((_) => generateRemoteEntry(options, virtualExposesId, _command, getEnvironmentConditions(this)));
|
|
9320
|
+
if (id.includes(remoteEntryId)) return getParsePromise().then((_) => generateRemoteEntry(options, virtualExposesId, _command, getEnvironmentConditions(this), isSsrBuild(this)));
|
|
8753
9321
|
if (id === virtualExposesId) {
|
|
8754
9322
|
await refreshExposeRemoteDependencies(this);
|
|
8755
9323
|
return generateExposes(options, exposeRemoteDependencies, _command, reactIslandExposes);
|
|
@@ -8847,7 +9415,7 @@ function pluginProxyRemotes_default(options) {
|
|
|
8847
9415
|
const remoteModule = getRemoteVirtualModule(source, command, enableSsrInit, consumer, options);
|
|
8848
9416
|
addUsedRemote(remoteName, source, options);
|
|
8849
9417
|
refreshHostAutoInit(options);
|
|
8850
|
-
return remoteModule.
|
|
9418
|
+
return remoteModule.getResolvedId();
|
|
8851
9419
|
}
|
|
8852
9420
|
return {
|
|
8853
9421
|
name: "proxyRemotes",
|
|
@@ -8867,7 +9435,7 @@ function pluginProxyRemotes_default(options) {
|
|
|
8867
9435
|
},
|
|
8868
9436
|
configResolved(config) {
|
|
8869
9437
|
hasMultiEnvironment = Boolean(config.environments?.ssr);
|
|
8870
|
-
enableSsrInit = getSsrCapabilities(parseInt(version, 10), command, Object.keys(remotes).length > 0).enableSsrInitBootstrap;
|
|
9438
|
+
enableSsrInit = getSsrCapabilities(parseInt(version, 10), command, Object.keys(remotes).length > 0, isSsrConfig(config)).enableSsrInitBootstrap;
|
|
8871
9439
|
},
|
|
8872
9440
|
resolveId(source, importer) {
|
|
8873
9441
|
const resolvedIslandConsumerId = resolveReactIslandConsumerId(source);
|
|
@@ -8892,6 +9460,12 @@ function pluginProxyRemotes_default(options) {
|
|
|
8892
9460
|
}
|
|
8893
9461
|
//#endregion
|
|
8894
9462
|
//#region src/utils/sharedSource.ts
|
|
9463
|
+
const pendingEntryLookups = /* @__PURE__ */ new Map();
|
|
9464
|
+
const getEntryLookupKey = (source, importer) => `${source}\0${importer}`;
|
|
9465
|
+
/** Whether a resolveId call is one of the shared source resolver's own entry lookups. */
|
|
9466
|
+
function isSharedEntryLookup(source, importer, options) {
|
|
9467
|
+
return options.custom?.__mfSharedEntryLookup === true || pendingEntryLookups.has(getEntryLookupKey(source, importer));
|
|
9468
|
+
}
|
|
8895
9469
|
/** Identify shared entries through Vite, with a cache scoped to this federation instance. */
|
|
8896
9470
|
function createSharedSourceResolver(shared, getResolutionConfig) {
|
|
8897
9471
|
const caches = /* @__PURE__ */ new Map();
|
|
@@ -8902,9 +9476,10 @@ function createSharedSourceResolver(shared, getResolutionConfig) {
|
|
|
8902
9476
|
if (findSharedKey(packageName, shared)) candidates.add(packageName);
|
|
8903
9477
|
if (findSharedKey(suffix, shared)) candidates.add(suffix);
|
|
8904
9478
|
for (const key of Object.keys(shared)) {
|
|
8905
|
-
|
|
8906
|
-
if (
|
|
8907
|
-
|
|
9479
|
+
const request = getSharedRequest(key, shared[key]);
|
|
9480
|
+
if (getPackageName(request) !== packageName) continue;
|
|
9481
|
+
if (!request.endsWith("/")) candidates.add(request);
|
|
9482
|
+
for (const subpath of getCommonSharedSubpaths(request)) if (findSharedKey(subpath, shared)) candidates.add(subpath);
|
|
8908
9483
|
}
|
|
8909
9484
|
if (candidates.size === 0) return;
|
|
8910
9485
|
const resolvedSource = await resolveEntry(source);
|
|
@@ -8912,7 +9487,8 @@ function createSharedSourceResolver(shared, getResolutionConfig) {
|
|
|
8912
9487
|
for (const candidate of candidates) {
|
|
8913
9488
|
const entry = await resolveEntry(candidate);
|
|
8914
9489
|
if (!entry) continue;
|
|
8915
|
-
|
|
9490
|
+
const allowNodeModulesSuffixMatch = shared[findSharedKey(candidate, shared) ?? candidate]?.shareConfig?.allowNodeModulesSuffixMatch === true;
|
|
9491
|
+
if (normalizeNodeModulePath(entry) === normalizeNodeModulePath(resolvedSource) || allowNodeModulesSuffixMatch && getNodeModulesSuffix(entry) === suffix) return candidate;
|
|
8916
9492
|
}
|
|
8917
9493
|
}
|
|
8918
9494
|
return {
|
|
@@ -8946,8 +9522,11 @@ function createSharedSourceResolver(shared, getResolutionConfig) {
|
|
|
8946
9522
|
cwd: root,
|
|
8947
9523
|
conditions
|
|
8948
9524
|
})) return void 0;
|
|
9525
|
+
const importer = path$1.join(root, "package.json");
|
|
9526
|
+
const lookupKey = getEntryLookupKey(request, importer);
|
|
9527
|
+
pendingEntryLookups.set(lookupKey, (pendingEntryLookups.get(lookupKey) ?? 0) + 1);
|
|
8949
9528
|
try {
|
|
8950
|
-
const resolved = await context.resolve(request,
|
|
9529
|
+
const resolved = await context.resolve(request, importer, {
|
|
8951
9530
|
...options,
|
|
8952
9531
|
skipSelf: true,
|
|
8953
9532
|
custom: {
|
|
@@ -8958,6 +9537,10 @@ function createSharedSourceResolver(shared, getResolutionConfig) {
|
|
|
8958
9537
|
return resolved && !resolved.external ? resolved.id : void 0;
|
|
8959
9538
|
} catch {
|
|
8960
9539
|
return;
|
|
9540
|
+
} finally {
|
|
9541
|
+
const remaining = pendingEntryLookups.get(lookupKey) - 1;
|
|
9542
|
+
if (remaining) pendingEntryLookups.set(lookupKey, remaining);
|
|
9543
|
+
else pendingEntryLookups.delete(lookupKey);
|
|
8961
9544
|
}
|
|
8962
9545
|
});
|
|
8963
9546
|
cache?.set(normalizedSource, result);
|
|
@@ -9006,7 +9589,7 @@ function tryResolveFromProjectRoot(source) {
|
|
|
9006
9589
|
const browserEntry = getInstalledPackageEntry(source, { cwd: getPackageDetectionCwd() });
|
|
9007
9590
|
if (browserEntry) return browserEntry;
|
|
9008
9591
|
try {
|
|
9009
|
-
return
|
|
9592
|
+
return resolveModulePath(source, path$1.join(getPackageDetectionCwd(), "package.json"));
|
|
9010
9593
|
} catch {
|
|
9011
9594
|
return;
|
|
9012
9595
|
}
|
|
@@ -9032,9 +9615,13 @@ function getPackageDependencies(pkg) {
|
|
|
9032
9615
|
*/
|
|
9033
9616
|
function excludeSharedSubDependencies(shared) {
|
|
9034
9617
|
const sharedKeys = new Set(Object.keys(shared));
|
|
9035
|
-
const
|
|
9618
|
+
const requestBase = (key) => {
|
|
9619
|
+
const request = getSharedRequest(key, shared[key]);
|
|
9620
|
+
return request.endsWith("/") ? request.slice(0, -1) : request;
|
|
9621
|
+
};
|
|
9622
|
+
const sharedKeyByBase = new Map(Object.keys(shared).map((key) => [requestBase(key), key]));
|
|
9036
9623
|
for (const parentKey of sharedKeys) {
|
|
9037
|
-
const deps = getPackageDependencies(parentKey);
|
|
9624
|
+
const deps = getPackageDependencies(requestBase(parentKey));
|
|
9038
9625
|
for (const dep of deps) {
|
|
9039
9626
|
const depKey = sharedKeyByBase.get(dep);
|
|
9040
9627
|
if (depKey && depKey !== parentKey) {
|
|
@@ -9361,6 +9948,7 @@ function isSharedPackageRuntimeDependency(sharedKey, dependency, conditions) {
|
|
|
9361
9948
|
function proxySharedModule(options) {
|
|
9362
9949
|
const { shared = {}, federationOptions, getParsePromise = () => Promise.resolve() } = options;
|
|
9363
9950
|
let _config;
|
|
9951
|
+
const getBuildImportAnalysis = (environment) => getImportAnalysis(environment ?? _config ?? options);
|
|
9364
9952
|
let _command = "serve";
|
|
9365
9953
|
let useDirectReactImport = false;
|
|
9366
9954
|
let useRolldown = false;
|
|
@@ -9378,7 +9966,7 @@ function proxySharedModule(options) {
|
|
|
9378
9966
|
const getRuntimeDependencyConditions = (context, resolveOptions) => {
|
|
9379
9967
|
const environment = context.environment;
|
|
9380
9968
|
const environmentConfig = environment?.config;
|
|
9381
|
-
const isSsr = resolveOptions.ssr === true || Boolean(_config?.build?.ssr) ||
|
|
9969
|
+
const isSsr = resolveOptions.ssr === true || Boolean(_config?.build?.ssr) || isServerEnvironment(environment?.name, environmentConfig);
|
|
9382
9970
|
return getSharedExportConditions({
|
|
9383
9971
|
environmentConditions: environmentConfig?.resolve?.conditions,
|
|
9384
9972
|
isProduction: environmentConfig?.isProduction ?? isProduction,
|
|
@@ -9434,12 +10022,13 @@ function proxySharedModule(options) {
|
|
|
9434
10022
|
}, federationOptions);
|
|
9435
10023
|
},
|
|
9436
10024
|
resolveId(source) {
|
|
9437
|
-
|
|
10025
|
+
const resolvedId = getResolvedLocalSharedImportMapId(federationOptions);
|
|
10026
|
+
if (source === getLocalSharedImportMapPath(federationOptions) || source === resolvedId) return resolvedId;
|
|
9438
10027
|
},
|
|
9439
10028
|
load(id) {
|
|
9440
10029
|
if (id === getResolvedLocalSharedImportMapId(federationOptions)) return getParsePromise().then((_) => {
|
|
9441
10030
|
refreshTreeShakingForEnvironment(this);
|
|
9442
|
-
const providerPackages = /* @__PURE__ */ new Set([...Object.keys(shared).filter((pkg) => !pkg.endsWith("/")), ...getUsedShares(federationOptions)]);
|
|
10031
|
+
const providerPackages = /* @__PURE__ */ new Set([...Object.keys(shared).filter((pkg) => !getSharedRequest(pkg, shared[pkg]).endsWith("/")), ...getUsedShares(federationOptions)]);
|
|
9443
10032
|
for (const pkg of providerPackages) {
|
|
9444
10033
|
const sharedKey = findSharedKey(pkg, shared);
|
|
9445
10034
|
const shareItem = shared[pkg] || (sharedKey ? shared[sharedKey] : void 0);
|
|
@@ -9484,14 +10073,15 @@ function proxySharedModule(options) {
|
|
|
9484
10073
|
const resolvedOptions = federationOptions ?? getNormalizeModuleFederationOptions();
|
|
9485
10074
|
const registerConfiguredShare = _command === "build" && Object.keys(resolvedOptions.exposes).length > 0 ? addUsedShares : addConfiguredShare;
|
|
9486
10075
|
Object.keys(shared).forEach((key) => {
|
|
9487
|
-
if (key.endsWith("/")) return;
|
|
9488
|
-
|
|
9489
|
-
|
|
10076
|
+
if (key.endsWith("/") || getSharedRequest(key, shared[key]).endsWith("/")) return;
|
|
10077
|
+
const runtimeKey = getSharedRuntimeKey(key, shared[key]);
|
|
10078
|
+
if (useDirectReactImport && runtimeKey === "react") {
|
|
10079
|
+
registerConfiguredShare(runtimeKey, federationOptions);
|
|
9490
10080
|
return;
|
|
9491
10081
|
}
|
|
9492
|
-
writeLoadShareModule(
|
|
9493
|
-
if (shared[key].shareConfig.import !== false) writePreBuildLibPath(
|
|
9494
|
-
registerConfiguredShare(
|
|
10082
|
+
writeLoadShareModule(runtimeKey, shared[key], _command, isRolldown, federationOptions);
|
|
10083
|
+
if (shared[key].shareConfig.import !== false) writePreBuildLibPath(runtimeKey, shared[key], federationOptions);
|
|
10084
|
+
registerConfiguredShare(runtimeKey, federationOptions);
|
|
9495
10085
|
});
|
|
9496
10086
|
writeLocalSharedImportMap(federationOptions);
|
|
9497
10087
|
refreshHostAutoInit(federationOptions);
|
|
@@ -9502,10 +10092,14 @@ function proxySharedModule(options) {
|
|
|
9502
10092
|
buildStart() {
|
|
9503
10093
|
sharedSourceResolver.clear();
|
|
9504
10094
|
if (_command !== "build") return;
|
|
10095
|
+
if (hasAnalyzableShares) getBuildImportAnalysis(this.environment).clear();
|
|
9505
10096
|
resetTreeShakingExports(federationOptions);
|
|
9506
10097
|
emittedTreeShakingProviders.clear();
|
|
9507
10098
|
refreshTreeShakingForEnvironment(this);
|
|
9508
10099
|
},
|
|
10100
|
+
buildEnd() {
|
|
10101
|
+
if (_command === "build" && hasAnalyzableShares) getBuildImportAnalysis(this.environment).clear();
|
|
10102
|
+
},
|
|
9509
10103
|
shouldTransformCachedModule() {
|
|
9510
10104
|
return _command === "build" && hasAnalyzableShares;
|
|
9511
10105
|
},
|
|
@@ -9514,7 +10108,7 @@ function proxySharedModule(options) {
|
|
|
9514
10108
|
await collectTreeShakingImports(code, id, shared, async (source, shares) => {
|
|
9515
10109
|
const request = await sharedSourceResolver.resolve(this, source, transformOptions);
|
|
9516
10110
|
return request ? findSharedKey(request, shares) : void 0;
|
|
9517
|
-
}, (sharedKey, exports, request) => recordTreeShakingExports(sharedKey, exports, request, federationOptions), (sharedKey, request) => markTreeShakingPackageUnsafe(sharedKey, request, federationOptions));
|
|
10111
|
+
}, (sharedKey, exports, request) => recordTreeShakingExports(sharedKey, exports, request, federationOptions), (sharedKey, request) => markTreeShakingPackageUnsafe(sharedKey, request, federationOptions), getBuildImportAnalysis(this.environment));
|
|
9518
10112
|
refreshTreeShakingForEnvironment(this);
|
|
9519
10113
|
}
|
|
9520
10114
|
},
|
|
@@ -9523,7 +10117,7 @@ function proxySharedModule(options) {
|
|
|
9523
10117
|
enforce: "pre",
|
|
9524
10118
|
apply: "build",
|
|
9525
10119
|
async resolveId(source, importer, resolveOptions) {
|
|
9526
|
-
if (resolveOptions
|
|
10120
|
+
if (isSharedEntryLookup(source, importer, resolveOptions)) return;
|
|
9527
10121
|
const sourceToken = getTreeShakingGraphToken(source);
|
|
9528
10122
|
const importerToken = getTreeShakingGraphToken(importer);
|
|
9529
10123
|
const token = sourceToken || importerToken;
|
|
@@ -9559,7 +10153,7 @@ function proxySharedModule(options) {
|
|
|
9559
10153
|
name: "proxyPreBuildShared:resolve-shared-loadShare",
|
|
9560
10154
|
enforce: "pre",
|
|
9561
10155
|
async resolveId(source, importer, resolveOptions) {
|
|
9562
|
-
if (resolveOptions
|
|
10156
|
+
if (isSharedEntryLookup(source, importer, resolveOptions) || resolveOptions.custom?.__mfTreeShakingGraph) return;
|
|
9563
10157
|
const sharedSource = await sharedSourceResolver.resolve(this, source, resolveOptions);
|
|
9564
10158
|
if (!sharedSource) return;
|
|
9565
10159
|
const key = findSharedKey(sharedSource, shared);
|
|
@@ -9574,8 +10168,9 @@ function proxySharedModule(options) {
|
|
|
9574
10168
|
if (importerPackage === getPackageName(key)) return;
|
|
9575
10169
|
if (importerPackage && shared[key].shareConfig.import !== false) {
|
|
9576
10170
|
const importerIsUnsharedWorkspacePackage = !isNodeModulePath(importer) && !Object.keys(shared).some((sharedKey) => getPackageName(sharedKey) === importerPackage);
|
|
9577
|
-
const
|
|
9578
|
-
|
|
10171
|
+
const request = getSharedRequest(key, shared[key]);
|
|
10172
|
+
const runtimeDependencyRequest = request.endsWith("/") && matchesSharedSource(sharedSource, key, shared[key]) ? sharedSource : request;
|
|
10173
|
+
if (importerIsUnsharedWorkspacePackage ? isSharedPackageRuntimeDependency(runtimeDependencyRequest, importerPackage, getRuntimeDependencyConditions(this, resolveOptions)) : isSharedPackageDependency(request, importerPackage)) return;
|
|
9579
10174
|
}
|
|
9580
10175
|
if (useDirectReactImport && key === "react") return;
|
|
9581
10176
|
if (isAssetLikeImport(source)) return;
|
|
@@ -9876,17 +10471,21 @@ function collectFromRegex(code, isRemoteImport) {
|
|
|
9876
10471
|
}
|
|
9877
10472
|
function pluginRemoteNamedExports(options) {
|
|
9878
10473
|
const remoteNames = Object.keys(options.remotes);
|
|
10474
|
+
let root = process.cwd();
|
|
9879
10475
|
const isNodeModulesId = (id) => id.includes("/node_modules/") || id.includes("\\node_modules\\");
|
|
9880
10476
|
function isRemoteImport(source, importerId) {
|
|
9881
10477
|
return remoteNames.some((name) => {
|
|
9882
10478
|
if (source.startsWith(name + "/")) return true;
|
|
9883
10479
|
if (source !== name) return false;
|
|
9884
|
-
return !isNodeModulesId(importerId);
|
|
10480
|
+
return !isNodeModulesId(importerId) || !getInstalledPackageEntry(source, { cwd: root });
|
|
9885
10481
|
}) || source.includes("__loadRemote__");
|
|
9886
10482
|
}
|
|
9887
10483
|
return {
|
|
9888
10484
|
name: "module-federation-remote-named-exports",
|
|
9889
10485
|
enforce: "post",
|
|
10486
|
+
configResolved(config) {
|
|
10487
|
+
root = config.root || process.cwd();
|
|
10488
|
+
},
|
|
9890
10489
|
async transform(code, id) {
|
|
9891
10490
|
if (remoteNames.length === 0) return;
|
|
9892
10491
|
if (id.includes("__loadRemote__") || id.includes("__loadShare__")) return;
|
|
@@ -10038,18 +10637,25 @@ function pluginSSRRemoteEntry(options) {
|
|
|
10038
10637
|
const remoteEntrySSRId = getRemoteEntrySSRId(options);
|
|
10039
10638
|
const virtualExposesSSRId = getVirtualExposesSSRId(options);
|
|
10040
10639
|
let cachedSsrRemoteEntrySource;
|
|
10041
|
-
const ssrOutputFilename = getSsrRemoteEntryFileName(options
|
|
10640
|
+
const ssrOutputFilename = getSsrRemoteEntryFileName(options);
|
|
10042
10641
|
const ssrExposesFileName = getSsrExposesFileName(options.filename);
|
|
10043
10642
|
let ssrOutputFiles = /* @__PURE__ */ new Set();
|
|
10044
10643
|
let ssrOutputDir = "";
|
|
10045
10644
|
let clientOutputDir = "";
|
|
10046
|
-
const
|
|
10645
|
+
const mfRuntimePackages = [
|
|
10047
10646
|
"@module-federation/runtime",
|
|
10048
10647
|
"@module-federation/runtime-core",
|
|
10049
|
-
"@module-federation/sdk"
|
|
10050
|
-
...options.ssrExternals ?? []
|
|
10648
|
+
"@module-federation/sdk"
|
|
10051
10649
|
];
|
|
10650
|
+
const ssrOnlyExternals = [...mfRuntimePackages, ...options.ssrExternals ?? []];
|
|
10052
10651
|
const ssrOnlyExternalPattern = new RegExp(`^(${ssrOnlyExternals.map((e) => e.replace(/[/\\^$*+?.()|[\]{}]/g, "\\$&")).join("|")})(\\/.*)?$`);
|
|
10652
|
+
let noExternal;
|
|
10653
|
+
const isNoExternal = (id) => {
|
|
10654
|
+
const pkg = ssrOnlyExternalPattern.exec(id)?.[1] ?? id;
|
|
10655
|
+
if (!noExternal || !mfRuntimePackages.includes(pkg)) return false;
|
|
10656
|
+
if (noExternal === true) return true;
|
|
10657
|
+
return (Array.isArray(noExternal) ? noExternal : [noExternal]).some((rule) => typeof rule === "string" ? rule === pkg : rule.test(pkg));
|
|
10658
|
+
};
|
|
10053
10659
|
const ssrModuleIds = /* @__PURE__ */ new Set([remoteEntrySSRId, virtualExposesSSRId]);
|
|
10054
10660
|
const resolvedAbsToPackage = /* @__PURE__ */ new Map();
|
|
10055
10661
|
let isServe = false;
|
|
@@ -10080,7 +10686,9 @@ function pluginSSRRemoteEntry(options) {
|
|
|
10080
10686
|
enforce: "pre",
|
|
10081
10687
|
configResolved(config) {
|
|
10082
10688
|
isServe = config.command === "serve";
|
|
10689
|
+
noExternal = config.environments?.ssr?.resolve?.noExternal ?? config.ssr?.noExternal;
|
|
10083
10690
|
for (const pkg of ssrOnlyExternals) {
|
|
10691
|
+
if (isNoExternal(pkg)) continue;
|
|
10084
10692
|
const aliasEntry = (config.resolve?.alias)?.find((a) => a.find === pkg || a.find instanceof RegExp && a.find.test(pkg));
|
|
10085
10693
|
if (aliasEntry?.replacement) resolvedAbsToPackage.set(aliasEntry.replacement, pkg);
|
|
10086
10694
|
}
|
|
@@ -10089,7 +10697,7 @@ function pluginSSRRemoteEntry(options) {
|
|
|
10089
10697
|
if (id === remoteEntrySSRId || id.startsWith(remoteEntrySSRId)) return id;
|
|
10090
10698
|
if (id === virtualExposesSSRId || id.startsWith(virtualExposesSSRId)) return id;
|
|
10091
10699
|
if (!importer || !ssrModuleIds.has(importer)) return;
|
|
10092
|
-
if (ssrOnlyExternalPattern.test(id)) return {
|
|
10700
|
+
if (ssrOnlyExternalPattern.test(id) && !isNoExternal(id)) return {
|
|
10093
10701
|
id,
|
|
10094
10702
|
external: true
|
|
10095
10703
|
};
|
|
@@ -10114,7 +10722,7 @@ function pluginSSRRemoteEntry(options) {
|
|
|
10114
10722
|
configureServer(server) {
|
|
10115
10723
|
const base = "/__mf_ssr__";
|
|
10116
10724
|
const basePath = getBasePath$1(viteConfig?.base);
|
|
10117
|
-
const ssrEntryFileName = getSsrRemoteEntryFileName(options
|
|
10725
|
+
const ssrEntryFileName = getSsrRemoteEntryFileName(options);
|
|
10118
10726
|
if (isNuxtProject || isNuxtClientBase(basePath)) server.middlewares.use((req, _res, next) => {
|
|
10119
10727
|
if (req.url?.replace(/\?.*/, "") === `${basePath}/${ssrEntryFileName}`) req.url = `${basePath}/__mf_ssr__/${ssrEntryFileName}`;
|
|
10120
10728
|
next();
|
|
@@ -10183,7 +10791,7 @@ function pluginSSRRemoteEntry(options) {
|
|
|
10183
10791
|
resolveId(id) {
|
|
10184
10792
|
if (id === remoteEntrySSRId || id.startsWith(remoteEntrySSRId)) return id;
|
|
10185
10793
|
if (id === virtualExposesSSRId || id.startsWith(virtualExposesSSRId)) return id;
|
|
10186
|
-
if (id === `/__mf_ssr__/${getSsrRemoteEntryFileName(options
|
|
10794
|
+
if (id === `/__mf_ssr__/${getSsrRemoteEntryFileName(options)}`) return remoteEntrySSRId;
|
|
10187
10795
|
if (id === `/__mf_ssr__/${ssrExposesFileName}`) return virtualExposesSSRId;
|
|
10188
10796
|
},
|
|
10189
10797
|
load(id) {
|
|
@@ -10388,6 +10996,85 @@ var aliasToArrayPlugin_default = {
|
|
|
10388
10996
|
}
|
|
10389
10997
|
};
|
|
10390
10998
|
//#endregion
|
|
10999
|
+
//#region src/utils/deferredPrebuildHelper.ts
|
|
11000
|
+
function isExportAllHelper(code, exportName) {
|
|
11001
|
+
try {
|
|
11002
|
+
const ast = parseAst(code);
|
|
11003
|
+
let localName;
|
|
11004
|
+
for (const node of ast.body) {
|
|
11005
|
+
if (node.type !== "ExportNamedDeclaration") continue;
|
|
11006
|
+
for (const specifier of node.specifiers) if (specifier.type === "ExportSpecifier" && specifier.exported.type === "Identifier" && specifier.exported.name === exportName && specifier.local.type === "Identifier") localName = specifier.local.name;
|
|
11007
|
+
}
|
|
11008
|
+
if (!localName) return false;
|
|
11009
|
+
for (const node of ast.body) {
|
|
11010
|
+
if (node.type !== "VariableDeclaration") continue;
|
|
11011
|
+
for (const declaration of node.declarations) {
|
|
11012
|
+
if (declaration.id.type !== "Identifier" || declaration.id.name !== localName) continue;
|
|
11013
|
+
const initializer = declaration.init;
|
|
11014
|
+
if (!initializer) return false;
|
|
11015
|
+
const source = code.slice(initializer.start, initializer.end);
|
|
11016
|
+
return source.includes("Symbol.toStringTag") && source.includes("Module");
|
|
11017
|
+
}
|
|
11018
|
+
}
|
|
11019
|
+
} catch {}
|
|
11020
|
+
return false;
|
|
11021
|
+
}
|
|
11022
|
+
/**
|
|
11023
|
+
* Rolldown sometimes places its shared namespace helper in a local prebuild
|
|
11024
|
+
* chunk. A loadShare wrapper then imports that helper statically, evaluating the
|
|
11025
|
+
* fallback even when a host provider is already in the cache. Inline only the
|
|
11026
|
+
* recognized Rolldown helper; leave every other prebuild import untouched.
|
|
11027
|
+
*/
|
|
11028
|
+
function inlineDeferredPrebuildNamespaceHelper(bundle) {
|
|
11029
|
+
for (const chunk of Object.values(bundle)) {
|
|
11030
|
+
if (chunk.type !== "chunk" || !chunk.fileName.includes("__loadShare__")) continue;
|
|
11031
|
+
let ast;
|
|
11032
|
+
try {
|
|
11033
|
+
ast = parseAst(chunk.code);
|
|
11034
|
+
} catch {
|
|
11035
|
+
continue;
|
|
11036
|
+
}
|
|
11037
|
+
const edits = [];
|
|
11038
|
+
const deferredSources = /* @__PURE__ */ new Set();
|
|
11039
|
+
forEachAstNode(ast, (node) => {
|
|
11040
|
+
if (node.type !== "ImportExpression") return;
|
|
11041
|
+
const source = getModuleSource(node.source);
|
|
11042
|
+
if (source) deferredSources.add(source);
|
|
11043
|
+
});
|
|
11044
|
+
const retainedImports = /* @__PURE__ */ new Set();
|
|
11045
|
+
const removedImports = /* @__PURE__ */ new Set();
|
|
11046
|
+
for (const node of ast.body) {
|
|
11047
|
+
if (node.type !== "ImportDeclaration") continue;
|
|
11048
|
+
const source = getModuleSource(node.source);
|
|
11049
|
+
if (!source) continue;
|
|
11050
|
+
const targetName = path.posix.normalize(path.posix.join(path.posix.dirname(chunk.fileName), source));
|
|
11051
|
+
const [specifier] = node.specifiers;
|
|
11052
|
+
const exported = specifier?.type === "ImportSpecifier" && specifier.imported;
|
|
11053
|
+
const target = bundle[targetName];
|
|
11054
|
+
if (!source.includes("__prebuild__") || node.specifiers.length !== 1 || !exported || exported.type !== "Identifier" || target?.type !== "chunk" || !deferredSources.has(source) || !Object.keys(target.modules ?? {}).some((id) => id.includes("rolldown/runtime.js")) || !isExportAllHelper(target.code, exported.name)) {
|
|
11055
|
+
retainedImports.add(targetName);
|
|
11056
|
+
continue;
|
|
11057
|
+
}
|
|
11058
|
+
removedImports.add(targetName);
|
|
11059
|
+
edits.push({
|
|
11060
|
+
start: node.start,
|
|
11061
|
+
end: node.end,
|
|
11062
|
+
replacement: `const ${specifier.local.name} = (all, noSymbols) => {
|
|
11063
|
+
const namespace = {};
|
|
11064
|
+
for (const name in all) Object.defineProperty(namespace, name, {
|
|
11065
|
+
get: all[name], enumerable: true,
|
|
11066
|
+
});
|
|
11067
|
+
if (!noSymbols) Object.defineProperty(namespace, Symbol.toStringTag, { value: 'Module' });
|
|
11068
|
+
return namespace;
|
|
11069
|
+
};`
|
|
11070
|
+
});
|
|
11071
|
+
}
|
|
11072
|
+
if (edits.length === 0) continue;
|
|
11073
|
+
for (const edit of edits.reverse()) chunk.code = chunk.code.slice(0, edit.start) + edit.replacement + chunk.code.slice(edit.end);
|
|
11074
|
+
if (chunk.imports) chunk.imports = chunk.imports.filter((imported) => !removedImports.has(imported) || retainedImports.has(imported));
|
|
11075
|
+
}
|
|
11076
|
+
}
|
|
11077
|
+
//#endregion
|
|
10391
11078
|
//#region src/utils/controlChunkSanitizer.ts
|
|
10392
11079
|
const FEDERATION_CONTROL_CHUNK_HINTS = ["hostInit", "localSharedImportMap"];
|
|
10393
11080
|
function stripEmptyPreloadCalls(code) {
|
|
@@ -10605,7 +11292,7 @@ function isFederationHtmlPreloadDependency(dep, includeSharedRuntime = false) {
|
|
|
10605
11292
|
}
|
|
10606
11293
|
function canResolveSharedSubpath(subpath, projectRoot) {
|
|
10607
11294
|
try {
|
|
10608
|
-
return isViteOptimizableEntry(
|
|
11295
|
+
return isViteOptimizableEntry(resolveModulePath(subpath, path$1.join(projectRoot, "package.json")));
|
|
10609
11296
|
} catch (error) {
|
|
10610
11297
|
if (error?.code === "ERR_PACKAGE_PATH_NOT_EXPORTED" && !isBarePackageSubpath(subpath)) {
|
|
10611
11298
|
const entry = resolveViteImportPackageEntry(subpath, projectRoot);
|
|
@@ -10843,11 +11530,21 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
10843
11530
|
config.optimizeDeps = config.optimizeDeps || {};
|
|
10844
11531
|
config.optimizeDeps.include = config.optimizeDeps.include || [];
|
|
10845
11532
|
const optimizeDeps = config.optimizeDeps;
|
|
11533
|
+
const preparedShares = /* @__PURE__ */ new Map();
|
|
11534
|
+
const writeSharedModules = (source, shareItem) => {
|
|
11535
|
+
if (preparedShares.get(source) === shareItem) return;
|
|
11536
|
+
writeLoadShareModule(source, shareItem, _command, isRolldown, options);
|
|
11537
|
+
if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(source, shareItem, options);
|
|
11538
|
+
preparedShares.set(source, shareItem);
|
|
11539
|
+
};
|
|
10846
11540
|
if (isRolldown) {
|
|
10847
11541
|
optimizeDeps.rolldownOptions ??= {};
|
|
10848
11542
|
optimizeDeps.rolldownOptions.plugins ??= [];
|
|
10849
11543
|
optimizeDeps.rolldownOptions.plugins.push({
|
|
10850
11544
|
name: "module-federation:optimize-shared-resolver",
|
|
11545
|
+
buildStart() {
|
|
11546
|
+
preparedShares.clear();
|
|
11547
|
+
},
|
|
10851
11548
|
load(id) {
|
|
10852
11549
|
if (!id.startsWith("module-federation:optimized-require-")) return;
|
|
10853
11550
|
const sourcePackage = id.slice(36);
|
|
@@ -10875,13 +11572,11 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
10875
11572
|
if (isCommonJsImporter(importer) && !isReactSingleton && !isReactDomRequire) return;
|
|
10876
11573
|
if (resolveOptions?.kind !== "entry-point") addUsedShares(source, options);
|
|
10877
11574
|
if (isReactRequire || isReactDomRequire) {
|
|
10878
|
-
|
|
10879
|
-
if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(source, shareItem, options);
|
|
11575
|
+
writeSharedModules(source, shareItem);
|
|
10880
11576
|
return { id: `module-federation:optimized-require-${source}` };
|
|
10881
11577
|
}
|
|
10882
11578
|
const loadSharePath = getLoadShareModulePath(source, isRolldown, options);
|
|
10883
|
-
|
|
10884
|
-
if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(source, shareItem, options);
|
|
11579
|
+
writeSharedModules(source, shareItem);
|
|
10885
11580
|
return {
|
|
10886
11581
|
id: loadSharePath,
|
|
10887
11582
|
external: true
|
|
@@ -10894,6 +11589,9 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
10894
11589
|
optimizeDeps.esbuildOptions.plugins.push({
|
|
10895
11590
|
name: "module-federation:optimize-shared-proxy",
|
|
10896
11591
|
setup(build) {
|
|
11592
|
+
build.onStart(() => {
|
|
11593
|
+
preparedShares.clear();
|
|
11594
|
+
});
|
|
10897
11595
|
build.onResolve({ filter: createViteEncodedIdPrefixRegExp("virtual:mf:") }, (args) => ({
|
|
10898
11596
|
path: args.path,
|
|
10899
11597
|
external: true
|
|
@@ -10911,8 +11609,7 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
10911
11609
|
if (args.kind === "import-statement" || args.kind === "dynamic-import") {
|
|
10912
11610
|
const shareItem = shared[key];
|
|
10913
11611
|
const loadSharePath = getLoadShareModulePath(args.path, isRolldown, options);
|
|
10914
|
-
|
|
10915
|
-
if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(args.path, shareItem, options);
|
|
11612
|
+
writeSharedModules(args.path, shareItem);
|
|
10916
11613
|
return {
|
|
10917
11614
|
path: loadSharePath,
|
|
10918
11615
|
external: true
|
|
@@ -10931,8 +11628,7 @@ function createEarlyVirtualModulesPlugin(options) {
|
|
|
10931
11628
|
if (!key) return;
|
|
10932
11629
|
const shareItem = shared[key];
|
|
10933
11630
|
const loadSharePath = getLoadShareModulePath(args.path, isRolldown, options);
|
|
10934
|
-
|
|
10935
|
-
if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(args.path, shareItem, options);
|
|
11631
|
+
writeSharedModules(args.path, shareItem);
|
|
10936
11632
|
return {
|
|
10937
11633
|
loader: "js",
|
|
10938
11634
|
resolveDir: root,
|
|
@@ -10947,12 +11643,14 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
10947
11643
|
}
|
|
10948
11644
|
for (const key of Object.keys(shared)) {
|
|
10949
11645
|
const shareItem = shared[key];
|
|
10950
|
-
|
|
11646
|
+
const request = getSharedRequest(key, shareItem);
|
|
11647
|
+
const runtimeKey = getSharedRuntimeKey(key, shareItem);
|
|
11648
|
+
if (key.endsWith("/") || request.endsWith("/") || runtimeKey.endsWith("/")) {
|
|
10951
11649
|
if (_command === "serve" && shareItem.shareConfig?.import !== false) {
|
|
10952
11650
|
const optimizeDeps = config.optimizeDeps ??= {};
|
|
10953
11651
|
optimizeDeps.include ??= [];
|
|
10954
11652
|
optimizeDeps.exclude ??= [];
|
|
10955
|
-
for (const subpath of getCommonSharedSubpaths(
|
|
11653
|
+
for (const subpath of getCommonSharedSubpaths(request)) {
|
|
10956
11654
|
writePreBuildLibPath(subpath, shareItem, options);
|
|
10957
11655
|
if (canResolveSharedSubpath(subpath, root)) optimizeDeps.include.push(subpath);
|
|
10958
11656
|
else optimizeDeps.exclude.push(subpath);
|
|
@@ -10960,23 +11658,24 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
10960
11658
|
}
|
|
10961
11659
|
continue;
|
|
10962
11660
|
}
|
|
10963
|
-
if (isVinext &&
|
|
10964
|
-
addConfiguredShare(
|
|
11661
|
+
if (isVinext && runtimeKey === "react") {
|
|
11662
|
+
addConfiguredShare(runtimeKey, options);
|
|
10965
11663
|
continue;
|
|
10966
11664
|
}
|
|
10967
|
-
getLoadShareModulePath(
|
|
10968
|
-
writeLoadShareModule(
|
|
10969
|
-
if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(
|
|
10970
|
-
addConfiguredShare(
|
|
11665
|
+
getLoadShareModulePath(runtimeKey, isRolldown, options);
|
|
11666
|
+
writeLoadShareModule(runtimeKey, shareItem, _command, isRolldown, options);
|
|
11667
|
+
if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(runtimeKey, shareItem, options);
|
|
11668
|
+
addConfiguredShare(runtimeKey, options);
|
|
10971
11669
|
if (_command === "serve" && shareItem.shareConfig?.import !== false) {
|
|
10972
11670
|
const optimizeDeps = config.optimizeDeps ??= {};
|
|
10973
11671
|
optimizeDeps.include ??= [];
|
|
10974
11672
|
optimizeDeps.exclude ??= [];
|
|
10975
|
-
const shouldBypassOptimizeDep = isLitShare(
|
|
10976
|
-
if (optimizeDeps.include.includes(
|
|
10977
|
-
else if (shouldBypassOptimizeDep || optimizeDeps.exclude.includes(
|
|
10978
|
-
else optimizeDeps.include.push(
|
|
10979
|
-
|
|
11673
|
+
const shouldBypassOptimizeDep = isLitShare(runtimeKey) || !canResolveSharedSubpath(runtimeKey, root);
|
|
11674
|
+
if (optimizeDeps.include.includes(runtimeKey)) optimizeDeps.exclude = optimizeDeps.exclude.filter((dep) => dep !== runtimeKey);
|
|
11675
|
+
else if (shouldBypassOptimizeDep || optimizeDeps.exclude.includes(runtimeKey)) optimizeDeps.exclude.push(runtimeKey);
|
|
11676
|
+
else optimizeDeps.include.push(runtimeKey);
|
|
11677
|
+
const commonSubpaths = shareItem.shareConfig.request === void 0 && shareItem.shareConfig.shareKey === void 0 ? getCommonSharedSubpaths(runtimeKey) : [];
|
|
11678
|
+
for (const subpath of commonSubpaths) {
|
|
10980
11679
|
const canResolveSubpath = canResolveSharedSubpath(subpath, root);
|
|
10981
11680
|
if ([
|
|
10982
11681
|
"react/compiler-runtime",
|
|
@@ -10992,7 +11691,7 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
10992
11691
|
addConfiguredShare(subpath, options);
|
|
10993
11692
|
if (canResolveSubpath) {
|
|
10994
11693
|
optimizeDeps.include.push(subpath);
|
|
10995
|
-
if (
|
|
11694
|
+
if (runtimeKey === "react-dom") optimizeDeps.include.push(`${runtimeKey} > ${subpath}`);
|
|
10996
11695
|
} else optimizeDeps.exclude.push(subpath);
|
|
10997
11696
|
}
|
|
10998
11697
|
}
|
|
@@ -11010,10 +11709,8 @@ export default __mfShared.default ?? __mfShared;`
|
|
|
11010
11709
|
const automaticJsxRuntime = getAutomaticJsxRuntime(config);
|
|
11011
11710
|
if (automaticJsxRuntime && materializeAutomaticJsxRuntime(options, automaticJsxRuntime)) writeLocalSharedImportMap(options);
|
|
11012
11711
|
}
|
|
11013
|
-
if (!getSsrCapabilities(parseInt(version, 10), config.command, hasRemotes(options)).injectSsrEntryLoader) return;
|
|
11014
|
-
if (options.runtimePlugins.some((p) =>
|
|
11015
|
-
return (typeof p === "string" ? p : p[0]) === "@module-federation/vite/ssrEntryLoader";
|
|
11016
|
-
})) return;
|
|
11712
|
+
if (!getSsrCapabilities(parseInt(version, 10), config.command, hasRemotes(options), isSsrConfig(config)).injectSsrEntryLoader) return;
|
|
11713
|
+
if (options.runtimePlugins.some((p) => getRuntimePluginSpecifier(p) === "@module-federation/vite/ssrEntryLoader")) return;
|
|
11017
11714
|
const projectRequire = createRequire$1(pathToFileURL(path$1.join(config.root, "package.json")));
|
|
11018
11715
|
const sharedKeys = Object.keys(options.shared ?? {});
|
|
11019
11716
|
const commonSharedPkgs = [
|
|
@@ -11056,16 +11753,14 @@ function applyBuildTimeRuntimeDefines(define, options, { target, isAstro, defaul
|
|
|
11056
11753
|
}
|
|
11057
11754
|
function loadPluginDts(options) {
|
|
11058
11755
|
if (options.dts === false) return [];
|
|
11059
|
-
return [import("./pluginDts-
|
|
11756
|
+
return [import("./pluginDts-VSLhAx6d.js").then(({ default: pluginDts }) => pluginDts(options))];
|
|
11060
11757
|
}
|
|
11061
11758
|
const INJECT_EXTERNAL_RUNTIME_CORE_PLUGIN = "@module-federation/vite/injectExternalRuntimeCorePlugin";
|
|
11062
11759
|
function isInjectExternalRuntimeCorePlugin(specifier) {
|
|
11063
11760
|
return specifier === INJECT_EXTERNAL_RUNTIME_CORE_PLUGIN || specifier.includes("injectExternalRuntimeCorePlugin") || specifier.includes("inject-external-runtime-core-plugin");
|
|
11064
11761
|
}
|
|
11065
11762
|
function hasInjectExternalRuntimeCorePlugin(runtimePlugins) {
|
|
11066
|
-
return runtimePlugins.some((plugin) =>
|
|
11067
|
-
return isInjectExternalRuntimeCorePlugin(typeof plugin === "string" ? plugin : plugin[0]);
|
|
11068
|
-
});
|
|
11763
|
+
return runtimePlugins.some((plugin) => isInjectExternalRuntimeCorePlugin(getRuntimePluginSpecifier(plugin)));
|
|
11069
11764
|
}
|
|
11070
11765
|
function resolveInjectExternalRuntimeCorePlugin() {
|
|
11071
11766
|
try {
|
|
@@ -11112,7 +11807,7 @@ function federation(mfUserOptions) {
|
|
|
11112
11807
|
const emittedRuntimeCapabilityWarnings = /* @__PURE__ */ new Set();
|
|
11113
11808
|
const getLoadHookExportConditions = (context, loadOptions) => {
|
|
11114
11809
|
const environment = context.environment;
|
|
11115
|
-
const isSsr = loadOptions?.ssr === true || isSsrBuild || environment?.
|
|
11810
|
+
const isSsr = loadOptions?.ssr === true || isSsrBuild || isServerEnvironment(environment?.name, environment?.config);
|
|
11116
11811
|
return getSharedExportConditions({
|
|
11117
11812
|
environmentConditions: environment?.config?.resolve?.conditions,
|
|
11118
11813
|
isProduction: environment?.config?.isProduction ?? isProduction,
|
|
@@ -11236,7 +11931,7 @@ function federation(mfUserOptions) {
|
|
|
11236
11931
|
ssrResolveConditions = config.ssr?.resolve?.conditions ? [...config.ssr.resolve.conditions] : void 0;
|
|
11237
11932
|
ssrTarget = config.ssr?.target ?? "node";
|
|
11238
11933
|
isProduction = config.isProduction;
|
|
11239
|
-
const ssrCapabilities = getSsrCapabilities(parseInt(version, 10), command, Object.keys(options.remotes).length > 0);
|
|
11934
|
+
const ssrCapabilities = getSsrCapabilities(parseInt(version, 10), command, Object.keys(options.remotes).length > 0, isSsrConfig(config));
|
|
11240
11935
|
resolveSharedVersions(shared, config.root);
|
|
11241
11936
|
initVirtualModules(command, remoteEntryId, ssrCapabilities.enableSsrInitBootstrap, options);
|
|
11242
11937
|
}
|
|
@@ -11286,6 +11981,7 @@ function federation(mfUserOptions) {
|
|
|
11286
11981
|
federationOptions: options,
|
|
11287
11982
|
getParsePromise: () => moduleParseController.parsePromise
|
|
11288
11983
|
}),
|
|
11984
|
+
pluginLazyConsumeOnlyShares(options),
|
|
11289
11985
|
{
|
|
11290
11986
|
name: "module-federation-esm-shims",
|
|
11291
11987
|
enforce: "pre",
|
|
@@ -11337,6 +12033,7 @@ function federation(mfUserOptions) {
|
|
|
11337
12033
|
priority: USER_GROUP_MAX_PRIORITY
|
|
11338
12034
|
};
|
|
11339
12035
|
};
|
|
12036
|
+
const federationGroupDebugName = supportsCodeSplittingGroupDebugName(this) ? { debugName: "module-federation" } : {};
|
|
11340
12037
|
let warnedAboutManualChunks = false;
|
|
11341
12038
|
let warnedAboutObjectManualChunks = false;
|
|
11342
12039
|
const applyManualChunks = (output, useCodeSplitting) => {
|
|
@@ -11344,11 +12041,13 @@ function federation(mfUserOptions) {
|
|
|
11344
12041
|
const isPatchedByPlugin = typeof output.manualChunks === "function" && patchedManualChunks.has(output.manualChunks);
|
|
11345
12042
|
const mfChunkName = function(id) {
|
|
11346
12043
|
if (id.includes(runtimeInitId) || id.includes("__mf_v__runtimeInit__mf_v__")) return "runtimeInit";
|
|
12044
|
+
if (isSharedCacheHelpersId(id)) return getSharedChunkName(id);
|
|
11347
12045
|
if (id.includes("__loadShare__")) {
|
|
11348
12046
|
const pkg = getCachedLoadSharePkg(id);
|
|
11349
12047
|
const key = pkg && findSharedKey(pkg, shared);
|
|
11350
12048
|
if (key && shared[key].shareConfig.eager === true) return "loadShare-eager";
|
|
11351
12049
|
if (key && shared[key].shareConfig.import === false) return null;
|
|
12050
|
+
if (pkg && !id.includes("commonjs-proxy") && isCoalescableLoadShareWrapper(pkg, options, id)) return getSharedChunkName(id);
|
|
11352
12051
|
const match = id.match(/([^/\\]+__loadShare__[^/\\]+)/);
|
|
11353
12052
|
return match ? match[1] : "loadShare";
|
|
11354
12053
|
}
|
|
@@ -11385,7 +12084,8 @@ function federation(mfUserOptions) {
|
|
|
11385
12084
|
};
|
|
11386
12085
|
const mfNameGroup = {
|
|
11387
12086
|
name: mfChunkName,
|
|
11388
|
-
priority: MF_GROUP_PRIORITY
|
|
12087
|
+
priority: MF_GROUP_PRIORITY,
|
|
12088
|
+
...federationGroupDebugName
|
|
11389
12089
|
};
|
|
11390
12090
|
federationGroups.add(mfPreloadGroup);
|
|
11391
12091
|
federationGroups.add(mfNameGroup);
|
|
@@ -11458,7 +12158,14 @@ function federation(mfUserOptions) {
|
|
|
11458
12158
|
if (!virtualModule?.code) return null;
|
|
11459
12159
|
let code = virtualModule.code;
|
|
11460
12160
|
const consumerTarget = resolveEnvironmentConsumerTarget(this);
|
|
11461
|
-
if (consumerTarget === "server" || !consumerTarget && isSsrBuild)
|
|
12161
|
+
if (consumerTarget === "server" || !consumerTarget && isSsrBuild) {
|
|
12162
|
+
const withSsrImport = prependWorkspaceSingletonSsrImport(code);
|
|
12163
|
+
if (withSsrImport !== code) {
|
|
12164
|
+
const pkg = getCachedLoadSharePkg(id);
|
|
12165
|
+
if (pkg) markLoadShareWrapperNotCoalescable(pkg, options, id);
|
|
12166
|
+
code = withSsrImport;
|
|
12167
|
+
}
|
|
12168
|
+
}
|
|
11462
12169
|
code = code.replace(/import\s+["'][^"']*__prebuild__[^"']*["']\s*;?/g, "");
|
|
11463
12170
|
code = code.replace(/export\s+\*\s+from\s+["'][^"']*__prebuild__[^"']*["']\s*;?/g, "");
|
|
11464
12171
|
if (!(/\b(?:var|let|const)\s+__moduleExports\b/.test(code) || /\bexport\s+const\s+__moduleExports\b/.test(code) || /\bexport\s*\{[^}]*__moduleExports/.test(code))) {
|
|
@@ -11476,6 +12183,9 @@ function federation(mfUserOptions) {
|
|
|
11476
12183
|
return loadVirtualModule();
|
|
11477
12184
|
},
|
|
11478
12185
|
generateBundle(_outputOptions, bundle, _isWrite) {
|
|
12186
|
+
inlineDeferredPrebuildNamespaceHelper(bundle);
|
|
12187
|
+
for (const [fileName, fallbacks] of findEagerFallbacksInSharedChunk(bundle)) mfWarn(`A shared-dependency fallback was merged into the loadShare chunk ${fileName}: ${fallbacks.join(", ")}.\n That fallback is no longer lazy, so consumers download their local copy even when a peer provides the share, and the container can deadlock.
|
|
12188
|
+
Stop the shared module from statically importing another share.`);
|
|
11479
12189
|
for (const [fileName, chunk] of Object.entries(bundle)) {
|
|
11480
12190
|
if (!isOutputChunk(chunk)) continue;
|
|
11481
12191
|
if (!isFederationControlChunk(fileName, filename)) continue;
|
|
@@ -11541,7 +12251,7 @@ function federation(mfUserOptions) {
|
|
|
11541
12251
|
config.optimizeDeps.include.push("@module-federation/runtime");
|
|
11542
12252
|
if (needsRuntimeHelpers) config.optimizeDeps.include.push("@module-federation/runtime/helpers");
|
|
11543
12253
|
options.runtimePlugins.forEach((p) => {
|
|
11544
|
-
const pluginPath =
|
|
12254
|
+
const pluginPath = getRuntimePluginSpecifier(p);
|
|
11545
12255
|
if (SSR_ONLY_RUNTIME_PLUGINS.has(pluginPath)) return;
|
|
11546
12256
|
if (pluginPath && !pluginPath.startsWith(".") && !pluginPath.startsWith("/") && !pluginPath.startsWith("\0") && !pluginPath.startsWith("virtual:")) {
|
|
11547
12257
|
let optimizeDep = pluginPath;
|
|
@@ -11577,7 +12287,7 @@ function federation(mfUserOptions) {
|
|
|
11577
12287
|
if (prematureExit) prematureExit.closeBundle = void 0;
|
|
11578
12288
|
},
|
|
11579
12289
|
configEnvironment(name, config) {
|
|
11580
|
-
if (!(
|
|
12290
|
+
if (!isServerEnvironment(name, config)) return;
|
|
11581
12291
|
const isAstro = hasPackageDependency("astro");
|
|
11582
12292
|
config.define = { ...config.define ?? {} };
|
|
11583
12293
|
applyBuildTimeRuntimeDefines(config.define, options, {
|