@module-federation/vite 1.13.5 → 1.13.6

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.mjs CHANGED
@@ -130,11 +130,13 @@ function removePathFromNpmPackage(packageString) {
130
130
  return match ? match[0] : packageString;
131
131
  }
132
132
  /**
133
- * Detect whether the current runtime is Vite 8+ (with rolldown internally) by checking
134
- * for `meta.rolldownVersion` on the plugin hook context.
133
+ * Detect whether the current runtime is Vite 8+ by checking for a Vite version flag
134
+ * on the plugin hook context, with Rolldown metadata kept as a compatibility fallback.
135
135
  */
136
136
  function getIsRolldown(ctx) {
137
- return !!ctx?.meta?.rolldownVersion;
137
+ const viteVersion = ctx?.meta?.viteVersion;
138
+ const viteMajor = Number(String(viteVersion ?? "").split(".")[0]);
139
+ return Number.isFinite(viteMajor) && viteMajor >= 8 || !!ctx?.meta?.rolldownVersion;
138
140
  }
139
141
  function hasPackageDependency(dependencyName, cwd = packageDetectionCwd || process.cwd()) {
140
142
  const cacheKey = getDependencyCacheKey(cwd, dependencyName);
@@ -783,13 +785,13 @@ function normalizeLibrary(library) {
783
785
  if (!library) return void 0;
784
786
  return library;
785
787
  }
786
- function normalizeManifest(manifest = false) {
788
+ function normalizeManifest(manifest) {
789
+ if (manifest === void 0) return;
787
790
  if (typeof manifest === "boolean") return manifest;
788
- return Object.assign({
789
- filePath: "",
790
- disableAssetsAnalyze: false,
791
- fileName: "mf-manifest.json"
792
- }, manifest);
791
+ return {
792
+ ...manifest,
793
+ fileName: manifest.fileName || "mf-manifest.json"
794
+ };
793
795
  }
794
796
  let config;
795
797
  function getNormalizeModuleFederationOptions() {
@@ -1208,6 +1210,9 @@ function escapeGeneratedStringLiteral(value) {
1208
1210
  }
1209
1211
  });
1210
1212
  }
1213
+ function isValidJsIdentifier(name) {
1214
+ return /^[$_\p{ID_Start}][$_\u200C\u200D\p{ID_Continue}]*$/u.test(name);
1215
+ }
1211
1216
  const localRequire = createRequire$1(import.meta.url);
1212
1217
  function resolvePackageEntryFromProjectRoot(pkg) {
1213
1218
  try {
@@ -1291,7 +1296,7 @@ function getEsmNamedExports(pkg) {
1291
1296
  const { initSync, parse } = localRequire("es-module-lexer");
1292
1297
  initSync();
1293
1298
  const [, exports] = parse(readFileSync(entryPath, "utf-8"), entryPath);
1294
- return exports.map((item) => item.n).filter((name) => !!name && name !== "default" && name !== "__esModule" && /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name));
1299
+ return exports.map((item) => item.n).filter((name) => !!name && name !== "default" && name !== "__esModule" && isValidJsIdentifier(name));
1295
1300
  } catch {
1296
1301
  return [];
1297
1302
  }
@@ -1299,7 +1304,7 @@ function getEsmNamedExports(pkg) {
1299
1304
  function getPackageNamedExports(pkg) {
1300
1305
  try {
1301
1306
  const mod = createRequire$1(new URL(`file://${path.join(getPackageDetectionCwd(), "package.json")}`))(pkg);
1302
- return Object.keys(mod).filter((k) => k !== "default" && k !== "__esModule" && /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(k));
1307
+ return Object.keys(mod).filter((k) => k !== "default" && k !== "__esModule" && isValidJsIdentifier(k));
1303
1308
  } catch {
1304
1309
  return getEsmNamedExports(pkg);
1305
1310
  }
@@ -1388,7 +1393,9 @@ function writeLoadShareModule(pkg, shareItem, command, isRolldown) {
1388
1393
  `, true);
1389
1394
  return;
1390
1395
  }
1391
- const useSsrProviderFallback = hasPackageDependency("vinext") && command === "build" && pkg === "react";
1396
+ const isVinext = hasPackageDependency("vinext");
1397
+ const isAstro = hasPackageDependency("astro");
1398
+ const useSsrProviderFallback = (isVinext || isAstro) && command === "build" && pkg === "react";
1392
1399
  const concreteSharedImportSource = getConcreteSharedImportSource(pkg, shareItem);
1393
1400
  const sharedImportSource = concreteSharedImportSource || getPreBuildLibImportId(pkg);
1394
1401
  const devImportSource = concreteSharedImportSource || pkg;
@@ -1443,6 +1450,8 @@ function writeLocalSharedImportMap() {
1443
1450
  }
1444
1451
  function generateLocalSharedImportMap() {
1445
1452
  const isVinext = hasPackageDependency("vinext");
1453
+ const isAstro = hasPackageDependency("astro");
1454
+ const useDirectReactImport = isVinext || isAstro;
1446
1455
  const options = getNormalizeModuleFederationOptions();
1447
1456
  return `
1448
1457
  import {loadShare} from "@module-federation/runtime";
@@ -1451,7 +1460,7 @@ function generateLocalSharedImportMap() {
1451
1460
  const shareItem = getNormalizeShareItem(pkg);
1452
1461
  return `
1453
1462
  ${JSON.stringify(pkg)}: async () => {
1454
- ${shareItem?.shareConfig.import === false ? `throw new Error(\`[Module Federation] Shared module '\${${JSON.stringify(pkg)}}' must be provided by host\`);` : isVinext && pkg === "react" ? `let pkg = await import("react");
1463
+ ${shareItem?.shareConfig.import === false ? `throw new Error(\`[Module Federation] Shared module '\${${JSON.stringify(pkg)}}' must be provided by host\`);` : useDirectReactImport && pkg === "react" ? `let pkg = await import("react");
1455
1464
  return pkg;` : `let pkg = await import(${JSON.stringify(getSharedImportSource(pkg, shareItem))});
1456
1465
  return pkg;`}
1457
1466
  }
@@ -1476,7 +1485,7 @@ function generateLocalSharedImportMap() {
1476
1485
  usedShared[${JSON.stringify(key)}].loaded = true
1477
1486
  const {${JSON.stringify(key)}: pkgDynamicImport} = importMap
1478
1487
  const res = await pkgDynamicImport()
1479
- const exportModule = ${JSON.stringify(isVinext)} && ${JSON.stringify(key)} === "react"
1488
+ const exportModule = ${JSON.stringify(useDirectReactImport)} && ${JSON.stringify(key)} === "react"
1480
1489
  ? (res?.default ?? res)
1481
1490
  : {...res}
1482
1491
  // All npm packages pre-built by vite will be converted to esm
@@ -1791,7 +1800,7 @@ const buildFileToShareKeyMap = async (shareKeys, resolveFn) => {
1791
1800
  * @returns The resolved public path
1792
1801
  */
1793
1802
  function resolvePublicPath(options, viteBase, originalBase) {
1794
- if (options.publicPath) return options.publicPath;
1803
+ if (options.publicPath && options.publicPath !== "auto") return options.publicPath;
1795
1804
  if (originalBase === "") return "auto";
1796
1805
  if (viteBase) return viteBase.replace(/\/?$/, "/");
1797
1806
  return "auto";
@@ -1801,9 +1810,17 @@ function resolvePublicPath(options, viteBase, originalBase) {
1801
1810
  const Manifest = () => {
1802
1811
  const mfOptions = getNormalizeModuleFederationOptions();
1803
1812
  const { name, filename, getPublicPath, manifest: manifestOptions, varFilename } = mfOptions;
1804
- let mfManifestName = "";
1805
- if (manifestOptions === true) mfManifestName = "mf-manifest.json";
1806
- if (typeof manifestOptions !== "boolean") mfManifestName = path$1.join(manifestOptions?.filePath || "", manifestOptions?.fileName || "");
1813
+ let mfManifestName = manifestOptions === true ? "mf-manifest.json" : typeof manifestOptions === "object" ? path$1.join(manifestOptions?.filePath || "", manifestOptions?.fileName || "mf-manifest.json") : void 0;
1814
+ let mfManifestStatsName = mfManifestName ? getStatsFileName(mfManifestName) : void 0;
1815
+ const isConsumerProject = Object.keys(mfOptions.exposes).length === 0;
1816
+ let disableAssetsAnalyze = false;
1817
+ const getDefaultDisableAssetsAnalyze = (command) => command === "serve" && isConsumerProject && (typeof manifestOptions !== "object" || !Object.prototype.hasOwnProperty.call(manifestOptions, "disableAssetsAnalyze"));
1818
+ const getConfiguredDisableAssetsAnalyze = (command) => {
1819
+ if (typeof manifestOptions === "object" && manifestOptions !== null) {
1820
+ if (Object.prototype.hasOwnProperty.call(manifestOptions, "disableAssetsAnalyze")) return manifestOptions.disableAssetsAnalyze === true;
1821
+ }
1822
+ return getDefaultDisableAssetsAnalyze(command);
1823
+ };
1807
1824
  let root;
1808
1825
  let remoteEntryFile;
1809
1826
  let publicPath;
@@ -1838,7 +1855,7 @@ const Manifest = () => {
1838
1855
  res.setHeader("Content-Type", "application/json");
1839
1856
  res.setHeader("Access-Control-Allow-Origin", "*");
1840
1857
  res.end(JSON.stringify({
1841
- ...generateMFManifest({}),
1858
+ ...generateMFManifest({}, disableAssetsAnalyze),
1842
1859
  id: name,
1843
1860
  name,
1844
1861
  metaData: {
@@ -1879,9 +1896,10 @@ const Manifest = () => {
1879
1896
  name: "module-federation-manifest",
1880
1897
  enforce: "post",
1881
1898
  config(config, { command }) {
1882
- if (!config.build) config.build = {};
1883
- if (!config.build.manifest) config.build.manifest = config.build.manifest || !!manifestOptions;
1884
1899
  _command = command;
1900
+ if (!config.build) config.build = {};
1901
+ if (!config.build.manifest) config.build.manifest = config.build.manifest || !!mfManifestName;
1902
+ disableAssetsAnalyze = getConfiguredDisableAssetsAnalyze(command);
1885
1903
  _originalConfigBase = config.base;
1886
1904
  },
1887
1905
  configResolved(config) {
@@ -1895,28 +1913,35 @@ const Manifest = () => {
1895
1913
  let filesMap = {};
1896
1914
  const foundRemoteEntryFile = findRemoteEntryFile(mfOptions.filename, bundle);
1897
1915
  if (foundRemoteEntryFile) remoteEntryFile = foundRemoteEntryFile;
1898
- const allCssAssets = mfOptions.bundleAllCSS ? collectCssAssets(bundle) : /* @__PURE__ */ new Set();
1899
- const exposesModules = Object.keys(mfOptions.exposes).map((item) => mfOptions.exposes[item].import);
1900
- processModuleAssets(bundle, filesMap, (modulePath) => {
1901
- const absoluteModulePath = path$1.resolve(root, modulePath);
1902
- return exposesModules.find((exposeModule) => {
1903
- const exposePath = path$1.resolve(root, exposeModule);
1904
- if (absoluteModulePath === exposePath) return true;
1905
- const getPathWithoutKnownExt = (filePath) => {
1906
- const ext = path$1.extname(filePath);
1907
- return JS_EXTENSIONS.includes(ext) ? path$1.join(path$1.dirname(filePath), path$1.basename(filePath, ext)) : filePath;
1908
- };
1909
- return getPathWithoutKnownExt(absoluteModulePath) === getPathWithoutKnownExt(exposePath);
1916
+ const allCssAssets = mfOptions.bundleAllCSS && !disableAssetsAnalyze ? collectCssAssets(bundle) : /* @__PURE__ */ new Set();
1917
+ if (!disableAssetsAnalyze) {
1918
+ const exposesModules = Object.keys(mfOptions.exposes).map((item) => mfOptions.exposes[item].import);
1919
+ processModuleAssets(bundle, filesMap, (modulePath) => {
1920
+ const absoluteModulePath = path$1.resolve(root, modulePath);
1921
+ return exposesModules.find((exposeModule) => {
1922
+ const exposePath = path$1.resolve(root, exposeModule);
1923
+ if (absoluteModulePath === exposePath) return true;
1924
+ const getPathWithoutKnownExt = (filePath) => {
1925
+ const ext = path$1.extname(filePath);
1926
+ return JS_EXTENSIONS.includes(ext) ? path$1.join(path$1.dirname(filePath), path$1.basename(filePath, ext)) : filePath;
1927
+ };
1928
+ return getPathWithoutKnownExt(absoluteModulePath) === getPathWithoutKnownExt(exposePath);
1929
+ });
1910
1930
  });
1911
- });
1912
- const fileToShareKey = await buildFileToShareKeyMap(getUsedShares(), this.resolve.bind(this));
1913
- processModuleAssets(bundle, filesMap, (modulePath) => fileToShareKey.get(modulePath));
1914
- if (mfOptions.bundleAllCSS) addCssAssetsToAllExports(filesMap, allCssAssets);
1915
- filesMap = deduplicateAssets(filesMap);
1931
+ const fileToShareKey = await buildFileToShareKeyMap(getUsedShares(), this.resolve.bind(this));
1932
+ processModuleAssets(bundle, filesMap, (modulePath) => fileToShareKey.get(modulePath));
1933
+ if (mfOptions.bundleAllCSS) addCssAssetsToAllExports(filesMap, allCssAssets);
1934
+ filesMap = deduplicateAssets(filesMap);
1935
+ }
1916
1936
  this.emitFile({
1917
1937
  type: "asset",
1918
1938
  fileName: mfManifestName,
1919
- source: JSON.stringify(generateMFManifest(filesMap))
1939
+ source: JSON.stringify(generateMFManifest(filesMap, disableAssetsAnalyze))
1940
+ });
1941
+ if (mfManifestStatsName) this.emitFile({
1942
+ type: "asset",
1943
+ fileName: mfManifestStatsName,
1944
+ source: JSON.stringify(generateMFStats(filesMap, bundle, disableAssetsAnalyze))
1920
1945
  });
1921
1946
  }
1922
1947
  }];
@@ -1925,7 +1950,7 @@ const Manifest = () => {
1925
1950
  * @param preloadMap - Map of module assets to include
1926
1951
  * @returns Complete manifest object
1927
1952
  */
1928
- function generateMFManifest(preloadMap) {
1953
+ function generateMFManifest(preloadMap, disableAssetsAnalyze = false) {
1929
1954
  const options = getNormalizeModuleFederationOptions();
1930
1955
  const { name, varFilename } = options;
1931
1956
  const remoteEntry = {
@@ -1951,6 +1976,7 @@ const Manifest = () => {
1951
1976
  id: `${name}:${shareKey}`,
1952
1977
  name: shareKey,
1953
1978
  version: shareItem.version,
1979
+ singleton: shareItem.shareConfig.singleton,
1954
1980
  requiredVersion: shareItem.shareConfig.requiredVersion,
1955
1981
  assets: {
1956
1982
  js: {
@@ -2004,12 +2030,33 @@ const Manifest = () => {
2004
2030
  pluginVersion: "0.2.5",
2005
2031
  ...!!getPublicPath ? { getPublicPath } : { publicPath }
2006
2032
  },
2007
- shared,
2033
+ ...disableAssetsAnalyze ? {} : { shared },
2008
2034
  remotes,
2009
- exposes
2035
+ ...disableAssetsAnalyze ? {} : { exposes }
2036
+ };
2037
+ }
2038
+ function generateMFStats(preloadMap, bundle, disableAssetsAnalyze = false) {
2039
+ const baseManifest = generateMFManifest(preloadMap, disableAssetsAnalyze);
2040
+ const bundleSummary = Object.entries(bundle).map(([fileName, chunkOrAsset]) => ({
2041
+ fileName,
2042
+ type: chunkOrAsset.type,
2043
+ isEntry: chunkOrAsset.isEntry || false,
2044
+ size: typeof chunkOrAsset.code === "string" ? chunkOrAsset.code.length : chunkOrAsset.source?.length || chunkOrAsset.source?.byteLength || void 0
2045
+ }));
2046
+ return {
2047
+ ...baseManifest,
2048
+ buildOutput: bundleSummary,
2049
+ ...disableAssetsAnalyze ? {} : { assetAnalysis: preloadMap }
2010
2050
  };
2011
2051
  }
2012
2052
  };
2053
+ function getStatsFileName(manifestFileName) {
2054
+ const parsed = path$1.parse(manifestFileName);
2055
+ const fileExt = parsed.ext || ".json";
2056
+ const baseName = parsed.ext ? parsed.name : parsed.base;
2057
+ const fileName = `${baseName === "mf-manifest" ? "mf" : baseName}-stats${fileExt}`;
2058
+ return parsed.dir ? path$1.join(parsed.dir, fileName) : fileName;
2059
+ }
2013
2060
  //#endregion
2014
2061
  //#region src/plugins/pluginModuleParseEnd.ts
2015
2062
  let _resolve, _parseTimeout;
@@ -2213,6 +2260,130 @@ function pluginProxyRemotes_default(options) {
2213
2260
  };
2214
2261
  }
2215
2262
  //#endregion
2263
+ //#region src/utils/PromiseStore.ts
2264
+ /**
2265
+ * example:
2266
+ * const store = new PromiseStore<number>();
2267
+ * store.get("example").then((result) => {
2268
+ * console.log("Result from example:", result); // 42
2269
+ * });
2270
+ * setTimeout(() => {
2271
+ * store.set("example", Promise.resolve(42));
2272
+ * }, 2000);
2273
+ */
2274
+ var PromiseStore = class {
2275
+ constructor() {
2276
+ this.promiseMap = /* @__PURE__ */ new Map();
2277
+ this.resolveMap = /* @__PURE__ */ new Map();
2278
+ }
2279
+ set(id, promise) {
2280
+ if (this.resolveMap.has(id)) {
2281
+ promise.then(this.resolveMap.get(id));
2282
+ this.resolveMap.delete(id);
2283
+ }
2284
+ this.promiseMap.set(id, promise);
2285
+ }
2286
+ get(id) {
2287
+ if (this.promiseMap.has(id)) return this.promiseMap.get(id);
2288
+ const pendingPromise = new Promise((resolve) => {
2289
+ this.resolveMap.set(id, resolve);
2290
+ });
2291
+ this.promiseMap.set(id, pendingPromise);
2292
+ return pendingPromise;
2293
+ }
2294
+ };
2295
+ //#endregion
2296
+ //#region src/plugins/pluginProxySharedModule_preBuild.ts
2297
+ function getPrebuildResolutionSource(pkgName, shareItem) {
2298
+ return getConcreteSharedImportSource(pkgName, shareItem) || pkgName;
2299
+ }
2300
+ function proxySharedModule(options) {
2301
+ const { shared = {} } = options;
2302
+ let _config;
2303
+ let _command = "serve";
2304
+ let useDirectReactImport = false;
2305
+ const savePrebuild = new PromiseStore();
2306
+ return [{
2307
+ name: "generateLocalSharedImportMap",
2308
+ enforce: "post",
2309
+ load(id) {
2310
+ if (id.includes(getLocalSharedImportMapPath())) return parsePromise.then((_) => generateLocalSharedImportMap());
2311
+ },
2312
+ transform(_, id) {
2313
+ if (id.includes(getLocalSharedImportMapPath())) return mapCodeToCodeWithSourcemap(parsePromise.then((_) => generateLocalSharedImportMap()));
2314
+ }
2315
+ }, {
2316
+ name: "proxyPreBuildShared",
2317
+ enforce: "post",
2318
+ config(config, { command }) {
2319
+ setPackageDetectionCwd(config.root || process.cwd());
2320
+ const isVinext = hasPackageDependency("vinext");
2321
+ const isAstro = hasPackageDependency("astro");
2322
+ const isRolldown = getIsRolldown(this);
2323
+ _command = command;
2324
+ useDirectReactImport = isVinext || isAstro;
2325
+ config.resolve.alias.push(...Object.keys(shared).filter((key) => !(useDirectReactImport && key === "react")).map((key) => {
2326
+ const keyBase = key.endsWith("/") ? key.slice(0, -1) : key;
2327
+ const escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2328
+ const escapedKeyBase = escapeRegex(keyBase);
2329
+ const pattern = key.endsWith("/") ? `^(${escapedKeyBase}(?:\\/.*)?)$` : `^(${escapedKeyBase})$`;
2330
+ return {
2331
+ find: new RegExp(pattern),
2332
+ replacement: "$1",
2333
+ customResolver(source, importer) {
2334
+ if (/\.css$/.test(source)) return;
2335
+ if (useDirectReactImport && source === "react") return;
2336
+ if (importer && importer.includes("localSharedImportMap")) return;
2337
+ if (key.endsWith("/") && source !== key.slice(0, -1)) return;
2338
+ const loadSharePath = getLoadShareModulePath(source, isRolldown, command);
2339
+ writeLoadShareModule(source, shared[key], command, isRolldown);
2340
+ if (shared[key].shareConfig.import !== false) writePreBuildLibPath(source, shared[key]);
2341
+ addUsedShares(source);
2342
+ writeLocalSharedImportMap();
2343
+ return this.resolve(loadSharePath, importer);
2344
+ }
2345
+ };
2346
+ }));
2347
+ config.resolve.alias.push(...Object.keys(shared).filter((key) => !(useDirectReactImport && key === "react")).map((key) => {
2348
+ return command === "build" ? {
2349
+ find: new RegExp(`(.*${PREBUILD_TAG}.*)`),
2350
+ replacement: function($1) {
2351
+ const pkgName = assertModuleFound(PREBUILD_TAG, $1).name;
2352
+ return getPrebuildResolutionSource(pkgName, getPreBuildShareItem(pkgName));
2353
+ }
2354
+ } : {
2355
+ find: new RegExp(`(.*${PREBUILD_TAG}.*)`),
2356
+ replacement: "$1",
2357
+ async customResolver(source, importer) {
2358
+ const pkgName = assertModuleFound(PREBUILD_TAG, source).name;
2359
+ const importSource = getPrebuildResolutionSource(pkgName, getPreBuildShareItem(pkgName));
2360
+ const resolved = await this.resolve(importSource, importer);
2361
+ if (!resolved?.id) return;
2362
+ const result = resolved.id;
2363
+ if (_config && !result.includes(_config.cacheDir)) savePrebuild.set(pkgName, Promise.resolve(result));
2364
+ return await this.resolve(await savePrebuild.get(pkgName), importer);
2365
+ }
2366
+ };
2367
+ }));
2368
+ },
2369
+ configResolved(config) {
2370
+ _config = config;
2371
+ const isRolldown = getIsRolldown(this);
2372
+ Object.keys(shared).forEach((key) => {
2373
+ if (key.endsWith("/")) return;
2374
+ if (useDirectReactImport && key === "react") {
2375
+ addUsedShares(key);
2376
+ return;
2377
+ }
2378
+ writeLoadShareModule(key, shared[key], _command, isRolldown);
2379
+ if (shared[key].shareConfig.import !== false) writePreBuildLibPath(key, shared[key]);
2380
+ addUsedShares(key);
2381
+ });
2382
+ writeLocalSharedImportMap();
2383
+ }
2384
+ }];
2385
+ }
2386
+ //#endregion
2216
2387
  //#region src/plugins/pluginRemoteNamedExports.ts
2217
2388
  /**
2218
2389
  * Transforms consumer-side imports of remote modules so that named exports
@@ -2235,6 +2406,7 @@ function pluginProxyRemotes_default(options) {
2235
2406
  * build time. Use explicit named re-exports instead.
2236
2407
  */
2237
2408
  const JS_EXTENSIONS_RE = /\.(?:[mc]?[jt]sx?|vue|svelte)(?:\?|$)/;
2409
+ const REGEX_FALLBACK_EXTENSIONS_RE = /\.(?:[mc]?[jt]sx?)(?:\?|$)/;
2238
2410
  function wrapDynamicImport(original) {
2239
2411
  return `${original}.then(function(__mf_m__) {\n if (!__mf_m__ || !__mf_m__.__moduleExports) return __mf_m__;\n var __mf_ns__ = Object.create(null);\n Object.defineProperty(__mf_ns__, Symbol.toStringTag, { value: "Module" });\n var __mf_e__ = __mf_m__.__moduleExports;\n Object.keys(__mf_e__).forEach(function(k) { if (k !== "__esModule") __mf_ns__[k] = __mf_e__[k] });\n if ("default" in __mf_m__) __mf_ns__.default = __mf_m__.default;\n return __mf_ns__;\n})`;
2240
2412
  }
@@ -2444,18 +2616,96 @@ async function collectFromEsLexer(code, isRemoteImport) {
2444
2616
  }
2445
2617
  return result;
2446
2618
  }
2619
+ function collectFromRegex(code, isRemoteImport) {
2620
+ const result = [];
2621
+ for (const match of code.matchAll(/^\s*import\s+([\s\S]*?)\s+from\s+(['"])([^'"]+)\2\s*;?/gm)) {
2622
+ const [full, specifiersPartRaw, , source] = match;
2623
+ if (!isRemoteImport(source)) continue;
2624
+ const specifiersPart = specifiersPartRaw.trim();
2625
+ if (/^type\s/.test(specifiersPart)) continue;
2626
+ const nsMatch = specifiersPart.match(/^\*\s+as\s+(\w+)$/);
2627
+ if (nsMatch) {
2628
+ result.push({
2629
+ kind: "static",
2630
+ source,
2631
+ start: match.index,
2632
+ end: match.index + full.length,
2633
+ named: [],
2634
+ namespaceLocal: nsMatch[1]
2635
+ });
2636
+ continue;
2637
+ }
2638
+ const braceMatch = specifiersPart.match(/\{([^}]*)\}/);
2639
+ if (!braceMatch) continue;
2640
+ const namedSpecifiers = braceMatch[1].split(",").map((s) => s.trim()).filter((s) => s.length > 0 && !s.startsWith("type "));
2641
+ if (namedSpecifiers.length === 0) continue;
2642
+ const defaultMatch = specifiersPart.match(/^(\w+)\s*,/);
2643
+ const named = namedSpecifiers.map((s) => {
2644
+ const asMatch = s.match(/^(\w+)\s+as\s+(\w+)$/);
2645
+ return {
2646
+ imported: asMatch ? asMatch[1] : s,
2647
+ local: asMatch ? asMatch[2] : s
2648
+ };
2649
+ });
2650
+ result.push({
2651
+ kind: "static",
2652
+ source,
2653
+ start: match.index,
2654
+ end: match.index + full.length,
2655
+ named,
2656
+ defaultLocal: defaultMatch?.[1]
2657
+ });
2658
+ }
2659
+ for (const match of code.matchAll(/^\s*export\s+\{([\s\S]*?)\}\s+from\s+(['"])([^'"]+)\2\s*;?/gm)) {
2660
+ const [full, specifiersRaw, , source] = match;
2661
+ if (!isRemoteImport(source)) continue;
2662
+ const specs = specifiersRaw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
2663
+ if (specs.length === 0) continue;
2664
+ result.push({
2665
+ kind: "reexport",
2666
+ source,
2667
+ start: match.index,
2668
+ end: match.index + full.length,
2669
+ specifiers: specs.map((s) => {
2670
+ const asMatch = s.match(/^(\w+)\s+as\s+(\w+)$/);
2671
+ return {
2672
+ local: asMatch ? asMatch[1] : s,
2673
+ exported: asMatch ? asMatch[2] : s
2674
+ };
2675
+ })
2676
+ });
2677
+ }
2678
+ for (const match of code.matchAll(/^\s*export\s+\*\s+from\s+(['"])([^'"]+)\1\s*;?/gm)) {
2679
+ const [full, , source] = match;
2680
+ if (!isRemoteImport(source)) continue;
2681
+ result.push({
2682
+ kind: "export-all",
2683
+ source,
2684
+ start: match.index,
2685
+ end: match.index + full.length
2686
+ });
2687
+ }
2688
+ for (const match of code.matchAll(/import\(\s*(['"])([^'"]+)\1\s*\)/g)) {
2689
+ const [full, , source] = match;
2690
+ if (!isRemoteImport(source)) continue;
2691
+ result.push({
2692
+ kind: "dynamic",
2693
+ start: match.index,
2694
+ end: match.index + full.length,
2695
+ originalText: full
2696
+ });
2697
+ }
2698
+ return result.length > 0 ? result : void 0;
2699
+ }
2447
2700
  function pluginRemoteNamedExports(options) {
2448
2701
  const remoteNames = Object.keys(options.remotes);
2449
- let rolldown;
2450
2702
  function isRemoteImport(source) {
2451
- return remoteNames.some((name) => source === name || source.startsWith(name + "/"));
2703
+ return remoteNames.some((name) => source === name || source.startsWith(name + "/")) || source.includes("__loadRemote__");
2452
2704
  }
2453
2705
  return {
2454
2706
  name: "module-federation-remote-named-exports",
2455
- enforce: "pre",
2707
+ enforce: "post",
2456
2708
  async transform(code, id) {
2457
- rolldown ??= getIsRolldown(this);
2458
- if (!rolldown) return;
2459
2709
  if (remoteNames.length === 0) return;
2460
2710
  if (id.includes("__loadRemote__") || id.includes("__loadShare__")) return;
2461
2711
  if (!JS_EXTENSIONS_RE.test(id)) return;
@@ -2466,134 +2716,13 @@ function pluginRemoteNamedExports(options) {
2466
2716
  } catch {
2467
2717
  imports = await collectFromEsLexer(code, isRemoteImport);
2468
2718
  }
2719
+ if ((!imports || imports.length === 0) && REGEX_FALLBACK_EXTENSIONS_RE.test(id)) imports = collectFromRegex(code, isRemoteImport);
2469
2720
  if (!imports) return;
2470
2721
  return applyRewrites(code, imports, id);
2471
2722
  }
2472
2723
  };
2473
2724
  }
2474
2725
  //#endregion
2475
- //#region src/utils/PromiseStore.ts
2476
- /**
2477
- * example:
2478
- * const store = new PromiseStore<number>();
2479
- * store.get("example").then((result) => {
2480
- * console.log("Result from example:", result); // 42
2481
- * });
2482
- * setTimeout(() => {
2483
- * store.set("example", Promise.resolve(42));
2484
- * }, 2000);
2485
- */
2486
- var PromiseStore = class {
2487
- constructor() {
2488
- this.promiseMap = /* @__PURE__ */ new Map();
2489
- this.resolveMap = /* @__PURE__ */ new Map();
2490
- }
2491
- set(id, promise) {
2492
- if (this.resolveMap.has(id)) {
2493
- promise.then(this.resolveMap.get(id));
2494
- this.resolveMap.delete(id);
2495
- }
2496
- this.promiseMap.set(id, promise);
2497
- }
2498
- get(id) {
2499
- if (this.promiseMap.has(id)) return this.promiseMap.get(id);
2500
- const pendingPromise = new Promise((resolve) => {
2501
- this.resolveMap.set(id, resolve);
2502
- });
2503
- this.promiseMap.set(id, pendingPromise);
2504
- return pendingPromise;
2505
- }
2506
- };
2507
- //#endregion
2508
- //#region src/plugins/pluginProxySharedModule_preBuild.ts
2509
- function getPrebuildResolutionSource(pkgName, shareItem) {
2510
- return getConcreteSharedImportSource(pkgName, shareItem) || pkgName;
2511
- }
2512
- function proxySharedModule(options) {
2513
- const { shared = {} } = options;
2514
- let _config;
2515
- let _command = "serve";
2516
- let isVinext = false;
2517
- const savePrebuild = new PromiseStore();
2518
- return [{
2519
- name: "generateLocalSharedImportMap",
2520
- enforce: "post",
2521
- load(id) {
2522
- if (id.includes(getLocalSharedImportMapPath())) return parsePromise.then((_) => generateLocalSharedImportMap());
2523
- },
2524
- transform(_, id) {
2525
- if (id.includes(getLocalSharedImportMapPath())) return mapCodeToCodeWithSourcemap(parsePromise.then((_) => generateLocalSharedImportMap()));
2526
- }
2527
- }, {
2528
- name: "proxyPreBuildShared",
2529
- enforce: "post",
2530
- config(config, { command }) {
2531
- setPackageDetectionCwd(config.root || process.cwd());
2532
- isVinext = hasPackageDependency("vinext");
2533
- const isRolldown = getIsRolldown(this);
2534
- _command = command;
2535
- config.resolve.alias.push(...Object.keys(shared).filter((key) => !(isVinext && key === "react")).map((key) => {
2536
- const keyBase = key.endsWith("/") ? key.slice(0, -1) : key;
2537
- const escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2538
- const escapedKeyBase = escapeRegex(keyBase);
2539
- const pattern = key.endsWith("/") ? `^(${escapedKeyBase}(?:\\/.*)?)$` : `^(${escapedKeyBase})$`;
2540
- return {
2541
- find: new RegExp(pattern),
2542
- replacement: "$1",
2543
- customResolver(source, importer) {
2544
- if (/\.css$/.test(source)) return;
2545
- if (isVinext && source === "react") return;
2546
- if (importer && importer.includes("localSharedImportMap")) return;
2547
- if (key.endsWith("/") && source !== key.slice(0, -1)) return;
2548
- const loadSharePath = getLoadShareModulePath(source, isRolldown, command);
2549
- writeLoadShareModule(source, shared[key], command, isRolldown);
2550
- if (shared[key].shareConfig.import !== false) writePreBuildLibPath(source, shared[key]);
2551
- addUsedShares(source);
2552
- writeLocalSharedImportMap();
2553
- return this.resolve(loadSharePath, importer);
2554
- }
2555
- };
2556
- }));
2557
- config.resolve.alias.push(...Object.keys(shared).filter((key) => !(isVinext && key === "react")).map((key) => {
2558
- return command === "build" ? {
2559
- find: new RegExp(`(.*${PREBUILD_TAG}.*)`),
2560
- replacement: function($1) {
2561
- const pkgName = assertModuleFound(PREBUILD_TAG, $1).name;
2562
- return getPrebuildResolutionSource(pkgName, getPreBuildShareItem(pkgName));
2563
- }
2564
- } : {
2565
- find: new RegExp(`(.*${PREBUILD_TAG}.*)`),
2566
- replacement: "$1",
2567
- async customResolver(source, importer) {
2568
- const pkgName = assertModuleFound(PREBUILD_TAG, source).name;
2569
- const importSource = getPrebuildResolutionSource(pkgName, getPreBuildShareItem(pkgName));
2570
- const resolved = await this.resolve(importSource, importer);
2571
- if (!resolved?.id) return;
2572
- const result = resolved.id;
2573
- if (_config && !result.includes(_config.cacheDir)) savePrebuild.set(pkgName, Promise.resolve(result));
2574
- return await this.resolve(await savePrebuild.get(pkgName), importer);
2575
- }
2576
- };
2577
- }));
2578
- },
2579
- configResolved(config) {
2580
- _config = config;
2581
- const isRolldown = getIsRolldown(this);
2582
- Object.keys(shared).forEach((key) => {
2583
- if (key.endsWith("/")) return;
2584
- if (isVinext && key === "react") {
2585
- addUsedShares(key);
2586
- return;
2587
- }
2588
- writeLoadShareModule(key, shared[key], _command, isRolldown);
2589
- if (shared[key].shareConfig.import !== false) writePreBuildLibPath(key, shared[key]);
2590
- addUsedShares(key);
2591
- });
2592
- writeLocalSharedImportMap();
2593
- }
2594
- }];
2595
- }
2596
- //#endregion
2597
2726
  //#region src/plugins/pluginVarRemoteEntry.ts
2598
2727
  const VarRemoteEntry = () => {
2599
2728
  const mfOptions = getNormalizeModuleFederationOptions();
@@ -2760,6 +2889,7 @@ var normalizeOptimizeDeps_default = {
2760
2889
  };
2761
2890
  //#endregion
2762
2891
  //#region src/index.ts
2892
+ const patchedManualChunks = /* @__PURE__ */ new WeakSet();
2763
2893
  const UNSAFE_JS_SOURCE_CHAR_MAP = {
2764
2894
  "<": "\\u003C",
2765
2895
  ">": "\\u003E",
@@ -2804,6 +2934,10 @@ function createEarlyVirtualModulesPlugin(options) {
2804
2934
  config.optimizeDeps = config.optimizeDeps || {};
2805
2935
  config.optimizeDeps.include = config.optimizeDeps.include || [];
2806
2936
  config.optimizeDeps.include.push(virtualRuntimeInitStatus.getImportId());
2937
+ if (isRolldown) {
2938
+ config.optimizeDeps.exclude = config.optimizeDeps.exclude || [];
2939
+ config.optimizeDeps.exclude.push(...Object.keys(remotes || {}));
2940
+ }
2807
2941
  }
2808
2942
  for (const key of Object.keys(shared)) {
2809
2943
  if (key.endsWith("/")) continue;
@@ -2928,17 +3062,20 @@ function federation(mfUserOptions) {
2928
3062
  let warnedAboutManualChunks = false;
2929
3063
  const applyManualChunks = (output) => {
2930
3064
  ensureCodeSplitting(output);
2931
- if (output.manualChunks && !warnedAboutManualChunks) {
3065
+ const isPatchedByPlugin = !!(output.manualChunks && patchedManualChunks.has(output.manualChunks));
3066
+ if (output.manualChunks && !isPatchedByPlugin && !warnedAboutManualChunks) {
2932
3067
  warnedAboutManualChunks = true;
2933
3068
  mfWarn("Ignoring `build.rollupOptions.output.manualChunks` because it conflicts with module federation. Module federation transforms shared dependency imports with top-level await, and grouping these transformed modules into a single chunk creates circular async dependencies that cause the application to silently hang.");
2934
3069
  }
2935
- output.manualChunks = function(id) {
3070
+ const mfManualChunks = function(id) {
2936
3071
  if (id.includes(runtimeInitId)) return "runtimeInit";
2937
3072
  if (id.includes("__loadShare__")) {
2938
3073
  const match = id.match(/([^/\\]+__loadShare__[^/\\]+)/);
2939
3074
  return match ? match[1] : "loadShare";
2940
3075
  }
2941
3076
  };
3077
+ patchedManualChunks.add(mfManualChunks);
3078
+ output.manualChunks = mfManualChunks;
2942
3079
  };
2943
3080
  config.build.rollupOptions = config.build.rollupOptions || {};
2944
3081
  if (!Array.isArray(config.build.rollupOptions.output)) applyManualChunks(config.build.rollupOptions.output ||= {});
@@ -3175,37 +3312,55 @@ function federation(mfUserOptions) {
3175
3312
  config.optimizeDeps.needsInterop.push(virtualDir);
3176
3313
  config.optimizeDeps.needsInterop.push(getLocalSharedImportMapPath());
3177
3314
  }
3315
+ const isAstro = hasPackageDependency("astro");
3178
3316
  const resolvedTarget = options.target ?? (config.build?.ssr ? "node" : "web");
3317
+ const envTargetDefineValue = !options.target && isAstro ? "undefined" : JSON.stringify(resolvedTarget);
3179
3318
  if (!config.define) config.define = {};
3180
- if (!("ENV_TARGET" in config.define)) config.define["ENV_TARGET"] = JSON.stringify(resolvedTarget);
3319
+ if (!("ENV_TARGET" in config.define)) config.define["ENV_TARGET"] = envTargetDefineValue;
3181
3320
  if (options.target && "ENV_TARGET" in config.define && config.define["ENV_TARGET"] !== JSON.stringify(options.target)) mfWarn(`ENV_TARGET define (${config.define["ENV_TARGET"]}) differs from target option ("${options.target}"). ENV_TARGET will not be overridden.`);
3182
3321
  }
3183
3322
  },
3184
3323
  ...Manifest(),
3185
3324
  ...VarRemoteEntry(),
3186
- ...Object.keys(options.exposes).length > 0 ? [{
3187
- name: "module-federation-fix-preload",
3188
- enforce: "post",
3189
- apply: "build",
3190
- generateBundle(_, bundle) {
3191
- for (const chunk of Object.values(bundle)) {
3192
- if (chunk.type !== "chunk") continue;
3193
- if (!chunk.code.includes("modulepreload")) continue;
3194
- const chunkDir = path.dirname(chunk.fileName);
3195
- const prefixToRoot = chunkDir === "." ? "" : `${path.relative(chunkDir, ".")}/`;
3196
- const replacementExpr = prefixToRoot ? `${escapeUnsafeJsSourceChars(JSON.stringify(prefixToRoot))}+$1` : "$1";
3197
- const replacement = `=function($1){return new URL(${replacementExpr},import.meta.url).href}`;
3198
- const replaced = chunk.code.replace(/=\(?(\w+)(?:,\w+)?\)?\s*=>\s*["'`][^"'`]*["'`]\s*\+\s*\1/, replacement);
3199
- if (replaced !== chunk.code) {
3200
- chunk.code = replaced;
3201
- continue;
3325
+ ...(function() {
3326
+ let disablePreload = false;
3327
+ return Object.keys(options.exposes).length > 0 ? [{
3328
+ name: "module-federation-fix-preload",
3329
+ enforce: "post",
3330
+ apply: "build",
3331
+ config(_config, { command }) {
3332
+ const manifest = options.manifest;
3333
+ const isConsumerProject = Object.keys(options.exposes).length === 0;
3334
+ const getDefaultDisableAssetsAnalyze = (cfgCommand) => cfgCommand === "serve" && isConsumerProject && (typeof manifest !== "object" || !Object.prototype.hasOwnProperty.call(manifest, "disableAssetsAnalyze"));
3335
+ const getConfiguredDisableAssetsAnalyze = (cfgCommand) => {
3336
+ if (typeof manifest === "object" && manifest !== null) {
3337
+ if (Object.prototype.hasOwnProperty.call(manifest, "disableAssetsAnalyze")) return manifest.disableAssetsAnalyze === true;
3338
+ }
3339
+ return getDefaultDisableAssetsAnalyze(cfgCommand);
3340
+ };
3341
+ disablePreload = getConfiguredDisableAssetsAnalyze(command);
3342
+ },
3343
+ generateBundle(_, bundle) {
3344
+ if (disablePreload) return;
3345
+ for (const chunk of Object.values(bundle)) {
3346
+ if (chunk.type !== "chunk") continue;
3347
+ if (!chunk.code.includes("modulepreload")) continue;
3348
+ const chunkDir = path.dirname(chunk.fileName);
3349
+ const prefixToRoot = chunkDir === "." ? "" : `${path.relative(chunkDir, ".")}/`;
3350
+ const replacementExpr = prefixToRoot ? `${escapeUnsafeJsSourceChars(JSON.stringify(prefixToRoot))}+$1` : "$1";
3351
+ const replacement = `=function($1){return new URL(${replacementExpr},import.meta.url).href}`;
3352
+ const replaced = chunk.code.replace(/=\(?(\w+)(?:,\w+)?\)?\s*=>\s*["'`][^"'`]*["'`]\s*\+\s*\1/, replacement);
3353
+ if (replaced !== chunk.code) {
3354
+ chunk.code = replaced;
3355
+ continue;
3356
+ }
3357
+ chunk.code = chunk.code.replace(/=function\((\w+)(?:,\w+)?\)\{return\s*["'`][^"'`]*["'`]\s*\+\s*\1\s*\}/, replacement);
3358
+ chunk.code = chunk.code.replace(/=function\((\w+)(?:,\w+)?\)\{return new URL\("\.\.\/"\+\1,import\.meta\.url\)\.href\}/, replacement);
3359
+ chunk.code = chunk.code.replace(/new URL\("\.\.\/"\+(\w+),import\.meta\.url\)\.href/g, `new URL(${replacementExpr},import.meta.url).href`);
3202
3360
  }
3203
- chunk.code = chunk.code.replace(/=function\((\w+)(?:,\w+)?\)\{return\s*["'`][^"'`]*["'`]\s*\+\s*\1\s*\}/, replacement);
3204
- chunk.code = chunk.code.replace(/=function\((\w+)(?:,\w+)?\)\{return new URL\("\.\.\/"\+\1,import\.meta\.url\)\.href\}/, replacement);
3205
- chunk.code = chunk.code.replace(/new URL\("\.\.\/"\+(\w+),import\.meta\.url\)\.href/g, `new URL(${replacementExpr},import.meta.url).href`);
3206
3361
  }
3207
- }
3208
- }] : []
3362
+ }] : [];
3363
+ })()
3209
3364
  ];
3210
3365
  }
3211
3366
  //#endregion