@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.cjs CHANGED
@@ -152,11 +152,13 @@ function removePathFromNpmPackage(packageString) {
152
152
  return match ? match[0] : packageString;
153
153
  }
154
154
  /**
155
- * Detect whether the current runtime is Vite 8+ (with rolldown internally) by checking
156
- * for `meta.rolldownVersion` on the plugin hook context.
155
+ * Detect whether the current runtime is Vite 8+ by checking for a Vite version flag
156
+ * on the plugin hook context, with Rolldown metadata kept as a compatibility fallback.
157
157
  */
158
158
  function getIsRolldown(ctx) {
159
- return !!ctx?.meta?.rolldownVersion;
159
+ const viteVersion = ctx?.meta?.viteVersion;
160
+ const viteMajor = Number(String(viteVersion ?? "").split(".")[0]);
161
+ return Number.isFinite(viteMajor) && viteMajor >= 8 || !!ctx?.meta?.rolldownVersion;
160
162
  }
161
163
  function hasPackageDependency(dependencyName, cwd = packageDetectionCwd || process.cwd()) {
162
164
  const cacheKey = getDependencyCacheKey(cwd, dependencyName);
@@ -806,13 +808,13 @@ function normalizeLibrary(library) {
806
808
  if (!library) return void 0;
807
809
  return library;
808
810
  }
809
- function normalizeManifest(manifest = false) {
811
+ function normalizeManifest(manifest) {
812
+ if (manifest === void 0) return;
810
813
  if (typeof manifest === "boolean") return manifest;
811
- return Object.assign({
812
- filePath: "",
813
- disableAssetsAnalyze: false,
814
- fileName: "mf-manifest.json"
815
- }, manifest);
814
+ return {
815
+ ...manifest,
816
+ fileName: manifest.fileName || "mf-manifest.json"
817
+ };
816
818
  }
817
819
  let config;
818
820
  function getNormalizeModuleFederationOptions() {
@@ -1231,6 +1233,9 @@ function escapeGeneratedStringLiteral(value) {
1231
1233
  }
1232
1234
  });
1233
1235
  }
1236
+ function isValidJsIdentifier(name) {
1237
+ return /^[$_\p{ID_Start}][$_\u200C\u200D\p{ID_Continue}]*$/u.test(name);
1238
+ }
1234
1239
  const localRequire = (0, module$1.createRequire)(require("url").pathToFileURL(__filename).href);
1235
1240
  function resolvePackageEntryFromProjectRoot(pkg) {
1236
1241
  try {
@@ -1314,7 +1319,7 @@ function getEsmNamedExports(pkg) {
1314
1319
  const { initSync, parse } = localRequire("es-module-lexer");
1315
1320
  initSync();
1316
1321
  const [, exports] = parse((0, fs.readFileSync)(entryPath, "utf-8"), entryPath);
1317
- return exports.map((item) => item.n).filter((name) => !!name && name !== "default" && name !== "__esModule" && /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name));
1322
+ return exports.map((item) => item.n).filter((name) => !!name && name !== "default" && name !== "__esModule" && isValidJsIdentifier(name));
1318
1323
  } catch {
1319
1324
  return [];
1320
1325
  }
@@ -1322,7 +1327,7 @@ function getEsmNamedExports(pkg) {
1322
1327
  function getPackageNamedExports(pkg) {
1323
1328
  try {
1324
1329
  const mod = (0, module$1.createRequire)(new URL(`file://${pathe.default.join(getPackageDetectionCwd(), "package.json")}`))(pkg);
1325
- return Object.keys(mod).filter((k) => k !== "default" && k !== "__esModule" && /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(k));
1330
+ return Object.keys(mod).filter((k) => k !== "default" && k !== "__esModule" && isValidJsIdentifier(k));
1326
1331
  } catch {
1327
1332
  return getEsmNamedExports(pkg);
1328
1333
  }
@@ -1411,7 +1416,9 @@ function writeLoadShareModule(pkg, shareItem, command, isRolldown) {
1411
1416
  `, true);
1412
1417
  return;
1413
1418
  }
1414
- const useSsrProviderFallback = hasPackageDependency("vinext") && command === "build" && pkg === "react";
1419
+ const isVinext = hasPackageDependency("vinext");
1420
+ const isAstro = hasPackageDependency("astro");
1421
+ const useSsrProviderFallback = (isVinext || isAstro) && command === "build" && pkg === "react";
1415
1422
  const concreteSharedImportSource = getConcreteSharedImportSource(pkg, shareItem);
1416
1423
  const sharedImportSource = concreteSharedImportSource || getPreBuildLibImportId(pkg);
1417
1424
  const devImportSource = concreteSharedImportSource || pkg;
@@ -1466,6 +1473,8 @@ function writeLocalSharedImportMap() {
1466
1473
  }
1467
1474
  function generateLocalSharedImportMap() {
1468
1475
  const isVinext = hasPackageDependency("vinext");
1476
+ const isAstro = hasPackageDependency("astro");
1477
+ const useDirectReactImport = isVinext || isAstro;
1469
1478
  const options = getNormalizeModuleFederationOptions();
1470
1479
  return `
1471
1480
  import {loadShare} from "@module-federation/runtime";
@@ -1474,7 +1483,7 @@ function generateLocalSharedImportMap() {
1474
1483
  const shareItem = getNormalizeShareItem(pkg);
1475
1484
  return `
1476
1485
  ${JSON.stringify(pkg)}: async () => {
1477
- ${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");
1486
+ ${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");
1478
1487
  return pkg;` : `let pkg = await import(${JSON.stringify(getSharedImportSource(pkg, shareItem))});
1479
1488
  return pkg;`}
1480
1489
  }
@@ -1499,7 +1508,7 @@ function generateLocalSharedImportMap() {
1499
1508
  usedShared[${JSON.stringify(key)}].loaded = true
1500
1509
  const {${JSON.stringify(key)}: pkgDynamicImport} = importMap
1501
1510
  const res = await pkgDynamicImport()
1502
- const exportModule = ${JSON.stringify(isVinext)} && ${JSON.stringify(key)} === "react"
1511
+ const exportModule = ${JSON.stringify(useDirectReactImport)} && ${JSON.stringify(key)} === "react"
1503
1512
  ? (res?.default ?? res)
1504
1513
  : {...res}
1505
1514
  // All npm packages pre-built by vite will be converted to esm
@@ -1814,7 +1823,7 @@ const buildFileToShareKeyMap = async (shareKeys, resolveFn) => {
1814
1823
  * @returns The resolved public path
1815
1824
  */
1816
1825
  function resolvePublicPath(options, viteBase, originalBase) {
1817
- if (options.publicPath) return options.publicPath;
1826
+ if (options.publicPath && options.publicPath !== "auto") return options.publicPath;
1818
1827
  if (originalBase === "") return "auto";
1819
1828
  if (viteBase) return viteBase.replace(/\/?$/, "/");
1820
1829
  return "auto";
@@ -1824,9 +1833,17 @@ function resolvePublicPath(options, viteBase, originalBase) {
1824
1833
  const Manifest = () => {
1825
1834
  const mfOptions = getNormalizeModuleFederationOptions();
1826
1835
  const { name, filename, getPublicPath, manifest: manifestOptions, varFilename } = mfOptions;
1827
- let mfManifestName = "";
1828
- if (manifestOptions === true) mfManifestName = "mf-manifest.json";
1829
- if (typeof manifestOptions !== "boolean") mfManifestName = pathe.join(manifestOptions?.filePath || "", manifestOptions?.fileName || "");
1836
+ let mfManifestName = manifestOptions === true ? "mf-manifest.json" : typeof manifestOptions === "object" ? pathe.join(manifestOptions?.filePath || "", manifestOptions?.fileName || "mf-manifest.json") : void 0;
1837
+ let mfManifestStatsName = mfManifestName ? getStatsFileName(mfManifestName) : void 0;
1838
+ const isConsumerProject = Object.keys(mfOptions.exposes).length === 0;
1839
+ let disableAssetsAnalyze = false;
1840
+ const getDefaultDisableAssetsAnalyze = (command) => command === "serve" && isConsumerProject && (typeof manifestOptions !== "object" || !Object.prototype.hasOwnProperty.call(manifestOptions, "disableAssetsAnalyze"));
1841
+ const getConfiguredDisableAssetsAnalyze = (command) => {
1842
+ if (typeof manifestOptions === "object" && manifestOptions !== null) {
1843
+ if (Object.prototype.hasOwnProperty.call(manifestOptions, "disableAssetsAnalyze")) return manifestOptions.disableAssetsAnalyze === true;
1844
+ }
1845
+ return getDefaultDisableAssetsAnalyze(command);
1846
+ };
1830
1847
  let root;
1831
1848
  let remoteEntryFile;
1832
1849
  let publicPath;
@@ -1861,7 +1878,7 @@ const Manifest = () => {
1861
1878
  res.setHeader("Content-Type", "application/json");
1862
1879
  res.setHeader("Access-Control-Allow-Origin", "*");
1863
1880
  res.end(JSON.stringify({
1864
- ...generateMFManifest({}),
1881
+ ...generateMFManifest({}, disableAssetsAnalyze),
1865
1882
  id: name,
1866
1883
  name,
1867
1884
  metaData: {
@@ -1902,9 +1919,10 @@ const Manifest = () => {
1902
1919
  name: "module-federation-manifest",
1903
1920
  enforce: "post",
1904
1921
  config(config, { command }) {
1905
- if (!config.build) config.build = {};
1906
- if (!config.build.manifest) config.build.manifest = config.build.manifest || !!manifestOptions;
1907
1922
  _command = command;
1923
+ if (!config.build) config.build = {};
1924
+ if (!config.build.manifest) config.build.manifest = config.build.manifest || !!mfManifestName;
1925
+ disableAssetsAnalyze = getConfiguredDisableAssetsAnalyze(command);
1908
1926
  _originalConfigBase = config.base;
1909
1927
  },
1910
1928
  configResolved(config) {
@@ -1918,28 +1936,35 @@ const Manifest = () => {
1918
1936
  let filesMap = {};
1919
1937
  const foundRemoteEntryFile = findRemoteEntryFile(mfOptions.filename, bundle);
1920
1938
  if (foundRemoteEntryFile) remoteEntryFile = foundRemoteEntryFile;
1921
- const allCssAssets = mfOptions.bundleAllCSS ? collectCssAssets(bundle) : /* @__PURE__ */ new Set();
1922
- const exposesModules = Object.keys(mfOptions.exposes).map((item) => mfOptions.exposes[item].import);
1923
- processModuleAssets(bundle, filesMap, (modulePath) => {
1924
- const absoluteModulePath = pathe.resolve(root, modulePath);
1925
- return exposesModules.find((exposeModule) => {
1926
- const exposePath = pathe.resolve(root, exposeModule);
1927
- if (absoluteModulePath === exposePath) return true;
1928
- const getPathWithoutKnownExt = (filePath) => {
1929
- const ext = pathe.extname(filePath);
1930
- return JS_EXTENSIONS.includes(ext) ? pathe.join(pathe.dirname(filePath), pathe.basename(filePath, ext)) : filePath;
1931
- };
1932
- return getPathWithoutKnownExt(absoluteModulePath) === getPathWithoutKnownExt(exposePath);
1939
+ const allCssAssets = mfOptions.bundleAllCSS && !disableAssetsAnalyze ? collectCssAssets(bundle) : /* @__PURE__ */ new Set();
1940
+ if (!disableAssetsAnalyze) {
1941
+ const exposesModules = Object.keys(mfOptions.exposes).map((item) => mfOptions.exposes[item].import);
1942
+ processModuleAssets(bundle, filesMap, (modulePath) => {
1943
+ const absoluteModulePath = pathe.resolve(root, modulePath);
1944
+ return exposesModules.find((exposeModule) => {
1945
+ const exposePath = pathe.resolve(root, exposeModule);
1946
+ if (absoluteModulePath === exposePath) return true;
1947
+ const getPathWithoutKnownExt = (filePath) => {
1948
+ const ext = pathe.extname(filePath);
1949
+ return JS_EXTENSIONS.includes(ext) ? pathe.join(pathe.dirname(filePath), pathe.basename(filePath, ext)) : filePath;
1950
+ };
1951
+ return getPathWithoutKnownExt(absoluteModulePath) === getPathWithoutKnownExt(exposePath);
1952
+ });
1933
1953
  });
1934
- });
1935
- const fileToShareKey = await buildFileToShareKeyMap(getUsedShares(), this.resolve.bind(this));
1936
- processModuleAssets(bundle, filesMap, (modulePath) => fileToShareKey.get(modulePath));
1937
- if (mfOptions.bundleAllCSS) addCssAssetsToAllExports(filesMap, allCssAssets);
1938
- filesMap = deduplicateAssets(filesMap);
1954
+ const fileToShareKey = await buildFileToShareKeyMap(getUsedShares(), this.resolve.bind(this));
1955
+ processModuleAssets(bundle, filesMap, (modulePath) => fileToShareKey.get(modulePath));
1956
+ if (mfOptions.bundleAllCSS) addCssAssetsToAllExports(filesMap, allCssAssets);
1957
+ filesMap = deduplicateAssets(filesMap);
1958
+ }
1939
1959
  this.emitFile({
1940
1960
  type: "asset",
1941
1961
  fileName: mfManifestName,
1942
- source: JSON.stringify(generateMFManifest(filesMap))
1962
+ source: JSON.stringify(generateMFManifest(filesMap, disableAssetsAnalyze))
1963
+ });
1964
+ if (mfManifestStatsName) this.emitFile({
1965
+ type: "asset",
1966
+ fileName: mfManifestStatsName,
1967
+ source: JSON.stringify(generateMFStats(filesMap, bundle, disableAssetsAnalyze))
1943
1968
  });
1944
1969
  }
1945
1970
  }];
@@ -1948,7 +1973,7 @@ const Manifest = () => {
1948
1973
  * @param preloadMap - Map of module assets to include
1949
1974
  * @returns Complete manifest object
1950
1975
  */
1951
- function generateMFManifest(preloadMap) {
1976
+ function generateMFManifest(preloadMap, disableAssetsAnalyze = false) {
1952
1977
  const options = getNormalizeModuleFederationOptions();
1953
1978
  const { name, varFilename } = options;
1954
1979
  const remoteEntry = {
@@ -1974,6 +1999,7 @@ const Manifest = () => {
1974
1999
  id: `${name}:${shareKey}`,
1975
2000
  name: shareKey,
1976
2001
  version: shareItem.version,
2002
+ singleton: shareItem.shareConfig.singleton,
1977
2003
  requiredVersion: shareItem.shareConfig.requiredVersion,
1978
2004
  assets: {
1979
2005
  js: {
@@ -2027,12 +2053,33 @@ const Manifest = () => {
2027
2053
  pluginVersion: "0.2.5",
2028
2054
  ...!!getPublicPath ? { getPublicPath } : { publicPath }
2029
2055
  },
2030
- shared,
2056
+ ...disableAssetsAnalyze ? {} : { shared },
2031
2057
  remotes,
2032
- exposes
2058
+ ...disableAssetsAnalyze ? {} : { exposes }
2059
+ };
2060
+ }
2061
+ function generateMFStats(preloadMap, bundle, disableAssetsAnalyze = false) {
2062
+ const baseManifest = generateMFManifest(preloadMap, disableAssetsAnalyze);
2063
+ const bundleSummary = Object.entries(bundle).map(([fileName, chunkOrAsset]) => ({
2064
+ fileName,
2065
+ type: chunkOrAsset.type,
2066
+ isEntry: chunkOrAsset.isEntry || false,
2067
+ size: typeof chunkOrAsset.code === "string" ? chunkOrAsset.code.length : chunkOrAsset.source?.length || chunkOrAsset.source?.byteLength || void 0
2068
+ }));
2069
+ return {
2070
+ ...baseManifest,
2071
+ buildOutput: bundleSummary,
2072
+ ...disableAssetsAnalyze ? {} : { assetAnalysis: preloadMap }
2033
2073
  };
2034
2074
  }
2035
2075
  };
2076
+ function getStatsFileName(manifestFileName) {
2077
+ const parsed = pathe.parse(manifestFileName);
2078
+ const fileExt = parsed.ext || ".json";
2079
+ const baseName = parsed.ext ? parsed.name : parsed.base;
2080
+ const fileName = `${baseName === "mf-manifest" ? "mf" : baseName}-stats${fileExt}`;
2081
+ return parsed.dir ? pathe.join(parsed.dir, fileName) : fileName;
2082
+ }
2036
2083
  //#endregion
2037
2084
  //#region src/plugins/pluginModuleParseEnd.ts
2038
2085
  let _resolve, _parseTimeout;
@@ -2236,6 +2283,130 @@ function pluginProxyRemotes_default(options) {
2236
2283
  };
2237
2284
  }
2238
2285
  //#endregion
2286
+ //#region src/utils/PromiseStore.ts
2287
+ /**
2288
+ * example:
2289
+ * const store = new PromiseStore<number>();
2290
+ * store.get("example").then((result) => {
2291
+ * console.log("Result from example:", result); // 42
2292
+ * });
2293
+ * setTimeout(() => {
2294
+ * store.set("example", Promise.resolve(42));
2295
+ * }, 2000);
2296
+ */
2297
+ var PromiseStore = class {
2298
+ constructor() {
2299
+ this.promiseMap = /* @__PURE__ */ new Map();
2300
+ this.resolveMap = /* @__PURE__ */ new Map();
2301
+ }
2302
+ set(id, promise) {
2303
+ if (this.resolveMap.has(id)) {
2304
+ promise.then(this.resolveMap.get(id));
2305
+ this.resolveMap.delete(id);
2306
+ }
2307
+ this.promiseMap.set(id, promise);
2308
+ }
2309
+ get(id) {
2310
+ if (this.promiseMap.has(id)) return this.promiseMap.get(id);
2311
+ const pendingPromise = new Promise((resolve) => {
2312
+ this.resolveMap.set(id, resolve);
2313
+ });
2314
+ this.promiseMap.set(id, pendingPromise);
2315
+ return pendingPromise;
2316
+ }
2317
+ };
2318
+ //#endregion
2319
+ //#region src/plugins/pluginProxySharedModule_preBuild.ts
2320
+ function getPrebuildResolutionSource(pkgName, shareItem) {
2321
+ return getConcreteSharedImportSource(pkgName, shareItem) || pkgName;
2322
+ }
2323
+ function proxySharedModule(options) {
2324
+ const { shared = {} } = options;
2325
+ let _config;
2326
+ let _command = "serve";
2327
+ let useDirectReactImport = false;
2328
+ const savePrebuild = new PromiseStore();
2329
+ return [{
2330
+ name: "generateLocalSharedImportMap",
2331
+ enforce: "post",
2332
+ load(id) {
2333
+ if (id.includes(getLocalSharedImportMapPath())) return parsePromise.then((_) => generateLocalSharedImportMap());
2334
+ },
2335
+ transform(_, id) {
2336
+ if (id.includes(getLocalSharedImportMapPath())) return mapCodeToCodeWithSourcemap(parsePromise.then((_) => generateLocalSharedImportMap()));
2337
+ }
2338
+ }, {
2339
+ name: "proxyPreBuildShared",
2340
+ enforce: "post",
2341
+ config(config, { command }) {
2342
+ setPackageDetectionCwd(config.root || process.cwd());
2343
+ const isVinext = hasPackageDependency("vinext");
2344
+ const isAstro = hasPackageDependency("astro");
2345
+ const isRolldown = getIsRolldown(this);
2346
+ _command = command;
2347
+ useDirectReactImport = isVinext || isAstro;
2348
+ config.resolve.alias.push(...Object.keys(shared).filter((key) => !(useDirectReactImport && key === "react")).map((key) => {
2349
+ const keyBase = key.endsWith("/") ? key.slice(0, -1) : key;
2350
+ const escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2351
+ const escapedKeyBase = escapeRegex(keyBase);
2352
+ const pattern = key.endsWith("/") ? `^(${escapedKeyBase}(?:\\/.*)?)$` : `^(${escapedKeyBase})$`;
2353
+ return {
2354
+ find: new RegExp(pattern),
2355
+ replacement: "$1",
2356
+ customResolver(source, importer) {
2357
+ if (/\.css$/.test(source)) return;
2358
+ if (useDirectReactImport && source === "react") return;
2359
+ if (importer && importer.includes("localSharedImportMap")) return;
2360
+ if (key.endsWith("/") && source !== key.slice(0, -1)) return;
2361
+ const loadSharePath = getLoadShareModulePath(source, isRolldown, command);
2362
+ writeLoadShareModule(source, shared[key], command, isRolldown);
2363
+ if (shared[key].shareConfig.import !== false) writePreBuildLibPath(source, shared[key]);
2364
+ addUsedShares(source);
2365
+ writeLocalSharedImportMap();
2366
+ return this.resolve(loadSharePath, importer);
2367
+ }
2368
+ };
2369
+ }));
2370
+ config.resolve.alias.push(...Object.keys(shared).filter((key) => !(useDirectReactImport && key === "react")).map((key) => {
2371
+ return command === "build" ? {
2372
+ find: new RegExp(`(.*${PREBUILD_TAG}.*)`),
2373
+ replacement: function($1) {
2374
+ const pkgName = assertModuleFound(PREBUILD_TAG, $1).name;
2375
+ return getPrebuildResolutionSource(pkgName, getPreBuildShareItem(pkgName));
2376
+ }
2377
+ } : {
2378
+ find: new RegExp(`(.*${PREBUILD_TAG}.*)`),
2379
+ replacement: "$1",
2380
+ async customResolver(source, importer) {
2381
+ const pkgName = assertModuleFound(PREBUILD_TAG, source).name;
2382
+ const importSource = getPrebuildResolutionSource(pkgName, getPreBuildShareItem(pkgName));
2383
+ const resolved = await this.resolve(importSource, importer);
2384
+ if (!resolved?.id) return;
2385
+ const result = resolved.id;
2386
+ if (_config && !result.includes(_config.cacheDir)) savePrebuild.set(pkgName, Promise.resolve(result));
2387
+ return await this.resolve(await savePrebuild.get(pkgName), importer);
2388
+ }
2389
+ };
2390
+ }));
2391
+ },
2392
+ configResolved(config) {
2393
+ _config = config;
2394
+ const isRolldown = getIsRolldown(this);
2395
+ Object.keys(shared).forEach((key) => {
2396
+ if (key.endsWith("/")) return;
2397
+ if (useDirectReactImport && key === "react") {
2398
+ addUsedShares(key);
2399
+ return;
2400
+ }
2401
+ writeLoadShareModule(key, shared[key], _command, isRolldown);
2402
+ if (shared[key].shareConfig.import !== false) writePreBuildLibPath(key, shared[key]);
2403
+ addUsedShares(key);
2404
+ });
2405
+ writeLocalSharedImportMap();
2406
+ }
2407
+ }];
2408
+ }
2409
+ //#endregion
2239
2410
  //#region src/plugins/pluginRemoteNamedExports.ts
2240
2411
  /**
2241
2412
  * Transforms consumer-side imports of remote modules so that named exports
@@ -2258,6 +2429,7 @@ function pluginProxyRemotes_default(options) {
2258
2429
  * build time. Use explicit named re-exports instead.
2259
2430
  */
2260
2431
  const JS_EXTENSIONS_RE = /\.(?:[mc]?[jt]sx?|vue|svelte)(?:\?|$)/;
2432
+ const REGEX_FALLBACK_EXTENSIONS_RE = /\.(?:[mc]?[jt]sx?)(?:\?|$)/;
2261
2433
  function wrapDynamicImport(original) {
2262
2434
  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})`;
2263
2435
  }
@@ -2467,18 +2639,96 @@ async function collectFromEsLexer(code, isRemoteImport) {
2467
2639
  }
2468
2640
  return result;
2469
2641
  }
2642
+ function collectFromRegex(code, isRemoteImport) {
2643
+ const result = [];
2644
+ for (const match of code.matchAll(/^\s*import\s+([\s\S]*?)\s+from\s+(['"])([^'"]+)\2\s*;?/gm)) {
2645
+ const [full, specifiersPartRaw, , source] = match;
2646
+ if (!isRemoteImport(source)) continue;
2647
+ const specifiersPart = specifiersPartRaw.trim();
2648
+ if (/^type\s/.test(specifiersPart)) continue;
2649
+ const nsMatch = specifiersPart.match(/^\*\s+as\s+(\w+)$/);
2650
+ if (nsMatch) {
2651
+ result.push({
2652
+ kind: "static",
2653
+ source,
2654
+ start: match.index,
2655
+ end: match.index + full.length,
2656
+ named: [],
2657
+ namespaceLocal: nsMatch[1]
2658
+ });
2659
+ continue;
2660
+ }
2661
+ const braceMatch = specifiersPart.match(/\{([^}]*)\}/);
2662
+ if (!braceMatch) continue;
2663
+ const namedSpecifiers = braceMatch[1].split(",").map((s) => s.trim()).filter((s) => s.length > 0 && !s.startsWith("type "));
2664
+ if (namedSpecifiers.length === 0) continue;
2665
+ const defaultMatch = specifiersPart.match(/^(\w+)\s*,/);
2666
+ const named = namedSpecifiers.map((s) => {
2667
+ const asMatch = s.match(/^(\w+)\s+as\s+(\w+)$/);
2668
+ return {
2669
+ imported: asMatch ? asMatch[1] : s,
2670
+ local: asMatch ? asMatch[2] : s
2671
+ };
2672
+ });
2673
+ result.push({
2674
+ kind: "static",
2675
+ source,
2676
+ start: match.index,
2677
+ end: match.index + full.length,
2678
+ named,
2679
+ defaultLocal: defaultMatch?.[1]
2680
+ });
2681
+ }
2682
+ for (const match of code.matchAll(/^\s*export\s+\{([\s\S]*?)\}\s+from\s+(['"])([^'"]+)\2\s*;?/gm)) {
2683
+ const [full, specifiersRaw, , source] = match;
2684
+ if (!isRemoteImport(source)) continue;
2685
+ const specs = specifiersRaw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
2686
+ if (specs.length === 0) continue;
2687
+ result.push({
2688
+ kind: "reexport",
2689
+ source,
2690
+ start: match.index,
2691
+ end: match.index + full.length,
2692
+ specifiers: specs.map((s) => {
2693
+ const asMatch = s.match(/^(\w+)\s+as\s+(\w+)$/);
2694
+ return {
2695
+ local: asMatch ? asMatch[1] : s,
2696
+ exported: asMatch ? asMatch[2] : s
2697
+ };
2698
+ })
2699
+ });
2700
+ }
2701
+ for (const match of code.matchAll(/^\s*export\s+\*\s+from\s+(['"])([^'"]+)\1\s*;?/gm)) {
2702
+ const [full, , source] = match;
2703
+ if (!isRemoteImport(source)) continue;
2704
+ result.push({
2705
+ kind: "export-all",
2706
+ source,
2707
+ start: match.index,
2708
+ end: match.index + full.length
2709
+ });
2710
+ }
2711
+ for (const match of code.matchAll(/import\(\s*(['"])([^'"]+)\1\s*\)/g)) {
2712
+ const [full, , source] = match;
2713
+ if (!isRemoteImport(source)) continue;
2714
+ result.push({
2715
+ kind: "dynamic",
2716
+ start: match.index,
2717
+ end: match.index + full.length,
2718
+ originalText: full
2719
+ });
2720
+ }
2721
+ return result.length > 0 ? result : void 0;
2722
+ }
2470
2723
  function pluginRemoteNamedExports(options) {
2471
2724
  const remoteNames = Object.keys(options.remotes);
2472
- let rolldown;
2473
2725
  function isRemoteImport(source) {
2474
- return remoteNames.some((name) => source === name || source.startsWith(name + "/"));
2726
+ return remoteNames.some((name) => source === name || source.startsWith(name + "/")) || source.includes("__loadRemote__");
2475
2727
  }
2476
2728
  return {
2477
2729
  name: "module-federation-remote-named-exports",
2478
- enforce: "pre",
2730
+ enforce: "post",
2479
2731
  async transform(code, id) {
2480
- rolldown ??= getIsRolldown(this);
2481
- if (!rolldown) return;
2482
2732
  if (remoteNames.length === 0) return;
2483
2733
  if (id.includes("__loadRemote__") || id.includes("__loadShare__")) return;
2484
2734
  if (!JS_EXTENSIONS_RE.test(id)) return;
@@ -2489,134 +2739,13 @@ function pluginRemoteNamedExports(options) {
2489
2739
  } catch {
2490
2740
  imports = await collectFromEsLexer(code, isRemoteImport);
2491
2741
  }
2742
+ if ((!imports || imports.length === 0) && REGEX_FALLBACK_EXTENSIONS_RE.test(id)) imports = collectFromRegex(code, isRemoteImport);
2492
2743
  if (!imports) return;
2493
2744
  return applyRewrites(code, imports, id);
2494
2745
  }
2495
2746
  };
2496
2747
  }
2497
2748
  //#endregion
2498
- //#region src/utils/PromiseStore.ts
2499
- /**
2500
- * example:
2501
- * const store = new PromiseStore<number>();
2502
- * store.get("example").then((result) => {
2503
- * console.log("Result from example:", result); // 42
2504
- * });
2505
- * setTimeout(() => {
2506
- * store.set("example", Promise.resolve(42));
2507
- * }, 2000);
2508
- */
2509
- var PromiseStore = class {
2510
- constructor() {
2511
- this.promiseMap = /* @__PURE__ */ new Map();
2512
- this.resolveMap = /* @__PURE__ */ new Map();
2513
- }
2514
- set(id, promise) {
2515
- if (this.resolveMap.has(id)) {
2516
- promise.then(this.resolveMap.get(id));
2517
- this.resolveMap.delete(id);
2518
- }
2519
- this.promiseMap.set(id, promise);
2520
- }
2521
- get(id) {
2522
- if (this.promiseMap.has(id)) return this.promiseMap.get(id);
2523
- const pendingPromise = new Promise((resolve) => {
2524
- this.resolveMap.set(id, resolve);
2525
- });
2526
- this.promiseMap.set(id, pendingPromise);
2527
- return pendingPromise;
2528
- }
2529
- };
2530
- //#endregion
2531
- //#region src/plugins/pluginProxySharedModule_preBuild.ts
2532
- function getPrebuildResolutionSource(pkgName, shareItem) {
2533
- return getConcreteSharedImportSource(pkgName, shareItem) || pkgName;
2534
- }
2535
- function proxySharedModule(options) {
2536
- const { shared = {} } = options;
2537
- let _config;
2538
- let _command = "serve";
2539
- let isVinext = false;
2540
- const savePrebuild = new PromiseStore();
2541
- return [{
2542
- name: "generateLocalSharedImportMap",
2543
- enforce: "post",
2544
- load(id) {
2545
- if (id.includes(getLocalSharedImportMapPath())) return parsePromise.then((_) => generateLocalSharedImportMap());
2546
- },
2547
- transform(_, id) {
2548
- if (id.includes(getLocalSharedImportMapPath())) return mapCodeToCodeWithSourcemap(parsePromise.then((_) => generateLocalSharedImportMap()));
2549
- }
2550
- }, {
2551
- name: "proxyPreBuildShared",
2552
- enforce: "post",
2553
- config(config, { command }) {
2554
- setPackageDetectionCwd(config.root || process.cwd());
2555
- isVinext = hasPackageDependency("vinext");
2556
- const isRolldown = getIsRolldown(this);
2557
- _command = command;
2558
- config.resolve.alias.push(...Object.keys(shared).filter((key) => !(isVinext && key === "react")).map((key) => {
2559
- const keyBase = key.endsWith("/") ? key.slice(0, -1) : key;
2560
- const escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2561
- const escapedKeyBase = escapeRegex(keyBase);
2562
- const pattern = key.endsWith("/") ? `^(${escapedKeyBase}(?:\\/.*)?)$` : `^(${escapedKeyBase})$`;
2563
- return {
2564
- find: new RegExp(pattern),
2565
- replacement: "$1",
2566
- customResolver(source, importer) {
2567
- if (/\.css$/.test(source)) return;
2568
- if (isVinext && source === "react") return;
2569
- if (importer && importer.includes("localSharedImportMap")) return;
2570
- if (key.endsWith("/") && source !== key.slice(0, -1)) return;
2571
- const loadSharePath = getLoadShareModulePath(source, isRolldown, command);
2572
- writeLoadShareModule(source, shared[key], command, isRolldown);
2573
- if (shared[key].shareConfig.import !== false) writePreBuildLibPath(source, shared[key]);
2574
- addUsedShares(source);
2575
- writeLocalSharedImportMap();
2576
- return this.resolve(loadSharePath, importer);
2577
- }
2578
- };
2579
- }));
2580
- config.resolve.alias.push(...Object.keys(shared).filter((key) => !(isVinext && key === "react")).map((key) => {
2581
- return command === "build" ? {
2582
- find: new RegExp(`(.*${PREBUILD_TAG}.*)`),
2583
- replacement: function($1) {
2584
- const pkgName = assertModuleFound(PREBUILD_TAG, $1).name;
2585
- return getPrebuildResolutionSource(pkgName, getPreBuildShareItem(pkgName));
2586
- }
2587
- } : {
2588
- find: new RegExp(`(.*${PREBUILD_TAG}.*)`),
2589
- replacement: "$1",
2590
- async customResolver(source, importer) {
2591
- const pkgName = assertModuleFound(PREBUILD_TAG, source).name;
2592
- const importSource = getPrebuildResolutionSource(pkgName, getPreBuildShareItem(pkgName));
2593
- const resolved = await this.resolve(importSource, importer);
2594
- if (!resolved?.id) return;
2595
- const result = resolved.id;
2596
- if (_config && !result.includes(_config.cacheDir)) savePrebuild.set(pkgName, Promise.resolve(result));
2597
- return await this.resolve(await savePrebuild.get(pkgName), importer);
2598
- }
2599
- };
2600
- }));
2601
- },
2602
- configResolved(config) {
2603
- _config = config;
2604
- const isRolldown = getIsRolldown(this);
2605
- Object.keys(shared).forEach((key) => {
2606
- if (key.endsWith("/")) return;
2607
- if (isVinext && key === "react") {
2608
- addUsedShares(key);
2609
- return;
2610
- }
2611
- writeLoadShareModule(key, shared[key], _command, isRolldown);
2612
- if (shared[key].shareConfig.import !== false) writePreBuildLibPath(key, shared[key]);
2613
- addUsedShares(key);
2614
- });
2615
- writeLocalSharedImportMap();
2616
- }
2617
- }];
2618
- }
2619
- //#endregion
2620
2749
  //#region src/plugins/pluginVarRemoteEntry.ts
2621
2750
  const VarRemoteEntry = () => {
2622
2751
  const mfOptions = getNormalizeModuleFederationOptions();
@@ -2783,6 +2912,7 @@ var normalizeOptimizeDeps_default = {
2783
2912
  };
2784
2913
  //#endregion
2785
2914
  //#region src/index.ts
2915
+ const patchedManualChunks = /* @__PURE__ */ new WeakSet();
2786
2916
  const UNSAFE_JS_SOURCE_CHAR_MAP = {
2787
2917
  "<": "\\u003C",
2788
2918
  ">": "\\u003E",
@@ -2827,6 +2957,10 @@ function createEarlyVirtualModulesPlugin(options) {
2827
2957
  config.optimizeDeps = config.optimizeDeps || {};
2828
2958
  config.optimizeDeps.include = config.optimizeDeps.include || [];
2829
2959
  config.optimizeDeps.include.push(virtualRuntimeInitStatus.getImportId());
2960
+ if (isRolldown) {
2961
+ config.optimizeDeps.exclude = config.optimizeDeps.exclude || [];
2962
+ config.optimizeDeps.exclude.push(...Object.keys(remotes || {}));
2963
+ }
2830
2964
  }
2831
2965
  for (const key of Object.keys(shared)) {
2832
2966
  if (key.endsWith("/")) continue;
@@ -2951,17 +3085,20 @@ function federation(mfUserOptions) {
2951
3085
  let warnedAboutManualChunks = false;
2952
3086
  const applyManualChunks = (output) => {
2953
3087
  ensureCodeSplitting(output);
2954
- if (output.manualChunks && !warnedAboutManualChunks) {
3088
+ const isPatchedByPlugin = !!(output.manualChunks && patchedManualChunks.has(output.manualChunks));
3089
+ if (output.manualChunks && !isPatchedByPlugin && !warnedAboutManualChunks) {
2955
3090
  warnedAboutManualChunks = true;
2956
3091
  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.");
2957
3092
  }
2958
- output.manualChunks = function(id) {
3093
+ const mfManualChunks = function(id) {
2959
3094
  if (id.includes(runtimeInitId)) return "runtimeInit";
2960
3095
  if (id.includes("__loadShare__")) {
2961
3096
  const match = id.match(/([^/\\]+__loadShare__[^/\\]+)/);
2962
3097
  return match ? match[1] : "loadShare";
2963
3098
  }
2964
3099
  };
3100
+ patchedManualChunks.add(mfManualChunks);
3101
+ output.manualChunks = mfManualChunks;
2965
3102
  };
2966
3103
  config.build.rollupOptions = config.build.rollupOptions || {};
2967
3104
  if (!Array.isArray(config.build.rollupOptions.output)) applyManualChunks(config.build.rollupOptions.output ||= {});
@@ -3198,37 +3335,55 @@ function federation(mfUserOptions) {
3198
3335
  config.optimizeDeps.needsInterop.push(virtualDir);
3199
3336
  config.optimizeDeps.needsInterop.push(getLocalSharedImportMapPath());
3200
3337
  }
3338
+ const isAstro = hasPackageDependency("astro");
3201
3339
  const resolvedTarget = options.target ?? (config.build?.ssr ? "node" : "web");
3340
+ const envTargetDefineValue = !options.target && isAstro ? "undefined" : JSON.stringify(resolvedTarget);
3202
3341
  if (!config.define) config.define = {};
3203
- if (!("ENV_TARGET" in config.define)) config.define["ENV_TARGET"] = JSON.stringify(resolvedTarget);
3342
+ if (!("ENV_TARGET" in config.define)) config.define["ENV_TARGET"] = envTargetDefineValue;
3204
3343
  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.`);
3205
3344
  }
3206
3345
  },
3207
3346
  ...Manifest(),
3208
3347
  ...VarRemoteEntry(),
3209
- ...Object.keys(options.exposes).length > 0 ? [{
3210
- name: "module-federation-fix-preload",
3211
- enforce: "post",
3212
- apply: "build",
3213
- generateBundle(_, bundle) {
3214
- for (const chunk of Object.values(bundle)) {
3215
- if (chunk.type !== "chunk") continue;
3216
- if (!chunk.code.includes("modulepreload")) continue;
3217
- const chunkDir = pathe.default.dirname(chunk.fileName);
3218
- const prefixToRoot = chunkDir === "." ? "" : `${pathe.default.relative(chunkDir, ".")}/`;
3219
- const replacementExpr = prefixToRoot ? `${escapeUnsafeJsSourceChars(JSON.stringify(prefixToRoot))}+$1` : "$1";
3220
- const replacement = `=function($1){return new URL(${replacementExpr},import.meta.url).href}`;
3221
- const replaced = chunk.code.replace(/=\(?(\w+)(?:,\w+)?\)?\s*=>\s*["'`][^"'`]*["'`]\s*\+\s*\1/, replacement);
3222
- if (replaced !== chunk.code) {
3223
- chunk.code = replaced;
3224
- continue;
3348
+ ...(function() {
3349
+ let disablePreload = false;
3350
+ return Object.keys(options.exposes).length > 0 ? [{
3351
+ name: "module-federation-fix-preload",
3352
+ enforce: "post",
3353
+ apply: "build",
3354
+ config(_config, { command }) {
3355
+ const manifest = options.manifest;
3356
+ const isConsumerProject = Object.keys(options.exposes).length === 0;
3357
+ const getDefaultDisableAssetsAnalyze = (cfgCommand) => cfgCommand === "serve" && isConsumerProject && (typeof manifest !== "object" || !Object.prototype.hasOwnProperty.call(manifest, "disableAssetsAnalyze"));
3358
+ const getConfiguredDisableAssetsAnalyze = (cfgCommand) => {
3359
+ if (typeof manifest === "object" && manifest !== null) {
3360
+ if (Object.prototype.hasOwnProperty.call(manifest, "disableAssetsAnalyze")) return manifest.disableAssetsAnalyze === true;
3361
+ }
3362
+ return getDefaultDisableAssetsAnalyze(cfgCommand);
3363
+ };
3364
+ disablePreload = getConfiguredDisableAssetsAnalyze(command);
3365
+ },
3366
+ generateBundle(_, bundle) {
3367
+ if (disablePreload) return;
3368
+ for (const chunk of Object.values(bundle)) {
3369
+ if (chunk.type !== "chunk") continue;
3370
+ if (!chunk.code.includes("modulepreload")) continue;
3371
+ const chunkDir = pathe.default.dirname(chunk.fileName);
3372
+ const prefixToRoot = chunkDir === "." ? "" : `${pathe.default.relative(chunkDir, ".")}/`;
3373
+ const replacementExpr = prefixToRoot ? `${escapeUnsafeJsSourceChars(JSON.stringify(prefixToRoot))}+$1` : "$1";
3374
+ const replacement = `=function($1){return new URL(${replacementExpr},import.meta.url).href}`;
3375
+ const replaced = chunk.code.replace(/=\(?(\w+)(?:,\w+)?\)?\s*=>\s*["'`][^"'`]*["'`]\s*\+\s*\1/, replacement);
3376
+ if (replaced !== chunk.code) {
3377
+ chunk.code = replaced;
3378
+ continue;
3379
+ }
3380
+ chunk.code = chunk.code.replace(/=function\((\w+)(?:,\w+)?\)\{return\s*["'`][^"'`]*["'`]\s*\+\s*\1\s*\}/, replacement);
3381
+ chunk.code = chunk.code.replace(/=function\((\w+)(?:,\w+)?\)\{return new URL\("\.\.\/"\+\1,import\.meta\.url\)\.href\}/, replacement);
3382
+ chunk.code = chunk.code.replace(/new URL\("\.\.\/"\+(\w+),import\.meta\.url\)\.href/g, `new URL(${replacementExpr},import.meta.url).href`);
3225
3383
  }
3226
- chunk.code = chunk.code.replace(/=function\((\w+)(?:,\w+)?\)\{return\s*["'`][^"'`]*["'`]\s*\+\s*\1\s*\}/, replacement);
3227
- chunk.code = chunk.code.replace(/=function\((\w+)(?:,\w+)?\)\{return new URL\("\.\.\/"\+\1,import\.meta\.url\)\.href\}/, replacement);
3228
- chunk.code = chunk.code.replace(/new URL\("\.\.\/"\+(\w+),import\.meta\.url\)\.href/g, `new URL(${replacementExpr},import.meta.url).href`);
3229
3384
  }
3230
- }
3231
- }] : []
3385
+ }] : [];
3386
+ })()
3232
3387
  ];
3233
3388
  }
3234
3389
  //#endregion