@module-federation/vite 1.16.2 → 1.16.4

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.cjs CHANGED
@@ -418,24 +418,51 @@ function getSuffix(name) {
418
418
  }
419
419
  const patternMap = {};
420
420
  const cacheMap = {};
421
+ const VITE_ID_PREFIX = "/@id/";
422
+ const VITE_ENCODED_NULL_BYTE_PREFIX = `${VITE_ID_PREFIX}__x00__`;
423
+ function escapeRegExp$1(value) {
424
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
425
+ }
426
+ function createViteEncodedIdPrefixRegExp(sourcePrefix = "") {
427
+ return new RegExp(`^(?:${escapeRegExp$1(VITE_ENCODED_NULL_BYTE_PREFIX)})?${sourcePrefix}`);
428
+ }
429
+ function toViteEncodedId(id) {
430
+ return `${VITE_ENCODED_NULL_BYTE_PREFIX}${id}`;
431
+ }
432
+ function decodeViteId(id) {
433
+ if (!id.startsWith("/@id/")) return id;
434
+ const viteId = id.slice(5);
435
+ return viteId.startsWith("__x00__") ? `\0${viteId.slice(7)}` : viteId;
436
+ }
421
437
  function assertModuleFound(tag, str = "") {
422
438
  const module = VirtualModule.findModule(tag, str);
423
439
  if (!module) throw require_packageUtils.createModuleFederationError(`Module Federation shared module '${str}' not found. Please ensure it's installed as a dependency in your package.json.`);
424
440
  return module;
425
441
  }
426
- var VirtualModule = class {
442
+ function normalizeVirtualModuleId(id) {
443
+ const decoded = decodeViteId(id).replace(/^\0+/, "");
444
+ const queryIndex = decoded.indexOf("?");
445
+ const hashIndex = decoded.indexOf("#");
446
+ const endIndex = queryIndex === -1 ? hashIndex : hashIndex === -1 ? queryIndex : Math.min(queryIndex, hashIndex);
447
+ return endIndex === -1 ? decoded : decoded.slice(0, endIndex);
448
+ }
449
+ var VirtualModule = class VirtualModule {
427
450
  name;
428
451
  tag;
429
452
  suffix;
430
453
  inited = false;
431
454
  code;
432
- static findModule(tag, str = "") {
455
+ static findName(tag, str = "") {
433
456
  if (!patternMap[tag]) patternMap[tag] = new RegExp(`(.*${require_packageUtils.packageNameEncode(tag)}(.+?)${require_packageUtils.packageNameEncode(tag)}.*)`);
434
- const moduleName = (str.match(patternMap[tag]) || [])[2];
435
- if (moduleName) return cacheMap[tag][require_packageUtils.packageNameDecode(moduleName)];
457
+ const moduleName = (normalizeVirtualModuleId(str).match(patternMap[tag]) || [])[2];
458
+ return moduleName ? require_packageUtils.packageNameDecode(moduleName) : void 0;
459
+ }
460
+ static findModule(tag, str = "") {
461
+ const moduleName = VirtualModule.findName(tag, str);
462
+ return moduleName ? cacheMap[tag][moduleName] : void 0;
436
463
  }
437
464
  static findById(id) {
438
- const normalized = id.replace(/^\0+/, "").replace(/^\/@id\//, "").replace(/^__x00__/, "").replace(/[?#].*$/, "");
465
+ const normalized = normalizeVirtualModuleId(id);
439
466
  for (const modules of Object.values(cacheMap)) for (const module of Object.values(modules)) if (module.getImportId() === normalized) return module;
440
467
  }
441
468
  constructor(name, tag = "__mf_v__", suffix = "") {
@@ -749,11 +776,9 @@ function getPackageEsmEntryPath(pkg) {
749
776
  resolveSubpathWithRequire: false
750
777
  }) || resolvePackageEntryFromProjectRoot(pkg);
751
778
  }
752
- function getEsmNamedExports(pkg) {
779
+ function getEsmNamedExportsFromFile(entryPath) {
753
780
  let source = "";
754
- let entryPath;
755
781
  try {
756
- entryPath = getPackageEsmEntryPath(pkg);
757
782
  if (!entryPath) return [];
758
783
  const { initSync, parse } = localRequire("es-module-lexer");
759
784
  initSync();
@@ -768,6 +793,48 @@ function getEsmNamedExports(pkg) {
768
793
  return source ? getNamedExportsViaRegex(source, entryPath) : [];
769
794
  }
770
795
  }
796
+ function getEsmNamedExports(pkg) {
797
+ return getEsmNamedExportsFromFile(getPackageEsmEntryPath(pkg));
798
+ }
799
+ function resolveConfiguredImportPath(importSource) {
800
+ if (pathe.default.isAbsolute(importSource)) return resolveFileLikeModule(importSource);
801
+ const projectRoot = require_packageUtils.getPackageDetectionCwd();
802
+ if (importSource.startsWith(".")) return resolveFileLikeModule(pathe.default.resolve(projectRoot, importSource));
803
+ const esmEntry = require_packageUtils.getInstalledPackageEntry(importSource, {
804
+ conditions: [
805
+ "browser",
806
+ "import",
807
+ "module",
808
+ "default"
809
+ ],
810
+ resolveSubpathWithRequire: false
811
+ });
812
+ if (esmEntry) return esmEntry;
813
+ try {
814
+ return (0, module$1.createRequire)(new URL(`file://${pathe.default.join(projectRoot, "package.json")}`)).resolve(importSource);
815
+ } catch {
816
+ return;
817
+ }
818
+ }
819
+ function resolveFileLikeModule(filePath) {
820
+ if ((0, fs.existsSync)(filePath) && !(0, fs.statSync)(filePath).isDirectory()) return filePath;
821
+ const extensions = [
822
+ ".ts",
823
+ ".tsx",
824
+ ".js",
825
+ ".jsx",
826
+ ".mjs",
827
+ ".mts"
828
+ ];
829
+ for (const ext of extensions) {
830
+ const candidate = filePath + ext;
831
+ if ((0, fs.existsSync)(candidate) && !(0, fs.statSync)(candidate).isDirectory()) return candidate;
832
+ }
833
+ for (const ext of extensions) {
834
+ const candidate = pathe.default.join(filePath, "index" + ext);
835
+ if ((0, fs.existsSync)(candidate) && !(0, fs.statSync)(candidate).isDirectory()) return candidate;
836
+ }
837
+ }
771
838
  function resolveRelativeModule(filePath, specifier) {
772
839
  const dir = pathe.default.dirname(filePath);
773
840
  const exact = pathe.default.resolve(dir, specifier);
@@ -794,12 +861,25 @@ function getNamedExportsViaRegex(source, filePath, visited) {
794
861
  const names = /* @__PURE__ */ new Set();
795
862
  visited = visited || /* @__PURE__ */ new Set();
796
863
  if (filePath) visited.add(filePath);
797
- const declRegex = new RegExp(`export\\s+(?:async\\s+)?(?:function(?:\\*\\s*|\\s+\\*?\\s*)|const\\s+|let\\s+|var\\s+|class\\s+)(${JS_IDENTIFIER_PATTERN})`, "gu");
864
+ 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");
798
865
  let match;
799
866
  while ((match = declRegex.exec(source)) !== null) {
800
867
  const name = match[1];
801
868
  if (isValidEsmExportName(name)) names.add(name);
802
869
  }
870
+ const destructureRegex = /export\s+(?:const|let|var)\s+(\{[^}]*\}|\[[^\]]*\])\s*=/g;
871
+ const bindingNameRegex = new RegExp(`^(${JS_IDENTIFIER_PATTERN})`, "u");
872
+ while ((match = destructureRegex.exec(source)) !== null) {
873
+ const inner = match[1].slice(1, -1);
874
+ for (const part of inner.split(",")) {
875
+ let token = part.split("=")[0].trim();
876
+ if (token.startsWith("...")) token = token.slice(3).trim();
877
+ if (!token) continue;
878
+ if (token.includes(":")) token = token.slice(token.indexOf(":") + 1).trim();
879
+ const bindingMatch = token.match(bindingNameRegex);
880
+ if (bindingMatch && isValidEsmExportName(bindingMatch[1])) names.add(bindingMatch[1]);
881
+ }
882
+ }
803
883
  const listRegex = /export\s*\{([^}]+)\}/g;
804
884
  const typeOnlySpecifierRegex = new RegExp(`^type\\s+${JS_IDENTIFIER_PATTERN}(?:\\s+as\\s+${JS_IDENTIFIER_PATTERN})?$`, "u");
805
885
  const exportSpecifierRegex = new RegExp(`(?:\\S+\\s+as\\s+)?(${JS_IDENTIFIER_PATTERN})$`, "u");
@@ -837,6 +917,14 @@ function getPackageNamedExports(pkg) {
837
917
  return getEsmNamedExports(pkg);
838
918
  }
839
919
  }
920
+ function getSharedNamedExports(pkg, shareItem) {
921
+ const configuredImport = shareItem?.shareConfig.import;
922
+ if (typeof configuredImport === "string") {
923
+ const configuredNamedExports = getEsmNamedExportsFromFile(resolveConfiguredImportPath(configuredImport));
924
+ if (configuredNamedExports.length > 0) return configuredNamedExports;
925
+ }
926
+ return getPackageNamedExports(pkg);
927
+ }
840
928
  function getLocalProviderImportPath(pkg) {
841
929
  try {
842
930
  const resolved = (0, module$1.createRequire)(new URL(`file://${pathe.default.join(require_packageUtils.getPackageDetectionCwd(), "package.json")}`)).resolve(pkg);
@@ -907,6 +995,20 @@ function writePreBuildLibPath(pkg, shareItem) {
907
995
  if (!preBuildCacheMap[pkg]) preBuildCacheMap[pkg] = new VirtualModule(pkg, PREBUILD_TAG, ".js");
908
996
  preBuildShareItemMap[pkg] = shareItem;
909
997
  const importSource = getConcreteSharedImportSource(pkg, shareItem) || pkg;
998
+ if (pkg === "react/compiler-runtime") {
999
+ preBuildCacheMap[pkg].writeSync(`
1000
+ const __mfCacheGlobalKey = "__mf_module_cache__";
1001
+ export const c = function(size) {
1002
+ const cache = globalThis[__mfCacheGlobalKey]?.share;
1003
+ const sharedReact = cache?.['react'];
1004
+ const reactExports = sharedReact?.default ?? sharedReact;
1005
+ const internals = reactExports?.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
1006
+ return internals?.H?.useMemoCache(size);
1007
+ };
1008
+ export default { c };
1009
+ `, true);
1010
+ return;
1011
+ }
910
1012
  if (pkg === "react/jsx-dev-runtime") {
911
1013
  preBuildCacheMap[pkg].writeSync(`
912
1014
  import __mfPrebuildDefault from ${escapeGeneratedStringLiteral(importSource)};
@@ -930,7 +1032,7 @@ function writePreBuildLibPath(pkg, shareItem) {
930
1032
  `, true);
931
1033
  return;
932
1034
  }
933
- const namedExports = getPackageNamedExports(pkg);
1035
+ const namedExports = getSharedNamedExports(pkg, shareItem);
934
1036
  if (namedExports.length > 0) {
935
1037
  const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
936
1038
  const declarations = namedExports.map((name, i) => `const ${namedExportVars[i]} = __mfPrebuildExports[${escapeGeneratedStringLiteral(name)}];`).join("\n ");
@@ -970,6 +1072,27 @@ function getLoadShareModulePath(pkg, isRolldown) {
970
1072
  if (!loadShareCacheMap[pkg]) getLoadShareImportId(pkg, isRolldown);
971
1073
  return loadShareCacheMap[pkg].getImportId();
972
1074
  }
1075
+ function toViteOptimizedDepVirtualId(id) {
1076
+ return toViteEncodedId(id);
1077
+ }
1078
+ function getCachedLoadSharePkg(id) {
1079
+ const normalized = normalizeVirtualModuleId(id);
1080
+ if (!normalized.startsWith("virtual:mf:")) return;
1081
+ const pkg = VirtualModule.findName(LOAD_SHARE_TAG, normalized);
1082
+ if (!pkg) return;
1083
+ return pkg;
1084
+ }
1085
+ function materializeCachedLoadShareModule(options) {
1086
+ const pkg = getCachedLoadSharePkg(options.id);
1087
+ if (!pkg) return;
1088
+ const key = options.findSharedKey(pkg, options.shared);
1089
+ if (!key) return;
1090
+ const shareItem = options.shared[key];
1091
+ writeLoadShareModule(pkg, shareItem, options.command, options.isRolldown);
1092
+ if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(pkg, shareItem);
1093
+ options.addUsedShares(pkg);
1094
+ options.writeLocalSharedImportMap();
1095
+ }
973
1096
  function generateDeferredHostProvidedExports(namedExports, pkg, cacheKey) {
974
1097
  const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
975
1098
  const declarations = ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ");
@@ -1037,7 +1160,7 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
1037
1160
  const lazyLocalFallbackSource = concreteSharedImportSource || localProviderPath || sharedImportSource;
1038
1161
  const skipServePrebuildWarmup = command !== "build" && (pkg === "lit" || pkg.startsWith("lit/"));
1039
1162
  const usesLazyLocalFallback = isWorkspacePackage && shareItem.shareConfig.singleton === true;
1040
- const namedExports = getPackageNamedExports(pkg);
1163
+ const namedExports = getSharedNamedExports(pkg, shareItem);
1041
1164
  let exportLine;
1042
1165
  if (namedExports.length > 0) {
1043
1166
  const destructure = `const { ${namedExports.map((name, i) => `${name}: __mf_${i}`).join(", ")} } = exportModule;`;
@@ -1137,7 +1260,7 @@ function generateLocalSharedImportMap() {
1137
1260
  version: ${JSON.stringify(shareItem.version)},
1138
1261
  scope: [${JSON.stringify(shareItem.scope)}],
1139
1262
  loaded: false,
1140
- from: ${JSON.stringify(options.internalName)},
1263
+ from: ${JSON.stringify(options.name)},
1141
1264
  async get () {
1142
1265
  if (${shareItem.shareConfig.import === false}) {
1143
1266
  throw new Error(\`[Module Federation] Shared module '\${${JSON.stringify(key)}}' must be provided by host\`);
@@ -1308,7 +1431,7 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
1308
1431
  ${getRuntimeModuleCacheBootstrapCode()}
1309
1432
  const initTokens = {}
1310
1433
  const shareScopeName = ${JSON.stringify(options.shareScope)}
1311
- const mfName = ${JSON.stringify(options.internalName)}
1434
+ const mfName = ${JSON.stringify(options.name)}
1312
1435
  let localSharedImportMapPromise
1313
1436
  let exposesMapPromise
1314
1437
  const shouldRetrySharedInitError = ${command !== "build"} && ((error) => {
@@ -1350,6 +1473,28 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
1350
1473
 
1351
1474
  async function init(shared = {}, initScope = []) {
1352
1475
  const {usedShared, usedRemotes} = await getLocalSharedImportMap()
1476
+ try {
1477
+ const allInstances = globalThis.__FEDERATION__?.__SHARE__;
1478
+ if (allInstances) {
1479
+ ${normalizeRuntimeShareCode}
1480
+ for (const [, scopes] of Object.entries(allInstances)) {
1481
+ const scopeShare = scopes?.['${options.shareScope}'];
1482
+ if (!scopeShare) continue;
1483
+ for (const [pkg, versionMap] of Object.entries(scopeShare)) {
1484
+ for (const [version, provider] of Object.entries(versionMap)) {
1485
+ if (!provider.lib) continue;
1486
+ const cacheKey = provider.shareConfig?.singleton ? pkg : \`\${pkg}@\${version}\`;
1487
+ if (__mfModuleCache.share[cacheKey] !== undefined) continue;
1488
+ const mod = typeof provider.lib === "function" ? provider.lib() : provider.lib;
1489
+ const resolved = await Promise.resolve(mod);
1490
+ __mfModuleCache.share[cacheKey] = __mfNormalizeRuntimeShare(resolved);
1491
+ }
1492
+ }
1493
+ }
1494
+ }
1495
+ } catch (e) {
1496
+ console.error('[Module Federation] Failed to bridge external shared modules', e)
1497
+ }
1353
1498
  ${generateDirectSharedCacheSeedCode(command)}
1354
1499
  const __browserPlugins = [${pluginImportNames.filter((item) => !isSsrOnlyPlugin(item[1])).map((item) => `${item[0]}(${item[2]})`).join(", ")}];
1355
1500
  const __ssrPlugins = typeof globalThis.window === 'undefined'
@@ -1689,7 +1834,8 @@ function patchHashEntryFileNames(config, entryName, fileName) {
1689
1834
  }
1690
1835
  const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClientInjected, skipTransformFor = [] }) => {
1691
1836
  const DEV_HTML_PROXY_PREFIX = "virtual:mf-html-entry-proxy?";
1692
- const ENTRY_BOOTSTRAP_QUERY = "?mf-entry-bootstrap";
1837
+ const ENTRY_BOOTSTRAP_PARAM = "mf-entry-bootstrap";
1838
+ const ENTRY_BOOTSTRAP_QUERY = `?${ENTRY_BOOTSTRAP_PARAM}`;
1693
1839
  const waitsForInit = entryName === "hostInit";
1694
1840
  const getEntryPath = () => typeof entryPath === "function" ? entryPath() : entryPath;
1695
1841
  let devEntryPath = "";
@@ -1707,6 +1853,9 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
1707
1853
  function isSvelteKitServerModule(id) {
1708
1854
  return require_packageUtils.hasPackageDependency("@sveltejs/kit") && (id.includes(".svelte-kit/generated/") || id.includes("/@sveltejs/kit/src/runtime/server/"));
1709
1855
  }
1856
+ function hasEntryBootstrapParam(id) {
1857
+ return id.includes(ENTRY_BOOTSTRAP_PARAM) || decodeURIComponent(id).includes(ENTRY_BOOTSTRAP_PARAM);
1858
+ }
1710
1859
  function rewriteSvelteKitInlineStart(html, initPath) {
1711
1860
  return html.replace(/<script>([\s\S]*?)<\/script>/gi, (scriptTag, body) => {
1712
1861
  if (!body.includes("kit.start(app, element);") || !body.includes("Promise.all([")) return scriptTag;
@@ -1806,7 +1955,7 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
1806
1955
  return inject === "entry" || !htmlFilePath;
1807
1956
  }
1808
1957
  function normalizeDevHtmlProxyId(id) {
1809
- return id.replace(/^\0/, "").replace(/^\/@id\//, "").replace(/^__x00__/, "");
1958
+ return decodeViteId(id).replace(/^\0/, "");
1810
1959
  }
1811
1960
  function normalizeModuleId(id) {
1812
1961
  return id.split("?")[0].replace(/\\/g, "/");
@@ -1840,7 +1989,7 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
1840
1989
  configResolved(config) {
1841
1990
  viteConfig = config;
1842
1991
  const resolvedEntryPath = getEntryPath();
1843
- if (resolvedEntryPath.startsWith("virtual:mf")) devEntryPath = config.base + "@id/" + resolvedEntryPath;
1992
+ if (resolvedEntryPath.startsWith("virtual:mf")) devEntryPath = config.base + VITE_ID_PREFIX.slice(1) + resolvedEntryPath;
1844
1993
  else {
1845
1994
  const normalized = resolvedEntryPath.replace(/\\\\?/g, "/");
1846
1995
  const root = config.root.replace(/\\\\?/g, "/").replace(/\/$/, "");
@@ -1881,10 +2030,10 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
1881
2030
  const base = viteConfig.base.replace(/\/$/, "");
1882
2031
  const stripBase = (p) => base && p.startsWith(base + "/") ? p.slice(base.length) : p;
1883
2032
  const html = rewriteEntryScripts(c, (originalSrc) => {
1884
- return `/@id/__x00__${DEV_HTML_PROXY_PREFIX}${new URLSearchParams({
2033
+ return toViteEncodedId(`${DEV_HTML_PROXY_PREFIX}${new URLSearchParams({
1885
2034
  init: sanitizeDevEntryPath(stripBase(devEntryPath)),
1886
2035
  entry: sanitizeDevEntryPath(stripBase(originalSrc))
1887
- }).toString()}`;
2036
+ }).toString()}`);
1888
2037
  });
1889
2038
  return html === c ? injectEntryScript(c, stripBase(devEntryPath)) : html;
1890
2039
  }
@@ -2016,7 +2165,7 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
2016
2165
  transform(code, id) {
2017
2166
  if (skipSvelteKitSsrBuild()) return;
2018
2167
  if (isSvelteKitServerModule(id)) return;
2019
- if (id.includes(ENTRY_BOOTSTRAP_QUERY)) return;
2168
+ if (hasEntryBootstrapParam(id)) return;
2020
2169
  if (normalizeModuleId(id).endsWith(".html")) return;
2021
2170
  if (skipTransformIds.has(resolveProjectId(id))) return;
2022
2171
  const transformCtx = this;
@@ -2044,7 +2193,7 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
2044
2193
  return mapCodeToCodeWithSourcemap(code.replace("vueApp.mount(vueAppRootContainer);", `${injection}vueApp.mount(vueAppRootContainer);`));
2045
2194
  }
2046
2195
  const isHydrationEntryFallback = inject === "entry" && entryFiles.length === 0 && (!htmlFilePath || !fs.existsSync(htmlFilePath)) && !clientInjected && !id.includes("node_modules") && (id.startsWith("\0") || /\.(js|ts|mjs|vue|jsx|tsx)(\?|$)/.test(id)) && /hydrateRoot|createRoot|ReactDOM\.render/.test(code);
2047
- const isNuxtClientEntryFallback = _command === "serve" && inject === "entry" && entryFiles.length === 0 && (!htmlFilePath || !fs.existsSync(htmlFilePath)) && !clientInjected && !id.includes("node_modules/.vite") && /(?:^|\/)nuxt\/dist\/app\/entry\.async\.js(?:\?|$)/.test(id) && code.includes("entry();");
2196
+ const isNuxtClientEntryFallback = _command === "serve" && inject === "entry" && entryFiles.length === 0 && (!htmlFilePath || !fs.existsSync(htmlFilePath)) && !clientInjected && !hasEntryBootstrapParam(id) && !id.includes("node_modules/.vite") && /(?:^|\/)nuxt\/dist\/app\/entry\.async\.js(?:\?|$)/.test(id) && code.includes("entry();");
2048
2197
  if (injectEntry() && entryFiles.some((file) => resolveProjectId(id) === file) || _command === "serve" && inject === "html" && !isVinext && !clientInjected && !id.startsWith("\0") && !id.includes("node_modules") && /\.(js|ts|mjs|vue|jsx|tsx)(\?|$)/.test(id) || isHydrationEntryFallback || isNuxtClientEntryFallback) {
2049
2198
  clientInjected = true;
2050
2199
  if (!waitsForInit || _command === "serve" && inject === "entry" && isHydrationEntryFallback) return mapCodeToCodeWithSourcemap(`import ${JSON.stringify(getEntryPath())};\n` + code);
@@ -2830,9 +2979,19 @@ const processModuleAssets = (bundle, filesMap, moduleMatcher, options = {}) => {
2830
2979
  foundCssViaMetadata = true;
2831
2980
  }
2832
2981
  if (!foundCssViaMetadata && chunkContainsCssModules(fileData.modules)) for (const cssAsset of Array.from(bundleCssAssets)) trackAsset(filesMap, matchKey, cssAsset, false, "css");
2833
- if (fileData.dynamicImports) for (const dynamicImport of fileData.dynamicImports) {
2834
- if (!bundle[dynamicImport]) continue;
2835
- trackAsset(filesMap, matchKey, dynamicImport, true, isCSSFile(dynamicImport) ? "css" : "js");
2982
+ const visited = /* @__PURE__ */ new Set();
2983
+ const queue = [fileName];
2984
+ for (let queueIndex = 0; queueIndex < queue.length; queueIndex++) {
2985
+ const cur = queue[queueIndex];
2986
+ if (visited.has(cur)) continue;
2987
+ visited.add(cur);
2988
+ const chunk = bundle[cur];
2989
+ if (!chunk || chunk.type !== "chunk") continue;
2990
+ if (chunk.dynamicImports) for (const dynamicImport of chunk.dynamicImports) {
2991
+ if (!bundle[dynamicImport]) continue;
2992
+ trackAsset(filesMap, matchKey, dynamicImport, true, isCSSFile(dynamicImport) ? "css" : "js");
2993
+ }
2994
+ if (chunk.imports) for (const imp of chunk.imports) queue.push(imp);
2836
2995
  }
2837
2996
  }
2838
2997
  }
@@ -2880,7 +3039,11 @@ const buildFileToShareKeyMap = async (shareKeys, resolveFn) => {
2880
3039
  //#endregion
2881
3040
  //#region src/utils/pathNormalization.ts
2882
3041
  const COMMON_SHARED_SUBPATHS = {
2883
- react: ["react/jsx-runtime", "react/jsx-dev-runtime"],
3042
+ react: [
3043
+ "react/jsx-runtime",
3044
+ "react/jsx-dev-runtime",
3045
+ "react/compiler-runtime"
3046
+ ],
2884
3047
  "react-dom": [
2885
3048
  "react-dom/client",
2886
3049
  "react-dom/server",
@@ -3015,11 +3178,11 @@ function generateRemoteEntrySSR(options) {
3015
3178
  */
3016
3179
  async function init(shared = {}, initScope = []) {
3017
3180
  const initRes = runtimeInit({
3018
- name: ${JSON.stringify(options.internalName)},
3181
+ name: ${JSON.stringify(options.name)},
3019
3182
  remotes: [],
3020
3183
  shared: {},
3021
3184
  });
3022
- const initToken = { from: ${JSON.stringify(options.internalName)} };
3185
+ const initToken = { from: ${JSON.stringify(options.name)} };
3023
3186
  if (initScope.indexOf(initToken) >= 0) return;
3024
3187
  initScope.push(initToken);
3025
3188
  initRes.initShareScopeMap(${JSON.stringify(options.shareScope)}, shared);
@@ -3612,9 +3775,16 @@ function findSharedKey(source, shared) {
3612
3775
  function findSharedKeyForSource(source, shared) {
3613
3776
  const key = findSharedKey(source, shared);
3614
3777
  if (key) return key;
3778
+ const explicitSharedSubpathKeys = Object.keys(shared || {}).filter((sharedKey) => require_packageUtils.getPackageName(sharedKey) !== sharedKey && !sharedKey.endsWith("/"));
3615
3779
  if (isNodeModulePath(source)) {
3616
- const explicitSubpathKey = getMatchingNodeModuleSubpath(source, Object.keys(shared || {}).filter((sharedKey) => sharedKey.includes("/") && !sharedKey.endsWith("/")));
3780
+ const explicitSubpathKey = getMatchingNodeModuleSubpath(source, explicitSharedSubpathKeys);
3617
3781
  if (explicitSubpathKey) return explicitSubpathKey;
3782
+ const normalizedSource = normalizeNodeModulePath(source);
3783
+ const explicitSubpathEntryKey = explicitSharedSubpathKeys.find((sharedKey) => {
3784
+ const entry = require_packageUtils.getInstalledPackageEntry(sharedKey, { cwd: require_packageUtils.getPackageDetectionCwd() });
3785
+ return entry ? normalizeNodeModulePath(entry) === normalizedSource : false;
3786
+ });
3787
+ if (explicitSubpathEntryKey) return explicitSubpathEntryKey;
3618
3788
  }
3619
3789
  const packageName = require_packageUtils.getPackageNameFromNodeModulePath(source);
3620
3790
  return packageName ? findSharedKey(packageName, shared) : void 0;
@@ -3659,6 +3829,7 @@ function proxySharedModule(options) {
3659
3829
  let useRolldown = false;
3660
3830
  const savePrebuild = new PromiseStore();
3661
3831
  let devServer;
3832
+ const materializedLoadShareSources = /* @__PURE__ */ new Set();
3662
3833
  return [
3663
3834
  {
3664
3835
  name: "generateLocalSharedImportMap",
@@ -3733,11 +3904,14 @@ function proxySharedModule(options) {
3733
3904
  if (shouldSkipTaggedImporterProxy(key, "__prebuild__")) return;
3734
3905
  const shareSource = key === "vue" && source.startsWith("vue/dist/") ? key : isNodeModulePath(source) ? getCommonSharedSubpathFromNodeModulePath(source, key) || key : source;
3735
3906
  const loadSharePath = getLoadShareModulePath(shareSource, useRolldown);
3736
- writeLoadShareModule(shareSource, shared[key], _command, useRolldown);
3737
- if (shared[key].shareConfig.import !== false) writePreBuildLibPath(shareSource, shared[key]);
3738
- addUsedShares(shareSource);
3739
- writeLocalSharedImportMap();
3740
- refreshHostAutoInit();
3907
+ if (!materializedLoadShareSources.has(shareSource)) {
3908
+ materializedLoadShareSources.add(shareSource);
3909
+ writeLoadShareModule(shareSource, shared[key], _command, useRolldown);
3910
+ if (shared[key].shareConfig.import !== false) writePreBuildLibPath(shareSource, shared[key]);
3911
+ addUsedShares(shareSource);
3912
+ writeLocalSharedImportMap();
3913
+ refreshHostAutoInit();
3914
+ }
3741
3915
  return this.resolve(loadSharePath, importer, { skipSelf: true });
3742
3916
  }
3743
3917
  },
@@ -4261,7 +4435,7 @@ function pluginSSRRemoteEntry(options) {
4261
4435
  try {
4262
4436
  result = await fetchFn(id, importer, opts);
4263
4437
  } catch (fetchErr) {
4264
- const bareId = id.startsWith("/@id/") ? id.slice(5).replace(/^__x00__/, "\0") : id;
4438
+ const bareId = decodeViteId(id);
4265
4439
  try {
4266
4440
  const { createRequire } = await import("module");
4267
4441
  const resolved = createRequire(new URL(`file://${server.config.root}/package.json`)).resolve(bareId.replace(/^\0/, ""));
@@ -4516,6 +4690,8 @@ var normalizeOptimizeDeps_default = {
4516
4690
  //#endregion
4517
4691
  //#region src/index.ts
4518
4692
  const patchedManualChunks = /* @__PURE__ */ new WeakSet();
4693
+ const PRELOAD_HELPER_CHUNK = "vite-preload-helper";
4694
+ const PRELOAD_HELPER_TEST = /\0?vite\/preload-helper/;
4519
4695
  function normalizeVinextRscPreloadHints(code) {
4520
4696
  return code.replace(/(:HL\[[^\]\n]*?,)"stylesheet"/g, "$1\"style\"").replace(/(:HL\[[^\]\n]*?,)\\"stylesheet\\"/g, "$1\\\"style\\\"");
4521
4697
  }
@@ -4583,6 +4759,14 @@ function isFederationHtmlPreloadDependency(dep, includeSharedRuntime = false) {
4583
4759
  if (file.includes("__mfe_internal__") || file.includes("virtual_mf-") || file.includes("virtualExposes") || file.includes("localSharedImportMap") || file.includes("hostInit")) return true;
4584
4760
  return includeSharedRuntime && (file.includes("preload-helper") || file.includes("rolldown-runtime") || file.startsWith("dist-"));
4585
4761
  }
4762
+ function canResolveSharedSubpath(subpath, projectRoot) {
4763
+ try {
4764
+ (0, module$1.createRequire)(new URL(`file://${projectRoot}/package.json`)).resolve(subpath);
4765
+ return true;
4766
+ } catch {
4767
+ return false;
4768
+ }
4769
+ }
4586
4770
  /**
4587
4771
  * Plugin that runs FIRST to register generated virtual modules in the config hook.
4588
4772
  * This prevents 504 "Outdated Optimize Dep" errors by ensuring ids are known
@@ -4649,7 +4833,7 @@ function createEarlyVirtualModulesPlugin(options) {
4649
4833
  optimizeDeps.esbuildOptions.plugins.push({
4650
4834
  name: "module-federation:optimize-shared-proxy",
4651
4835
  setup(build) {
4652
- build.onResolve({ filter: /^virtual:mf:/ }, (args) => ({
4836
+ build.onResolve({ filter: createViteEncodedIdPrefixRegExp("virtual:mf:") }, (args) => ({
4653
4837
  path: args.path,
4654
4838
  external: true
4655
4839
  }));
@@ -4669,15 +4853,15 @@ function createEarlyVirtualModulesPlugin(options) {
4669
4853
  const key = findSharedKey(args.path, shared);
4670
4854
  if (!key) return;
4671
4855
  const shareItem = shared[key];
4672
- const loadSharePath = getLoadShareModulePath(args.path, isRolldown);
4856
+ const optimizedLoadSharePath = toViteOptimizedDepVirtualId(getLoadShareModulePath(args.path, isRolldown));
4673
4857
  writeLoadShareModule(args.path, shareItem, _command, isRolldown);
4674
4858
  if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(args.path, shareItem);
4675
4859
  addUsedShares(args.path);
4676
4860
  return {
4677
4861
  loader: "js",
4678
4862
  resolveDir: root,
4679
- contents: `import * as __mfShared from ${JSON.stringify(loadSharePath)};
4680
- export * from ${JSON.stringify(loadSharePath)};
4863
+ contents: `import * as __mfShared from ${JSON.stringify(optimizedLoadSharePath)};
4864
+ export * from ${JSON.stringify(optimizedLoadSharePath)};
4681
4865
  export default __mfShared.default ?? __mfShared;`
4682
4866
  };
4683
4867
  });
@@ -4691,9 +4875,11 @@ export default __mfShared.default ?? __mfShared;`
4691
4875
  if (_command === "serve" && shareItem.shareConfig?.import !== false) {
4692
4876
  const optimizeDeps = config.optimizeDeps ??= {};
4693
4877
  optimizeDeps.include ??= [];
4878
+ optimizeDeps.exclude ??= [];
4694
4879
  for (const subpath of getCommonSharedSubpaths(key)) {
4695
4880
  writePreBuildLibPath(subpath, shareItem);
4696
- optimizeDeps.include.push(subpath);
4881
+ if (canResolveSharedSubpath(subpath, root)) optimizeDeps.include.push(subpath);
4882
+ else optimizeDeps.exclude.push(subpath);
4697
4883
  }
4698
4884
  }
4699
4885
  continue;
@@ -4717,7 +4903,8 @@ export default __mfShared.default ?? __mfShared;`
4717
4903
  writeLoadShareModule(subpath, shareItem, _command, isRolldown);
4718
4904
  writePreBuildLibPath(subpath, shareItem);
4719
4905
  addUsedShares(subpath);
4720
- optimizeDeps.include.push(subpath);
4906
+ if (canResolveSharedSubpath(subpath, root)) optimizeDeps.include.push(subpath);
4907
+ else optimizeDeps.exclude.push(subpath);
4721
4908
  }
4722
4909
  }
4723
4910
  }
@@ -4738,6 +4925,7 @@ export default __mfShared.default ?? __mfShared;`
4738
4925
  "react-dom",
4739
4926
  "react/jsx-runtime",
4740
4927
  "react/jsx-dev-runtime",
4928
+ "react/compiler-runtime",
4741
4929
  "@module-federation/runtime",
4742
4930
  "@module-federation/runtime-core",
4743
4931
  "@module-federation/sdk"
@@ -4778,7 +4966,19 @@ function federation(mfUserOptions) {
4778
4966
  name: "vite:module-federation-virtual-modules",
4779
4967
  enforce: "pre",
4780
4968
  resolveId(id) {
4781
- const virtualModule = VirtualModule.findById(id);
4969
+ let virtualModule = VirtualModule.findById(id);
4970
+ if (!virtualModule) {
4971
+ materializeCachedLoadShareModule({
4972
+ id,
4973
+ shared: options.shared,
4974
+ command,
4975
+ isRolldown: require_packageUtils.getIsRolldown(this),
4976
+ findSharedKey,
4977
+ addUsedShares,
4978
+ writeLocalSharedImportMap
4979
+ });
4980
+ virtualModule = VirtualModule.findById(id);
4981
+ }
4782
4982
  if (!virtualModule) return;
4783
4983
  return virtualModule.getResolvedId();
4784
4984
  },
@@ -4797,7 +4997,8 @@ function federation(mfUserOptions) {
4797
4997
  resolveId(id) {
4798
4998
  const reactServerEntryMap = {
4799
4999
  "react/jsx-runtime": "react/cjs/react-jsx-runtime.production.js",
4800
- "react/jsx-dev-runtime": "react/cjs/react-jsx-dev-runtime.production.js"
5000
+ "react/jsx-dev-runtime": "react/cjs/react-jsx-dev-runtime.production.js",
5001
+ "react/compiler-runtime": "react/cjs/react-compiler-runtime.production.js"
4801
5002
  };
4802
5003
  if (!(id in reactServerEntryMap)) return;
4803
5004
  const environmentName = this.environment?.name;
@@ -4899,6 +5100,8 @@ function federation(mfUserOptions) {
4899
5100
  }
4900
5101
  if (!output?.codeSplitting || typeof output.codeSplitting !== "object") return;
4901
5102
  if (!("groups" in output.codeSplitting)) return;
5103
+ const groups = output.codeSplitting.groups;
5104
+ if (Array.isArray(groups) && groups.some((group) => typeof group?.name === "function" && patchedManualChunks.has(group.name))) return;
4902
5105
  delete output.codeSplitting.groups;
4903
5106
  if (Object.keys(output.codeSplitting).length === 0) delete output.codeSplitting;
4904
5107
  if (warnedAboutCodeSplittingGroups) return;
@@ -4906,27 +5109,45 @@ function federation(mfUserOptions) {
4906
5109
  require_packageUtils.mfWarn("Ignoring `output.codeSplitting.groups` because it conflicts with module federation. Grouping shared dependency init wrappers with their dependent modules can break runtime init order and cause standalone remotes to fail before mount.");
4907
5110
  };
4908
5111
  let warnedAboutManualChunks = false;
4909
- const applyManualChunks = (output) => {
5112
+ const applyManualChunks = (output, useCodeSplitting) => {
4910
5113
  ensureCodeSplitting(output);
4911
5114
  const isPatchedByPlugin = typeof output.manualChunks === "function" && patchedManualChunks.has(output.manualChunks);
4912
5115
  if (output.manualChunks && !isPatchedByPlugin && !warnedAboutManualChunks) {
4913
5116
  warnedAboutManualChunks = true;
4914
5117
  require_packageUtils.mfWarn("Ignoring `output.manualChunks` because it conflicts with module federation. Module federation transforms shared dependency imports with async init wrappers, and grouping these transformed modules into a single chunk creates circular async dependencies that cause the application to silently hang.");
4915
5118
  }
4916
- const mfManualChunks = function(id) {
5119
+ const mfChunkName = function(id) {
4917
5120
  if (id.includes(runtimeInitId)) return "runtimeInit";
4918
5121
  if (id.includes("__loadShare__")) {
4919
5122
  const match = id.match(/([^/\\]+__loadShare__[^/\\]+)/);
4920
5123
  return match ? match[1] : "loadShare";
4921
5124
  }
5125
+ return null;
5126
+ };
5127
+ patchedManualChunks.add(mfChunkName);
5128
+ if (!useCodeSplitting) {
5129
+ const mfManualChunks = function(id) {
5130
+ return mfChunkName(id) ?? void 0;
5131
+ };
5132
+ patchedManualChunks.add(mfManualChunks);
5133
+ output.manualChunks = mfManualChunks;
5134
+ return;
5135
+ }
5136
+ const groups = [{
5137
+ name: PRELOAD_HELPER_CHUNK,
5138
+ test: PRELOAD_HELPER_TEST,
5139
+ priority: 100
5140
+ }, { name: mfChunkName }];
5141
+ output.codeSplitting = {
5142
+ ...output.codeSplitting || {},
5143
+ groups
4922
5144
  };
4923
- patchedManualChunks.add(mfManualChunks);
4924
- output.manualChunks = mfManualChunks;
5145
+ delete output.manualChunks;
4925
5146
  };
4926
5147
  config.build.rollupOptions = config.build.rollupOptions || {};
4927
5148
  const rollupOutput = config.build.rollupOptions.output;
4928
- if (Array.isArray(rollupOutput)) rollupOutput.forEach((output) => applyManualChunks(output));
4929
- else applyManualChunks(config.build.rollupOptions.output ||= {});
5149
+ if (Array.isArray(rollupOutput)) rollupOutput.forEach((output) => applyManualChunks(output, false));
5150
+ else applyManualChunks(config.build.rollupOptions.output ||= {}, false);
4930
5151
  const buildWithRolldown = config.build;
4931
5152
  buildWithRolldown.rolldownOptions = buildWithRolldown.rolldownOptions || {};
4932
5153
  const rolldownOutput = buildWithRolldown.rolldownOptions.output;
@@ -4936,10 +5157,10 @@ function federation(mfUserOptions) {
4936
5157
  assetFileNames: output.assetFileNames
4937
5158
  });
4938
5159
  if (Array.isArray(rolldownOutput)) {
4939
- rolldownOutput.forEach((output) => applyManualChunks(output));
5160
+ rolldownOutput.forEach((output) => applyManualChunks(output, true));
4940
5161
  desiredRolldownOutput = rolldownOutput.map((output) => snapshotRolldownOutput(output));
4941
5162
  } else {
4942
- applyManualChunks(buildWithRolldown.rolldownOptions.output ||= {});
5163
+ applyManualChunks(buildWithRolldown.rolldownOptions.output ||= {}, true);
4943
5164
  desiredRolldownOutput = [snapshotRolldownOutput(buildWithRolldown.rolldownOptions.output)];
4944
5165
  }
4945
5166
  },
package/lib/index.d.cts CHANGED
@@ -156,7 +156,7 @@ interface DtsHostOptions {
156
156
  runtimePkgs?: string[];
157
157
  remoteTypeUrls?: (() => Promise<RemoteTypeUrls>) | RemoteTypeUrls;
158
158
  timeout?: number;
159
- family?: 4 | 6;
159
+ family?: 0 | 4 | 6;
160
160
  typesOnBuild?: boolean;
161
161
  }
162
162
  //#endregion
package/lib/index.d.mts CHANGED
@@ -156,7 +156,7 @@ interface DtsHostOptions {
156
156
  runtimePkgs?: string[];
157
157
  remoteTypeUrls?: (() => Promise<RemoteTypeUrls>) | RemoteTypeUrls;
158
158
  timeout?: number;
159
- family?: 4 | 6;
159
+ family?: 0 | 4 | 6;
160
160
  typesOnBuild?: boolean;
161
161
  }
162
162
  //#endregion
package/lib/index.mjs CHANGED
@@ -417,24 +417,51 @@ function getSuffix(name) {
417
417
  }
418
418
  const patternMap = {};
419
419
  const cacheMap = {};
420
+ const VITE_ID_PREFIX = "/@id/";
421
+ const VITE_ENCODED_NULL_BYTE_PREFIX = `${VITE_ID_PREFIX}__x00__`;
422
+ function escapeRegExp$1(value) {
423
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
424
+ }
425
+ function createViteEncodedIdPrefixRegExp(sourcePrefix = "") {
426
+ return new RegExp(`^(?:${escapeRegExp$1(VITE_ENCODED_NULL_BYTE_PREFIX)})?${sourcePrefix}`);
427
+ }
428
+ function toViteEncodedId(id) {
429
+ return `${VITE_ENCODED_NULL_BYTE_PREFIX}${id}`;
430
+ }
431
+ function decodeViteId(id) {
432
+ if (!id.startsWith("/@id/")) return id;
433
+ const viteId = id.slice(5);
434
+ return viteId.startsWith("__x00__") ? `\0${viteId.slice(7)}` : viteId;
435
+ }
420
436
  function assertModuleFound(tag, str = "") {
421
437
  const module = VirtualModule.findModule(tag, str);
422
438
  if (!module) throw createModuleFederationError(`Module Federation shared module '${str}' not found. Please ensure it's installed as a dependency in your package.json.`);
423
439
  return module;
424
440
  }
425
- var VirtualModule = class {
441
+ function normalizeVirtualModuleId(id) {
442
+ const decoded = decodeViteId(id).replace(/^\0+/, "");
443
+ const queryIndex = decoded.indexOf("?");
444
+ const hashIndex = decoded.indexOf("#");
445
+ const endIndex = queryIndex === -1 ? hashIndex : hashIndex === -1 ? queryIndex : Math.min(queryIndex, hashIndex);
446
+ return endIndex === -1 ? decoded : decoded.slice(0, endIndex);
447
+ }
448
+ var VirtualModule = class VirtualModule {
426
449
  name;
427
450
  tag;
428
451
  suffix;
429
452
  inited = false;
430
453
  code;
431
- static findModule(tag, str = "") {
454
+ static findName(tag, str = "") {
432
455
  if (!patternMap[tag]) patternMap[tag] = new RegExp(`(.*${packageNameEncode(tag)}(.+?)${packageNameEncode(tag)}.*)`);
433
- const moduleName = (str.match(patternMap[tag]) || [])[2];
434
- if (moduleName) return cacheMap[tag][packageNameDecode(moduleName)];
456
+ const moduleName = (normalizeVirtualModuleId(str).match(patternMap[tag]) || [])[2];
457
+ return moduleName ? packageNameDecode(moduleName) : void 0;
458
+ }
459
+ static findModule(tag, str = "") {
460
+ const moduleName = VirtualModule.findName(tag, str);
461
+ return moduleName ? cacheMap[tag][moduleName] : void 0;
435
462
  }
436
463
  static findById(id) {
437
- const normalized = id.replace(/^\0+/, "").replace(/^\/@id\//, "").replace(/^__x00__/, "").replace(/[?#].*$/, "");
464
+ const normalized = normalizeVirtualModuleId(id);
438
465
  for (const modules of Object.values(cacheMap)) for (const module of Object.values(modules)) if (module.getImportId() === normalized) return module;
439
466
  }
440
467
  constructor(name, tag = "__mf_v__", suffix = "") {
@@ -748,11 +775,9 @@ function getPackageEsmEntryPath(pkg) {
748
775
  resolveSubpathWithRequire: false
749
776
  }) || resolvePackageEntryFromProjectRoot(pkg);
750
777
  }
751
- function getEsmNamedExports(pkg) {
778
+ function getEsmNamedExportsFromFile(entryPath) {
752
779
  let source = "";
753
- let entryPath;
754
780
  try {
755
- entryPath = getPackageEsmEntryPath(pkg);
756
781
  if (!entryPath) return [];
757
782
  const { initSync, parse } = localRequire("es-module-lexer");
758
783
  initSync();
@@ -767,6 +792,48 @@ function getEsmNamedExports(pkg) {
767
792
  return source ? getNamedExportsViaRegex(source, entryPath) : [];
768
793
  }
769
794
  }
795
+ function getEsmNamedExports(pkg) {
796
+ return getEsmNamedExportsFromFile(getPackageEsmEntryPath(pkg));
797
+ }
798
+ function resolveConfiguredImportPath(importSource) {
799
+ if (path.isAbsolute(importSource)) return resolveFileLikeModule(importSource);
800
+ const projectRoot = getPackageDetectionCwd();
801
+ if (importSource.startsWith(".")) return resolveFileLikeModule(path.resolve(projectRoot, importSource));
802
+ const esmEntry = getInstalledPackageEntry(importSource, {
803
+ conditions: [
804
+ "browser",
805
+ "import",
806
+ "module",
807
+ "default"
808
+ ],
809
+ resolveSubpathWithRequire: false
810
+ });
811
+ if (esmEntry) return esmEntry;
812
+ try {
813
+ return createRequire(new URL(`file://${path.join(projectRoot, "package.json")}`)).resolve(importSource);
814
+ } catch {
815
+ return;
816
+ }
817
+ }
818
+ function resolveFileLikeModule(filePath) {
819
+ if (existsSync(filePath) && !statSync(filePath).isDirectory()) return filePath;
820
+ const extensions = [
821
+ ".ts",
822
+ ".tsx",
823
+ ".js",
824
+ ".jsx",
825
+ ".mjs",
826
+ ".mts"
827
+ ];
828
+ for (const ext of extensions) {
829
+ const candidate = filePath + ext;
830
+ if (existsSync(candidate) && !statSync(candidate).isDirectory()) return candidate;
831
+ }
832
+ for (const ext of extensions) {
833
+ const candidate = path.join(filePath, "index" + ext);
834
+ if (existsSync(candidate) && !statSync(candidate).isDirectory()) return candidate;
835
+ }
836
+ }
770
837
  function resolveRelativeModule(filePath, specifier) {
771
838
  const dir = path.dirname(filePath);
772
839
  const exact = path.resolve(dir, specifier);
@@ -793,12 +860,25 @@ function getNamedExportsViaRegex(source, filePath, visited) {
793
860
  const names = /* @__PURE__ */ new Set();
794
861
  visited = visited || /* @__PURE__ */ new Set();
795
862
  if (filePath) visited.add(filePath);
796
- const declRegex = new RegExp(`export\\s+(?:async\\s+)?(?:function(?:\\*\\s*|\\s+\\*?\\s*)|const\\s+|let\\s+|var\\s+|class\\s+)(${JS_IDENTIFIER_PATTERN})`, "gu");
863
+ 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");
797
864
  let match;
798
865
  while ((match = declRegex.exec(source)) !== null) {
799
866
  const name = match[1];
800
867
  if (isValidEsmExportName(name)) names.add(name);
801
868
  }
869
+ const destructureRegex = /export\s+(?:const|let|var)\s+(\{[^}]*\}|\[[^\]]*\])\s*=/g;
870
+ const bindingNameRegex = new RegExp(`^(${JS_IDENTIFIER_PATTERN})`, "u");
871
+ while ((match = destructureRegex.exec(source)) !== null) {
872
+ const inner = match[1].slice(1, -1);
873
+ for (const part of inner.split(",")) {
874
+ let token = part.split("=")[0].trim();
875
+ if (token.startsWith("...")) token = token.slice(3).trim();
876
+ if (!token) continue;
877
+ if (token.includes(":")) token = token.slice(token.indexOf(":") + 1).trim();
878
+ const bindingMatch = token.match(bindingNameRegex);
879
+ if (bindingMatch && isValidEsmExportName(bindingMatch[1])) names.add(bindingMatch[1]);
880
+ }
881
+ }
802
882
  const listRegex = /export\s*\{([^}]+)\}/g;
803
883
  const typeOnlySpecifierRegex = new RegExp(`^type\\s+${JS_IDENTIFIER_PATTERN}(?:\\s+as\\s+${JS_IDENTIFIER_PATTERN})?$`, "u");
804
884
  const exportSpecifierRegex = new RegExp(`(?:\\S+\\s+as\\s+)?(${JS_IDENTIFIER_PATTERN})$`, "u");
@@ -836,6 +916,14 @@ function getPackageNamedExports(pkg) {
836
916
  return getEsmNamedExports(pkg);
837
917
  }
838
918
  }
919
+ function getSharedNamedExports(pkg, shareItem) {
920
+ const configuredImport = shareItem?.shareConfig.import;
921
+ if (typeof configuredImport === "string") {
922
+ const configuredNamedExports = getEsmNamedExportsFromFile(resolveConfiguredImportPath(configuredImport));
923
+ if (configuredNamedExports.length > 0) return configuredNamedExports;
924
+ }
925
+ return getPackageNamedExports(pkg);
926
+ }
839
927
  function getLocalProviderImportPath(pkg) {
840
928
  try {
841
929
  const resolved = createRequire(new URL(`file://${path.join(getPackageDetectionCwd(), "package.json")}`)).resolve(pkg);
@@ -906,6 +994,20 @@ function writePreBuildLibPath(pkg, shareItem) {
906
994
  if (!preBuildCacheMap[pkg]) preBuildCacheMap[pkg] = new VirtualModule(pkg, PREBUILD_TAG, ".js");
907
995
  preBuildShareItemMap[pkg] = shareItem;
908
996
  const importSource = getConcreteSharedImportSource(pkg, shareItem) || pkg;
997
+ if (pkg === "react/compiler-runtime") {
998
+ preBuildCacheMap[pkg].writeSync(`
999
+ const __mfCacheGlobalKey = "__mf_module_cache__";
1000
+ export const c = function(size) {
1001
+ const cache = globalThis[__mfCacheGlobalKey]?.share;
1002
+ const sharedReact = cache?.['react'];
1003
+ const reactExports = sharedReact?.default ?? sharedReact;
1004
+ const internals = reactExports?.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
1005
+ return internals?.H?.useMemoCache(size);
1006
+ };
1007
+ export default { c };
1008
+ `, true);
1009
+ return;
1010
+ }
909
1011
  if (pkg === "react/jsx-dev-runtime") {
910
1012
  preBuildCacheMap[pkg].writeSync(`
911
1013
  import __mfPrebuildDefault from ${escapeGeneratedStringLiteral(importSource)};
@@ -929,7 +1031,7 @@ function writePreBuildLibPath(pkg, shareItem) {
929
1031
  `, true);
930
1032
  return;
931
1033
  }
932
- const namedExports = getPackageNamedExports(pkg);
1034
+ const namedExports = getSharedNamedExports(pkg, shareItem);
933
1035
  if (namedExports.length > 0) {
934
1036
  const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
935
1037
  const declarations = namedExports.map((name, i) => `const ${namedExportVars[i]} = __mfPrebuildExports[${escapeGeneratedStringLiteral(name)}];`).join("\n ");
@@ -969,6 +1071,27 @@ function getLoadShareModulePath(pkg, isRolldown) {
969
1071
  if (!loadShareCacheMap[pkg]) getLoadShareImportId(pkg, isRolldown);
970
1072
  return loadShareCacheMap[pkg].getImportId();
971
1073
  }
1074
+ function toViteOptimizedDepVirtualId(id) {
1075
+ return toViteEncodedId(id);
1076
+ }
1077
+ function getCachedLoadSharePkg(id) {
1078
+ const normalized = normalizeVirtualModuleId(id);
1079
+ if (!normalized.startsWith("virtual:mf:")) return;
1080
+ const pkg = VirtualModule.findName(LOAD_SHARE_TAG, normalized);
1081
+ if (!pkg) return;
1082
+ return pkg;
1083
+ }
1084
+ function materializeCachedLoadShareModule(options) {
1085
+ const pkg = getCachedLoadSharePkg(options.id);
1086
+ if (!pkg) return;
1087
+ const key = options.findSharedKey(pkg, options.shared);
1088
+ if (!key) return;
1089
+ const shareItem = options.shared[key];
1090
+ writeLoadShareModule(pkg, shareItem, options.command, options.isRolldown);
1091
+ if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(pkg, shareItem);
1092
+ options.addUsedShares(pkg);
1093
+ options.writeLocalSharedImportMap();
1094
+ }
972
1095
  function generateDeferredHostProvidedExports(namedExports, pkg, cacheKey) {
973
1096
  const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
974
1097
  const declarations = ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ");
@@ -1036,7 +1159,7 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
1036
1159
  const lazyLocalFallbackSource = concreteSharedImportSource || localProviderPath || sharedImportSource;
1037
1160
  const skipServePrebuildWarmup = command !== "build" && (pkg === "lit" || pkg.startsWith("lit/"));
1038
1161
  const usesLazyLocalFallback = isWorkspacePackage && shareItem.shareConfig.singleton === true;
1039
- const namedExports = getPackageNamedExports(pkg);
1162
+ const namedExports = getSharedNamedExports(pkg, shareItem);
1040
1163
  let exportLine;
1041
1164
  if (namedExports.length > 0) {
1042
1165
  const destructure = `const { ${namedExports.map((name, i) => `${name}: __mf_${i}`).join(", ")} } = exportModule;`;
@@ -1136,7 +1259,7 @@ function generateLocalSharedImportMap() {
1136
1259
  version: ${JSON.stringify(shareItem.version)},
1137
1260
  scope: [${JSON.stringify(shareItem.scope)}],
1138
1261
  loaded: false,
1139
- from: ${JSON.stringify(options.internalName)},
1262
+ from: ${JSON.stringify(options.name)},
1140
1263
  async get () {
1141
1264
  if (${shareItem.shareConfig.import === false}) {
1142
1265
  throw new Error(\`[Module Federation] Shared module '\${${JSON.stringify(key)}}' must be provided by host\`);
@@ -1307,7 +1430,7 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
1307
1430
  ${getRuntimeModuleCacheBootstrapCode()}
1308
1431
  const initTokens = {}
1309
1432
  const shareScopeName = ${JSON.stringify(options.shareScope)}
1310
- const mfName = ${JSON.stringify(options.internalName)}
1433
+ const mfName = ${JSON.stringify(options.name)}
1311
1434
  let localSharedImportMapPromise
1312
1435
  let exposesMapPromise
1313
1436
  const shouldRetrySharedInitError = ${command !== "build"} && ((error) => {
@@ -1349,6 +1472,28 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
1349
1472
 
1350
1473
  async function init(shared = {}, initScope = []) {
1351
1474
  const {usedShared, usedRemotes} = await getLocalSharedImportMap()
1475
+ try {
1476
+ const allInstances = globalThis.__FEDERATION__?.__SHARE__;
1477
+ if (allInstances) {
1478
+ ${normalizeRuntimeShareCode}
1479
+ for (const [, scopes] of Object.entries(allInstances)) {
1480
+ const scopeShare = scopes?.['${options.shareScope}'];
1481
+ if (!scopeShare) continue;
1482
+ for (const [pkg, versionMap] of Object.entries(scopeShare)) {
1483
+ for (const [version, provider] of Object.entries(versionMap)) {
1484
+ if (!provider.lib) continue;
1485
+ const cacheKey = provider.shareConfig?.singleton ? pkg : \`\${pkg}@\${version}\`;
1486
+ if (__mfModuleCache.share[cacheKey] !== undefined) continue;
1487
+ const mod = typeof provider.lib === "function" ? provider.lib() : provider.lib;
1488
+ const resolved = await Promise.resolve(mod);
1489
+ __mfModuleCache.share[cacheKey] = __mfNormalizeRuntimeShare(resolved);
1490
+ }
1491
+ }
1492
+ }
1493
+ }
1494
+ } catch (e) {
1495
+ console.error('[Module Federation] Failed to bridge external shared modules', e)
1496
+ }
1352
1497
  ${generateDirectSharedCacheSeedCode(command)}
1353
1498
  const __browserPlugins = [${pluginImportNames.filter((item) => !isSsrOnlyPlugin(item[1])).map((item) => `${item[0]}(${item[2]})`).join(", ")}];
1354
1499
  const __ssrPlugins = typeof globalThis.window === 'undefined'
@@ -1688,7 +1833,8 @@ function patchHashEntryFileNames(config, entryName, fileName) {
1688
1833
  }
1689
1834
  const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClientInjected, skipTransformFor = [] }) => {
1690
1835
  const DEV_HTML_PROXY_PREFIX = "virtual:mf-html-entry-proxy?";
1691
- const ENTRY_BOOTSTRAP_QUERY = "?mf-entry-bootstrap";
1836
+ const ENTRY_BOOTSTRAP_PARAM = "mf-entry-bootstrap";
1837
+ const ENTRY_BOOTSTRAP_QUERY = `?${ENTRY_BOOTSTRAP_PARAM}`;
1692
1838
  const waitsForInit = entryName === "hostInit";
1693
1839
  const getEntryPath = () => typeof entryPath === "function" ? entryPath() : entryPath;
1694
1840
  let devEntryPath = "";
@@ -1706,6 +1852,9 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
1706
1852
  function isSvelteKitServerModule(id) {
1707
1853
  return hasPackageDependency("@sveltejs/kit") && (id.includes(".svelte-kit/generated/") || id.includes("/@sveltejs/kit/src/runtime/server/"));
1708
1854
  }
1855
+ function hasEntryBootstrapParam(id) {
1856
+ return id.includes(ENTRY_BOOTSTRAP_PARAM) || decodeURIComponent(id).includes(ENTRY_BOOTSTRAP_PARAM);
1857
+ }
1709
1858
  function rewriteSvelteKitInlineStart(html, initPath) {
1710
1859
  return html.replace(/<script>([\s\S]*?)<\/script>/gi, (scriptTag, body) => {
1711
1860
  if (!body.includes("kit.start(app, element);") || !body.includes("Promise.all([")) return scriptTag;
@@ -1805,7 +1954,7 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
1805
1954
  return inject === "entry" || !htmlFilePath;
1806
1955
  }
1807
1956
  function normalizeDevHtmlProxyId(id) {
1808
- return id.replace(/^\0/, "").replace(/^\/@id\//, "").replace(/^__x00__/, "");
1957
+ return decodeViteId(id).replace(/^\0/, "");
1809
1958
  }
1810
1959
  function normalizeModuleId(id) {
1811
1960
  return id.split("?")[0].replace(/\\/g, "/");
@@ -1839,7 +1988,7 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
1839
1988
  configResolved(config) {
1840
1989
  viteConfig = config;
1841
1990
  const resolvedEntryPath = getEntryPath();
1842
- if (resolvedEntryPath.startsWith("virtual:mf")) devEntryPath = config.base + "@id/" + resolvedEntryPath;
1991
+ if (resolvedEntryPath.startsWith("virtual:mf")) devEntryPath = config.base + VITE_ID_PREFIX.slice(1) + resolvedEntryPath;
1843
1992
  else {
1844
1993
  const normalized = resolvedEntryPath.replace(/\\\\?/g, "/");
1845
1994
  const root = config.root.replace(/\\\\?/g, "/").replace(/\/$/, "");
@@ -1880,10 +2029,10 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
1880
2029
  const base = viteConfig.base.replace(/\/$/, "");
1881
2030
  const stripBase = (p) => base && p.startsWith(base + "/") ? p.slice(base.length) : p;
1882
2031
  const html = rewriteEntryScripts(c, (originalSrc) => {
1883
- return `/@id/__x00__${DEV_HTML_PROXY_PREFIX}${new URLSearchParams({
2032
+ return toViteEncodedId(`${DEV_HTML_PROXY_PREFIX}${new URLSearchParams({
1884
2033
  init: sanitizeDevEntryPath(stripBase(devEntryPath)),
1885
2034
  entry: sanitizeDevEntryPath(stripBase(originalSrc))
1886
- }).toString()}`;
2035
+ }).toString()}`);
1887
2036
  });
1888
2037
  return html === c ? injectEntryScript(c, stripBase(devEntryPath)) : html;
1889
2038
  }
@@ -2015,7 +2164,7 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
2015
2164
  transform(code, id) {
2016
2165
  if (skipSvelteKitSsrBuild()) return;
2017
2166
  if (isSvelteKitServerModule(id)) return;
2018
- if (id.includes(ENTRY_BOOTSTRAP_QUERY)) return;
2167
+ if (hasEntryBootstrapParam(id)) return;
2019
2168
  if (normalizeModuleId(id).endsWith(".html")) return;
2020
2169
  if (skipTransformIds.has(resolveProjectId(id))) return;
2021
2170
  const transformCtx = this;
@@ -2043,7 +2192,7 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
2043
2192
  return mapCodeToCodeWithSourcemap(code.replace("vueApp.mount(vueAppRootContainer);", `${injection}vueApp.mount(vueAppRootContainer);`));
2044
2193
  }
2045
2194
  const isHydrationEntryFallback = inject === "entry" && entryFiles.length === 0 && (!htmlFilePath || !fs$1.existsSync(htmlFilePath)) && !clientInjected && !id.includes("node_modules") && (id.startsWith("\0") || /\.(js|ts|mjs|vue|jsx|tsx)(\?|$)/.test(id)) && /hydrateRoot|createRoot|ReactDOM\.render/.test(code);
2046
- const isNuxtClientEntryFallback = _command === "serve" && inject === "entry" && entryFiles.length === 0 && (!htmlFilePath || !fs$1.existsSync(htmlFilePath)) && !clientInjected && !id.includes("node_modules/.vite") && /(?:^|\/)nuxt\/dist\/app\/entry\.async\.js(?:\?|$)/.test(id) && code.includes("entry();");
2195
+ const isNuxtClientEntryFallback = _command === "serve" && inject === "entry" && entryFiles.length === 0 && (!htmlFilePath || !fs$1.existsSync(htmlFilePath)) && !clientInjected && !hasEntryBootstrapParam(id) && !id.includes("node_modules/.vite") && /(?:^|\/)nuxt\/dist\/app\/entry\.async\.js(?:\?|$)/.test(id) && code.includes("entry();");
2047
2196
  if (injectEntry() && entryFiles.some((file) => resolveProjectId(id) === file) || _command === "serve" && inject === "html" && !isVinext && !clientInjected && !id.startsWith("\0") && !id.includes("node_modules") && /\.(js|ts|mjs|vue|jsx|tsx)(\?|$)/.test(id) || isHydrationEntryFallback || isNuxtClientEntryFallback) {
2048
2197
  clientInjected = true;
2049
2198
  if (!waitsForInit || _command === "serve" && inject === "entry" && isHydrationEntryFallback) return mapCodeToCodeWithSourcemap(`import ${JSON.stringify(getEntryPath())};\n` + code);
@@ -2829,9 +2978,19 @@ const processModuleAssets = (bundle, filesMap, moduleMatcher, options = {}) => {
2829
2978
  foundCssViaMetadata = true;
2830
2979
  }
2831
2980
  if (!foundCssViaMetadata && chunkContainsCssModules(fileData.modules)) for (const cssAsset of Array.from(bundleCssAssets)) trackAsset(filesMap, matchKey, cssAsset, false, "css");
2832
- if (fileData.dynamicImports) for (const dynamicImport of fileData.dynamicImports) {
2833
- if (!bundle[dynamicImport]) continue;
2834
- trackAsset(filesMap, matchKey, dynamicImport, true, isCSSFile(dynamicImport) ? "css" : "js");
2981
+ const visited = /* @__PURE__ */ new Set();
2982
+ const queue = [fileName];
2983
+ for (let queueIndex = 0; queueIndex < queue.length; queueIndex++) {
2984
+ const cur = queue[queueIndex];
2985
+ if (visited.has(cur)) continue;
2986
+ visited.add(cur);
2987
+ const chunk = bundle[cur];
2988
+ if (!chunk || chunk.type !== "chunk") continue;
2989
+ if (chunk.dynamicImports) for (const dynamicImport of chunk.dynamicImports) {
2990
+ if (!bundle[dynamicImport]) continue;
2991
+ trackAsset(filesMap, matchKey, dynamicImport, true, isCSSFile(dynamicImport) ? "css" : "js");
2992
+ }
2993
+ if (chunk.imports) for (const imp of chunk.imports) queue.push(imp);
2835
2994
  }
2836
2995
  }
2837
2996
  }
@@ -2879,7 +3038,11 @@ const buildFileToShareKeyMap = async (shareKeys, resolveFn) => {
2879
3038
  //#endregion
2880
3039
  //#region src/utils/pathNormalization.ts
2881
3040
  const COMMON_SHARED_SUBPATHS = {
2882
- react: ["react/jsx-runtime", "react/jsx-dev-runtime"],
3041
+ react: [
3042
+ "react/jsx-runtime",
3043
+ "react/jsx-dev-runtime",
3044
+ "react/compiler-runtime"
3045
+ ],
2883
3046
  "react-dom": [
2884
3047
  "react-dom/client",
2885
3048
  "react-dom/server",
@@ -3014,11 +3177,11 @@ function generateRemoteEntrySSR(options) {
3014
3177
  */
3015
3178
  async function init(shared = {}, initScope = []) {
3016
3179
  const initRes = runtimeInit({
3017
- name: ${JSON.stringify(options.internalName)},
3180
+ name: ${JSON.stringify(options.name)},
3018
3181
  remotes: [],
3019
3182
  shared: {},
3020
3183
  });
3021
- const initToken = { from: ${JSON.stringify(options.internalName)} };
3184
+ const initToken = { from: ${JSON.stringify(options.name)} };
3022
3185
  if (initScope.indexOf(initToken) >= 0) return;
3023
3186
  initScope.push(initToken);
3024
3187
  initRes.initShareScopeMap(${JSON.stringify(options.shareScope)}, shared);
@@ -3611,9 +3774,16 @@ function findSharedKey(source, shared) {
3611
3774
  function findSharedKeyForSource(source, shared) {
3612
3775
  const key = findSharedKey(source, shared);
3613
3776
  if (key) return key;
3777
+ const explicitSharedSubpathKeys = Object.keys(shared || {}).filter((sharedKey) => getPackageName(sharedKey) !== sharedKey && !sharedKey.endsWith("/"));
3614
3778
  if (isNodeModulePath(source)) {
3615
- const explicitSubpathKey = getMatchingNodeModuleSubpath(source, Object.keys(shared || {}).filter((sharedKey) => sharedKey.includes("/") && !sharedKey.endsWith("/")));
3779
+ const explicitSubpathKey = getMatchingNodeModuleSubpath(source, explicitSharedSubpathKeys);
3616
3780
  if (explicitSubpathKey) return explicitSubpathKey;
3781
+ const normalizedSource = normalizeNodeModulePath(source);
3782
+ const explicitSubpathEntryKey = explicitSharedSubpathKeys.find((sharedKey) => {
3783
+ const entry = getInstalledPackageEntry(sharedKey, { cwd: getPackageDetectionCwd() });
3784
+ return entry ? normalizeNodeModulePath(entry) === normalizedSource : false;
3785
+ });
3786
+ if (explicitSubpathEntryKey) return explicitSubpathEntryKey;
3617
3787
  }
3618
3788
  const packageName = getPackageNameFromNodeModulePath(source);
3619
3789
  return packageName ? findSharedKey(packageName, shared) : void 0;
@@ -3658,6 +3828,7 @@ function proxySharedModule(options) {
3658
3828
  let useRolldown = false;
3659
3829
  const savePrebuild = new PromiseStore();
3660
3830
  let devServer;
3831
+ const materializedLoadShareSources = /* @__PURE__ */ new Set();
3661
3832
  return [
3662
3833
  {
3663
3834
  name: "generateLocalSharedImportMap",
@@ -3732,11 +3903,14 @@ function proxySharedModule(options) {
3732
3903
  if (shouldSkipTaggedImporterProxy(key, "__prebuild__")) return;
3733
3904
  const shareSource = key === "vue" && source.startsWith("vue/dist/") ? key : isNodeModulePath(source) ? getCommonSharedSubpathFromNodeModulePath(source, key) || key : source;
3734
3905
  const loadSharePath = getLoadShareModulePath(shareSource, useRolldown);
3735
- writeLoadShareModule(shareSource, shared[key], _command, useRolldown);
3736
- if (shared[key].shareConfig.import !== false) writePreBuildLibPath(shareSource, shared[key]);
3737
- addUsedShares(shareSource);
3738
- writeLocalSharedImportMap();
3739
- refreshHostAutoInit();
3906
+ if (!materializedLoadShareSources.has(shareSource)) {
3907
+ materializedLoadShareSources.add(shareSource);
3908
+ writeLoadShareModule(shareSource, shared[key], _command, useRolldown);
3909
+ if (shared[key].shareConfig.import !== false) writePreBuildLibPath(shareSource, shared[key]);
3910
+ addUsedShares(shareSource);
3911
+ writeLocalSharedImportMap();
3912
+ refreshHostAutoInit();
3913
+ }
3740
3914
  return this.resolve(loadSharePath, importer, { skipSelf: true });
3741
3915
  }
3742
3916
  },
@@ -4260,7 +4434,7 @@ function pluginSSRRemoteEntry(options) {
4260
4434
  try {
4261
4435
  result = await fetchFn(id, importer, opts);
4262
4436
  } catch (fetchErr) {
4263
- const bareId = id.startsWith("/@id/") ? id.slice(5).replace(/^__x00__/, "\0") : id;
4437
+ const bareId = decodeViteId(id);
4264
4438
  try {
4265
4439
  const { createRequire } = await import("module");
4266
4440
  const resolved = createRequire(new URL(`file://${server.config.root}/package.json`)).resolve(bareId.replace(/^\0/, ""));
@@ -4515,6 +4689,8 @@ var normalizeOptimizeDeps_default = {
4515
4689
  //#endregion
4516
4690
  //#region src/index.ts
4517
4691
  const patchedManualChunks = /* @__PURE__ */ new WeakSet();
4692
+ const PRELOAD_HELPER_CHUNK = "vite-preload-helper";
4693
+ const PRELOAD_HELPER_TEST = /\0?vite\/preload-helper/;
4518
4694
  function normalizeVinextRscPreloadHints(code) {
4519
4695
  return code.replace(/(:HL\[[^\]\n]*?,)"stylesheet"/g, "$1\"style\"").replace(/(:HL\[[^\]\n]*?,)\\"stylesheet\\"/g, "$1\\\"style\\\"");
4520
4696
  }
@@ -4582,6 +4758,14 @@ function isFederationHtmlPreloadDependency(dep, includeSharedRuntime = false) {
4582
4758
  if (file.includes("__mfe_internal__") || file.includes("virtual_mf-") || file.includes("virtualExposes") || file.includes("localSharedImportMap") || file.includes("hostInit")) return true;
4583
4759
  return includeSharedRuntime && (file.includes("preload-helper") || file.includes("rolldown-runtime") || file.startsWith("dist-"));
4584
4760
  }
4761
+ function canResolveSharedSubpath(subpath, projectRoot) {
4762
+ try {
4763
+ createRequire(new URL(`file://${projectRoot}/package.json`)).resolve(subpath);
4764
+ return true;
4765
+ } catch {
4766
+ return false;
4767
+ }
4768
+ }
4585
4769
  /**
4586
4770
  * Plugin that runs FIRST to register generated virtual modules in the config hook.
4587
4771
  * This prevents 504 "Outdated Optimize Dep" errors by ensuring ids are known
@@ -4648,7 +4832,7 @@ function createEarlyVirtualModulesPlugin(options) {
4648
4832
  optimizeDeps.esbuildOptions.plugins.push({
4649
4833
  name: "module-federation:optimize-shared-proxy",
4650
4834
  setup(build) {
4651
- build.onResolve({ filter: /^virtual:mf:/ }, (args) => ({
4835
+ build.onResolve({ filter: createViteEncodedIdPrefixRegExp("virtual:mf:") }, (args) => ({
4652
4836
  path: args.path,
4653
4837
  external: true
4654
4838
  }));
@@ -4668,15 +4852,15 @@ function createEarlyVirtualModulesPlugin(options) {
4668
4852
  const key = findSharedKey(args.path, shared);
4669
4853
  if (!key) return;
4670
4854
  const shareItem = shared[key];
4671
- const loadSharePath = getLoadShareModulePath(args.path, isRolldown);
4855
+ const optimizedLoadSharePath = toViteOptimizedDepVirtualId(getLoadShareModulePath(args.path, isRolldown));
4672
4856
  writeLoadShareModule(args.path, shareItem, _command, isRolldown);
4673
4857
  if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(args.path, shareItem);
4674
4858
  addUsedShares(args.path);
4675
4859
  return {
4676
4860
  loader: "js",
4677
4861
  resolveDir: root,
4678
- contents: `import * as __mfShared from ${JSON.stringify(loadSharePath)};
4679
- export * from ${JSON.stringify(loadSharePath)};
4862
+ contents: `import * as __mfShared from ${JSON.stringify(optimizedLoadSharePath)};
4863
+ export * from ${JSON.stringify(optimizedLoadSharePath)};
4680
4864
  export default __mfShared.default ?? __mfShared;`
4681
4865
  };
4682
4866
  });
@@ -4690,9 +4874,11 @@ export default __mfShared.default ?? __mfShared;`
4690
4874
  if (_command === "serve" && shareItem.shareConfig?.import !== false) {
4691
4875
  const optimizeDeps = config.optimizeDeps ??= {};
4692
4876
  optimizeDeps.include ??= [];
4877
+ optimizeDeps.exclude ??= [];
4693
4878
  for (const subpath of getCommonSharedSubpaths(key)) {
4694
4879
  writePreBuildLibPath(subpath, shareItem);
4695
- optimizeDeps.include.push(subpath);
4880
+ if (canResolveSharedSubpath(subpath, root)) optimizeDeps.include.push(subpath);
4881
+ else optimizeDeps.exclude.push(subpath);
4696
4882
  }
4697
4883
  }
4698
4884
  continue;
@@ -4716,7 +4902,8 @@ export default __mfShared.default ?? __mfShared;`
4716
4902
  writeLoadShareModule(subpath, shareItem, _command, isRolldown);
4717
4903
  writePreBuildLibPath(subpath, shareItem);
4718
4904
  addUsedShares(subpath);
4719
- optimizeDeps.include.push(subpath);
4905
+ if (canResolveSharedSubpath(subpath, root)) optimizeDeps.include.push(subpath);
4906
+ else optimizeDeps.exclude.push(subpath);
4720
4907
  }
4721
4908
  }
4722
4909
  }
@@ -4737,6 +4924,7 @@ export default __mfShared.default ?? __mfShared;`
4737
4924
  "react-dom",
4738
4925
  "react/jsx-runtime",
4739
4926
  "react/jsx-dev-runtime",
4927
+ "react/compiler-runtime",
4740
4928
  "@module-federation/runtime",
4741
4929
  "@module-federation/runtime-core",
4742
4930
  "@module-federation/sdk"
@@ -4777,7 +4965,19 @@ function federation(mfUserOptions) {
4777
4965
  name: "vite:module-federation-virtual-modules",
4778
4966
  enforce: "pre",
4779
4967
  resolveId(id) {
4780
- const virtualModule = VirtualModule.findById(id);
4968
+ let virtualModule = VirtualModule.findById(id);
4969
+ if (!virtualModule) {
4970
+ materializeCachedLoadShareModule({
4971
+ id,
4972
+ shared: options.shared,
4973
+ command,
4974
+ isRolldown: getIsRolldown(this),
4975
+ findSharedKey,
4976
+ addUsedShares,
4977
+ writeLocalSharedImportMap
4978
+ });
4979
+ virtualModule = VirtualModule.findById(id);
4980
+ }
4781
4981
  if (!virtualModule) return;
4782
4982
  return virtualModule.getResolvedId();
4783
4983
  },
@@ -4796,7 +4996,8 @@ function federation(mfUserOptions) {
4796
4996
  resolveId(id) {
4797
4997
  const reactServerEntryMap = {
4798
4998
  "react/jsx-runtime": "react/cjs/react-jsx-runtime.production.js",
4799
- "react/jsx-dev-runtime": "react/cjs/react-jsx-dev-runtime.production.js"
4999
+ "react/jsx-dev-runtime": "react/cjs/react-jsx-dev-runtime.production.js",
5000
+ "react/compiler-runtime": "react/cjs/react-compiler-runtime.production.js"
4800
5001
  };
4801
5002
  if (!(id in reactServerEntryMap)) return;
4802
5003
  const environmentName = this.environment?.name;
@@ -4898,6 +5099,8 @@ function federation(mfUserOptions) {
4898
5099
  }
4899
5100
  if (!output?.codeSplitting || typeof output.codeSplitting !== "object") return;
4900
5101
  if (!("groups" in output.codeSplitting)) return;
5102
+ const groups = output.codeSplitting.groups;
5103
+ if (Array.isArray(groups) && groups.some((group) => typeof group?.name === "function" && patchedManualChunks.has(group.name))) return;
4901
5104
  delete output.codeSplitting.groups;
4902
5105
  if (Object.keys(output.codeSplitting).length === 0) delete output.codeSplitting;
4903
5106
  if (warnedAboutCodeSplittingGroups) return;
@@ -4905,27 +5108,45 @@ function federation(mfUserOptions) {
4905
5108
  mfWarn("Ignoring `output.codeSplitting.groups` because it conflicts with module federation. Grouping shared dependency init wrappers with their dependent modules can break runtime init order and cause standalone remotes to fail before mount.");
4906
5109
  };
4907
5110
  let warnedAboutManualChunks = false;
4908
- const applyManualChunks = (output) => {
5111
+ const applyManualChunks = (output, useCodeSplitting) => {
4909
5112
  ensureCodeSplitting(output);
4910
5113
  const isPatchedByPlugin = typeof output.manualChunks === "function" && patchedManualChunks.has(output.manualChunks);
4911
5114
  if (output.manualChunks && !isPatchedByPlugin && !warnedAboutManualChunks) {
4912
5115
  warnedAboutManualChunks = true;
4913
5116
  mfWarn("Ignoring `output.manualChunks` because it conflicts with module federation. Module federation transforms shared dependency imports with async init wrappers, and grouping these transformed modules into a single chunk creates circular async dependencies that cause the application to silently hang.");
4914
5117
  }
4915
- const mfManualChunks = function(id) {
5118
+ const mfChunkName = function(id) {
4916
5119
  if (id.includes(runtimeInitId)) return "runtimeInit";
4917
5120
  if (id.includes("__loadShare__")) {
4918
5121
  const match = id.match(/([^/\\]+__loadShare__[^/\\]+)/);
4919
5122
  return match ? match[1] : "loadShare";
4920
5123
  }
5124
+ return null;
5125
+ };
5126
+ patchedManualChunks.add(mfChunkName);
5127
+ if (!useCodeSplitting) {
5128
+ const mfManualChunks = function(id) {
5129
+ return mfChunkName(id) ?? void 0;
5130
+ };
5131
+ patchedManualChunks.add(mfManualChunks);
5132
+ output.manualChunks = mfManualChunks;
5133
+ return;
5134
+ }
5135
+ const groups = [{
5136
+ name: PRELOAD_HELPER_CHUNK,
5137
+ test: PRELOAD_HELPER_TEST,
5138
+ priority: 100
5139
+ }, { name: mfChunkName }];
5140
+ output.codeSplitting = {
5141
+ ...output.codeSplitting || {},
5142
+ groups
4921
5143
  };
4922
- patchedManualChunks.add(mfManualChunks);
4923
- output.manualChunks = mfManualChunks;
5144
+ delete output.manualChunks;
4924
5145
  };
4925
5146
  config.build.rollupOptions = config.build.rollupOptions || {};
4926
5147
  const rollupOutput = config.build.rollupOptions.output;
4927
- if (Array.isArray(rollupOutput)) rollupOutput.forEach((output) => applyManualChunks(output));
4928
- else applyManualChunks(config.build.rollupOptions.output ||= {});
5148
+ if (Array.isArray(rollupOutput)) rollupOutput.forEach((output) => applyManualChunks(output, false));
5149
+ else applyManualChunks(config.build.rollupOptions.output ||= {}, false);
4929
5150
  const buildWithRolldown = config.build;
4930
5151
  buildWithRolldown.rolldownOptions = buildWithRolldown.rolldownOptions || {};
4931
5152
  const rolldownOutput = buildWithRolldown.rolldownOptions.output;
@@ -4935,10 +5156,10 @@ function federation(mfUserOptions) {
4935
5156
  assetFileNames: output.assetFileNames
4936
5157
  });
4937
5158
  if (Array.isArray(rolldownOutput)) {
4938
- rolldownOutput.forEach((output) => applyManualChunks(output));
5159
+ rolldownOutput.forEach((output) => applyManualChunks(output, true));
4939
5160
  desiredRolldownOutput = rolldownOutput.map((output) => snapshotRolldownOutput(output));
4940
5161
  } else {
4941
- applyManualChunks(buildWithRolldown.rolldownOptions.output ||= {});
5162
+ applyManualChunks(buildWithRolldown.rolldownOptions.output ||= {}, true);
4942
5163
  desiredRolldownOutput = [snapshotRolldownOutput(buildWithRolldown.rolldownOptions.output)];
4943
5164
  }
4944
5165
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@module-federation/vite",
3
- "version": "1.16.2",
3
+ "version": "1.16.4",
4
4
  "description": "Vite plugin for Module Federation",
5
5
  "type": "module",
6
6
  "main": "./lib/index.cjs",
@@ -77,23 +77,23 @@
77
77
  "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
78
78
  },
79
79
  "dependencies": {
80
- "@module-federation/dts-plugin": "2.5.0",
81
- "@module-federation/runtime": "2.5.0",
82
- "@module-federation/sdk": "2.5.0",
83
- "es-module-lexer": "^2.0.0",
84
- "estree-walker": "^3.0.3",
85
- "pathe": "^2.0.3"
80
+ "@module-federation/dts-plugin": "2.5.1",
81
+ "@module-federation/runtime": "2.5.1",
82
+ "@module-federation/sdk": "2.5.1",
83
+ "es-module-lexer": "2.1.0",
84
+ "estree-walker": "3.0.3",
85
+ "pathe": "2.0.3"
86
86
  },
87
87
  "devDependencies": {
88
- "@changesets/cli": "^2.30.0",
89
- "@playwright/test": "^1.58.2",
90
- "@types/node": "^25.3.3",
91
- "husky": "^9.1.7",
92
- "oxfmt": "^0.36.0",
93
- "rollup": "^4.47.1",
94
- "tsdown": "^0.21.0",
88
+ "@changesets/cli": "2.30.0",
89
+ "@playwright/test": "1.58.2",
90
+ "@types/node": "25.3.3",
91
+ "husky": "9.1.7",
92
+ "oxfmt": "0.36.0",
93
+ "rollup": "4.47.1",
94
+ "tsdown": "0.21.0",
95
95
  "typescript": "5.9.3",
96
- "vite": "^8.0.10",
97
- "vitest": "^4.0.18"
96
+ "vite": "8.0.10",
97
+ "vitest": "4.0.18"
98
98
  }
99
99
  }