@module-federation/vite 1.23.1 → 1.23.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.
package/lib/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { _ as resolvePublicPath, a as matchesSharedSource, c as filterId, d as getNodeModulesSuffix, f as isAssetLikeImport, g as normalizeNodeModulePath, h as isViteOptimizableEntry, i as invalidateSharedKeyMatcher, l as getBasePath$1, m as isNuxtClientBase, n as getSharedRequest, p as isNodeModulePath, r as getSharedRuntimeKey, s as ensureTrailingSlash, t as findSharedKey, u as getCommonSharedSubpaths, v as stripQueryAndHash, y as stripViteFsPrefix } from "./sharedKeyMatcher-Od_nYxJA.js";
2
- import { a as CodeRewriter, c as normalizePathForImport, i as createCodePositionMap, l as rebaseImport, o as createSourceMap, r as mfWarn, t as createModuleFederationError, u as resolveHashPlaceholderFileName } from "./logger--uKHOVjR.js";
3
- import { C as isReactCoreShare, S as REACT_DOM_CLIENT_SHARE, _ as resolveModulePath, a as getIsRolldown, b as supportsCodeSplittingGroupDebugName, c as getPackageNameFromNodeModulePath, d as isNuxtProjectRoot, f as isPackageExportAvailable, g as resolveImportPath, h as packageNameEncode, i as getInstalledPackageJson, l as getSharedCacheDescriptor, m as packageNameDecode, n as getDependencyNames, o as getPackageDetectionCwd, p as isPackageInstalled, r as getInstalledPackageEntry, s as getPackageName, u as hasPackageDependency, v as setPackageDetectionCwd, x as REACT_CLIENT_INTERNALS_KEY, y as sharedCacheHelperCode } from "./dtsConstants-Bs4FukGL.js";
2
+ import { a as CodeRewriter, c as isAbsoluteUrl, d as resolveHashPlaceholderFileName, i as createCodePositionMap, l as normalizePathForImport, o as createSourceMap, r as mfWarn, t as createModuleFederationError, u as rebaseImport } from "./logger-DOwfTlw5.js";
3
+ import { C as isReactCoreShare, S as REACT_DOM_CLIENT_SHARE, _ as resolveModulePath, a as getIsRolldown, b as supportsCodeSplittingGroupDebugName, c as getPackageNameFromNodeModulePath, d as isNuxtProjectRoot, f as isPackageExportAvailable, g as resolveImportPath, h as packageNameEncode, i as getInstalledPackageJson, l as getSharedCacheDescriptor, m as packageNameDecode, n as getDependencyNames, o as getPackageDetectionCwd, p as isPackageInstalled, r as getInstalledPackageEntry, s as getPackageName, u as hasPackageDependency, v as setPackageDetectionCwd, x as REACT_CLIENT_INTERNALS_KEY, y as sharedCacheHelperCode } from "./dtsConstants-DSTzyKSG.js";
4
4
  import { createRequire } from "node:module";
5
5
  import * as fs$2 from "fs";
6
6
  import { existsSync, readFileSync, readdirSync, realpathSync, statSync, writeFileSync } from "fs";
@@ -15,6 +15,8 @@ import * as fs$1 from "node:fs";
15
15
  import { existsSync as existsSync$1, readFileSync as readFileSync$1 } from "node:fs";
16
16
  import { pathToFileURL as pathToFileURL$1 } from "node:url";
17
17
  import { isIPv6 } from "node:net";
18
+ import { inferAutoPublicPath } from "@module-federation/sdk";
19
+ import { readFile } from "node:fs/promises";
18
20
  //#region src/utils/regexEscape.ts
19
21
  const REGEXP_SPECIAL_CHARS_RE = /[.*+?^${}()|[\]\\]/g;
20
22
  /**
@@ -279,9 +281,17 @@ function isClientEnvironment(ctx) {
279
281
  * the legacy root `build.ssr` flag.
280
282
  */
281
283
  function isServerBuildContext(ctx, config) {
284
+ return isServerContext(ctx, Boolean(config?.build?.ssr));
285
+ }
286
+ /**
287
+ * Whether a hook runs for a server graph. Hooks without an environment context
288
+ * (Vite 5) use `legacySsr`, such as the root `build.ssr` flag or the load
289
+ * hook's `ssr` option.
290
+ */
291
+ function isServerContext(ctx, legacySsr) {
282
292
  const target = resolveEnvironmentConsumerTarget(ctx);
283
293
  if (target) return target === "server";
284
- return Boolean(config?.build?.ssr);
294
+ return legacySsr;
285
295
  }
286
296
  function resolveRemoteConsumer(ctx, hasMultiEnvironment) {
287
297
  if (!hasMultiEnvironment) return "unified";
@@ -723,13 +733,18 @@ function normalizeExperiments(experiments) {
723
733
  return {
724
734
  externalRuntime: experiments?.externalRuntime === true,
725
735
  provideExternalRuntime: experiments?.provideExternalRuntime === true,
726
- ssrMode: experiments?.ssrMode === "ISLAND" ? "ISLAND" : void 0
736
+ ssrMode: experiments?.ssrMode === "ISLAND" ? "ISLAND" : void 0,
737
+ hostProvidesAllShared: experiments?.hostProvidesAllShared === true
727
738
  };
728
739
  }
729
740
  function normalizeSsrEntryLoader(ssrEntryLoader) {
730
- const strategy = ssrEntryLoader?.strategy;
731
- if (strategy !== "temp-file" && strategy !== "vm") return void 0;
732
- return { strategy };
741
+ if (!ssrEntryLoader) return void 0;
742
+ const normalized = {};
743
+ if (ssrEntryLoader.strategy === "temp-file" || ssrEntryLoader.strategy === "vm") normalized.strategy = ssrEntryLoader.strategy;
744
+ if (Number.isFinite(ssrEntryLoader.maxAgeMs)) normalized.maxAgeMs = ssrEntryLoader.maxAgeMs;
745
+ if (Number.isFinite(ssrEntryLoader.fetchTimeoutMs)) normalized.fetchTimeoutMs = ssrEntryLoader.fetchTimeoutMs;
746
+ if (Number.isFinite(ssrEntryLoader.fetchMaxBytes)) normalized.fetchMaxBytes = ssrEntryLoader.fetchMaxBytes;
747
+ return Object.keys(normalized).length > 0 ? normalized : void 0;
733
748
  }
734
749
  let config;
735
750
  let explicitSharedKeys = /* @__PURE__ */ new Set();
@@ -3297,7 +3312,7 @@ function generateEagerWorkspaceSingletonExports(edges, namedExports, importSourc
3297
3312
  __mfApplyEagerShareExportsWhenReady(exportModule);
3298
3313
  export { __mf_default as default };${namedExportLine}${mutableExportLine}`;
3299
3314
  }
3300
- function generateLazyWorkspaceSingletonExports(edges, namedExports, importSource, cacheDescriptor, cacheOwner, treeShakingConsumer, serveLocalFallback = false, mutableExports = [], deferredEntryFallback = false) {
3315
+ function generateLazyWorkspaceSingletonExports(edges, namedExports, importSource, cacheDescriptor, cacheOwner, treeShakingConsumer, serveLocalFallback = false, mutableExports = [], deferredEntryFallback = false, ssrLocalFallback = true) {
3301
3316
  const copiedExports = namedExports.filter((name) => !mutableExports.includes(name));
3302
3317
  const namedExportVars = copiedExports.map((_name, i) => `__mf_${i}`);
3303
3318
  const declarations = namedExports.length > 0 ? ["let __mf_default;", ...namedExportVars.map((name) => `let ${name};`)].join("\n ") : "let __mf_default;";
@@ -3337,7 +3352,7 @@ function generateLazyWorkspaceSingletonExports(edges, namedExports, importSource
3337
3352
  __mfWriteSharedCache(__mfModuleCache.share, ${cacheDescriptor}, exportModule, ${cacheOwner});
3338
3353
  });
3339
3354
  })`;
3340
- const synchronousFallbackConditions = [...deferredEntryFallback ? [] : ["import.meta.env.SSR"], ...serveLocalFallback ? ["(import.meta.env.DEV && typeof __mfLocalShare !== 'undefined')"] : []];
3355
+ const synchronousFallbackConditions = [...ssrLocalFallback ? ["import.meta.env.SSR"] : [], ...serveLocalFallback ? ["(import.meta.env.DEV && typeof __mfLocalShare !== 'undefined')"] : []];
3341
3356
  const trackPendingLoad = `__mfTrackPendingShareLoad(${deferredEntryFallback ? deferredEntryLoad : deferredInitLoad});`;
3342
3357
  return `${declarations}
3343
3358
  const __mfApplyLazyShareExports = (mod) => {
@@ -3543,7 +3558,7 @@ function writeLoadShareModule(pkg, shareItem, command, _isRolldown, options, exp
3543
3558
  exportLine = generateLazyWorkspaceSingletonExports(edges, namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, command !== "build" && !servesRemoteSingletonFallback && (isWorkspaceSingleton || isWorkspacePackage), liveNamedExports);
3544
3559
  } else if (usesDeferredEntryInjectedSingletonFallback) {
3545
3560
  importLine = `${getRuntimeInitPromiseBootstrapCode(false, runtimeInitOwnerImportId)}\n ${importLine}`;
3546
- exportLine = generateLazyWorkspaceSingletonExports(edges, namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, false, liveNamedExports, true);
3561
+ exportLine = generateLazyWorkspaceSingletonExports(edges, namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, false, liveNamedExports, true, pkg !== REACT_DOM_CLIENT_SHARE);
3547
3562
  } else if (usesEagerWorkspaceFallback || usesEntryInjectedRemoteFallback) exportLine = generateEagerWorkspaceSingletonExports(edges, namedExports, lazyLocalFallbackSource, cacheDescriptor, cacheOwner, treeShakingConsumer, liveNamedExports);
3548
3563
  else if (usesDeferredSingletonFallback) {
3549
3564
  importLine = `${getRuntimeInitPromiseBootstrapCode(false, runtimeInitOwnerImportId)}\n ${importLine}`;
@@ -3738,16 +3753,22 @@ function generateLocalSharedImportMap(options) {
3738
3753
  const __mfGetCachedReactFamily = (keys, reactKeys, localVersion, requiredExport) => {
3739
3754
  const cache = globalThis.__mf_module_cache__?.share;
3740
3755
  const react = reactKeys.map((key) => cache?.[key]).find((value) => value !== undefined);
3741
- const reactVersion = react?.version ?? react?.default?.version;
3742
- const actual = String(reactVersion || '').split(/[^0-9]+/).map(Number);
3743
- const expected = String(localVersion || '').split(/[^0-9]+/).map(Number);
3744
- for (let index = 0; index < Math.max(actual.length, expected.length); index++) {
3745
- if ((actual[index] || 0) < (expected[index] || 0)) return undefined;
3746
- if ((actual[index] || 0) > (expected[index] || 0)) break;
3747
- }
3756
+ const isOlder = (version) => {
3757
+ const actual = String(version || '').split(/[^0-9]+/).map(Number);
3758
+ const expected = String(localVersion || '').split(/[^0-9]+/).map(Number);
3759
+ for (let index = 0; index < Math.max(actual.length, expected.length); index++) {
3760
+ if ((actual[index] || 0) < (expected[index] || 0)) return true;
3761
+ if ((actual[index] || 0) > (expected[index] || 0)) return false;
3762
+ }
3763
+ return false;
3764
+ };
3765
+ if (isOlder(react?.version ?? react?.default?.version)) return undefined;
3748
3766
  for (const key of keys) {
3749
3767
  const cached = cache?.[key];
3750
3768
  if (cached === undefined) continue;
3769
+ // A host seed from an older React family is not coherent with the newer cached react
3770
+ const cachedVersion = cached?.version ?? cached?.default?.version;
3771
+ if (cachedVersion !== undefined && isOlder(cachedVersion)) continue;
3751
3772
  if (!requiredExport || typeof cached?.[requiredExport] === 'function' || typeof cached?.default?.[requiredExport] === 'function') return cached;
3752
3773
  }
3753
3774
  return undefined;
@@ -5830,6 +5851,22 @@ function generateHostAutoInitCode(remoteEntryImport, _command = "build", options
5830
5851
  }));
5831
5852
  }
5832
5853
  ` : ""}
5854
+ // The seed called this container's get() directly, so the Runtime's
5855
+ // provider never learned it is in use and a remote could load its own
5856
+ // copy (#1396). Mark it once the host is bound to the local copy.
5857
+ for (const [pkg, share] of Object.entries(usedShared)) {
5858
+ if (!share.lib || share.treeShaking || share.shareConfig?.import === false) continue;
5859
+ const cacheDescriptor = __mfGetSharedCacheDescriptor(pkg, share.shareConfig?.singleton, share.version, share.scope);
5860
+ if (__mfReadSharedCacheOwner(__mfModuleCache.share, cacheDescriptor) !== ${cacheOwner}) continue;
5861
+ for (const scopeName of Array.isArray(share.scope) ? share.scope : [share.scope || "default"]) {
5862
+ const versions = runtime.shareScopeMap?.[scopeName]?.[pkg];
5863
+ const provider = versions?.[share.version];
5864
+ if (!provider || provider.get !== share.get || provider.lib) continue;
5865
+ if (Object.values(versions).some((other) => other !== provider && (other?.lib || other?.loaded))) continue;
5866
+ provider.lib = share.lib;
5867
+ provider.loaded = true;
5868
+ }
5869
+ }
5833
5870
  return runtime;
5834
5871
  })();
5835
5872
  }
@@ -6196,9 +6233,23 @@ function getLazyRemotePendingExport() {
6196
6233
  };`;
6197
6234
  }
6198
6235
  function getEagerRemotePendingExport() {
6199
- return `export const __mf_remote_pending =
6236
+ return `export let __mf_remote_pending =
6200
6237
  __mfRemotePending ??
6201
- __mfStartRemoteLoad().then(__mfAssignRemoteModule);`;
6238
+ __mfStartRemoteLoad().then(__mfAssignRemoteModule);
6239
+ __mf_remote_pending.then(undefined, () => {
6240
+ let attempt;
6241
+ const retry = {
6242
+ then(onFulfilled, onRejected) {
6243
+ attempt ||= __mfStartRemoteLoad().then(__mfAssignRemoteModule, (error) => {
6244
+ attempt = undefined;
6245
+ throw error;
6246
+ });
6247
+ return attempt.then(onFulfilled, onRejected);
6248
+ },
6249
+ };
6250
+ if (__mfRemotePending) __mfRemotePending = retry;
6251
+ __mf_remote_pending = retry;
6252
+ });`;
6202
6253
  }
6203
6254
  function getServerThenExport() {
6204
6255
  return `export function then(onFulfilled, onRejected) {
@@ -6212,7 +6263,15 @@ function getServerThenExport() {
6212
6263
  __moduleExports: exportModule,
6213
6264
  __mf_remote_pending: __mfRemotePending,
6214
6265
  };
6215
- })
6266
+ }, () => ({
6267
+ get default() {
6268
+ return __mfDefaultExport;
6269
+ },
6270
+ get __moduleExports() {
6271
+ return exportModule;
6272
+ },
6273
+ __mf_remote_pending: { then: (resolve, reject) => __mf_remote_pending.then(resolve, reject) },
6274
+ }))
6216
6275
  .then(onFulfilled, onRejected);
6217
6276
  }`;
6218
6277
  }
@@ -6456,6 +6515,7 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
6456
6515
  let emittedFileName;
6457
6516
  let skipTransformIds = /* @__PURE__ */ new Set();
6458
6517
  let injectedTransformIds = /* @__PURE__ */ new Set();
6518
+ const virtualEntryCode = /* @__PURE__ */ new Map();
6459
6519
  const ignoredHtmlScriptSources = /* @__PURE__ */ new Set();
6460
6520
  let bootstrapDir = "";
6461
6521
  function skipSvelteKitSsrBuild() {
@@ -6841,7 +6901,12 @@ for (const __mfRemoteEntryPrefetchUrl of __mfRemoteEntryPrefetchUrls) {
6841
6901
  }
6842
6902
  if (htmlFilePath) addHtmlScriptEntries(htmlFilePath);
6843
6903
  },
6844
- buildStart() {
6904
+ async buildStart() {
6905
+ if (inject === "entry" && waitsForInit && isClientEnvironment(this)) for (const entry of [...entryFiles]) {
6906
+ if (path$1.isAbsolute(entry)) continue;
6907
+ const resolved = await this.resolve(entry, void 0, { skipSelf: true }).catch(() => null);
6908
+ if (resolved && !resolved.external && (_command === "serve" || !resolved.id.startsWith("\0"))) addEntryFile(resolveProjectId(resolved.id));
6909
+ }
6845
6910
  if (_command === "serve") return;
6846
6911
  if (skipSvelteKitSsrBuild()) return;
6847
6912
  if (this.environment?.name === "ssr") return;
@@ -6947,11 +7012,18 @@ for (const __mfRemoteEntryPrefetchUrl of __mfRemoteEntryPrefetchUrls) {
6947
7012
  };
6948
7013
  setTimeout(retry, 0);
6949
7014
  },
7015
+ load(id) {
7016
+ return virtualEntryCode.get(id);
7017
+ },
6950
7018
  transform(code, id) {
6951
7019
  if (skipSvelteKitSsrBuild()) return;
6952
7020
  if (viteConfig?.command === "build" && !waitsForInit) return;
6953
7021
  if (isSvelteKitServerModule(id)) return;
6954
- if (hasEntryBootstrapParam(id)) return;
7022
+ if (hasEntryBootstrapParam(id)) return {
7023
+ code,
7024
+ map: null,
7025
+ moduleSideEffects: true
7026
+ };
6955
7027
  if (normalizeModuleId(id).endsWith(".html")) return;
6956
7028
  const projectId = resolveProjectId(id);
6957
7029
  if (skipTransformIds.has(projectId)) return;
@@ -6985,7 +7057,11 @@ for (const __mfRemoteEntryPrefetchUrl of __mfRemoteEntryPrefetchUrls) {
6985
7057
  clientInjected = true;
6986
7058
  injectedTransformIds.add(projectId);
6987
7059
  if (!waitsForInit) return mapCodeToCodeWithSourcemap(`import ${JSON.stringify(getEntryPath())};\n` + code);
6988
- const entrySrc = id.includes("?") ? `${id}&${ENTRY_BOOTSTRAP_QUERY.slice(1)}` : `${id}${ENTRY_BOOTSTRAP_QUERY}`;
7060
+ let entrySrc = id.includes("?") ? `${id}&${ENTRY_BOOTSTRAP_QUERY.slice(1)}` : `${id}${ENTRY_BOOTSTRAP_QUERY}`;
7061
+ if (entrySrc.startsWith("\0")) {
7062
+ virtualEntryCode.set(entrySrc, code);
7063
+ entrySrc = toViteEncodedId(entrySrc.slice(1));
7064
+ }
6989
7065
  return mapCodeToCodeWithSourcemap(getBootstrapSource(getEntryPath(), entrySrc, false, { skipRemotePreload: _command === "serve" && isNuxtEntryAsyncModule }));
6990
7066
  }
6991
7067
  }
@@ -8058,7 +8134,7 @@ function ${helperName}(names) {
8058
8134
  }
8059
8135
  //#endregion
8060
8136
  //#region package.json
8061
- var version$1 = "1.23.1";
8137
+ var version$1 = "1.23.3";
8062
8138
  //#endregion
8063
8139
  //#region src/virtualModules/virtualExposesSSR.ts
8064
8140
  /**
@@ -8160,6 +8236,8 @@ function generateRemoteEntrySSR(options) {
8160
8236
  const sharedSingletons = ${JSON.stringify(sharedSingletons)};
8161
8237
  const moduleCacheKey = Symbol.for(${JSON.stringify(MODULE_CACHE_SHARE_SCOPE_KEY)});
8162
8238
  let exposesMapPromise;
8239
+ // One identity per container, so a re-entrant init with the same initScope finds it.
8240
+ const initToken = { from: ${JSON.stringify(options.name)} };
8163
8241
 
8164
8242
  function createShareInitError(errors) {
8165
8243
  const details = errors.map(({ scopeName, pkg, error }) => {
@@ -8188,7 +8266,6 @@ function generateRemoteEntrySSR(options) {
8188
8266
  remotes: [],
8189
8267
  shared: {},
8190
8268
  });
8191
- const initToken = { from: ${JSON.stringify(options.name)} };
8192
8269
  if (initScope.indexOf(initToken) >= 0) return;
8193
8270
  initScope.push(initToken);
8194
8271
  const shareScopeNames = Array.isArray(${JSON.stringify(options.shareScope)})
@@ -8525,18 +8602,21 @@ const Manifest = (providedOptions) => {
8525
8602
  publicPath = mfOptions.publicPath === "auto" ? "auto" : resolvePublicPath(mfOptions, base, _originalConfigBase);
8526
8603
  },
8527
8604
  /**
8528
- * A standalone `vite build --ssr` may run with its own `filename`, e.g.
8529
- * `defineConfig(({ isSsrBuild }) => ...)`. The manifest written by the
8530
- * earlier client build then advertises an SSR entry derived from the
8531
- * browser filename, which is not the file this build emitted. Point the
8532
- * manifest and stats on disk at the emitted SSR entry.
8605
+ * The client manifest only advertises an SSR entry its own bundle
8606
+ * emitted. The SSR entry usually lands in a separate build: a standalone
8607
+ * `vite build --ssr` (possibly with its own `filename`, e.g.
8608
+ * `defineConfig(({ isSsrBuild }) => ...)`) or the `ssr` environment,
8609
+ * which the builder may run before or after `client`. Whichever build
8610
+ * finishes with the SSR entry on disk points the manifest and stats at it.
8533
8611
  */
8534
8612
  writeBundle(outputOptions) {
8535
8613
  if (!mfManifestName || _command !== "build" || isConsumerProject) return;
8536
- const environment = this.environment;
8537
- if (!(environment ? environment.name === "ssr" : Boolean(viteConfig?.build?.ssr))) return;
8538
8614
  const ssrEntryName = getSsrRemoteEntryFileName(mfOptions);
8539
- const outDirs = [...new Set([outputOptions.dir, viteConfig?.environments?.client?.build?.outDir].filter((dir) => typeof dir === "string").map((dir) => path$1.resolve(root, dir)))];
8615
+ const outDirs = [...new Set([
8616
+ outputOptions.dir,
8617
+ viteConfig?.environments?.client?.build?.outDir,
8618
+ viteConfig?.environments?.ssr?.build?.outDir
8619
+ ].filter((dir) => typeof dir === "string").map((dir) => path$1.resolve(root, dir)))];
8540
8620
  if (!outDirs.some((dir) => fs$1.existsSync(path$1.resolve(dir, ssrEntryName)))) return;
8541
8621
  for (const dir of outDirs) for (const fileName of [mfManifestName, mfManifestStatsName]) {
8542
8622
  if (!fileName) continue;
@@ -8545,8 +8625,12 @@ const Manifest = (providedOptions) => {
8545
8625
  try {
8546
8626
  const data = JSON.parse(fs$1.readFileSync(file, "utf8"));
8547
8627
  const entry = data?.metaData?.ssrRemoteEntry;
8548
- if (!entry || typeof entry !== "object" || entry.name === ssrEntryName) continue;
8549
- entry.name = ssrEntryName;
8628
+ if (!data?.metaData || entry?.name === ssrEntryName) continue;
8629
+ data.metaData.ssrRemoteEntry = Object.assign({
8630
+ name: ssrEntryName,
8631
+ path: "",
8632
+ type: "module"
8633
+ }, typeof entry === "object" ? entry : null, { name: ssrEntryName });
8550
8634
  fs$1.writeFileSync(file, JSON.stringify(data));
8551
8635
  } catch {}
8552
8636
  }
@@ -8564,7 +8648,7 @@ const Manifest = (providedOptions) => {
8564
8648
  const expectedSsrRemoteEntryFile = getSsrRemoteEntryFileName(mfOptions);
8565
8649
  const foundSsrRemoteEntryFile = Object.values(bundle).find((file) => file.fileName === expectedSsrRemoteEntryFile)?.fileName;
8566
8650
  if (foundRemoteEntryFile) remoteEntryFile = foundRemoteEntryFile;
8567
- ssrRemoteEntryFile = foundSsrRemoteEntryFile || (_command === "serve" ? getSsrRemoteEntryFileName(mfOptions, resolveHashPlaceholderFileName(mfOptions.filename)) : expectedSsrRemoteEntryFile);
8651
+ ssrRemoteEntryFile = foundSsrRemoteEntryFile || (_command === "serve" ? getSsrRemoteEntryFileName(mfOptions, resolveHashPlaceholderFileName(mfOptions.filename)) : void 0);
8568
8652
  const allCssAssets = mfOptions.bundleAllCSS && !disableAssetsAnalyze ? collectCssAssets(bundle) : /* @__PURE__ */ new Set();
8569
8653
  if (allCssAssets.size > 0) {
8570
8654
  const secondaryCss = /* @__PURE__ */ new Set();
@@ -8640,11 +8724,12 @@ const Manifest = (providedOptions) => {
8640
8724
  path: "",
8641
8725
  type: "module"
8642
8726
  };
8643
- const ssrRemoteEntry = {
8644
- name: ssrRemoteEntryFile || getSsrRemoteEntryFileName(mfOptions, _command === "serve" ? resolveHashPlaceholderFileName(filename) : filename),
8727
+ const resolvedSsrRemoteEntryFile = _command === "serve" ? ssrRemoteEntryFile || getSsrRemoteEntryFileName(mfOptions, resolveHashPlaceholderFileName(filename)) : ssrRemoteEntryFile;
8728
+ const ssrRemoteEntry = resolvedSsrRemoteEntryFile ? {
8729
+ name: resolvedSsrRemoteEntryFile,
8645
8730
  path: _command === "serve" ? "/__mf_ssr__/" : "",
8646
8731
  type: "module"
8647
- };
8732
+ } : void 0;
8648
8733
  const varRemoteEntry = varFilename ? {
8649
8734
  name: varFilename,
8650
8735
  path: "",
@@ -8769,6 +8854,106 @@ function getStatsFileName(manifestFileName) {
8769
8854
  return parsed.dir ? normalizePathForImport(path$1.join(parsed.dir, fileName)) : fileName;
8770
8855
  }
8771
8856
  //#endregion
8857
+ //#region src/utils/sharedSource.ts
8858
+ const pendingEntryLookups = /* @__PURE__ */ new Map();
8859
+ const getEntryLookupKey = (source, importer) => `${source}\0${importer}`;
8860
+ /** Whether a resolveId call is one of the shared source resolver's own entry lookups. */
8861
+ function isSharedEntryLookup(source, importer, options) {
8862
+ return options.custom?.__mfSharedEntryLookup === true || pendingEntryLookups.has(getEntryLookupKey(source, importer));
8863
+ }
8864
+ /**
8865
+ * Runs one of the plugin's own `this.resolve()` calls (a shared entry lookup, a
8866
+ * parse-barrier external probe), marked so `isSharedEntryLookup` recognizes it
8867
+ * and the share hooks neither proxy it nor register a used share for it.
8868
+ */
8869
+ async function resolveInternally(context, source, importer, options = {}) {
8870
+ const lookupKey = getEntryLookupKey(source, importer);
8871
+ pendingEntryLookups.set(lookupKey, (pendingEntryLookups.get(lookupKey) ?? 0) + 1);
8872
+ try {
8873
+ return await context.resolve(source, importer, {
8874
+ ...options,
8875
+ skipSelf: true,
8876
+ custom: {
8877
+ ...options.custom,
8878
+ __mfSharedEntryLookup: true
8879
+ }
8880
+ });
8881
+ } finally {
8882
+ const remaining = pendingEntryLookups.get(lookupKey) - 1;
8883
+ if (remaining) pendingEntryLookups.set(lookupKey, remaining);
8884
+ else pendingEntryLookups.delete(lookupKey);
8885
+ }
8886
+ }
8887
+ /** Identify shared entries through Vite, with a cache scoped to this federation instance. */
8888
+ function createSharedSourceResolver(shared, getResolutionConfig) {
8889
+ const caches = /* @__PURE__ */ new Map();
8890
+ async function matchEntry(source, suffix, resolveEntry) {
8891
+ const packageName = getPackageNameFromNodeModulePath(source);
8892
+ if (!packageName) return;
8893
+ const candidates = /* @__PURE__ */ new Set();
8894
+ if (findSharedKey(packageName, shared)) candidates.add(packageName);
8895
+ if (findSharedKey(suffix, shared)) candidates.add(suffix);
8896
+ for (const key of Object.keys(shared)) {
8897
+ const request = getSharedRequest(key, shared[key]);
8898
+ if (getPackageName(request) !== packageName) continue;
8899
+ if (!request.endsWith("/")) candidates.add(request);
8900
+ for (const subpath of getCommonSharedSubpaths(request)) if (findSharedKey(subpath, shared)) candidates.add(subpath);
8901
+ }
8902
+ if (candidates.size === 0) return;
8903
+ const resolvedSource = await resolveEntry(source);
8904
+ if (!resolvedSource) return;
8905
+ for (const candidate of candidates) {
8906
+ const entry = await resolveEntry(candidate);
8907
+ if (!entry) continue;
8908
+ const allowNodeModulesSuffixMatch = shared[findSharedKey(candidate, shared) ?? candidate]?.shareConfig?.allowNodeModulesSuffixMatch === true;
8909
+ if (normalizeNodeModulePath(entry) === normalizeNodeModulePath(resolvedSource) || allowNodeModulesSuffixMatch && getNodeModulesSuffix(entry) === suffix) return candidate;
8910
+ }
8911
+ }
8912
+ return {
8913
+ clear() {
8914
+ caches.clear();
8915
+ },
8916
+ async resolve(context, source, options = {}) {
8917
+ if (source.startsWith("\0") || source.includes("#")) return;
8918
+ const queryIndex = source.indexOf("?");
8919
+ const query = queryIndex === -1 ? "" : source.slice(queryIndex + 1);
8920
+ if (query && [...new URLSearchParams(query).keys()].some((key) => ![
8921
+ "v",
8922
+ "t",
8923
+ "import"
8924
+ ].includes(key))) return;
8925
+ if (findSharedKey(source, shared)) return source;
8926
+ const suffix = getNodeModulesSuffix(source);
8927
+ if (!suffix) return;
8928
+ const normalizedSource = stripViteFsPrefix(normalizeNodeModulePath(source));
8929
+ const environment = context.environment ?? !!options.ssr;
8930
+ const cacheable = !options.isEntry && !options.scan && (!options.kind || options.kind === "import-statement") && Object.keys(options.attributes ?? {}).length === 0 && Object.keys(options.custom ?? {}).length === 0;
8931
+ let cache = cacheable ? caches.get(environment) : void 0;
8932
+ if (cacheable && !cache) {
8933
+ cache = /* @__PURE__ */ new Map();
8934
+ caches.set(environment, cache);
8935
+ }
8936
+ if (cache?.has(normalizedSource)) return cache.get(normalizedSource);
8937
+ const { root, conditions } = getResolutionConfig(context, options);
8938
+ const result = await matchEntry(normalizedSource, suffix, async (request) => {
8939
+ if (!path$1.isAbsolute(request) && !isPackageExportAvailable(request, {
8940
+ cwd: root,
8941
+ conditions
8942
+ })) return void 0;
8943
+ const importer = path$1.join(root, "package.json");
8944
+ try {
8945
+ const resolved = await resolveInternally(context, request, importer, options);
8946
+ return resolved && !resolved.external ? resolved.id : void 0;
8947
+ } catch {
8948
+ return;
8949
+ }
8950
+ });
8951
+ cache?.set(normalizedSource, result);
8952
+ return result;
8953
+ }
8954
+ };
8955
+ }
8956
+ //#endregion
8772
8957
  //#region src/plugins/pluginModuleParseEnd.ts
8773
8958
  function createModuleParseController() {
8774
8959
  return {
@@ -8910,7 +9095,7 @@ function pluginModuleParseEnd_default(excludeFn, options, controller = createMod
8910
9095
  if (typeof this.resolve !== "function") return;
8911
9096
  if (controller.resolutionProbed.has(pendingId)) return;
8912
9097
  controller.resolutionProbed.add(pendingId);
8913
- this.resolve(pendingId, id, { skipSelf: true }).then((resolved) => {
9098
+ resolveInternally(this, pendingId, id).then((resolved) => {
8914
9099
  if (!resolved?.external) return;
8915
9100
  controller.externalSet.add(pendingId);
8916
9101
  controller.parseStartSet.delete(pendingId);
@@ -8919,7 +9104,7 @@ function pluginModuleParseEnd_default(excludeFn, options, controller = createMod
8919
9104
  };
8920
9105
  const addPendingIds = (ids) => {
8921
9106
  for (const pendingId of ids || []) {
8922
- if (!this.getModuleInfo(pendingId) || controller.externalSet.has(pendingId) || matchesExternal(configuredExternal, pendingId, id) || excludeFn(pendingId)) continue;
9107
+ if (controller.externalSet.has(pendingId) || matchesExternal(configuredExternal, pendingId, id) || excludeFn(pendingId)) continue;
8923
9108
  controller.parseStartSet.add(pendingId);
8924
9109
  if (!controller.parseEndSet.has(pendingId)) probeExternal(pendingId);
8925
9110
  }
@@ -9219,96 +9404,6 @@ function pluginProxyRemotes_default(options) {
9219
9404
  };
9220
9405
  }
9221
9406
  //#endregion
9222
- //#region src/utils/sharedSource.ts
9223
- const pendingEntryLookups = /* @__PURE__ */ new Map();
9224
- const getEntryLookupKey = (source, importer) => `${source}\0${importer}`;
9225
- /** Whether a resolveId call is one of the shared source resolver's own entry lookups. */
9226
- function isSharedEntryLookup(source, importer, options) {
9227
- return options.custom?.__mfSharedEntryLookup === true || pendingEntryLookups.has(getEntryLookupKey(source, importer));
9228
- }
9229
- /** Identify shared entries through Vite, with a cache scoped to this federation instance. */
9230
- function createSharedSourceResolver(shared, getResolutionConfig) {
9231
- const caches = /* @__PURE__ */ new Map();
9232
- async function matchEntry(source, suffix, resolveEntry) {
9233
- const packageName = getPackageNameFromNodeModulePath(source);
9234
- if (!packageName) return;
9235
- const candidates = /* @__PURE__ */ new Set();
9236
- if (findSharedKey(packageName, shared)) candidates.add(packageName);
9237
- if (findSharedKey(suffix, shared)) candidates.add(suffix);
9238
- for (const key of Object.keys(shared)) {
9239
- const request = getSharedRequest(key, shared[key]);
9240
- if (getPackageName(request) !== packageName) continue;
9241
- if (!request.endsWith("/")) candidates.add(request);
9242
- for (const subpath of getCommonSharedSubpaths(request)) if (findSharedKey(subpath, shared)) candidates.add(subpath);
9243
- }
9244
- if (candidates.size === 0) return;
9245
- const resolvedSource = await resolveEntry(source);
9246
- if (!resolvedSource) return;
9247
- for (const candidate of candidates) {
9248
- const entry = await resolveEntry(candidate);
9249
- if (!entry) continue;
9250
- const allowNodeModulesSuffixMatch = shared[findSharedKey(candidate, shared) ?? candidate]?.shareConfig?.allowNodeModulesSuffixMatch === true;
9251
- if (normalizeNodeModulePath(entry) === normalizeNodeModulePath(resolvedSource) || allowNodeModulesSuffixMatch && getNodeModulesSuffix(entry) === suffix) return candidate;
9252
- }
9253
- }
9254
- return {
9255
- clear() {
9256
- caches.clear();
9257
- },
9258
- async resolve(context, source, options = {}) {
9259
- if (source.startsWith("\0") || source.includes("#")) return;
9260
- const queryIndex = source.indexOf("?");
9261
- const query = queryIndex === -1 ? "" : source.slice(queryIndex + 1);
9262
- if (query && [...new URLSearchParams(query).keys()].some((key) => ![
9263
- "v",
9264
- "t",
9265
- "import"
9266
- ].includes(key))) return;
9267
- if (findSharedKey(source, shared)) return source;
9268
- const suffix = getNodeModulesSuffix(source);
9269
- if (!suffix) return;
9270
- const normalizedSource = stripViteFsPrefix(normalizeNodeModulePath(source));
9271
- const environment = context.environment ?? !!options.ssr;
9272
- const cacheable = !options.isEntry && !options.scan && (!options.kind || options.kind === "import-statement") && Object.keys(options.attributes ?? {}).length === 0 && Object.keys(options.custom ?? {}).length === 0;
9273
- let cache = cacheable ? caches.get(environment) : void 0;
9274
- if (cacheable && !cache) {
9275
- cache = /* @__PURE__ */ new Map();
9276
- caches.set(environment, cache);
9277
- }
9278
- if (cache?.has(normalizedSource)) return cache.get(normalizedSource);
9279
- const { root, conditions } = getResolutionConfig(context, options);
9280
- const result = await matchEntry(normalizedSource, suffix, async (request) => {
9281
- if (!path$1.isAbsolute(request) && !isPackageExportAvailable(request, {
9282
- cwd: root,
9283
- conditions
9284
- })) return void 0;
9285
- const importer = path$1.join(root, "package.json");
9286
- const lookupKey = getEntryLookupKey(request, importer);
9287
- pendingEntryLookups.set(lookupKey, (pendingEntryLookups.get(lookupKey) ?? 0) + 1);
9288
- try {
9289
- const resolved = await context.resolve(request, importer, {
9290
- ...options,
9291
- skipSelf: true,
9292
- custom: {
9293
- ...options.custom,
9294
- __mfSharedEntryLookup: true
9295
- }
9296
- });
9297
- return resolved && !resolved.external ? resolved.id : void 0;
9298
- } catch {
9299
- return;
9300
- } finally {
9301
- const remaining = pendingEntryLookups.get(lookupKey) - 1;
9302
- if (remaining) pendingEntryLookups.set(lookupKey, remaining);
9303
- else pendingEntryLookups.delete(lookupKey);
9304
- }
9305
- });
9306
- cache?.set(normalizedSource, result);
9307
- return result;
9308
- }
9309
- };
9310
- }
9311
- //#endregion
9312
9407
  //#region src/utils/PromiseStore.ts
9313
9408
  /**
9314
9409
  * example:
@@ -9522,8 +9617,9 @@ function isSharedPackageDependency(sharedKey, dependency) {
9522
9617
  function isConfiguredSharedPackage(pkg, shared) {
9523
9618
  return Object.keys(shared).some((key) => getPackageName(key) === pkg);
9524
9619
  }
9525
- function shouldKeepSharedImportLocal(source, importer, sharedKey, shared, importerPackage) {
9620
+ function shouldKeepSharedImportLocal(source, importer, sharedKey, shared, importerPackage, federationOptions) {
9526
9621
  if (!importer || shared[sharedKey]?.shareConfig.import === false) return false;
9622
+ if (hasRemotes(federationOptions)) return false;
9527
9623
  const prebuildImporter = importer.includes("__prebuild__") ? VirtualModule.findModule(PREBUILD_TAG, importer) : void 0;
9528
9624
  const fallbackPackage = prebuildImporter ? getPackageName(prebuildImporter.name) : importerPackage;
9529
9625
  if (!fallbackPackage || !isConfiguredSharedPackage(fallbackPackage, shared)) return false;
@@ -9941,7 +10037,7 @@ function proxySharedModule(options) {
9941
10037
  if (shouldSkipTaggedImporterProxy(key, "__loadShare__")) return;
9942
10038
  if (shouldSkipTaggedImporterProxy(key, "__prebuild__")) return;
9943
10039
  const shareSource = key === "vue" && sharedSource.startsWith("vue/dist/") ? key : sharedSource;
9944
- if (shouldKeepSharedImportLocal(sharedSource, importer, key, shared, importerPackage)) {
10040
+ if (shouldKeepSharedImportLocal(shareSource, importer, key, shared, importerPackage, federationOptions)) {
9945
10041
  const localSource = getPrebuildResolutionSource(shareSource, shared[key]);
9946
10042
  return tryResolveFromProjectRoot(localSource) || localSource;
9947
10043
  }
@@ -10441,6 +10537,8 @@ function pluginSSRRemoteEntry(options) {
10441
10537
  return exposeKeys.every((key) => code.includes(JSON.stringify(key)));
10442
10538
  })?.fileName;
10443
10539
  };
10540
+ const isNuxtLike = () => isNuxtProject || isNuxtClientBase(getBasePath$1(viteConfig?.base));
10541
+ const findEmittedExposesChunk = (bundle) => Object.values(bundle).find((file) => file.type === "chunk" && file.facadeModuleId === virtualExposesSSRId)?.fileName;
10444
10542
  return [{
10445
10543
  name: "mf:ssr-remote-entry:pre",
10446
10544
  enforce: "pre",
@@ -10483,7 +10581,7 @@ function pluginSSRRemoteEntry(options) {
10483
10581
  const base = "/__mf_ssr__";
10484
10582
  const basePath = getBasePath$1(viteConfig?.base);
10485
10583
  const ssrEntryFileName = getSsrRemoteEntryFileName(options);
10486
- if (isNuxtProject || isNuxtClientBase(basePath)) server.middlewares.use((req, _res, next) => {
10584
+ if (isNuxtLike()) server.middlewares.use((req, _res, next) => {
10487
10585
  if (req.url?.replace(/\?.*/, "") === `${basePath}/${ssrEntryFileName}`) req.url = `${basePath}/__mf_ssr__/${ssrEntryFileName}`;
10488
10586
  next();
10489
10587
  });
@@ -10570,16 +10668,26 @@ function pluginSSRRemoteEntry(options) {
10570
10668
  fileName: ssrOutputFilename,
10571
10669
  preserveSignature: "strict"
10572
10670
  });
10671
+ else if (Object.keys(options.exposes).length > 0 && !isNuxtLike()) this.emitFile({
10672
+ type: "chunk",
10673
+ id: virtualExposesSSRId,
10674
+ name: "ssrExposes",
10675
+ preserveSignature: "strict"
10676
+ });
10573
10677
  },
10574
10678
  generateBundle: {
10575
10679
  order: "post",
10576
10680
  handler(_options, bundle) {
10577
10681
  const isRolldown = getIsRolldown(this);
10578
10682
  const environment = this.environment;
10579
- const exposesChunk = findNuxtExposesChunk(bundle);
10683
+ const exposesChunk = findNuxtExposesChunk(bundle) ?? findEmittedExposesChunk(bundle);
10580
10684
  if (!isRolldown && isSsrRemoteEntryBuild(environment)) {
10581
10685
  let source = getSsrRemoteEntrySource();
10582
- if (exposesChunk) source = source.replace(/import\("virtual:mf-exposes-ssr:[^"]+"\)/g, `import("./${exposesChunk}")`);
10686
+ if (exposesChunk) {
10687
+ let exposesImport = path$1.posix.relative(path$1.posix.dirname(ssrOutputFilename), exposesChunk);
10688
+ if (!exposesImport.startsWith(".")) exposesImport = `./${exposesImport}`;
10689
+ source = source.replace(/import\("virtual:mf-exposes-ssr:[^"]+"\)/g, `import("${exposesImport}")`);
10690
+ }
10583
10691
  this.emitFile({
10584
10692
  type: "asset",
10585
10693
  fileName: ssrOutputFilename,
@@ -10900,6 +11008,360 @@ function isTestEnv() {
10900
11008
  return process.env.NODE_ENV === "test" || process.env.VITEST != null || process.env.JEST_WORKER_ID != null;
10901
11009
  }
10902
11010
  //#endregion
11011
+ //#region src/utils/hostProvidesAllShared.ts
11012
+ /** Virtual-module prefix of the host's per-share re-export entries. */
11013
+ const SHARE_MODULE_PREFIX = "\0mf-host-provided-share:";
11014
+ /** `./a/b` → `a/b`, `.` → `index`: the fixed entry name of an expose, without `.js`. */
11015
+ function exposeEntryName(exposeKey) {
11016
+ return exposeKey === "." ? "index" : exposeKey.replace(/^\.\//, "");
11017
+ }
11018
+ /** Bare specifier a host uses for an expose: `remote` for `.`, `remote/a/b` otherwise. */
11019
+ function remoteSpecifier(remoteName, exposeKey) {
11020
+ const entry = exposeEntryName(exposeKey);
11021
+ return entry === "index" ? remoteName : `${remoteName}/${entry}`;
11022
+ }
11023
+ /** `id` is a remote alias or a subpath of one. */
11024
+ function isRemoteSpecifier(id, remoteKeys) {
11025
+ return remoteKeys.some((key) => id === key || id.startsWith(`${key}/`));
11026
+ }
11027
+ /**
11028
+ * The shared key that owns `id`: an exact match, else the longest key `id` is a subpath
11029
+ * of (`lodash-es/debounce` → `lodash-es`). Used to spot an unshared subpath of a shared
11030
+ * package, which would bundle a private copy of that package into a remote.
11031
+ */
11032
+ function sharedKeyOwning(id, sharedKeys) {
11033
+ let owner;
11034
+ for (const key of sharedKeys) {
11035
+ if (id !== key && !id.startsWith(`${key}/`)) continue;
11036
+ if (!owner || key.length > owner.length) owner = key;
11037
+ }
11038
+ return owner;
11039
+ }
11040
+ /** Chunk name of the host's re-export entry for a shared key. */
11041
+ function shareChunkName(key) {
11042
+ return `shared/${key.replace(/^@/, "").replace(/[^\w-]+/g, "-")}`;
11043
+ }
11044
+ /** Reads a remote's `mf-manifest.json` from a URL or a path relative to `root`. */
11045
+ async function readHostProvidesAllSharedManifest(location, root) {
11046
+ let source;
11047
+ if (isAbsoluteUrl(location)) {
11048
+ const response = await fetch(location);
11049
+ if (!response.ok) throw new Error(`Failed to fetch ${location}: ${response.status} ${response.statusText}`);
11050
+ source = await response.text();
11051
+ } else source = await readFile(path$1.resolve(root, location), "utf8");
11052
+ const manifest = JSON.parse(source);
11053
+ if (!manifest.metaData || !Array.isArray(manifest.exposes)) throw new Error(`${location} is not a Module Federation manifest.`);
11054
+ if (manifest.metaData.remoteEntry) throw new Error(`${location} describes a Module Federation runtime remote (it has a remoteEntry). Build the remote with \`experiments: { hostProvidesAllShared: true }\`.`);
11055
+ return manifest;
11056
+ }
11057
+ /** URL prefix of a remote's files: `metaData.publicPath`, `auto` inferred from the manifest URL. */
11058
+ function remotePublicPath(manifest, location) {
11059
+ const publicPath = manifest.metaData.publicPath ?? "auto";
11060
+ if (publicPath !== "auto") return ensureTrailingSlash(publicPath);
11061
+ if (!isAbsoluteUrl(location)) throw new Error(`${location}: publicPath is "auto", which can only be inferred from a manifest URL. Reference the manifest by URL or set \`base\` / \`publicPath\` in the remote build.`);
11062
+ return ensureTrailingSlash(inferAutoPublicPath(location));
11063
+ }
11064
+ /** Import-map entries (`remote/Expose` → URL) for every expose of every remote. */
11065
+ async function collectRemoteImports(remotes, root) {
11066
+ const imports = {};
11067
+ for (const [alias, remote] of Object.entries(remotes)) {
11068
+ const manifest = await readHostProvidesAllSharedManifest(remote.entry, root);
11069
+ const publicPath = remotePublicPath(manifest, remote.entry);
11070
+ for (const expose of manifest.exposes) {
11071
+ const file = expose.assets.js.sync[0];
11072
+ if (!expose.path || !file) continue;
11073
+ imports[remoteSpecifier(alias, expose.path)] = isAbsoluteUrl(remote.entry) ? new URL(file, new URL(publicPath, remote.entry)).href : publicPath + file;
11074
+ }
11075
+ }
11076
+ return imports;
11077
+ }
11078
+ /** Top-level options that only the Module Federation runtime or `remoteEntry.js` pipeline reads. */
11079
+ const IGNORED_OPTIONS = [
11080
+ "filename",
11081
+ "ssrFilename",
11082
+ "varFilename",
11083
+ "library",
11084
+ "runtime",
11085
+ "shareScope",
11086
+ "shareStrategy",
11087
+ "runtimePlugins",
11088
+ "implementation",
11089
+ "getPublicPath",
11090
+ "ignoreOrigin",
11091
+ "virtualModuleDir",
11092
+ "hostInitInjectLocation",
11093
+ "bundleAllCSS",
11094
+ "treeShakingDir",
11095
+ "injectTreeShakingUsedExports",
11096
+ "treeShakingSharedPlugins",
11097
+ "treeShakingSharedExcludePlugins",
11098
+ "moduleParseTimeout",
11099
+ "moduleParseIdleTimeout",
11100
+ "target",
11101
+ "ssrExternals",
11102
+ "ssrEntryLoader",
11103
+ "disableRemote",
11104
+ "disableShared",
11105
+ "disableSnapshot"
11106
+ ];
11107
+ const IGNORED_EXPERIMENTS = [
11108
+ "externalRuntime",
11109
+ "provideExternalRuntime",
11110
+ "ssrMode"
11111
+ ];
11112
+ /** Per-share options: version negotiation, aliasing and fallbacks do not exist in this mode. */
11113
+ const IGNORED_SHARE_OPTIONS = [
11114
+ "eager",
11115
+ "requiredVersion",
11116
+ "strictVersion",
11117
+ "import",
11118
+ "request",
11119
+ "shareKey",
11120
+ "name",
11121
+ "version",
11122
+ "shareScope",
11123
+ "treeShaking",
11124
+ "allowNodeModulesSuffixMatch",
11125
+ "suppressMissingImportWarning"
11126
+ ];
11127
+ const isSet = (value) => value !== void 0 && value !== false && !(Array.isArray(value) && value.length === 0);
11128
+ /** A single warning naming every option the user set that import-map mode ignores. */
11129
+ function getIgnoredOptionWarning(options) {
11130
+ const shared = options.shared;
11131
+ const ignored = [
11132
+ ...IGNORED_OPTIONS.filter((key) => isSet(options[key])).map((key) => `\`${key}\``),
11133
+ ...IGNORED_EXPERIMENTS.filter((key) => isSet(options.experiments?.[key])).map((key) => `\`experiments.${key}\``),
11134
+ ...shared && !Array.isArray(shared) ? Object.entries(shared).flatMap(([key, config]) => typeof config === "object" && config !== null ? IGNORED_SHARE_OPTIONS.filter((option) => option === "import" ? config.import !== void 0 : isSet(config[option])).map((option) => `\`shared.${key}.${option}\``) : []) : []
11135
+ ];
11136
+ if (ignored.length === 0) return void 0;
11137
+ return `experiments.hostProvidesAllShared: ${ignored.join(", ")} ignored. The Module Federation runtime is not used and the host provides the only copy of every shared key.`;
11138
+ }
11139
+ //#endregion
11140
+ //#region src/plugins/pluginHostProvidesAllSharedHost.ts
11141
+ const ESM_SYNTAX_RE = /(^|[\s;])(export|import)[\s{*]/m;
11142
+ const DEFAULT_EXPORT_RE = /export\s+default\b|export\s*\{[^}]*\bas\s+default\b/;
11143
+ const IDENTIFIER_RE = /^[A-Za-z_$][\w$]*$/;
11144
+ /**
11145
+ * Export names of a CommonJS package, read by loading it in Node from the project root
11146
+ * (what the bundler's interop exposes as named imports). Empty when it cannot be loaded
11147
+ * in Node, e.g. because it touches `window`.
11148
+ */
11149
+ function cjsExportNames(key, root) {
11150
+ try {
11151
+ const exported = createRequire(path$1.join(root, "package.json"))(key);
11152
+ return Object.keys(exported ?? {}).filter((name) => name !== "default" && name !== "__esModule" && IDENTIFIER_RE.test(name));
11153
+ } catch {
11154
+ return [];
11155
+ }
11156
+ }
11157
+ /** Shape of a shared module, sniffed from its real package entry (never a pre-bundle). */
11158
+ function detectShareShape(key, entry, root) {
11159
+ const source = entry && fs$1.existsSync(entry) ? fs$1.readFileSync(entry, "utf8") : "";
11160
+ if (source !== "" && !ESM_SYNTAX_RE.test(source)) return {
11161
+ kind: "cjs",
11162
+ names: cjsExportNames(key, root)
11163
+ };
11164
+ return {
11165
+ kind: "esm",
11166
+ hasDefault: DEFAULT_EXPORT_RE.test(source)
11167
+ };
11168
+ }
11169
+ /**
11170
+ * Body of the re-export entry for one shared key. `export *` never forwards `default` and
11171
+ * forwards nothing named from CommonJS, so an ESM module adds `default` only when it has
11172
+ * one, and a CommonJS module re-exports each key explicitly (`react/jsx-runtime` → `jsx`,
11173
+ * `jsxs`) so remotes can `import { jsxs }`.
11174
+ */
11175
+ function shareModuleCode(key, shape) {
11176
+ const spec = JSON.stringify(key);
11177
+ if (shape.kind === "cjs") return `import __mf_cjs from ${spec};\nexport default __mf_cjs;\n${shape.names.length ? `export const { ${shape.names.join(", ")} } = __mf_cjs;\n` : ""}`;
11178
+ return `export * from ${spec};\n${shape.hasDefault ? `export { default } from ${spec};\n` : ""}`;
11179
+ }
11180
+ /** BUILD: shared key → URL of its emitted entry chunk. */
11181
+ function bundledShareImports(bundle, base) {
11182
+ const imports = {};
11183
+ for (const chunk of Object.values(bundle)) if (chunk.type === "chunk" && chunk.facadeModuleId?.startsWith("\0mf-host-provided-share:")) imports[chunk.facadeModuleId.slice(24)] = `${base}${chunk.fileName}`;
11184
+ return imports;
11185
+ }
11186
+ /**
11187
+ * DEV: shared key → dev-server URL of its virtual re-export module. Vite serves `\0` ids
11188
+ * at `/@id/__x00__<id>`; import analysis then rewrites the module's own `from '<key>'` to
11189
+ * the same pre-bundle URL the host's code gets, so host and remotes share one instance.
11190
+ */
11191
+ function devShareImports(sharedKeys, base) {
11192
+ const prefix = `${base}@id/__x00__${SHARE_MODULE_PREFIX.slice(1)}`;
11193
+ return Object.fromEntries(sharedKeys.map((key) => [key, `${prefix}${key}`]));
11194
+ }
11195
+ function importMapTag(imports) {
11196
+ return {
11197
+ tag: "script",
11198
+ attrs: { type: "importmap" },
11199
+ children: JSON.stringify({ imports }, null, 2),
11200
+ injectTo: "head-prepend"
11201
+ };
11202
+ }
11203
+ /**
11204
+ * Host side of `experiments.hostProvidesAllShared`. The host provides every shared key:
11205
+ *
11206
+ * 1. one re-export module per shared key, emitted in a build as a `preserveSignature:
11207
+ * 'strict'` entry chunk that the bundler dedupes with the host's own imports, and served
11208
+ * in dev as a virtual module; either way host and remotes land on one module instance;
11209
+ * 2. an import map in `index.html` pointing each shared key at that module and each remote
11210
+ * expose at the entry listed in the remote's `mf-manifest.json`.
11211
+ */
11212
+ function pluginHostProvidesAllSharedHost(options) {
11213
+ const sharedKeys = Object.keys(options.shared);
11214
+ const remoteKeys = Object.keys(options.remotes);
11215
+ let isBuild = true;
11216
+ let base = "/";
11217
+ let root = process.cwd();
11218
+ let remoteImports = {};
11219
+ let resolveEntry;
11220
+ return {
11221
+ name: "module-federation:host-provides-all-shared-host",
11222
+ enforce: "pre",
11223
+ configResolved(config) {
11224
+ isBuild = config.command === "build";
11225
+ base = ensureTrailingSlash(config.base);
11226
+ root = config.root;
11227
+ resolveEntry = isBuild ? void 0 : config.createResolver();
11228
+ },
11229
+ async buildStart() {
11230
+ remoteImports = await collectRemoteImports(options.remotes, root);
11231
+ if (!isBuild) return;
11232
+ for (const key of sharedKeys) this.emitFile({
11233
+ type: "chunk",
11234
+ id: `${SHARE_MODULE_PREFIX}${key}`,
11235
+ name: shareChunkName(key),
11236
+ preserveSignature: "strict"
11237
+ });
11238
+ },
11239
+ resolveId(id) {
11240
+ if (id.startsWith("\0mf-host-provided-share:")) return id;
11241
+ if (!isRemoteSpecifier(id, remoteKeys)) return null;
11242
+ return {
11243
+ id: isBuild ? id : remoteImports[id] ?? id,
11244
+ external: true
11245
+ };
11246
+ },
11247
+ async load(id) {
11248
+ if (!id.startsWith("\0mf-host-provided-share:")) return null;
11249
+ const key = id.slice(24);
11250
+ const entry = resolveEntry ? await resolveEntry(key) : (await this.resolve(key, void 0, { skipSelf: true }))?.id;
11251
+ return shareModuleCode(key, detectShareShape(key, entry && stripQueryAndHash(entry), root));
11252
+ },
11253
+ transformIndexHtml: {
11254
+ order: "post",
11255
+ handler(html, context) {
11256
+ const shares = context.bundle ? bundledShareImports(context.bundle, base) : devShareImports(sharedKeys, base);
11257
+ return {
11258
+ html,
11259
+ tags: [importMapTag({
11260
+ ...remoteImports,
11261
+ ...shares
11262
+ })]
11263
+ };
11264
+ }
11265
+ }
11266
+ };
11267
+ }
11268
+ //#endregion
11269
+ //#region src/plugins/pluginHostProvidesAllSharedRemote.ts
11270
+ /**
11271
+ * Remote side of `experiments.hostProvidesAllShared`. The remote ships only its own code:
11272
+ *
11273
+ * - one fixed-name, signature-preserving entry per expose (`./Button` → `Button.js`), so
11274
+ * the host can map `<remote>/Button` to a stable URL;
11275
+ * - every shared key, and every configured remote, stays an external bare import that the
11276
+ * host's import map resolves at runtime;
11277
+ * - a standard `mf-manifest.json` without `remoteEntry`, listing each expose's entry file.
11278
+ */
11279
+ function pluginHostProvidesAllSharedRemote(options) {
11280
+ const sharedKeys = Object.keys(options.shared);
11281
+ const remoteKeys = Object.keys(options.remotes);
11282
+ const isExternal = (id) => sharedKeys.includes(id) || isRemoteSpecifier(id, remoteKeys);
11283
+ const unsharedSubpaths = /* @__PURE__ */ new Map();
11284
+ let publicPath = "/";
11285
+ return {
11286
+ name: "module-federation:host-provides-all-shared-remote",
11287
+ enforce: "pre",
11288
+ apply: "build",
11289
+ config(config) {
11290
+ const root = path$1.resolve(config.root ?? process.cwd());
11291
+ return { build: { rollupOptions: {
11292
+ input: Object.fromEntries(Object.entries(options.exposes).map(([key, expose]) => [exposeEntryName(key), path$1.resolve(root, expose.import)])),
11293
+ external: isExternal,
11294
+ preserveEntrySignatures: "strict",
11295
+ output: {
11296
+ entryFileNames: "[name].js",
11297
+ chunkFileNames: "assets/[name]-[hash].js"
11298
+ }
11299
+ } } };
11300
+ },
11301
+ configResolved(config) {
11302
+ publicPath = options.publicPath ?? config.base;
11303
+ },
11304
+ buildStart() {
11305
+ unsharedSubpaths.clear();
11306
+ },
11307
+ resolveId(id, importer) {
11308
+ if (importer && !isExternal(id) && sharedKeyOwning(id, sharedKeys)) unsharedSubpaths.set(id, importer);
11309
+ return null;
11310
+ },
11311
+ buildEnd() {
11312
+ for (const [id, importer] of unsharedSubpaths) this.warn(`"${id}" (imported by ${importer}) is a subpath of a shared package but is not shared itself, so a private copy is bundled into this remote. Add it to \`shared\`.`);
11313
+ },
11314
+ generateBundle(_outputOptions, bundle) {
11315
+ const { name } = options;
11316
+ const exposes = [];
11317
+ for (const key of Object.keys(options.exposes)) {
11318
+ const entryName = exposeEntryName(key);
11319
+ const chunk = Object.values(bundle).find((item) => item.type === "chunk" && item.isEntry && item.name === entryName);
11320
+ if (!chunk) continue;
11321
+ exposes.push({
11322
+ id: `${name}:${entryName}`,
11323
+ name: entryName,
11324
+ path: key,
11325
+ assets: {
11326
+ js: {
11327
+ sync: [chunk.fileName],
11328
+ async: []
11329
+ },
11330
+ css: {
11331
+ sync: [],
11332
+ async: []
11333
+ }
11334
+ }
11335
+ });
11336
+ }
11337
+ const manifest = {
11338
+ id: name,
11339
+ name,
11340
+ metaData: {
11341
+ name,
11342
+ type: "app",
11343
+ buildInfo: {
11344
+ buildVersion: getBuildVersion(),
11345
+ buildName: name
11346
+ },
11347
+ globalName: name,
11348
+ pluginVersion: version$1,
11349
+ publicPath,
11350
+ types: resolveTypesMeta(options.dts)
11351
+ },
11352
+ shared: [],
11353
+ remotes: [],
11354
+ exposes
11355
+ };
11356
+ this.emitFile({
11357
+ type: "asset",
11358
+ fileName: typeof options.manifest === "object" && options.manifest.fileName || "mf-manifest.json",
11359
+ source: `${JSON.stringify(manifest, null, 2)}\n`
11360
+ });
11361
+ }
11362
+ };
11363
+ }
11364
+ //#endregion
10903
11365
  //#region src/utils/normalizeOptimizeDeps.ts
10904
11366
  var normalizeOptimizeDeps_default = {
10905
11367
  name: "normalizeOptimizeDeps",
@@ -11499,7 +11961,7 @@ export default __mfShared.default ?? __mfShared;`
11499
11961
  resolveImportPath(ssrEntryLoaderSpecifier);
11500
11962
  options.runtimePlugins.push([ssrEntryLoaderSpecifier, {
11501
11963
  resolvedShared,
11502
- ...options.ssrEntryLoader?.strategy ? { strategy: options.ssrEntryLoader.strategy } : {}
11964
+ ...options.ssrEntryLoader
11503
11965
  }]);
11504
11966
  } catch {}
11505
11967
  }
@@ -11514,9 +11976,21 @@ function applyBuildTimeRuntimeDefines(define, options, { target, isAstro, defaul
11514
11976
  });
11515
11977
  if (options.target && define.ENV_TARGET !== JSON.stringify(options.target)) mfWarn(`ENV_TARGET define (${define.ENV_TARGET}) differs from target option ("${options.target}"). ENV_TARGET will not be overridden.`);
11516
11978
  }
11979
+ /** Dynamic remote type hints are a runtime plugin; hostProvidesAllShared has no runtime. */
11980
+ function withoutDynamicRemoteTypeHints(options) {
11981
+ if (options.dev === false) return options;
11982
+ const dev = options.dev === true || options.dev === void 0 ? {} : options.dev;
11983
+ return {
11984
+ ...options,
11985
+ dev: {
11986
+ ...dev,
11987
+ disableDynamicRemoteTypeHints: true
11988
+ }
11989
+ };
11990
+ }
11517
11991
  function loadPluginDts(options) {
11518
11992
  if (options.dts === false) return [];
11519
- return [import("./pluginDts-DxgS2FEd.js").then(({ default: pluginDts }) => pluginDts(options))];
11993
+ return [import("./pluginDts-CVyHPAEq.js").then(({ default: pluginDts }) => pluginDts(options))];
11520
11994
  }
11521
11995
  const INJECT_EXTERNAL_RUNTIME_CORE_PLUGIN = "@module-federation/vite/injectExternalRuntimeCorePlugin";
11522
11996
  function isInjectExternalRuntimeCorePlugin(specifier) {
@@ -11545,11 +12019,16 @@ function applyExternalRuntimeExperiments(options) {
11545
12019
  function federation(mfUserOptions) {
11546
12020
  if (isTestEnv()) return [];
11547
12021
  const options = normalizeModuleFederationOptions(mfUserOptions);
12022
+ if (!options.name) throw createModuleFederationError("name is required");
12023
+ if (options.experiments.hostProvidesAllShared) {
12024
+ const ignored = getIgnoredOptionWarning(mfUserOptions);
12025
+ if (ignored) mfWarn(ignored);
12026
+ return [Object.keys(options.exposes).length > 0 ? pluginHostProvidesAllSharedRemote(options) : pluginHostProvidesAllSharedHost(options), ...loadPluginDts(withoutDynamicRemoteTypeHints(options))];
12027
+ }
11548
12028
  applyExternalRuntimeExperiments(options);
11549
12029
  const isVinext = hasPackageDependency("vinext");
11550
- const { name, shared, filename, hostInitInjectLocation } = options;
12030
+ const { shared, filename, hostInitInjectLocation } = options;
11551
12031
  const hasTreeShakingShared = Object.values(shared).some((share) => !!share.shareConfig.treeShaking);
11552
- if (!name) throw createModuleFederationError("name is required");
11553
12032
  const remoteEntryId = getRemoteEntryId(options);
11554
12033
  const virtualExposesId = getVirtualExposesId(options);
11555
12034
  const moduleParseController = createModuleParseController();
@@ -11567,6 +12046,7 @@ function federation(mfUserOptions) {
11567
12046
  let rootResolveConditions;
11568
12047
  let ssrResolveConditions;
11569
12048
  let ssrTarget = "node";
12049
+ let inheritedEnvTarget;
11570
12050
  const emittedRuntimeCapabilityWarnings = /* @__PURE__ */ new Set();
11571
12051
  const getLoadHookExportConditions = (context, loadOptions) => {
11572
12052
  const environment = context.environment;
@@ -11660,7 +12140,11 @@ function federation(mfUserOptions) {
11660
12140
  const virtualModule = VirtualModule.findById(id);
11661
12141
  if (!virtualModule) return;
11662
12142
  if (command === "build" && (id.includes("__loadShare__") || id.includes("__loadRemote__"))) return;
11663
- return virtualModule.code;
12143
+ const code = virtualModule.code;
12144
+ if (code && id.includes("__loadShare__")) {
12145
+ if (isServerContext(this, loadOptions?.ssr === true)) return prependWorkspaceSingletonSsrImport(code);
12146
+ }
12147
+ return code;
11664
12148
  }
11665
12149
  },
11666
12150
  ...options.experiments.externalRuntime ? [pluginExternalRuntimeCore()] : [],
@@ -11920,8 +12404,7 @@ function federation(mfUserOptions) {
11920
12404
  const virtualModule = VirtualModule.findById(id);
11921
12405
  if (!virtualModule?.code) return null;
11922
12406
  let code = virtualModule.code;
11923
- const consumerTarget = resolveEnvironmentConsumerTarget(this);
11924
- if (consumerTarget === "server" || !consumerTarget && isSsrBuild) {
12407
+ if (isServerContext(this, isSsrBuild)) {
11925
12408
  const withSsrImport = prependWorkspaceSingletonSsrImport(code);
11926
12409
  if (withSsrImport !== code) {
11927
12410
  const pkg = getCachedLoadSharePkg(id);
@@ -12041,11 +12524,13 @@ function federation(mfUserOptions) {
12041
12524
  const isAstro = hasPackageDependency("astro");
12042
12525
  const resolvedTarget = options.target ?? (config.build?.ssr ? "node" : "web");
12043
12526
  if (!config.define) config.define = {};
12527
+ const userSetEnvTarget = "ENV_TARGET" in config.define;
12044
12528
  applyBuildTimeRuntimeDefines(config.define, options, {
12045
12529
  target: resolvedTarget,
12046
12530
  isAstro,
12047
12531
  defaultDisableSnapshot: resolvedTarget === "node" ? true : void 0
12048
12532
  });
12533
+ inheritedEnvTarget = userSetEnvTarget ? void 0 : config.define.ENV_TARGET;
12049
12534
  for (const warning of getRuntimeCapabilityConfigurationWarnings(options)) {
12050
12535
  if (emittedRuntimeCapabilityWarnings.has(warning)) continue;
12051
12536
  emittedRuntimeCapabilityWarnings.add(warning);
@@ -12061,6 +12546,7 @@ function federation(mfUserOptions) {
12061
12546
  if (!isServerEnvironment(name, config)) return;
12062
12547
  const isAstro = hasPackageDependency("astro");
12063
12548
  config.define = { ...config.define ?? {} };
12549
+ if (inheritedEnvTarget !== void 0 && config.define.ENV_TARGET === inheritedEnvTarget) delete config.define.ENV_TARGET;
12064
12550
  applyBuildTimeRuntimeDefines(config.define, options, {
12065
12551
  target: options.target ?? "node",
12066
12552
  isAstro,