@module-federation/vite 1.16.11 → 1.16.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,6 +6,23 @@
6
6
 
7
7
  [Read the announcement](https://www.linkedin.com/posts/voidzero_github-module-federationvite-vite-plugin-activity-7449452398202241024-JyAL).
8
8
 
9
+ <div align="center">
10
+ <h2>Gold Sponsor</h2>
11
+ <a href="https://www.zephyr-cloud.io/">
12
+ <img src="./docs/sponsors/zephyr-logo.png" alt="Zephyr Cloud" width="360" />
13
+ </a>
14
+
15
+ <h3>Sponsors</h3>
16
+ <p>
17
+ <a href="https://github.com/thecoder93">
18
+ <img src="https://github.com/thecoder93.png?size=96" alt="thecoder93" width="64" height="64" />
19
+ </a>
20
+ <a href="https://github.com/stephanelgrg">
21
+ <img src="https://github.com/stephanelgrg.png?size=96" alt="stephanelgrg" width="64" height="64" />
22
+ </a>
23
+ </p>
24
+ </div>
25
+
9
26
  ## Reason why 🤔
10
27
 
11
28
  [Microservices](https://martinfowler.com/articles/microservices.html) nowadays is a well-known concept and maybe you are using it in your current company.
package/lib/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { _ as mfWarn, a as getIsRolldown, c as getPackageNameFromNodeModulePath, d as isNuxtProjectRoot, f as packageNameDecode, g as createModuleFederationError, h as setPackageDetectionCwd, i as getInstalledPackageJson, l as getSharedCacheKey, m as resolveImportPath, o as getPackageDetectionCwd, p as packageNameEncode, r as getInstalledPackageEntry, s as getPackageName, u as hasPackageDependency, v as normalizePathForImport, y as rebaseImport } from "./pluginDts-CrSsDUnT.js";
1
+ import { _ as createModuleFederationError, a as getIsRolldown, b as rebaseImport, c as getPackageNameFromNodeModulePath, d as isNuxtProjectRoot, f as packageNameDecode, g as sharedCacheHelperCode, h as setPackageDetectionCwd, i as getInstalledPackageJson, l as getSharedCacheDescriptor, m as resolveImportPath, o as getPackageDetectionCwd, p as packageNameEncode, r as getInstalledPackageEntry, s as getPackageName, u as hasPackageDependency, v as mfWarn, y as normalizePathForImport } from "./pluginDts-CTAHkt4C.js";
2
2
  import { createRequire } from "node:module";
3
- import * as fs$1 from "fs";
3
+ import * as fs$2 from "fs";
4
4
  import { existsSync, readFileSync, realpathSync, statSync, writeFileSync } from "fs";
5
5
  import { createRequire as createRequire$1 } from "module";
6
6
  import * as path$1 from "node:path";
@@ -8,6 +8,7 @@ import path, { basename } from "node:path";
8
8
  import { fileURLToPath, pathToFileURL } from "url";
9
9
  import { version } from "vite";
10
10
  import { createHash } from "node:crypto";
11
+ import * as fs$1 from "node:fs";
11
12
  import { existsSync as existsSync$1, readFileSync as readFileSync$1 } from "node:fs";
12
13
  import { pathToFileURL as pathToFileURL$1 } from "node:url";
13
14
  //#region src/utils/codeRewriter.ts
@@ -360,7 +361,7 @@ function normalizeShared(shared) {
360
361
  const result = {};
361
362
  const packageJsonPath = path$1.join(getPackageDetectionCwd(), "package.json");
362
363
  try {
363
- const packageJson = JSON.parse(fs$1.readFileSync(packageJsonPath, "utf-8"));
364
+ const packageJson = JSON.parse(fs$2.readFileSync(packageJsonPath, "utf-8"));
364
365
  if (packageJson.name === "@module-federation/vite") return result;
365
366
  Object.keys(packageJson.dependencies || {}).filter((key) => shouldAutoShareDependency(key)).forEach((key) => {
366
367
  result[key] = normalizeShareItem(key, {
@@ -434,7 +435,7 @@ function resolveRuntimeImplementation() {
434
435
  const fallback = resolveImportPath("@module-federation/runtime");
435
436
  try {
436
437
  const packageJsonPath = resolveImportPath("@module-federation/runtime/package.json");
437
- const packageJson = JSON.parse(fs$1.readFileSync(packageJsonPath, "utf-8"));
438
+ const packageJson = JSON.parse(fs$2.readFileSync(packageJsonPath, "utf-8"));
438
439
  const importExport = packageJson.exports?.["."];
439
440
  const exportImport = typeof importExport === "object" ? typeof importExport.import === "string" ? importExport.import : importExport.import?.default : void 0;
440
441
  const esmEntry = packageJson.module || exportImport;
@@ -573,6 +574,27 @@ var VirtualModule = class VirtualModule {
573
574
  }
574
575
  };
575
576
  //#endregion
577
+ //#region src/utils/ssrCapabilities.ts
578
+ /** A browser-safe generated expression that is true only in Node.js. */
579
+ const SERVER_ENV_GUARD = "typeof process !== 'undefined' && !!process.versions && !!process.versions.node";
580
+ /**
581
+ * Single source of truth for SSR-related feature gates.
582
+ *
583
+ * - Vite 8+ dev: ModuleRunner + FetchableDevEnvironment for `/__mf_ssr__/` entries.
584
+ * - Any Vite major on build/preview: HTTP fetch + temp-file import via ssrEntryLoader.
585
+ */
586
+ function getSsrCapabilities(viteMajor, command, hasRemotes) {
587
+ if (!hasRemotes) return {
588
+ enableSsrInitBootstrap: false,
589
+ injectSsrEntryLoader: false
590
+ };
591
+ const supported = command === "build" || command === "serve" && viteMajor >= 8;
592
+ return {
593
+ enableSsrInitBootstrap: supported,
594
+ injectSsrEntryLoader: supported
595
+ };
596
+ }
597
+ //#endregion
576
598
  //#region src/utils/serializeRuntimeOptions.ts
577
599
  /**
578
600
  * Serializes a JavaScript object into a string of source code that can be evaluated.
@@ -722,7 +744,7 @@ function setSsrRemotes(remotes) {
722
744
  }
723
745
  function getSsrNoopResolveCode(enableSsrInit, hostInitImportId, initResolveExpression = "initResolve") {
724
746
  if (!enableSsrInit) return "";
725
- return `if (typeof window === 'undefined') {
747
+ return `if (${SERVER_ENV_GUARD}) {
726
748
  var _noop = { loadRemote: function() { return Promise.resolve(undefined); }, loadShare: function() { return Promise.resolve(undefined); } };
727
749
  ${hostInitImportId ? `import(${JSON.stringify(hostInitImportId)})
728
750
  .then(function(mod) { return mod.hostInitPromise; })
@@ -781,7 +803,7 @@ globalThis[globalKey] = {
781
803
  };
782
804
  }
783
805
  ${enableSsrInit ? `
784
- if (typeof window === 'undefined' && !globalThis[globalKey].ssrInitStarted) {
806
+ if (${SERVER_ENV_GUARD} && !globalThis[globalKey].ssrInitStarted) {
785
807
  globalThis[globalKey].ssrInitStarted = true;
786
808
  ${getSsrNoopResolveCode(enableSsrInit, hostInitImportId, "globalThis[globalKey].initResolve")}
787
809
  }` : ""}
@@ -862,6 +884,9 @@ function escapeGeneratedStringLiteral(value) {
862
884
  }
863
885
  });
864
886
  }
887
+ function getSharedCacheDescriptorLiteral(pkg, shareItem) {
888
+ return JSON.stringify(getSharedCacheDescriptor(pkg, shareItem));
889
+ }
865
890
  function isValidJsIdentifier(name) {
866
891
  return JS_IDENTIFIER_REGEX.test(name);
867
892
  }
@@ -1031,7 +1056,7 @@ function getSharedNamedExports(pkg, shareItem) {
1031
1056
  }
1032
1057
  function getLocalProviderImportPath(pkg) {
1033
1058
  try {
1034
- const resolved = createRequire$1(pathToFileURL(path$1.join(getPackageDetectionCwd(), "package.json"))).resolve(pkg);
1059
+ const resolved = resolveWorkspaceEsmEntry(pkg, createRequire$1(pathToFileURL(path$1.join(getPackageDetectionCwd(), "package.json"))).resolve(pkg));
1035
1060
  return isWorkspaceFilePath(resolved) ? resolved : void 0;
1036
1061
  } catch {
1037
1062
  const resolved = getInstalledPackageEntry(pkg, {
@@ -1052,7 +1077,7 @@ function getProjectResolvedImportPath(pkg) {
1052
1077
  if (esmEntry) return esmEntry;
1053
1078
  }
1054
1079
  try {
1055
- return createRequire$1(pathToFileURL(path$1.join(getPackageDetectionCwd(), "package.json"))).resolve(pkg);
1080
+ return resolveWorkspaceEsmEntry(pkg, createRequire$1(pathToFileURL(path$1.join(getPackageDetectionCwd(), "package.json"))).resolve(pkg));
1056
1081
  } catch {
1057
1082
  return;
1058
1083
  }
@@ -1065,6 +1090,30 @@ function isWorkspaceFilePath(resolved) {
1065
1090
  } catch {}
1066
1091
  return !realResolved.includes("/node_modules/") && !realResolved.includes("\\node_modules\\");
1067
1092
  }
1093
+ /**
1094
+ * When createRequire resolves a workspace package to a CJS entry (e.g. dist/index.cjs),
1095
+ * re-resolve via getInstalledPackageEntry with ESM-preferring conditions.
1096
+ *
1097
+ * Workspace packages produce browser code, so they must use the ESM build — CJS files
1098
+ * contain `module.exports` which is undefined in the browser. createRequire().resolve()
1099
+ * follows Node.js CJS conditions ["node", "require"], which matches exports["."].require.default
1100
+ * and returns the .cjs path for packages with dual ESM/CJS exports.
1101
+ */
1102
+ function resolveWorkspaceEsmEntry(pkg, resolved, cwd = getPackageDetectionCwd()) {
1103
+ if (!isWorkspaceFilePath(resolved)) return resolved;
1104
+ const esmEntry = getInstalledPackageEntry(pkg, {
1105
+ cwd,
1106
+ conditions: [
1107
+ "browser",
1108
+ "import",
1109
+ "module",
1110
+ "default"
1111
+ ],
1112
+ resolveSubpathWithRequire: false
1113
+ });
1114
+ if (esmEntry && isWorkspaceFilePath(esmEntry)) return esmEntry;
1115
+ return resolved;
1116
+ }
1068
1117
  function isWorkspacePackageEntry(pkg, resolved) {
1069
1118
  if (!resolved || !path$1.isAbsolute(resolved) || !isWorkspaceFilePath(resolved)) return false;
1070
1119
  return !!getInstalledPackageJson(pkg, {
@@ -1117,7 +1166,7 @@ function isWorkspaceSingletonConsumedByPeer(pkg) {
1117
1166
  }
1118
1167
  function tryResolveImportFromPackageRoot(pkg, root) {
1119
1168
  try {
1120
- return createRequire$1(pathToFileURL(path$1.join(root, "package.json"))).resolve(pkg);
1169
+ return resolveWorkspaceEsmEntry(pkg, createRequire$1(pathToFileURL(path$1.join(root, "package.json"))).resolve(pkg), root);
1121
1170
  } catch {
1122
1171
  return;
1123
1172
  }
@@ -1143,11 +1192,18 @@ function writePreBuildLibPath(pkg, shareItem) {
1143
1192
  preBuildShareItemMap[pkg] = shareItem;
1144
1193
  const importSource = getConcreteSharedImportSource(pkg, shareItem) || pkg;
1145
1194
  if (pkg === "react/compiler-runtime") {
1195
+ const reactCacheDescriptor = getSharedCacheDescriptorLiteral("react", shareItem ?? {
1196
+ name: "react",
1197
+ from: "",
1198
+ scope: "default",
1199
+ shareConfig: { singleton: true }
1200
+ });
1146
1201
  preBuildCacheMap[pkg].writeSync(`
1202
+ ${sharedCacheHelperCode}
1147
1203
  const __mfCacheGlobalKey = "__mf_module_cache__";
1148
1204
  export const c = function(size) {
1149
1205
  const cache = globalThis[__mfCacheGlobalKey]?.share;
1150
- const sharedReact = cache?.['react'];
1206
+ const sharedReact = cache && __mfReadSharedCache(cache, ${reactCacheDescriptor});
1151
1207
  const reactExports = sharedReact?.default ?? sharedReact;
1152
1208
  const internals = reactExports?.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
1153
1209
  return internals?.H?.useMemoCache(size);
@@ -1244,34 +1300,36 @@ function materializeCachedLoadShareModule(options) {
1244
1300
  options.addUsedShares(pkg);
1245
1301
  options.writeLocalSharedImportMap();
1246
1302
  }
1247
- function generateEagerWorkspaceSingletonExports(namedExports, importSource, cacheKey) {
1248
- const namedExportLine = namedExports.length > 0 ? `\n export { ${namedExports.join(", ")} } from ${escapeGeneratedStringLiteral(importSource)};` : "";
1303
+ function generateEagerWorkspaceSingletonExports(namedExports, importSource, cacheDescriptor) {
1304
+ const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
1305
+ const namedExportAssignments = namedExports.length > 0 ? `\n ${namedExports.map((name, i) => `const ${namedExportVars[i]} = exportModule[${escapeGeneratedStringLiteral(name)}];`).join("\n ")}` : "";
1306
+ const namedExportLine = namedExports.length > 0 ? `\n export { ${namedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
1249
1307
  return `import * as __mfLocalShare from ${escapeGeneratedStringLiteral(importSource)};
1250
- let exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(cacheKey)}];
1308
+ let exportModule = __mfReadSharedCache(__mfModuleCache.share, ${cacheDescriptor});
1251
1309
  if (exportModule === undefined) {
1252
1310
  Promise.resolve().then(() => {
1253
- if (__mfModuleCache.share[${escapeGeneratedStringLiteral(cacheKey)}] === undefined) {
1254
- __mfModuleCache.share[${escapeGeneratedStringLiteral(cacheKey)}] = __mfNormalizeShareModule(__mfLocalShare);
1311
+ if (__mfReadSharedCache(__mfModuleCache.share, ${cacheDescriptor}) === undefined) {
1312
+ __mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, __mfNormalizeShareModule(__mfLocalShare));
1255
1313
  }
1256
1314
  });
1257
1315
  exportModule = __mfLocalShare;
1258
1316
  }
1259
- const __mf_default = exportModule.default ?? exportModule;
1317
+ const __mf_default = exportModule.default ?? exportModule;${namedExportAssignments}
1260
1318
  export { __mf_default as default };${namedExportLine}`;
1261
1319
  }
1262
- function generateLazyWorkspaceSingletonExports(namedExports, importSource, cacheKey, eagerLocalFallback) {
1320
+ function generateLazyWorkspaceSingletonExports(namedExports, importSource, cacheDescriptor, eagerLocalFallback) {
1263
1321
  const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
1264
1322
  const declarations = namedExports.length > 0 ? ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ") : "let __mf_default;";
1265
1323
  const assignments = namedExports.length > 0 ? [...namedExports.map((name, i) => `${namedExportVars[i]} = mod[${escapeGeneratedStringLiteral(name)}];`), "__mf_default = mod.default ?? mod;"].join("\n ") : "__mf_default = mod.default ?? mod;";
1266
1324
  const namedExportLine = namedExports.length > 0 ? `\n export { ${namedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
1267
1325
  const applyLocalFallback = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
1268
- __mfModuleCache.share[${escapeGeneratedStringLiteral(cacheKey)}] = exportModule;
1326
+ __mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule);
1269
1327
  __mfApplyLazyShareExports(exportModule);`;
1270
1328
  const body = `${declarations}
1271
1329
  const __mfApplyLazyShareExports = (mod) => {
1272
1330
  ${assignments}
1273
1331
  };
1274
- let exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(cacheKey)}];
1332
+ let exportModule = __mfReadSharedCache(__mfModuleCache.share, ${cacheDescriptor});
1275
1333
  if (exportModule === undefined) {
1276
1334
  ${eagerLocalFallback ? applyLocalFallback : `if (import.meta.env.SSR) {
1277
1335
  ${applyLocalFallback}
@@ -1279,7 +1337,7 @@ function generateLazyWorkspaceSingletonExports(namedExports, importSource, cache
1279
1337
  initPromise.then(() =>
1280
1338
  import(${escapeGeneratedStringLiteral(importSource)}).then((mod) => {
1281
1339
  exportModule = __mfNormalizeShareModule(mod);
1282
- __mfModuleCache.share[${escapeGeneratedStringLiteral(cacheKey)}] = exportModule;
1340
+ __mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule);
1283
1341
  __mfApplyLazyShareExports(exportModule);
1284
1342
  })
1285
1343
  );
@@ -1301,19 +1359,16 @@ function prependWorkspaceSingletonSsrImport(code) {
1301
1359
  const quote = importMatch[1];
1302
1360
  return `import * as __mfLocalShare from ${quote}${importMatch[2]}${quote};\n${code}`;
1303
1361
  }
1304
- function generateDeferredHostProvidedExports(namedExports, pkg, cacheKey) {
1362
+ function generateDeferredHostProvidedExports(namedExports, pkg, cacheDescriptor) {
1305
1363
  const namedExportVars = namedExports.map((_name, i) => `__mf_${i}`);
1306
- const declarations = ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ");
1307
- const assignments = [...namedExports.map((name, i) => `${namedExportVars[i]} = exportModule[${escapeGeneratedStringLiteral(name)}];`), "__mf_default = exportModule.default ?? exportModule;"].join("\n ");
1308
- const namedExportLine = namedExports.length > 0 ? `\n export { ${namedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : "";
1309
- return `${declarations}
1364
+ return `${["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ")}
1310
1365
  const __mfApplyHostProvidedExports = (exportModule) => {
1311
- ${assignments}
1366
+ ${[...namedExports.map((name, i) => `${namedExportVars[i]} = exportModule[${escapeGeneratedStringLiteral(name)}];`), "__mf_default = exportModule.default ?? exportModule;"].join("\n ")}
1312
1367
  };
1313
- let exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(cacheKey)}];
1368
+ let exportModule = __mfReadSharedCache(__mfModuleCache.share, ${cacheDescriptor});
1314
1369
  if (exportModule === undefined) {
1315
1370
  initPromise.then(() => {
1316
- exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(cacheKey)}];
1371
+ exportModule = __mfReadSharedCache(__mfModuleCache.share, ${cacheDescriptor});
1317
1372
  if (exportModule === undefined) {
1318
1373
  throw new Error("[Module Federation] Shared module ${pkg} was imported before federation bootstrap finished.");
1319
1374
  }
@@ -1322,7 +1377,7 @@ function generateDeferredHostProvidedExports(namedExports, pkg, cacheKey) {
1322
1377
  } else {
1323
1378
  __mfApplyHostProvidedExports(exportModule);
1324
1379
  }
1325
- export { __mf_default as default };${namedExportLine}`;
1380
+ export { __mf_default as default };${namedExports.length > 0 ? `\n export { ${namedExports.map((name, i) => `${namedExportVars[i]} as ${name}`).join(", ")} };` : ""}`;
1326
1381
  }
1327
1382
  function generateShareModuleUnwrapCode({ source, preserveNamedExports, stopWithReturn }) {
1328
1383
  return `let current = ${source};
@@ -1344,18 +1399,19 @@ const normalizeLocalShareModuleCode = `const __mfNormalizeShareModule = (mod) =>
1344
1399
  function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
1345
1400
  if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = new VirtualModule(pkg, LOAD_SHARE_TAG, ".js");
1346
1401
  let importLine = getRuntimeModuleCacheBootstrapCode();
1347
- const cacheKey = getSharedCacheKey(pkg, shareItem);
1402
+ const cacheDescriptor = getSharedCacheDescriptorLiteral(pkg, shareItem);
1348
1403
  if (shareItem.shareConfig.import === false) {
1349
1404
  const namedExports = getPackageNamedExports(pkg);
1350
1405
  let exportLine;
1351
- if (namedExports.length > 0) exportLine = generateDeferredHostProvidedExports(namedExports, pkg, cacheKey);
1406
+ if (namedExports.length > 0) exportLine = generateDeferredHostProvidedExports(namedExports, pkg, cacheDescriptor);
1352
1407
  else {
1353
1408
  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.`);
1354
- exportLine = generateDeferredHostProvidedExports([], pkg, cacheKey);
1409
+ exportLine = generateDeferredHostProvidedExports([], pkg, cacheDescriptor);
1355
1410
  }
1356
1411
  loadShareCacheMap[pkg].writeSync(`
1357
1412
  ${getRuntimeInitPromiseBootstrapCode()}
1358
1413
  ${importLine}
1414
+ ${sharedCacheHelperCode}
1359
1415
  ${exportLine}
1360
1416
  `, true);
1361
1417
  return;
@@ -1372,10 +1428,10 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
1372
1428
  const namedExports = getSharedNamedExports(pkg, shareItem);
1373
1429
  let exportLine;
1374
1430
  let initBlock = "";
1375
- if (usesEagerWorkspaceFallback) exportLine = generateEagerWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheKey);
1431
+ if (usesEagerWorkspaceFallback) exportLine = generateEagerWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor);
1376
1432
  else if (isWorkspaceSingleton) {
1377
1433
  importLine = `${getRuntimeInitPromiseBootstrapCode()}\n ${importLine}`;
1378
- exportLine = generateLazyWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheKey, command !== "build");
1434
+ exportLine = generateLazyWorkspaceSingletonExports(namedExports, lazyLocalFallbackSource, cacheDescriptor, command !== "build");
1379
1435
  } else if (namedExports.length > 0) {
1380
1436
  const destructure = `const { ${namedExports.map((name, i) => `${name}: __mf_${i}`).join(", ")} } = exportModule;`;
1381
1437
  const namedExportLine = `export { ${namedExports.map((name, i) => `__mf_${i} as ${name}`).join(", ")} };`;
@@ -1390,11 +1446,11 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
1390
1446
  ${destructure}
1391
1447
  ${namedExportLine}`;
1392
1448
  initBlock = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
1393
- __mfModuleCache.share[${escapeGeneratedStringLiteral(cacheKey)}] = exportModule;`;
1449
+ __mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule);`;
1394
1450
  } else {
1395
1451
  exportLine = `export default exportModule.default ?? exportModule\n export * from ${escapeGeneratedStringLiteral(sharedImportSource)}`;
1396
1452
  initBlock = `exportModule = __mfNormalizeShareModule(__mfLocalShare);
1397
- __mfModuleCache.share[${escapeGeneratedStringLiteral(cacheKey)}] = exportModule;`;
1453
+ __mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule);`;
1398
1454
  }
1399
1455
  const prebuildImportLine = isWorkspaceSingleton || isWorkspacePackage && command !== "build" ? "" : `import * as __mfLocalShare from ${escapeGeneratedStringLiteral(skipServePrebuildWarmup ? devImportSource : sharedImportSource)};`;
1400
1456
  const devDynamicImportLine = isWorkspacePackage ? "" : command !== "build" && !skipServePrebuildWarmup ? `;() => import(${escapeGeneratedStringLiteral(devImportSource)}).catch(() => {});` : "";
@@ -1402,14 +1458,16 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
1402
1458
  ${prebuildImportLine}
1403
1459
  ${devDynamicImportLine}
1404
1460
  ${importLine}
1461
+ ${sharedCacheHelperCode}
1405
1462
  ${normalizeLocalShareModuleCode}
1406
1463
  ${exportLine}
1407
1464
  ` : `
1408
1465
  ${prebuildImportLine}
1409
1466
  ${devDynamicImportLine}
1410
1467
  ${importLine}
1468
+ ${sharedCacheHelperCode}
1411
1469
  ${normalizeLocalShareModuleCode}
1412
- let exportModule = __mfModuleCache.share[${escapeGeneratedStringLiteral(cacheKey)}]
1470
+ let exportModule = __mfReadSharedCache(__mfModuleCache.share, ${cacheDescriptor})
1413
1471
  if (exportModule === undefined) {
1414
1472
  ${initBlock}
1415
1473
  }
@@ -1596,8 +1654,8 @@ function getShareItemForPreload(pkg) {
1596
1654
  if (isExplicitSharedKey(wildcardKey)) return shared[wildcardKey];
1597
1655
  }
1598
1656
  function generateSharedCacheSeedItem(pkg, shareItem, importPath) {
1599
- const cacheKey = getSharedCacheKey(pkg, shareItem);
1600
- return `if (__mfModuleCache.share[${JSON.stringify(cacheKey)}] === undefined) {
1657
+ const cacheDescriptor = getSharedCacheDescriptor(pkg, shareItem);
1658
+ return `if (__mfReadSharedCache(__mfModuleCache.share, ${JSON.stringify(cacheDescriptor)}) === undefined) {
1601
1659
  const mod = await import(${JSON.stringify(importPath)});
1602
1660
  ${normalizeRuntimeShareCode}
1603
1661
  const normalizedModule = __mfNormalizeRuntimeShare(mod);
@@ -1606,14 +1664,9 @@ function generateSharedCacheSeedItem(pkg, shareItem, importPath) {
1606
1664
  value: true,
1607
1665
  enumerable: false
1608
1666
  });
1609
- __mfModuleCache.share[${JSON.stringify(cacheKey)}] = exportModule;
1667
+ __mfWriteSharedCache(__mfModuleCache.share, ${JSON.stringify(cacheDescriptor)}, exportModule);
1610
1668
  }`;
1611
1669
  }
1612
- const sharedCacheKeyHelperCode = `const __mfGetSharedCacheKey = (pkg, singleton, version, scope) => {
1613
- const normalizedScope = Array.isArray(scope) ? scope[0] : scope;
1614
- const prefix = (normalizedScope || "default") + ":";
1615
- return singleton || !version ? prefix + pkg : prefix + pkg + "@" + version;
1616
- };`;
1617
1670
  const normalizeRuntimeShareCode = `const __mfNormalizeRuntimeShare = (mod) => {
1618
1671
  let current = mod;
1619
1672
  for (let i = 0; i < 5; i++) {
@@ -1767,7 +1820,7 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
1767
1820
  }
1768
1821
 
1769
1822
  async function init(shared = {}, initScope = []) {
1770
- ${sharedCacheKeyHelperCode}
1823
+ ${sharedCacheHelperCode}
1771
1824
  const {usedShared, usedRemotes} = await getLocalSharedImportMap()
1772
1825
  try {
1773
1826
  const allInstances = globalThis.__FEDERATION__?.__SHARE__;
@@ -1786,16 +1839,16 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
1786
1839
  : Object.entries(versionMap);
1787
1840
  for (const [version, provider] of providerEntries) {
1788
1841
  if (!provider.lib) continue;
1789
- const cacheKey = __mfGetSharedCacheKey(pkg, provider.shareConfig?.singleton, version, ${JSON.stringify(options.shareScope)});
1790
- if (__mfModuleCache.share[cacheKey] !== undefined) continue;
1842
+ const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, provider.shareConfig?.singleton, version, ${JSON.stringify(options.shareScope)});
1843
+ if (__mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) !== undefined) continue;
1791
1844
  const mod = typeof provider.lib === "function" ? provider.lib() : provider.lib;
1792
1845
  const resolved = await Promise.resolve(mod);
1793
1846
  const normalized = __mfNormalizeRuntimeShare(resolved);
1794
- __mfModuleCache.share[cacheKey] = normalized;
1847
+ __mfWriteSharedCache(__mfModuleCache.share, cacheDescriptor, normalized);
1795
1848
  if (provider.shareConfig?.singleton && usedShare) {
1796
- const usedCacheKey = __mfGetSharedCacheKey(pkg, usedShare.shareConfig?.singleton, usedShare.version, usedShare.scope);
1797
- if (__mfModuleCache.share[usedCacheKey] === undefined) {
1798
- __mfModuleCache.share[usedCacheKey] = normalized;
1849
+ const usedCacheDescriptor = __mfGetSharedCacheDescriptor(pkg, usedShare.shareConfig?.singleton, usedShare.version, usedShare.scope);
1850
+ if (__mfReadSharedCache(__mfModuleCache.share, usedCacheDescriptor) === undefined) {
1851
+ __mfWriteSharedCache(__mfModuleCache.share, usedCacheDescriptor, normalized);
1799
1852
  }
1800
1853
  }
1801
1854
  }
@@ -1806,11 +1859,12 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
1806
1859
  console.error('[Module Federation] Failed to bridge external shared modules', e)
1807
1860
  }
1808
1861
  for (const [pkg, share] of Object.entries(usedShared)) {
1809
- const cacheKey = __mfGetSharedCacheKey(pkg, share.shareConfig?.singleton, share.version, share.scope);
1810
- if (__mfModuleCache.share[cacheKey] !== undefined) continue;
1811
- const singletonCacheKey = __mfGetSharedCacheKey(pkg, true, share.version, share.scope);
1812
- if (__mfModuleCache.share[singletonCacheKey] !== undefined) {
1813
- __mfModuleCache.share[cacheKey] = __mfModuleCache.share[singletonCacheKey];
1862
+ const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
1863
+ if (__mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) !== undefined) continue;
1864
+ const singletonCacheDescriptor = __mfGetSharedCacheDescriptor(pkg, true, share.version, share.scope);
1865
+ const singletonModule = __mfReadSharedCache(__mfModuleCache.share, singletonCacheDescriptor);
1866
+ if (singletonModule !== undefined) {
1867
+ __mfWriteSharedCache(__mfModuleCache.share, cacheDescriptor, singletonModule);
1814
1868
  }
1815
1869
  }
1816
1870
  ${generateDirectSharedCacheSeedCode(command)}
@@ -1849,8 +1903,8 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
1849
1903
  console.error('[Module Federation]', e)
1850
1904
  }
1851
1905
  for (const [pkg, share] of Object.entries(usedShared)) {
1852
- const cacheKey = __mfGetSharedCacheKey(pkg, share.shareConfig?.singleton, share.version, share.scope);
1853
- if (share.shareConfig?.import !== false || __mfModuleCache.share[cacheKey] !== undefined) continue;
1906
+ const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
1907
+ if (share.shareConfig?.import !== false || __mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) !== undefined) continue;
1854
1908
  ${normalizeRuntimeShareCode}
1855
1909
  const versions = shared?.[pkg];
1856
1910
  const provider = __mfSelectSharedProvider(versions, pkg, share, '${options.shareStrategy}');
@@ -1858,7 +1912,7 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
1858
1912
  const factory = provider.lib || (provider.loading ? await provider.loading : await provider.get?.());
1859
1913
  const mod = typeof factory === "function" ? factory() : factory;
1860
1914
  const resolved = await Promise.resolve(mod);
1861
- __mfModuleCache.share[cacheKey] = __mfNormalizeRuntimeShare(resolved);
1915
+ __mfWriteSharedCache(__mfModuleCache.share, cacheDescriptor, __mfNormalizeRuntimeShare(resolved));
1862
1916
  }
1863
1917
  return initRes
1864
1918
  }
@@ -1885,16 +1939,16 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build") {
1885
1939
  async function initHost() {
1886
1940
  if (!hostInitPromise) {
1887
1941
  hostInitPromise = (async () => {
1942
+ ${sharedCacheHelperCode}
1888
1943
  ${generateHostAutoInitSharedCacheSeedCode(_command)}
1889
1944
  const remoteEntry = await import(${remoteEntryImport});
1890
1945
  const runtime = await remoteEntry.init();
1891
1946
  const usedShared = ${generateUsedSharedPreloadConfig()};
1892
- ${sharedCacheKeyHelperCode}
1893
1947
  ${normalizeRuntimeShareCode}
1894
1948
  ${shouldPreloadShares ? `
1895
1949
  for (const [pkg, share] of Object.entries(usedShared)) {
1896
- const cacheKey = __mfGetSharedCacheKey(pkg, share.shareConfig?.singleton, share.version, share.scope);
1897
- if (__mfModuleCache.share[cacheKey] !== undefined) {
1950
+ const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
1951
+ if (__mfReadSharedCache(__mfModuleCache.share, cacheDescriptor) !== undefined) {
1898
1952
  continue;
1899
1953
  }
1900
1954
  await runtime.loadShare(pkg, {
@@ -1902,7 +1956,7 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build") {
1902
1956
  }).then((factory) => {
1903
1957
  const mod = typeof factory === "function" ? factory() : factory;
1904
1958
  return Promise.resolve(mod).then((resolved) => {
1905
- __mfModuleCache.share[cacheKey] = __mfNormalizeRuntimeShare(resolved);
1959
+ __mfWriteSharedCache(__mfModuleCache.share, cacheDescriptor, __mfNormalizeRuntimeShare(resolved));
1906
1960
  });
1907
1961
  });
1908
1962
  }
@@ -2162,7 +2216,7 @@ function generateRemotes(id, command, enableSsrInit = false, consumer = "unified
2162
2216
  const eagerLoadClientRemote = shouldEagerLoadClientRemoteInDev(command, enableSsrInit);
2163
2217
  const eagerClientInit = eagerLoadClientRemote ? getEagerDeferredClientInit() : deferredClientInit;
2164
2218
  const loadedFirstClientInit = eagerLoadClientRemote ? getEagerDeferredClientInit() : deferredClientInit;
2165
- const environmentSplitInit = (clientInit, serverInit) => consumer === "client" ? clientInit : consumer === "server" ? serverInit : `if (typeof window === "undefined") {
2219
+ const environmentSplitInit = (clientInit, serverInit) => consumer === "client" ? clientInit : consumer === "server" ? serverInit : `if (${SERVER_ENV_GUARD}) {
2166
2220
  ${serverInit}
2167
2221
  } else {
2168
2222
  ${clientInit}
@@ -2298,8 +2352,8 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
2298
2352
  });
2299
2353
  }
2300
2354
  function walkFiles(dir, predicate) {
2301
- if (!fs$1.existsSync(dir)) return [];
2302
- return fs$1.readdirSync(dir, { withFileTypes: true }).flatMap((entry) => {
2355
+ if (!fs$2.existsSync(dir)) return [];
2356
+ return fs$2.readdirSync(dir, { withFileTypes: true }).flatMap((entry) => {
2303
2357
  const entryPath = path$1.join(dir, entry.name);
2304
2358
  if (entry.isDirectory()) return walkFiles(entryPath, predicate);
2305
2359
  return entry.isFile() && predicate(entry.name) ? [entryPath] : [];
@@ -2315,17 +2369,17 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
2315
2369
  function patchSvelteKitStaticHtml() {
2316
2370
  const buildDir = path$1.resolve(viteConfig.root, "build");
2317
2371
  let initFile = emittedFileName ? path$1.resolve(buildDir, emittedFileName) : void 0;
2318
- if (!initFile || !fs$1.existsSync(initFile)) initFile = walkFiles(buildDir, (fileName) => fileName.endsWith(".js")).find((file) => {
2319
- const code = fs$1.readFileSync(file, "utf-8");
2372
+ if (!initFile || !fs$2.existsSync(initFile)) initFile = walkFiles(buildDir, (fileName) => fileName.endsWith(".js")).find((file) => {
2373
+ const code = fs$2.readFileSync(file, "utf-8");
2320
2374
  return code.includes("hostInitPromise") && code.includes("initHost");
2321
2375
  });
2322
2376
  if (!initFile) return false;
2323
2377
  let patched = false;
2324
2378
  for (const htmlFile of walkHtmlFiles(buildDir)) {
2325
- const html = fs$1.readFileSync(htmlFile, "utf-8");
2379
+ const html = fs$2.readFileSync(htmlFile, "utf-8");
2326
2380
  const rewritten = rewriteSvelteKitInlineStart(html, toRelativeImport(htmlFile, initFile));
2327
2381
  if (rewritten !== html) {
2328
- fs$1.writeFileSync(htmlFile, rewritten);
2382
+ fs$2.writeFileSync(htmlFile, rewritten);
2329
2383
  patched = true;
2330
2384
  }
2331
2385
  }
@@ -2402,8 +2456,8 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
2402
2456
  if (!entryFiles.includes(normalized)) entryFiles.push(normalized);
2403
2457
  }
2404
2458
  function addHtmlScriptEntries(htmlPath) {
2405
- if (!fs$1.existsSync(htmlPath)) return;
2406
- const htmlContent = fs$1.readFileSync(htmlPath, "utf-8");
2459
+ if (!fs$2.existsSync(htmlPath)) return;
2460
+ const htmlContent = fs$2.readFileSync(htmlPath, "utf-8");
2407
2461
  const scriptRegex = /<script\b(?=[^>]*\btype=["']module["'])(?=[^>]*\bsrc=["']([^"']+)["'])[^>]*>/gi;
2408
2462
  let match;
2409
2463
  while ((match = scriptRegex.exec(htmlContent)) !== null) {
@@ -2634,9 +2688,9 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
2634
2688
  const injection = `await import(${JSON.stringify(getEntryPath())}).then(({ initHost }) => initHost());\n `;
2635
2689
  return mapCodeToCodeWithSourcemap(code.replace("vueApp.mount(vueAppRootContainer);", `${injection}vueApp.mount(vueAppRootContainer);`));
2636
2690
  }
2637
- const isHydrationEntryFallback = inject === "entry" && entryFiles.length === 0 && (!htmlFilePath || !fs$1.existsSync(htmlFilePath)) && !clientInjected && !isFederationInternalVirtualId(id) && !id.includes("node_modules") && (id.startsWith("\0") || /\.(js|ts|mjs|vue|jsx|tsx)(\?|$)/.test(id)) && (/hydrateRoot|createRoot|ReactDOM\.render/.test(code) || /\.mount\s*\(\s*['"#]/.test(code) || /\.mount\s*\(/.test(code) && /createSSRApp|createApp/.test(code));
2691
+ const isHydrationEntryFallback = inject === "entry" && entryFiles.length === 0 && (!htmlFilePath || !fs$2.existsSync(htmlFilePath)) && !clientInjected && !isFederationInternalVirtualId(id) && !id.includes("node_modules") && (id.startsWith("\0") || /\.(js|ts|mjs|vue|jsx|tsx)(\?|$)/.test(id)) && (/hydrateRoot|createRoot|ReactDOM\.render/.test(code) || /\.mount\s*\(\s*['"#]/.test(code) || /\.mount\s*\(/.test(code) && /createSSRApp|createApp/.test(code));
2638
2692
  const isNuxtEntryAsyncModule = /(?:^|\/)nuxt\/dist\/app\/entry\.async\.js(?:\?|$)/.test(id) && code.includes("entry();");
2639
- const isNuxtClientEntryFallback = _command === "serve" && inject === "entry" && (!htmlFilePath || !fs$1.existsSync(htmlFilePath)) && !clientInjected && !hasEntryBootstrapParam(id) && !id.includes("node_modules/.vite") && isNuxtEntryAsyncModule && !entryFiles.some((file) => projectId === file);
2693
+ const isNuxtClientEntryFallback = _command === "serve" && inject === "entry" && (!htmlFilePath || !fs$2.existsSync(htmlFilePath)) && !clientInjected && !hasEntryBootstrapParam(id) && !id.includes("node_modules/.vite") && isNuxtEntryAsyncModule && !entryFiles.some((file) => projectId === file);
2640
2694
  if (!(_command === "serve" && isNuxtEntryAsyncModule) && (injectedTransformIds.has(projectId) || injectEntry() && entryFiles.some((file) => projectId === file) || _command === "serve" && inject === "html" && !isVinext && !clientInjected && !skipHtmlDevFallback && !id.startsWith("\0") && !id.includes("node_modules") && /\.(js|ts|mjs|vue|jsx|tsx)(\?|$)/.test(id) || isHydrationEntryFallback || isNuxtClientEntryFallback)) {
2641
2695
  clientInjected = true;
2642
2696
  injectedTransformIds.add(projectId);
@@ -3783,6 +3837,7 @@ const Manifest = () => {
3783
3837
  },
3784
3838
  async generateBundle(_options, bundle) {
3785
3839
  if (!mfManifestName) return;
3840
+ if (this.environment?.name === "ssr") return;
3786
3841
  let filesMap = {};
3787
3842
  const foundRemoteEntryFile = findRemoteEntryFile(mfOptions.filename, bundle);
3788
3843
  const expectedSsrRemoteEntryFile = getSsrRemoteEntryFileName(foundRemoteEntryFile || mfOptions.filename);
@@ -4145,25 +4200,6 @@ function resolveRemoteConsumer(ctx, hasMultiEnvironment) {
4145
4200
  return "server";
4146
4201
  }
4147
4202
  //#endregion
4148
- //#region src/utils/ssrCapabilities.ts
4149
- /**
4150
- * Single source of truth for SSR-related feature gates.
4151
- *
4152
- * - Vite 8+ dev: ModuleRunner + FetchableDevEnvironment for `/__mf_ssr__/` entries.
4153
- * - Any Vite major on build/preview: HTTP fetch + temp-file import via ssrEntryLoader.
4154
- */
4155
- function getSsrCapabilities(viteMajor, command, hasRemotes) {
4156
- if (!hasRemotes) return {
4157
- enableSsrInitBootstrap: false,
4158
- injectSsrEntryLoader: false
4159
- };
4160
- const supported = command === "build" || command === "serve" && viteMajor >= 8;
4161
- return {
4162
- enableSsrInitBootstrap: supported,
4163
- injectSsrEntryLoader: supported
4164
- };
4165
- }
4166
- //#endregion
4167
4203
  //#region src/plugins/pluginProxyRemotes.ts
4168
4204
  function isNodeModulesImporter(importer) {
4169
4205
  return importer?.includes("/node_modules/") || importer?.includes("\\node_modules\\");
@@ -4861,6 +4897,9 @@ function pluginSSRRemoteEntry(options) {
4861
4897
  const virtualExposesSSRId = getVirtualExposesSSRId(options);
4862
4898
  let isRolldown = false;
4863
4899
  let ssrOutputFilename = "";
4900
+ let ssrOutputFiles = /* @__PURE__ */ new Set();
4901
+ let ssrOutputDir = "";
4902
+ let clientOutputDir = "";
4864
4903
  const ssrOnlyExternals = [
4865
4904
  "@module-federation/runtime",
4866
4905
  "@module-federation/runtime-core",
@@ -4912,6 +4951,7 @@ function pluginSSRRemoteEntry(options) {
4912
4951
  }
4913
4952
  }, {
4914
4953
  name: "mf:ssr-remote-entry",
4954
+ sharedDuringBuild: true,
4915
4955
  configResolved(config) {
4916
4956
  viteConfig = config;
4917
4957
  isNuxtProject = isNuxtProjectRoot(config.root);
@@ -5041,11 +5081,62 @@ function pluginSSRRemoteEntry(options) {
5041
5081
  const exposesChunk = findNuxtExposesChunk(bundle);
5042
5082
  const ssrAsset = bundle[ssrOutputFilename];
5043
5083
  if (exposesChunk && ssrAsset?.type === "asset" && typeof ssrAsset.source === "string") ssrAsset.source = ssrAsset.source.replace(/import\("virtual:mf-exposes-ssr:[^"]+"\)/g, `import("./${exposesChunk}")`);
5084
+ if (this.environment?.name === "ssr") ssrOutputFiles = collectEntryOutputFiles(bundle, ssrOutputFilename);
5044
5085
  if (!isRolldown) return;
5045
5086
  const chunk = bundle[ssrOutputFilename];
5046
5087
  if (!chunk || chunk.type !== "chunk") return;
5088
+ },
5089
+ writeBundle(outputOptions) {
5090
+ const environmentName = this.environment?.name;
5091
+ if (environmentName === "ssr" && outputOptions.dir) ssrOutputDir = outputOptions.dir;
5092
+ else if (environmentName === "client" && outputOptions.dir) clientOutputDir = outputOptions.dir;
5093
+ publishSsrOutputFiles(ssrOutputDir, clientOutputDir || viteConfig?.environments?.client?.build?.outDir);
5047
5094
  }
5048
5095
  }];
5096
+ function publishSsrOutputFiles(ssrOutDir, clientOutDir) {
5097
+ if (ssrOutputFiles.size === 0 || !ssrOutDir || !clientOutDir) return;
5098
+ const root = viteConfig?.root ?? process.cwd();
5099
+ const ssrDir = path$1.resolve(root, ssrOutDir);
5100
+ const clientDir = path$1.resolve(root, clientOutDir);
5101
+ if (ssrDir === clientDir || !fs$1.existsSync(ssrDir)) return;
5102
+ fs$1.mkdirSync(clientDir, { recursive: true });
5103
+ for (const fileName of ssrOutputFiles) {
5104
+ const source = path$1.resolve(ssrDir, fileName);
5105
+ const destination = path$1.resolve(clientDir, fileName);
5106
+ if (!isWithinDirectory(source, ssrDir) || !isWithinDirectory(destination, clientDir)) continue;
5107
+ if (!fs$1.existsSync(source) || fs$1.existsSync(destination)) continue;
5108
+ fs$1.mkdirSync(path$1.dirname(destination), { recursive: true });
5109
+ fs$1.copyFileSync(source, destination);
5110
+ }
5111
+ }
5112
+ }
5113
+ const RELATIVE_IMPORT_RE = /(?:\bfrom|\bimport\s*(?:\(\s*)?|\bexport\s*\*\s*from)\s*["'`](\.\.?\/[^"'`]+)["'`]/g;
5114
+ function collectEntryOutputFiles(bundle, entryFileName) {
5115
+ const files = /* @__PURE__ */ new Set();
5116
+ const visit = (fileName) => {
5117
+ if (files.has(fileName)) return;
5118
+ const file = bundle[fileName];
5119
+ if (!file) return;
5120
+ files.add(fileName);
5121
+ const dependencies = new Set([
5122
+ ...file.imports || [],
5123
+ ...file.dynamicImports || [],
5124
+ ...file.implicitlyLoadedBefore || [],
5125
+ ...file.referencedFiles || []
5126
+ ]);
5127
+ const source = typeof file.code === "string" ? file.code : typeof file.source === "string" ? file.source : "";
5128
+ if (source) {
5129
+ const directory = path$1.posix.dirname(fileName);
5130
+ for (const match of source.matchAll(RELATIVE_IMPORT_RE)) dependencies.add(path$1.posix.normalize(path$1.posix.join(directory, match[1])));
5131
+ }
5132
+ for (const dependency of dependencies) visit(dependency);
5133
+ };
5134
+ visit(entryFileName);
5135
+ return files;
5136
+ }
5137
+ function isWithinDirectory(filePath, directory) {
5138
+ const relative = path$1.relative(directory, filePath);
5139
+ return relative !== "" && !relative.startsWith(`..${path$1.sep}`) && relative !== "..";
5049
5140
  }
5050
5141
  //#endregion
5051
5142
  //#region src/plugins/pluginVarRemoteEntry.ts
@@ -5367,14 +5458,32 @@ function createEarlyVirtualModulesPlugin(options) {
5367
5458
  optimizeDeps.rolldownOptions.plugins ??= [];
5368
5459
  optimizeDeps.rolldownOptions.plugins.push({
5369
5460
  name: "module-federation:optimize-shared-resolver",
5461
+ load(id) {
5462
+ if (id !== "module-federation:optimized-require-react") return;
5463
+ const optimizedLoadSharePath = toViteOptimizedDepVirtualId(getLoadShareModulePath("react", isRolldown));
5464
+ const source = JSON.stringify(optimizedLoadSharePath);
5465
+ return "import * as __mfShared from " + source + ";\nexport * from " + source + ";\nexport default __mfShared.default ?? __mfShared;";
5466
+ },
5370
5467
  resolveId(source, importer, options) {
5371
- if (options?.kind?.startsWith("require")) return;
5468
+ if (createViteEncodedIdPrefixRegExp("virtual:mf:").test(source)) return {
5469
+ id: source,
5470
+ external: true
5471
+ };
5372
5472
  if (isSharedResolverInternalImporter(importer)) return;
5373
- if (isCommonJsImporter(importer)) return;
5374
5473
  const key = findSharedKey(source, shared);
5375
5474
  if (!key) return;
5376
5475
  if (source.endsWith(".css")) return;
5377
5476
  const shareItem = shared[key];
5477
+ const isReactSingleton = source === "react" && key === "react" && shareItem.shareConfig?.singleton === true;
5478
+ const isReactRequire = options?.kind?.startsWith("require") && isReactSingleton;
5479
+ if (options?.kind?.startsWith("require") && !isReactSingleton) return;
5480
+ if (isCommonJsImporter(importer) && !isReactSingleton) return;
5481
+ if (isReactRequire) {
5482
+ writeLoadShareModule(source, shareItem, _command, isRolldown);
5483
+ if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(source, shareItem);
5484
+ addUsedShares(source);
5485
+ return { id: "module-federation:optimized-require-react" };
5486
+ }
5378
5487
  const loadSharePath = getLoadShareModulePath(source, isRolldown);
5379
5488
  writeLoadShareModule(source, shareItem, _command, isRolldown);
5380
5489
  if (shareItem.shareConfig?.import !== false) writePreBuildLibPath(source, shareItem);
@@ -5455,7 +5564,7 @@ export default __mfShared.default ?? __mfShared;`
5455
5564
  const optimizeDeps = config.optimizeDeps ??= {};
5456
5565
  optimizeDeps.include ??= [];
5457
5566
  optimizeDeps.exclude ??= [];
5458
- const shouldBypassOptimizeDep = isLitShare(key) || key === "react" && hasPackageDependency("react-redux", root);
5567
+ const shouldBypassOptimizeDep = isLitShare(key) || key === "react" && shareItem.shareConfig?.singleton === true;
5459
5568
  if (optimizeDeps.include.includes(key)) optimizeDeps.exclude = optimizeDeps.exclude.filter((dep) => dep !== key);
5460
5569
  else if (shouldBypassOptimizeDep) optimizeDeps.exclude.push(key);
5461
5570
  else optimizeDeps.include.push(key);
@@ -5510,7 +5619,7 @@ export default __mfShared.default ?? __mfShared;`
5510
5619
  const SSR_ONLY_PLUGINS = new Set(["@module-federation/vite/ssrEntryLoader"]);
5511
5620
  function loadPluginDts(options) {
5512
5621
  if (options.dts === false) return [];
5513
- return [import("./pluginDts-CrSsDUnT.js").then((n) => n.n).then(({ default: pluginDts }) => pluginDts(options))];
5622
+ return [import("./pluginDts-CTAHkt4C.js").then((n) => n.n).then(({ default: pluginDts }) => pluginDts(options))];
5514
5623
  }
5515
5624
  function federation(mfUserOptions) {
5516
5625
  if (isTestEnv()) return [];
@@ -193,10 +193,56 @@ function getPackageNameFromNodeModulePath(source) {
193
193
  if (parts[0].startsWith("@")) return parts[1] ? `${parts[0]}/${parts[1]}` : void 0;
194
194
  return parts[0];
195
195
  }
196
- function getSharedCacheKey(pkg, shareItem) {
197
- const prefix = `${shareItem.scope || "default"}:`;
198
- return shareItem.shareConfig.singleton || !shareItem.version ? `${prefix}${pkg}` : `${prefix}${pkg}@${shareItem.version}`;
196
+ function getSharedCacheKeyParts(input) {
197
+ const scope = (Array.isArray(input.scope) ? input.scope[0] : input.scope) || "default";
198
+ const id = input.singleton || !input.version ? input.pkg : `${input.pkg}@${input.version}`;
199
+ return {
200
+ scope,
201
+ id,
202
+ key: `${scope}:${id}`
203
+ };
204
+ }
205
+ function getSharedCacheDescriptor(pkg, shareItem) {
206
+ const parts = getSharedCacheKeyParts({
207
+ pkg,
208
+ singleton: shareItem.shareConfig.singleton,
209
+ version: shareItem.version,
210
+ scope: shareItem.scope
211
+ });
212
+ return {
213
+ canonical: parts.key,
214
+ ...parts.scope === "default" ? { aliases: [parts.id] } : {}
215
+ };
199
216
  }
217
+ const sharedCacheHelperCode = `const __mfGetSharedCacheDescriptor = (pkg, singleton, version, scope) => {
218
+ const normalizedScope = Array.isArray(scope) ? scope[0] : scope;
219
+ const scopeName = normalizedScope || "default";
220
+ const id = singleton || !version ? pkg : pkg + "@" + version;
221
+ const descriptor = { canonical: scopeName + ":" + id };
222
+ if (scopeName === "default") descriptor.aliases = [id];
223
+ return descriptor;
224
+ };
225
+ const __mfReadSharedCache = (cache, descriptor) => {
226
+ const value = cache[descriptor.canonical];
227
+ if (value !== undefined) return value;
228
+ const aliases = descriptor.aliases || [];
229
+ for (const alias of aliases) {
230
+ const aliasValue = cache[alias];
231
+ if (aliasValue !== undefined) {
232
+ cache[descriptor.canonical] = aliasValue;
233
+ return aliasValue;
234
+ }
235
+ }
236
+ return undefined;
237
+ };
238
+ const __mfWriteSharedCache = (cache, descriptor, value) => {
239
+ cache[descriptor.canonical] = value;
240
+ const aliases = descriptor.aliases || [];
241
+ for (const alias of aliases) {
242
+ if (cache[alias] === undefined) cache[alias] = value;
243
+ }
244
+ return value;
245
+ };`;
200
246
  function getInstalledPackageJson(pkg, opts) {
201
247
  const cwd = opts?.cwd || getPackageDetectionCwd();
202
248
  const packageName = opts?.packageName || getPackageName(pkg);
@@ -630,4 +676,4 @@ function pluginDts(options) {
630
676
  }];
631
677
  }
632
678
  //#endregion
633
- export { mfWarn as _, getIsRolldown as a, getPackageNameFromNodeModulePath as c, isNuxtProjectRoot as d, packageNameDecode as f, createModuleFederationError as g, setPackageDetectionCwd as h, getInstalledPackageJson as i, getSharedCacheKey as l, resolveImportPath as m, pluginDts_exports as n, getPackageDetectionCwd as o, packageNameEncode as p, getInstalledPackageEntry as r, getPackageName as s, DEFAULT_PUBLIC_TYPES_FOLDER as t, hasPackageDependency as u, normalizePathForImport as v, rebaseImport as y };
679
+ export { createModuleFederationError as _, getIsRolldown as a, rebaseImport as b, getPackageNameFromNodeModulePath as c, isNuxtProjectRoot as d, packageNameDecode as f, sharedCacheHelperCode as g, setPackageDetectionCwd as h, getInstalledPackageJson as i, getSharedCacheDescriptor as l, resolveImportPath as m, pluginDts_exports as n, getPackageDetectionCwd as o, packageNameEncode as p, getInstalledPackageEntry as r, getPackageName as s, DEFAULT_PUBLIC_TYPES_FOLDER as t, hasPackageDependency as u, mfWarn as v, normalizePathForImport as y };
@@ -8,7 +8,7 @@
8
8
  * `loadScriptNode` — if the hook returns a value, the runtime uses it directly.
9
9
  *
10
10
  * Strategy:
11
- * - In Node (typeof window === 'undefined'), fetch the remote's mf-manifest.json
11
+ * - In Node (detected through process.versions.node), fetch the remote's mf-manifest.json
12
12
  * to discover the ssrRemoteEntry URL and its type.
13
13
  * - ESM entry: use a dynamic `import()` — the SSR entry has no browser
14
14
  * globals and all shared packages are external.
@@ -8,7 +8,7 @@
8
8
  * `loadScriptNode` — if the hook returns a value, the runtime uses it directly.
9
9
  *
10
10
  * Strategy:
11
- * - In Node (typeof window === 'undefined'), fetch the remote's mf-manifest.json
11
+ * - In Node (detected through process.versions.node), fetch the remote's mf-manifest.json
12
12
  * to discover the ssrRemoteEntry URL and its type.
13
13
  * - ESM entry: use a dynamic `import()` — the SSR entry has no browser
14
14
  * globals and all shared packages are external.
@@ -34,6 +34,7 @@ async function nodeImport(id) {
34
34
  ));
35
35
  return importCache.get(id);
36
36
  }
37
+ const isNodeServer = () => typeof globalThis.process?.versions?.node === "string";
37
38
  const runnerCache = /* @__PURE__ */ new Map();
38
39
  /**
39
40
  * Import `vite/module-runner` dynamically. Returns null on Vite < 8 where the
@@ -362,7 +363,7 @@ function ssrEntryLoaderPlugin(options = {}) {
362
363
  return {
363
364
  name: "mf-vite:ssr-entry-loader",
364
365
  async loadEntry({ remoteInfo }) {
365
- if (typeof globalThis.window !== "undefined") return;
366
+ if (!isNodeServer()) return;
366
367
  const ssrEntry = await getSSREntry(remoteInfo.entry);
367
368
  if (!ssrEntry) return;
368
369
  const mod = await loadSSRRemoteEntry(ssrEntry, resolvedShared);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@module-federation/vite",
3
- "version": "1.16.11",
3
+ "version": "1.16.12",
4
4
  "description": "Vite plugin for Module Federation",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",