@module-federation/vite 1.22.0 → 1.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -1,6 +1,6 @@
1
+ import { _ as stripViteFsPrefix, a as ensureTrailingSlash, c as getCommonSharedSubpaths, d as isNodeModulePath, f as isNuxtClientBase, g as stripQueryAndHash, h as resolvePublicPath, l as getNodeModulesSuffix, m as normalizeNodeModulePath, n as invalidateSharedKeyMatcher, o as filterId, p as isViteOptimizableEntry, r as matchesSharedSource, s as getBasePath$1, t as findSharedKey, u as isAssetLikeImport } from "./sharedKeyMatcher-BRzBCbuR.js";
1
2
  import { i as resolveHashPlaceholderFileName, n as normalizePathForImport, r as rebaseImport } from "./buildPaths-BoaQTkxt.js";
2
- import { a as getPackageDetectionCwd, c as getSharedCacheDescriptor, d as packageNameDecode, f as packageNameEncode, g as createModuleFederationError, h as sharedCacheHelperCode, i as getIsRolldown, l as hasPackageDependency, m as setPackageDetectionCwd, n as getInstalledPackageEntry, o as getPackageName, p as resolveImportPath, r as getInstalledPackageJson, s as getPackageNameFromNodeModulePath, u as isNuxtProjectRoot, v as mfWarn } from "./dtsConstants-BEGrtvcw.js";
3
- import { a as filterId, c as getCommonSharedSubpaths, d as isNodeModulePath, f as isNuxtClientBase, h as resolvePublicPath, i as ensureTrailingSlash, l as getMatchingNodeModuleSubpath, m as normalizeNodeModulePath, n as invalidateSharedKeyMatcher, o as getBasePath$1, p as isViteOptimizableEntry, r as matchesSharedSource, s as getCommonSharedSubpathFromNodeModulePath, t as findSharedKey, u as isAssetLikeImport } from "./sharedKeyMatcher-DiUzRVH1.js";
3
+ import { _ as sharedCacheHelperCode, a as getPackageDetectionCwd, b as mfWarn, c as getSharedCacheDescriptor, d as isPackageExportAvailable, f as isPackageInstalled, g as setPackageDetectionCwd, h as resolveImportPath, i as getIsRolldown, l as hasPackageDependency, m as packageNameEncode, n as getInstalledPackageEntry, o as getPackageName, p as packageNameDecode, r as getInstalledPackageJson, s as getPackageNameFromNodeModulePath, u as isNuxtProjectRoot, v as createModuleFederationError } from "./dtsConstants-dDsHZFC1.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";
@@ -431,7 +431,7 @@ function isJsxClosingTagSlash(code, slashIndex) {
431
431
  return code[cursor] === ">";
432
432
  }
433
433
  /** Mark comments, string/template literals, and regular expressions as non-code. */
434
- function createCodePositionMap(code) {
434
+ function createCodePositionMap(code, onComment) {
435
435
  const positions = Array(code.length).fill(true);
436
436
  const mask = (start, end) => {
437
437
  for (let index = start; index < end; index++) positions[index] = false;
@@ -449,6 +449,7 @@ function createCodePositionMap(code) {
449
449
  index += 2;
450
450
  while (index < code.length && code[index] !== "\n" && code[index] !== "\r") index++;
451
451
  mask(start, index);
452
+ onComment?.(start, index);
452
453
  continue;
453
454
  }
454
455
  if (char === "/" && next === "*") {
@@ -457,6 +458,7 @@ function createCodePositionMap(code) {
457
458
  while (index < code.length && !(code[index] === "*" && code[index + 1] === "/")) index++;
458
459
  index = Math.min(code.length, index + 2);
459
460
  mask(start, index);
461
+ onComment?.(start, index);
460
462
  continue;
461
463
  }
462
464
  if (char === "\"" || char === "'" || char === "`") {
@@ -762,8 +764,8 @@ function normalizeRemoteItem(key, remote) {
762
764
  * @param {string} sharedName
763
765
  * @returns {string | undefined}
764
766
  */
765
- function searchPackageVersion(sharedName) {
766
- const version = getInstalledPackageJson(sharedName)?.packageJson.version;
767
+ function searchPackageVersion(sharedName, cwd) {
768
+ const version = getInstalledPackageJson(sharedName, { cwd })?.packageJson.version;
767
769
  return typeof version === "string" ? version : void 0;
768
770
  }
769
771
  function inferVersionFromRequiredVersion(requiredVersion) {
@@ -798,36 +800,88 @@ const PACKAGE_SPECIFIER_PROTOCOL_RE = /^[a-z][a-z\d+.-]*:/i;
798
800
  function isProtocolRequiredVersion(requiredVersion) {
799
801
  return PACKAGE_SPECIFIER_PROTOCOL_RE.test(requiredVersion.trim());
800
802
  }
803
+ const SEMVER_COMPARATOR_RE = /^(?:[<>=~^]*v?(?:\d+|[xX*])(?:\.(?:\d+|[xX*]))*(?:[-+][\w.-]+)?|[<>=~^]+|[xX*]|-)$/;
804
+ function isSemverRange(range) {
805
+ return range.split("||").every((alternative) => {
806
+ const comparators = alternative.trim().split(/\s+/).filter(Boolean);
807
+ return comparators.length > 0 && comparators.every((c) => SEMVER_COMPARATOR_RE.test(c));
808
+ });
809
+ }
810
+ function isUsableRequiredVersion(requiredVersion) {
811
+ return requiredVersion.trim() !== "" && !isProtocolRequiredVersion(requiredVersion) && isSemverRange(requiredVersion);
812
+ }
813
+ /** Bare specifiers name an installed package; relative/absolute paths do not. */
814
+ function isBareSpecifier(specifier) {
815
+ return !specifier.startsWith(".") && !specifier.startsWith("\0") && !path$1.isAbsolute(specifier) && !PACKAGE_SPECIFIER_PROTOCOL_RE.test(specifier);
816
+ }
817
+ function readProjectPackageJson(cwd, cache) {
818
+ if (cache.has(cwd)) return cache.get(cwd);
819
+ let packageJson;
820
+ try {
821
+ packageJson = JSON.parse(fs$2.readFileSync(path$1.join(cwd, "package.json"), "utf8"));
822
+ } catch {}
823
+ cache.set(cwd, packageJson);
824
+ return packageJson;
825
+ }
801
826
  function getLitExportSubpathShares(sharedName) {
802
827
  if (sharedName !== "lit") return [];
803
828
  const exportsField = getInstalledPackageJson(sharedName, { packageName: sharedName })?.packageJson.exports;
804
829
  if (!exportsField || typeof exportsField === "string") return [];
805
830
  return Object.keys(exportsField).filter((key) => key.startsWith("./") && key !== "." && !key.includes("*")).map((key) => `${sharedName}/${key.slice(2)}`);
806
831
  }
832
+ const sharedVersionConfigs = /* @__PURE__ */ new WeakMap();
833
+ function resolveSharedVersion(key, config, cwd, packageJsonCache = /* @__PURE__ */ new Map(), fallbackVersion) {
834
+ const source = typeof config.import === "string" && isBareSpecifier(config.import) ? config.import : key;
835
+ const version = config.version || searchPackageVersion(source, cwd) || inferVersionFromRequiredVersion(config.requiredVersion) || fallbackVersion;
836
+ let requiredVersion = config.requiredVersion;
837
+ if (requiredVersion === void 0 && !config.version) {
838
+ const packageJson = readProjectPackageJson(cwd, packageJsonCache);
839
+ const packageName = getPackageName(source);
840
+ requiredVersion = packageJson?.dependencies?.[packageName] ?? packageJson?.devDependencies?.[packageName] ?? packageJson?.peerDependencies?.[packageName] ?? packageJson?.optionalDependencies?.[packageName];
841
+ }
842
+ if (requiredVersion === false || typeof requiredVersion === "string" && isUsableRequiredVersion(requiredVersion)) return {
843
+ version,
844
+ requiredVersion
845
+ };
846
+ return {
847
+ version,
848
+ requiredVersion: config.import === false || config.version ? "*" : version ? `^${version}` : "*"
849
+ };
850
+ }
851
+ function resolveSharedVersions(shared, root) {
852
+ const packageJsonCache = /* @__PURE__ */ new Map();
853
+ for (const [key, item] of Object.entries(shared)) {
854
+ const config = sharedVersionConfigs.get(item);
855
+ if (!config) continue;
856
+ const { version, requiredVersion } = resolveSharedVersion(key, config, root, packageJsonCache, item.version);
857
+ item.version = version;
858
+ item.shareConfig.requiredVersion = requiredVersion;
859
+ }
860
+ }
807
861
  function normalizeShareItem(key, shareItem) {
808
- const isImportFalse = typeof shareItem === "object" && shareItem.import === false;
809
- const explicitVersion = typeof shareItem === "object" ? shareItem.version : void 0;
810
- const inferredVersion = typeof shareItem === "object" ? inferVersionFromRequiredVersion(shareItem.requiredVersion) : void 0;
811
862
  const treeShaking = typeof shareItem === "object" ? shareItem.treeShaking : void 0;
812
863
  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".`);
813
864
  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.`);
814
865
  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.`);
815
- const version = explicitVersion || searchPackageVersion(key) || inferredVersion;
816
- if (typeof shareItem === "string") return {
817
- name: shareItem,
818
- version,
819
- scope: "default",
820
- from: "",
821
- shareConfig: {
822
- import: void 0,
823
- singleton: false,
824
- eager: false,
825
- requiredVersion: version ? `^${version}` : "*"
826
- }
827
- };
828
- const userRequiredVersion = shareItem.requiredVersion;
829
- const keepUserRequiredVersion = userRequiredVersion === false || typeof userRequiredVersion === "string" && userRequiredVersion.trim() !== "" && !isProtocolRequiredVersion(userRequiredVersion);
830
- return {
866
+ const config = typeof shareItem === "object" ? shareItem : {};
867
+ const { version, requiredVersion } = resolveSharedVersion(key, config, getPackageDetectionCwd());
868
+ if (typeof shareItem === "string") {
869
+ const result = {
870
+ name: shareItem,
871
+ version,
872
+ scope: "default",
873
+ from: "",
874
+ shareConfig: {
875
+ import: void 0,
876
+ singleton: false,
877
+ eager: false,
878
+ requiredVersion
879
+ }
880
+ };
881
+ sharedVersionConfigs.set(result, { ...config });
882
+ return result;
883
+ }
884
+ const result = {
831
885
  name: key,
832
886
  from: "",
833
887
  version,
@@ -836,12 +890,14 @@ function normalizeShareItem(key, shareItem) {
836
890
  import: shareItem.import,
837
891
  singleton: shareItem.singleton || false,
838
892
  eager: shareItem.eager || false,
839
- requiredVersion: keepUserRequiredVersion ? userRequiredVersion : isImportFalse || shareItem.version ? "*" : version ? `^${version}` : "*",
893
+ requiredVersion,
840
894
  strictVersion: !!shareItem.strictVersion,
841
895
  ...shareItem.suppressMissingImportWarning ? { suppressMissingImportWarning: true } : {},
842
896
  ...treeShaking ? { treeShaking: { ...treeShaking } } : {}
843
897
  }
844
898
  };
899
+ sharedVersionConfigs.set(result, { ...config });
900
+ return result;
845
901
  }
846
902
  /**
847
903
  * Trailing-slash keys are package namespace prefixes (`lodash/`, `@scope/ui/`).
@@ -945,6 +1001,9 @@ function getNormalizeModuleFederationOptions() {
945
1001
  function hasRemotes(options = getNormalizeModuleFederationOptions()) {
946
1002
  return Object.keys(options.remotes || {}).length > 0;
947
1003
  }
1004
+ function hasShared(options = getNormalizeModuleFederationOptions()) {
1005
+ return Object.keys(options.shared || {}).length > 0;
1006
+ }
948
1007
  function isRemoteContainer(options = getNormalizeModuleFederationOptions()) {
949
1008
  return Object.keys(options.exposes || {}).length > 0;
950
1009
  }
@@ -958,7 +1017,8 @@ function isExplicitSharedKey(key, options) {
958
1017
  return (options ? explicitSharedKeysByOptions.get(options) : explicitSharedKeys)?.has(key) ?? false;
959
1018
  }
960
1019
  function getNormalizeShareItem(key, options = getNormalizeModuleFederationOptions()) {
961
- return options.shared[key] || options.shared[getPackageName(key)] || options.shared[getPackageName(key) + "/"];
1020
+ const matchedKey = findSharedKey(key, options.shared);
1021
+ return options.shared[key] || (matchedKey ? options.shared[matchedKey] : void 0) || options.shared[getPackageName(key)] || options.shared[getPackageName(key) + "/"];
962
1022
  }
963
1023
  function normalizeModuleFederationOptions(options) {
964
1024
  warnOnReservedInternalNamePrefix(options.name, "containerName");
@@ -1216,6 +1276,279 @@ function isParsableExpression(source) {
1216
1276
  }
1217
1277
  }
1218
1278
  //#endregion
1279
+ //#region src/utils/treeShaking.ts
1280
+ function shouldAnalyzeSharedExports(shareItem) {
1281
+ return !!(shareItem && (shareItem.shareConfig.treeShaking || shareItem.shareConfig.import === false));
1282
+ }
1283
+ const legacyTreeShakingState = {
1284
+ inferredUsage: /* @__PURE__ */ new Map(),
1285
+ buildMode: false
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;
1348
+ }
1349
+ /**
1350
+ * Return the analyzed requirement for one concrete shared request.
1351
+ *
1352
+ * Callers that know the configured share key should pass it explicitly. The
1353
+ * fallback lookup across keys keeps aliases/backwards-compatible callers
1354
+ * working, while still keeping each concrete request's exports isolated.
1355
+ */
1356
+ function getSharedExportUsage(request, shareItem, sharedKey, options) {
1357
+ const treeShaking = shareItem?.shareConfig.treeShaking;
1358
+ if (!shouldAnalyzeSharedExports(shareItem) || !getTreeShakingState(options).buildMode) return;
1359
+ const records = getExportRecords(sharedKey, request, options);
1360
+ if (records.some((record) => record.requiresFullBundle)) return { kind: "full" };
1361
+ const configured = treeShaking?.usedExports ?? [];
1362
+ const result = new Set(configured);
1363
+ records.forEach((record) => record.usedExports.forEach((name) => result.add(name)));
1364
+ if (result.size > 0) return {
1365
+ kind: "exports",
1366
+ usedExports: [...result].sort()
1367
+ };
1368
+ return records.length > 0 ? {
1369
+ kind: "exports",
1370
+ usedExports: []
1371
+ } : { kind: "unknown" };
1372
+ }
1373
+ function getTreeShakingExportUsage(request, shareItem, sharedKey, options) {
1374
+ if (!shareItem?.shareConfig.treeShaking) return void 0;
1375
+ return getSharedExportUsage(request, shareItem, sharedKey, options);
1376
+ }
1377
+ function getModuleSource(node) {
1378
+ if (!node || typeof node !== "object") return void 0;
1379
+ const source = node;
1380
+ if (source.type === "Literal" && typeof source.value === "string") return source.value;
1381
+ if (source.type === "StringLiteral" && typeof source.value === "string") return source.value;
1382
+ if (source.type !== "TemplateLiteral") return void 0;
1383
+ const expressions = Array.isArray(source.expressions) ? source.expressions : [];
1384
+ const quasis = Array.isArray(source.quasis) ? source.quasis : [];
1385
+ if (expressions.length > 0 || quasis.length !== 1) return void 0;
1386
+ const value = quasis[0]?.value;
1387
+ return typeof value?.cooked === "string" ? value.cooked : typeof value?.raw === "string" ? value.raw : void 0;
1388
+ }
1389
+ function getExportedName(node) {
1390
+ if (!node || typeof node !== "object") return void 0;
1391
+ const exported = node;
1392
+ if (exported.type === "Identifier" && typeof exported.name === "string") return exported.name;
1393
+ if ((exported.type === "Literal" || exported.type === "StringLiteral") && typeof exported.value === "string") return exported.value;
1394
+ }
1395
+ function isTypeOnly(node) {
1396
+ return node.importKind === "type" || node.exportKind === "type";
1397
+ }
1398
+ function forEachAstNode(root, visit) {
1399
+ const stack = [root];
1400
+ const seen = /* @__PURE__ */ new Set();
1401
+ while (stack.length > 0) {
1402
+ const value = stack.pop();
1403
+ if (!value || typeof value !== "object") continue;
1404
+ if (seen.has(value)) continue;
1405
+ seen.add(value);
1406
+ if (Array.isArray(value)) {
1407
+ for (let index = value.length - 1; index >= 0; index--) stack.push(value[index]);
1408
+ continue;
1409
+ }
1410
+ const node = value;
1411
+ if (typeof node.type === "string") visit(node);
1412
+ Object.entries(node).forEach(([key, child]) => {
1413
+ if (key !== "parent" && key !== "loc") stack.push(child);
1414
+ });
1415
+ }
1416
+ }
1417
+ function collectImportDeclaration(node, source, record, markUnsafe) {
1418
+ if (isTypeOnly(node)) return;
1419
+ const specifiers = Array.isArray(node.specifiers) ? node.specifiers : [];
1420
+ if (specifiers.length === 0) {
1421
+ markUnsafe(source);
1422
+ return;
1423
+ }
1424
+ const names = [];
1425
+ for (const specifier of specifiers) {
1426
+ if (isTypeOnly(specifier)) continue;
1427
+ if (specifier.type === "ImportNamespaceSpecifier") {
1428
+ markUnsafe(source);
1429
+ return;
1430
+ }
1431
+ if (specifier.type === "ImportDefaultSpecifier") {
1432
+ names.push("default");
1433
+ continue;
1434
+ }
1435
+ if (specifier.type === "ImportSpecifier") {
1436
+ const imported = specifier.imported;
1437
+ if (imported?.type === "Literal" || imported?.type === "StringLiteral") {
1438
+ markUnsafe(source);
1439
+ return;
1440
+ }
1441
+ const name = getExportedName(specifier.imported);
1442
+ if (!name) {
1443
+ markUnsafe(source);
1444
+ return;
1445
+ }
1446
+ names.push(name);
1447
+ continue;
1448
+ }
1449
+ markUnsafe(source);
1450
+ return;
1451
+ }
1452
+ record(names, source);
1453
+ }
1454
+ function collectReExport(node, source, record, markUnsafe) {
1455
+ if (isTypeOnly(node)) return;
1456
+ if (node.type === "ExportAllDeclaration") {
1457
+ markUnsafe(source);
1458
+ return;
1459
+ }
1460
+ const specifiers = Array.isArray(node.specifiers) ? node.specifiers : [];
1461
+ if (specifiers.length === 0) {
1462
+ markUnsafe(source);
1463
+ return;
1464
+ }
1465
+ const names = [];
1466
+ for (const specifier of specifiers) {
1467
+ if (isTypeOnly(specifier)) continue;
1468
+ if (specifier.type !== "ExportSpecifier") {
1469
+ markUnsafe(source);
1470
+ return;
1471
+ }
1472
+ const local = specifier.local;
1473
+ if (local?.type === "Literal" || local?.type === "StringLiteral") {
1474
+ markUnsafe(source);
1475
+ return;
1476
+ }
1477
+ const name = getExportedName(specifier.local);
1478
+ if (!name) {
1479
+ markUnsafe(source);
1480
+ return;
1481
+ }
1482
+ names.push(name);
1483
+ }
1484
+ record(names, source);
1485
+ }
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;
1500
+ let ast;
1501
+ try {
1502
+ ast = parseAst(code);
1503
+ } catch {
1504
+ Object.entries(shared).forEach(([sharedKey, shareItem]) => {
1505
+ if (shouldAnalyzeSharedExports(shareItem)) markUnsafe(sharedKey, "*");
1506
+ });
1507
+ return;
1508
+ }
1509
+ const pending = [];
1510
+ const withSharedSource = (source, use) => {
1511
+ const apply = (key) => {
1512
+ if (key && shouldAnalyzeSharedExports(shared[key])) use(key);
1513
+ };
1514
+ const key = findSharedKey(source, shared);
1515
+ if (key instanceof Promise) pending.push(key.then(apply));
1516
+ else apply(key);
1517
+ };
1518
+ const recordSource = (names, source) => {
1519
+ withSharedSource(source, (key) => record(key, names, source));
1520
+ };
1521
+ const markSourceUnsafe = (source) => {
1522
+ withSharedSource(source, (key) => markUnsafe(key, source));
1523
+ };
1524
+ forEachAstNode(ast, (node) => {
1525
+ if (node.type === "ImportDeclaration") {
1526
+ const source = getModuleSource(node.source);
1527
+ if (source) collectImportDeclaration(node, source, recordSource, markSourceUnsafe);
1528
+ return;
1529
+ }
1530
+ if ((node.type === "ExportNamedDeclaration" || node.type === "ExportAllDeclaration") && node.source) {
1531
+ const source = getModuleSource(node.source);
1532
+ if (source) collectReExport(node, source, recordSource, markSourceUnsafe);
1533
+ return;
1534
+ }
1535
+ if (node.type === "ImportExpression") {
1536
+ const source = getModuleSource(node.source);
1537
+ if (source) markSourceUnsafe(source);
1538
+ return;
1539
+ }
1540
+ if (node.type === "CallExpression") {
1541
+ const callee = node.callee;
1542
+ const args = Array.isArray(node.arguments) ? node.arguments : [];
1543
+ if (callee?.type === "Identifier" && callee.name === "require" && args.length > 0) {
1544
+ const source = getModuleSource(args[0]);
1545
+ if (source) markSourceUnsafe(source);
1546
+ }
1547
+ }
1548
+ });
1549
+ await Promise.all(pending);
1550
+ }
1551
+ //#endregion
1219
1552
  //#region src/utils/reactIsland.ts
1220
1553
  const SOURCE_EXTENSIONS$1 = [
1221
1554
  ".tsx",
@@ -1227,11 +1560,8 @@ const SOURCE_EXTENSIONS$1 = [
1227
1560
  ".cts",
1228
1561
  ".cjs"
1229
1562
  ];
1230
- function stripQueryAndHash$2(id) {
1231
- return id.split(/[?#]/, 1)[0];
1232
- }
1233
1563
  function resolveSourceFile(importPath, root) {
1234
- const cleanImport = stripQueryAndHash$2(importPath);
1564
+ const cleanImport = stripQueryAndHash(importPath);
1235
1565
  if (!cleanImport.startsWith(".") && !path$1.isAbsolute(cleanImport)) return;
1236
1566
  const candidate = path$1.isAbsolute(cleanImport) ? cleanImport : path$1.resolve(root, cleanImport);
1237
1567
  return [
@@ -1252,7 +1582,7 @@ function localDefaultReexport(source) {
1252
1582
  }
1253
1583
  function isReactComponentSource(source, filePath = "component.tsx") {
1254
1584
  if (!(/\bexport\s+default\b/.test(source) || /\bexport\s*{[^}]*\bdefault\b[^}]*}(?:\s*from\s*["'][^"']+["'])?/.test(source))) return false;
1255
- const extension = path$1.extname(stripQueryAndHash$2(filePath)).toLowerCase();
1585
+ const extension = path$1.extname(stripQueryAndHash(filePath)).toLowerCase();
1256
1586
  const canContainJsx = extension === ".tsx" || extension === ".jsx";
1257
1587
  const hasJsx = /<>|<\s*[A-Za-z][\w.:-]*(?:\s[^<>]*?)?\s*\/?>/.test(source);
1258
1588
  const importsReact = /\bfrom\s*["']react["']|\brequire\(\s*["']react["']\s*\)/.test(source);
@@ -1786,335 +2116,66 @@ for (const __mfShareKey of Object.keys(__mfModuleCache.share)) {
1786
2116
  const __mfLegacyShareKey = __mfShareKey.slice("default:".length);
1787
2117
  if (__mfModuleCache.share[__mfLegacyShareKey] === undefined) {
1788
2118
  __mfModuleCache.share[__mfLegacyShareKey] = __mfModuleCache.share[__mfShareKey];
1789
- }
1790
- } else if (!__mfShareKey.includes(":")) {
1791
- const __mfDefaultShareKey = "default:" + __mfShareKey;
1792
- if (__mfModuleCache.share[__mfDefaultShareKey] === undefined) {
1793
- __mfModuleCache.share[__mfDefaultShareKey] = __mfModuleCache.share[__mfShareKey];
1794
- }
1795
- }
1796
- }
1797
- `;
1798
- }
1799
- function getRuntimeInitPromiseBootstrapCode(enableSsrInit = false, ownerImportId, ssrRemotes, hostInitImportId = ownerImportId) {
1800
- return getRuntimeInitStateBootstrapCode({
1801
- globalKeyVar: "__mfPromiseGlobalKey",
1802
- stateVar: "__mfPromiseState",
1803
- exposedConst: "initPromise",
1804
- exposedProperty: "initPromise",
1805
- enableSsrInit,
1806
- ownerImportId,
1807
- hostInitImportId,
1808
- ssrRemotes
1809
- });
1810
- }
1811
- function getRuntimeInitResolveBootstrapCode(enableSsrInit = false, ownerImportId, ssrRemotes, hostInitImportId = ownerImportId) {
1812
- return getRuntimeInitStateBootstrapCode({
1813
- globalKeyVar: "__mfResolveGlobalKey",
1814
- stateVar: "__mfResolveState",
1815
- exposedConst: "initResolve",
1816
- exposedProperty: "initResolve",
1817
- enableSsrInit,
1818
- ownerImportId,
1819
- hostInitImportId,
1820
- ssrRemotes
1821
- });
1822
- }
1823
- function writeRuntimeInitStatus(command, enableSsrInit = false, hostInitImportId, options, ssrRemotes = _ssrRemotes) {
1824
- const exportStatement = command === "build" ? `const { initPromise, initResolve, initReject, moduleCache } = globalThis[globalKey];
1825
- export { initPromise, initResolve, initReject, moduleCache };` : `module.exports = globalThis[globalKey];`;
1826
- const ownerImportId = options ? getRuntimeInitStatusImportId(options) : hostInitImportId;
1827
- getRuntimeInitModule(options).writeSync(`
1828
- ${getRuntimeInitBootstrapCode(enableSsrInit, ownerImportId, ssrRemotes, hostInitImportId)}
1829
- ${exportStatement}
1830
- `);
1831
- }
1832
- //#endregion
1833
- //#region src/plugins/pluginReactMixedModeGuard.ts
1834
- function createReactMixedModeRuntimeGuard() {
1835
- return `const __mfReactInternals = mod["__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE"];
1836
- if (__mfReactInternals && "A" in __mfReactInternals) {
1837
- let __mfReactDispatcher = __mfReactInternals.A;
1838
- Object.defineProperty(__mfReactInternals, "A", {
1839
- configurable: true,
1840
- enumerable: true,
1841
- get: () => __mfReactDispatcher,
1842
- set: (next) => {
1843
- if (next && typeof next.getOwner !== "function") next.getOwner = () => null;
1844
- __mfReactDispatcher = next;
1845
- },
1846
- });
1847
- __mfReactInternals.A = __mfReactDispatcher;
1848
- }`;
1849
- }
1850
- //#endregion
1851
- //#region src/utils/treeShaking.ts
1852
- function shouldAnalyzeSharedExports(shareItem) {
1853
- return !!(shareItem && (shareItem.shareConfig.treeShaking || shareItem.shareConfig.import === false));
1854
- }
1855
- const legacyTreeShakingState = {
1856
- inferredUsage: /* @__PURE__ */ new Map(),
1857
- buildMode: false
1858
- };
1859
- const treeShakingStates = /* @__PURE__ */ new WeakMap();
1860
- function getTreeShakingState(options) {
1861
- if (!options) return legacyTreeShakingState;
1862
- let state = treeShakingStates.get(options);
1863
- if (!state) {
1864
- state = {
1865
- inferredUsage: /* @__PURE__ */ new Map(),
1866
- buildMode: false
1867
- };
1868
- treeShakingStates.set(options, state);
1869
- }
1870
- return state;
1871
- }
1872
- function setTreeShakingBuildMode(enabled, options) {
1873
- getTreeShakingState(options).buildMode = enabled;
1874
- }
1875
- function resetTreeShakingExports(options) {
1876
- getTreeShakingState(options).inferredUsage.clear();
1877
- }
1878
- function getOrCreateExportRecord(sharedKey, request, options) {
1879
- const inferredUsage = getTreeShakingState(options).inferredUsage;
1880
- let byRequest = inferredUsage.get(sharedKey);
1881
- if (!byRequest) {
1882
- byRequest = /* @__PURE__ */ new Map();
1883
- inferredUsage.set(sharedKey, byRequest);
1884
- }
1885
- let record = byRequest.get(request);
1886
- if (!record) {
1887
- record = {
1888
- requiresFullBundle: false,
1889
- usedExports: /* @__PURE__ */ new Set()
1890
- };
1891
- byRequest.set(request, record);
1892
- }
1893
- return record;
1894
- }
1895
- function recordTreeShakingExports(sharedKey, exports, request = sharedKey, options) {
1896
- const record = getOrCreateExportRecord(sharedKey, request, options);
1897
- exports.forEach((name) => record.usedExports.add(name));
1898
- }
1899
- function markTreeShakingPackageUnsafe(sharedKey, request = sharedKey, options) {
1900
- getOrCreateExportRecord(sharedKey, request, options).requiresFullBundle = true;
1901
- }
1902
- function getExportRecords(sharedKey, request, options) {
1903
- const inferredUsage = getTreeShakingState(options).inferredUsage;
1904
- if (sharedKey) {
1905
- const records = inferredUsage.get(sharedKey);
1906
- const wildcard = records?.get("*");
1907
- const exact = records?.get(request);
1908
- return [wildcard, exact === wildcard ? void 0 : exact].filter((record) => !!record);
1909
- }
1910
- const records = [];
1911
- inferredUsage.forEach((byRequest, configuredKey) => {
1912
- const wildcard = byRequest.get("*");
1913
- const exact = byRequest.get(request);
1914
- const keyBase = configuredKey.endsWith("/") ? configuredKey.slice(0, -1) : configuredKey;
1915
- const requestMatchesConfiguredKey = request === keyBase || request.startsWith(`${keyBase}/`);
1916
- if (wildcard && requestMatchesConfiguredKey) records.push(wildcard);
1917
- if (exact && exact !== wildcard) records.push(exact);
1918
- });
1919
- return records;
1920
- }
1921
- /**
1922
- * Return the analyzed requirement for one concrete shared request.
1923
- *
1924
- * Callers that know the configured share key should pass it explicitly. The
1925
- * fallback lookup across keys keeps aliases/backwards-compatible callers
1926
- * working, while still keeping each concrete request's exports isolated.
1927
- */
1928
- function getSharedExportUsage(request, shareItem, sharedKey, options) {
1929
- const treeShaking = shareItem?.shareConfig.treeShaking;
1930
- if (!shouldAnalyzeSharedExports(shareItem) || !getTreeShakingState(options).buildMode) return;
1931
- const records = getExportRecords(sharedKey, request, options);
1932
- if (records.some((record) => record.requiresFullBundle)) return { kind: "full" };
1933
- const configured = treeShaking?.usedExports ?? [];
1934
- const result = new Set(configured);
1935
- records.forEach((record) => record.usedExports.forEach((name) => result.add(name)));
1936
- if (result.size > 0) return {
1937
- kind: "exports",
1938
- usedExports: [...result].sort()
1939
- };
1940
- return records.length > 0 ? {
1941
- kind: "exports",
1942
- usedExports: []
1943
- } : { kind: "unknown" };
1944
- }
1945
- function getTreeShakingExportUsage(request, shareItem, sharedKey, options) {
1946
- if (!shareItem?.shareConfig.treeShaking) return void 0;
1947
- return getSharedExportUsage(request, shareItem, sharedKey, options);
1948
- }
1949
- function getModuleSource(node) {
1950
- if (!node || typeof node !== "object") return void 0;
1951
- const source = node;
1952
- if (source.type === "Literal" && typeof source.value === "string") return source.value;
1953
- if (source.type === "StringLiteral" && typeof source.value === "string") return source.value;
1954
- if (source.type !== "TemplateLiteral") return void 0;
1955
- const expressions = Array.isArray(source.expressions) ? source.expressions : [];
1956
- const quasis = Array.isArray(source.quasis) ? source.quasis : [];
1957
- if (expressions.length > 0 || quasis.length !== 1) return void 0;
1958
- const value = quasis[0]?.value;
1959
- return typeof value?.cooked === "string" ? value.cooked : typeof value?.raw === "string" ? value.raw : void 0;
1960
- }
1961
- function getExportedName(node) {
1962
- if (!node || typeof node !== "object") return void 0;
1963
- const exported = node;
1964
- if (exported.type === "Identifier" && typeof exported.name === "string") return exported.name;
1965
- if ((exported.type === "Literal" || exported.type === "StringLiteral") && typeof exported.value === "string") return exported.value;
2119
+ }
2120
+ } else if (!__mfShareKey.includes(":")) {
2121
+ const __mfDefaultShareKey = "default:" + __mfShareKey;
2122
+ if (__mfModuleCache.share[__mfDefaultShareKey] === undefined) {
2123
+ __mfModuleCache.share[__mfDefaultShareKey] = __mfModuleCache.share[__mfShareKey];
2124
+ }
2125
+ }
1966
2126
  }
1967
- function isTypeOnly(node) {
1968
- return node.importKind === "type" || node.exportKind === "type";
2127
+ `;
1969
2128
  }
1970
- function forEachAstNode(root, visit) {
1971
- const stack = [root];
1972
- const seen = /* @__PURE__ */ new Set();
1973
- while (stack.length > 0) {
1974
- const value = stack.pop();
1975
- if (!value || typeof value !== "object") continue;
1976
- if (seen.has(value)) continue;
1977
- seen.add(value);
1978
- if (Array.isArray(value)) {
1979
- for (let index = value.length - 1; index >= 0; index--) stack.push(value[index]);
1980
- continue;
1981
- }
1982
- const node = value;
1983
- if (typeof node.type === "string") visit(node);
1984
- Object.entries(node).forEach(([key, child]) => {
1985
- if (key !== "parent" && key !== "loc") stack.push(child);
1986
- });
1987
- }
2129
+ function getRuntimeInitPromiseBootstrapCode(enableSsrInit = false, ownerImportId, ssrRemotes, hostInitImportId = ownerImportId) {
2130
+ return getRuntimeInitStateBootstrapCode({
2131
+ globalKeyVar: "__mfPromiseGlobalKey",
2132
+ stateVar: "__mfPromiseState",
2133
+ exposedConst: "initPromise",
2134
+ exposedProperty: "initPromise",
2135
+ enableSsrInit,
2136
+ ownerImportId,
2137
+ hostInitImportId,
2138
+ ssrRemotes
2139
+ });
1988
2140
  }
1989
- function collectImportDeclaration(node, source, record, markUnsafe) {
1990
- if (isTypeOnly(node)) return;
1991
- const specifiers = Array.isArray(node.specifiers) ? node.specifiers : [];
1992
- if (specifiers.length === 0) {
1993
- markUnsafe(source);
1994
- return;
1995
- }
1996
- const names = [];
1997
- for (const specifier of specifiers) {
1998
- if (isTypeOnly(specifier)) continue;
1999
- if (specifier.type === "ImportNamespaceSpecifier") {
2000
- markUnsafe(source);
2001
- return;
2002
- }
2003
- if (specifier.type === "ImportDefaultSpecifier") {
2004
- names.push("default");
2005
- continue;
2006
- }
2007
- if (specifier.type === "ImportSpecifier") {
2008
- const imported = specifier.imported;
2009
- if (imported?.type === "Literal" || imported?.type === "StringLiteral") {
2010
- markUnsafe(source);
2011
- return;
2012
- }
2013
- const name = getExportedName(specifier.imported);
2014
- if (!name) {
2015
- markUnsafe(source);
2016
- return;
2017
- }
2018
- names.push(name);
2019
- continue;
2020
- }
2021
- markUnsafe(source);
2022
- return;
2023
- }
2024
- record(names, source);
2141
+ function getRuntimeInitResolveBootstrapCode(enableSsrInit = false, ownerImportId, ssrRemotes, hostInitImportId = ownerImportId) {
2142
+ return getRuntimeInitStateBootstrapCode({
2143
+ globalKeyVar: "__mfResolveGlobalKey",
2144
+ stateVar: "__mfResolveState",
2145
+ exposedConst: "initResolve",
2146
+ exposedProperty: "initResolve",
2147
+ enableSsrInit,
2148
+ ownerImportId,
2149
+ hostInitImportId,
2150
+ ssrRemotes
2151
+ });
2025
2152
  }
2026
- function collectReExport(node, source, record, markUnsafe) {
2027
- if (isTypeOnly(node)) return;
2028
- if (node.type === "ExportAllDeclaration") {
2029
- markUnsafe(source);
2030
- return;
2031
- }
2032
- const specifiers = Array.isArray(node.specifiers) ? node.specifiers : [];
2033
- if (specifiers.length === 0) {
2034
- markUnsafe(source);
2035
- return;
2036
- }
2037
- const names = [];
2038
- for (const specifier of specifiers) {
2039
- if (isTypeOnly(specifier)) continue;
2040
- if (specifier.type !== "ExportSpecifier") {
2041
- markUnsafe(source);
2042
- return;
2043
- }
2044
- const local = specifier.local;
2045
- if (local?.type === "Literal" || local?.type === "StringLiteral") {
2046
- markUnsafe(source);
2047
- return;
2048
- }
2049
- const name = getExportedName(specifier.local);
2050
- if (!name) {
2051
- markUnsafe(source);
2052
- return;
2053
- }
2054
- names.push(name);
2055
- }
2056
- record(names, source);
2153
+ function writeRuntimeInitStatus(command, enableSsrInit = false, hostInitImportId, options, ssrRemotes = _ssrRemotes) {
2154
+ const exportStatement = command === "build" ? `const { initPromise, initResolve, initReject, moduleCache } = globalThis[globalKey];
2155
+ export { initPromise, initResolve, initReject, moduleCache };` : `module.exports = globalThis[globalKey];`;
2156
+ const ownerImportId = options ? getRuntimeInitStatusImportId(options) : hostInitImportId;
2157
+ getRuntimeInitModule(options).writeSync(`
2158
+ ${getRuntimeInitBootstrapCode(enableSsrInit, ownerImportId, ssrRemotes, hostInitImportId)}
2159
+ ${exportStatement}
2160
+ `);
2057
2161
  }
2058
- /**
2059
- * Collect the exports required by a consumer's ESM graph.
2060
- *
2061
- * Parsing the module avoids treating import-looking text in comments, strings,
2062
- * templates, or regular expressions as real dependencies. If parsing fails,
2063
- * every configured share whose exports are analyzed is conservatively marked
2064
- * as requiring its full export surface instead of guessing from source text.
2065
- *
2066
- * Generated federation wrappers are excluded because their imports describe
2067
- * the wrapper implementation, not the consumer's requirements.
2068
- */
2069
- function collectTreeShakingImports(code, id, shared, findSharedKey, record, markUnsafe) {
2070
- const normalizedId = normalizePathForImport(id);
2071
- if (normalizedId.includes("__prebuild__") || normalizedId.includes("__loadShare__") || normalizedId.includes("__mf_tree_shaking_graph__")) return;
2072
- let ast;
2073
- try {
2074
- ast = parseAst(code);
2075
- } catch {
2076
- Object.entries(shared).forEach(([sharedKey, shareItem]) => {
2077
- if (shouldAnalyzeSharedExports(shareItem)) markUnsafe(sharedKey, "*");
2078
- });
2079
- return;
2080
- }
2081
- const matchShared = (source) => {
2082
- const sharedKey = findSharedKey(source, shared);
2083
- return sharedKey && shouldAnalyzeSharedExports(shared[sharedKey]) ? sharedKey : void 0;
2084
- };
2085
- const recordSource = (names, source) => {
2086
- const sharedKey = matchShared(source);
2087
- if (sharedKey) record(sharedKey, names, source);
2088
- };
2089
- const markSourceUnsafe = (source) => {
2090
- const sharedKey = matchShared(source);
2091
- if (sharedKey) markUnsafe(sharedKey, source);
2092
- };
2093
- forEachAstNode(ast, (node) => {
2094
- if (node.type === "ImportDeclaration") {
2095
- const source = getModuleSource(node.source);
2096
- if (source) collectImportDeclaration(node, source, recordSource, markSourceUnsafe);
2097
- return;
2098
- }
2099
- if ((node.type === "ExportNamedDeclaration" || node.type === "ExportAllDeclaration") && node.source) {
2100
- const source = getModuleSource(node.source);
2101
- if (source) collectReExport(node, source, recordSource, markSourceUnsafe);
2102
- return;
2103
- }
2104
- if (node.type === "ImportExpression") {
2105
- const source = getModuleSource(node.source);
2106
- if (source) markSourceUnsafe(source);
2107
- return;
2108
- }
2109
- if (node.type === "CallExpression") {
2110
- const callee = node.callee;
2111
- const args = Array.isArray(node.arguments) ? node.arguments : [];
2112
- if (callee?.type === "Identifier" && callee.name === "require" && args.length > 0) {
2113
- const source = getModuleSource(args[0]);
2114
- if (source) markSourceUnsafe(source);
2115
- }
2116
- }
2117
- });
2162
+ //#endregion
2163
+ //#region src/plugins/pluginReactMixedModeGuard.ts
2164
+ function createReactMixedModeRuntimeGuard() {
2165
+ return `const __mfReactInternals = mod["__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE"];
2166
+ if (__mfReactInternals && "A" in __mfReactInternals) {
2167
+ let __mfReactDispatcher = __mfReactInternals.A;
2168
+ Object.defineProperty(__mfReactInternals, "A", {
2169
+ configurable: true,
2170
+ enumerable: true,
2171
+ get: () => __mfReactDispatcher,
2172
+ set: (next) => {
2173
+ if (next && typeof next.getOwner !== "function") next.getOwner = () => null;
2174
+ __mfReactDispatcher = next;
2175
+ },
2176
+ });
2177
+ __mfReactInternals.A = __mfReactDispatcher;
2178
+ }`;
2118
2179
  }
2119
2180
  //#endregion
2120
2181
  //#region src/utils/typeArgumentScanner.ts
@@ -2257,6 +2318,18 @@ const DEFAULT_SHARED_EXPORT_CONDITIONS = [
2257
2318
  "module",
2258
2319
  "default"
2259
2320
  ];
2321
+ function getSharedExportSource(source) {
2322
+ const parts = [];
2323
+ let offset = 0;
2324
+ const codePositions = createCodePositionMap(source, (start, end) => {
2325
+ parts.push(source.slice(offset, start), source.slice(start, end).replace(/[^\r\n\u2028\u2029]/g, " "));
2326
+ offset = end;
2327
+ });
2328
+ return {
2329
+ source: parts.length ? parts.join("") + source.slice(offset) : source,
2330
+ codePositions
2331
+ };
2332
+ }
2260
2333
  function hasCodeMatch(source, regex, codePositions) {
2261
2334
  regex.lastIndex = 0;
2262
2335
  let match;
@@ -2301,8 +2374,7 @@ function getMutableExportsFromFile(entryPath, exportConditions = DEFAULT_SHARED_
2301
2374
  if (!entryPath || visited.has(entryPath)) return [];
2302
2375
  visited.add(entryPath);
2303
2376
  try {
2304
- const source = readFileSync(entryPath, "utf-8");
2305
- const codePositions = createCodePositionMap(source);
2377
+ const { source, codePositions } = getSharedExportSource(readFileSync(entryPath, "utf-8"));
2306
2378
  const mutableBindings = /* @__PURE__ */ new Set();
2307
2379
  const mutableExports = /* @__PURE__ */ new Set();
2308
2380
  let match;
@@ -2616,7 +2688,9 @@ function hasUnsupportedBindingPattern(source, start) {
2616
2688
  }
2617
2689
  function getNamedExportsViaRegex(source, filePath, visited, scanState = { complete: true }, exportConditions = DEFAULT_SHARED_EXPORT_CONDITIONS) {
2618
2690
  const names = /* @__PURE__ */ new Set();
2619
- const codePositions = createCodePositionMap(source);
2691
+ const inspected = getSharedExportSource(source);
2692
+ source = inspected.source;
2693
+ const codePositions = inspected.codePositions;
2620
2694
  const recognizedExportStarts = /* @__PURE__ */ new Set();
2621
2695
  visited = visited || /* @__PURE__ */ new Set();
2622
2696
  if (filePath) visited.add(filePath);
@@ -3806,10 +3880,11 @@ function generateLocalSharedImportMap(options) {
3806
3880
  }
3807
3881
  `;
3808
3882
  }
3809
- /** Expand `pkg/` → package root + matching usedShares; never returns the prefix string. */
3883
+ /** Expand `pkg/` → package root (if importable) + matching usedShares; never returns the prefix string. */
3810
3884
  function expandSharedPrefixKey(prefixKey, used) {
3811
3885
  const base = prefixKey.slice(0, -1);
3812
- const expanded = /* @__PURE__ */ new Set([base]);
3886
+ const baseImportable = isPackageInstalled(base) && isPackageExportAvailable(base);
3887
+ const expanded = new Set(baseImportable ? [base] : []);
3813
3888
  for (const pkg of used) {
3814
3889
  if (pkg.endsWith("/")) continue;
3815
3890
  if (pkg === base || pkg.startsWith(`${base}/`)) expanded.add(pkg);
@@ -3987,6 +4062,8 @@ const normalizeRuntimeShareCode = `const __mfNormalizeRuntimeShare = (mod) => {
3987
4062
  };`;
3988
4063
  const sharedProviderSelectionHelperCode = `const __mfOriginalProviderKey = Symbol("mf.originalSharedProvider");
3989
4064
  const __mfResolveShareHook = { emit: (params) => params };
4065
+ const __mfGetShareScopeNames = (share) =>
4066
+ Array.isArray(share.scope) ? share.scope : [share.scope || "default"];
3990
4067
  const __mfCreateProviderSelectionVersions = (versions, strategy) => {
3991
4068
  if (strategy !== "version-first") return versions;
3992
4069
  const selectionVersions = {};
@@ -4028,7 +4105,7 @@ const sharedProviderSelectionHelperCode = `const __mfOriginalProviderKey = Symbo
4028
4105
  Object.entries(versions).filter(([, provider]) => provider?.shareConfig?.import !== false)
4029
4106
  );
4030
4107
  if (Object.keys(candidates).length === 0) return undefined;
4031
- const scopes = Array.isArray(share.scope) ? share.scope : [share.scope || "default"];
4108
+ const scopes = __mfGetShareScopeNames(share);
4032
4109
  const selectionVersions = __mfCreateProviderSelectionVersions(candidates, strategy);
4033
4110
  const shareScopeMap = {};
4034
4111
  for (const scope of scopes) {
@@ -4488,7 +4565,7 @@ function generateTreeShakingSnapshotPluginCode(enabled) {
4488
4565
  });`;
4489
4566
  }
4490
4567
  function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(options), command = "build", exportConditions) {
4491
- const needsSharedProviderSelectionHelper = Object.keys(options.shared ?? {}).length > 0;
4568
+ const needsSharedProviderSelectionHelper = hasShared(options);
4492
4569
  const hasTreeShakingShared = Object.values(options.shared ?? {}).some((share) => !!share?.shareConfig.treeShaking);
4493
4570
  const hasMultipleShareScopes = Array.isArray(options.shareScope);
4494
4571
  const guardHostAutoInit = command === "build" && isRemoteContainer(options) && hasRemotes(options);
@@ -5468,7 +5545,28 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build", options
5468
5545
  const hostInitShareBatches = toSafeJsLiteral(getShareBatches(options, false));
5469
5546
  const cacheOwner = toSafeJsLiteral(resolvedOptions.name);
5470
5547
  const preferLocalVinextReact = hasPackageDependency("vinext") && (!exportConditions?.includes("browser") || exportConditions.includes("worker"));
5548
+ const hasConfiguredShared = hasShared(resolvedOptions);
5549
+ const hostInitSharedProviderHelperImport = shouldPreloadShares && hasConfiguredShared ? "import {share as runtimeShare} from \"@module-federation/runtime/helpers\";" : "";
5550
+ const hostInitSharedProviderHelperCode = shouldPreloadShares && hasConfiguredShared ? `
5551
+ ${sharedProviderSelectionHelperCode}
5552
+ const __mfHasUsableProvider = (versions, pkg, share, scopeName) => {
5553
+ // Keep runtime singleton negotiation unchanged. A singleton already
5554
+ // registered in this scope is authoritative, even when runtime-core
5555
+ // reports a version mismatch.
5556
+ if (share.shareConfig?.singleton) {
5557
+ return Object.values(versions || {}).some(
5558
+ (provider) => provider?.shareConfig?.import !== false
5559
+ );
5560
+ }
5561
+ return Boolean(__mfSelectSharedProvider(
5562
+ versions,
5563
+ pkg,
5564
+ { ...share, scope: [scopeName] },
5565
+ ${toSafeJsLiteral(resolvedOptions.shareStrategy)}
5566
+ ));
5567
+ };` : "";
5471
5568
  return `
5569
+ ${hostInitSharedProviderHelperImport}
5472
5570
  ${getRuntimeModuleCacheBootstrapCode(exportConditions)}
5473
5571
  let hostInitPromise;
5474
5572
  async function initHost() {
@@ -5482,12 +5580,13 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build", options
5482
5580
  ${normalizeRuntimeShareCode}
5483
5581
  ${shouldPreloadShares ? `
5484
5582
  const __mfHasAlternativeSharedVersion = (pkg, share) =>
5485
- (Array.isArray(share.scope) ? share.scope : [share.scope || 'default']).some(
5583
+ __mfGetShareScopeNames(share).some(
5486
5584
  (scopeName) => Object.keys(runtime.shareScopeMap?.[scopeName]?.[pkg] || {}).some(
5487
5585
  (version) => version !== share.version
5488
5586
  )
5489
5587
  );
5490
5588
  const __mfHostInitShareBatches = ${hostInitShareBatches};
5589
+ ${hostInitSharedProviderHelperCode}
5491
5590
  for (const __mfHostInitShareBatch of __mfHostInitShareBatches) {
5492
5591
  await Promise.all(__mfHostInitShareBatch.map(async (pkg) => {
5493
5592
  const share = usedShared[pkg];
@@ -5505,18 +5604,57 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build", options
5505
5604
  )`}
5506
5605
  ) return;
5507
5606
  // An import:false share has nothing to load until a foreign provider
5508
- // registers: its own stub getter throws by construction.
5509
- if (
5510
- share.shareConfig?.import === false &&
5511
- !(Array.isArray(share.scope) ? share.scope : [share.scope || 'default']).some((scopeName) =>
5512
- Object.values(runtime.shareScopeMap?.[scopeName]?.[pkg] || {}).some(
5513
- (provider) => provider?.shareConfig?.import !== false
5514
- )
5515
- )
5516
- ) return;
5607
+ // registers: its own stub getter throws by construction. A standalone
5608
+ // container initialized on the same page keeps its providers in its
5609
+ // own runtime scope (#1307), so adopt those before giving up.
5610
+ if (share.shareConfig?.import === false) {
5611
+ const __mfScopeNames = __mfGetShareScopeNames(share);
5612
+ const __mfNeedsSiblingProvider = (scopeName) =>
5613
+ !__mfHasUsableProvider(
5614
+ runtime.shareScopeMap?.[scopeName]?.[pkg],
5615
+ pkg,
5616
+ share,
5617
+ scopeName
5618
+ );
5619
+ if (__mfScopeNames.some(__mfNeedsSiblingProvider)) {
5620
+ // loadShare() re-runs initializeSharing(), which re-registers this
5621
+ // container's own stub and lets it displace an unloaded adopted
5622
+ // provider whenever this container's name sorts after the provider's
5623
+ // (#1311). Put the provider back: a stub never outranks a provider.
5624
+ if (!runtime.__mfKeepAdoptedProviders) {
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
+ }
5638
+ for (const instance of globalThis.__FEDERATION__?.__INSTANCES__ || []) {
5639
+ for (const scopeName of __mfScopeNames) {
5640
+ const versions = instance?.shareScopeMap?.[scopeName]?.[pkg];
5641
+ if (!__mfHasUsableProvider(versions, pkg, share, scopeName)) continue;
5642
+ if (!__mfNeedsSiblingProvider(scopeName)) continue;
5643
+ const target = (runtime.shareScopeMap[scopeName] ||= {})[pkg] ||= {};
5644
+ for (const [version, provider] of Object.entries(versions)) {
5645
+ if (provider?.shareConfig?.import === false) continue;
5646
+ if (target[version] && target[version].shareConfig?.import !== false) continue;
5647
+ target[version] = provider;
5648
+ }
5649
+ }
5650
+ }
5651
+ }
5652
+ if (__mfScopeNames.every(__mfNeedsSiblingProvider)) return;
5653
+ }
5517
5654
  await runtime.loadShare(pkg, {
5518
5655
  customShareInfo: { shareConfig: share.shareConfig }
5519
5656
  }).then(async (factory) => {
5657
+ if (factory === false) return;
5520
5658
  const mod = typeof factory === "function" ? factory() : factory;
5521
5659
  let resolved = __mfNormalizeRuntimeShare(await Promise.resolve(mod));
5522
5660
  ${preferLocalVinextReact ? `if (
@@ -6100,9 +6238,6 @@ if (typeof document !== 'undefined' && document.head) {
6100
6238
  function getFirstHtmlEntryFile(entryFiles) {
6101
6239
  return entryFiles.find((file) => file.endsWith(".html"));
6102
6240
  }
6103
- function stripQueryAndHash$1(file) {
6104
- return file.split(/[?#]/)[0];
6105
- }
6106
6241
  function isReactRouterClientRouteInput(file) {
6107
6242
  return /[?&]__react-router-build-client-route(?:[=&]|$)/.test(file);
6108
6243
  }
@@ -6153,6 +6288,7 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
6153
6288
  let emitFileId;
6154
6289
  let pendingSharesEmitId;
6155
6290
  let viteConfig;
6291
+ let devServer;
6156
6292
  let skipHtmlDevFallback = forceClientInjected ?? false;
6157
6293
  let clientInjected = false;
6158
6294
  let emittedFileName;
@@ -6229,6 +6365,28 @@ const __mfCurrentScript = document.currentScript;
6229
6365
  return registration && (registration.type === "module" || registration.type === "esm") && /^(?:https?:)?\/\//.test(registration.entry) && !/\.json(?:[?#]|$)/i.test(registration.entry) ? [registration.entry] : [];
6230
6366
  })));
6231
6367
  }
6368
+ async function warmupDevEntryGraph(entryUrl) {
6369
+ const server = devServer;
6370
+ if (!server) return;
6371
+ const seen = /* @__PURE__ */ new Set();
6372
+ const cacheDir = normalizePathForImport(server.config?.cacheDir ?? "").replace(/\/$/, "") + "/";
6373
+ const visit = async (url) => {
6374
+ if (seen.has(url)) return;
6375
+ seen.add(url);
6376
+ try {
6377
+ await server.transformRequest(url);
6378
+ } catch {
6379
+ return;
6380
+ }
6381
+ const deps = [...(await server.moduleGraph.getModuleByUrl(url))?.importedModules ?? []].filter((dep) => {
6382
+ if (!dep.file || dep.type !== "js" || !path$1.isAbsolute(dep.file)) return false;
6383
+ const file = normalizePathForImport(dep.file);
6384
+ return !file.includes("/node_modules/") && !file.startsWith(cacheDir);
6385
+ });
6386
+ await Promise.all(deps.map((dep) => visit(dep.url)));
6387
+ };
6388
+ await visit(entryUrl).catch(() => {});
6389
+ }
6232
6390
  function getBootstrapSource(initSrc, entrySrc, useSystemImportFallback = false, options) {
6233
6391
  const importHelper = useSystemImportFallback ? `const __mfImport = (src) =>
6234
6392
  globalThis.System && typeof globalThis.System.import === 'function'
@@ -6345,7 +6503,7 @@ for (const __mfRemoteEntryPrefetchUrl of __mfRemoteEntryPrefetchUrls) {
6345
6503
  function isWorkspaceSourceId(id) {
6346
6504
  const normalized = normalizeModuleId(decodeViteId(id));
6347
6505
  if (normalized.startsWith("\0") || normalized.startsWith("virtual:")) return false;
6348
- const filePath = stripQueryAndHash$1(normalized);
6506
+ const filePath = stripQueryAndHash(normalized);
6349
6507
  if (filePath.startsWith("/@fs/")) return true;
6350
6508
  if (!path$1.isAbsolute(filePath)) return false;
6351
6509
  const root = normalizePathForImport(path$1.resolve(viteConfig.root));
@@ -6367,7 +6525,7 @@ for (const __mfRemoteEntryPrefetchUrl of __mfRemoteEntryPrefetchUrls) {
6367
6525
  ignoredHtmlScriptSources.add(match[1]);
6368
6526
  continue;
6369
6527
  }
6370
- const scriptSrc = stripQueryAndHash$1(match[1]);
6528
+ const scriptSrc = stripQueryAndHash(match[1]);
6371
6529
  if (/^(?:[a-z]+:)?\/\//i.test(scriptSrc)) continue;
6372
6530
  addEntryFile(scriptSrc);
6373
6531
  addEntryFile(scriptSrc.startsWith("/") ? path$1.resolve(viteConfig.root, scriptSrc.slice(1)) : path$1.resolve(path$1.dirname(htmlPath), scriptSrc));
@@ -6375,7 +6533,7 @@ for (const __mfRemoteEntryPrefetchUrl of __mfRemoteEntryPrefetchUrls) {
6375
6533
  }
6376
6534
  function addEntryRemoteImports(entrySrc) {
6377
6535
  if (!federationOptions || /^(?:[a-z]+:)?\/\//i.test(entrySrc)) return;
6378
- const file = path$1.resolve(viteConfig.root, stripQueryAndHash$1(entrySrc).replace(/^\//, ""));
6536
+ const file = path$1.resolve(viteConfig.root, stripQueryAndHash(entrySrc).replace(/^\//, ""));
6379
6537
  if (!fs$2.existsSync(file)) return;
6380
6538
  const code = fs$2.readFileSync(file, "utf-8");
6381
6539
  for (const source of findModuleImportSources(code)) {
@@ -6402,6 +6560,7 @@ for (const __mfRemoteEntryPrefetchUrl of __mfRemoteEntryPrefetchUrls) {
6402
6560
  skipTransformIds = new Set(skipTransformFor.map(resolveProjectId));
6403
6561
  },
6404
6562
  configureServer(server) {
6563
+ devServer = server;
6405
6564
  server.middlewares.use((req, res, next) => {
6406
6565
  const rawUrl = req.url?.split("#")[0] ?? "";
6407
6566
  if (normalizeDevHtmlProxyId(rawUrl.split("?")[0]) === DEV_HTML_PROXY_PREFIX.slice(0, -1)) {
@@ -6411,9 +6570,12 @@ for (const __mfRemoteEntryPrefetchUrl of __mfRemoteEntryPrefetchUrls) {
6411
6570
  const entrySrc = params.get("entry");
6412
6571
  if (initSrc && entrySrc) {
6413
6572
  const withBase = (src) => viteConfig.base + src.replace(/^\//, "");
6414
- res.statusCode = 200;
6415
- res.setHeader("Content-Type", "application/javascript");
6416
- res.end(getBootstrapSource(withBase(initSrc), withBase(entrySrc)));
6573
+ const source = getBootstrapSource(withBase(initSrc), withBase(entrySrc));
6574
+ warmupDevEntryGraph(entrySrc).finally(() => {
6575
+ res.statusCode = 200;
6576
+ res.setHeader("Content-Type", "application/javascript");
6577
+ res.end(source);
6578
+ });
6417
6579
  return;
6418
6580
  }
6419
6581
  }
@@ -6461,7 +6623,8 @@ for (const __mfRemoteEntryPrefetchUrl of __mfRemoteEntryPrefetchUrls) {
6461
6623
  const initSrc = params.get("init");
6462
6624
  const entrySrc = params.get("entry");
6463
6625
  if (!initSrc || !entrySrc) return;
6464
- return getBootstrapSource(initSrc, entrySrc);
6626
+ const source = getBootstrapSource(initSrc, entrySrc);
6627
+ return warmupDevEntryGraph(entrySrc).then(() => source);
6465
6628
  },
6466
6629
  transform(code, id) {
6467
6630
  if (id.includes("node_modules") || inject !== "html" || htmlFilePath) return;
@@ -7405,7 +7568,7 @@ function pluginExternalRuntimeCore() {
7405
7568
  }
7406
7569
  //#endregion
7407
7570
  //#region package.json
7408
- var version$1 = "1.22.0";
7571
+ var version$1 = "1.22.1";
7409
7572
  //#endregion
7410
7573
  //#region src/virtualModules/index.ts
7411
7574
  function initVirtualModules(command, remoteEntryId, enableSsrInit = false, options) {
@@ -7494,16 +7657,31 @@ const collectStaticChunks = (bundle, roots) => {
7494
7657
  };
7495
7658
  /**
7496
7659
  * Analyzes assets associated with a chunk without mutating the output map.
7497
- * The static-import traversal is cycle-safe and ignores missing bundle entries.
7660
+ * Dynamic imports are collected transitively (a lazy route nested behind another
7661
+ * lazy route is still reachable), following both static and dynamic edges.
7662
+ * The traversal is cycle-safe and ignores missing bundle entries.
7498
7663
  */
7499
7664
  const analyzeChunkAssets = (bundle, fileName, chunk) => {
7500
7665
  const dynamicAssets = [];
7501
- for (const currentChunk of collectStaticChunks(bundle, [fileName])) for (const dynamicImport of currentChunk.dynamicImports ?? []) {
7502
- if (!bundle[dynamicImport]) continue;
7503
- dynamicAssets.push({
7504
- fileName: dynamicImport,
7505
- type: isCSSFile(dynamicImport) ? "css" : "js"
7506
- });
7666
+ const visited = /* @__PURE__ */ new Set([fileName]);
7667
+ const queue = [fileName];
7668
+ const enqueue = (imported) => {
7669
+ if (visited.has(imported)) return;
7670
+ visited.add(imported);
7671
+ queue.push(imported);
7672
+ };
7673
+ for (let queueIndex = 0; queueIndex < queue.length; queueIndex++) {
7674
+ const currentChunk = bundle[queue[queueIndex]];
7675
+ if (!currentChunk || currentChunk.type !== "chunk") continue;
7676
+ for (const imported of currentChunk.imports ?? []) enqueue(imported);
7677
+ for (const dynamicImport of currentChunk.dynamicImports ?? []) {
7678
+ if (!bundle[dynamicImport]) continue;
7679
+ dynamicAssets.push({
7680
+ fileName: dynamicImport,
7681
+ type: isCSSFile(dynamicImport) ? "css" : "js"
7682
+ });
7683
+ enqueue(dynamicImport);
7684
+ }
7507
7685
  }
7508
7686
  return {
7509
7687
  importedCss: Array.from(chunk.viteMetadata?.importedCss ?? []),
@@ -8089,14 +8267,25 @@ const Manifest = (providedOptions) => {
8089
8267
  expandExposeAssets(filesMap, exposesModules, bundle, foundRemoteEntryFile, mfOptions, getIsRolldown(this));
8090
8268
  const fileToShareKey = await buildFileToShareKeyMap(getUsedShares(mfOptions), this.resolve.bind(this), mfOptions);
8091
8269
  processModuleAssets(Object.fromEntries(Object.entries(bundle).filter(([, file]) => !isTreeShakingProviderChunk(file))), filesMap, (modulePath) => fileToShareKey.get(modulePath));
8270
+ const deferredSharedAssets = {
8271
+ js: /* @__PURE__ */ new Set(),
8272
+ css: /* @__PURE__ */ new Set()
8273
+ };
8092
8274
  for (const shareKey of getUsedShares(mfOptions)) {
8093
8275
  const shareItem = getNormalizeShareItem(shareKey, mfOptions);
8094
8276
  const assets = filesMap[shareKey];
8095
8277
  if (!assets || shareItem?.shareConfig.eager === true) continue;
8096
- assets.js.async.push(...assets.js.sync.splice(0));
8097
- assets.css.async.push(...assets.css.sync.splice(0));
8278
+ for (const type of ASSET_TYPES) {
8279
+ assets[type].async.push(...assets[type].sync.splice(0));
8280
+ for (const asset of assets[type].async) deferredSharedAssets[type].add(asset);
8281
+ }
8098
8282
  }
8099
8283
  if (mfOptions.bundleAllCSS) addCssAssetsToAllExports(filesMap, allCssAssets);
8284
+ for (const exposeModule of exposesModules) {
8285
+ const assets = filesMap[exposeModule];
8286
+ if (!assets) continue;
8287
+ for (const type of ASSET_TYPES) for (const timing of LOAD_TIMINGS) assets[type][timing] = assets[type][timing].filter((asset) => !deferredSharedAssets[type].has(asset));
8288
+ }
8100
8289
  filesMap = deduplicateAssets(filesMap);
8101
8290
  }
8102
8291
  const manifest = await applyManifestAdditionalData(generateMFManifest(filesMap, disableAssetsAnalyze), void 0);
@@ -8702,6 +8891,81 @@ function pluginProxyRemotes_default(options) {
8702
8891
  };
8703
8892
  }
8704
8893
  //#endregion
8894
+ //#region src/utils/sharedSource.ts
8895
+ /** Identify shared entries through Vite, with a cache scoped to this federation instance. */
8896
+ function createSharedSourceResolver(shared, getResolutionConfig) {
8897
+ const caches = /* @__PURE__ */ new Map();
8898
+ async function matchEntry(source, suffix, resolveEntry) {
8899
+ const packageName = getPackageNameFromNodeModulePath(source);
8900
+ if (!packageName) return;
8901
+ const candidates = /* @__PURE__ */ new Set();
8902
+ if (findSharedKey(packageName, shared)) candidates.add(packageName);
8903
+ if (findSharedKey(suffix, shared)) candidates.add(suffix);
8904
+ for (const key of Object.keys(shared)) {
8905
+ if (getPackageName(key) !== packageName) continue;
8906
+ if (!key.endsWith("/")) candidates.add(key);
8907
+ for (const subpath of getCommonSharedSubpaths(key)) if (findSharedKey(subpath, shared)) candidates.add(subpath);
8908
+ }
8909
+ if (candidates.size === 0) return;
8910
+ const resolvedSource = await resolveEntry(source);
8911
+ if (!resolvedSource) return;
8912
+ for (const candidate of candidates) {
8913
+ const entry = await resolveEntry(candidate);
8914
+ if (!entry) continue;
8915
+ if (normalizeNodeModulePath(entry) === normalizeNodeModulePath(resolvedSource) || getNodeModulesSuffix(entry) === suffix) return candidate;
8916
+ }
8917
+ }
8918
+ return {
8919
+ clear() {
8920
+ caches.clear();
8921
+ },
8922
+ async resolve(context, source, options = {}) {
8923
+ if (source.startsWith("\0") || source.includes("#")) return;
8924
+ const queryIndex = source.indexOf("?");
8925
+ const query = queryIndex === -1 ? "" : source.slice(queryIndex + 1);
8926
+ if (query && [...new URLSearchParams(query).keys()].some((key) => ![
8927
+ "v",
8928
+ "t",
8929
+ "import"
8930
+ ].includes(key))) return;
8931
+ if (findSharedKey(source, shared)) return source;
8932
+ const suffix = getNodeModulesSuffix(source);
8933
+ if (!suffix) return;
8934
+ const normalizedSource = stripViteFsPrefix(normalizeNodeModulePath(source));
8935
+ const environment = context.environment ?? !!options.ssr;
8936
+ const cacheable = !options.isEntry && !options.scan && (!options.kind || options.kind === "import-statement") && Object.keys(options.attributes ?? {}).length === 0 && Object.keys(options.custom ?? {}).length === 0;
8937
+ let cache = cacheable ? caches.get(environment) : void 0;
8938
+ if (cacheable && !cache) {
8939
+ cache = /* @__PURE__ */ new Map();
8940
+ caches.set(environment, cache);
8941
+ }
8942
+ if (cache?.has(normalizedSource)) return cache.get(normalizedSource);
8943
+ const { root, conditions } = getResolutionConfig(context, options);
8944
+ const result = await matchEntry(normalizedSource, suffix, async (request) => {
8945
+ if (!path$1.isAbsolute(request) && !isPackageExportAvailable(request, {
8946
+ cwd: root,
8947
+ conditions
8948
+ })) return void 0;
8949
+ try {
8950
+ const resolved = await context.resolve(request, path$1.join(root, "package.json"), {
8951
+ ...options,
8952
+ skipSelf: true,
8953
+ custom: {
8954
+ ...options.custom,
8955
+ __mfSharedEntryLookup: true
8956
+ }
8957
+ });
8958
+ return resolved && !resolved.external ? resolved.id : void 0;
8959
+ } catch {
8960
+ return;
8961
+ }
8962
+ });
8963
+ cache?.set(normalizedSource, result);
8964
+ return result;
8965
+ }
8966
+ };
8967
+ }
8968
+ //#endregion
8705
8969
  //#region src/utils/PromiseStore.ts
8706
8970
  /**
8707
8971
  * example:
@@ -8751,23 +9015,6 @@ function isBuildConfigImporter(importer) {
8751
9015
  if (!importer) return false;
8752
9016
  return /(^|\/)(?:nuxt|vite|vitest|webpack|rollup|rspack)\.config\.[cm]?[jt]sx?$/.test(importer.replace(/\\/g, "/"));
8753
9017
  }
8754
- function findSharedKeyForSource(source, shared) {
8755
- const key = findSharedKey(source, shared);
8756
- if (key) return key;
8757
- const explicitSharedSubpathKeys = Object.keys(shared || {}).filter((sharedKey) => getPackageName(sharedKey) !== sharedKey && !sharedKey.endsWith("/"));
8758
- if (isNodeModulePath(source)) {
8759
- const explicitSubpathKey = getMatchingNodeModuleSubpath(source, explicitSharedSubpathKeys);
8760
- if (explicitSubpathKey) return explicitSubpathKey;
8761
- const normalizedSource = normalizeNodeModulePath(source);
8762
- const explicitSubpathEntryKey = explicitSharedSubpathKeys.find((sharedKey) => {
8763
- const entry = getInstalledPackageEntry(sharedKey, { cwd: getPackageDetectionCwd() });
8764
- return entry ? normalizeNodeModulePath(entry) === normalizedSource : false;
8765
- });
8766
- if (explicitSubpathEntryKey) return explicitSubpathEntryKey;
8767
- }
8768
- const packageName = getPackageNameFromNodeModulePath(source);
8769
- return packageName ? findSharedKey(packageName, shared) : void 0;
8770
- }
8771
9018
  /**
8772
9019
  * Reads the dependencies of an installed package from its package.json.
8773
9020
  */
@@ -9141,6 +9388,10 @@ function proxySharedModule(options) {
9141
9388
  ssrTarget
9142
9389
  });
9143
9390
  };
9391
+ const sharedSourceResolver = createSharedSourceResolver(shared, (context, resolveOptions) => ({
9392
+ root: _config?.root || getPackageDetectionCwd(),
9393
+ conditions: getRuntimeDependencyConditions(context, resolveOptions)
9394
+ }));
9144
9395
  const refreshTreeShakingForEnvironment = (context) => refreshTreeShakingModules(federationOptions, _command, getIsRolldown(context), getEnvironmentConditions(context));
9145
9396
  const normalizeTreeShakingOutputPath = (value) => {
9146
9397
  const normalized = normalizePathForImport(value);
@@ -9190,7 +9441,7 @@ function proxySharedModule(options) {
9190
9441
  refreshTreeShakingForEnvironment(this);
9191
9442
  const providerPackages = /* @__PURE__ */ new Set([...Object.keys(shared).filter((pkg) => !pkg.endsWith("/")), ...getUsedShares(federationOptions)]);
9192
9443
  for (const pkg of providerPackages) {
9193
- const sharedKey = findSharedKeyForSource(pkg, shared);
9444
+ const sharedKey = findSharedKey(pkg, shared);
9194
9445
  const shareItem = shared[pkg] || (sharedKey ? shared[sharedKey] : void 0);
9195
9446
  if (shareItem) emitTreeShakingProvider(this, pkg, shareItem);
9196
9447
  }
@@ -9210,6 +9461,7 @@ function proxySharedModule(options) {
9210
9461
  setTreeShakingBuildMode(command === "build", federationOptions);
9211
9462
  resetTreeShakingExports(federationOptions);
9212
9463
  emittedTreeShakingProviders.clear();
9464
+ sharedSourceResolver.clear();
9213
9465
  sharedDependencyCache.clear();
9214
9466
  dependencyManifestCache.clear();
9215
9467
  sharedRuntimeDependencyCache.clear();
@@ -9244,7 +9496,11 @@ function proxySharedModule(options) {
9244
9496
  writeLocalSharedImportMap(federationOptions);
9245
9497
  refreshHostAutoInit(federationOptions);
9246
9498
  },
9499
+ watchChange() {
9500
+ sharedSourceResolver.clear();
9501
+ },
9247
9502
  buildStart() {
9503
+ sharedSourceResolver.clear();
9248
9504
  if (_command !== "build") return;
9249
9505
  resetTreeShakingExports(federationOptions);
9250
9506
  emittedTreeShakingProviders.clear();
@@ -9253,9 +9509,12 @@ function proxySharedModule(options) {
9253
9509
  shouldTransformCachedModule() {
9254
9510
  return _command === "build" && hasAnalyzableShares;
9255
9511
  },
9256
- transform(code, id) {
9512
+ async transform(code, id, transformOptions) {
9257
9513
  if (_command !== "build" || !hasAnalyzableShares) return;
9258
- collectTreeShakingImports(code, id, shared, findSharedKeyForSource, (sharedKey, exports, request) => recordTreeShakingExports(sharedKey, exports, request, federationOptions), (sharedKey, request) => markTreeShakingPackageUnsafe(sharedKey, request, federationOptions));
9514
+ await collectTreeShakingImports(code, id, shared, async (source, shares) => {
9515
+ const request = await sharedSourceResolver.resolve(this, source, transformOptions);
9516
+ return request ? findSharedKey(request, shares) : void 0;
9517
+ }, (sharedKey, exports, request) => recordTreeShakingExports(sharedKey, exports, request, federationOptions), (sharedKey, request) => markTreeShakingPackageUnsafe(sharedKey, request, federationOptions));
9259
9518
  refreshTreeShakingForEnvironment(this);
9260
9519
  }
9261
9520
  },
@@ -9264,6 +9523,7 @@ function proxySharedModule(options) {
9264
9523
  enforce: "pre",
9265
9524
  apply: "build",
9266
9525
  async resolveId(source, importer, resolveOptions) {
9526
+ if (resolveOptions.custom?.__mfSharedEntryLookup) return;
9267
9527
  const sourceToken = getTreeShakingGraphToken(source);
9268
9528
  const importerToken = getTreeShakingGraphToken(importer);
9269
9529
  const token = sourceToken || importerToken;
@@ -9271,7 +9531,8 @@ function proxySharedModule(options) {
9271
9531
  const cleanSource = normalizePathForImport(stripTreeShakingGraphQuery(source));
9272
9532
  const cleanImporter = importer ? normalizePathForImport(stripTreeShakingGraphQuery(importer)) : void 0;
9273
9533
  if (!sourceToken && importerToken) {
9274
- const nestedSharedKey = findSharedKeyForSource(cleanSource, shared);
9534
+ const request = await sharedSourceResolver.resolve(this, cleanSource, resolveOptions);
9535
+ const nestedSharedKey = request ? findSharedKey(request, shared) : void 0;
9275
9536
  if (nestedSharedKey && getPackageName(nestedSharedKey) !== getPackageName(importerToken)) return this.resolve(cleanSource, cleanImporter, {
9276
9537
  ...resolveOptions,
9277
9538
  skipSelf: true
@@ -9298,20 +9559,22 @@ function proxySharedModule(options) {
9298
9559
  name: "proxyPreBuildShared:resolve-shared-loadShare",
9299
9560
  enforce: "pre",
9300
9561
  async resolveId(source, importer, resolveOptions) {
9301
- if (resolveOptions.custom?.__mfTreeShakingGraph) return;
9302
- function shouldSkipTaggedImporterProxy(sharedKey, tag) {
9562
+ if (resolveOptions.custom?.__mfSharedEntryLookup || resolveOptions.custom?.__mfTreeShakingGraph) return;
9563
+ const sharedSource = await sharedSourceResolver.resolve(this, source, resolveOptions);
9564
+ if (!sharedSource) return;
9565
+ const key = findSharedKey(sharedSource, shared);
9566
+ if (!key) return;
9567
+ const shouldSkipTaggedImporterProxy = (sharedKey, tag) => {
9303
9568
  if (!importer?.includes(tag)) return false;
9304
9569
  const taggedModule = VirtualModule.findModule(tag, importer);
9305
9570
  if (!taggedModule) return true;
9306
- return taggedModule.name === sharedKey || matchesSharedSource(source, taggedModule.name);
9307
- }
9308
- const key = findSharedKeyForSource(source, shared);
9309
- if (!key) return;
9571
+ return taggedModule.name === sharedKey || matchesSharedSource(sharedSource, taggedModule.name);
9572
+ };
9310
9573
  const importerPackage = getSharedPackageFromFile(importer, shared);
9311
9574
  if (importerPackage === getPackageName(key)) return;
9312
9575
  if (importerPackage && shared[key].shareConfig.import !== false) {
9313
9576
  const importerIsUnsharedWorkspacePackage = !isNodeModulePath(importer) && !Object.keys(shared).some((sharedKey) => getPackageName(sharedKey) === importerPackage);
9314
- const runtimeDependencyRequest = key.endsWith("/") && matchesSharedSource(source, key) ? source : key;
9577
+ const runtimeDependencyRequest = key.endsWith("/") && matchesSharedSource(sharedSource, key) ? sharedSource : key;
9315
9578
  if (importerIsUnsharedWorkspacePackage ? isSharedPackageRuntimeDependency(runtimeDependencyRequest, importerPackage, getRuntimeDependencyConditions(this, resolveOptions)) : isSharedPackageDependency(key, importerPackage)) return;
9316
9579
  }
9317
9580
  if (useDirectReactImport && key === "react") return;
@@ -9322,8 +9585,8 @@ function proxySharedModule(options) {
9322
9585
  if (importer && (importer.includes("hostAutoInit") || importer.includes("__H_A_I__"))) return;
9323
9586
  if (shouldSkipTaggedImporterProxy(key, "__loadShare__")) return;
9324
9587
  if (shouldSkipTaggedImporterProxy(key, "__prebuild__")) return;
9325
- const shareSource = key === "vue" && source.startsWith("vue/dist/") ? key : isNodeModulePath(source) ? getCommonSharedSubpathFromNodeModulePath(source, key) || key : source;
9326
- if (shouldKeepSharedImportLocal(source, importer, key, shared, importerPackage)) {
9588
+ const shareSource = key === "vue" && sharedSource.startsWith("vue/dist/") ? key : sharedSource;
9589
+ if (shouldKeepSharedImportLocal(sharedSource, importer, key, shared, importerPackage)) {
9327
9590
  const localSource = getPrebuildResolutionSource(shareSource, shared[key]);
9328
9591
  return tryResolveFromProjectRoot(localSource) || localSource;
9329
9592
  }
@@ -9649,7 +9912,6 @@ function pluginRemoteNamedExports(options) {
9649
9912
  const MAX_RUNNER_BODY_BYTES = 1024 * 1024;
9650
9913
  const MAX_RUNNER_START_OFFSET = 1024 * 1024;
9651
9914
  const ALLOWED_RUNNER_INVOKE_NAMES = /* @__PURE__ */ new Set(["fetchModule", "getBuiltins"]);
9652
- const VITE_FS_PREFIX = "/@fs/";
9653
9915
  function isPlainObject(value) {
9654
9916
  return !!value && typeof value === "object" && !Array.isArray(value);
9655
9917
  }
@@ -9668,12 +9930,6 @@ function isSafeRunnerFetchModuleOptions(value) {
9668
9930
  }
9669
9931
  return true;
9670
9932
  }
9671
- function stripQueryAndHash(id) {
9672
- const queryIndex = id.indexOf("?");
9673
- const hashIndex = id.indexOf("#");
9674
- const endIndex = queryIndex === -1 ? hashIndex : hashIndex === -1 ? queryIndex : Math.min(queryIndex, hashIndex);
9675
- return endIndex === -1 ? id : id.slice(0, endIndex);
9676
- }
9677
9933
  function decodeRunnerFilePath(filePath) {
9678
9934
  try {
9679
9935
  return decodeURIComponent(filePath);
@@ -9717,8 +9973,8 @@ function isSafeRunnerFetchModuleId(id, config) {
9717
9973
  const cleanId = decodeRunnerFilePath(stripQueryAndHash(decoded));
9718
9974
  if (!cleanId || hasRelativeTraversal(cleanId)) return false;
9719
9975
  const allowedDirectories = getRunnerAllowedDirectories(config);
9720
- if (cleanId.startsWith(VITE_FS_PREFIX)) {
9721
- const fsPath = `/${cleanId.slice(5)}`;
9976
+ if (cleanId.startsWith("/@fs/")) {
9977
+ const fsPath = stripViteFsPrefix(cleanId);
9722
9978
  return path$1.isAbsolute(fsPath) && isPathWithinAllowedDirectories(fsPath, allowedDirectories);
9723
9979
  }
9724
9980
  if (path$1.isAbsolute(cleanId)) {
@@ -10253,7 +10509,7 @@ function applyRuntimeCapabilityDefines(define, options, { defaultDisableSnapshot
10253
10509
  function getRuntimeCapabilityConfigurationWarnings(options) {
10254
10510
  const warnings = [];
10255
10511
  if (options.disableRemote && Object.keys(options.remotes).length > 0) warnings.push("disableRemote is true, but remotes are configured. Remote loading will be unavailable at runtime.");
10256
- if (options.disableShared && Object.keys(options.shared).length > 0) warnings.push("disableShared is true, but shared dependencies are configured. Shared dependency loading will be unavailable at runtime.");
10512
+ if (options.disableShared && hasShared(options)) warnings.push("disableShared is true, but shared dependencies are configured. Shared dependency loading will be unavailable at runtime.");
10257
10513
  return warnings;
10258
10514
  }
10259
10515
  //#endregion
@@ -10564,6 +10820,7 @@ function createEarlyVirtualModulesPlugin(options) {
10564
10820
  const resolvedConfiguredEntryFiles = (typeof buildInput === "string" ? [buildInput] : Array.isArray(buildInput) ? buildInput : buildInput && typeof buildInput === "object" ? Object.values(buildInput) : []).map((entry) => String(entry)).filter((entry) => !isReactRouterBuildClientRouteInput(entry)).map((entry) => entry.split(/[?#]/)[0]).map((entry) => path$1.isAbsolute(entry) ? entry : path$1.resolve(root, entry));
10565
10821
  resetConcreteSharedImportSourceCache();
10566
10822
  setPackageDetectionCwd(root);
10823
+ resolveSharedVersions(shared, root);
10567
10824
  const isVinext = hasPackageDependency("vinext");
10568
10825
  initVirtualModules(_command, getRemoteEntryId(options), false, options);
10569
10826
  const isRolldown = getIsRolldown(this);
@@ -10576,11 +10833,11 @@ function createEarlyVirtualModulesPlugin(options) {
10576
10833
  config.optimizeDeps.exclude.push(...Object.keys(remotes || {}));
10577
10834
  }
10578
10835
  }
10579
- if (!config.build?.ssr && (Object.keys(shared ?? {}).length > 0 || Object.keys(remotes ?? {}).length > 0)) {
10836
+ if (!config.build?.ssr && (hasShared(options) || hasRemotes(options))) {
10580
10837
  const hasJsxSource = registerEntryImports(options, root, _command === "serve", resolvedConfiguredEntryFiles);
10581
10838
  if (_command === "serve") hasClientJsxSource = hasJsxSource;
10582
10839
  }
10583
- if (shared && Object.keys(shared).length > 0) {
10840
+ if (hasShared(options)) {
10584
10841
  if (_command === "serve") {
10585
10842
  excludeSharedSubDependencies(shared);
10586
10843
  config.optimizeDeps = config.optimizeDeps || {};
@@ -10799,7 +11056,7 @@ function applyBuildTimeRuntimeDefines(define, options, { target, isAstro, defaul
10799
11056
  }
10800
11057
  function loadPluginDts(options) {
10801
11058
  if (options.dts === false) return [];
10802
- return [import("./pluginDts-D7Faa4NJ.js").then(({ default: pluginDts }) => pluginDts(options))];
11059
+ return [import("./pluginDts-CQ088qGF.js").then(({ default: pluginDts }) => pluginDts(options))];
10803
11060
  }
10804
11061
  const INJECT_EXTERNAL_RUNTIME_CORE_PLUGIN = "@module-federation/vite/injectExternalRuntimeCorePlugin";
10805
11062
  function isInjectExternalRuntimeCorePlugin(specifier) {
@@ -10980,6 +11237,7 @@ function federation(mfUserOptions) {
10980
11237
  ssrTarget = config.ssr?.target ?? "node";
10981
11238
  isProduction = config.isProduction;
10982
11239
  const ssrCapabilities = getSsrCapabilities(parseInt(version, 10), command, Object.keys(options.remotes).length > 0);
11240
+ resolveSharedVersions(shared, config.root);
10983
11241
  initVirtualModules(command, remoteEntryId, ssrCapabilities.enableSsrInitBootstrap, options);
10984
11242
  }
10985
11243
  },
@@ -11089,7 +11347,7 @@ function federation(mfUserOptions) {
11089
11347
  if (id.includes("__loadShare__")) {
11090
11348
  const pkg = getCachedLoadSharePkg(id);
11091
11349
  const key = pkg && findSharedKey(pkg, shared);
11092
- if (useCodeSplitting && key && shared[key].shareConfig.eager === true) return "loadShare-eager";
11350
+ if (key && shared[key].shareConfig.eager === true) return "loadShare-eager";
11093
11351
  if (key && shared[key].shareConfig.import === false) return null;
11094
11352
  const match = id.match(/([^/\\]+__loadShare__[^/\\]+)/);
11095
11353
  return match ? match[1] : "loadShare";
@@ -11266,7 +11524,7 @@ function federation(mfUserOptions) {
11266
11524
  config(config, { command: _command }) {
11267
11525
  const isRolldown = getIsRolldown(this);
11268
11526
  isSsrBuild = _command === "build" && Boolean(config.build?.ssr);
11269
- const needsRuntimeHelpers = Object.keys(options.shared ?? {}).length > 0;
11527
+ const needsRuntimeHelpers = hasShared(options);
11270
11528
  if (needsRuntimeHelpers) appendResolveAlias(config, {
11271
11529
  find: /^@module-federation\/runtime\/helpers$/,
11272
11530
  replacement: getRuntimeHelpersImplementation(options.implementation)