@module-federation/vite 1.16.9 → 1.16.11

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
@@ -797,6 +797,19 @@ globalThis[__mfCacheGlobalKey] ||= { share: {}, remote: {} };
797
797
  globalThis[__mfCacheGlobalKey].share ||= {};
798
798
  globalThis[__mfCacheGlobalKey].remote ||= {};
799
799
  const __mfModuleCache = globalThis[__mfCacheGlobalKey];
800
+ for (const __mfShareKey of Object.keys(__mfModuleCache.share)) {
801
+ if (__mfShareKey.startsWith("default:")) {
802
+ const __mfLegacyShareKey = __mfShareKey.slice("default:".length);
803
+ if (__mfModuleCache.share[__mfLegacyShareKey] === undefined) {
804
+ __mfModuleCache.share[__mfLegacyShareKey] = __mfModuleCache.share[__mfShareKey];
805
+ }
806
+ } else if (!__mfShareKey.includes(":")) {
807
+ const __mfDefaultShareKey = "default:" + __mfShareKey;
808
+ if (__mfModuleCache.share[__mfDefaultShareKey] === undefined) {
809
+ __mfModuleCache.share[__mfDefaultShareKey] = __mfModuleCache.share[__mfShareKey];
810
+ }
811
+ }
812
+ }
800
813
  `;
801
814
  }
802
815
  function getRuntimeInitPromiseBootstrapCode(enableSsrInit = false) {
@@ -1489,6 +1502,7 @@ function generateLocalSharedImportMap() {
1489
1502
  shareConfig: {
1490
1503
  singleton: ${shareItem.shareConfig.singleton},
1491
1504
  requiredVersion: ${JSON.stringify(shareItem.shareConfig.requiredVersion)},
1505
+ strictVersion: ${shareItem.shareConfig.strictVersion},
1492
1506
  ${shareItem.shareConfig.import === false ? "import: false," : ""}
1493
1507
  }
1494
1508
  }
@@ -1526,6 +1540,7 @@ function generateUsedSharedPreloadConfig() {
1526
1540
  shareConfig: {
1527
1541
  singleton: ${shareItem.shareConfig.singleton},
1528
1542
  requiredVersion: ${JSON.stringify(shareItem.shareConfig.requiredVersion)},
1543
+ strictVersion: ${shareItem.shareConfig.strictVersion},
1529
1544
  ${shareItem.shareConfig.import === false ? "import: false," : ""}
1530
1545
  }
1531
1546
  }`;
@@ -1610,6 +1625,40 @@ const normalizeRuntimeShareCode = `const __mfNormalizeRuntimeShare = (mod) => {
1610
1625
  }
1611
1626
  return current;
1612
1627
  };`;
1628
+ const sharedProviderSelectionHelperCode = `const __mfOriginalProviderKey = Symbol("mf.originalSharedProvider");
1629
+ const __mfResolveShareHook = { emit: (params) => params };
1630
+ const __mfCreateProviderSelectionVersions = (versions, strategy) => {
1631
+ if (strategy !== "version-first") return versions;
1632
+ const selectionVersions = {};
1633
+ for (const [version, provider] of Object.entries(versions)) {
1634
+ selectionVersions[version] = Object.assign({}, provider, {
1635
+ loaded: false,
1636
+ loading: undefined,
1637
+ lib: undefined,
1638
+ [__mfOriginalProviderKey]: provider
1639
+ });
1640
+ }
1641
+ return selectionVersions;
1642
+ };
1643
+ const __mfSelectSharedProvider = (versions, pkg, share, strategy) => {
1644
+ if (!versions || !share) return undefined;
1645
+ const scopes = Array.isArray(share.scope) ? share.scope : [share.scope || "default"];
1646
+ const selectionVersions = __mfCreateProviderSelectionVersions(versions, strategy);
1647
+ const shareScopeMap = {};
1648
+ for (const scope of scopes) {
1649
+ shareScopeMap[scope || "default"] = { [pkg]: selectionVersions };
1650
+ }
1651
+ const selected = runtimeShare.getRegisteredShare(
1652
+ shareScopeMap,
1653
+ pkg,
1654
+ { ...share, scope: scopes, strategy },
1655
+ __mfResolveShareHook
1656
+ )?.shared;
1657
+ return selected?.[__mfOriginalProviderKey] || selected;
1658
+ };`;
1659
+ function hasImportFalseShared$1(options) {
1660
+ return Object.values(options.shared ?? {}).some((share) => share?.shareConfig?.import === false);
1661
+ }
1613
1662
  function generateDirectSharedCacheSeedCode(command = "build") {
1614
1663
  return getOrderedUsedShares().map((pkg) => {
1615
1664
  const shareItem = getShareItemForPreload(pkg);
@@ -1647,6 +1696,7 @@ const SSR_ONLY_PLUGIN_SPECIFIERS = new Set(["@module-federation/vite/ssrEntryLoa
1647
1696
  const isSsrOnlyPlugin = (importStatement) => [...SSR_ONLY_PLUGIN_SPECIFIERS].some((s) => importStatement.includes(s));
1648
1697
  const getSsrOnlyPluginSpecifier = (importStatement) => [...SSR_ONLY_PLUGIN_SPECIFIERS].find((s) => importStatement.includes(s));
1649
1698
  function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(options), command = "build") {
1699
+ const needsSharedProviderSelectionHelper = hasImportFalseShared$1(options);
1650
1700
  const pluginImportNames = options.runtimePlugins.map((p, i) => {
1651
1701
  if (typeof p === "string") return [
1652
1702
  `$runtimePlugin_${i}`,
@@ -1669,6 +1719,7 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
1669
1719
  globalThis.__VUE_HMR_RUNTIME__ = { createRecord() {}, rerender() {}, reload() {} };
1670
1720
  }
1671
1721
  import {init as runtimeInit, loadRemote} from "@module-federation/runtime";
1722
+ ${needsSharedProviderSelectionHelper ? "import {share as runtimeShare} from \"@module-federation/runtime/helpers\";" : ""}
1672
1723
  ${pluginImportNames.filter((item) => !isSsrOnlyPlugin(item[1])).map((item) => item[1]).join("\n")}
1673
1724
  ${command === "build" ? getRuntimeInitResolveBootstrapCode() : getRuntimeInitBootstrapCode() + "\n const { initResolve } = globalThis[globalKey];"}
1674
1725
  ${getRuntimeModuleCacheBootstrapCode()}
@@ -1696,6 +1747,7 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
1696
1747
  }
1697
1748
  }
1698
1749
  }
1750
+ ${needsSharedProviderSelectionHelper ? sharedProviderSelectionHelperCode : ""}
1699
1751
 
1700
1752
  async function getLocalSharedImportMap() {
1701
1753
  if (!localSharedImportMapPromise) {
@@ -1725,7 +1777,14 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
1725
1777
  const scopeShare = scopes?.['${options.shareScope}'];
1726
1778
  if (!scopeShare) continue;
1727
1779
  for (const [pkg, versionMap] of Object.entries(scopeShare)) {
1728
- for (const [version, provider] of Object.entries(versionMap)) {
1780
+ const usedShare = usedShared?.[pkg];
1781
+ const selectedProvider = usedShare?.shareConfig?.import === false
1782
+ ? __mfSelectSharedProvider(versionMap, pkg, usedShare, '${options.shareStrategy}')
1783
+ : undefined;
1784
+ const providerEntries = usedShare?.shareConfig?.import === false
1785
+ ? Object.entries(versionMap).filter(([, provider]) => provider === selectedProvider)
1786
+ : Object.entries(versionMap);
1787
+ for (const [version, provider] of providerEntries) {
1729
1788
  if (!provider.lib) continue;
1730
1789
  const cacheKey = __mfGetSharedCacheKey(pkg, provider.shareConfig?.singleton, version, ${JSON.stringify(options.shareScope)});
1731
1790
  if (__mfModuleCache.share[cacheKey] !== undefined) continue;
@@ -1733,7 +1792,6 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
1733
1792
  const resolved = await Promise.resolve(mod);
1734
1793
  const normalized = __mfNormalizeRuntimeShare(resolved);
1735
1794
  __mfModuleCache.share[cacheKey] = normalized;
1736
- const usedShare = usedShared?.[pkg];
1737
1795
  if (provider.shareConfig?.singleton && usedShare) {
1738
1796
  const usedCacheKey = __mfGetSharedCacheKey(pkg, usedShare.shareConfig?.singleton, usedShare.version, usedShare.scope);
1739
1797
  if (__mfModuleCache.share[usedCacheKey] === undefined) {
@@ -1795,7 +1853,7 @@ function generateRemoteEntry(options, virtualExposesId = getVirtualExposesId(opt
1795
1853
  if (share.shareConfig?.import !== false || __mfModuleCache.share[cacheKey] !== undefined) continue;
1796
1854
  ${normalizeRuntimeShareCode}
1797
1855
  const versions = shared?.[pkg];
1798
- const provider = versions && versions[Object.keys(versions)[0]];
1856
+ const provider = __mfSelectSharedProvider(versions, pkg, share, '${options.shareStrategy}');
1799
1857
  if (!provider) continue;
1800
1858
  const factory = provider.lib || (provider.loading ? await provider.loading : await provider.get?.());
1801
1859
  const mod = typeof factory === "function" ? factory() : factory;
@@ -2163,6 +2221,12 @@ function getFirstHtmlEntryFile(entryFiles) {
2163
2221
  function stripQueryAndHash(file) {
2164
2222
  return file.split(/[?#]/)[0];
2165
2223
  }
2224
+ function resolveDevHashEntryFileName(fileName) {
2225
+ if (!fileName.includes("[hash")) return fileName;
2226
+ const normalized = fileName.replace(/(?:[._-]?\[hash(?::\d+)?\])/g, "");
2227
+ const baseName = path$1.basename(normalized);
2228
+ return path$1.extname(baseName) ? normalized : `${normalized}.js`;
2229
+ }
2166
2230
  function getBuildInput(config) {
2167
2231
  return config.build?.rollupOptions?.input ?? config.build?.rolldownOptions?.input;
2168
2232
  }
@@ -2386,6 +2450,8 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
2386
2450
  next();
2387
2451
  return;
2388
2452
  }
2453
+ const devFileName = resolveDevHashEntryFileName(fileName);
2454
+ if (devFileName !== fileName && req.url?.startsWith((viteConfig.base + devFileName).replace(/^\/?/, "/"))) req.url = req.url.replace(devFileName, fileName);
2389
2455
  if (req.url && req.url.startsWith((viteConfig.base + fileName).replace(/^\/?/, "/"))) req.url = devEntryPath;
2390
2456
  next();
2391
2457
  });
@@ -3291,7 +3357,13 @@ function rewriteSystemProxyConsumers(code, systemProxyInfo) {
3291
3357
  return nextCode;
3292
3358
  }
3293
3359
  function findRemoteEntryFile(filename, bundle) {
3294
- for (const [_, fileData] of Object.entries(bundle)) if (filename.replace(/[\[\]]/g, "_").replace(/\.[^/.]+$/, "") === fileData.name || fileData.name === "remoteEntry") return fileData.fileName;
3360
+ const strippedName = filename.replace(/[\[\]]/g, "_").replace(/\.[^/.]+$/, "");
3361
+ let fallback;
3362
+ for (const fileData of Object.values(bundle)) {
3363
+ if (fileData.fileName === filename) return fileData.fileName;
3364
+ if (fallback === void 0 && (strippedName === fileData.name || fileData.name === "remoteEntry")) fallback = fileData.fileName;
3365
+ }
3366
+ return fallback;
3295
3367
  }
3296
3368
  //#endregion
3297
3369
  //#region src/utils/cssModuleHelpers.ts
@@ -3641,13 +3713,13 @@ const Manifest = () => {
3641
3713
  },
3642
3714
  configureServer(server) {
3643
3715
  server.middlewares.use((req, res, next) => {
3644
- if (!mfManifestName) {
3716
+ const devRemoteEntryFile = resolveDevRemoteEntryFileName(filename);
3717
+ if (devRemoteEntryFile !== filename && Object.keys(mfOptions.exposes).length > 0 && req.url?.startsWith((viteConfig.base + devRemoteEntryFile).replace(/^\/?/, "/"))) {
3718
+ req.url = req.url.replace(devRemoteEntryFile, filename);
3645
3719
  next();
3646
3720
  return;
3647
3721
  }
3648
- const devRemoteEntryFile = resolveDevRemoteEntryFileName(filename);
3649
- if (devRemoteEntryFile !== filename && req.url?.startsWith((viteConfig.base + devRemoteEntryFile).replace(/^\/?/, "/"))) {
3650
- req.url = req.url.replace(devRemoteEntryFile, filename);
3722
+ if (!mfManifestName) {
3651
3723
  next();
3652
3724
  return;
3653
3725
  }
@@ -4424,7 +4496,6 @@ function proxySharedModule(options) {
4424
4496
  //#endregion
4425
4497
  //#region src/plugins/pluginRemoteNamedExports.ts
4426
4498
  const JS_EXTENSIONS_RE = /\.(?:[mc]?[jt]sx?|vue|svelte)(?:\?|$)/;
4427
- const REGEX_FALLBACK_EXTENSIONS_RE = /\.(?:[mc]?[jt]sx?)(?:\?|$)/;
4428
4499
  function isAstNode(value) {
4429
4500
  return !!value && typeof value === "object" && typeof value.type === "string";
4430
4501
  }
@@ -4621,10 +4692,12 @@ async function collectFromAST(ast, code, isRemoteImport) {
4621
4692
  }
4622
4693
  function collectFromRegex(code, isRemoteImport) {
4623
4694
  const result = [];
4695
+ const codePositions = createCodePositionMap(code);
4624
4696
  const importAttributes = String.raw`(?:\s+(?:with|assert)\s+\{[^;]*\})?`;
4625
4697
  const staticRe = new RegExp(String.raw`^\s*import\s+([\s\S]*?)\s+from\s+(['"])([^'"]+)\2${importAttributes}\s*;?`, "gm");
4626
4698
  for (const match of code.matchAll(staticRe)) {
4627
4699
  const [full, specifiersPartRaw, , source] = match;
4700
+ if (!codePositions[match.index]) continue;
4628
4701
  if (!isRemoteImport(source)) continue;
4629
4702
  const specifiersPart = specifiersPartRaw.trim();
4630
4703
  if (/^type\s/.test(specifiersPart)) continue;
@@ -4657,6 +4730,7 @@ function collectFromRegex(code, isRemoteImport) {
4657
4730
  const reexportRe = new RegExp(String.raw`^\s*export\s+\{([\s\S]*?)\}\s+from\s+(['"])([^'"]+)\2${importAttributes}\s*;?`, "gm");
4658
4731
  for (const match of code.matchAll(reexportRe)) {
4659
4732
  const [full, specifiersRaw, , source] = match;
4733
+ if (!codePositions[match.index]) continue;
4660
4734
  if (!isRemoteImport(source)) continue;
4661
4735
  const specifiers = parseNamedSpecifiers(specifiersRaw, "export");
4662
4736
  if (specifiers.length === 0) continue;
@@ -4671,6 +4745,7 @@ function collectFromRegex(code, isRemoteImport) {
4671
4745
  const exportAllRe = new RegExp(String.raw`^\s*export\s+\*\s+from\s+(['"])([^'"]+)\1${importAttributes}\s*;?`, "gm");
4672
4746
  for (const match of code.matchAll(exportAllRe)) {
4673
4747
  const [full, , source] = match;
4748
+ if (!codePositions[match.index]) continue;
4674
4749
  if (!isRemoteImport(source)) continue;
4675
4750
  result.push({
4676
4751
  kind: "export-all",
@@ -4681,6 +4756,7 @@ function collectFromRegex(code, isRemoteImport) {
4681
4756
  }
4682
4757
  for (const match of code.matchAll(/import\(\s*(?:\/\*[\s\S]*?\*\/\s*)?(['"])([^'"]+)\1\s*\)/g)) {
4683
4758
  const [full, , source] = match;
4759
+ if (!codePositions[match.index]) continue;
4684
4760
  if (!isRemoteImport(source)) continue;
4685
4761
  result.push({
4686
4762
  kind: "dynamic",
@@ -4691,6 +4767,50 @@ function collectFromRegex(code, isRemoteImport) {
4691
4767
  }
4692
4768
  return result.length > 0 ? result : void 0;
4693
4769
  }
4770
+ function createCodePositionMap(code) {
4771
+ const positions = Array(code.length).fill(true);
4772
+ function mask(start, end) {
4773
+ for (let i = start; i < end; i++) positions[i] = false;
4774
+ }
4775
+ for (let i = 0; i < code.length;) {
4776
+ const char = code[i];
4777
+ const next = code[i + 1];
4778
+ if (char === "/" && next === "/") {
4779
+ const start = i;
4780
+ i += 2;
4781
+ while (i < code.length && code[i] !== "\n" && code[i] !== "\r") i++;
4782
+ mask(start, i);
4783
+ continue;
4784
+ }
4785
+ if (char === "/" && next === "*") {
4786
+ const start = i;
4787
+ i += 2;
4788
+ while (i < code.length && !(code[i] === "*" && code[i + 1] === "/")) i++;
4789
+ i = Math.min(code.length, i + 2);
4790
+ mask(start, i);
4791
+ continue;
4792
+ }
4793
+ if (char === "\"" || char === "'" || char === "`") {
4794
+ const quote = char;
4795
+ const start = i++;
4796
+ while (i < code.length) {
4797
+ if (code[i] === "\\") {
4798
+ i += 2;
4799
+ continue;
4800
+ }
4801
+ if (code[i] === quote) {
4802
+ i++;
4803
+ break;
4804
+ }
4805
+ i++;
4806
+ }
4807
+ mask(start, i);
4808
+ continue;
4809
+ }
4810
+ i++;
4811
+ }
4812
+ return positions;
4813
+ }
4694
4814
  function pluginRemoteNamedExports(options) {
4695
4815
  const remoteNames = Object.keys(options.remotes);
4696
4816
  const isNodeModulesId = (id) => id.includes("/node_modules/") || id.includes("\\node_modules\\");
@@ -4717,7 +4837,6 @@ function pluginRemoteNamedExports(options) {
4717
4837
  if ((id.includes(".vue") || id.includes(".svelte")) && /^\s*</.test(code)) return;
4718
4838
  imports = collectFromRegex(code, matchesRemoteImport);
4719
4839
  }
4720
- if ((!imports || imports.length === 0) && REGEX_FALLBACK_EXTENSIONS_RE.test(id)) imports = collectFromRegex(code, matchesRemoteImport);
4721
4840
  if (!imports) return;
4722
4841
  return applyRewrites(code, imports, id);
4723
4842
  }
@@ -5122,18 +5241,21 @@ function normalizeVinextRscPreloadHints(code) {
5122
5241
  }
5123
5242
  function ignoreFederationGeneratedFiles(config, options) {
5124
5243
  config.server ??= {};
5125
- config.server.watch ??= {};
5244
+ const watch = config.server.watch;
5245
+ if (watch === false || watch === null) return;
5246
+ const watchOptions = watch === true || watch === void 0 ? {} : watch;
5247
+ config.server.watch = watchOptions;
5126
5248
  const federationIgnore = (file) => shouldIgnoreFile(file, options);
5127
- const ignored = config.server.watch.ignored;
5249
+ const ignored = watchOptions.ignored;
5128
5250
  if (!ignored) {
5129
- config.server.watch.ignored = federationIgnore;
5251
+ watchOptions.ignored = federationIgnore;
5130
5252
  return;
5131
5253
  }
5132
5254
  if (Array.isArray(ignored)) {
5133
5255
  ignored.push(federationIgnore);
5134
5256
  return;
5135
5257
  }
5136
- config.server.watch.ignored = [ignored, federationIgnore];
5258
+ watchOptions.ignored = [ignored, federationIgnore];
5137
5259
  }
5138
5260
  function isSharedResolverInternalImporter(importer) {
5139
5261
  return !!importer && (importer.includes("__loadShare__") || importer.includes("__prebuild__"));
@@ -5160,6 +5282,17 @@ function appendResolveAlias(config, alias) {
5160
5282
  replacement
5161
5283
  })), alias];
5162
5284
  }
5285
+ function hasImportFalseShared(options) {
5286
+ return Object.values(options.shared ?? {}).some((share) => share?.shareConfig?.import === false);
5287
+ }
5288
+ function getRuntimeHelpersImplementation(runtimeImplementation) {
5289
+ const indexEntryMatch = runtimeImplementation.match(/^(.*[\\/])index(\.[cm]?js)$/);
5290
+ if (indexEntryMatch) return `${indexEntryMatch[1]}helpers${indexEntryMatch[2]}`;
5291
+ const extension = path$1.extname(runtimeImplementation);
5292
+ if (extension) return path$1.join(path$1.dirname(runtimeImplementation), `helpers${extension}`);
5293
+ if (path$1.isAbsolute(runtimeImplementation) || runtimeImplementation.startsWith(".")) return path$1.join(runtimeImplementation, "helpers");
5294
+ return `${runtimeImplementation.replace(/\/$/, "")}/helpers`;
5295
+ }
5163
5296
  const UNSAFE_JS_SOURCE_CHAR_MAP = {
5164
5297
  "<": "\\u003C",
5165
5298
  ">": "\\u003E",
@@ -5687,8 +5820,13 @@ function federation(mfUserOptions) {
5687
5820
  config(config, { command: _command }) {
5688
5821
  const isRolldown = getIsRolldown(this);
5689
5822
  isSsrBuild = _command === "build" && config.build?.ssr === true;
5823
+ const needsSharedProviderSelectionHelper = hasImportFalseShared(options);
5824
+ if (needsSharedProviderSelectionHelper) appendResolveAlias(config, {
5825
+ find: /^@module-federation\/runtime\/helpers$/,
5826
+ replacement: getRuntimeHelpersImplementation(options.implementation)
5827
+ });
5690
5828
  appendResolveAlias(config, {
5691
- find: "@module-federation/runtime",
5829
+ find: /^@module-federation\/runtime$/,
5692
5830
  replacement: options.implementation
5693
5831
  });
5694
5832
  config.build ||= {};
@@ -5697,6 +5835,7 @@ function federation(mfUserOptions) {
5697
5835
  config.optimizeDeps ||= {};
5698
5836
  config.optimizeDeps.include ||= [];
5699
5837
  config.optimizeDeps.include.push("@module-federation/runtime");
5838
+ if (needsSharedProviderSelectionHelper) config.optimizeDeps.include.push("@module-federation/runtime/helpers");
5700
5839
  options.runtimePlugins.forEach((p) => {
5701
5840
  const pluginPath = typeof p === "string" ? p : p[0];
5702
5841
  if (SSR_ONLY_PLUGINS.has(pluginPath)) return;
@@ -89,6 +89,22 @@ const _crypto = () => nodeImport("crypto");
89
89
  const _module = () => nodeImport("module");
90
90
  const ssrEntryCache = /* @__PURE__ */ new Map();
91
91
  const manifestFetchCache = /* @__PURE__ */ new Map();
92
+ var SsrEntryHttpError = class extends Error {
93
+ constructor(url, status, statusText, bodyPreview) {
94
+ super(`Failed to fetch SSR module "${url}": ${status} ${statusText}` + (bodyPreview ? `\npreview: ${bodyPreview}` : ""));
95
+ this.url = url;
96
+ this.status = status;
97
+ this.statusText = statusText;
98
+ this.bodyPreview = bodyPreview;
99
+ this.name = "SsrEntryHttpError";
100
+ }
101
+ };
102
+ function getBodyPreview(body) {
103
+ return body.slice(0, 240).replace(/\s+/g, " ").trim();
104
+ }
105
+ function isSsrEntryHttpError(error) {
106
+ return error instanceof SsrEntryHttpError;
107
+ }
92
108
  async function fetchManifest(manifestUrl) {
93
109
  try {
94
110
  const res = await fetch(manifestUrl);
@@ -253,6 +269,9 @@ function transformSsrCode(code, base, sharedPkgMap) {
253
269
  code = code.replace(/\b([A-Za-z_$][\w$]*)\s*\(\s*\(\s*\)\s*=>\s*import\(([^)]*)\)\s*,\s*\[\]\s*\)/g, "import($2)");
254
270
  return code;
255
271
  }
272
+ function isVitePreloadHelperSpecifier(specifier) {
273
+ return specifier.includes("preload-helper");
274
+ }
256
275
  /**
257
276
  * Fetch an HTTP ESM module, transform it, write it to a temp .js file and
258
277
  * return the file path. Recursively does the same for HTTP transitive imports
@@ -262,12 +281,14 @@ async function fetchEsmToTempFile(url, tmpDir, visited, sharedPkgMap) {
262
281
  if (visited.has(url)) return visited.get(url);
263
282
  if (tempFileCache.has(url)) return tempFileCache.get(url);
264
283
  const promise = (async () => {
265
- let code = await (await fetch(url)).text();
284
+ const res = await fetch(url);
285
+ let code = await res.text();
286
+ if (!res.ok) throw new SsrEntryHttpError(url, res.status, res.statusText, getBodyPreview(code));
266
287
  const base = url.replace(/\/[^/]*$/, "/");
267
288
  const relImports = [];
268
289
  const relRegex = /(?:from|export\s*\*\s*from|import\s*(?:\(|\s))\s*["'`]([^"'`\s]+)["'`]/g;
269
290
  let m;
270
- while ((m = relRegex.exec(code)) !== null) if (m[1].startsWith("./") || m[1].startsWith("../")) relImports.push(new URL(m[1], base).href);
291
+ while ((m = relRegex.exec(code)) !== null) if ((m[1].startsWith("./") || m[1].startsWith("../")) && !isVitePreloadHelperSpecifier(m[1])) relImports.push(new URL(m[1], base).href);
271
292
  const subMap = /* @__PURE__ */ new Map();
272
293
  await Promise.all([...new Set(relImports)].filter((u) => u.startsWith("http://") || u.startsWith("https://")).map(async (u) => {
273
294
  const tmpPath = await fetchEsmToTempFile(u, tmpDir, visited, sharedPkgMap);
@@ -322,7 +343,8 @@ async function loadSSRRemoteEntry(ssrEntry, resolvedShared = {}) {
322
343
  const sharedPkgMap = new Map(Object.entries(resolvedShared));
323
344
  try {
324
345
  return await importTempModule(await fetchEsmToTempFile(url, cacheDir, /* @__PURE__ */ new Map(), sharedPkgMap));
325
- } catch {
346
+ } catch (error) {
347
+ if (isSsrEntryHttpError(error)) throw error;
326
348
  return null;
327
349
  }
328
350
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@module-federation/vite",
3
- "version": "1.16.9",
3
+ "version": "1.16.11",
4
4
  "description": "Vite plugin for Module Federation",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -70,9 +70,9 @@
70
70
  "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
71
71
  },
72
72
  "dependencies": {
73
- "@module-federation/dts-plugin": "2.5.1",
74
- "@module-federation/runtime": "2.5.1",
75
- "@module-federation/sdk": "2.5.1"
73
+ "@module-federation/dts-plugin": "2.6.0",
74
+ "@module-federation/runtime": "2.6.0",
75
+ "@module-federation/sdk": "2.6.0"
76
76
  },
77
77
  "devDependencies": {
78
78
  "@playwright/test": "1.58.2",
@@ -83,7 +83,7 @@
83
83
  "rollup": "4.47.1",
84
84
  "tsdown": "0.21.0",
85
85
  "typescript": "5.9.3",
86
- "vite": "8.0.10",
86
+ "vite": "8.1.0",
87
87
  "vitest": "4.0.18"
88
88
  }
89
89
  }