@module-federation/vite 1.17.0 → 1.18.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/lib/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as createModuleFederationError, a as getIsRolldown, b as rebaseImport, c as getPackageNameFromNodeModulePath, d as isNuxtProjectRoot, f as packageNameDecode, g as sharedCacheHelperCode, h as setPackageDetectionCwd, i as getInstalledPackageJson, l as getSharedCacheDescriptor, m as resolveImportPath, o as getPackageDetectionCwd, p as packageNameEncode, r as getInstalledPackageEntry, s as getPackageName, u as hasPackageDependency, v as mfWarn, y as normalizePathForImport } from "./pluginDts-BcvLBYP3.js";
1
+ import { _ as createModuleFederationError, a as getIsRolldown, b as rebaseImport, c as getPackageNameFromNodeModulePath, d as isNuxtProjectRoot, f as packageNameDecode, g as sharedCacheHelperCode, h as setPackageDetectionCwd, i as getInstalledPackageJson, l as getSharedCacheDescriptor, m as resolveImportPath, o as getPackageDetectionCwd, p as packageNameEncode, r as getInstalledPackageEntry, s as getPackageName, u as hasPackageDependency, v as mfWarn, y as normalizePathForImport } from "./pluginDts-CGDIZCsD.js";
2
2
  import { createRequire } from "node:module";
3
3
  import * as fs$2 from "fs";
4
4
  import { existsSync, readFileSync, realpathSync, statSync, writeFileSync } from "fs";
@@ -639,7 +639,7 @@ var VirtualModule = class VirtualModule {
639
639
  //#endregion
640
640
  //#region src/utils/ssrCapabilities.ts
641
641
  /** A browser-safe generated expression that is true only in Node.js. */
642
- const SERVER_ENV_GUARD = "typeof process !== 'undefined' && !!process.versions && !!process.versions.node";
642
+ const SERVER_ENV_GUARD = "import.meta.env.SSR";
643
643
  /**
644
644
  * Single source of truth for SSR-related feature gates.
645
645
  *
@@ -939,6 +939,145 @@ ${exportStatement}
939
939
  `);
940
940
  }
941
941
  //#endregion
942
+ //#region src/utils/codePositionMap.ts
943
+ const REGEX_PREFIX_KEYWORDS = new Set([
944
+ "await",
945
+ "case",
946
+ "delete",
947
+ "in",
948
+ "instanceof",
949
+ "new",
950
+ "return",
951
+ "throw",
952
+ "typeof",
953
+ "void",
954
+ "yield"
955
+ ]);
956
+ function isJsxClosingTagSlash(code, slashIndex) {
957
+ if (code[slashIndex - 1] !== "<") return false;
958
+ let cursor = slashIndex + 1;
959
+ while (/\s/.test(code[cursor] || "")) cursor++;
960
+ if (code[cursor] === ">") return true;
961
+ const tagStart = cursor;
962
+ while (/[-:.$_\u200C\u200D\p{ID_Continue}]/u.test(code[cursor] || "")) cursor++;
963
+ if (cursor === tagStart) return false;
964
+ while (/\s/.test(code[cursor] || "")) cursor++;
965
+ return code[cursor] === ">";
966
+ }
967
+ /** Mark comments, string/template literals, and regular expressions as non-code. */
968
+ function createCodePositionMap(code) {
969
+ const positions = Array(code.length).fill(true);
970
+ const mask = (start, end) => {
971
+ for (let index = start; index < end; index++) positions[index] = false;
972
+ };
973
+ let canStartRegex = true;
974
+ for (let index = 0; index < code.length;) {
975
+ const char = code[index];
976
+ const next = code[index + 1];
977
+ if (/\s/.test(char)) {
978
+ index++;
979
+ continue;
980
+ }
981
+ if (char === "/" && next === "/") {
982
+ const start = index;
983
+ index += 2;
984
+ while (index < code.length && code[index] !== "\n" && code[index] !== "\r") index++;
985
+ mask(start, index);
986
+ continue;
987
+ }
988
+ if (char === "/" && next === "*") {
989
+ const start = index;
990
+ index += 2;
991
+ while (index < code.length && !(code[index] === "*" && code[index + 1] === "/")) index++;
992
+ index = Math.min(code.length, index + 2);
993
+ mask(start, index);
994
+ continue;
995
+ }
996
+ if (char === "\"" || char === "'" || char === "`") {
997
+ const quote = char;
998
+ const start = index++;
999
+ while (index < code.length) {
1000
+ if (code[index] === "\\") {
1001
+ index += 2;
1002
+ continue;
1003
+ }
1004
+ if (code[index] === quote) {
1005
+ index++;
1006
+ break;
1007
+ }
1008
+ index++;
1009
+ }
1010
+ mask(start, index);
1011
+ canStartRegex = false;
1012
+ continue;
1013
+ }
1014
+ const closesJsxTag = isJsxClosingTagSlash(code, index);
1015
+ if (char === "/" && canStartRegex && !closesJsxTag) {
1016
+ const start = index;
1017
+ let cursor = index + 1;
1018
+ let escaped = false;
1019
+ let inCharacterClass = false;
1020
+ let closed = false;
1021
+ for (; cursor < code.length; cursor++) {
1022
+ const regexChar = code[cursor];
1023
+ if (regexChar === "\n" || regexChar === "\r") break;
1024
+ if (escaped) {
1025
+ escaped = false;
1026
+ continue;
1027
+ }
1028
+ if (regexChar === "\\") {
1029
+ escaped = true;
1030
+ continue;
1031
+ }
1032
+ if (regexChar === "[") {
1033
+ inCharacterClass = true;
1034
+ continue;
1035
+ }
1036
+ if (regexChar === "]" && inCharacterClass) {
1037
+ inCharacterClass = false;
1038
+ continue;
1039
+ }
1040
+ if (regexChar === "/" && !inCharacterClass) {
1041
+ cursor++;
1042
+ while (/[$_\p{ID_Continue}]/u.test(code[cursor] || "")) cursor++;
1043
+ closed = true;
1044
+ break;
1045
+ }
1046
+ }
1047
+ if (closed) {
1048
+ mask(start, cursor);
1049
+ index = cursor;
1050
+ canStartRegex = false;
1051
+ continue;
1052
+ }
1053
+ }
1054
+ if (/[$_\p{ID_Start}]/u.test(char)) {
1055
+ const start = index++;
1056
+ while (/[$_\u200C\u200D\p{ID_Continue}]/u.test(code[index] || "")) index++;
1057
+ canStartRegex = REGEX_PREFIX_KEYWORDS.has(code.slice(start, index));
1058
+ continue;
1059
+ }
1060
+ if (/\d/.test(char)) {
1061
+ index++;
1062
+ while (/[\w.]/.test(code[index] || "")) index++;
1063
+ canStartRegex = false;
1064
+ continue;
1065
+ }
1066
+ if ((char === "+" || char === "-") && next === char) {
1067
+ index += 2;
1068
+ continue;
1069
+ }
1070
+ if (char === "!" && next !== "=") {
1071
+ index++;
1072
+ continue;
1073
+ }
1074
+ if (char === ")" || char === "]" || char === "}") canStartRegex = false;
1075
+ else if (char !== ".") canStartRegex = true;
1076
+ index++;
1077
+ }
1078
+ return positions;
1079
+ }
1080
+ //#endregion
942
1081
  //#region src/utils/treeShaking.ts
943
1082
  /**
944
1083
  * Analysis is scoped by both the configured share key and the concrete module
@@ -1241,17 +1380,30 @@ function getPackageEsmEntryPath(pkg) {
1241
1380
  resolveSubpathWithRequire: false
1242
1381
  }) || resolvePackageEntryFromProjectRoot(pkg);
1243
1382
  }
1244
- function getEsmNamedExportsFromFile(entryPath) {
1383
+ function hasCodeMatch(source, regex, codePositions) {
1384
+ regex.lastIndex = 0;
1385
+ let match;
1386
+ while ((match = regex.exec(source)) !== null) if (codePositions[match.index]) return true;
1387
+ return false;
1388
+ }
1389
+ function hasCommonJsExports(source) {
1390
+ return hasCodeMatch(source, /\bmodule\s*(?:\.exports|\[\s*['"]exports['"]\s*\])|\bexports\s*(?:\.|\[|[,)]|=(?!=|>))/g, createCodePositionMap(source));
1391
+ }
1392
+ function inspectSharedExportsFromFile(entryPath) {
1245
1393
  try {
1246
- if (!entryPath) return [];
1247
- return getNamedExportsViaRegex(readFileSync(entryPath, "utf-8"), entryPath);
1394
+ if (!entryPath) return void 0;
1395
+ const source = readFileSync(entryPath, "utf-8");
1396
+ const scanState = { complete: true };
1397
+ const namedExports = getNamedExportsViaRegex(source, entryPath, void 0, scanState);
1398
+ const commonJs = hasCommonJsExports(source);
1399
+ return {
1400
+ namedExports: scanState.complete && !commonJs ? namedExports : void 0,
1401
+ commonJs
1402
+ };
1248
1403
  } catch {
1249
- return [];
1404
+ return;
1250
1405
  }
1251
1406
  }
1252
- function getEsmNamedExports(pkg) {
1253
- return getEsmNamedExportsFromFile(getPackageEsmEntryPath(pkg));
1254
- }
1255
1407
  function resolveConfiguredImportPath(importSource) {
1256
1408
  if (path$1.isAbsolute(importSource)) return resolveFileLikeModule(importSource);
1257
1409
  const projectRoot = getPackageDetectionCwd();
@@ -1332,19 +1484,156 @@ function resolveReExportModule(filePath, specifier) {
1332
1484
  return;
1333
1485
  }
1334
1486
  }
1335
- function getNamedExportsViaRegex(source, filePath, visited) {
1487
+ function hasTopLevelDeclaratorComma(source, start) {
1488
+ let depth = 0;
1489
+ let quote;
1490
+ let escaped = false;
1491
+ let canStartRegex = true;
1492
+ for (let index = start; index < source.length; index++) {
1493
+ const char = source[index];
1494
+ if (quote) {
1495
+ if (escaped) escaped = false;
1496
+ else if (char === "\\") escaped = true;
1497
+ else if (char === quote) quote = void 0;
1498
+ continue;
1499
+ }
1500
+ if (char === "\"" || char === "'" || char === "`") {
1501
+ quote = char;
1502
+ canStartRegex = false;
1503
+ continue;
1504
+ }
1505
+ if (char === "/" && source[index + 1] === "/") {
1506
+ index = source.indexOf("\n", index + 2);
1507
+ if (index === -1) return false;
1508
+ continue;
1509
+ }
1510
+ if (char === "/" && source[index + 1] === "*") {
1511
+ const commentEnd = source.indexOf("*/", index + 2);
1512
+ if (commentEnd === -1) return true;
1513
+ index = commentEnd + 1;
1514
+ continue;
1515
+ }
1516
+ if (char === "/" && canStartRegex) {
1517
+ let regexEscaped = false;
1518
+ let inCharacterClass = false;
1519
+ let closed = false;
1520
+ for (index++; index < source.length; index++) {
1521
+ const regexChar = source[index];
1522
+ if (regexEscaped) {
1523
+ regexEscaped = false;
1524
+ continue;
1525
+ }
1526
+ if (regexChar === "\\") {
1527
+ regexEscaped = true;
1528
+ continue;
1529
+ }
1530
+ if (regexChar === "[") {
1531
+ inCharacterClass = true;
1532
+ continue;
1533
+ }
1534
+ if (regexChar === "]" && inCharacterClass) {
1535
+ inCharacterClass = false;
1536
+ continue;
1537
+ }
1538
+ if (regexChar === "/" && !inCharacterClass) {
1539
+ closed = true;
1540
+ while (/[$_\p{ID_Continue}]/u.test(source[index + 1] || "")) index++;
1541
+ break;
1542
+ }
1543
+ if (regexChar === "\n" || regexChar === "\r") return true;
1544
+ }
1545
+ if (!closed) return true;
1546
+ canStartRegex = false;
1547
+ continue;
1548
+ }
1549
+ if (char === "/") {
1550
+ canStartRegex = true;
1551
+ continue;
1552
+ }
1553
+ if (/[$_\p{ID_Start}]/u.test(char)) {
1554
+ const tokenStart = index;
1555
+ while (/[$_\u200C\u200D\p{ID_Continue}]/u.test(source[index + 1] || "")) index++;
1556
+ const token = source.slice(tokenStart, index + 1);
1557
+ canStartRegex = /^(?:await|case|delete|in|instanceof|new|return|throw|typeof|void|yield)$/.test(token);
1558
+ continue;
1559
+ }
1560
+ if (/\d/.test(char)) {
1561
+ while (/[\w.]/.test(source[index + 1] || "")) index++;
1562
+ canStartRegex = false;
1563
+ continue;
1564
+ }
1565
+ if ((char === "+" || char === "-") && source[index + 1] === char) {
1566
+ index++;
1567
+ continue;
1568
+ }
1569
+ if (char === "!" && source[index + 1] !== "=") continue;
1570
+ if (char === "(" || char === "[" || char === "{") {
1571
+ depth++;
1572
+ canStartRegex = true;
1573
+ continue;
1574
+ }
1575
+ if (char === ")" || char === "]" || char === "}") {
1576
+ depth = Math.max(0, depth - 1);
1577
+ canStartRegex = false;
1578
+ continue;
1579
+ }
1580
+ if (depth === 0 && char === ",") return true;
1581
+ if (depth === 0 && char === ";") return false;
1582
+ if (!/\s/.test(char)) canStartRegex = char !== ".";
1583
+ }
1584
+ return false;
1585
+ }
1586
+ function hasUnsupportedBindingPattern(source, start) {
1587
+ const opening = source[start];
1588
+ if (opening !== "{" && opening !== "[") return false;
1589
+ let depth = 0;
1590
+ for (let index = start; index < source.length; index++) {
1591
+ const char = source[index];
1592
+ if (char === "\"" || char === "'" || char === "`") return true;
1593
+ if (char === "(" || char === "/" || char === ":" && opening === "[") return true;
1594
+ if (char === "{" || char === "[") {
1595
+ depth++;
1596
+ if (depth > 1) return true;
1597
+ continue;
1598
+ }
1599
+ if (char === "}" || char === "]") {
1600
+ depth--;
1601
+ if (depth === 0) {
1602
+ let next = index + 1;
1603
+ while (/\s/.test(source[next] || "")) next++;
1604
+ return source[next] !== "=";
1605
+ }
1606
+ }
1607
+ }
1608
+ return true;
1609
+ }
1610
+ function getNamedExportsViaRegex(source, filePath, visited, scanState = { complete: true }) {
1336
1611
  const names = /* @__PURE__ */ new Set();
1612
+ const codePositions = createCodePositionMap(source);
1613
+ const recognizedExportStarts = /* @__PURE__ */ new Set();
1337
1614
  visited = visited || /* @__PURE__ */ new Set();
1338
1615
  if (filePath) visited.add(filePath);
1339
- const declRegex = new RegExp(`export\\s+(?:async\\s+)?(?:function(?:\\*\\s*|\\s+\\*?\\s*)|const\\s+|let\\s+|var\\s+|class\\s+|enum\\s+|namespace\\s+)(${JS_IDENTIFIER_PATTERN})`, "gu");
1616
+ const declRegex = new RegExp(`export\\s+(?:async\\s+)?(?:function(?:\\*\\s*|\\s+\\*?\\s*)|const\\s+enum\\s+|const\\s+|let\\s+|var\\s+|class\\s+|abstract\\s+class\\s+|enum\\s+|namespace\\s+|module\\s+)(${JS_IDENTIFIER_PATTERN})`, "gu");
1340
1617
  let match;
1341
1618
  while ((match = declRegex.exec(source)) !== null) {
1619
+ if (!codePositions[match.index]) continue;
1620
+ recognizedExportStarts.add(match.index);
1342
1621
  const name = match[1];
1343
1622
  if (isValidEsmExportName(name)) names.add(name);
1344
1623
  }
1624
+ const exportedVariableDeclarationRegex = /export\s+(?:const|let|var)\s+/g;
1625
+ while ((match = exportedVariableDeclarationRegex.exec(source)) !== null) {
1626
+ if (!codePositions[match.index]) continue;
1627
+ if (hasTopLevelDeclaratorComma(source, exportedVariableDeclarationRegex.lastIndex)) scanState.complete = false;
1628
+ if (hasUnsupportedBindingPattern(source, exportedVariableDeclarationRegex.lastIndex)) scanState.complete = false;
1629
+ }
1630
+ if (hasCodeMatch(source, /export\s+import\s+/g, codePositions) || hasCodeMatch(source, /export\s*=/g, codePositions)) scanState.complete = false;
1631
+ if (hasCodeMatch(source, /export\s+@/g, codePositions)) scanState.complete = false;
1345
1632
  const destructureRegex = /export\s+(?:const|let|var)\s+(\{[^}]*\}|\[[^\]]*\])\s*=/g;
1346
1633
  const bindingNameRegex = new RegExp(`^(${JS_IDENTIFIER_PATTERN})`, "u");
1347
1634
  while ((match = destructureRegex.exec(source)) !== null) {
1635
+ if (!codePositions[match.index]) continue;
1636
+ recognizedExportStarts.add(match.index);
1348
1637
  const inner = match[1].slice(1, -1);
1349
1638
  for (const part of inner.split(",")) {
1350
1639
  let token = part.split("=")[0].trim();
@@ -1359,45 +1648,109 @@ function getNamedExportsViaRegex(source, filePath, visited) {
1359
1648
  const typeOnlySpecifierRegex = new RegExp(`^type\\s+${JS_IDENTIFIER_PATTERN}(?:\\s+as\\s+${JS_IDENTIFIER_PATTERN})?$`, "u");
1360
1649
  const exportSpecifierRegex = new RegExp(`(?:\\S+\\s+as\\s+)?(${JS_IDENTIFIER_PATTERN})$`, "u");
1361
1650
  while ((match = listRegex.exec(source)) !== null) {
1651
+ if (!codePositions[match.index]) continue;
1652
+ recognizedExportStarts.add(match.index);
1362
1653
  const specifiers = match[1].split(",");
1363
1654
  for (const specifier of specifiers) {
1364
1655
  const trimmed = specifier.trim();
1365
1656
  if (typeOnlySpecifierRegex.test(trimmed)) continue;
1366
1657
  const asMatch = trimmed.match(exportSpecifierRegex);
1367
- if (!asMatch) continue;
1658
+ if (!asMatch) {
1659
+ scanState.complete = false;
1660
+ continue;
1661
+ }
1368
1662
  const name = asMatch[1];
1369
1663
  if (isValidEsmExportName(name)) names.add(name);
1664
+ else scanState.complete = false;
1370
1665
  }
1371
1666
  }
1372
1667
  const namespaceReExportRegex = new RegExp(`export\\s+\\*\\s+as\\s+(${JS_IDENTIFIER_PATTERN})\\s+from\\s+['"][^'"]+['"]`, "gu");
1373
- while ((match = namespaceReExportRegex.exec(source)) !== null) if (isValidEsmExportName(match[1])) names.add(match[1]);
1668
+ while ((match = namespaceReExportRegex.exec(source)) !== null) {
1669
+ if (!codePositions[match.index]) continue;
1670
+ recognizedExportStarts.add(match.index);
1671
+ if (isValidEsmExportName(match[1])) names.add(match[1]);
1672
+ }
1673
+ if (hasCodeMatch(source, /export\s+\*\s+as\s+['"]/g, codePositions)) scanState.complete = false;
1374
1674
  if (filePath) {
1375
1675
  const starExportRegex = /export\s+\*\s+from\s+['"]([^'"]+)['"]/g;
1376
1676
  while ((match = starExportRegex.exec(source)) !== null) {
1677
+ if (!codePositions[match.index]) continue;
1678
+ recognizedExportStarts.add(match.index);
1377
1679
  const specifier = match[1];
1378
1680
  const resolvedPath = resolveReExportModule(filePath, specifier);
1379
- if (!resolvedPath || visited.has(resolvedPath)) continue;
1681
+ if (!resolvedPath) {
1682
+ scanState.complete = false;
1683
+ continue;
1684
+ }
1685
+ if (visited.has(resolvedPath)) continue;
1686
+ if (path$1.extname(resolvedPath) === ".cjs") {
1687
+ scanState.complete = false;
1688
+ continue;
1689
+ }
1380
1690
  try {
1381
- const reExportNames = getNamedExportsViaRegex(readFileSync(resolvedPath, "utf-8"), resolvedPath, visited);
1691
+ const reExportSource = readFileSync(resolvedPath, "utf-8");
1692
+ if (hasCommonJsExports(reExportSource)) {
1693
+ scanState.complete = false;
1694
+ continue;
1695
+ }
1696
+ const reExportNames = getNamedExportsViaRegex(reExportSource, resolvedPath, visited, scanState);
1382
1697
  for (const name of reExportNames) names.add(name);
1383
- } catch {}
1698
+ } catch {
1699
+ scanState.complete = false;
1700
+ }
1701
+ }
1702
+ }
1703
+ const noNamedExportRegex = /export(?:\s+default\b|\s*\{\s*\}|\s+(?:type|interface|declare)\b)/g;
1704
+ while ((match = noNamedExportRegex.exec(source)) !== null) {
1705
+ if (!codePositions[match.index]) continue;
1706
+ recognizedExportStarts.add(match.index);
1707
+ }
1708
+ const exportKeywordRegex = /\bexport\b/g;
1709
+ while ((match = exportKeywordRegex.exec(source)) !== null) {
1710
+ if (!codePositions[match.index]) continue;
1711
+ if (!recognizedExportStarts.has(match.index)) {
1712
+ scanState.complete = false;
1713
+ break;
1384
1714
  }
1385
1715
  }
1386
1716
  return Array.from(names);
1387
1717
  }
1388
- function getPackageNamedExports(pkg) {
1718
+ function getRequiredNamedExports(specifier) {
1389
1719
  try {
1390
- const mod = createRequire$1(pathToFileURL(path$1.join(getPackageDetectionCwd(), "package.json")))(pkg);
1391
- return Object.keys(mod).filter((k) => isValidEsmExportName(k));
1720
+ const mod = createRequire$1(pathToFileURL(path$1.join(getPackageDetectionCwd(), "package.json")))(specifier);
1721
+ const runtimeNamedKeys = Object.keys(mod).filter((key) => key !== "default" && key !== "__esModule");
1722
+ if (runtimeNamedKeys.some((key) => !isValidEsmExportName(key))) return void 0;
1723
+ return runtimeNamedKeys;
1392
1724
  } catch {
1393
- return getEsmNamedExports(pkg);
1725
+ return;
1726
+ }
1727
+ }
1728
+ function getPackageNamedExports(pkg) {
1729
+ const esmEntryPath = getInstalledPackageEntry(pkg, {
1730
+ conditions: [
1731
+ "browser",
1732
+ "import",
1733
+ "module",
1734
+ "default"
1735
+ ],
1736
+ resolveSubpathWithRequire: false
1737
+ });
1738
+ if (esmEntryPath) {
1739
+ const inspection = inspectSharedExportsFromFile(esmEntryPath);
1740
+ if (!inspection || inspection.commonJs || path$1.extname(esmEntryPath) === ".cjs") return getRequiredNamedExports(esmEntryPath);
1741
+ if (inspection.namedExports !== void 0) return inspection.namedExports;
1742
+ return;
1394
1743
  }
1744
+ return getRequiredNamedExports(pkg);
1395
1745
  }
1396
1746
  function getSharedNamedExports(pkg, shareItem) {
1397
1747
  const configuredImport = shareItem?.shareConfig.import;
1398
1748
  if (typeof configuredImport === "string") {
1399
- const configuredNamedExports = getEsmNamedExportsFromFile(resolveConfiguredImportPath(configuredImport));
1400
- if (configuredNamedExports.length > 0) return configuredNamedExports;
1749
+ const configuredImportPath = resolveConfiguredImportPath(configuredImport);
1750
+ const inspection = inspectSharedExportsFromFile(configuredImportPath);
1751
+ if (configuredImportPath && (inspection?.commonJs || path$1.extname(configuredImportPath) === ".cjs")) return getRequiredNamedExports(configuredImportPath);
1752
+ if (inspection?.namedExports !== void 0) return inspection.namedExports;
1753
+ return;
1401
1754
  }
1402
1755
  return getPackageNamedExports(pkg);
1403
1756
  }
@@ -1501,6 +1854,7 @@ function getDependencyNames(packageJson) {
1501
1854
  }
1502
1855
  function isSharedSingletonConsumedByPeer(pkg) {
1503
1856
  const shared = getNormalizeModuleFederationOptions()?.shared || {};
1857
+ if (Object.entries(shared).some(([key, item]) => key !== pkg && key.startsWith(`${pkg}/`) && item.shareConfig.singleton === true)) return true;
1504
1858
  const sharedKeyByPackageName = /* @__PURE__ */ new Map();
1505
1859
  Object.entries(shared).filter(([, item]) => item.shareConfig.singleton === true).forEach(([key]) => {
1506
1860
  const packageName = getPackageName(key);
@@ -1689,7 +2043,7 @@ function writePreBuildLibPath(pkg, shareItem) {
1689
2043
  `, true);
1690
2044
  return;
1691
2045
  }
1692
- const namedExports = getSharedNamedExports(pkg, shareItem);
2046
+ const namedExports = getSharedNamedExports(pkg, shareItem) ?? [];
1693
2047
  if (namedExports.length > 0) {
1694
2048
  const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
1695
2049
  const declarations = namedExports.map((name, i) => `const ${namedExportVars[i]} = __mfPrebuildExports[${escapeGeneratedStringLiteral(name)}];`).join("\n ");
@@ -1768,38 +2122,45 @@ function materializeCachedLoadShareModule(options) {
1768
2122
  function getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer) {
1769
2123
  return treeShakingConsumer ? `__mfReadTreeShakingSharedSelection(__mfModuleCache.share, ${cacheDescriptor}, ${JSON.stringify(treeShakingConsumer)})` : `__mfReadSharedCache(__mfModuleCache.share, ${cacheDescriptor})`;
1770
2124
  }
1771
- function generateEagerWorkspaceSingletonExports(namedExports, importSource, cacheDescriptor, treeShakingConsumer) {
2125
+ function generateEagerWorkspaceSingletonExports(namedExports, importSource, cacheDescriptor, cacheOwner, treeShakingConsumer) {
1772
2126
  const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
1773
- const namedExportAssignments = namedExports.length > 0 ? `\n ${namedExports.map((name, i) => `const ${namedExportVars[i]} = exportModule[${escapeGeneratedStringLiteral(name)}];`).join("\n ")}` : "";
2127
+ const declarations = namedExports.length > 0 ? ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ") : "let __mf_default;";
2128
+ const assignments = [...namedExports.map((name, i) => `${namedExportVars[i]} = mod[${escapeGeneratedStringLiteral(name)}];`), "__mf_default = mod.default ?? mod;"].join("\n ");
1774
2129
  const namedExportLine = namedExports.length > 0 ? `\n export { ${namedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
1775
2130
  return `import * as __mfLocalShare from ${escapeGeneratedStringLiteral(importSource)};
1776
2131
  let exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)};
1777
2132
  if (exportModule === undefined) {
1778
2133
  Promise.resolve().then(() => {
1779
2134
  if (__mfReadSharedCache(__mfModuleCache.share, ${cacheDescriptor}) === undefined) {
1780
- __mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, __mfNormalizeShareModule(__mfLocalShare));
2135
+ __mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, __mfNormalizeShareModule(__mfLocalShare), ${cacheOwner});
1781
2136
  }
1782
2137
  });
1783
2138
  exportModule = __mfLocalShare;
1784
2139
  }
1785
- const __mf_default = exportModule.default ?? exportModule;${namedExportAssignments}
2140
+ ${declarations}
2141
+ const __mfApplyEagerShareExports = (mod) => {
2142
+ ${assignments}
2143
+ };
2144
+ __mfSubscribeSharedCache(__mfModuleCache.share, ${cacheDescriptor}, __mfApplyEagerShareExports);
2145
+ __mfApplyEagerShareExports(exportModule);
1786
2146
  export { __mf_default as default };${namedExportLine}`;
1787
2147
  }
1788
- function generateLazyWorkspaceSingletonExports(namedExports, importSource, cacheDescriptor, treeShakingConsumer) {
2148
+ function generateLazyWorkspaceSingletonExports(namedExports, importSource, cacheDescriptor, cacheOwner, treeShakingConsumer, serveLocalFallback = false) {
1789
2149
  const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
1790
2150
  const declarations = namedExports.length > 0 ? ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ") : "let __mf_default;";
1791
2151
  const assignments = namedExports.length > 0 ? [...namedExports.map((name, i) => `${namedExportVars[i]} = mod[${escapeGeneratedStringLiteral(name)}];`), "__mf_default = mod.default ?? mod;"].join("\n ") : "__mf_default = mod.default ?? mod;";
1792
2152
  const namedExportLine = namedExports.length > 0 ? `\n export { ${namedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
1793
2153
  const applyLocalFallback = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
1794
- __mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule);
2154
+ __mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});
1795
2155
  __mfApplyLazyShareExports(exportModule);`;
1796
2156
  return `${declarations}
1797
2157
  const __mfApplyLazyShareExports = (mod) => {
1798
2158
  ${assignments}
1799
2159
  };
2160
+ __mfSubscribeSharedCache(__mfModuleCache.share, ${cacheDescriptor}, __mfApplyLazyShareExports);
1800
2161
  let exportModule = ${getSharedCacheReadExpression(cacheDescriptor, treeShakingConsumer)};
1801
2162
  if (exportModule === undefined) {
1802
- if (import.meta.env.SSR) {
2163
+ if (import.meta.env.SSR${serveLocalFallback ? " || (import.meta.env.DEV && typeof __mfLocalShare !== 'undefined')" : ""}) {
1803
2164
  ${applyLocalFallback}
1804
2165
  } else {
1805
2166
  (__mfModuleCache.pendingShareLoads ||= []).push(initPromise.then(() => {
@@ -1810,8 +2171,7 @@ function generateLazyWorkspaceSingletonExports(namedExports, importSource, cache
1810
2171
  }
1811
2172
  return import(${escapeGeneratedStringLiteral(importSource)}).then((mod) => {
1812
2173
  exportModule = __mfNormalizeShareModule(mod);
1813
- __mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule);
1814
- __mfApplyLazyShareExports(exportModule);
2174
+ __mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});
1815
2175
  });
1816
2176
  }));
1817
2177
  }
@@ -1825,7 +2185,7 @@ function prependWorkspaceSingletonSsrImport(code) {
1825
2185
  if (!code.includes("if (import.meta.env.SSR)")) return code;
1826
2186
  if (!code.includes(WORKSPACE_SINGLETON_SSR_LOCAL_SHARE)) return code;
1827
2187
  if (code.includes("import * as __mfLocalShare")) return code;
1828
- const importMatch = code.match(/initPromise\.then\(\(\)\s*=>\s*\{[\s\S]*?\breturn import\((["'])(.+?)\1\)\.then\(\(mod\)\s*=>\s*\{[\s\S]*?__mfApplyLazyShareExports/) ?? code.match(/initPromise\.then\(\(\)\s*=>\s*\n\s*import\((["'])(.+?)\1\)\.then\(\(mod\)\s*=>\s*\{[\s\S]*?__mfApplyLazyShareExports/);
2188
+ const importMatch = code.match(/initPromise\.then\(\(\)\s*=>\s*\{[\s\S]*?\breturn import\((["'])(.+?)\1\)\.then\(\(mod\)\s*=>\s*\{[\s\S]*?__mfApplyLazyShareExports/) ?? code.match(/initPromise\.then\(\(\)\s*=>\s*\n\s*import\((["'])(.+?)\1\)\.then\(\(mod\)\s*=>\s*\{[\s\S]*?__mfApplyLazyShareExports/) ?? code.match(/import\((["'])(.+?)\1\)/);
1829
2189
  if (!importMatch) return code;
1830
2190
  const quote = importMatch[1];
1831
2191
  return `import * as __mfLocalShare from ${quote}${importMatch[2]}${quote};\n${code}`;
@@ -1865,22 +2225,29 @@ function generateShareModuleUnwrapCode({ source, preserveNamedExports, stopWithR
1865
2225
  return current;`;
1866
2226
  }
1867
2227
  const normalizeLocalShareModuleCode = `const __mfNormalizeShareModule = (mod) => {
1868
- ${generateShareModuleUnwrapCode({
2228
+ const normalized = (() => {
2229
+ ${generateShareModuleUnwrapCode({
1869
2230
  source: "mod",
1870
2231
  preserveNamedExports: true
1871
2232
  })}
2233
+ })();
2234
+ return normalized && Object.getPrototypeOf(normalized) === null
2235
+ ? Object.assign({}, normalized)
2236
+ : normalized;
1872
2237
  };`;
1873
2238
  function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
1874
2239
  if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = new VirtualModule(pkg, LOAD_SHARE_TAG, ".js");
1875
2240
  let importLine = getRuntimeModuleCacheBootstrapCode();
1876
2241
  const cacheDescriptor = getSharedCacheDescriptorLiteral(pkg, shareItem);
2242
+ const cacheOwner = JSON.stringify(getNormalizeModuleFederationOptions().name);
1877
2243
  const treeShakingConsumer = command === "build" && shareItem.shareConfig.treeShaking ? getNormalizeModuleFederationOptions().name : void 0;
1878
2244
  if (shareItem.shareConfig.import === false) {
1879
- const namedExports = getPackageNamedExports(pkg);
2245
+ const detectedNamedExports = getPackageNamedExports(pkg);
2246
+ const namedExports = detectedNamedExports ?? [];
1880
2247
  let exportLine;
1881
2248
  if (namedExports.length > 0) exportLine = generateDeferredHostProvidedExports(namedExports, pkg, cacheDescriptor, treeShakingConsumer);
1882
2249
  else {
1883
- mfWarn(`Shared dependency "${pkg}" has import: false but is not installed locally.\n Named imports (e.g. import { ... } from '${pkg}') will not work in production builds.\n Install it as a devDependency to enable named export detection.`);
2250
+ if (detectedNamedExports === void 0) mfWarn(`Shared dependency "${pkg}" has import: false but is not installed locally.\n Named imports (e.g. import { ... } from '${pkg}') will not work in production builds.\n Install it as a devDependency to enable named export detection.`);
1884
2251
  exportLine = generateDeferredHostProvidedExports([], pkg, cacheDescriptor, treeShakingConsumer);
1885
2252
  }
1886
2253
  loadShareCacheMap[pkg].writeSync(`
@@ -1895,26 +2262,60 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
1895
2262
  const sharedImportSource = concreteSharedImportSource || getPreBuildLibImportId(pkg);
1896
2263
  const devImportSource = concreteSharedImportSource || pkg;
1897
2264
  const localProviderPath = getLocalProviderImportPath(pkg);
2265
+ const coherentLocalSource = concreteSharedImportSource || localProviderPath || devImportSource;
1898
2266
  const isWorkspacePackage = isWorkspacePackageEntry(pkg, localProviderPath) || isWorkspacePackageEntry(pkg, concreteSharedImportSource);
1899
2267
  const lazyLocalFallbackSource = command !== "build" ? concreteSharedImportSource || localProviderPath || devImportSource : concreteSharedImportSource || localProviderPath || sharedImportSource;
1900
2268
  const skipServePrebuildWarmup = command !== "build" && (pkg === "lit" || pkg.startsWith("lit/"));
2269
+ const detectedNamedExports = getSharedNamedExports(pkg, shareItem);
2270
+ const namedExports = detectedNamedExports ?? [];
2271
+ const hasCompleteExportCoverage = detectedNamedExports !== void 0;
1901
2272
  const isWorkspaceSingleton = isWorkspacePackage && shareItem.shareConfig.singleton === true;
1902
2273
  const isDefaultShareScope = shareItem.scope === void 0 || shareItem.scope === "default" || Array.isArray(shareItem.scope) && shareItem.scope[0] === "default";
1903
- const usesDeferredSingletonFallback = isWorkspaceSingleton || command !== "build" && isRemoteOnlyContainer() && shareItem.shareConfig.singleton === true || command === "build" && isRemoteOnlyContainer() && shareItem.shareConfig.singleton === true && !isDefaultShareScope;
2274
+ const usesDeferredSingletonFallback = hasCompleteExportCoverage && (isWorkspaceSingleton || command !== "build" && isRemoteOnlyContainer() && shareItem.shareConfig.singleton === true || command === "build" && isRemoteOnlyContainer() && shareItem.shareConfig.singleton === true && !isDefaultShareScope);
2275
+ const servesRemoteSingletonFallback = command !== "build" && isRemoteOnlyContainer() && shareItem.shareConfig.singleton === true;
1904
2276
  const isConsumedByPeerSingleton = isSharedSingletonConsumedByPeer(pkg);
1905
- const usesEntryInjectedRemoteFallback = command !== "build" && !isWorkspaceSingleton && isRemoteOnlyContainer() && shareItem.shareConfig.singleton === true && getNormalizeModuleFederationOptions().hostInitInjectLocation === "entry" && isConsumedByPeerSingleton;
1906
- const usesEagerWorkspaceFallback = isWorkspaceSingleton && isConsumedByPeerSingleton;
1907
- const usesDeferredTreeShakingFallback = Boolean(treeShakingConsumer);
1908
- const namedExports = getSharedNamedExports(pkg, shareItem);
2277
+ const usesEntryInjectedRemoteFallback = hasCompleteExportCoverage && command !== "build" && !isWorkspaceSingleton && isRemoteOnlyContainer() && shareItem.shareConfig.singleton === true && getNormalizeModuleFederationOptions().hostInitInjectLocation === "entry" && isConsumedByPeerSingleton;
2278
+ const usesEagerWorkspaceFallback = hasCompleteExportCoverage && isWorkspaceSingleton && isConsumedByPeerSingleton;
2279
+ const usesDeferredTreeShakingFallback = hasCompleteExportCoverage && Boolean(treeShakingConsumer);
1909
2280
  let exportLine;
1910
2281
  let initBlock = "";
1911
2282
  if (usesDeferredTreeShakingFallback) {
1912
2283
  importLine = `${getRuntimeInitPromiseBootstrapCode()}\n ${importLine}`;
1913
- exportLine = generateLazyWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor, treeShakingConsumer);
1914
- } else if (usesEagerWorkspaceFallback || usesEntryInjectedRemoteFallback) exportLine = generateEagerWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor, treeShakingConsumer);
2284
+ exportLine = generateLazyWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, command !== "build" && (isWorkspaceSingleton || isWorkspacePackage || servesRemoteSingletonFallback));
2285
+ } else if (usesEagerWorkspaceFallback || usesEntryInjectedRemoteFallback) exportLine = generateEagerWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer);
1915
2286
  else if (usesDeferredSingletonFallback) {
1916
2287
  importLine = `${getRuntimeInitPromiseBootstrapCode()}\n ${importLine}`;
1917
- exportLine = generateLazyWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor, treeShakingConsumer);
2288
+ exportLine = generateLazyWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, command !== "build" && (isWorkspaceSingleton || isWorkspacePackage || servesRemoteSingletonFallback));
2289
+ } else if (detectedNamedExports === void 0) {
2290
+ exportLine = `const __mfDefaultExport = (() => {
2291
+ ${generateShareModuleUnwrapCode({
2292
+ source: "__mfLocalShare",
2293
+ preserveNamedExports: false,
2294
+ stopWithReturn: "defaultExport ?? current"
2295
+ })}
2296
+ })();
2297
+ export default __mfDefaultExport;
2298
+ export * from ${escapeGeneratedStringLiteral(coherentLocalSource)}`;
2299
+ initBlock = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
2300
+ __mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});`;
2301
+ } else if (namedExports.length > 0 && shareItem.shareConfig.singleton === true) {
2302
+ const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
2303
+ exportLine = `${["let __mfDefaultExport;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ")}
2304
+ const __mfApplySharedExports = (mod) => {
2305
+ ${[...namedExports.map((name, i) => `${namedExportVars[i]} = mod[${escapeGeneratedStringLiteral(name)}];`), `__mfDefaultExport = (() => {
2306
+ ${generateShareModuleUnwrapCode({
2307
+ source: "mod",
2308
+ preserveNamedExports: false,
2309
+ stopWithReturn: "defaultExport ?? current"
2310
+ })}
2311
+ })();`].join("\n ")}
2312
+ };
2313
+ __mfSubscribeSharedCache(__mfModuleCache.share, ${cacheDescriptor}, __mfApplySharedExports);
2314
+ __mfApplySharedExports(exportModule);
2315
+ export { __mfDefaultExport as default };
2316
+ ${`export { ${namedExports.map((name, i) => `__mf_${i} as ${name}`).join(", ")} };`}`;
2317
+ initBlock = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
2318
+ __mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});`;
1918
2319
  } else if (namedExports.length > 0) {
1919
2320
  const destructure = `const { ${namedExports.map((name, i) => `${name}: __mf_${i}`).join(", ")} } = exportModule;`;
1920
2321
  const namedExportLine = `export { ${namedExports.map((name, i) => `__mf_${i} as ${name}`).join(", ")} };`;
@@ -1929,13 +2330,24 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
1929
2330
  ${destructure}
1930
2331
  ${namedExportLine}`;
1931
2332
  initBlock = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
1932
- __mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule);`;
2333
+ __mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});`;
2334
+ } else if (shareItem.shareConfig.singleton === true) {
2335
+ exportLine = `let __mfDefaultExport;
2336
+ const __mfApplySharedDefaultExport = (mod) => {
2337
+ __mfDefaultExport = mod.default ?? mod;
2338
+ };
2339
+ __mfSubscribeSharedCache(__mfModuleCache.share, ${cacheDescriptor}, __mfApplySharedDefaultExport);
2340
+ __mfApplySharedDefaultExport(exportModule);
2341
+ export { __mfDefaultExport as default };
2342
+ export * from ${escapeGeneratedStringLiteral(sharedImportSource)}`;
2343
+ initBlock = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
2344
+ __mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});`;
1933
2345
  } else {
1934
2346
  exportLine = `export default exportModule.default ?? exportModule\n export * from ${escapeGeneratedStringLiteral(sharedImportSource)}`;
1935
2347
  initBlock = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
1936
- __mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule);`;
2348
+ __mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});`;
1937
2349
  }
1938
- const prebuildImportLine = usesDeferredSingletonFallback || usesDeferredTreeShakingFallback || isWorkspacePackage && command !== "build" ? "" : `import * as __mfLocalShare from ${escapeGeneratedStringLiteral(skipServePrebuildWarmup ? devImportSource : sharedImportSource)};`;
2350
+ const prebuildImportLine = usesDeferredSingletonFallback || usesDeferredTreeShakingFallback ? servesRemoteSingletonFallback || usesDeferredSingletonFallback && command !== "build" && (isWorkspaceSingleton || isWorkspacePackage) ? `import * as __mfLocalShare from ${escapeGeneratedStringLiteral(lazyLocalFallbackSource)};` : "" : `import * as __mfLocalShare from ${escapeGeneratedStringLiteral(detectedNamedExports === void 0 ? coherentLocalSource : skipServePrebuildWarmup ? devImportSource : sharedImportSource)};`;
1939
2351
  const devDynamicImportLine = isWorkspacePackage ? "" : usesDeferredSingletonFallback || usesDeferredTreeShakingFallback ? "" : command !== "build" && !skipServePrebuildWarmup ? `;() => import(${escapeGeneratedStringLiteral(devImportSource)}).catch(() => {});` : "";
1940
2352
  const moduleBody = usesDeferredSingletonFallback || usesDeferredTreeShakingFallback ? `
1941
2353
  ${prebuildImportLine}
@@ -2021,12 +2433,15 @@ function generateLocalSharedImportMap() {
2021
2433
  ${getOrderedUsedShares().map((key) => {
2022
2434
  const shareItem = getNormalizeShareItem(key);
2023
2435
  if (!shareItem) return null;
2024
- const treeShakingUsage = getTreeShakingExportUsage(key, shareItem, shareItem.name);
2436
+ const detectedNamedExports = getSharedNamedExports(key, shareItem);
2437
+ const canLiveRebind = shareItem.shareConfig.import === false || detectedNamedExports !== void 0;
2438
+ const treeShakingConfig = canLiveRebind ? shareItem.shareConfig.treeShaking : void 0;
2439
+ const treeShakingUsage = treeShakingConfig ? getTreeShakingExportUsage(key, shareItem, shareItem.name) : void 0;
2025
2440
  const treeShakingProviderExports = treeShakingUsage?.kind === "exports" ? treeShakingUsage.usedExports : [];
2026
- const treeShakingUsedExports = options.injectTreeShakingUsedExports === false ? shareItem.shareConfig.treeShaking?.usedExports || [] : treeShakingProviderExports;
2027
- const disableRuntimeInference = shareItem.shareConfig.treeShaking?.mode === "runtime-infer" && options.injectTreeShakingUsedExports === false;
2028
- const treeShakingProviderImportId = !disableRuntimeInference && hasTreeShakingSharedProvider(key, shareItem) ? getTreeShakingSharedProviderImportId(key) : void 0;
2029
- const treeShakingStatus = treeShakingUsage?.kind === "full" || disableRuntimeInference || shareItem.shareConfig.treeShaking?.mode === "runtime-infer" && !treeShakingProviderImportId && shareItem.shareConfig.import !== false ? 0 : 1;
2441
+ const treeShakingUsedExports = options.injectTreeShakingUsedExports === false ? treeShakingConfig?.usedExports || [] : treeShakingProviderExports;
2442
+ const disableRuntimeInference = treeShakingConfig?.mode === "runtime-infer" && options.injectTreeShakingUsedExports === false;
2443
+ const treeShakingProviderImportId = treeShakingConfig && !disableRuntimeInference && hasTreeShakingSharedProvider(key, shareItem) ? getTreeShakingSharedProviderImportId(key) : void 0;
2444
+ const treeShakingStatus = treeShakingUsage?.kind === "full" || disableRuntimeInference || treeShakingConfig?.mode === "runtime-infer" && !treeShakingProviderImportId && shareItem.shareConfig.import !== false ? 0 : 1;
2030
2445
  return `
2031
2446
  ${JSON.stringify(key)}: {
2032
2447
  name: ${JSON.stringify(key)},
@@ -2035,6 +2450,7 @@ function generateLocalSharedImportMap() {
2035
2450
  loaded: false,
2036
2451
  eager: ${Boolean(shareItem.shareConfig.eager)},
2037
2452
  from: ${JSON.stringify(options.name)},
2453
+ canLiveRebind: ${canLiveRebind},
2038
2454
  async get () {
2039
2455
  if (${shareItem.shareConfig.import === false}) {
2040
2456
  throw new Error(\`[Module Federation] Shared module '\${${JSON.stringify(key)}}' must be provided by host\`);
@@ -2046,10 +2462,12 @@ function generateLocalSharedImportMap() {
2046
2462
  ? (res?.default ?? res)
2047
2463
  : {...res}
2048
2464
  // All npm packages pre-built by vite will be converted to esm
2049
- Object.defineProperty(exportModule, "__esModule", {
2050
- value: true,
2051
- enumerable: false
2052
- })
2465
+ if (exportModule.__esModule !== true) {
2466
+ Object.defineProperty(exportModule, "__esModule", {
2467
+ value: true,
2468
+ enumerable: false
2469
+ })
2470
+ }
2053
2471
  return function () {
2054
2472
  return exportModule
2055
2473
  }
@@ -2061,8 +2479,8 @@ function generateLocalSharedImportMap() {
2061
2479
  eager: ${Boolean(shareItem.shareConfig.eager)},
2062
2480
  ${shareItem.shareConfig.import === false ? "import: false," : ""}
2063
2481
  },
2064
- ${shareItem.shareConfig.treeShaking ? `treeShaking: {
2065
- mode: ${JSON.stringify(shareItem.shareConfig.treeShaking.mode)},
2482
+ ${treeShakingConfig ? `treeShaking: {
2483
+ mode: ${JSON.stringify(treeShakingConfig.mode)},
2066
2484
  usedExports: ${JSON.stringify(treeShakingUsedExports)},
2067
2485
  providedExports: ${JSON.stringify(treeShakingProviderExports)},
2068
2486
  status: ${treeShakingStatus},
@@ -2142,7 +2560,17 @@ function orderSharedDependenciesFirst(sharedPackages) {
2142
2560
  const sharedDependency = sharedKeyByPackageName.get(dependency);
2143
2561
  if (sharedDependency) visit(sharedDependency);
2144
2562
  });
2145
- if (pkg === packageName) (subpathKeysByPackageName.get(packageName) || []).forEach(visit);
2563
+ if (pkg === packageName) {
2564
+ const subpaths = subpathKeysByPackageName.get(packageName) || [];
2565
+ if (packageName === "react" || packageName === "react-dom") {
2566
+ visiting.delete(pkg);
2567
+ visited.add(pkg);
2568
+ ordered.push(pkg);
2569
+ subpaths.forEach(visit);
2570
+ return;
2571
+ }
2572
+ subpaths.forEach(visit);
2573
+ }
2146
2574
  visiting.delete(pkg);
2147
2575
  visited.add(pkg);
2148
2576
  ordered.push(pkg);
@@ -2158,16 +2586,17 @@ function getShareItemForPreload(pkg) {
2158
2586
  }
2159
2587
  function generateSharedCacheSeedItem(pkg, shareItem, importPath) {
2160
2588
  const cacheDescriptor = getSharedCacheDescriptor(pkg, shareItem);
2589
+ const cacheOwner = getNormalizeModuleFederationOptions().name;
2161
2590
  return `if (__mfReadSharedCache(__mfModuleCache.share, ${JSON.stringify(cacheDescriptor)}) === undefined) {
2162
2591
  const mod = await import(${JSON.stringify(importPath)});
2163
2592
  ${normalizeRuntimeShareCode}
2164
2593
  const normalizedModule = __mfNormalizeRuntimeShare(mod);
2165
2594
  const exportModule = normalizedModule === mod ? {...mod} : normalizedModule;
2166
- Object.defineProperty(exportModule, "__esModule", {
2595
+ if (exportModule.__esModule !== true) Object.defineProperty(exportModule, "__esModule", {
2167
2596
  value: true,
2168
2597
  enumerable: false
2169
2598
  });
2170
- __mfWriteSharedCache(__mfModuleCache.share, ${JSON.stringify(cacheDescriptor)}, exportModule);
2599
+ __mfWriteSharedCache(__mfModuleCache.share, ${JSON.stringify(cacheDescriptor)}, exportModule, ${JSON.stringify(cacheOwner)});
2171
2600
  }`;
2172
2601
  }
2173
2602
  const normalizeRuntimeShareCode = `const __mfNormalizeRuntimeShare = (mod) => {
@@ -2188,15 +2617,33 @@ const sharedProviderSelectionHelperCode = `const __mfOriginalProviderKey = Symbo
2188
2617
  const selectionVersions = {};
2189
2618
  for (const [version, provider] of Object.entries(versions)) {
2190
2619
  selectionVersions[version] = Object.assign({}, provider, {
2191
- loaded: false,
2192
- loading: undefined,
2193
- lib: undefined,
2194
2620
  [__mfOriginalProviderKey]: provider
2195
2621
  });
2196
2622
  }
2197
2623
  return selectionVersions;
2198
2624
  };
2199
- const __mfSelectSharedProvider = (versions, pkg, share, strategy) => {
2625
+ const __mfFindSharedProviderEntry = (versions, provider) => {
2626
+ if (!provider) return undefined;
2627
+ const entries = Object.entries(versions || {});
2628
+ const registeredEntry = entries.find(([, candidate]) => candidate === provider);
2629
+ if (registeredEntry) {
2630
+ return { version: registeredEntry[0], provider, registered: true };
2631
+ }
2632
+ if (typeof provider.version === "string" && provider.version) {
2633
+ return { version: provider.version, provider, registered: false };
2634
+ }
2635
+ const provenanceEntries = entries.filter(([, candidate]) =>
2636
+ candidate === provider || Boolean(provider.from && candidate?.from === provider.from)
2637
+ );
2638
+ if (provenanceEntries.length !== 1) return undefined;
2639
+ return { version: provenanceEntries[0][0], provider, registered: false };
2640
+ };
2641
+ const __mfSelectSharedProvider = (
2642
+ versions,
2643
+ pkg,
2644
+ share,
2645
+ strategy
2646
+ ) => {
2200
2647
  if (!versions || !share) return undefined;
2201
2648
  const scopes = Array.isArray(share.scope) ? share.scope : [share.scope || "default"];
2202
2649
  const selectionVersions = __mfCreateProviderSelectionVersions(versions, strategy);
@@ -2212,10 +2659,103 @@ const sharedProviderSelectionHelperCode = `const __mfOriginalProviderKey = Symbo
2212
2659
  )?.shared;
2213
2660
  return selected?.[__mfOriginalProviderKey] || selected;
2214
2661
  };`;
2215
- function hasImportFalseShared$1(options) {
2216
- return Object.values(options.shared ?? {}).some((share) => share?.shareConfig?.import === false);
2217
- }
2218
- function generateRuntimeSharedCacheSeedCode() {
2662
+ const externalSharedProviderSelectionHelperCode = `const __mfSelectExternalSharedProvider = (
2663
+ versions,
2664
+ pkg,
2665
+ localShare,
2666
+ strategy
2667
+ ) => {
2668
+ const isLocalProvider = (provider) => __mfMatchesSharedProvider(provider, localShare);
2669
+ const candidates = Object.fromEntries(
2670
+ Object.entries(versions || {}).filter(([, provider]) => !isLocalProvider(provider))
2671
+ );
2672
+ if (localShare?.version) {
2673
+ const sameVersionProvider = candidates[localShare.version];
2674
+ // Runtime registration keeps an existing same-version record,
2675
+ // even when it has only a getter and is not loaded yet. Model
2676
+ // that retained provider here so pre-init seeding cannot choose
2677
+ // the local module while loadShare() later chooses the parent.
2678
+ if (!sameVersionProvider) {
2679
+ candidates[localShare.version] = localShare;
2680
+ }
2681
+ }
2682
+ const provider = __mfSelectSharedProvider(
2683
+ candidates,
2684
+ pkg,
2685
+ localShare,
2686
+ strategy
2687
+ );
2688
+ return isLocalProvider(provider) ? undefined : provider;
2689
+ };
2690
+ const __mfMatchesSharedProvider = (provider, expected) => provider === expected || Boolean(
2691
+ expected?.from && provider?.from === expected.from
2692
+ );
2693
+ const __mfGetScopeRootProvider = (
2694
+ instances,
2695
+ scopeRoot,
2696
+ shared,
2697
+ scopeName,
2698
+ pkg,
2699
+ version,
2700
+ provider,
2701
+ passedProvider,
2702
+ strategy
2703
+ ) => {
2704
+ if (strategy !== "version-first" || !passedProvider) return undefined;
2705
+ const scopeRootProviders = scopeRoot?.options?.shared?.[pkg];
2706
+ const configuredScopeRootProvider = Array.isArray(scopeRootProviders)
2707
+ ? scopeRootProviders.find((candidate) => candidate?.version === version)
2708
+ : undefined;
2709
+ const registeredScopeRootProvider = passedProvider?.from === scopeRoot?.options?.name
2710
+ ? passedProvider
2711
+ : undefined;
2712
+ const scopeRootProvider = registeredScopeRootProvider || (
2713
+ __mfMatchesSharedProvider(configuredScopeRootProvider, passedProvider)
2714
+ ? configuredScopeRootProvider
2715
+ // A plain Webpack/Rspack host has no enhanced-runtime instance.
2716
+ // Its pre-init snapshot is still authoritative when this remote's
2717
+ // registration rewrites the same-version provider in-place.
2718
+ : scopeRoot ? undefined : passedProvider
2719
+ );
2720
+ if (!scopeRootProvider) return undefined;
2721
+ const selectedFromLaterInstance = instances.some((instance) =>
2722
+ instance !== scopeRoot &&
2723
+ instance?.options?.name === provider?.from &&
2724
+ instance?.shareScopeMap?.[scopeName] === shared
2725
+ );
2726
+ return selectedFromLaterInstance ? scopeRootProvider : undefined;
2727
+ };
2728
+ const __mfResolveExternalSharedProvider = (
2729
+ instances,
2730
+ scopeRoot,
2731
+ shared,
2732
+ scopeName,
2733
+ pkg,
2734
+ providerEntry,
2735
+ selectedExternalProvider,
2736
+ passedProvider,
2737
+ strategy
2738
+ ) => {
2739
+ const scopeRootProvider = providerEntry.registered ? __mfGetScopeRootProvider(
2740
+ instances,
2741
+ scopeRoot,
2742
+ shared,
2743
+ scopeName,
2744
+ pkg,
2745
+ providerEntry.version,
2746
+ providerEntry.provider,
2747
+ passedProvider,
2748
+ strategy
2749
+ ) : undefined;
2750
+ const provider = scopeRootProvider || selectedExternalProvider;
2751
+ if (!provider) return undefined;
2752
+ if (
2753
+ providerEntry.registered &&
2754
+ !__mfMatchesSharedProvider(provider, passedProvider)
2755
+ ) return undefined;
2756
+ return { provider, scopeRootProvider };
2757
+ };`;
2758
+ function generateRuntimeSharedCacheSeedCode(shareStrategy) {
2219
2759
  const seedOrder = getOrderedUsedShares();
2220
2760
  return `
2221
2761
  const __mfSeedOrder = ${JSON.stringify(seedOrder)};
@@ -2241,34 +2781,99 @@ function generateRuntimeSharedCacheSeedCode() {
2241
2781
  }
2242
2782
  __mfSeedKeys.splice(insertIndex, 0, pkg);
2243
2783
  }
2244
- for (const pkg of __mfSeedKeys) {
2245
- const share = usedShared[pkg];
2246
- const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
2247
- if (
2248
- share.shareConfig?.import === false ||
2249
- Boolean(share.treeShaking) ||
2250
- __mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) !== undefined
2251
- ) {
2252
- continue;
2253
- }
2254
- const singletonCacheDescriptor = __mfGetSharedCacheDescriptor(pkg, true, share.version, share.scope);
2255
- const singletonModule = __mfReadSharedCache(__mfModuleCache.share, singletonCacheDescriptor);
2256
- if (singletonModule !== undefined) {
2257
- __mfWriteSharedCache(__mfModuleCache.share, cacheDescriptor, singletonModule);
2258
- continue;
2784
+ var __mfSeedLocalShared = async (seedKeys) => {
2785
+ for (const pkg of seedKeys) {
2786
+ const share = usedShared[pkg];
2787
+ const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
2788
+ if (
2789
+ share.shareConfig?.import === false ||
2790
+ Boolean(share.treeShaking) ||
2791
+ __mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) !== undefined
2792
+ ) {
2793
+ continue;
2794
+ }
2795
+ const singletonCacheDescriptor = __mfGetSharedCacheDescriptor(pkg, true, share.version, share.scope);
2796
+ const singletonModule = __mfReadSharedCache(__mfModuleCache.share, singletonCacheDescriptor);
2797
+ if (singletonModule !== undefined) {
2798
+ __mfWriteSharedCache(
2799
+ __mfModuleCache.share,
2800
+ cacheDescriptor,
2801
+ singletonModule,
2802
+ __mfReadSharedCacheOwner(__mfModuleCache.share, singletonCacheDescriptor)
2803
+ );
2804
+ continue;
2805
+ }
2806
+ const factory = await share.get();
2807
+ const mod = typeof factory === "function" ? factory() : factory;
2808
+ const resolved = await Promise.resolve(mod);
2809
+ ${normalizeRuntimeShareCode}
2810
+ const normalizedModule = __mfNormalizeRuntimeShare(resolved);
2811
+ const exportModule = normalizedModule === resolved ? {...resolved} : normalizedModule;
2812
+ if (exportModule.__esModule !== true) Object.defineProperty(exportModule, "__esModule", {
2813
+ value: true,
2814
+ enumerable: false
2815
+ });
2816
+ __mfWriteSharedCache(__mfModuleCache.share, cacheDescriptor, exportModule, mfName);
2259
2817
  }
2260
- const factory = await share.get();
2261
- const mod = typeof factory === "function" ? factory() : factory;
2262
- const resolved = await Promise.resolve(mod);
2263
- ${normalizeRuntimeShareCode}
2264
- const normalizedModule = __mfNormalizeRuntimeShare(resolved);
2265
- const exportModule = normalizedModule === resolved ? {...resolved} : normalizedModule;
2266
- Object.defineProperty(exportModule, "__esModule", {
2267
- value: true,
2268
- enumerable: false
2269
- });
2270
- __mfWriteSharedCache(__mfModuleCache.share, cacheDescriptor, exportModule);
2271
- }`;
2818
+ };
2819
+ const __mfIsRuntimeOnlySharePending = (pkg) => {
2820
+ const share = usedShared[pkg];
2821
+ if (!share.treeShaking && share.shareConfig?.import !== false) return false;
2822
+ const cacheDescriptor = __mfGetSharedCacheDescriptor(
2823
+ pkg,
2824
+ share.shareConfig?.singleton,
2825
+ share.version,
2826
+ share.scope
2827
+ );
2828
+ return share.treeShaking
2829
+ ? (
2830
+ __mfReadTreeShakingSharedSelection(
2831
+ __mfModuleCache.share,
2832
+ cacheDescriptor,
2833
+ mfName
2834
+ ) === undefined &&
2835
+ __mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) === undefined
2836
+ )
2837
+ : __mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) === undefined;
2838
+ };
2839
+ const __mfNeedsPreInitSeedBarrier = (pkg) => {
2840
+ const share = usedShared[pkg];
2841
+ const cacheDescriptor = __mfGetSharedCacheDescriptor(
2842
+ pkg,
2843
+ share.shareConfig?.singleton,
2844
+ share.version,
2845
+ share.scope
2846
+ );
2847
+ const cachedShare = share.treeShaking
2848
+ ? (
2849
+ __mfReadTreeShakingSharedSelection(
2850
+ __mfModuleCache.share,
2851
+ cacheDescriptor,
2852
+ mfName
2853
+ ) ?? __mfReadSharedCache(__mfModuleCache.share, cacheDescriptor)
2854
+ )
2855
+ : __mfReadSharedCache(__mfModuleCache.share, cacheDescriptor);
2856
+ if (cachedShare !== undefined) return false;
2857
+ if (share.treeShaking || share.shareConfig?.import === false) return true;
2858
+ if (!share.shareConfig?.singleton) return false;
2859
+ if (typeof __mfSelectExternalSharedProvider !== 'function') return false;
2860
+ return Boolean(__mfSelectExternalSharedProvider(
2861
+ initialShared[pkg],
2862
+ pkg,
2863
+ share,
2864
+ ${JSON.stringify(shareStrategy)}
2865
+ ));
2866
+ };
2867
+ const __mfFirstRuntimeSeedBarrierIndex = __mfSeedKeys.findIndex(
2868
+ __mfNeedsPreInitSeedBarrier
2869
+ );
2870
+ const __mfImmediateSeedKeys = __mfFirstRuntimeSeedBarrierIndex === -1
2871
+ ? __mfSeedKeys
2872
+ : __mfSeedKeys.slice(0, __mfFirstRuntimeSeedBarrierIndex);
2873
+ var __mfDeferredSeedKeys = __mfFirstRuntimeSeedBarrierIndex === -1
2874
+ ? []
2875
+ : __mfSeedKeys.slice(__mfFirstRuntimeSeedBarrierIndex);
2876
+ await __mfSeedLocalShared(__mfImmediateSeedKeys);`;
2272
2877
  }
2273
2878
  function getBrowserImportPath(importPath) {
2274
2879
  if (/^(?:[a-zA-Z]:[\\/]|\/)/.test(importPath) && !importPath.startsWith("/@")) return `/@fs/${importPath}`;
@@ -2300,15 +2905,15 @@ const SSR_ONLY_PLUGIN_SPECIFIERS = new Set(["@module-federation/vite/ssrEntryLoa
2300
2905
  const isSsrOnlyPlugin = (importStatement) => [...SSR_ONLY_PLUGIN_SPECIFIERS].some((s) => importStatement.includes(s));
2301
2906
  const getSsrOnlyPluginSpecifier = (importStatement) => [...SSR_ONLY_PLUGIN_SPECIFIERS].find((s) => importStatement.includes(s));
2302
2907
  function generateTreeShakingSharedResolutionCode(enabled) {
2303
- if (!enabled) return "";
2908
+ if (!enabled) return "const __mfResolveTreeShakingShared = async () => {};";
2304
2909
  return `
2305
2910
  // Resolve tree-enabled shares through the Runtime after all providers have
2306
2911
  // registered. Partial providers are stored with their export coverage and
2307
2912
  // never occupy generic/legacy cache keys, which are reserved for complete
2308
2913
  // modules only.
2309
- for (const [pkg, share] of Object.entries(usedShared)) {
2914
+ const __mfResolveTreeShakingShared = async (pkg, share) => {
2310
2915
  const treeShaking = share.treeShaking;
2311
- if (!treeShaking) continue;
2916
+ if (!treeShaking) return;
2312
2917
  try {
2313
2918
  const factory = await initRes.loadShare(pkg, {
2314
2919
  customShareInfo: {
@@ -2320,22 +2925,21 @@ function generateTreeShakingSharedResolutionCode(enabled) {
2320
2925
  },
2321
2926
  },
2322
2927
  });
2323
- if (factory === false) continue;
2928
+ if (factory === false) return;
2324
2929
  const mod = typeof factory === "function" ? factory() : factory;
2325
2930
  const resolved = await Promise.resolve(mod);
2326
2931
  ${normalizeRuntimeShareCode}
2327
2932
  const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
2328
2933
  const normalizedShared = __mfNormalizeRuntimeShare(resolved);
2934
+ const providedExports = treeShaking.providedExports ?? treeShaking.usedExports ?? [];
2329
2935
  const hasPartialProvider =
2330
- Array.isArray(treeShaking.providedExports) &&
2331
- treeShaking.providedExports.length > 0 &&
2332
2936
  ((treeShaking.mode === "runtime-infer" && treeShaking.status !== 0) ||
2333
2937
  treeShaking.status === 2);
2334
2938
  if (hasPartialProvider) {
2335
2939
  __mfWriteTreeShakingSharedCache(
2336
2940
  __mfModuleCache.share,
2337
2941
  cacheDescriptor,
2338
- treeShaking.providedExports,
2942
+ providedExports,
2339
2943
  normalizedShared
2340
2944
  );
2341
2945
  __mfWriteTreeShakingSharedSelection(
@@ -2350,18 +2954,18 @@ function generateTreeShakingSharedResolutionCode(enabled) {
2350
2954
  } catch (e) {
2351
2955
  console.warn('[Module Federation] Failed to load tree-shaken shared module', pkg, e);
2352
2956
  }
2353
- }`;
2957
+ };`;
2354
2958
  }
2355
- const treeShakingResolveShareBodyCode = `const originalResolver = args.resolver;
2959
+ const treeShakingResolveShareBodyCode = `const consumerTreeShaking = args.shareInfo?.treeShaking;
2960
+ if (consumerTreeShaking?.mode !== "runtime-infer") return args;
2961
+ const requiredExports = consumerTreeShaking.usedExports;
2962
+ if (!Array.isArray(requiredExports)) return args;
2963
+
2964
+ const originalResolver = args.resolver;
2356
2965
  args.resolver = () => {
2357
2966
  const resolved = originalResolver();
2358
2967
  if (!resolved?.useTreesShaking) return resolved;
2359
2968
 
2360
- const consumerTreeShaking = args.shareInfo?.treeShaking;
2361
- if (consumerTreeShaking?.mode !== "runtime-infer") return resolved;
2362
- const requiredExports = consumerTreeShaking.usedExports;
2363
- if (!Array.isArray(requiredExports)) return resolved;
2364
-
2365
2969
  const selectedExports = resolved.shared?.treeShaking?.usedExports;
2366
2970
  const selectedMatches = Array.isArray(selectedExports) &&
2367
2971
  requiredExports.every((name) => selectedExports.includes(name));
@@ -2460,9 +3064,10 @@ function generateTreeShakingSnapshotPluginCode(enabled) {
2460
3064
  });`;
2461
3065
  }
2462
3066
  function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(options), command = "build") {
2463
- const needsSharedProviderSelectionHelper = hasImportFalseShared$1(options);
3067
+ const needsSharedProviderSelectionHelper = Object.keys(options.shared ?? {}).length > 0;
2464
3068
  const hasTreeShakingShared = Object.values(options.shared ?? {}).some((share) => !!share?.shareConfig.treeShaking);
2465
3069
  const hasEagerShared = Object.values(options.shared ?? {}).some((share) => share?.shareConfig.eager === true && share.shareConfig.import !== false);
3070
+ const hasMultipleShareScopes = Array.isArray(options.shareScope);
2466
3071
  const runtimeImports = [
2467
3072
  "init as runtimeInit",
2468
3073
  "loadRemote",
@@ -2481,6 +3086,29 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
2481
3086
  serializeRuntimeOptions(p[1])
2482
3087
  ];
2483
3088
  });
3089
+ const initializeSharingCode = hasMultipleShareScopes ? `for (const shareScopeName of shareScopeNamesToInitialize) {
3090
+ try {
3091
+ await retrySharedInit(async () => {
3092
+ await Promise.all(await initRes.initializeSharing(shareScopeName, {
3093
+ strategy: '${options.shareStrategy}',
3094
+ from: "build",
3095
+ initScope
3096
+ }));
3097
+ });
3098
+ } catch (e) {
3099
+ console.error('[Module Federation]', e)
3100
+ }
3101
+ }` : `try {
3102
+ await retrySharedInit(async () => {
3103
+ await Promise.all(await initRes.initializeSharing('${options.shareScope}', {
3104
+ strategy: '${options.shareStrategy}',
3105
+ from: "build",
3106
+ initScope
3107
+ }));
3108
+ });
3109
+ } catch (e) {
3110
+ console.error('[Module Federation]', e)
3111
+ }`;
2484
3112
  return `
2485
3113
  // Shim Vue HMR runtime for dev-compiled components loaded by a non-Vite host.
2486
3114
  // When a remote is served by a Vite dev server, Vue's SFC compiler injects HMR
@@ -2497,7 +3125,8 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
2497
3125
  ${command === "build" ? getRuntimeInitResolveBootstrapCode() : getRuntimeInitBootstrapCode() + "\n const { initResolve } = globalThis[globalKey];"}
2498
3126
  ${getRuntimeModuleCacheBootstrapCode()}
2499
3127
  const initTokens = {}
2500
- const shareScopeName = ${JSON.stringify(options.shareScope)}
3128
+ const shareScopeNames = Array.isArray(${JSON.stringify(options.shareScope)}) ? ${JSON.stringify(options.shareScope)} : [${JSON.stringify(options.shareScope)}]
3129
+ const shareScopeName = ${JSON.stringify(hasMultipleShareScopes ? options.shareScope[0] : options.shareScope)}
2501
3130
  const mfName = ${JSON.stringify(options.name)}
2502
3131
  let localSharedImportMapPromise
2503
3132
  let exposesMapPromise
@@ -2522,6 +3151,7 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
2522
3151
  }
2523
3152
  ${generateTreeShakingSnapshotPluginCode(hasTreeShakingShared)}
2524
3153
  ${needsSharedProviderSelectionHelper ? sharedProviderSelectionHelperCode : ""}
3154
+ ${needsSharedProviderSelectionHelper ? externalSharedProviderSelectionHelperCode : ""}
2525
3155
 
2526
3156
  async function getLocalSharedImportMap() {
2527
3157
  ${hasEagerShared ? "return __mfLocalSharedImportMap;" : ""}
@@ -2543,53 +3173,67 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
2543
3173
 
2544
3174
  async function init(shared = {}, initScope = []) {
2545
3175
  ${sharedCacheHelperCode}
2546
- const {usedShared, usedRemotes} = await getLocalSharedImportMap()
2547
- try {
2548
- const allInstances = globalThis.__FEDERATION__?.__SHARE__;
2549
- if (allInstances) {
2550
- ${normalizeRuntimeShareCode}
2551
- for (const [, scopes] of Object.entries(allInstances)) {
2552
- const scopeShare = scopes?.['${options.shareScope}'];
2553
- if (!scopeShare) continue;
2554
- for (const [pkg, versionMap] of Object.entries(scopeShare)) {
2555
- const usedShare = usedShared?.[pkg];
2556
- const selectedProvider = usedShare?.shareConfig?.import === false
2557
- ? __mfSelectSharedProvider(versionMap, pkg, usedShare, '${options.shareStrategy}')
2558
- : undefined;
2559
- const providerEntries = usedShare?.shareConfig?.import === false
2560
- ? Object.entries(versionMap).filter(([, provider]) => provider === selectedProvider)
2561
- : Object.entries(versionMap);
2562
- for (const [version, provider] of providerEntries) {
2563
- if (!provider.lib) continue;
2564
- const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, provider.shareConfig?.singleton, version, ${JSON.stringify(options.shareScope)});
2565
- if (__mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) !== undefined) continue;
2566
- const mod = typeof provider.lib === "function" ? provider.lib() : provider.lib;
2567
- const resolved = await Promise.resolve(mod);
2568
- const normalized = __mfNormalizeRuntimeShare(resolved);
2569
- __mfWriteSharedCache(__mfModuleCache.share, cacheDescriptor, normalized);
2570
- if (provider.shareConfig?.singleton && usedShare) {
2571
- const usedCacheDescriptor = __mfGetSharedCacheDescriptor(pkg, usedShare.shareConfig?.singleton, usedShare.version, usedShare.scope);
2572
- if (__mfReadSharedCache(__mfModuleCache.share, usedCacheDescriptor) === undefined) {
2573
- __mfWriteSharedCache(__mfModuleCache.share, usedCacheDescriptor, normalized);
2574
- }
2575
- }
2576
- }
2577
- }
3176
+ const getShareScope = (scopeName) => ${hasMultipleShareScopes} ? (shared?.[scopeName] || {}) : shared;
3177
+ const getShareScopeNames = (share) => {
3178
+ const configuredScopes = Array.isArray(share?.scope) ? share.scope : [share?.scope || shareScopeName];
3179
+ if (!${hasMultipleShareScopes}) return configuredScopes;
3180
+ return [...new Set([...configuredScopes, ...shareScopeNames])];
3181
+ };
3182
+ const getShareScopeName = (pkg, share) => {
3183
+ for (const scopeName of getShareScopeNames(share)) {
3184
+ if (getShareScope(scopeName)?.[pkg]) return scopeName;
3185
+ }
3186
+ return shareScopeName;
3187
+ };
3188
+ const getShareVersions = (pkg, share) => {
3189
+ for (const scopeName of getShareScopeNames(share)) {
3190
+ const versions = getShareScope(scopeName)?.[pkg];
3191
+ if (versions) return versions;
3192
+ }
3193
+ return getShareScope(shareScopeName)?.[pkg];
3194
+ };
3195
+ const federationInstances = globalThis.__FEDERATION__?.__INSTANCES__ || [];
3196
+ const initRootName = initScope.find((token) => token?.from)?.from;
3197
+ const scopeRoot = federationInstances.find((instance) =>
3198
+ instance?.options?.name === initRootName &&
3199
+ ${hasMultipleShareScopes ? "shareScopeNames.some((scopeName) => instance?.shareScopeMap?.[scopeName] === getShareScope(scopeName))" : `instance?.shareScopeMap?.['${options.shareScope}'] === shared`}
3200
+ ) || federationInstances.find((instance) =>
3201
+ instance?.options?.name !== mfName &&
3202
+ ${hasMultipleShareScopes ? "shareScopeNames.some((scopeName) => instance?.shareScopeMap?.[scopeName] === getShareScope(scopeName))" : `instance?.shareScopeMap?.['${options.shareScope}'] === shared`}
3203
+ );
3204
+ const initialShared = Object.create(null);
3205
+ ${hasMultipleShareScopes ? `for (const scopeName of shareScopeNames) {
3206
+ for (const [pkg, versions] of Object.entries(getShareScope(scopeName))) {
3207
+ if (initialShared[pkg]) continue;
3208
+ const initialVersions = initialShared[pkg] = Object.create(null);
3209
+ for (const [version, provider] of Object.entries(versions)) {
3210
+ initialVersions[version] = Object.assign({}, provider);
2578
3211
  }
2579
3212
  }
2580
- } catch (e) {
2581
- console.error('[Module Federation] Failed to bridge external shared modules', e)
2582
- }
2583
- for (const [pkg, share] of Object.entries(usedShared)) {
2584
- const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
2585
- if (__mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) !== undefined) continue;
2586
- const singletonCacheDescriptor = __mfGetSharedCacheDescriptor(pkg, true, share.version, share.scope);
2587
- const singletonModule = __mfReadSharedCache(__mfModuleCache.share, singletonCacheDescriptor);
2588
- if (singletonModule !== undefined) {
2589
- __mfWriteSharedCache(__mfModuleCache.share, cacheDescriptor, singletonModule);
3213
+ }` : `for (const [pkg, versions] of Object.entries(shared)) {
3214
+ const initialVersions = initialShared[pkg] = Object.create(null);
3215
+ for (const [version, provider] of Object.entries(versions)) {
3216
+ // Runtime registration mutates provider records in-place, notably their origin.
3217
+ // Preserve the parent-visible provider and its original provenance.
3218
+ initialVersions[version] = Object.assign({}, provider);
2590
3219
  }
3220
+ }`}
3221
+ const {usedShared, usedRemotes} = await getLocalSharedImportMap()
3222
+ // handling circular init calls before an external provider can re-enter this container
3223
+ ${hasMultipleShareScopes ? `const shareScopeNamesToInitialize = [];
3224
+ for (const shareScopeName of shareScopeNames) {
3225
+ let initToken = initTokens[shareScopeName];
3226
+ if (!initToken) initToken = initTokens[shareScopeName] = { from: mfName };
3227
+ if (initScope.indexOf(initToken) >= 0) continue;
3228
+ initScope.push(initToken);
3229
+ shareScopeNamesToInitialize.push(shareScopeName);
2591
3230
  }
2592
- ${generateRuntimeSharedCacheSeedCode()}
3231
+ if (shareScopeNamesToInitialize.length === 0) return;` : `var initToken = initTokens[shareScopeName];
3232
+ if (!initToken)
3233
+ initToken = initTokens[shareScopeName] = { from: mfName };
3234
+ if (initScope.indexOf(initToken) >= 0) return;
3235
+ initScope.push(initToken);`}
3236
+ ${normalizeRuntimeShareCode}
2593
3237
  const __browserPlugins = [${pluginImportNames.filter((item) => !isSsrOnlyPlugin(item[1])).map((item) => `${item[0]}(${item[2]})`).join(", ")}];
2594
3238
  const __ssrPlugins = typeof globalThis.window === 'undefined'
2595
3239
  ? await Promise.all([${pluginImportNames.filter((item) => isSsrOnlyPlugin(item[1])).map((item) => {
@@ -2598,46 +3242,597 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
2598
3242
  return `import(${JSON.stringify(specifier)}).then(m => (m.default ?? m)(${opts}))`;
2599
3243
  }).join(", ")}])
2600
3244
  : [];
3245
+ const __mfRuntimeShareLoadIdKey = "__mf_vite_runtime_share_load_id__";
3246
+ let __mfRuntimeShareLoadId = 0;
3247
+ const __mfRuntimeShareSelections = new Map();
3248
+ const __mfRuntimeShareLifecycles = new Map();
2601
3249
  const initRes = runtimeInit({
2602
3250
  name: mfName,
2603
3251
  remotes: ${options.shareStrategy === "loaded-first" ? "[]" : "usedRemotes"},
2604
3252
  shared: usedShared,
2605
- plugins: [${hasTreeShakingShared ? "__mfTreeShakingSnapshotPlugin()," : ""} ...__browserPlugins, ...__ssrPlugins],
3253
+ plugins: [__mfSharePinLifecyclePlugin(), ${hasTreeShakingShared ? "__mfTreeShakingSnapshotPlugin()," : ""} ...__browserPlugins, ...__ssrPlugins],
2606
3254
  ${options.shareStrategy ? `shareStrategy: '${options.shareStrategy}'` : ""}
2607
3255
  });
2608
- // handling circular init calls
2609
- var initToken = initTokens[shareScopeName];
2610
- if (!initToken)
2611
- initToken = initTokens[shareScopeName] = { from: mfName };
2612
- if (initScope.indexOf(initToken) >= 0) return;
2613
- initScope.push(initToken);
2614
- initRes.initShareScopeMap('${options.shareScope}', shared);
2615
- try {
2616
- await retrySharedInit(async () => {
2617
- await Promise.all(await initRes.initializeSharing('${options.shareScope}', {
2618
- strategy: '${options.shareStrategy}',
2619
- from: "build",
2620
- initScope
2621
- }));
3256
+ ${hasMultipleShareScopes ? `for (const shareScopeName of shareScopeNamesToInitialize) {
3257
+ const scopeShare = getShareScope(shareScopeName);
3258
+ initRes.initShareScopeMap(shareScopeName, scopeShare);
3259
+ }` : `initRes.initShareScopeMap('${options.shareScope}', shared);`}
3260
+ function __mfSharePinLifecyclePlugin() {
3261
+ return {
3262
+ name: "vite-share-pin-lifecycle-plugin",
3263
+ resolveShare(args) {
3264
+ const loadId = args.shareInfo?.[__mfRuntimeShareLoadIdKey];
3265
+ const lifecycle = loadId === undefined
3266
+ ? undefined
3267
+ : __mfRuntimeShareLifecycles.get(loadId);
3268
+ if (!lifecycle) return args;
3269
+ const defaultResolver = args.resolver;
3270
+ args.resolver = (...resolverArgs) => {
3271
+ lifecycle.pinned.reapply();
3272
+ return defaultResolver(...resolverArgs);
3273
+ };
3274
+ lifecycle.pinned.reveal();
3275
+ return args;
3276
+ }
3277
+ };
3278
+ }
3279
+ const runtimeResolveShareHook = initRes.sharedHandler.hooks.lifecycle.resolveShare;
3280
+ const __mfRuntimeProviderOrigins = new WeakMap();
3281
+ runtimeResolveShareHook.on((args) => {
3282
+ const loadId = args.shareInfo?.[__mfRuntimeShareLoadIdKey];
3283
+ const resolver = args.resolver;
3284
+ if (typeof resolver !== "function") return args;
3285
+ const instrumentedResolver = (...resolverArgs) => {
3286
+ const resolved = resolver(...resolverArgs);
3287
+ const selectedProvider = resolved?.shared;
3288
+ if (
3289
+ selectedProvider &&
3290
+ (typeof selectedProvider === "object" || typeof selectedProvider === "function") &&
3291
+ !__mfRuntimeProviderOrigins.has(selectedProvider)
3292
+ ) {
3293
+ __mfRuntimeProviderOrigins.set(selectedProvider, { from: selectedProvider.from });
3294
+ }
3295
+ if (loadId !== undefined && selectedProvider) {
3296
+ __mfRuntimeShareSelections.set(loadId, selectedProvider);
3297
+ }
3298
+ return resolved;
3299
+ };
3300
+ args.resolver = instrumentedResolver;
3301
+ return args;
3302
+ });
3303
+ const __mfPinSharedProvider = (versionMap, version, currentProvider, provider) => {
3304
+ if (!versionMap || versionMap[version] !== currentProvider) return undefined;
3305
+ const pinnedProvider = Object.assign({}, provider, {
3306
+ version: provider.version ?? version,
3307
+ scope: provider.scope ?? currentProvider?.scope ?? ${JSON.stringify(hasMultipleShareScopes ? options.shareScope : [options.shareScope])},
3308
+ strategy: 'loaded-first'
2622
3309
  });
3310
+ const providerFrom = provider.from;
3311
+ versionMap[version] = pinnedProvider;
3312
+ const isCurrentProviderActive = () => currentProvider === undefined
3313
+ ? versionMap[version] === undefined
3314
+ : versionMap[version] === currentProvider;
3315
+ return {
3316
+ provider: pinnedProvider,
3317
+ reveal() {
3318
+ if (versionMap[version] !== pinnedProvider) return false;
3319
+ if (currentProvider === undefined) delete versionMap[version];
3320
+ else versionMap[version] = currentProvider;
3321
+ return true;
3322
+ },
3323
+ reapply() {
3324
+ if (!isCurrentProviderActive()) return false;
3325
+ versionMap[version] = pinnedProvider;
3326
+ return true;
3327
+ },
3328
+ release(loaded, selected = true) {
3329
+ provider.from = providerFrom;
3330
+ if (versionMap[version] !== pinnedProvider) {
3331
+ return !selected && isCurrentProviderActive();
3332
+ }
3333
+ if (!selected) {
3334
+ if (currentProvider === undefined) delete versionMap[version];
3335
+ else versionMap[version] = currentProvider;
3336
+ return true;
3337
+ }
3338
+ if (!loaded) {
3339
+ if (currentProvider === undefined) delete versionMap[version];
3340
+ else versionMap[version] = currentProvider;
3341
+ return false;
3342
+ }
3343
+ pinnedProvider.from = providerFrom;
3344
+ if (loaded && pinnedProvider.lib) pinnedProvider.loaded = true;
3345
+ if (provider.strategy === undefined) delete pinnedProvider.strategy;
3346
+ else pinnedProvider.strategy = provider.strategy;
3347
+ return true;
3348
+ }
3349
+ };
3350
+ };
3351
+ const __mfSnapshotSharedProviders = (versionMap) => (
3352
+ Object.entries(versionMap || {}).map(([version, provider]) => ({
3353
+ provider,
3354
+ version,
3355
+ from: provider.from,
3356
+ registered: true
3357
+ }))
3358
+ );
3359
+ const __mfMatchLoadedSharedProvider = (providerSelections, factory) => {
3360
+ if (factory === undefined) return undefined;
3361
+ let match;
3362
+ for (const selection of providerSelections) {
3363
+ const provider = selection.provider;
3364
+ const directProvider = provider.treeShaking || provider;
3365
+ if (
3366
+ selection.loadedFactory !== factory &&
3367
+ provider.lib !== factory &&
3368
+ directProvider.lib !== factory
3369
+ ) continue;
3370
+ if (match) return undefined;
3371
+ match = selection;
3372
+ }
3373
+ return match;
3374
+ };
3375
+ const __mfLoadRuntimeShare = async (pkg, shareConfig, pinned) => {
3376
+ const loadId = ++__mfRuntimeShareLoadId;
3377
+ __mfRuntimeShareLifecycles.set(loadId, {
3378
+ pinned
3379
+ });
3380
+ try {
3381
+ const factory = await initRes.loadShare(pkg, {
3382
+ customShareInfo: {
3383
+ shareConfig,
3384
+ [__mfRuntimeShareLoadIdKey]: loadId
3385
+ }
3386
+ });
3387
+ return {
3388
+ factory: factory === false ? undefined : factory,
3389
+ selectedProvider: __mfRuntimeShareSelections.get(loadId)
3390
+ };
3391
+ } finally {
3392
+ __mfRuntimeShareSelections.delete(loadId);
3393
+ __mfRuntimeShareLifecycles.delete(loadId);
3394
+ }
3395
+ };
3396
+ const __mfLoadPinnedRuntimeShare = async (
3397
+ pkg,
3398
+ shareConfig,
3399
+ versionMap,
3400
+ version,
3401
+ currentProvider,
3402
+ provider,
3403
+ providerRegistered = true
3404
+ ) => {
3405
+ const providerFrom = provider.from;
3406
+ const pinned = __mfPinSharedProvider(
3407
+ versionMap,
3408
+ version,
3409
+ currentProvider,
3410
+ provider
3411
+ );
3412
+ if (!pinned) return undefined;
3413
+ let runtimeLoad;
3414
+ try {
3415
+ runtimeLoad = await __mfLoadRuntimeShare(pkg, shareConfig, pinned);
3416
+ } catch (error) {
3417
+ pinned.release(false);
3418
+ throw error;
3419
+ }
3420
+ const factory = runtimeLoad?.factory;
3421
+ if (factory === undefined) {
3422
+ pinned.release(false);
3423
+ return undefined;
3424
+ }
3425
+ const providerSelections = __mfSnapshotSharedProviders(versionMap);
3426
+ const directPinnedProvider = pinned.provider.treeShaking || pinned.provider;
3427
+ const pinnedMatchesFactory =
3428
+ pinned.provider.lib === factory || directPinnedProvider.lib === factory;
3429
+ if (!providerRegistered && pinnedMatchesFactory) {
3430
+ const pinnedSelectionIndex = providerSelections.findIndex(
3431
+ (selection) => selection.provider === pinned.provider
3432
+ );
3433
+ if (pinnedSelectionIndex !== -1) providerSelections.splice(pinnedSelectionIndex, 1);
3434
+ }
3435
+ if (!providerRegistered && !providerSelections.some((selection) => selection.provider === provider)) {
3436
+ providerSelections.push({
3437
+ provider,
3438
+ version,
3439
+ from: providerFrom,
3440
+ registered: false,
3441
+ loadedFactory: pinnedMatchesFactory ? factory : undefined
3442
+ });
3443
+ }
3444
+ const runtimeSelectedProvider =
3445
+ !providerRegistered &&
3446
+ runtimeLoad.selectedProvider === pinned.provider &&
3447
+ pinnedMatchesFactory
3448
+ ? provider
3449
+ : runtimeLoad.selectedProvider;
3450
+ if (
3451
+ runtimeSelectedProvider &&
3452
+ !providerSelections.some((selection) => selection.provider === runtimeSelectedProvider)
3453
+ ) {
3454
+ const runtimeProviderOrigin = __mfRuntimeProviderOrigins.get(runtimeSelectedProvider);
3455
+ const selectedVersion = typeof runtimeSelectedProvider.version === "string" && runtimeSelectedProvider.version
3456
+ ? runtimeSelectedProvider.version
3457
+ : version;
3458
+ providerSelections.push({
3459
+ provider: runtimeSelectedProvider,
3460
+ version: selectedVersion,
3461
+ from: runtimeProviderOrigin ? runtimeProviderOrigin.from : runtimeSelectedProvider.from,
3462
+ registered: versionMap?.[selectedVersion] === runtimeSelectedProvider,
3463
+ loadedFactory: factory
3464
+ });
3465
+ }
3466
+ const selection = providerSelections.find(
3467
+ (candidate) => candidate.provider === runtimeSelectedProvider
3468
+ ) ?? __mfMatchLoadedSharedProvider(providerSelections, factory);
3469
+ const providerStayedActive = pinned.release(
3470
+ true,
3471
+ selection?.provider === pinned.provider
3472
+ );
3473
+ if (!providerStayedActive || !selection) return undefined;
3474
+ const runtimeProviderOrigin = __mfRuntimeProviderOrigins.get(selection.provider);
3475
+ selection.from = selection.provider === provider
3476
+ ? providerFrom
3477
+ : runtimeProviderOrigin
3478
+ ? runtimeProviderOrigin.from
3479
+ : selection.provider.from;
3480
+ if (runtimeProviderOrigin) selection.provider.from = runtimeProviderOrigin.from;
3481
+ const mod = typeof factory === "function" ? factory() : factory;
3482
+ const resolved = await Promise.resolve(mod);
3483
+ if (selection.registered && versionMap?.[selection.version] !== selection.provider) return undefined;
3484
+ return { provider: selection.provider, selection, resolved };
3485
+ };
3486
+ const bridgedProviders = new Set();
3487
+ const bridgeSelections = new Map();
3488
+ const __mfBridgeMaterializedProvider = async (pkg, usedShare, versionMap) => {
3489
+ const singleton = Boolean(usedShare.shareConfig?.singleton);
3490
+ if (singleton && '${options.shareStrategy}' !== 'loaded-first') return;
3491
+ if (usedShare.canLiveRebind === false) return;
3492
+ try {
3493
+ const provider = __mfSelectExternalSharedProvider(
3494
+ versionMap,
3495
+ pkg,
3496
+ usedShare,
3497
+ '${options.shareStrategy}'
3498
+ );
3499
+ const providerEntry = __mfFindSharedProviderEntry(versionMap, provider);
3500
+ if (!providerEntry) return;
3501
+ const { version } = providerEntry;
3502
+ if (!singleton && version !== usedShare.version) return;
3503
+ if (
3504
+ !provider.lib &&
3505
+ !provider.loading &&
3506
+ !(provider.loaded && typeof provider.get === 'function')
3507
+ ) return;
3508
+ const usedCacheDescriptor = __mfGetSharedCacheDescriptor(
3509
+ pkg,
3510
+ singleton,
3511
+ usedShare.version,
3512
+ usedShare.scope
3513
+ );
3514
+ if (__mfReadSharedCache(__mfModuleCache.share, usedCacheDescriptor) !== undefined) return;
3515
+ const liveVersionMap = ${hasMultipleShareScopes ? "getShareVersions(pkg, usedShare)" : "shared[pkg]"};
3516
+ const liveProvider = liveVersionMap?.[version];
3517
+ if (providerEntry.registered && !__mfMatchesSharedProvider(liveProvider, provider)) return;
3518
+ let loadedShare;
3519
+ ${options.shareStrategy === "loaded-first" ? `loadedShare = await __mfLoadPinnedRuntimeShare(
3520
+ pkg,
3521
+ usedShare.shareConfig,
3522
+ liveVersionMap,
3523
+ version,
3524
+ liveProvider,
3525
+ provider,
3526
+ providerEntry.registered
3527
+ );` : `// Runtime loadShare() implicitly initializes version-first remotes without
3528
+ // this container's outer initScope. Materialized providers are already active,
3529
+ // so resolve them directly and keep remote initialization on the guarded path.
3530
+ let directFactory = provider.lib;
3531
+ if (!directFactory && provider.loading) directFactory = await provider.loading;
3532
+ if (!directFactory && provider.loaded && typeof provider.get === 'function') {
3533
+ directFactory = await provider.get();
3534
+ }
3535
+ if (!directFactory) return;
3536
+ const directModule = typeof directFactory === "function" ? directFactory() : directFactory;
3537
+ const directResolved = await Promise.resolve(directModule);
3538
+ const directProvider = providerEntry.registered ? liveProvider : provider;
3539
+ loadedShare = {
3540
+ provider: directProvider,
3541
+ selection: {
3542
+ provider: directProvider,
3543
+ version,
3544
+ from: provider.from,
3545
+ registered: providerEntry.registered
3546
+ },
3547
+ resolved: directResolved
3548
+ };`}
3549
+ const actualProvider = loadedShare?.provider;
3550
+ const actualSelection = loadedShare?.selection;
3551
+ if (!actualSelection) return;
3552
+ const resolved = loadedShare?.resolved;
3553
+ if (resolved === undefined) return;
3554
+ if (__mfReadSharedCache(__mfModuleCache.share, usedCacheDescriptor) !== undefined) return;
3555
+ ${options.shareStrategy === "loaded-first" ? `if (
3556
+ actualSelection.registered &&
3557
+ liveVersionMap?.[actualSelection.version] !== actualProvider
3558
+ ) return;` : `if (
3559
+ actualSelection.registered &&
3560
+ liveVersionMap?.[actualSelection.version] !== actualProvider
3561
+ ) return;`}
3562
+ __mfWriteSharedCache(
3563
+ __mfModuleCache.share,
3564
+ usedCacheDescriptor,
3565
+ __mfNormalizeRuntimeShare(resolved),
3566
+ actualSelection.from
3567
+ );
3568
+ bridgedProviders.add(actualProvider);
3569
+ } catch (e) {
3570
+ console.error('[Module Federation] Failed to bridge materialized shared module "' + pkg + '"', e)
3571
+ }
3572
+ };
3573
+ const __mfBridgeExternalSharedProvider = async (
3574
+ pkg,
3575
+ usedShare,
3576
+ versionMap,
3577
+ passedVersionMap,
3578
+ expectedSelection
3579
+ ) => {
3580
+ try {
3581
+ const usedCacheDescriptor = __mfGetSharedCacheDescriptor(pkg, usedShare.shareConfig?.singleton, usedShare.version, usedShare.scope);
3582
+ const cachedShare = __mfReadSharedCache(__mfModuleCache.share, usedCacheDescriptor);
3583
+ const cachedShareOwner = __mfReadSharedCacheOwner(__mfModuleCache.share, usedCacheDescriptor);
3584
+ const selectedExternalProvider = __mfSelectExternalSharedProvider(
3585
+ versionMap,
3586
+ pkg,
3587
+ usedShare,
3588
+ '${options.shareStrategy}'
3589
+ );
3590
+ const selectedRuntimeProvider = selectedExternalProvider ||
3591
+ __mfSelectSharedProvider(versionMap, pkg, usedShare, '${options.shareStrategy}') ||
3592
+ usedShare;
3593
+ const providerEntry = __mfFindSharedProviderEntry(versionMap, selectedRuntimeProvider);
3594
+ if (!providerEntry) return;
3595
+ const selectedLocalProvider = __mfMatchesSharedProvider(selectedRuntimeProvider, usedShare);
3596
+ const { version } = providerEntry;
3597
+ const passedProvider = passedVersionMap?.[version];
3598
+ const resolvedExternalProvider = __mfResolveExternalSharedProvider(
3599
+ federationInstances,
3600
+ scopeRoot,
3601
+ ${hasMultipleShareScopes ? "getShareScope(getShareScopeName(pkg, usedShare))" : "shared"},
3602
+ ${hasMultipleShareScopes ? "getShareScopeName(pkg, usedShare)" : `'${options.shareScope}'`},
3603
+ pkg,
3604
+ providerEntry,
3605
+ selectedExternalProvider,
3606
+ passedProvider,
3607
+ '${options.shareStrategy}'
3608
+ );
3609
+ if (!resolvedExternalProvider && !selectedLocalProvider) return;
3610
+ const { provider, scopeRootProvider } = resolvedExternalProvider || {
3611
+ provider: selectedRuntimeProvider,
3612
+ scopeRootProvider: undefined
3613
+ };
3614
+ // Non-singleton proxies may have already snapshotted their local exports while
3615
+ // seeding shared dependencies. Late cache replacement is safe only for the
3616
+ // live-bound singleton proxies.
3617
+ if (!usedShare.shareConfig?.singleton) return;
3618
+ if (usedShare.canLiveRebind === false) return;
3619
+ // Preserve a singleton already selected by another container. The bridge may
3620
+ // only replace the provisional local fallback seeded by this container.
3621
+ if (cachedShare !== undefined && cachedShareOwner !== mfName) return;
3622
+ // Registration can replace an unloaded same-version root provider in-place.
3623
+ // Pin the chosen provider while loadShare() runs its implicit registration.
3624
+ const liveVersionMap = ${hasMultipleShareScopes ? "getShareVersions(pkg, usedShare)" : "shared[pkg]"};
3625
+ const liveProvider = liveVersionMap?.[version];
3626
+ if (
3627
+ providerEntry.registered &&
3628
+ !scopeRootProvider &&
3629
+ !__mfMatchesSharedProvider(liveProvider, provider)
3630
+ ) return;
3631
+ const loadedShare = await __mfLoadPinnedRuntimeShare(
3632
+ pkg,
3633
+ usedShare.shareConfig,
3634
+ liveVersionMap,
3635
+ version,
3636
+ liveProvider,
3637
+ provider,
3638
+ providerEntry.registered && !selectedLocalProvider
3639
+ );
3640
+ const actualProvider = loadedShare?.provider;
3641
+ const actualSelection = loadedShare?.selection;
3642
+ if (!actualSelection) return;
3643
+ if (__mfMatchesSharedProvider(actualProvider, usedShare)) return;
3644
+ if (expectedSelection) {
3645
+ if (
3646
+ expectedSelection.version !== actualSelection.version ||
3647
+ !__mfMatchesSharedProvider({ from: actualSelection.from }, expectedSelection.provider)
3648
+ ) return;
3649
+ }
3650
+ if (bridgedProviders.has(actualProvider)) return;
3651
+ const resolved = loadedShare?.resolved;
3652
+ if (resolved === undefined) return;
3653
+ const latestCachedShare = __mfReadSharedCache(__mfModuleCache.share, usedCacheDescriptor);
3654
+ const latestCachedShareOwner = __mfReadSharedCacheOwner(__mfModuleCache.share, usedCacheDescriptor);
3655
+ if (latestCachedShare !== undefined && latestCachedShareOwner !== mfName) return;
3656
+ if (
3657
+ actualSelection.registered &&
3658
+ liveVersionMap?.[actualSelection.version] !== actualProvider
3659
+ ) return;
3660
+ if (!expectedSelection) {
3661
+ bridgeSelections.set(pkg, {
3662
+ version: actualSelection.version,
3663
+ provider: { from: actualSelection.from }
3664
+ });
3665
+ }
3666
+ bridgedProviders.add(actualProvider);
3667
+ const normalized = __mfNormalizeRuntimeShare(resolved);
3668
+ __mfWriteSharedCache(
3669
+ __mfModuleCache.share,
3670
+ usedCacheDescriptor,
3671
+ normalized,
3672
+ actualSelection.from
3673
+ );
3674
+ } catch (e) {
3675
+ console.error('[Module Federation] Failed to bridge external shared module "' + pkg + '"', e)
3676
+ }
3677
+ };
3678
+ for (const [pkg, usedShare] of Object.entries(usedShared)) {
3679
+ if (usedShare.treeShaking) continue;
3680
+ await __mfBridgeMaterializedProvider(pkg, usedShare, initialShared[pkg]);
3681
+ }
3682
+ for (const [pkg, share] of Object.entries(usedShared)) {
3683
+ if (share.treeShaking) continue;
3684
+ const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
3685
+ if (__mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) !== undefined) continue;
3686
+ const singletonCacheDescriptor = __mfGetSharedCacheDescriptor(pkg, true, share.version, share.scope);
3687
+ const singletonModule = __mfReadSharedCache(__mfModuleCache.share, singletonCacheDescriptor);
3688
+ if (singletonModule !== undefined) {
3689
+ __mfWriteSharedCache(
3690
+ __mfModuleCache.share,
3691
+ cacheDescriptor,
3692
+ singletonModule,
3693
+ __mfReadSharedCacheOwner(__mfModuleCache.share, singletonCacheDescriptor)
3694
+ );
3695
+ }
3696
+ }
3697
+ ${generateRuntimeSharedCacheSeedCode(options.shareStrategy)}
3698
+ ${initializeSharingCode}
3699
+ // Calling provider.get() marks a provider as loaded. Wait until the Runtime has
3700
+ // finalized normal same-version precedence before materializing an external share.
3701
+ for (const [pkg, usedShare] of Object.entries(usedShared)) {
3702
+ if (usedShare.treeShaking) continue;
3703
+ await __mfBridgeExternalSharedProvider(
3704
+ pkg,
3705
+ usedShare,
3706
+ ${hasMultipleShareScopes ? "getShareVersions(pkg, usedShare)" : "shared[pkg]"},
3707
+ initialShared[pkg],
3708
+ undefined
3709
+ );
3710
+ }
3711
+ try {
3712
+ const allInstances = globalThis.__FEDERATION__?.__SHARE__;
3713
+ const globalVersionsByPackage = Object.create(null);
3714
+ if (allInstances) {
3715
+ for (const [, scopes] of Object.entries(allInstances)) {
3716
+ for (const scopeName of shareScopeNames) {
3717
+ const scopeShare = scopes?.[scopeName];
3718
+ if (!scopeShare) continue;
3719
+ for (const [pkg, versionMap] of Object.entries(scopeShare)) {
3720
+ const usedShare = usedShared?.[pkg];
3721
+ const passedVersions = initialShared[pkg];
3722
+ const bridgeSelection = bridgeSelections.get(pkg);
3723
+ if (!usedShare) continue;
3724
+ if (!passedVersions) continue;
3725
+ if (!bridgeSelection) continue;
3726
+ if (usedShare.treeShaking) continue;
3727
+ const globalVersions = globalVersionsByPackage[pkg] || (globalVersionsByPackage[pkg] = Object.create(null));
3728
+ for (const [version, provider] of Object.entries(versionMap)) {
3729
+ if (!provider.lib) continue;
3730
+ if (bridgeSelection.version !== version) continue;
3731
+ if (!__mfMatchesSharedProvider(provider, bridgeSelection.provider)) continue;
3732
+ const passedProvider = passedVersions[version];
3733
+ const matchesPassedProvider = provider === passedProvider || (
3734
+ passedProvider?.from && provider.from === passedProvider.from
3735
+ );
3736
+ if (!matchesPassedProvider) continue;
3737
+ if (provider === usedShare || (usedShare.from && provider.from === usedShare.from)) continue;
3738
+ if (globalVersions[version] === undefined) globalVersions[version] = provider;
3739
+ }
3740
+ }
3741
+ }
3742
+ }
3743
+ }
3744
+ for (const [pkg, versionMap] of Object.entries(globalVersionsByPackage)) {
3745
+ await __mfBridgeExternalSharedProvider(
3746
+ pkg,
3747
+ usedShared[pkg],
3748
+ versionMap,
3749
+ initialShared[pkg],
3750
+ bridgeSelections.get(pkg)
3751
+ );
3752
+ }
2623
3753
  } catch (e) {
2624
- console.error('[Module Federation]', e)
3754
+ console.error('[Module Federation] Failed to bridge external shared modules', e)
2625
3755
  }
2626
3756
  ${generateTreeShakingSharedResolutionCode(hasTreeShakingShared)}
2627
- for (const [pkg, share] of Object.entries(usedShared)) {
3757
+ const __mfResolveImportFalseShared = async (pkg, share) => {
2628
3758
  const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
2629
3759
  const cachedShare = share.treeShaking
2630
3760
  ? __mfReadTreeShakingSharedSelection(__mfModuleCache.share, cacheDescriptor, mfName)
2631
3761
  : __mfReadSharedCache(__mfModuleCache.share, cacheDescriptor);
2632
- if (share.shareConfig?.import !== false || cachedShare !== undefined) continue;
3762
+ if (share.shareConfig?.import !== false || cachedShare !== undefined) return;
2633
3763
  ${normalizeRuntimeShareCode}
2634
- const versions = shared?.[pkg];
2635
- const provider = __mfSelectSharedProvider(versions, pkg, share, '${options.shareStrategy}');
2636
- if (!provider) continue;
2637
- const factory = provider.lib || (provider.loading ? await provider.loading : await provider.get?.());
2638
- const mod = typeof factory === "function" ? factory() : factory;
2639
- const resolved = await Promise.resolve(mod);
2640
- __mfWriteSharedCache(__mfModuleCache.share, cacheDescriptor, __mfNormalizeRuntimeShare(resolved));
3764
+ const versionMap = ${hasMultipleShareScopes ? "getShareVersions(pkg, share)" : "shared?.[pkg]"};
3765
+ const provider = __mfSelectSharedProvider(
3766
+ versionMap,
3767
+ pkg,
3768
+ share,
3769
+ '${options.shareStrategy}'
3770
+ ) || share;
3771
+ const providerEntry = __mfFindSharedProviderEntry(versionMap, provider);
3772
+ if (!providerEntry) return;
3773
+ const { version } = providerEntry;
3774
+ const currentProvider = versionMap?.[version];
3775
+ const loadedShare = await __mfLoadPinnedRuntimeShare(
3776
+ pkg,
3777
+ share.shareConfig,
3778
+ versionMap,
3779
+ version,
3780
+ currentProvider,
3781
+ provider,
3782
+ providerEntry.registered && !__mfMatchesSharedProvider(provider, share)
3783
+ );
3784
+ const providerSelection = loadedShare?.selection;
3785
+ const actualProvider = loadedShare?.provider;
3786
+ const resolved = loadedShare?.resolved;
3787
+ if (!providerSelection) return;
3788
+ if (__mfMatchesSharedProvider(actualProvider, share)) return;
3789
+ if (resolved === undefined) return;
3790
+ const latestCachedShare = share.treeShaking
3791
+ ? __mfReadTreeShakingSharedSelection(__mfModuleCache.share, cacheDescriptor, mfName)
3792
+ : __mfReadSharedCache(__mfModuleCache.share, cacheDescriptor);
3793
+ if (latestCachedShare !== undefined) return;
3794
+ if (
3795
+ providerSelection.registered &&
3796
+ versionMap?.[providerSelection.version] !== actualProvider
3797
+ ) return;
3798
+ const normalizedShared = __mfNormalizeRuntimeShare(resolved);
3799
+ if (share.treeShaking) {
3800
+ const providedExports = share.treeShaking.providedExports ?? share.treeShaking.usedExports ?? [];
3801
+ __mfWriteTreeShakingSharedCache(
3802
+ __mfModuleCache.share,
3803
+ cacheDescriptor,
3804
+ providedExports,
3805
+ normalizedShared
3806
+ );
3807
+ __mfWriteTreeShakingSharedSelection(
3808
+ __mfModuleCache.share,
3809
+ cacheDescriptor,
3810
+ mfName,
3811
+ normalizedShared
3812
+ );
3813
+ } else {
3814
+ __mfWriteSharedCache(
3815
+ __mfModuleCache.share,
3816
+ cacheDescriptor,
3817
+ normalizedShared,
3818
+ providerSelection.from
3819
+ );
3820
+ }
3821
+ };
3822
+ // Resolve runtime-only dependencies and seed local fallbacks in dependency
3823
+ // order. Stop at an unresolved provider so its consumers cannot capture an
3824
+ // undefined or provisional singleton.
3825
+ for (const pkg of __mfDeferredSeedKeys) {
3826
+ const share = usedShared[pkg];
3827
+ if (__mfIsRuntimeOnlySharePending(pkg)) {
3828
+ if (share.treeShaking) {
3829
+ await __mfResolveTreeShakingShared(pkg, share);
3830
+ } else if (share.shareConfig?.import === false) {
3831
+ await __mfResolveImportFalseShared(pkg, share);
3832
+ }
3833
+ }
3834
+ if (__mfIsRuntimeOnlySharePending(pkg)) break;
3835
+ await __mfSeedLocalShared([pkg]);
2641
3836
  }
2642
3837
  initResolve(initRes)
2643
3838
  return initRes
@@ -2663,6 +3858,7 @@ let currentHostAutoInitCommand = "build";
2663
3858
  function generateHostAutoInitCode(remoteEntryImport, _command = "build") {
2664
3859
  const shouldPreloadShares = getNormalizeModuleFederationOptions().shareStrategy !== "loaded-first";
2665
3860
  const hostInitShareOrder = JSON.stringify(getOrderedUsedShares());
3861
+ const cacheOwner = JSON.stringify(getNormalizeModuleFederationOptions().name);
2666
3862
  return `
2667
3863
  ${getRuntimeModuleCacheBootstrapCode()}
2668
3864
  let hostInitPromise;
@@ -2694,7 +3890,12 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build") {
2694
3890
  }).then((factory) => {
2695
3891
  const mod = typeof factory === "function" ? factory() : factory;
2696
3892
  return Promise.resolve(mod).then((resolved) => {
2697
- __mfWriteSharedCache(__mfModuleCache.share, cacheDescriptor, __mfNormalizeRuntimeShare(resolved));
3893
+ __mfWriteSharedCache(
3894
+ __mfModuleCache.share,
3895
+ cacheDescriptor,
3896
+ __mfNormalizeRuntimeShare(resolved),
3897
+ ${cacheOwner}
3898
+ );
2698
3899
  });
2699
3900
  });
2700
3901
  }
@@ -2734,7 +3935,7 @@ function getRemoteVirtualModule(remote, command, enableSsrInit = false, consumer
2734
3935
  const { shareStrategy } = getNormalizeModuleFederationOptions();
2735
3936
  const cacheKey = `${remote}__${command}__${shareStrategy}__${consumer}__${enableSsrInit ? "ssr-init" : "no-ssr-init"}`;
2736
3937
  if (!cacheRemoteMap[cacheKey]) {
2737
- cacheRemoteMap[cacheKey] = new VirtualModule(remote, LOAD_REMOTE_TAG, ".js");
3938
+ cacheRemoteMap[cacheKey] = new VirtualModule(consumer === "unified" ? remote : `${remote}__mf_consumer__${consumer}`, LOAD_REMOTE_TAG, ".js");
2738
3939
  cacheRemoteMap[cacheKey].writeSync(generateRemotes(remote, command, enableSsrInit, consumer));
2739
3940
  }
2740
3941
  return cacheRemoteMap[cacheKey];
@@ -2777,9 +3978,24 @@ function shouldIncludeDeferredProxy(initMode, consumer, eagerLoadClientRemote, d
2777
3978
  function getRemoteModuleRuntimeHelpers() {
2778
3979
  return `
2779
3980
  function __mfUnwrapRemoteDefault(mod) {
2780
- if (mod == null) return mod;
2781
- if (mod.__esModule && mod.default != null) return mod.default;
2782
- return mod.default ?? mod;
3981
+ let value = mod;
3982
+ // A federated expose can pass through more than one ESM/CJS namespace
3983
+ // wrapper (notably with React/Preact lazy imports). Keep unwrapping
3984
+ // explicit default namespaces until the actual component is reached.
3985
+ const seen = new Set();
3986
+ while (value != null && typeof value === "object" && !seen.has(value)) {
3987
+ seen.add(value);
3988
+ if (value.__esModule && value.default != null) {
3989
+ value = value.default;
3990
+ continue;
3991
+ }
3992
+ if (!value.__esModule && value.default != null) {
3993
+ value = value.default;
3994
+ continue;
3995
+ }
3996
+ break;
3997
+ }
3998
+ return value;
2783
3999
  }
2784
4000
  let __mfDefaultExport;
2785
4001
  function __mfSyncDefaultExport() {
@@ -3083,9 +4299,10 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
3083
4299
  const blockEnd = body.lastIndexOf("}");
3084
4300
  if (blockStart === -1 || blockEnd <= blockStart) return scriptTag;
3085
4301
  return `<script>${body.slice(0, blockStart + 1) + `
4302
+ const __mfCurrentScript = document.currentScript;
3086
4303
  (async () => {
3087
4304
  await import(${JSON.stringify(initPath)}).then(({ initHost }) => initHost());
3088
- ` + body.slice(blockStart + 1, blockEnd) + `
4305
+ ` + body.slice(blockStart + 1, blockEnd).replaceAll("document.currentScript", "__mfCurrentScript") + `
3089
4306
  })();
3090
4307
  ` + body.slice(blockEnd)}<\/script>`;
3091
4308
  });
@@ -4394,15 +5611,25 @@ function generateRemoteEntrySSR(options) {
4394
5611
  const initToken = { from: ${JSON.stringify(options.name)} };
4395
5612
  if (initScope.indexOf(initToken) >= 0) return;
4396
5613
  initScope.push(initToken);
4397
- initRes.initShareScopeMap(${JSON.stringify(options.shareScope)}, shared);
5614
+ const shareScopeNames = Array.isArray(${JSON.stringify(options.shareScope)})
5615
+ ? ${JSON.stringify(options.shareScope)}
5616
+ : [${JSON.stringify(options.shareScope)}];
4398
5617
  try {
4399
- await Promise.all(
4400
- await initRes.initializeSharing(${JSON.stringify(options.shareScope)}, {
4401
- strategy: ${JSON.stringify(options.shareStrategy ?? "version-first")},
4402
- from: 'build',
4403
- initScope,
4404
- })
4405
- );
5618
+ for (const scopeName of shareScopeNames) {
5619
+ try {
5620
+ const scopeShare = Array.isArray(${JSON.stringify(options.shareScope)}) ? (shared?.[scopeName] || {}) : shared;
5621
+ initRes.initShareScopeMap(scopeName, scopeShare);
5622
+ await Promise.all(
5623
+ await initRes.initializeSharing(scopeName, {
5624
+ strategy: ${JSON.stringify(options.shareStrategy ?? "version-first")},
5625
+ from: 'build',
5626
+ initScope,
5627
+ })
5628
+ );
5629
+ } catch (e) {
5630
+ console.error('[Module Federation SSR]', e);
5631
+ }
5632
+ }
4406
5633
  } catch (e) {
4407
5634
  console.error('[Module Federation SSR]', e);
4408
5635
  }
@@ -4987,7 +6214,7 @@ function pluginProxyRemoteEntry_default({ options, remoteEntryId, virtualExposes
4987
6214
  },
4988
6215
  async buildStart() {
4989
6216
  await refreshExposeRemoteDependencies(this);
4990
- if (_command !== "build") return;
6217
+ if (_command !== "build" || hasPackageDependency("@tanstack/react-start", root)) return;
4991
6218
  for (const expose of Object.values(options.exposes)) {
4992
6219
  const resolved = await this.resolve(expose.import);
4993
6220
  if (resolved) this.emitFile({
@@ -5764,50 +6991,6 @@ function collectFromRegex(code, isRemoteImport) {
5764
6991
  }
5765
6992
  return result.length > 0 ? result : void 0;
5766
6993
  }
5767
- function createCodePositionMap(code) {
5768
- const positions = Array(code.length).fill(true);
5769
- function mask(start, end) {
5770
- for (let i = start; i < end; i++) positions[i] = false;
5771
- }
5772
- for (let i = 0; i < code.length;) {
5773
- const char = code[i];
5774
- const next = code[i + 1];
5775
- if (char === "/" && next === "/") {
5776
- const start = i;
5777
- i += 2;
5778
- while (i < code.length && code[i] !== "\n" && code[i] !== "\r") i++;
5779
- mask(start, i);
5780
- continue;
5781
- }
5782
- if (char === "/" && next === "*") {
5783
- const start = i;
5784
- i += 2;
5785
- while (i < code.length && !(code[i] === "*" && code[i + 1] === "/")) i++;
5786
- i = Math.min(code.length, i + 2);
5787
- mask(start, i);
5788
- continue;
5789
- }
5790
- if (char === "\"" || char === "'" || char === "`") {
5791
- const quote = char;
5792
- const start = i++;
5793
- while (i < code.length) {
5794
- if (code[i] === "\\") {
5795
- i += 2;
5796
- continue;
5797
- }
5798
- if (code[i] === quote) {
5799
- i++;
5800
- break;
5801
- }
5802
- i++;
5803
- }
5804
- mask(start, i);
5805
- continue;
5806
- }
5807
- i++;
5808
- }
5809
- return positions;
5810
- }
5811
6994
  function pluginRemoteNamedExports(options) {
5812
6995
  const remoteNames = Object.keys(options.remotes);
5813
6996
  const isNodeModulesId = (id) => id.includes("/node_modules/") || id.includes("\\node_modules\\");
@@ -5883,15 +7066,22 @@ function isPathWithinAllowedDirectories(filePath, allowedDirectories) {
5883
7066
  return allowedDirectories.some((directory) => isPathWithinDirectory(filePath, directory));
5884
7067
  }
5885
7068
  function isSafeRunnerFetchModuleId(id, config) {
5886
- if (typeof id !== "string" || !id || id.includes("\0")) return false;
5887
- const decoded = decodeViteId(id).replace(/^\0+/, "");
5888
- if (!decoded || decoded.startsWith("virtual:")) return !!decoded;
5889
- if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(decoded) || decoded.startsWith("//")) return false;
7069
+ if (typeof id !== "string" || !id) return false;
7070
+ const rawDecoded = decodeViteId(id);
7071
+ const decoded = rawDecoded.replace(/^\0+/, "");
7072
+ if (!decoded || rawDecoded.startsWith("\0") || decoded.startsWith("virtual:")) return !!decoded;
7073
+ if (decoded.startsWith("file://")) try {
7074
+ const filePath = decodeURIComponent(new URL(decoded).pathname);
7075
+ return path$1.isAbsolute(filePath) && isPathWithinAllowedDirectories(filePath, getRunnerAllowedDirectories(config));
7076
+ } catch {
7077
+ return false;
7078
+ }
7079
+ if (/^(?:https?|data|blob|javascript):/i.test(decoded) || decoded.startsWith("//")) return false;
5890
7080
  const cleanId = decodeRunnerFilePath(stripQueryAndHash(decoded));
5891
7081
  if (!cleanId || hasRelativeTraversal(cleanId)) return false;
5892
7082
  const allowedDirectories = getRunnerAllowedDirectories(config);
5893
7083
  if (cleanId.startsWith(VITE_FS_PREFIX)) {
5894
- const fsPath = cleanId.slice(5);
7084
+ const fsPath = `/${cleanId.slice(5)}`;
5895
7085
  return path$1.isAbsolute(fsPath) && isPathWithinAllowedDirectories(fsPath, allowedDirectories);
5896
7086
  }
5897
7087
  if (path$1.isAbsolute(cleanId)) {
@@ -6424,9 +7614,6 @@ function appendResolveAlias(config, alias) {
6424
7614
  replacement
6425
7615
  })), alias];
6426
7616
  }
6427
- function hasImportFalseShared(options) {
6428
- return Object.values(options.shared ?? {}).some((share) => share?.shareConfig?.import === false);
6429
- }
6430
7617
  function getRuntimeHelpersImplementation(runtimeImplementation) {
6431
7618
  const indexEntryMatch = runtimeImplementation.match(/^(.*[\\/])index(\.[cm]?js)$/);
6432
7619
  if (indexEntryMatch) return normalizePathForImport(`${indexEntryMatch[1]}helpers${indexEntryMatch[2]}`);
@@ -6511,8 +7698,8 @@ function createEarlyVirtualModulesPlugin(options) {
6511
7698
  name: "module-federation:optimize-shared-resolver",
6512
7699
  load(id) {
6513
7700
  if (id !== "module-federation:optimized-require-react") return;
6514
- const optimizedLoadSharePath = toViteOptimizedDepVirtualId(getLoadShareModulePath("react", isRolldown));
6515
- const source = JSON.stringify(optimizedLoadSharePath);
7701
+ const loadSharePath = getLoadShareModulePath("react", isRolldown);
7702
+ const source = JSON.stringify(loadSharePath);
6516
7703
  return "import * as __mfShared from " + source + ";\nexport * from " + source + ";\nexport default __mfShared.default ?? __mfShared;";
6517
7704
  },
6518
7705
  resolveId(source, importer, options) {
@@ -6670,7 +7857,7 @@ export default __mfShared.default ?? __mfShared;`
6670
7857
  const SSR_ONLY_PLUGINS = new Set(["@module-federation/vite/ssrEntryLoader"]);
6671
7858
  function loadPluginDts(options) {
6672
7859
  if (options.dts === false) return [];
6673
- return [import("./pluginDts-BcvLBYP3.js").then((n) => n.n).then(({ default: pluginDts }) => pluginDts(options))];
7860
+ return [import("./pluginDts-CGDIZCsD.js").then((n) => n.n).then(({ default: pluginDts }) => pluginDts(options))];
6674
7861
  }
6675
7862
  function federation(mfUserOptions) {
6676
7863
  if (isTestEnv()) return [];
@@ -6984,7 +8171,7 @@ function federation(mfUserOptions) {
6984
8171
  config(config, { command: _command }) {
6985
8172
  const isRolldown = getIsRolldown(this);
6986
8173
  isSsrBuild = _command === "build" && config.build?.ssr === true;
6987
- const needsRuntimeHelpers = hasImportFalseShared(options) || Object.values(options.shared ?? {}).some((share) => !!share?.shareConfig.treeShaking);
8174
+ const needsRuntimeHelpers = Object.keys(options.shared ?? {}).length > 0;
6988
8175
  if (needsRuntimeHelpers) appendResolveAlias(config, {
6989
8176
  find: /^@module-federation\/runtime\/helpers$/,
6990
8177
  replacement: getRuntimeHelpersImplementation(options.implementation)
@@ -7025,6 +8212,11 @@ function federation(mfUserOptions) {
7025
8212
  if (resolvedTarget === "node" && !("FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN" in config.define)) config.define["FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN"] = "true";
7026
8213
  if (options.target && "ENV_TARGET" in config.define && config.define["ENV_TARGET"] !== JSON.stringify(options.target)) mfWarn(`ENV_TARGET define (${config.define["ENV_TARGET"]}) differs from target option ("${options.target}"). ENV_TARGET will not be overridden.`);
7027
8214
  },
8215
+ configResolved(config) {
8216
+ if (!hasPackageDependency("nitro")) return;
8217
+ const prematureExit = config.plugins.find((plugin) => plugin.name === "tanstack-build-exit");
8218
+ if (prematureExit) prematureExit.closeBundle = void 0;
8219
+ },
7028
8220
  configEnvironment(name, config) {
7029
8221
  if (!(config.consumer === "server" || name === "ssr" || name === "server" || config.build?.ssr === true)) return;
7030
8222
  const isAstro = hasPackageDependency("astro");