@module-federation/vite 1.15.2 → 1.15.3

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.
Files changed (3) hide show
  1. package/lib/index.cjs +185 -131
  2. package/lib/index.mjs +189 -135
  3. package/package.json +2 -1
package/lib/index.cjs CHANGED
@@ -544,7 +544,7 @@ function normalizeShareItem(key, shareItem) {
544
544
  shareConfig: {
545
545
  import: shareItem.import,
546
546
  singleton: shareItem.singleton || false,
547
- requiredVersion: shareItem.requiredVersion || (version ? `^${version}` : "*"),
547
+ requiredVersion: shareItem.requiredVersion || (isImportFalse ? "*" : version ? `^${version}` : "*"),
548
548
  strictVersion: !!shareItem.strictVersion
549
549
  }
550
550
  };
@@ -661,35 +661,6 @@ function normalizeModuleFederationOptions(options) {
661
661
  }
662
662
  //#endregion
663
663
  //#region src/utils/VirtualModule.ts
664
- /**
665
- * Initialize virtual module infrastructure BEFORE VirtualModule class is used.
666
- * This must be called in the config hook to ensure the directory exists
667
- * before Vite's optimization phase.
668
- */
669
- function initVirtualModuleInfrastructure(root, virtualModuleDir = "__mf__virtual") {
670
- const virtualPackagePath = (0, pathe.join)((0, pathe.join)(root, "node_modules"), virtualModuleDir);
671
- (0, fs.mkdirSync)(virtualPackagePath, { recursive: true });
672
- (0, fs.writeFileSync)((0, pathe.join)(virtualPackagePath, "empty.js"), "");
673
- (0, fs.writeFileSync)((0, pathe.join)(virtualPackagePath, "package.json"), JSON.stringify({
674
- name: virtualModuleDir,
675
- main: "empty.js"
676
- }));
677
- }
678
- let rootDir;
679
- function findNodeModulesDir(root = process.cwd()) {
680
- let currentDir = root;
681
- while (currentDir !== (0, pathe.parse)(currentDir).root) {
682
- const nodeModulesPath = (0, pathe.join)(currentDir, "node_modules");
683
- if ((0, fs.existsSync)(nodeModulesPath)) return nodeModulesPath;
684
- currentDir = (0, pathe.dirname)(currentDir);
685
- }
686
- return "";
687
- }
688
- let cachedNodeModulesDir;
689
- function getNodeModulesDir() {
690
- if (!cachedNodeModulesDir) cachedNodeModulesDir = findNodeModulesDir(rootDir);
691
- return cachedNodeModulesDir;
692
- }
693
664
  function getSuffix(name) {
694
665
  const base = (0, pathe.basename)(name);
695
666
  const dotIndex = base.lastIndexOf(".");
@@ -698,9 +669,6 @@ function getSuffix(name) {
698
669
  }
699
670
  const patternMap = {};
700
671
  const cacheMap = {};
701
- /**
702
- * Physically generate files as virtual modules under node_modules/__mf__virtual/*
703
- */
704
672
  function assertModuleFound(tag, str = "") {
705
673
  const module = VirtualModule.findModule(tag, str);
706
674
  if (!module) throw createModuleFederationError(`Module Federation shared module '${str}' not found. Please ensure it's installed as a dependency in your package.json.`);
@@ -711,33 +679,16 @@ var VirtualModule = class {
711
679
  tag;
712
680
  suffix;
713
681
  inited = false;
714
- /**
715
- * Set the root path for finding node_modules
716
- * @param root - Root path
717
- */
718
- static setRoot(root) {
719
- rootDir = root;
720
- cachedNodeModulesDir = void 0;
721
- }
722
- /**
723
- * Ensure virtual package directory exists
724
- */
725
- static ensureVirtualPackageExists() {
726
- const nodeModulesDir = getNodeModulesDir();
727
- const { virtualModuleDir } = getNormalizeModuleFederationOptions();
728
- const virtualPackagePath = (0, pathe.resolve)(nodeModulesDir, virtualModuleDir);
729
- (0, fs.mkdirSync)(virtualPackagePath, { recursive: true });
730
- (0, fs.writeFileSync)((0, pathe.resolve)(virtualPackagePath, "empty.js"), "");
731
- (0, fs.writeFileSync)((0, pathe.resolve)(virtualPackagePath, "package.json"), JSON.stringify({
732
- name: virtualModuleDir,
733
- main: "empty.js"
734
- }));
735
- }
682
+ code;
736
683
  static findModule(tag, str = "") {
737
684
  if (!patternMap[tag]) patternMap[tag] = new RegExp(`(.*${packageNameEncode(tag)}(.+?)${packageNameEncode(tag)}.*)`);
738
685
  const moduleName = (str.match(patternMap[tag]) || [])[2];
739
686
  if (moduleName) return cacheMap[tag][packageNameDecode(moduleName)];
740
687
  }
688
+ static findById(id) {
689
+ const normalized = id.replace(/^\0+/, "").replace(/^\/@id\//, "").replace(/^__x00__/, "").replace(/[?#].*$/, "");
690
+ for (const modules of Object.values(cacheMap)) for (const module of Object.values(modules)) if (module.getImportId() === normalized) return module;
691
+ }
741
692
  constructor(name, tag = "__mf_v__", suffix = "") {
742
693
  this.name = name;
743
694
  this.tag = tag;
@@ -745,24 +696,20 @@ var VirtualModule = class {
745
696
  if (!cacheMap[this.tag]) cacheMap[this.tag] = {};
746
697
  cacheMap[this.tag][this.name] = this;
747
698
  }
748
- getPath() {
749
- return (0, pathe.resolve)(getNodeModulesDir(), this.getImportId());
750
- }
751
699
  getImportId() {
752
- const { internalName: mfName, virtualModuleDir } = getNormalizeModuleFederationOptions();
753
- return `${virtualModuleDir}/${packageNameEncode(`${mfName}${this.tag}${this.name}${this.tag}`)}${this.suffix}`;
700
+ const { internalName: mfName } = getNormalizeModuleFederationOptions();
701
+ return `virtual:mf:${packageNameEncode(`${mfName}${this.tag}${this.name}${this.tag}`)}${this.suffix}`;
702
+ }
703
+ getResolvedId() {
704
+ return `\0${this.getImportId()}`;
754
705
  }
755
706
  writeSync(code, force) {
756
707
  if (!force && this.inited) return;
757
708
  if (!this.inited) this.inited = true;
758
- const path = this.getPath();
759
- (0, fs.mkdirSync)((0, pathe.dirname)(path), { recursive: true });
760
- (0, fs.writeFileSync)(path, code);
709
+ this.code = code;
761
710
  }
762
711
  write(code) {
763
- const path = this.getPath();
764
- (0, fs.mkdirSync)((0, pathe.dirname)(path), { recursive: true });
765
- (0, fs.writeFile)(path, code, function() {});
712
+ this.writeSync(code, true);
766
713
  }
767
714
  };
768
715
  //#endregion
@@ -964,6 +911,14 @@ globalThis[__mfCacheGlobalKey].remote ||= {};
964
911
  const __mfModuleCache = globalThis[__mfCacheGlobalKey];
965
912
  `;
966
913
  }
914
+ function getRuntimeInitPromiseBootstrapCode() {
915
+ return getRuntimeInitStateBootstrapCode({
916
+ globalKeyVar: "__mfPromiseGlobalKey",
917
+ stateVar: "__mfPromiseState",
918
+ exposedConst: "initPromise",
919
+ exposedProperty: "initPromise"
920
+ });
921
+ }
967
922
  function getRuntimeInitResolveBootstrapCode() {
968
923
  return getRuntimeInitStateBootstrapCode({
969
924
  globalKeyVar: "__mfResolveGlobalKey",
@@ -1208,6 +1163,16 @@ function writePreBuildLibPath(pkg, shareItem) {
1208
1163
  export const jsx = __mfPrebuildExports.jsx;
1209
1164
  export const jsxs = __mfPrebuildExports.jsxs;
1210
1165
  export default __mfPrebuildExports;
1166
+ `, true);
1167
+ return;
1168
+ }
1169
+ const namedExports = getPackageNamedExports(pkg);
1170
+ if (namedExports.length > 0) {
1171
+ preBuildCacheMap[pkg].writeSync(`
1172
+ import * as __mfPrebuildNamespace from ${escapeGeneratedStringLiteral(importSource)};
1173
+ const __mfPrebuildExports = __mfPrebuildNamespace;
1174
+ ${namedExports.map((name) => `export const ${name} = __mfPrebuildExports[${escapeGeneratedStringLiteral(name)}];`).join("\n ")}
1175
+ export default __mfPrebuildExports;
1211
1176
  `, true);
1212
1177
  return;
1213
1178
  }
@@ -1235,25 +1200,62 @@ function getLoadShareImportId(pkg, _isRolldown) {
1235
1200
  }
1236
1201
  function getLoadShareModulePath(pkg, isRolldown) {
1237
1202
  if (!loadShareCacheMap[pkg]) getLoadShareImportId(pkg, isRolldown);
1238
- return loadShareCacheMap[pkg].getPath();
1203
+ return loadShareCacheMap[pkg].getImportId();
1239
1204
  }
1205
+ function generateDeferredHostProvidedExports(namedExports, pkg) {
1206
+ const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
1207
+ const declarations = ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ");
1208
+ const assignments = [...namedExports.map((name, i) => `${namedExportVars[i]} = exportModule[${escapeGeneratedStringLiteral(name)}];`), "__mf_default = exportModule.default ?? exportModule;"].join("\n ");
1209
+ const namedExportLine = namedExports.length > 0 ? `\n export { ${namedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
1210
+ return `${declarations}
1211
+ const __mfApplyHostProvidedExports = (exportModule) => {
1212
+ ${assignments}
1213
+ };
1214
+ let exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}];
1215
+ if (exportModule === undefined) {
1216
+ initPromise.then(() => {
1217
+ exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}];
1218
+ if (exportModule === undefined) {
1219
+ throw new Error("[Module Federation] Shared module ${pkg} was imported before federation bootstrap finished.");
1220
+ }
1221
+ __mfApplyHostProvidedExports(exportModule);
1222
+ });
1223
+ } else {
1224
+ __mfApplyHostProvidedExports(exportModule);
1225
+ }
1226
+ export { __mf_default as default };${namedExportLine}`;
1227
+ }
1228
+ function generateShareModuleUnwrapCode({ source, preserveNamedExports, stopWithReturn }) {
1229
+ return `let current = ${source};
1230
+ for (let i = 0; i < 5; i++) {
1231
+ const defaultExport = current?.default;
1232
+ ${stopWithReturn ? `if (!defaultExport || typeof defaultExport !== "object") return ${stopWithReturn};` : `if (!defaultExport || typeof defaultExport !== "object") break;`}${preserveNamedExports ? `
1233
+ const namedValues = Object.keys(current).filter((key) => key !== "default").map((key) => current[key]);
1234
+ if (namedValues.length > 0 && namedValues.some((value) => value !== undefined)) break;` : ""}
1235
+ current = defaultExport;
1236
+ }
1237
+ return current;`;
1238
+ }
1239
+ const normalizeLocalShareModuleCode = `const __mfNormalizeShareModule = (mod) => {
1240
+ ${generateShareModuleUnwrapCode({
1241
+ source: "mod",
1242
+ preserveNamedExports: true
1243
+ })}
1244
+ };`;
1240
1245
  function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
1241
1246
  if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = new VirtualModule(pkg, LOAD_SHARE_TAG, ".mjs");
1242
1247
  const importLine = getRuntimeModuleCacheBootstrapCode();
1243
1248
  if (shareItem.shareConfig.import === false) {
1244
1249
  const namedExports = getPackageNamedExports(pkg);
1245
1250
  let exportLine;
1246
- if (namedExports.length > 0) exportLine = `export default exportModule.default ?? exportModule;\n ${`const { ${namedExports.map((name, i) => `${name}: __mf_${i}`).join(", ")} } = exportModule;`}\n ${`export { ${namedExports.map((name, i) => `__mf_${i} as ${name}`).join(", ")} };`}`;
1251
+ if (namedExports.length > 0) exportLine = generateDeferredHostProvidedExports(namedExports, pkg);
1247
1252
  else {
1248
1253
  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.`);
1249
- exportLine = "export default exportModule.default ?? exportModule";
1254
+ exportLine = generateDeferredHostProvidedExports([], pkg);
1250
1255
  }
1251
1256
  loadShareCacheMap[pkg].writeSync(`
1257
+ ${getRuntimeInitPromiseBootstrapCode()}
1252
1258
  ${importLine}
1253
- const exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}]
1254
- if (exportModule === undefined) {
1255
- throw new Error("[Module Federation] Shared module ${pkg} was imported before federation bootstrap finished.")
1256
- }
1257
1259
  ${exportLine}
1258
1260
  `, true);
1259
1261
  return;
@@ -1268,8 +1270,20 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
1268
1270
  const usesLazyLocalFallback = isWorkspacePackage && shareItem.shareConfig.singleton === true;
1269
1271
  const namedExports = getPackageNamedExports(pkg);
1270
1272
  let exportLine;
1271
- if (namedExports.length > 0) exportLine = `export default exportModule.default ?? exportModule;\n ${`const { ${namedExports.map((name, i) => `${name}: __mf_${i}`).join(", ")} } = exportModule;`}\n ${`export { ${namedExports.map((name, i) => `__mf_${i} as ${name}`).join(", ")} };`}`;
1272
- else if (usesLazyLocalFallback) exportLine = `export default exportModule.default ?? exportModule`;
1273
+ if (namedExports.length > 0) {
1274
+ const destructure = `const { ${namedExports.map((name, i) => `${name}: __mf_${i}`).join(", ")} } = exportModule;`;
1275
+ const namedExportLine = `export { ${namedExports.map((name, i) => `__mf_${i} as ${name}`).join(", ")} };`;
1276
+ exportLine = `const __mfDefaultExport = (() => {
1277
+ ${generateShareModuleUnwrapCode({
1278
+ source: "exportModule",
1279
+ preserveNamedExports: false,
1280
+ stopWithReturn: "defaultExport ?? current"
1281
+ })}
1282
+ })();
1283
+ export default __mfDefaultExport;
1284
+ ${destructure}
1285
+ ${namedExportLine}`;
1286
+ } else if (usesLazyLocalFallback) exportLine = `export default exportModule.default ?? exportModule`;
1273
1287
  else exportLine = `export default exportModule.default ?? exportModule\n export * from ${escapeGeneratedStringLiteral(sharedImportSource)}`;
1274
1288
  const prebuildImportLine = usesLazyLocalFallback || isWorkspacePackage && command !== "build" ? "" : `import * as __mfLocalShare from ${escapeGeneratedStringLiteral(skipServePrebuildWarmup ? devImportSource : sharedImportSource)};`;
1275
1289
  const devDynamicImportLine = isWorkspacePackage ? "" : command !== "build" && !skipServePrebuildWarmup ? `;() => import(${escapeGeneratedStringLiteral(devImportSource)}).catch(() => {});` : "";
@@ -1277,10 +1291,11 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
1277
1291
  ${prebuildImportLine}
1278
1292
  ${devDynamicImportLine}
1279
1293
  ${importLine}
1294
+ ${normalizeLocalShareModuleCode}
1280
1295
  let exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}]
1281
1296
  if (exportModule === undefined) {
1282
- ${usesLazyLocalFallback ? `exportModule = await import(${escapeGeneratedStringLiteral(lazyLocalFallbackSource)});
1283
- __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}] = exportModule;` : `exportModule = __mfLocalShare;
1297
+ ${usesLazyLocalFallback ? `exportModule = __mfNormalizeShareModule(await import(${escapeGeneratedStringLiteral(lazyLocalFallbackSource)}));
1298
+ __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}] = exportModule;` : `exportModule = __mfNormalizeShareModule(__mfLocalShare);
1284
1299
  __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}] = exportModule;`}
1285
1300
  }
1286
1301
  ${exportLine}
@@ -1438,9 +1453,9 @@ function getShareItemForPreload(pkg) {
1438
1453
  function generateSharedCacheSeedItem(pkg, importPath) {
1439
1454
  return `if (__mfModuleCache.share[${JSON.stringify(pkg)}] === undefined) {
1440
1455
  const mod = await import(${JSON.stringify(importPath)});
1441
- const exportModule = ${JSON.stringify(shouldUseDirectReactImport())} && ${JSON.stringify(pkg)} === "react"
1442
- ? (mod?.default ?? mod)
1443
- : {...mod};
1456
+ ${normalizeRuntimeShareCode}
1457
+ const normalizedModule = __mfNormalizeRuntimeShare(mod);
1458
+ const exportModule = normalizedModule === mod ? {...mod} : normalizedModule;
1444
1459
  Object.defineProperty(exportModule, "__esModule", {
1445
1460
  value: true,
1446
1461
  enumerable: false
@@ -1448,6 +1463,17 @@ function generateSharedCacheSeedItem(pkg, importPath) {
1448
1463
  __mfModuleCache.share[${JSON.stringify(pkg)}] = exportModule;
1449
1464
  }`;
1450
1465
  }
1466
+ const normalizeRuntimeShareCode = `const __mfNormalizeRuntimeShare = (mod) => {
1467
+ let current = mod;
1468
+ for (let i = 0; i < 5; i++) {
1469
+ const defaultExport = current?.default;
1470
+ if (!defaultExport || typeof defaultExport !== "object") break;
1471
+ const namedValues = Object.keys(current).filter((key) => key !== "default").map((key) => current[key]);
1472
+ if (namedValues.length > 0 && namedValues.some((value) => value !== undefined)) break;
1473
+ current = defaultExport;
1474
+ }
1475
+ return current;
1476
+ };`;
1451
1477
  function generateDirectSharedCacheSeedCode(command = "build") {
1452
1478
  return getOrderedUsedShares().map((pkg) => {
1453
1479
  const shareItem = getShareItemForPreload(pkg);
@@ -1470,7 +1496,8 @@ function getHostAutoInitSharedSeedItems() {
1470
1496
  return priority(a.pkg) - priority(b.pkg) || Number(aIsLocal) - Number(bIsLocal) || a.pkg.localeCompare(b.pkg);
1471
1497
  });
1472
1498
  }
1473
- function generateHostAutoInitSharedCacheSeedCode() {
1499
+ function generateHostAutoInitSharedCacheSeedCode(command = "build") {
1500
+ if (command === "build") return "";
1474
1501
  return getHostAutoInitSharedSeedItems().map(({ pkg, shareItem }) => {
1475
1502
  if (!shareItem) return null;
1476
1503
  return generateSharedCacheSeedItem(pkg, getBrowserImportPath(getDirectSharedCacheSeedImportPath(pkg, shareItem)));
@@ -1502,14 +1529,13 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
1502
1529
  if (typeof __VUE_HMR_RUNTIME__ === 'undefined') {
1503
1530
  globalThis.__VUE_HMR_RUNTIME__ = { createRecord() {}, rerender() {}, reload() {} };
1504
1531
  }
1505
- import {createInstance, loadRemote} from "@module-federation/runtime";
1532
+ import {init as runtimeInit, loadRemote} from "@module-federation/runtime";
1506
1533
  ${pluginImportNames.map((item) => item[1]).join("\n")}
1507
1534
  ${command === "build" ? getRuntimeInitResolveBootstrapCode() : getRuntimeInitBootstrapCode() + "\n const { initResolve } = globalThis[globalKey];"}
1508
1535
  ${getRuntimeModuleCacheBootstrapCode()}
1509
1536
  const initTokens = {}
1510
1537
  const shareScopeName = ${JSON.stringify(options.shareScope)}
1511
1538
  const mfName = ${JSON.stringify(options.internalName)}
1512
- let runtimeInstance
1513
1539
  let localSharedImportMapPromise
1514
1540
  let exposesMapPromise
1515
1541
  const shouldRetrySharedInitError = ${command !== "build"} && ((error) => {
@@ -1552,19 +1578,13 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
1552
1578
  async function init(shared = {}, initScope = []) {
1553
1579
  const {usedShared, usedRemotes} = await getLocalSharedImportMap()
1554
1580
  ${generateDirectSharedCacheSeedCode(command)}
1555
- const runtimeOptions = {
1581
+ const initRes = runtimeInit({
1556
1582
  name: mfName,
1557
1583
  remotes: usedRemotes,
1558
1584
  shared: usedShared,
1559
1585
  plugins: [${pluginImportNames.map((item) => `${item[0]}(${item[2]})`).join(", ")}],
1560
1586
  ${options.shareStrategy ? `shareStrategy: '${options.shareStrategy}'` : ""}
1561
- };
1562
- if (!runtimeInstance) {
1563
- runtimeInstance = createInstance(runtimeOptions);
1564
- } else {
1565
- runtimeInstance.initOptions(runtimeOptions);
1566
- }
1567
- const initRes = runtimeInstance;
1587
+ });
1568
1588
  // handling circular init calls
1569
1589
  var initToken = initTokens[shareScopeName];
1570
1590
  if (!initToken)
@@ -1584,6 +1604,17 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
1584
1604
  } catch (e) {
1585
1605
  console.error('[Module Federation]', e)
1586
1606
  }
1607
+ for (const [pkg, share] of Object.entries(usedShared)) {
1608
+ if (share.shareConfig?.import !== false || __mfModuleCache.share[pkg] !== undefined) continue;
1609
+ ${normalizeRuntimeShareCode}
1610
+ const versions = shared?.[pkg];
1611
+ const provider = versions && versions[Object.keys(versions)[0]];
1612
+ if (!provider) continue;
1613
+ const factory = provider.lib || (provider.loading ? await provider.loading : await provider.get?.());
1614
+ const mod = typeof factory === "function" ? factory() : factory;
1615
+ const resolved = await Promise.resolve(mod);
1616
+ __mfModuleCache.share[pkg] = __mfNormalizeRuntimeShare(resolved);
1617
+ }
1587
1618
  return initRes
1588
1619
  }
1589
1620
 
@@ -1608,10 +1639,11 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build") {
1608
1639
  async function initHost() {
1609
1640
  if (!hostInitPromise) {
1610
1641
  hostInitPromise = (async () => {
1611
- ${generateHostAutoInitSharedCacheSeedCode()}
1642
+ ${generateHostAutoInitSharedCacheSeedCode(_command)}
1612
1643
  const remoteEntry = await import(${remoteEntryImport});
1613
1644
  const runtime = await remoteEntry.init();
1614
1645
  const usedShared = ${generateUsedSharedPreloadConfig()};
1646
+ ${normalizeRuntimeShareCode}
1615
1647
  for (const [pkg, share] of Object.entries(usedShared)) {
1616
1648
  if (__mfModuleCache.share[pkg] !== undefined) {
1617
1649
  continue;
@@ -1621,7 +1653,7 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build") {
1621
1653
  }).then((factory) => {
1622
1654
  const mod = typeof factory === "function" ? factory() : factory;
1623
1655
  return Promise.resolve(mod).then((resolved) => {
1624
- __mfModuleCache.share[pkg] = resolved;
1656
+ __mfModuleCache.share[pkg] = __mfNormalizeRuntimeShare(resolved);
1625
1657
  });
1626
1658
  });
1627
1659
  }
@@ -1650,7 +1682,7 @@ function getHostAutoInitImportId() {
1650
1682
  return hostAutoInitModule.getImportId();
1651
1683
  }
1652
1684
  function getHostAutoInitPath() {
1653
- return hostAutoInitModule.getPath();
1685
+ return hostAutoInitModule.getImportId();
1654
1686
  }
1655
1687
  //#endregion
1656
1688
  //#region src/virtualModules/virtualRemotes.ts
@@ -1673,7 +1705,9 @@ function getUsedRemotesMap() {
1673
1705
  }
1674
1706
  function generateRemotes(id, command) {
1675
1707
  const useReactProxy = command === "serve" && hasPackageDependency("react");
1676
- const reactImportLine = useReactProxy ? `import * as __mfReact from "react";` : "";
1708
+ const reactImportLine = useReactProxy ? `import __mfReactDefault from "react";
1709
+ import * as __mfReactNamespace from "react";
1710
+ const __mfReact = __mfReactDefault ?? __mfReactNamespace.default ?? __mfReactNamespace;` : "";
1677
1711
  const importLine = command === "build" ? `${getRuntimeModuleCacheBootstrapCode()}
1678
1712
  import { hostInitPromise as __mfHostInitPromise } from ${JSON.stringify(getHostAutoInitPath())};` : `${getRuntimeInitBootstrapCode()}
1679
1713
  const { initPromise, moduleCache: __mfModuleCache } = globalThis[globalKey];`;
@@ -1683,13 +1717,13 @@ function generateRemotes(id, command) {
1683
1717
  }
1684
1718
  export const __moduleExports = exportModule;
1685
1719
  export const __mf_remote_pending = Promise.resolve(exportModule);
1686
- export default exportModule?.__esModule ? exportModule.default : exportModule.default ?? exportModule` : command === "build" ? `if (__mfRemotePending) {
1720
+ export default exportModule?.__mf_is_remote_proxy ? exportModule : exportModule?.__esModule ? exportModule.default : exportModule.default ?? exportModule` : command === "build" ? `if (__mfRemotePending) {
1687
1721
  const mod = await __mfRemotePending;
1688
1722
  if (mod !== undefined) exportModule = mod;
1689
1723
  }
1690
1724
  export const __moduleExports = exportModule;
1691
1725
  export const __mf_remote_pending = Promise.resolve(exportModule);
1692
- export default exportModule?.__esModule ? exportModule.default : exportModule.default ?? exportModule` : "export default exportModule";
1726
+ export default exportModule?.__mf_is_remote_proxy ? exportModule : exportModule?.__esModule ? exportModule.default : exportModule.default ?? exportModule` : "export default exportModule";
1693
1727
  return `
1694
1728
  ${reactImportLine}
1695
1729
  ${importLine}
@@ -1889,6 +1923,9 @@ ${importHelper}(async () => {
1889
1923
  if (inject === "html" && hasPackageDependency("@sveltejs/kit")) return false;
1890
1924
  return inject === "entry" || !htmlFilePath;
1891
1925
  }
1926
+ function normalizeDevHtmlProxyId(id) {
1927
+ return id.replace(/^\0/, "").replace(/^\/@id\//, "").replace(/^__x00__/, "");
1928
+ }
1892
1929
  return [{
1893
1930
  name: "add-entry",
1894
1931
  apply: "serve",
@@ -1907,7 +1944,20 @@ ${importHelper}(async () => {
1907
1944
  }
1908
1945
  },
1909
1946
  configureServer(server) {
1910
- server.middlewares.use((req, _res, next) => {
1947
+ server.middlewares.use((req, res, next) => {
1948
+ const rawUrl = req.url?.split("#")[0] ?? "";
1949
+ if (normalizeDevHtmlProxyId(rawUrl.split("?")[0]) === DEV_HTML_PROXY_PREFIX.slice(0, -1)) {
1950
+ const query = rawUrl.slice(rawUrl.indexOf("?") + 1);
1951
+ const params = new URLSearchParams(query);
1952
+ const initSrc = params.get("init");
1953
+ const entrySrc = params.get("entry");
1954
+ if (initSrc && entrySrc) {
1955
+ res.statusCode = 200;
1956
+ res.setHeader("Content-Type", "application/javascript");
1957
+ res.end(getBootstrapSource(initSrc, entrySrc));
1958
+ return;
1959
+ }
1960
+ }
1911
1961
  if (!fileName) {
1912
1962
  next();
1913
1963
  return;
@@ -1924,7 +1974,7 @@ ${importHelper}(async () => {
1924
1974
  const base = viteConfig.base.replace(/\/$/, "");
1925
1975
  const stripBase = (p) => base && p.startsWith(base + "/") ? p.slice(base.length) : p;
1926
1976
  const html = rewriteEntryScripts(c, (originalSrc) => {
1927
- return `/@id/${DEV_HTML_PROXY_PREFIX}${new URLSearchParams({
1977
+ return `/@id/__x00__${DEV_HTML_PROXY_PREFIX}${new URLSearchParams({
1928
1978
  init: sanitizeDevEntryPath(stripBase(devEntryPath)),
1929
1979
  entry: sanitizeDevEntryPath(stripBase(originalSrc))
1930
1980
  }).toString()}`;
@@ -1933,11 +1983,12 @@ ${importHelper}(async () => {
1933
1983
  }
1934
1984
  },
1935
1985
  resolveId(id) {
1936
- if (id.startsWith(DEV_HTML_PROXY_PREFIX)) return id;
1986
+ if (normalizeDevHtmlProxyId(id).startsWith(DEV_HTML_PROXY_PREFIX)) return id;
1937
1987
  },
1938
1988
  load(id) {
1939
- if (!id.startsWith(DEV_HTML_PROXY_PREFIX)) return;
1940
- const params = new URLSearchParams(id.slice(28));
1989
+ const normalizedId = normalizeDevHtmlProxyId(id);
1990
+ if (!normalizedId.startsWith(DEV_HTML_PROXY_PREFIX)) return;
1991
+ const params = new URLSearchParams(normalizedId.slice(28));
1941
1992
  const initSrc = params.get("init");
1942
1993
  const entrySrc = params.get("entry");
1943
1994
  if (!initSrc || !entrySrc) return;
@@ -2744,7 +2795,7 @@ function collectSystemProxyInfos(proxyChunks, loadShareTag) {
2744
2795
  for (const m of proxyInfo.code.matchAll(/exports\(\s*["']([^"']+)["']\s*,([\s\S]*?)\);/g)) {
2745
2796
  const exported = m[1];
2746
2797
  const expression = m[2];
2747
- for (const [local, exportName] of Object.entries(loadShareBindings)) if (new RegExp(`\\b${local}\\b`).test(expression)) {
2798
+ for (const [local, exportName] of Object.entries(loadShareBindings).reverse()) if (new RegExp(`\\b${local}\\b`).test(expression)) {
2748
2799
  exportMap[exported] = {
2749
2800
  type: "reexport",
2750
2801
  exportName
@@ -3508,7 +3559,7 @@ function pluginProxyRemotes_default(options) {
3508
3559
  const remoteModule = getRemoteVirtualModule(source, command);
3509
3560
  addUsedRemote(remoteName, source);
3510
3561
  refreshHostAutoInit();
3511
- return remoteModule.getPath();
3562
+ return remoteModule.getImportId();
3512
3563
  }
3513
3564
  return {
3514
3565
  name: "proxyRemotes",
@@ -4330,12 +4381,12 @@ function isFederationHtmlPreloadDependency(dep, includeSharedRuntime = false) {
4330
4381
  return includeSharedRuntime && (file.includes("preload-helper") || file.includes("rolldown-runtime") || file.startsWith("dist-"));
4331
4382
  }
4332
4383
  /**
4333
- * Plugin that runs FIRST to create virtual module files in the config hook.
4334
- * This prevents 504 "Outdated Optimize Dep" errors by ensuring files exist
4384
+ * Plugin that runs FIRST to register generated virtual modules in the config hook.
4385
+ * This prevents 504 "Outdated Optimize Dep" errors by ensuring ids are known
4335
4386
  * before Vite's optimization phase.
4336
4387
  */
4337
4388
  function createEarlyVirtualModulesPlugin(options) {
4338
- const { shared, remotes, virtualModuleDir } = options;
4389
+ const { shared, remotes } = options;
4339
4390
  const isLitShare = (pkg) => pkg === "lit" || pkg.startsWith("lit/");
4340
4391
  return {
4341
4392
  name: "vite:module-federation-early-init",
@@ -4345,9 +4396,6 @@ function createEarlyVirtualModulesPlugin(options) {
4345
4396
  const root = config.root || process.cwd();
4346
4397
  setPackageDetectionCwd(root);
4347
4398
  const isVinext = hasPackageDependency("vinext");
4348
- initVirtualModuleInfrastructure(root, virtualModuleDir);
4349
- VirtualModule.setRoot(root);
4350
- VirtualModule.ensureVirtualPackageExists();
4351
4399
  initVirtualModules(_command, getRemoteEntryId(options));
4352
4400
  const isRolldown = getIsRolldown(this);
4353
4401
  if (remotes && Object.keys(remotes).length > 0) {
@@ -4393,6 +4441,10 @@ function createEarlyVirtualModulesPlugin(options) {
4393
4441
  optimizeDeps.esbuildOptions.plugins.push({
4394
4442
  name: "module-federation:optimize-shared-proxy",
4395
4443
  setup(build) {
4444
+ build.onResolve({ filter: /^virtual:mf:/ }, (args) => ({
4445
+ path: args.path,
4446
+ external: true
4447
+ }));
4396
4448
  build.onResolve({ filter: /.*/ }, (args) => {
4397
4449
  if (!args.importer || args.namespace === "mf-shared") return;
4398
4450
  if (isSharedResolverInternalImporter(args.importer)) return;
@@ -4424,7 +4476,6 @@ export default __mfShared.default ?? __mfShared;`
4424
4476
  }
4425
4477
  });
4426
4478
  }
4427
- config.optimizeDeps.include.push(virtualRuntimeInitStatus.getImportId());
4428
4479
  }
4429
4480
  for (const key of Object.keys(shared)) {
4430
4481
  const shareItem = shared[key];
@@ -4435,7 +4486,6 @@ export default __mfShared.default ?? __mfShared;`
4435
4486
  for (const subpath of getCommonSharedSubpaths(key)) {
4436
4487
  writePreBuildLibPath(subpath, shareItem);
4437
4488
  optimizeDeps.include.push(subpath);
4438
- optimizeDeps.include.push(getPreBuildLibImportId(subpath));
4439
4489
  }
4440
4490
  }
4441
4491
  continue;
@@ -4452,14 +4502,11 @@ export default __mfShared.default ?? __mfShared;`
4452
4502
  const optimizeDeps = config.optimizeDeps ??= {};
4453
4503
  optimizeDeps.include ??= [];
4454
4504
  optimizeDeps.exclude ??= [];
4455
- const shouldBypassOptimizeDep = isLitShare(key);
4456
- if (shouldBypassOptimizeDep) optimizeDeps.exclude.push(key);
4457
- if (!isRolldown && !shouldBypassOptimizeDep) optimizeDeps.include.push(getLoadShareImportId(key, isRolldown));
4458
- optimizeDeps.include.push(getPreBuildLibImportId(key));
4505
+ if (isLitShare(key)) optimizeDeps.exclude.push(key);
4506
+ else optimizeDeps.include.push(key);
4459
4507
  for (const subpath of getCommonSharedSubpaths(key)) {
4460
4508
  writePreBuildLibPath(subpath, shareItem);
4461
4509
  optimizeDeps.include.push(subpath);
4462
- optimizeDeps.include.push(getPreBuildLibImportId(subpath));
4463
4510
  }
4464
4511
  }
4465
4512
  }
@@ -4479,6 +4526,21 @@ function federation(mfUserOptions) {
4479
4526
  let command;
4480
4527
  let desiredRolldownOutput;
4481
4528
  return [
4529
+ {
4530
+ name: "vite:module-federation-virtual-modules",
4531
+ enforce: "pre",
4532
+ resolveId(id) {
4533
+ const virtualModule = VirtualModule.findById(id);
4534
+ if (!virtualModule) return;
4535
+ return virtualModule.getResolvedId();
4536
+ },
4537
+ load(id) {
4538
+ const virtualModule = VirtualModule.findById(id);
4539
+ if (!virtualModule) return;
4540
+ if (command === "build" && (id.includes("__loadShare__") || id.includes("__loadRemote__"))) return;
4541
+ return virtualModule.code;
4542
+ }
4543
+ },
4482
4544
  createEarlyVirtualModulesPlugin(options),
4483
4545
  ...isVinext ? [{
4484
4546
  name: "module-federation-vinext-react-server-build-alias",
@@ -4503,9 +4565,7 @@ function federation(mfUserOptions) {
4503
4565
  config(_config, env) {
4504
4566
  command = env.command;
4505
4567
  },
4506
- configResolved(config) {
4507
- VirtualModule.setRoot(config.root);
4508
- VirtualModule.ensureVirtualPackageExists();
4568
+ configResolved() {
4509
4569
  initVirtualModules(command, remoteEntryId);
4510
4570
  }
4511
4571
  },
@@ -4648,9 +4708,8 @@ function federation(mfUserOptions) {
4648
4708
  }
4649
4709
  },
4650
4710
  load(id) {
4651
- if (id.startsWith("\0")) return;
4652
4711
  if (id.includes("__loadShare__") || id.includes("__loadRemote__")) {
4653
- let code = (0, fs.readFileSync)(id, "utf-8");
4712
+ let code = VirtualModule.findById(id)?.code ?? (0, fs.readFileSync)(id, "utf-8");
4654
4713
  code = code.replace(/import\s+["'][^"']*__prebuild__[^"']*["']\s*;?/g, "");
4655
4714
  code = code.replace(/export\s+\*\s+from\s+["'][^"']*__prebuild__[^"']*["']\s*;?/g, "");
4656
4715
  /**
@@ -4669,7 +4728,10 @@ function federation(mfUserOptions) {
4669
4728
  *
4670
4729
  * @see https://rollupjs.org/plugin-development/#synthetic-named-exports
4671
4730
  */
4672
- if (!code.includes("__moduleExports")) code = code.replace("export default exportModule", "export const __moduleExports = exportModule;\nexport default exportModule.__esModule ? exportModule.default : exportModule");
4731
+ if (!/\bexport\s+const\s+__moduleExports\b/.test(code)) {
4732
+ const nextCode = code.replace("export default exportModule", "export const __moduleExports = exportModule;\nexport default exportModule.__esModule ? exportModule.default : exportModule");
4733
+ code = nextCode === code ? `${code}\nexport const __moduleExports = exportModule;\n` : nextCode;
4734
+ }
4673
4735
  if (getIsRolldown(this)) return { code };
4674
4736
  return {
4675
4737
  code,
@@ -4734,14 +4796,9 @@ function federation(mfUserOptions) {
4734
4796
  config.build ||= {};
4735
4797
  config.build.commonjsOptions ||= {};
4736
4798
  config.build.commonjsOptions.strictRequires ??= "auto";
4737
- const virtualDir = options.virtualModuleDir;
4738
4799
  config.optimizeDeps ||= {};
4739
4800
  config.optimizeDeps.include ||= [];
4740
4801
  config.optimizeDeps.include.push("@module-federation/runtime");
4741
- if (!isRolldown) config.optimizeDeps.include.push(virtualDir);
4742
- config.ssr ||= {};
4743
- config.ssr.noExternal ||= [];
4744
- if (Array.isArray(config.ssr.noExternal)) config.ssr.noExternal.push(virtualDir);
4745
4802
  options.runtimePlugins.forEach((p) => {
4746
4803
  const pluginPath = typeof p === "string" ? p : p[0];
4747
4804
  if (pluginPath && !pluginPath.startsWith(".") && !pluginPath.startsWith("/") && !pluginPath.startsWith("\0") && !pluginPath.startsWith("virtual:")) config.optimizeDeps.include.push(pluginPath);
@@ -4749,9 +4806,6 @@ function federation(mfUserOptions) {
4749
4806
  if (isRolldown) {
4750
4807
  config.build ??= {};
4751
4808
  config.build.target ??= "esnext";
4752
- } else {
4753
- config.optimizeDeps.needsInterop ||= [];
4754
- config.optimizeDeps.needsInterop.push(virtualDir);
4755
4809
  }
4756
4810
  const isAstro = hasPackageDependency("astro");
4757
4811
  const resolvedTarget = options.target ?? (config.build?.ssr ? "node" : "web");
package/lib/index.mjs CHANGED
@@ -1,14 +1,14 @@
1
1
  import { createRequire } from "node:module";
2
2
  import * as fs$1 from "fs";
3
- import fs, { existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, statSync, writeFile, writeFileSync } from "fs";
3
+ import fs, { existsSync, readFileSync, readdirSync, realpathSync, statSync, writeFileSync } from "fs";
4
4
  import { createRequire as createRequire$1 } from "module";
5
5
  import * as path$1 from "pathe";
6
- import path, { basename, dirname, join, parse, resolve } from "pathe";
6
+ import path, { basename } from "pathe";
7
7
  import { normalizeOptions } from "@module-federation/sdk";
8
8
  import { consumeTypesAPI, generateTypesAPI, isTSProject, normalizeConsumeTypesOptions, normalizeDtsOptions, normalizeGenerateTypesOptions } from "@module-federation/dts-plugin";
9
9
  import { rpc } from "@module-federation/dts-plugin/core";
10
10
  import { fileURLToPath } from "url";
11
- import { init, parse as parse$1 } from "es-module-lexer";
11
+ import { init, parse } from "es-module-lexer";
12
12
  //#region \0rolldown/runtime.js
13
13
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
14
14
  //#endregion
@@ -524,7 +524,7 @@ function normalizeShareItem(key, shareItem) {
524
524
  shareConfig: {
525
525
  import: shareItem.import,
526
526
  singleton: shareItem.singleton || false,
527
- requiredVersion: shareItem.requiredVersion || (version ? `^${version}` : "*"),
527
+ requiredVersion: shareItem.requiredVersion || (isImportFalse ? "*" : version ? `^${version}` : "*"),
528
528
  strictVersion: !!shareItem.strictVersion
529
529
  }
530
530
  };
@@ -641,35 +641,6 @@ function normalizeModuleFederationOptions(options) {
641
641
  }
642
642
  //#endregion
643
643
  //#region src/utils/VirtualModule.ts
644
- /**
645
- * Initialize virtual module infrastructure BEFORE VirtualModule class is used.
646
- * This must be called in the config hook to ensure the directory exists
647
- * before Vite's optimization phase.
648
- */
649
- function initVirtualModuleInfrastructure(root, virtualModuleDir = "__mf__virtual") {
650
- const virtualPackagePath = join(join(root, "node_modules"), virtualModuleDir);
651
- mkdirSync(virtualPackagePath, { recursive: true });
652
- writeFileSync(join(virtualPackagePath, "empty.js"), "");
653
- writeFileSync(join(virtualPackagePath, "package.json"), JSON.stringify({
654
- name: virtualModuleDir,
655
- main: "empty.js"
656
- }));
657
- }
658
- let rootDir;
659
- function findNodeModulesDir(root = process.cwd()) {
660
- let currentDir = root;
661
- while (currentDir !== parse(currentDir).root) {
662
- const nodeModulesPath = join(currentDir, "node_modules");
663
- if (existsSync(nodeModulesPath)) return nodeModulesPath;
664
- currentDir = dirname(currentDir);
665
- }
666
- return "";
667
- }
668
- let cachedNodeModulesDir;
669
- function getNodeModulesDir() {
670
- if (!cachedNodeModulesDir) cachedNodeModulesDir = findNodeModulesDir(rootDir);
671
- return cachedNodeModulesDir;
672
- }
673
644
  function getSuffix(name) {
674
645
  const base = basename(name);
675
646
  const dotIndex = base.lastIndexOf(".");
@@ -678,9 +649,6 @@ function getSuffix(name) {
678
649
  }
679
650
  const patternMap = {};
680
651
  const cacheMap = {};
681
- /**
682
- * Physically generate files as virtual modules under node_modules/__mf__virtual/*
683
- */
684
652
  function assertModuleFound(tag, str = "") {
685
653
  const module = VirtualModule.findModule(tag, str);
686
654
  if (!module) throw createModuleFederationError(`Module Federation shared module '${str}' not found. Please ensure it's installed as a dependency in your package.json.`);
@@ -691,33 +659,16 @@ var VirtualModule = class {
691
659
  tag;
692
660
  suffix;
693
661
  inited = false;
694
- /**
695
- * Set the root path for finding node_modules
696
- * @param root - Root path
697
- */
698
- static setRoot(root) {
699
- rootDir = root;
700
- cachedNodeModulesDir = void 0;
701
- }
702
- /**
703
- * Ensure virtual package directory exists
704
- */
705
- static ensureVirtualPackageExists() {
706
- const nodeModulesDir = getNodeModulesDir();
707
- const { virtualModuleDir } = getNormalizeModuleFederationOptions();
708
- const virtualPackagePath = resolve(nodeModulesDir, virtualModuleDir);
709
- mkdirSync(virtualPackagePath, { recursive: true });
710
- writeFileSync(resolve(virtualPackagePath, "empty.js"), "");
711
- writeFileSync(resolve(virtualPackagePath, "package.json"), JSON.stringify({
712
- name: virtualModuleDir,
713
- main: "empty.js"
714
- }));
715
- }
662
+ code;
716
663
  static findModule(tag, str = "") {
717
664
  if (!patternMap[tag]) patternMap[tag] = new RegExp(`(.*${packageNameEncode(tag)}(.+?)${packageNameEncode(tag)}.*)`);
718
665
  const moduleName = (str.match(patternMap[tag]) || [])[2];
719
666
  if (moduleName) return cacheMap[tag][packageNameDecode(moduleName)];
720
667
  }
668
+ static findById(id) {
669
+ const normalized = id.replace(/^\0+/, "").replace(/^\/@id\//, "").replace(/^__x00__/, "").replace(/[?#].*$/, "");
670
+ for (const modules of Object.values(cacheMap)) for (const module of Object.values(modules)) if (module.getImportId() === normalized) return module;
671
+ }
721
672
  constructor(name, tag = "__mf_v__", suffix = "") {
722
673
  this.name = name;
723
674
  this.tag = tag;
@@ -725,24 +676,20 @@ var VirtualModule = class {
725
676
  if (!cacheMap[this.tag]) cacheMap[this.tag] = {};
726
677
  cacheMap[this.tag][this.name] = this;
727
678
  }
728
- getPath() {
729
- return resolve(getNodeModulesDir(), this.getImportId());
730
- }
731
679
  getImportId() {
732
- const { internalName: mfName, virtualModuleDir } = getNormalizeModuleFederationOptions();
733
- return `${virtualModuleDir}/${packageNameEncode(`${mfName}${this.tag}${this.name}${this.tag}`)}${this.suffix}`;
680
+ const { internalName: mfName } = getNormalizeModuleFederationOptions();
681
+ return `virtual:mf:${packageNameEncode(`${mfName}${this.tag}${this.name}${this.tag}`)}${this.suffix}`;
682
+ }
683
+ getResolvedId() {
684
+ return `\0${this.getImportId()}`;
734
685
  }
735
686
  writeSync(code, force) {
736
687
  if (!force && this.inited) return;
737
688
  if (!this.inited) this.inited = true;
738
- const path = this.getPath();
739
- mkdirSync(dirname(path), { recursive: true });
740
- writeFileSync(path, code);
689
+ this.code = code;
741
690
  }
742
691
  write(code) {
743
- const path = this.getPath();
744
- mkdirSync(dirname(path), { recursive: true });
745
- writeFile(path, code, function() {});
692
+ this.writeSync(code, true);
746
693
  }
747
694
  };
748
695
  //#endregion
@@ -944,6 +891,14 @@ globalThis[__mfCacheGlobalKey].remote ||= {};
944
891
  const __mfModuleCache = globalThis[__mfCacheGlobalKey];
945
892
  `;
946
893
  }
894
+ function getRuntimeInitPromiseBootstrapCode() {
895
+ return getRuntimeInitStateBootstrapCode({
896
+ globalKeyVar: "__mfPromiseGlobalKey",
897
+ stateVar: "__mfPromiseState",
898
+ exposedConst: "initPromise",
899
+ exposedProperty: "initPromise"
900
+ });
901
+ }
947
902
  function getRuntimeInitResolveBootstrapCode() {
948
903
  return getRuntimeInitStateBootstrapCode({
949
904
  globalKeyVar: "__mfResolveGlobalKey",
@@ -1188,6 +1143,16 @@ function writePreBuildLibPath(pkg, shareItem) {
1188
1143
  export const jsx = __mfPrebuildExports.jsx;
1189
1144
  export const jsxs = __mfPrebuildExports.jsxs;
1190
1145
  export default __mfPrebuildExports;
1146
+ `, true);
1147
+ return;
1148
+ }
1149
+ const namedExports = getPackageNamedExports(pkg);
1150
+ if (namedExports.length > 0) {
1151
+ preBuildCacheMap[pkg].writeSync(`
1152
+ import * as __mfPrebuildNamespace from ${escapeGeneratedStringLiteral(importSource)};
1153
+ const __mfPrebuildExports = __mfPrebuildNamespace;
1154
+ ${namedExports.map((name) => `export const ${name} = __mfPrebuildExports[${escapeGeneratedStringLiteral(name)}];`).join("\n ")}
1155
+ export default __mfPrebuildExports;
1191
1156
  `, true);
1192
1157
  return;
1193
1158
  }
@@ -1215,25 +1180,62 @@ function getLoadShareImportId(pkg, _isRolldown) {
1215
1180
  }
1216
1181
  function getLoadShareModulePath(pkg, isRolldown) {
1217
1182
  if (!loadShareCacheMap[pkg]) getLoadShareImportId(pkg, isRolldown);
1218
- return loadShareCacheMap[pkg].getPath();
1183
+ return loadShareCacheMap[pkg].getImportId();
1219
1184
  }
1185
+ function generateDeferredHostProvidedExports(namedExports, pkg) {
1186
+ const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
1187
+ const declarations = ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ");
1188
+ const assignments = [...namedExports.map((name, i) => `${namedExportVars[i]} = exportModule[${escapeGeneratedStringLiteral(name)}];`), "__mf_default = exportModule.default ?? exportModule;"].join("\n ");
1189
+ const namedExportLine = namedExports.length > 0 ? `\n export { ${namedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
1190
+ return `${declarations}
1191
+ const __mfApplyHostProvidedExports = (exportModule) => {
1192
+ ${assignments}
1193
+ };
1194
+ let exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}];
1195
+ if (exportModule === undefined) {
1196
+ initPromise.then(() => {
1197
+ exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}];
1198
+ if (exportModule === undefined) {
1199
+ throw new Error("[Module Federation] Shared module ${pkg} was imported before federation bootstrap finished.");
1200
+ }
1201
+ __mfApplyHostProvidedExports(exportModule);
1202
+ });
1203
+ } else {
1204
+ __mfApplyHostProvidedExports(exportModule);
1205
+ }
1206
+ export { __mf_default as default };${namedExportLine}`;
1207
+ }
1208
+ function generateShareModuleUnwrapCode({ source, preserveNamedExports, stopWithReturn }) {
1209
+ return `let current = ${source};
1210
+ for (let i = 0; i < 5; i++) {
1211
+ const defaultExport = current?.default;
1212
+ ${stopWithReturn ? `if (!defaultExport || typeof defaultExport !== "object") return ${stopWithReturn};` : `if (!defaultExport || typeof defaultExport !== "object") break;`}${preserveNamedExports ? `
1213
+ const namedValues = Object.keys(current).filter((key) => key !== "default").map((key) => current[key]);
1214
+ if (namedValues.length > 0 && namedValues.some((value) => value !== undefined)) break;` : ""}
1215
+ current = defaultExport;
1216
+ }
1217
+ return current;`;
1218
+ }
1219
+ const normalizeLocalShareModuleCode = `const __mfNormalizeShareModule = (mod) => {
1220
+ ${generateShareModuleUnwrapCode({
1221
+ source: "mod",
1222
+ preserveNamedExports: true
1223
+ })}
1224
+ };`;
1220
1225
  function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
1221
1226
  if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = new VirtualModule(pkg, LOAD_SHARE_TAG, ".mjs");
1222
1227
  const importLine = getRuntimeModuleCacheBootstrapCode();
1223
1228
  if (shareItem.shareConfig.import === false) {
1224
1229
  const namedExports = getPackageNamedExports(pkg);
1225
1230
  let exportLine;
1226
- if (namedExports.length > 0) exportLine = `export default exportModule.default ?? exportModule;\n ${`const { ${namedExports.map((name, i) => `${name}: __mf_${i}`).join(", ")} } = exportModule;`}\n ${`export { ${namedExports.map((name, i) => `__mf_${i} as ${name}`).join(", ")} };`}`;
1231
+ if (namedExports.length > 0) exportLine = generateDeferredHostProvidedExports(namedExports, pkg);
1227
1232
  else {
1228
1233
  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.`);
1229
- exportLine = "export default exportModule.default ?? exportModule";
1234
+ exportLine = generateDeferredHostProvidedExports([], pkg);
1230
1235
  }
1231
1236
  loadShareCacheMap[pkg].writeSync(`
1237
+ ${getRuntimeInitPromiseBootstrapCode()}
1232
1238
  ${importLine}
1233
- const exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}]
1234
- if (exportModule === undefined) {
1235
- throw new Error("[Module Federation] Shared module ${pkg} was imported before federation bootstrap finished.")
1236
- }
1237
1239
  ${exportLine}
1238
1240
  `, true);
1239
1241
  return;
@@ -1248,8 +1250,20 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
1248
1250
  const usesLazyLocalFallback = isWorkspacePackage && shareItem.shareConfig.singleton === true;
1249
1251
  const namedExports = getPackageNamedExports(pkg);
1250
1252
  let exportLine;
1251
- if (namedExports.length > 0) exportLine = `export default exportModule.default ?? exportModule;\n ${`const { ${namedExports.map((name, i) => `${name}: __mf_${i}`).join(", ")} } = exportModule;`}\n ${`export { ${namedExports.map((name, i) => `__mf_${i} as ${name}`).join(", ")} };`}`;
1252
- else if (usesLazyLocalFallback) exportLine = `export default exportModule.default ?? exportModule`;
1253
+ if (namedExports.length > 0) {
1254
+ const destructure = `const { ${namedExports.map((name, i) => `${name}: __mf_${i}`).join(", ")} } = exportModule;`;
1255
+ const namedExportLine = `export { ${namedExports.map((name, i) => `__mf_${i} as ${name}`).join(", ")} };`;
1256
+ exportLine = `const __mfDefaultExport = (() => {
1257
+ ${generateShareModuleUnwrapCode({
1258
+ source: "exportModule",
1259
+ preserveNamedExports: false,
1260
+ stopWithReturn: "defaultExport ?? current"
1261
+ })}
1262
+ })();
1263
+ export default __mfDefaultExport;
1264
+ ${destructure}
1265
+ ${namedExportLine}`;
1266
+ } else if (usesLazyLocalFallback) exportLine = `export default exportModule.default ?? exportModule`;
1253
1267
  else exportLine = `export default exportModule.default ?? exportModule\n export * from ${escapeGeneratedStringLiteral(sharedImportSource)}`;
1254
1268
  const prebuildImportLine = usesLazyLocalFallback || isWorkspacePackage && command !== "build" ? "" : `import * as __mfLocalShare from ${escapeGeneratedStringLiteral(skipServePrebuildWarmup ? devImportSource : sharedImportSource)};`;
1255
1269
  const devDynamicImportLine = isWorkspacePackage ? "" : command !== "build" && !skipServePrebuildWarmup ? `;() => import(${escapeGeneratedStringLiteral(devImportSource)}).catch(() => {});` : "";
@@ -1257,10 +1271,11 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
1257
1271
  ${prebuildImportLine}
1258
1272
  ${devDynamicImportLine}
1259
1273
  ${importLine}
1274
+ ${normalizeLocalShareModuleCode}
1260
1275
  let exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}]
1261
1276
  if (exportModule === undefined) {
1262
- ${usesLazyLocalFallback ? `exportModule = await import(${escapeGeneratedStringLiteral(lazyLocalFallbackSource)});
1263
- __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}] = exportModule;` : `exportModule = __mfLocalShare;
1277
+ ${usesLazyLocalFallback ? `exportModule = __mfNormalizeShareModule(await import(${escapeGeneratedStringLiteral(lazyLocalFallbackSource)}));
1278
+ __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}] = exportModule;` : `exportModule = __mfNormalizeShareModule(__mfLocalShare);
1264
1279
  __mfModuleCache.share[${escapeGeneratedStringLiteral(pkg)}] = exportModule;`}
1265
1280
  }
1266
1281
  ${exportLine}
@@ -1418,9 +1433,9 @@ function getShareItemForPreload(pkg) {
1418
1433
  function generateSharedCacheSeedItem(pkg, importPath) {
1419
1434
  return `if (__mfModuleCache.share[${JSON.stringify(pkg)}] === undefined) {
1420
1435
  const mod = await import(${JSON.stringify(importPath)});
1421
- const exportModule = ${JSON.stringify(shouldUseDirectReactImport())} && ${JSON.stringify(pkg)} === "react"
1422
- ? (mod?.default ?? mod)
1423
- : {...mod};
1436
+ ${normalizeRuntimeShareCode}
1437
+ const normalizedModule = __mfNormalizeRuntimeShare(mod);
1438
+ const exportModule = normalizedModule === mod ? {...mod} : normalizedModule;
1424
1439
  Object.defineProperty(exportModule, "__esModule", {
1425
1440
  value: true,
1426
1441
  enumerable: false
@@ -1428,6 +1443,17 @@ function generateSharedCacheSeedItem(pkg, importPath) {
1428
1443
  __mfModuleCache.share[${JSON.stringify(pkg)}] = exportModule;
1429
1444
  }`;
1430
1445
  }
1446
+ const normalizeRuntimeShareCode = `const __mfNormalizeRuntimeShare = (mod) => {
1447
+ let current = mod;
1448
+ for (let i = 0; i < 5; i++) {
1449
+ const defaultExport = current?.default;
1450
+ if (!defaultExport || typeof defaultExport !== "object") break;
1451
+ const namedValues = Object.keys(current).filter((key) => key !== "default").map((key) => current[key]);
1452
+ if (namedValues.length > 0 && namedValues.some((value) => value !== undefined)) break;
1453
+ current = defaultExport;
1454
+ }
1455
+ return current;
1456
+ };`;
1431
1457
  function generateDirectSharedCacheSeedCode(command = "build") {
1432
1458
  return getOrderedUsedShares().map((pkg) => {
1433
1459
  const shareItem = getShareItemForPreload(pkg);
@@ -1450,7 +1476,8 @@ function getHostAutoInitSharedSeedItems() {
1450
1476
  return priority(a.pkg) - priority(b.pkg) || Number(aIsLocal) - Number(bIsLocal) || a.pkg.localeCompare(b.pkg);
1451
1477
  });
1452
1478
  }
1453
- function generateHostAutoInitSharedCacheSeedCode() {
1479
+ function generateHostAutoInitSharedCacheSeedCode(command = "build") {
1480
+ if (command === "build") return "";
1454
1481
  return getHostAutoInitSharedSeedItems().map(({ pkg, shareItem }) => {
1455
1482
  if (!shareItem) return null;
1456
1483
  return generateSharedCacheSeedItem(pkg, getBrowserImportPath(getDirectSharedCacheSeedImportPath(pkg, shareItem)));
@@ -1482,14 +1509,13 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
1482
1509
  if (typeof __VUE_HMR_RUNTIME__ === 'undefined') {
1483
1510
  globalThis.__VUE_HMR_RUNTIME__ = { createRecord() {}, rerender() {}, reload() {} };
1484
1511
  }
1485
- import {createInstance, loadRemote} from "@module-federation/runtime";
1512
+ import {init as runtimeInit, loadRemote} from "@module-federation/runtime";
1486
1513
  ${pluginImportNames.map((item) => item[1]).join("\n")}
1487
1514
  ${command === "build" ? getRuntimeInitResolveBootstrapCode() : getRuntimeInitBootstrapCode() + "\n const { initResolve } = globalThis[globalKey];"}
1488
1515
  ${getRuntimeModuleCacheBootstrapCode()}
1489
1516
  const initTokens = {}
1490
1517
  const shareScopeName = ${JSON.stringify(options.shareScope)}
1491
1518
  const mfName = ${JSON.stringify(options.internalName)}
1492
- let runtimeInstance
1493
1519
  let localSharedImportMapPromise
1494
1520
  let exposesMapPromise
1495
1521
  const shouldRetrySharedInitError = ${command !== "build"} && ((error) => {
@@ -1532,19 +1558,13 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
1532
1558
  async function init(shared = {}, initScope = []) {
1533
1559
  const {usedShared, usedRemotes} = await getLocalSharedImportMap()
1534
1560
  ${generateDirectSharedCacheSeedCode(command)}
1535
- const runtimeOptions = {
1561
+ const initRes = runtimeInit({
1536
1562
  name: mfName,
1537
1563
  remotes: usedRemotes,
1538
1564
  shared: usedShared,
1539
1565
  plugins: [${pluginImportNames.map((item) => `${item[0]}(${item[2]})`).join(", ")}],
1540
1566
  ${options.shareStrategy ? `shareStrategy: '${options.shareStrategy}'` : ""}
1541
- };
1542
- if (!runtimeInstance) {
1543
- runtimeInstance = createInstance(runtimeOptions);
1544
- } else {
1545
- runtimeInstance.initOptions(runtimeOptions);
1546
- }
1547
- const initRes = runtimeInstance;
1567
+ });
1548
1568
  // handling circular init calls
1549
1569
  var initToken = initTokens[shareScopeName];
1550
1570
  if (!initToken)
@@ -1564,6 +1584,17 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
1564
1584
  } catch (e) {
1565
1585
  console.error('[Module Federation]', e)
1566
1586
  }
1587
+ for (const [pkg, share] of Object.entries(usedShared)) {
1588
+ if (share.shareConfig?.import !== false || __mfModuleCache.share[pkg] !== undefined) continue;
1589
+ ${normalizeRuntimeShareCode}
1590
+ const versions = shared?.[pkg];
1591
+ const provider = versions && versions[Object.keys(versions)[0]];
1592
+ if (!provider) continue;
1593
+ const factory = provider.lib || (provider.loading ? await provider.loading : await provider.get?.());
1594
+ const mod = typeof factory === "function" ? factory() : factory;
1595
+ const resolved = await Promise.resolve(mod);
1596
+ __mfModuleCache.share[pkg] = __mfNormalizeRuntimeShare(resolved);
1597
+ }
1567
1598
  return initRes
1568
1599
  }
1569
1600
 
@@ -1588,10 +1619,11 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build") {
1588
1619
  async function initHost() {
1589
1620
  if (!hostInitPromise) {
1590
1621
  hostInitPromise = (async () => {
1591
- ${generateHostAutoInitSharedCacheSeedCode()}
1622
+ ${generateHostAutoInitSharedCacheSeedCode(_command)}
1592
1623
  const remoteEntry = await import(${remoteEntryImport});
1593
1624
  const runtime = await remoteEntry.init();
1594
1625
  const usedShared = ${generateUsedSharedPreloadConfig()};
1626
+ ${normalizeRuntimeShareCode}
1595
1627
  for (const [pkg, share] of Object.entries(usedShared)) {
1596
1628
  if (__mfModuleCache.share[pkg] !== undefined) {
1597
1629
  continue;
@@ -1601,7 +1633,7 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build") {
1601
1633
  }).then((factory) => {
1602
1634
  const mod = typeof factory === "function" ? factory() : factory;
1603
1635
  return Promise.resolve(mod).then((resolved) => {
1604
- __mfModuleCache.share[pkg] = resolved;
1636
+ __mfModuleCache.share[pkg] = __mfNormalizeRuntimeShare(resolved);
1605
1637
  });
1606
1638
  });
1607
1639
  }
@@ -1630,7 +1662,7 @@ function getHostAutoInitImportId() {
1630
1662
  return hostAutoInitModule.getImportId();
1631
1663
  }
1632
1664
  function getHostAutoInitPath() {
1633
- return hostAutoInitModule.getPath();
1665
+ return hostAutoInitModule.getImportId();
1634
1666
  }
1635
1667
  //#endregion
1636
1668
  //#region src/virtualModules/virtualRemotes.ts
@@ -1653,7 +1685,9 @@ function getUsedRemotesMap() {
1653
1685
  }
1654
1686
  function generateRemotes(id, command) {
1655
1687
  const useReactProxy = command === "serve" && hasPackageDependency("react");
1656
- const reactImportLine = useReactProxy ? `import * as __mfReact from "react";` : "";
1688
+ const reactImportLine = useReactProxy ? `import __mfReactDefault from "react";
1689
+ import * as __mfReactNamespace from "react";
1690
+ const __mfReact = __mfReactDefault ?? __mfReactNamespace.default ?? __mfReactNamespace;` : "";
1657
1691
  const importLine = command === "build" ? `${getRuntimeModuleCacheBootstrapCode()}
1658
1692
  import { hostInitPromise as __mfHostInitPromise } from ${JSON.stringify(getHostAutoInitPath())};` : `${getRuntimeInitBootstrapCode()}
1659
1693
  const { initPromise, moduleCache: __mfModuleCache } = globalThis[globalKey];`;
@@ -1663,13 +1697,13 @@ function generateRemotes(id, command) {
1663
1697
  }
1664
1698
  export const __moduleExports = exportModule;
1665
1699
  export const __mf_remote_pending = Promise.resolve(exportModule);
1666
- export default exportModule?.__esModule ? exportModule.default : exportModule.default ?? exportModule` : command === "build" ? `if (__mfRemotePending) {
1700
+ export default exportModule?.__mf_is_remote_proxy ? exportModule : exportModule?.__esModule ? exportModule.default : exportModule.default ?? exportModule` : command === "build" ? `if (__mfRemotePending) {
1667
1701
  const mod = await __mfRemotePending;
1668
1702
  if (mod !== undefined) exportModule = mod;
1669
1703
  }
1670
1704
  export const __moduleExports = exportModule;
1671
1705
  export const __mf_remote_pending = Promise.resolve(exportModule);
1672
- export default exportModule?.__esModule ? exportModule.default : exportModule.default ?? exportModule` : "export default exportModule";
1706
+ export default exportModule?.__mf_is_remote_proxy ? exportModule : exportModule?.__esModule ? exportModule.default : exportModule.default ?? exportModule` : "export default exportModule";
1673
1707
  return `
1674
1708
  ${reactImportLine}
1675
1709
  ${importLine}
@@ -1869,6 +1903,9 @@ ${importHelper}(async () => {
1869
1903
  if (inject === "html" && hasPackageDependency("@sveltejs/kit")) return false;
1870
1904
  return inject === "entry" || !htmlFilePath;
1871
1905
  }
1906
+ function normalizeDevHtmlProxyId(id) {
1907
+ return id.replace(/^\0/, "").replace(/^\/@id\//, "").replace(/^__x00__/, "");
1908
+ }
1872
1909
  return [{
1873
1910
  name: "add-entry",
1874
1911
  apply: "serve",
@@ -1887,7 +1924,20 @@ ${importHelper}(async () => {
1887
1924
  }
1888
1925
  },
1889
1926
  configureServer(server) {
1890
- server.middlewares.use((req, _res, next) => {
1927
+ server.middlewares.use((req, res, next) => {
1928
+ const rawUrl = req.url?.split("#")[0] ?? "";
1929
+ if (normalizeDevHtmlProxyId(rawUrl.split("?")[0]) === DEV_HTML_PROXY_PREFIX.slice(0, -1)) {
1930
+ const query = rawUrl.slice(rawUrl.indexOf("?") + 1);
1931
+ const params = new URLSearchParams(query);
1932
+ const initSrc = params.get("init");
1933
+ const entrySrc = params.get("entry");
1934
+ if (initSrc && entrySrc) {
1935
+ res.statusCode = 200;
1936
+ res.setHeader("Content-Type", "application/javascript");
1937
+ res.end(getBootstrapSource(initSrc, entrySrc));
1938
+ return;
1939
+ }
1940
+ }
1891
1941
  if (!fileName) {
1892
1942
  next();
1893
1943
  return;
@@ -1904,7 +1954,7 @@ ${importHelper}(async () => {
1904
1954
  const base = viteConfig.base.replace(/\/$/, "");
1905
1955
  const stripBase = (p) => base && p.startsWith(base + "/") ? p.slice(base.length) : p;
1906
1956
  const html = rewriteEntryScripts(c, (originalSrc) => {
1907
- return `/@id/${DEV_HTML_PROXY_PREFIX}${new URLSearchParams({
1957
+ return `/@id/__x00__${DEV_HTML_PROXY_PREFIX}${new URLSearchParams({
1908
1958
  init: sanitizeDevEntryPath(stripBase(devEntryPath)),
1909
1959
  entry: sanitizeDevEntryPath(stripBase(originalSrc))
1910
1960
  }).toString()}`;
@@ -1913,11 +1963,12 @@ ${importHelper}(async () => {
1913
1963
  }
1914
1964
  },
1915
1965
  resolveId(id) {
1916
- if (id.startsWith(DEV_HTML_PROXY_PREFIX)) return id;
1966
+ if (normalizeDevHtmlProxyId(id).startsWith(DEV_HTML_PROXY_PREFIX)) return id;
1917
1967
  },
1918
1968
  load(id) {
1919
- if (!id.startsWith(DEV_HTML_PROXY_PREFIX)) return;
1920
- const params = new URLSearchParams(id.slice(28));
1969
+ const normalizedId = normalizeDevHtmlProxyId(id);
1970
+ if (!normalizedId.startsWith(DEV_HTML_PROXY_PREFIX)) return;
1971
+ const params = new URLSearchParams(normalizedId.slice(28));
1921
1972
  const initSrc = params.get("init");
1922
1973
  const entrySrc = params.get("entry");
1923
1974
  if (!initSrc || !entrySrc) return;
@@ -2724,7 +2775,7 @@ function collectSystemProxyInfos(proxyChunks, loadShareTag) {
2724
2775
  for (const m of proxyInfo.code.matchAll(/exports\(\s*["']([^"']+)["']\s*,([\s\S]*?)\);/g)) {
2725
2776
  const exported = m[1];
2726
2777
  const expression = m[2];
2727
- for (const [local, exportName] of Object.entries(loadShareBindings)) if (new RegExp(`\\b${local}\\b`).test(expression)) {
2778
+ for (const [local, exportName] of Object.entries(loadShareBindings).reverse()) if (new RegExp(`\\b${local}\\b`).test(expression)) {
2728
2779
  exportMap[exported] = {
2729
2780
  type: "reexport",
2730
2781
  exportName
@@ -3488,7 +3539,7 @@ function pluginProxyRemotes_default(options) {
3488
3539
  const remoteModule = getRemoteVirtualModule(source, command);
3489
3540
  addUsedRemote(remoteName, source);
3490
3541
  refreshHostAutoInit();
3491
- return remoteModule.getPath();
3542
+ return remoteModule.getImportId();
3492
3543
  }
3493
3544
  return {
3494
3545
  name: "proxyRemotes",
@@ -3890,7 +3941,7 @@ async function collectFromEsLexer(code, isRemoteImport) {
3890
3941
  await init;
3891
3942
  let imports;
3892
3943
  try {
3893
- [imports] = parse$1(code);
3944
+ [imports] = parse(code);
3894
3945
  } catch {
3895
3946
  return;
3896
3947
  }
@@ -4310,12 +4361,12 @@ function isFederationHtmlPreloadDependency(dep, includeSharedRuntime = false) {
4310
4361
  return includeSharedRuntime && (file.includes("preload-helper") || file.includes("rolldown-runtime") || file.startsWith("dist-"));
4311
4362
  }
4312
4363
  /**
4313
- * Plugin that runs FIRST to create virtual module files in the config hook.
4314
- * This prevents 504 "Outdated Optimize Dep" errors by ensuring files exist
4364
+ * Plugin that runs FIRST to register generated virtual modules in the config hook.
4365
+ * This prevents 504 "Outdated Optimize Dep" errors by ensuring ids are known
4315
4366
  * before Vite's optimization phase.
4316
4367
  */
4317
4368
  function createEarlyVirtualModulesPlugin(options) {
4318
- const { shared, remotes, virtualModuleDir } = options;
4369
+ const { shared, remotes } = options;
4319
4370
  const isLitShare = (pkg) => pkg === "lit" || pkg.startsWith("lit/");
4320
4371
  return {
4321
4372
  name: "vite:module-federation-early-init",
@@ -4325,9 +4376,6 @@ function createEarlyVirtualModulesPlugin(options) {
4325
4376
  const root = config.root || process.cwd();
4326
4377
  setPackageDetectionCwd(root);
4327
4378
  const isVinext = hasPackageDependency("vinext");
4328
- initVirtualModuleInfrastructure(root, virtualModuleDir);
4329
- VirtualModule.setRoot(root);
4330
- VirtualModule.ensureVirtualPackageExists();
4331
4379
  initVirtualModules(_command, getRemoteEntryId(options));
4332
4380
  const isRolldown = getIsRolldown(this);
4333
4381
  if (remotes && Object.keys(remotes).length > 0) {
@@ -4373,6 +4421,10 @@ function createEarlyVirtualModulesPlugin(options) {
4373
4421
  optimizeDeps.esbuildOptions.plugins.push({
4374
4422
  name: "module-federation:optimize-shared-proxy",
4375
4423
  setup(build) {
4424
+ build.onResolve({ filter: /^virtual:mf:/ }, (args) => ({
4425
+ path: args.path,
4426
+ external: true
4427
+ }));
4376
4428
  build.onResolve({ filter: /.*/ }, (args) => {
4377
4429
  if (!args.importer || args.namespace === "mf-shared") return;
4378
4430
  if (isSharedResolverInternalImporter(args.importer)) return;
@@ -4404,7 +4456,6 @@ export default __mfShared.default ?? __mfShared;`
4404
4456
  }
4405
4457
  });
4406
4458
  }
4407
- config.optimizeDeps.include.push(virtualRuntimeInitStatus.getImportId());
4408
4459
  }
4409
4460
  for (const key of Object.keys(shared)) {
4410
4461
  const shareItem = shared[key];
@@ -4415,7 +4466,6 @@ export default __mfShared.default ?? __mfShared;`
4415
4466
  for (const subpath of getCommonSharedSubpaths(key)) {
4416
4467
  writePreBuildLibPath(subpath, shareItem);
4417
4468
  optimizeDeps.include.push(subpath);
4418
- optimizeDeps.include.push(getPreBuildLibImportId(subpath));
4419
4469
  }
4420
4470
  }
4421
4471
  continue;
@@ -4432,14 +4482,11 @@ export default __mfShared.default ?? __mfShared;`
4432
4482
  const optimizeDeps = config.optimizeDeps ??= {};
4433
4483
  optimizeDeps.include ??= [];
4434
4484
  optimizeDeps.exclude ??= [];
4435
- const shouldBypassOptimizeDep = isLitShare(key);
4436
- if (shouldBypassOptimizeDep) optimizeDeps.exclude.push(key);
4437
- if (!isRolldown && !shouldBypassOptimizeDep) optimizeDeps.include.push(getLoadShareImportId(key, isRolldown));
4438
- optimizeDeps.include.push(getPreBuildLibImportId(key));
4485
+ if (isLitShare(key)) optimizeDeps.exclude.push(key);
4486
+ else optimizeDeps.include.push(key);
4439
4487
  for (const subpath of getCommonSharedSubpaths(key)) {
4440
4488
  writePreBuildLibPath(subpath, shareItem);
4441
4489
  optimizeDeps.include.push(subpath);
4442
- optimizeDeps.include.push(getPreBuildLibImportId(subpath));
4443
4490
  }
4444
4491
  }
4445
4492
  }
@@ -4459,6 +4506,21 @@ function federation(mfUserOptions) {
4459
4506
  let command;
4460
4507
  let desiredRolldownOutput;
4461
4508
  return [
4509
+ {
4510
+ name: "vite:module-federation-virtual-modules",
4511
+ enforce: "pre",
4512
+ resolveId(id) {
4513
+ const virtualModule = VirtualModule.findById(id);
4514
+ if (!virtualModule) return;
4515
+ return virtualModule.getResolvedId();
4516
+ },
4517
+ load(id) {
4518
+ const virtualModule = VirtualModule.findById(id);
4519
+ if (!virtualModule) return;
4520
+ if (command === "build" && (id.includes("__loadShare__") || id.includes("__loadRemote__"))) return;
4521
+ return virtualModule.code;
4522
+ }
4523
+ },
4462
4524
  createEarlyVirtualModulesPlugin(options),
4463
4525
  ...isVinext ? [{
4464
4526
  name: "module-federation-vinext-react-server-build-alias",
@@ -4483,9 +4545,7 @@ function federation(mfUserOptions) {
4483
4545
  config(_config, env) {
4484
4546
  command = env.command;
4485
4547
  },
4486
- configResolved(config) {
4487
- VirtualModule.setRoot(config.root);
4488
- VirtualModule.ensureVirtualPackageExists();
4548
+ configResolved() {
4489
4549
  initVirtualModules(command, remoteEntryId);
4490
4550
  }
4491
4551
  },
@@ -4628,9 +4688,8 @@ function federation(mfUserOptions) {
4628
4688
  }
4629
4689
  },
4630
4690
  load(id) {
4631
- if (id.startsWith("\0")) return;
4632
4691
  if (id.includes("__loadShare__") || id.includes("__loadRemote__")) {
4633
- let code = readFileSync(id, "utf-8");
4692
+ let code = VirtualModule.findById(id)?.code ?? readFileSync(id, "utf-8");
4634
4693
  code = code.replace(/import\s+["'][^"']*__prebuild__[^"']*["']\s*;?/g, "");
4635
4694
  code = code.replace(/export\s+\*\s+from\s+["'][^"']*__prebuild__[^"']*["']\s*;?/g, "");
4636
4695
  /**
@@ -4649,7 +4708,10 @@ function federation(mfUserOptions) {
4649
4708
  *
4650
4709
  * @see https://rollupjs.org/plugin-development/#synthetic-named-exports
4651
4710
  */
4652
- if (!code.includes("__moduleExports")) code = code.replace("export default exportModule", "export const __moduleExports = exportModule;\nexport default exportModule.__esModule ? exportModule.default : exportModule");
4711
+ if (!/\bexport\s+const\s+__moduleExports\b/.test(code)) {
4712
+ const nextCode = code.replace("export default exportModule", "export const __moduleExports = exportModule;\nexport default exportModule.__esModule ? exportModule.default : exportModule");
4713
+ code = nextCode === code ? `${code}\nexport const __moduleExports = exportModule;\n` : nextCode;
4714
+ }
4653
4715
  if (getIsRolldown(this)) return { code };
4654
4716
  return {
4655
4717
  code,
@@ -4714,14 +4776,9 @@ function federation(mfUserOptions) {
4714
4776
  config.build ||= {};
4715
4777
  config.build.commonjsOptions ||= {};
4716
4778
  config.build.commonjsOptions.strictRequires ??= "auto";
4717
- const virtualDir = options.virtualModuleDir;
4718
4779
  config.optimizeDeps ||= {};
4719
4780
  config.optimizeDeps.include ||= [];
4720
4781
  config.optimizeDeps.include.push("@module-federation/runtime");
4721
- if (!isRolldown) config.optimizeDeps.include.push(virtualDir);
4722
- config.ssr ||= {};
4723
- config.ssr.noExternal ||= [];
4724
- if (Array.isArray(config.ssr.noExternal)) config.ssr.noExternal.push(virtualDir);
4725
4782
  options.runtimePlugins.forEach((p) => {
4726
4783
  const pluginPath = typeof p === "string" ? p : p[0];
4727
4784
  if (pluginPath && !pluginPath.startsWith(".") && !pluginPath.startsWith("/") && !pluginPath.startsWith("\0") && !pluginPath.startsWith("virtual:")) config.optimizeDeps.include.push(pluginPath);
@@ -4729,9 +4786,6 @@ function federation(mfUserOptions) {
4729
4786
  if (isRolldown) {
4730
4787
  config.build ??= {};
4731
4788
  config.build.target ??= "esnext";
4732
- } else {
4733
- config.optimizeDeps.needsInterop ||= [];
4734
- config.optimizeDeps.needsInterop.push(virtualDir);
4735
4789
  }
4736
4790
  const isAstro = hasPackageDependency("astro");
4737
4791
  const resolvedTarget = options.target ?? (config.build?.ssr ? "node" : "web");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@module-federation/vite",
3
- "version": "1.15.2",
3
+ "version": "1.15.3",
4
4
  "description": "Vite plugin for Module Federation",
5
5
  "type": "module",
6
6
  "main": "./lib/index.cjs",
@@ -84,6 +84,7 @@
84
84
  "oxfmt": "^0.36.0",
85
85
  "rollup": "^4.47.1",
86
86
  "tsdown": "^0.21.0",
87
+ "typescript": "5.9.3",
87
88
  "vite": "^8.0.10",
88
89
  "vitest": "^4.0.18"
89
90
  }