@module-federation/vite 1.16.3 → 1.16.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -59,22 +59,22 @@ With **@module-federation/vite**, the process becomes delightfully simple, you w
59
59
  You can keep Module Federation options in `module-federation.config.ts`.
60
60
 
61
61
  ```ts
62
- import { createModuleFederationConfig } from '@module-federation/vite';
62
+ import { createModuleFederationConfig } from "@module-federation/vite";
63
63
 
64
64
  export default createModuleFederationConfig({
65
- name: 'remote',
66
- filename: 'remoteEntry.js',
65
+ name: "remote",
66
+ filename: "remoteEntry.js",
67
67
  exposes: {
68
- './remote-app': './src/App.vue',
68
+ "./remote-app": "./src/App.vue",
69
69
  },
70
- shared: ['vue'],
70
+ shared: ["vue"],
71
71
  });
72
72
  ```
73
73
 
74
74
  ```ts
75
- import { defineConfig } from 'vite';
76
- import { federation } from '@module-federation/vite';
77
- import moduleFederationConfig from './module-federation.config';
75
+ import { defineConfig } from "vite";
76
+ import { federation } from "@module-federation/vite";
77
+ import moduleFederationConfig from "./module-federation.config";
78
78
 
79
79
  export default defineConfig({
80
80
  plugins: [federation(moduleFederationConfig)],
@@ -175,6 +175,19 @@ export default defineConfig({
175
175
  // It also disables the preload-helper patch used for remotes.
176
176
  // In serve for consumer-only apps, this defaults to true unless explicitly set.
177
177
  disableAssetsAnalyze: false,
178
+ // Optional hook to mutate generated manifest/stats data.
179
+ additionalData: ({ stats }) => {
180
+ stats.metaData.deployEnv = process.env.NODE_ENV;
181
+ stats.metaData.region = "eu";
182
+ stats.custom = {
183
+ buildId: process.env.BUILD_ID,
184
+ };
185
+ },
186
+ // Or return a replacement/merged object.
187
+ // additionalData: ({ stats }) => ({
188
+ // ...stats,
189
+ // custom: { buildId: process.env.BUILD_ID },
190
+ // }),
178
191
  },
179
192
  }),
180
193
  ],
@@ -1,5 +1,5 @@
1
- import { ShareStrategy } from "@module-federation/runtime/types";
2
1
  import { moduleFederationPlugin } from "@module-federation/sdk";
2
+ import { ShareStrategy } from "@module-federation/runtime/types";
3
3
 
4
4
  //#region src/utils/normalizeModuleFederationOptions.d.ts
5
5
  interface RemoteObjectConfig {
@@ -14,6 +14,14 @@ interface PluginManifestOptions {
14
14
  filePath?: string;
15
15
  disableAssetsAnalyze?: boolean;
16
16
  fileName?: string;
17
+ additionalData?: (options: {
18
+ stats: Record<string, unknown>;
19
+ manifest?: Record<string, unknown>;
20
+ pluginOptions: Record<string, unknown>;
21
+ compiler?: unknown;
22
+ compilation?: unknown;
23
+ bundler: 'vite';
24
+ }) => Promise<Record<string, unknown> | void> | Record<string, unknown> | void;
17
25
  }
18
26
  type ModuleFederationOptions = {
19
27
  exposes?: Record<string, string | {
@@ -1,4 +1,4 @@
1
- import { a as getPackageName, c as hasPackageDependency, d as packageNameEncode, f as setPackageDetectionCwd, g as __require, h as mfWarn, i as getPackageDetectionCwd, l as isNuxtProjectRoot, n as getInstalledPackageJson, o as getPackageNameFromNodeModulePath, p as createModuleFederationError, r as getIsRolldown, s as getSharedCacheKey, t as getInstalledPackageEntry, u as packageNameDecode } from "./packageUtils-Bbc6r6__.mjs";
1
+ import { a as getPackageName, c as hasPackageDependency, d as packageNameEncode, f as resolveImportPath, g as mfWarn, i as getPackageDetectionCwd, l as isNuxtProjectRoot, m as createModuleFederationError, n as getInstalledPackageJson, o as getPackageNameFromNodeModulePath, p as setPackageDetectionCwd, r as getIsRolldown, s as getSharedCacheKey, t as getInstalledPackageEntry, u as packageNameDecode } from "./packageUtils-CxYRnFwy.js";
2
2
  import * as fs$1 from "fs";
3
3
  import { existsSync, readFileSync, realpathSync, statSync, writeFileSync } from "fs";
4
4
  import { createRequire } from "module";
@@ -8,6 +8,41 @@ import { version } from "vite";
8
8
  import { createHash } from "node:crypto";
9
9
  import { fileURLToPath } from "url";
10
10
  import { init, parse } from "es-module-lexer";
11
+ //#region src/utils/buildPaths.ts
12
+ /**
13
+ * Rebase an import path for a bootstrap file that moved from root into `dir`.
14
+ *
15
+ * When entryFileNames places entries in a subdirectory (e.g. `static/js/`),
16
+ * the bootstrap file moves there too. Paths that resolved from the HTML root
17
+ * must resolve from the new directory instead.
18
+ *
19
+ * Cases: `/static/js/hostInit.js` → `./hostInit.js` (strip dir prefix)
20
+ * `./src/main.tsx` → `../../src/main.tsx` (climb back up for each dir level)
21
+ * `https://cdn.example.com` → unchanged (absolute URL)
22
+ */
23
+ function rebaseImport(importSrc, dir) {
24
+ if (!dir) return importSrc;
25
+ if (isAbsoluteUrl(importSrc)) return importSrc;
26
+ const absPrefix = "/" + dir;
27
+ if (importSrc.startsWith(absPrefix)) {
28
+ const remainder = importSrc.slice(absPrefix.length);
29
+ return remainder ? "./" + remainder : "./";
30
+ }
31
+ if (importSrc.startsWith(dir)) {
32
+ const remainder = importSrc.slice(dir.length);
33
+ return remainder ? "./" + remainder : "./";
34
+ }
35
+ const upLevels = dir.split("/").filter(Boolean).length;
36
+ const prefix = upLevels > 0 ? "../".repeat(upLevels) : "./";
37
+ if (importSrc.startsWith("./")) return prefix + importSrc.slice(2);
38
+ if (importSrc.startsWith("/")) return prefix + importSrc.slice(1);
39
+ return prefix + importSrc;
40
+ }
41
+ const EXTERNAL_URL_RE = /^(?:[a-z]+:|\/\/)/i;
42
+ function isAbsoluteUrl(src) {
43
+ return EXTERNAL_URL_RE.test(src);
44
+ }
45
+ //#endregion
11
46
  //#region src/utils/codeRewriter.ts
12
47
  const BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
13
48
  var CodeRewriter = class {
@@ -355,9 +390,9 @@ function normalizeManifest(manifest) {
355
390
  let config;
356
391
  let explicitSharedKeys = /* @__PURE__ */ new Set();
357
392
  function resolveRuntimeImplementation() {
358
- const fallback = __require.resolve("@module-federation/runtime");
393
+ const fallback = resolveImportPath("@module-federation/runtime");
359
394
  try {
360
- const packageJsonPath = __require.resolve("@module-federation/runtime/package.json");
395
+ const packageJsonPath = resolveImportPath("@module-federation/runtime/package.json");
361
396
  const packageJson = JSON.parse(fs$1.readFileSync(packageJsonPath, "utf-8"));
362
397
  const importExport = packageJson.exports?.["."];
363
398
  const exportImport = typeof importExport === "object" ? typeof importExport.import === "string" ? importExport.import : importExport.import?.default : void 0;
@@ -860,12 +895,25 @@ function getNamedExportsViaRegex(source, filePath, visited) {
860
895
  const names = /* @__PURE__ */ new Set();
861
896
  visited = visited || /* @__PURE__ */ new Set();
862
897
  if (filePath) visited.add(filePath);
863
- const declRegex = new RegExp(`export\\s+(?:async\\s+)?(?:function(?:\\*\\s*|\\s+\\*?\\s*)|const\\s+|let\\s+|var\\s+|class\\s+)(${JS_IDENTIFIER_PATTERN})`, "gu");
898
+ const declRegex = new RegExp(`export\\s+(?:async\\s+)?(?:function(?:\\*\\s*|\\s+\\*?\\s*)|const\\s+|let\\s+|var\\s+|class\\s+|enum\\s+|namespace\\s+)(${JS_IDENTIFIER_PATTERN})`, "gu");
864
899
  let match;
865
900
  while ((match = declRegex.exec(source)) !== null) {
866
901
  const name = match[1];
867
902
  if (isValidEsmExportName(name)) names.add(name);
868
903
  }
904
+ const destructureRegex = /export\s+(?:const|let|var)\s+(\{[^}]*\}|\[[^\]]*\])\s*=/g;
905
+ const bindingNameRegex = new RegExp(`^(${JS_IDENTIFIER_PATTERN})`, "u");
906
+ while ((match = destructureRegex.exec(source)) !== null) {
907
+ const inner = match[1].slice(1, -1);
908
+ for (const part of inner.split(",")) {
909
+ let token = part.split("=")[0].trim();
910
+ if (token.startsWith("...")) token = token.slice(3).trim();
911
+ if (!token) continue;
912
+ if (token.includes(":")) token = token.slice(token.indexOf(":") + 1).trim();
913
+ const bindingMatch = token.match(bindingNameRegex);
914
+ if (bindingMatch && isValidEsmExportName(bindingMatch[1])) names.add(bindingMatch[1]);
915
+ }
916
+ }
869
917
  const listRegex = /export\s*\{([^}]+)\}/g;
870
918
  const typeOnlySpecifierRegex = new RegExp(`^type\\s+${JS_IDENTIFIER_PATTERN}(?:\\s+as\\s+${JS_IDENTIFIER_PATTERN})?$`, "u");
871
919
  const exportSpecifierRegex = new RegExp(`(?:\\S+\\s+as\\s+)?(${JS_IDENTIFIER_PATTERN})$`, "u");
@@ -1051,7 +1099,7 @@ function getSharedImportSource(pkg, shareItem) {
1051
1099
  const LOAD_SHARE_TAG = "__loadShare__";
1052
1100
  const loadShareCacheMap = {};
1053
1101
  function getLoadShareImportId(pkg, _isRolldown) {
1054
- if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = new VirtualModule(pkg, LOAD_SHARE_TAG, ".mjs");
1102
+ if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = new VirtualModule(pkg, LOAD_SHARE_TAG, ".js");
1055
1103
  return loadShareCacheMap[pkg].getImportId();
1056
1104
  }
1057
1105
  function getLoadShareModulePath(pkg, isRolldown) {
@@ -1120,7 +1168,7 @@ const normalizeLocalShareModuleCode = `const __mfNormalizeShareModule = (mod) =>
1120
1168
  })}
1121
1169
  };`;
1122
1170
  function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
1123
- if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = new VirtualModule(pkg, LOAD_SHARE_TAG, ".mjs");
1171
+ if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = new VirtualModule(pkg, LOAD_SHARE_TAG, ".js");
1124
1172
  const importLine = getRuntimeModuleCacheBootstrapCode();
1125
1173
  const cacheKey = getSharedCacheKey(pkg, shareItem);
1126
1174
  if (shareItem.shareConfig.import === false) {
@@ -1608,7 +1656,7 @@ const LOAD_REMOTE_TAG = "__loadRemote__";
1608
1656
  function getRemoteVirtualModule(remote, command, enableSsrInit = false) {
1609
1657
  const cacheKey = `${remote}__${command}__${enableSsrInit ? "ssr" : "no-ssr"}`;
1610
1658
  if (!cacheRemoteMap[cacheKey]) {
1611
- cacheRemoteMap[cacheKey] = new VirtualModule(remote, LOAD_REMOTE_TAG, ".mjs");
1659
+ cacheRemoteMap[cacheKey] = new VirtualModule(remote, LOAD_REMOTE_TAG, ".js");
1612
1660
  cacheRemoteMap[cacheKey].writeSync(generateRemotes(remote, command, enableSsrInit));
1613
1661
  }
1614
1662
  return cacheRemoteMap[cacheKey];
@@ -1627,6 +1675,7 @@ function getRemoteFromId(id, remotes) {
1627
1675
  }
1628
1676
  function generateRemotes(id, command, enableSsrInit = false) {
1629
1677
  const useReactProxy = hasPackageDependency("react");
1678
+ const useVueProxy = !useReactProxy && hasPackageDependency("vue");
1630
1679
  const options = getNormalizeModuleFederationOptions();
1631
1680
  const isLoadedFirst = options.shareStrategy === "loaded-first";
1632
1681
  const remote = getRemoteFromId(id, options.remotes);
@@ -1640,6 +1689,7 @@ function generateRemotes(id, command, enableSsrInit = false) {
1640
1689
  const reactImportLine = useReactProxy ? `import __mfReactDefault from "react";
1641
1690
  import * as __mfReactNamespace from "react";
1642
1691
  const __mfReact = __mfReactDefault ?? __mfReactNamespace.default ?? __mfReactNamespace;` : "";
1692
+ const vueImportLine = useVueProxy ? `import { defineAsyncComponent as __mfDefineAsyncComponent } from "vue";` : "";
1643
1693
  const importLine = command === "build" ? `${getRuntimeModuleCacheBootstrapCode()}
1644
1694
  import { hostInitPromise as __mfHostInitPromise } from ${JSON.stringify(getHostAutoInitPath())};` : `${getRuntimeInitBootstrapCode(enableSsrInit)}
1645
1695
  const { initPromise, initResolve, initReject, moduleCache: __mfModuleCache } = globalThis[globalKey];
@@ -1674,6 +1724,7 @@ export default exportModule?.__mf_is_remote_proxy ? exportModule : exportModule?
1674
1724
  })`;
1675
1725
  return `
1676
1726
  ${reactImportLine}
1727
+ ${vueImportLine}
1677
1728
  ${importLine}
1678
1729
  ${`
1679
1730
  function __mfStartRemoteLoad() {
@@ -1685,6 +1736,7 @@ export default exportModule?.__mf_is_remote_proxy ? exportModule : exportModule?
1685
1736
  ${registerRemoteCode}
1686
1737
  return runtime.loadRemote(${JSON.stringify(id)});
1687
1738
  })
1739
+ .then((mod) => Promise.resolve(mod?.__mf_remote_dependency_pending).then(() => mod))
1688
1740
  .then((mod) => {
1689
1741
  __mfModuleCache.remote[${JSON.stringify(id)}] = mod;
1690
1742
  delete __mfModuleCache.remote[pendingKey];
@@ -1695,14 +1747,17 @@ export default exportModule?.__mf_is_remote_proxy ? exportModule : exportModule?
1695
1747
  return __mfModuleCache.remote[pendingKey];`}
1696
1748
  }
1697
1749
  function __mfCreateRemoteProxy(pendingPromise) {
1698
- const listeners = new Set();
1699
1750
  const ensurePending = () => {
1700
1751
  pendingPromise ||= __mfStartRemoteLoad();
1701
- pendingPromise?.finally(() => {
1752
+ ${useVueProxy ? "" : `pendingPromise?.finally(() => {
1702
1753
  for (const listener of listeners) listener();
1703
- });
1754
+ });`}
1704
1755
  return pendingPromise;
1705
1756
  };
1757
+ ${useVueProxy ? `return __mfDefineAsyncComponent(() =>
1758
+ ensurePending().then((mod) => mod?.default ?? mod)
1759
+ );` : `
1760
+ const listeners = new Set();
1706
1761
  const getModule = () => __mfModuleCache.remote[${JSON.stringify(id)}];
1707
1762
  const proxyTarget = function (...args) {
1708
1763
  ${useReactProxy ? `const [, setVersion] = __mfReact.useState(0);
@@ -1771,7 +1826,7 @@ export default exportModule?.__mf_is_remote_proxy ? exportModule : exportModule?
1771
1826
  apply(target, thisArg, args) {
1772
1827
  return target.apply(thisArg, args);
1773
1828
  }
1774
- });
1829
+ });`}
1775
1830
  }`}
1776
1831
  let __mfRemotePending;
1777
1832
  let exportModule = __mfModuleCache.remote[${JSON.stringify(id)}]
@@ -1820,7 +1875,8 @@ function patchHashEntryFileNames(config, entryName, fileName) {
1820
1875
  }
1821
1876
  const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClientInjected, skipTransformFor = [] }) => {
1822
1877
  const DEV_HTML_PROXY_PREFIX = "virtual:mf-html-entry-proxy?";
1823
- const ENTRY_BOOTSTRAP_QUERY = "?mf-entry-bootstrap";
1878
+ const ENTRY_BOOTSTRAP_PARAM = "mf-entry-bootstrap";
1879
+ const ENTRY_BOOTSTRAP_QUERY = `?${ENTRY_BOOTSTRAP_PARAM}`;
1824
1880
  const waitsForInit = entryName === "hostInit";
1825
1881
  const getEntryPath = () => typeof entryPath === "function" ? entryPath() : entryPath;
1826
1882
  let devEntryPath = "";
@@ -1832,12 +1888,16 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
1832
1888
  let clientInjected = forceClientInjected ?? false;
1833
1889
  let emittedFileName;
1834
1890
  let skipTransformIds = /* @__PURE__ */ new Set();
1891
+ let bootstrapDir = "";
1835
1892
  function skipSvelteKitSsrBuild() {
1836
1893
  return (_command === "build" || viteConfig?.command === "build") && viteConfig?.build?.ssr && hasPackageDependency("@sveltejs/kit");
1837
1894
  }
1838
1895
  function isSvelteKitServerModule(id) {
1839
1896
  return hasPackageDependency("@sveltejs/kit") && (id.includes(".svelte-kit/generated/") || id.includes("/@sveltejs/kit/src/runtime/server/"));
1840
1897
  }
1898
+ function hasEntryBootstrapParam(id) {
1899
+ return id.includes(ENTRY_BOOTSTRAP_PARAM) || decodeURIComponent(id).includes(ENTRY_BOOTSTRAP_PARAM);
1900
+ }
1841
1901
  function rewriteSvelteKitInlineStart(html, initPath) {
1842
1902
  return html.replace(/<script>([\s\S]*?)<\/script>/gi, (scriptTag, body) => {
1843
1903
  if (!body.includes("kit.start(app, element);") || !body.includes("Promise.all([")) return scriptTag;
@@ -2082,6 +2142,8 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
2082
2142
  if (htmlFileNames.length === 0) return;
2083
2143
  const file = this.getFileName(emitFileId);
2084
2144
  emittedFileName = file;
2145
+ const lastSlash = file.lastIndexOf("/");
2146
+ bootstrapDir = lastSlash !== -1 ? file.slice(0, lastSlash + 1) : "";
2085
2147
  const resolvePath = (htmlFileName) => {
2086
2148
  if (!viteConfig.experimental?.renderBuiltUrl) return viteConfig.base + file;
2087
2149
  const result = viteConfig.experimental.renderBuiltUrl(file, {
@@ -2100,6 +2162,8 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
2100
2162
  }
2101
2163
  return viteConfig.base + file;
2102
2164
  };
2165
+ const basePrefix = viteConfig.base?.replace(/\/$/, "") ?? "";
2166
+ const stripBase = (p) => basePrefix && p.startsWith(basePrefix + "/") ? p.slice(basePrefix.length) : p;
2103
2167
  let bootstrapIndex = 0;
2104
2168
  for (const fileName of htmlFileNames) {
2105
2169
  let htmlAsset = bundle[fileName];
@@ -2110,9 +2174,11 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
2110
2174
  let rewritten = false;
2111
2175
  htmlContent = htmlContent.replace(scriptRegex, (scriptTag, entrySrc) => {
2112
2176
  rewritten = true;
2113
- const bootstrapSource = getSystemBootstrapSource(initPath, entrySrc);
2177
+ const strippedInit = stripBase(initPath);
2178
+ const strippedEntry = stripBase(entrySrc);
2179
+ const bootstrapSource = getSystemBootstrapSource(bootstrapDir ? rebaseImport(strippedInit, bootstrapDir) : initPath, bootstrapDir ? rebaseImport(strippedEntry, bootstrapDir) : entrySrc);
2114
2180
  const bootstrapHash = createHash("sha256").update(bootstrapSource).digest("hex").slice(0, 8);
2115
- const bootstrapFileName = `mf-entry-bootstrap-${bootstrapIndex++}-${bootstrapHash}.js`;
2181
+ const bootstrapFileName = `${bootstrapDir}mf-entry-bootstrap-${bootstrapIndex++}-${bootstrapHash}.js`;
2116
2182
  const bootstrapRef = this.emitFile({
2117
2183
  type: "asset",
2118
2184
  fileName: bootstrapFileName,
@@ -2147,7 +2213,7 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
2147
2213
  transform(code, id) {
2148
2214
  if (skipSvelteKitSsrBuild()) return;
2149
2215
  if (isSvelteKitServerModule(id)) return;
2150
- if (id.includes(ENTRY_BOOTSTRAP_QUERY)) return;
2216
+ if (hasEntryBootstrapParam(id)) return;
2151
2217
  if (normalizeModuleId(id).endsWith(".html")) return;
2152
2218
  if (skipTransformIds.has(resolveProjectId(id))) return;
2153
2219
  const transformCtx = this;
@@ -2175,7 +2241,7 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
2175
2241
  return mapCodeToCodeWithSourcemap(code.replace("vueApp.mount(vueAppRootContainer);", `${injection}vueApp.mount(vueAppRootContainer);`));
2176
2242
  }
2177
2243
  const isHydrationEntryFallback = inject === "entry" && entryFiles.length === 0 && (!htmlFilePath || !fs$1.existsSync(htmlFilePath)) && !clientInjected && !id.includes("node_modules") && (id.startsWith("\0") || /\.(js|ts|mjs|vue|jsx|tsx)(\?|$)/.test(id)) && /hydrateRoot|createRoot|ReactDOM\.render/.test(code);
2178
- const isNuxtClientEntryFallback = _command === "serve" && inject === "entry" && entryFiles.length === 0 && (!htmlFilePath || !fs$1.existsSync(htmlFilePath)) && !clientInjected && !id.includes("node_modules/.vite") && /(?:^|\/)nuxt\/dist\/app\/entry\.async\.js(?:\?|$)/.test(id) && code.includes("entry();");
2244
+ const isNuxtClientEntryFallback = _command === "serve" && inject === "entry" && entryFiles.length === 0 && (!htmlFilePath || !fs$1.existsSync(htmlFilePath)) && !clientInjected && !hasEntryBootstrapParam(id) && !id.includes("node_modules/.vite") && /(?:^|\/)nuxt\/dist\/app\/entry\.async\.js(?:\?|$)/.test(id) && code.includes("entry();");
2179
2245
  if (injectEntry() && entryFiles.some((file) => resolveProjectId(id) === file) || _command === "serve" && inject === "html" && !isVinext && !clientInjected && !id.startsWith("\0") && !id.includes("node_modules") && /\.(js|ts|mjs|vue|jsx|tsx)(\?|$)/.test(id) || isHydrationEntryFallback || isNuxtClientEntryFallback) {
2180
2246
  clientInjected = true;
2181
2247
  if (!waitsForInit || _command === "serve" && inject === "entry" && isHydrationEntryFallback) return mapCodeToCodeWithSourcemap(`import ${JSON.stringify(getEntryPath())};\n` + code);
@@ -3243,41 +3309,44 @@ const Manifest = () => {
3243
3309
  if (req.url?.replace(/\?.*/, "") === (viteConfig.base + mfManifestName).replace(/^\/?/, "/")) {
3244
3310
  res.setHeader("Content-Type", "application/json");
3245
3311
  res.setHeader("Access-Control-Allow-Origin", "*");
3246
- res.end(JSON.stringify({
3247
- ...generateMFManifest({}, disableAssetsAnalyze),
3248
- id: name,
3249
- name,
3250
- metaData: {
3312
+ (async () => {
3313
+ const manifest = await applyManifestAdditionalData({
3314
+ ...generateMFManifest({}, disableAssetsAnalyze),
3315
+ id: name,
3251
3316
  name,
3252
- type: "app",
3253
- buildInfo: {
3254
- buildVersion: getBuildVersion(),
3255
- buildName: name
3256
- },
3257
- remoteEntry: {
3258
- name: filename,
3259
- path: "",
3260
- type: "module"
3261
- },
3262
- ssrRemoteEntry: {
3263
- name: getSsrRemoteEntryFileName(filename),
3264
- path: "/__mf_ssr__/",
3265
- type: "module"
3266
- },
3267
- varRemoteEntry: varFilename ? {
3268
- name: varFilename,
3269
- path: "",
3270
- type: "var"
3271
- } : void 0,
3272
- types: {
3273
- path: "",
3274
- name: ""
3275
- },
3276
- globalName: name,
3277
- pluginVersion: "0.2.5",
3278
- publicPath
3279
- }
3280
- }));
3317
+ metaData: {
3318
+ name,
3319
+ type: "app",
3320
+ buildInfo: {
3321
+ buildVersion: getBuildVersion(),
3322
+ buildName: name
3323
+ },
3324
+ remoteEntry: {
3325
+ name: filename,
3326
+ path: "",
3327
+ type: "module"
3328
+ },
3329
+ ssrRemoteEntry: {
3330
+ name: getSsrRemoteEntryFileName(filename),
3331
+ path: "/__mf_ssr__/",
3332
+ type: "module"
3333
+ },
3334
+ varRemoteEntry: varFilename ? {
3335
+ name: varFilename,
3336
+ path: "",
3337
+ type: "var"
3338
+ } : void 0,
3339
+ types: {
3340
+ path: "",
3341
+ name: ""
3342
+ },
3343
+ globalName: name,
3344
+ pluginVersion: "0.2.5",
3345
+ publicPath
3346
+ }
3347
+ });
3348
+ res.end(JSON.stringify(manifest));
3349
+ })().catch(next);
3281
3350
  } else next();
3282
3351
  });
3283
3352
  }
@@ -3322,16 +3391,20 @@ const Manifest = () => {
3322
3391
  if (mfOptions.bundleAllCSS) addCssAssetsToAllExports(filesMap, allCssAssets);
3323
3392
  filesMap = deduplicateAssets(filesMap);
3324
3393
  }
3394
+ const manifest = await applyManifestAdditionalData(generateMFManifest(filesMap, disableAssetsAnalyze), void 0);
3325
3395
  this.emitFile({
3326
3396
  type: "asset",
3327
3397
  fileName: mfManifestName,
3328
- source: JSON.stringify(generateMFManifest(filesMap, disableAssetsAnalyze))
3329
- });
3330
- if (mfManifestStatsName) this.emitFile({
3331
- type: "asset",
3332
- fileName: mfManifestStatsName,
3333
- source: JSON.stringify(generateMFStats(filesMap, bundle, disableAssetsAnalyze))
3398
+ source: JSON.stringify(manifest)
3334
3399
  });
3400
+ if (mfManifestStatsName) {
3401
+ const stats = await applyManifestAdditionalData(generateMFStats(manifest, filesMap, bundle, disableAssetsAnalyze), manifest);
3402
+ this.emitFile({
3403
+ type: "asset",
3404
+ fileName: mfManifestStatsName,
3405
+ source: JSON.stringify(stats)
3406
+ });
3407
+ }
3335
3408
  }
3336
3409
  }];
3337
3410
  /**
@@ -3430,8 +3503,7 @@ const Manifest = () => {
3430
3503
  ...disableAssetsAnalyze ? {} : { exposes }
3431
3504
  };
3432
3505
  }
3433
- function generateMFStats(preloadMap, bundle, disableAssetsAnalyze = false) {
3434
- const baseManifest = generateMFManifest(preloadMap, disableAssetsAnalyze);
3506
+ function generateMFStats(manifest, preloadMap, bundle, disableAssetsAnalyze = false) {
3435
3507
  const bundleSummary = Object.entries(bundle).map(([fileName, chunkOrAsset]) => ({
3436
3508
  fileName,
3437
3509
  type: chunkOrAsset.type,
@@ -3439,11 +3511,22 @@ const Manifest = () => {
3439
3511
  size: typeof chunkOrAsset.code === "string" ? chunkOrAsset.code.length : chunkOrAsset.source?.length || void 0
3440
3512
  }));
3441
3513
  return {
3442
- ...baseManifest,
3514
+ ...manifest,
3443
3515
  buildOutput: bundleSummary,
3444
3516
  ...disableAssetsAnalyze ? {} : { assetAnalysis: preloadMap }
3445
3517
  };
3446
3518
  }
3519
+ async function applyManifestAdditionalData(stats, manifest) {
3520
+ if (typeof manifestOptions !== "object" || typeof manifestOptions.additionalData !== "function") return stats;
3521
+ return await manifestOptions.additionalData({
3522
+ stats,
3523
+ manifest,
3524
+ pluginOptions: mfOptions,
3525
+ compiler: void 0,
3526
+ compilation: void 0,
3527
+ bundler: "vite"
3528
+ }) || stats;
3529
+ }
3447
3530
  };
3448
3531
  function getStatsFileName(manifestFileName) {
3449
3532
  const parsed = path$1.parse(manifestFileName);
@@ -3975,6 +4058,7 @@ function applyRewrites(code, imports, id) {
3975
4058
  let changed = false;
3976
4059
  let counter = 0;
3977
4060
  let namedProxyHelperDeclared = false;
4061
+ const dependencyPendingIds = [];
3978
4062
  const namedProxyHelper = `function __mfCreateNamedRemoteProxy(ns, key) {
3979
4063
  const target = function (...args) {
3980
4064
  const value = ns[key];
@@ -3996,12 +4080,18 @@ function applyRewrites(code, imports, id) {
3996
4080
  for (const imp of imports) switch (imp.kind) {
3997
4081
  case "static": {
3998
4082
  const src = JSON.stringify(imp.source);
3999
- if (imp.namespaceLocal && !imp.defaultLocal && imp.named.length === 0) ms.overwrite(imp.start, imp.end, `import { __moduleExports as ${imp.namespaceLocal} } from ${src};`);
4000
- else {
4083
+ if (imp.namespaceLocal && !imp.defaultLocal && imp.named.length === 0) {
4084
+ const pendingId = `${imp.namespaceLocal}__mf_pending`;
4085
+ dependencyPendingIds.push(pendingId);
4086
+ ms.overwrite(imp.start, imp.end, `import { __moduleExports as ${imp.namespaceLocal}, __mf_remote_pending as ${pendingId} } from ${src};`);
4087
+ } else {
4001
4088
  const nsId = `__mf_ns_${counter++}`;
4089
+ const pendingId = `${nsId}_pending`;
4090
+ dependencyPendingIds.push(pendingId);
4002
4091
  const importParts = [];
4003
4092
  if (imp.defaultLocal) importParts.push(`default as ${imp.defaultLocal}`);
4004
4093
  importParts.push(`__moduleExports as ${nsId}`);
4094
+ importParts.push(`__mf_remote_pending as ${pendingId}`);
4005
4095
  let rewrite = `import { ${importParts.join(", ")} } from ${src};`;
4006
4096
  if (imp.named.length > 0) {
4007
4097
  const isProxyId = `__mf_is_proxy_${counter++}`;
@@ -4027,6 +4117,8 @@ function applyRewrites(code, imports, id) {
4027
4117
  case "reexport": {
4028
4118
  const src = JSON.stringify(imp.source);
4029
4119
  const nsId = `__mf_ns_${counter++}`;
4120
+ const pendingId = `${nsId}_pending`;
4121
+ dependencyPendingIds.push(pendingId);
4030
4122
  const vars = imp.specifiers.map((s) => {
4031
4123
  const tmp = `__mf_re_${counter++}`;
4032
4124
  return {
@@ -4034,10 +4126,11 @@ function applyRewrites(code, imports, id) {
4034
4126
  tmp
4035
4127
  };
4036
4128
  });
4037
- const importLine = `import { __moduleExports as ${nsId} } from ${src};`;
4038
- const varLines = vars.map((v) => `const ${v.tmp} = ${nsId}[${JSON.stringify(v.local)}];`).join("\n");
4129
+ const importLine = `import { __moduleExports as ${nsId}, __mf_remote_pending as ${pendingId} } from ${src};`;
4130
+ const varLines = vars.map((v) => `let ${v.tmp} = ${nsId}[${JSON.stringify(v.local)}];`).join("\n");
4131
+ const syncLine = `${pendingId}.then(() => {\n${vars.map((v) => `${v.tmp} = ${nsId}[${JSON.stringify(v.local)}];`).join("\n")}\n});`;
4039
4132
  const exportLine = `export { ${vars.map((v) => `${v.tmp} as ${v.exported}`).join(", ")} };`;
4040
- ms.overwrite(imp.start, imp.end, `${importLine}\n${varLines}\n${exportLine}`);
4133
+ ms.overwrite(imp.start, imp.end, `${importLine}\n${varLines}\n${syncLine}\n${exportLine}`);
4041
4134
  changed = true;
4042
4135
  break;
4043
4136
  }
@@ -4050,6 +4143,7 @@ function applyRewrites(code, imports, id) {
4050
4143
  break;
4051
4144
  }
4052
4145
  if (!changed) return;
4146
+ if (dependencyPendingIds.length > 0) ms.overwrite(code.length, code.length, `\nexport const __mf_remote_dependency_pending = Promise.all([${dependencyPendingIds.join(", ")}]);`);
4053
4147
  return {
4054
4148
  code: ms.toString(),
4055
4149
  map: ms.generateMap(id)
@@ -4899,7 +4993,6 @@ export default __mfShared.default ?? __mfShared;`
4899
4993
  if (options.runtimePlugins.some((p) => {
4900
4994
  return (typeof p === "string" ? p : p[0]) === "@module-federation/vite/ssrEntryLoader";
4901
4995
  })) return;
4902
- const pluginRequire = createRequire(import.meta.url);
4903
4996
  const projectRequire = createRequire(new URL(`file://${config.root}/package.json`));
4904
4997
  const sharedKeys = Object.keys(options.shared ?? {});
4905
4998
  const commonSharedPkgs = [
@@ -4917,12 +5010,12 @@ export default __mfShared.default ?? __mfShared;`
4917
5010
  resolvedShared[pkg] = projectRequire.resolve(pkg);
4918
5011
  } catch {
4919
5012
  try {
4920
- resolvedShared[pkg] = pluginRequire.resolve(pkg);
5013
+ resolvedShared[pkg] = resolveImportPath(pkg);
4921
5014
  } catch {}
4922
5015
  }
4923
5016
  const ssrEntryLoaderSpecifier = "@module-federation/vite/ssrEntryLoader";
4924
5017
  try {
4925
- pluginRequire.resolve(ssrEntryLoaderSpecifier);
5018
+ resolveImportPath(ssrEntryLoaderSpecifier);
4926
5019
  options.runtimePlugins.push([ssrEntryLoaderSpecifier, { resolvedShared }]);
4927
5020
  } catch {}
4928
5021
  }
@@ -4931,7 +5024,7 @@ export default __mfShared.default ?? __mfShared;`
4931
5024
  const SSR_ONLY_PLUGINS = new Set(["@module-federation/vite/ssrEntryLoader"]);
4932
5025
  function loadPluginDts(options) {
4933
5026
  if (options.dts === false) return [];
4934
- return [import("./pluginDts-DDx4TPN8.mjs").then(({ default: pluginDts }) => pluginDts(options))];
5027
+ return [import("./pluginDts-Bgdw5ODE.js").then(({ default: pluginDts }) => pluginDts(options))];
4935
5028
  }
4936
5029
  function federation(mfUserOptions) {
4937
5030
  if (isTestEnv()) return [];
@@ -5251,11 +5344,9 @@ function federation(mfUserOptions) {
5251
5344
  _options: options,
5252
5345
  config(config, { command: _command }) {
5253
5346
  const isRolldown = getIsRolldown(this);
5254
- let implementation = options.implementation;
5255
- if (isRolldown) implementation = implementation.replace(/\.cjs(\.js)?$/, ".js");
5256
5347
  appendResolveAlias(config, {
5257
5348
  find: "@module-federation/runtime",
5258
- replacement: implementation
5349
+ replacement: options.implementation
5259
5350
  });
5260
5351
  config.build ||= {};
5261
5352
  config.build.commonjsOptions ||= {};
@@ -1,10 +1,7 @@
1
- import { createRequire } from "node:module";
2
1
  import { existsSync, readFileSync, readdirSync } from "fs";
3
- import { createRequire as createRequire$1 } from "module";
2
+ import { createRequire } from "module";
4
3
  import path from "pathe";
5
- //#region \0rolldown/runtime.js
6
- var __require = /* @__PURE__ */ createRequire(import.meta.url);
7
- //#endregion
4
+ import { fileURLToPath } from "url";
8
5
  //#region src/utils/logger.ts
9
6
  const MODULE_FEDERATION_LOG_PREFIX = "[Module Federation]";
10
7
  function formatModuleFederationMessage(message) {
@@ -49,6 +46,17 @@ function setPackageDetectionCwd(cwd) {
49
46
  function getPackageDetectionCwd() {
50
47
  return packageDetectionCwd || process.cwd();
51
48
  }
49
+ function resolveImportPath(specifier) {
50
+ const resolved = import.meta.resolve(specifier);
51
+ if (!resolved.startsWith("file:")) return resolved;
52
+ const filePath = fileURLToPath(resolved);
53
+ if (!existsSync(filePath)) {
54
+ const error = /* @__PURE__ */ new Error(`Cannot find module '${specifier}'`);
55
+ error.code = "MODULE_NOT_FOUND";
56
+ throw error;
57
+ }
58
+ return filePath;
59
+ }
52
60
  const DEFAULT_EXPORT_CONDITIONS = [
53
61
  "browser",
54
62
  "import",
@@ -158,7 +166,7 @@ function getInstalledPackageJson(pkg, opts) {
158
166
  }
159
167
  };
160
168
  try {
161
- const projectRequire = createRequire$1(new URL(`file://${path.join(cwd, "package.json")}`));
169
+ const projectRequire = createRequire(new URL(`file://${path.join(cwd, "package.json")}`));
162
170
  let resolvedPath;
163
171
  if (opts?.fromResolvedEntry) resolvedPath = opts.fromResolvedEntry;
164
172
  else try {
@@ -204,7 +212,7 @@ function getInstalledPackageEntry(pkg, opts) {
204
212
  const cwd = opts?.cwd || getPackageDetectionCwd();
205
213
  const packageName = opts?.packageName || getPackageName(pkg);
206
214
  if (pkg !== packageName && opts?.resolveSubpathWithRequire !== false) try {
207
- return createRequire$1(new URL(`file://${path.join(cwd, "package.json")}`)).resolve(pkg);
215
+ return createRequire(new URL(`file://${path.join(cwd, "package.json")}`)).resolve(pkg);
208
216
  } catch {}
209
217
  const packageJson = installed.packageJson;
210
218
  const explicitEntry = resolveExportsEntry(getPackageExportsTarget(pkg, packageName, packageJson.exports), opts?.conditions) || (typeof packageJson.module === "string" ? packageJson.module : void 0) || (typeof packageJson.main === "string" ? packageJson.main : void 0) || "index.js";
@@ -250,4 +258,4 @@ function hasPackageDependency(dependencyName, cwd = packageDetectionCwd || proce
250
258
  }
251
259
  }
252
260
  //#endregion
253
- export { getPackageName as a, hasPackageDependency as c, packageNameEncode as d, setPackageDetectionCwd as f, __require as g, mfWarn as h, getPackageDetectionCwd as i, isNuxtProjectRoot as l, mfError as m, getInstalledPackageJson as n, getPackageNameFromNodeModulePath as o, createModuleFederationError as p, getIsRolldown as r, getSharedCacheKey as s, getInstalledPackageEntry as t, packageNameDecode as u };
261
+ export { getPackageName as a, hasPackageDependency as c, packageNameEncode as d, resolveImportPath as f, mfWarn as g, mfError as h, getPackageDetectionCwd as i, isNuxtProjectRoot as l, createModuleFederationError as m, getInstalledPackageJson as n, getPackageNameFromNodeModulePath as o, setPackageDetectionCwd as p, getIsRolldown as r, getSharedCacheKey as s, getInstalledPackageEntry as t, packageNameDecode as u };
@@ -1,4 +1,4 @@
1
- import { c as hasPackageDependency, g as __require, m as mfError, p as createModuleFederationError } from "./packageUtils-Bbc6r6__.mjs";
1
+ import { c as hasPackageDependency, f as resolveImportPath, h as mfError, m as createModuleFederationError } from "./packageUtils-CxYRnFwy.js";
2
2
  import fs from "fs";
3
3
  import * as path$1 from "pathe";
4
4
  import { normalizeOptions } from "@module-federation/sdk";
@@ -14,7 +14,7 @@ const DYNAMIC_HINTS_PLUGIN = "@module-federation/dts-plugin/dynamic-remote-type-
14
14
  const getIPv4 = () => process.env["FEDERATION_IPV4"] || "127.0.0.1";
15
15
  const DEV_TYPES_FOLDER = ".dev-server";
16
16
  const DEFAULT_PUBLIC_TYPES_FOLDER = "@mf-types";
17
- const forkDevWorkerPath = __require.resolve("@module-federation/dts-plugin/dist/fork-dev-worker.js");
17
+ const forkDevWorkerPath = resolveImportPath("@module-federation/dts-plugin/dist/fork-dev-worker.js");
18
18
  var DevWorker = class {
19
19
  worker = rpc.createRpcWorker(forkDevWorkerPath, {}, void 0, false);
20
20
  constructor(options) {
@@ -205,9 +205,9 @@ function transformSsrCode(code, base, sharedPkgMap) {
205
205
  return code;
206
206
  }
207
207
  /**
208
- * Fetch an HTTP ESM module, transform it, write it to a temp .mjs file and
208
+ * Fetch an HTTP ESM module, transform it, write it to a temp .js file and
209
209
  * return the file path. Recursively does the same for HTTP transitive imports
210
- * so that `import('file:///...temp.mjs')` can resolve them.
210
+ * so that `import('file:///...temp.js')` can resolve them.
211
211
  */
212
212
  async function fetchEsmToTempFile(url, tmpDir, visited, sharedPkgMap) {
213
213
  if (visited.has(url)) return visited.get(url);
@@ -229,7 +229,7 @@ async function fetchEsmToTempFile(url, tmpDir, visited, sharedPkgMap) {
229
229
  const { createHash } = await _crypto();
230
230
  const { join } = await _path();
231
231
  const { writeFileSync } = await _fs();
232
- const tmpFile = join(tmpDir, `${createHash("sha1").update(url).digest("hex").slice(0, 12)}.mjs`);
232
+ const tmpFile = join(tmpDir, `${createHash("sha1").update(url).digest("hex").slice(0, 12)}.js`);
233
233
  writeFileSync(tmpFile, code, "utf8");
234
234
  visited.set(url, tmpFile);
235
235
  return tmpFile;