@module-federation/vite 1.16.4 → 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;
@@ -1064,7 +1099,7 @@ function getSharedImportSource(pkg, shareItem) {
1064
1099
  const LOAD_SHARE_TAG = "__loadShare__";
1065
1100
  const loadShareCacheMap = {};
1066
1101
  function getLoadShareImportId(pkg, _isRolldown) {
1067
- 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");
1068
1103
  return loadShareCacheMap[pkg].getImportId();
1069
1104
  }
1070
1105
  function getLoadShareModulePath(pkg, isRolldown) {
@@ -1133,7 +1168,7 @@ const normalizeLocalShareModuleCode = `const __mfNormalizeShareModule = (mod) =>
1133
1168
  })}
1134
1169
  };`;
1135
1170
  function writeLoadShareModule(pkg, shareItem, command, _isRolldown) {
1136
- 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");
1137
1172
  const importLine = getRuntimeModuleCacheBootstrapCode();
1138
1173
  const cacheKey = getSharedCacheKey(pkg, shareItem);
1139
1174
  if (shareItem.shareConfig.import === false) {
@@ -1621,7 +1656,7 @@ const LOAD_REMOTE_TAG = "__loadRemote__";
1621
1656
  function getRemoteVirtualModule(remote, command, enableSsrInit = false) {
1622
1657
  const cacheKey = `${remote}__${command}__${enableSsrInit ? "ssr" : "no-ssr"}`;
1623
1658
  if (!cacheRemoteMap[cacheKey]) {
1624
- cacheRemoteMap[cacheKey] = new VirtualModule(remote, LOAD_REMOTE_TAG, ".mjs");
1659
+ cacheRemoteMap[cacheKey] = new VirtualModule(remote, LOAD_REMOTE_TAG, ".js");
1625
1660
  cacheRemoteMap[cacheKey].writeSync(generateRemotes(remote, command, enableSsrInit));
1626
1661
  }
1627
1662
  return cacheRemoteMap[cacheKey];
@@ -1640,6 +1675,7 @@ function getRemoteFromId(id, remotes) {
1640
1675
  }
1641
1676
  function generateRemotes(id, command, enableSsrInit = false) {
1642
1677
  const useReactProxy = hasPackageDependency("react");
1678
+ const useVueProxy = !useReactProxy && hasPackageDependency("vue");
1643
1679
  const options = getNormalizeModuleFederationOptions();
1644
1680
  const isLoadedFirst = options.shareStrategy === "loaded-first";
1645
1681
  const remote = getRemoteFromId(id, options.remotes);
@@ -1653,6 +1689,7 @@ function generateRemotes(id, command, enableSsrInit = false) {
1653
1689
  const reactImportLine = useReactProxy ? `import __mfReactDefault from "react";
1654
1690
  import * as __mfReactNamespace from "react";
1655
1691
  const __mfReact = __mfReactDefault ?? __mfReactNamespace.default ?? __mfReactNamespace;` : "";
1692
+ const vueImportLine = useVueProxy ? `import { defineAsyncComponent as __mfDefineAsyncComponent } from "vue";` : "";
1656
1693
  const importLine = command === "build" ? `${getRuntimeModuleCacheBootstrapCode()}
1657
1694
  import { hostInitPromise as __mfHostInitPromise } from ${JSON.stringify(getHostAutoInitPath())};` : `${getRuntimeInitBootstrapCode(enableSsrInit)}
1658
1695
  const { initPromise, initResolve, initReject, moduleCache: __mfModuleCache } = globalThis[globalKey];
@@ -1687,6 +1724,7 @@ export default exportModule?.__mf_is_remote_proxy ? exportModule : exportModule?
1687
1724
  })`;
1688
1725
  return `
1689
1726
  ${reactImportLine}
1727
+ ${vueImportLine}
1690
1728
  ${importLine}
1691
1729
  ${`
1692
1730
  function __mfStartRemoteLoad() {
@@ -1698,6 +1736,7 @@ export default exportModule?.__mf_is_remote_proxy ? exportModule : exportModule?
1698
1736
  ${registerRemoteCode}
1699
1737
  return runtime.loadRemote(${JSON.stringify(id)});
1700
1738
  })
1739
+ .then((mod) => Promise.resolve(mod?.__mf_remote_dependency_pending).then(() => mod))
1701
1740
  .then((mod) => {
1702
1741
  __mfModuleCache.remote[${JSON.stringify(id)}] = mod;
1703
1742
  delete __mfModuleCache.remote[pendingKey];
@@ -1708,14 +1747,17 @@ export default exportModule?.__mf_is_remote_proxy ? exportModule : exportModule?
1708
1747
  return __mfModuleCache.remote[pendingKey];`}
1709
1748
  }
1710
1749
  function __mfCreateRemoteProxy(pendingPromise) {
1711
- const listeners = new Set();
1712
1750
  const ensurePending = () => {
1713
1751
  pendingPromise ||= __mfStartRemoteLoad();
1714
- pendingPromise?.finally(() => {
1752
+ ${useVueProxy ? "" : `pendingPromise?.finally(() => {
1715
1753
  for (const listener of listeners) listener();
1716
- });
1754
+ });`}
1717
1755
  return pendingPromise;
1718
1756
  };
1757
+ ${useVueProxy ? `return __mfDefineAsyncComponent(() =>
1758
+ ensurePending().then((mod) => mod?.default ?? mod)
1759
+ );` : `
1760
+ const listeners = new Set();
1719
1761
  const getModule = () => __mfModuleCache.remote[${JSON.stringify(id)}];
1720
1762
  const proxyTarget = function (...args) {
1721
1763
  ${useReactProxy ? `const [, setVersion] = __mfReact.useState(0);
@@ -1784,7 +1826,7 @@ export default exportModule?.__mf_is_remote_proxy ? exportModule : exportModule?
1784
1826
  apply(target, thisArg, args) {
1785
1827
  return target.apply(thisArg, args);
1786
1828
  }
1787
- });
1829
+ });`}
1788
1830
  }`}
1789
1831
  let __mfRemotePending;
1790
1832
  let exportModule = __mfModuleCache.remote[${JSON.stringify(id)}]
@@ -1846,6 +1888,7 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
1846
1888
  let clientInjected = forceClientInjected ?? false;
1847
1889
  let emittedFileName;
1848
1890
  let skipTransformIds = /* @__PURE__ */ new Set();
1891
+ let bootstrapDir = "";
1849
1892
  function skipSvelteKitSsrBuild() {
1850
1893
  return (_command === "build" || viteConfig?.command === "build") && viteConfig?.build?.ssr && hasPackageDependency("@sveltejs/kit");
1851
1894
  }
@@ -2099,6 +2142,8 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
2099
2142
  if (htmlFileNames.length === 0) return;
2100
2143
  const file = this.getFileName(emitFileId);
2101
2144
  emittedFileName = file;
2145
+ const lastSlash = file.lastIndexOf("/");
2146
+ bootstrapDir = lastSlash !== -1 ? file.slice(0, lastSlash + 1) : "";
2102
2147
  const resolvePath = (htmlFileName) => {
2103
2148
  if (!viteConfig.experimental?.renderBuiltUrl) return viteConfig.base + file;
2104
2149
  const result = viteConfig.experimental.renderBuiltUrl(file, {
@@ -2117,6 +2162,8 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
2117
2162
  }
2118
2163
  return viteConfig.base + file;
2119
2164
  };
2165
+ const basePrefix = viteConfig.base?.replace(/\/$/, "") ?? "";
2166
+ const stripBase = (p) => basePrefix && p.startsWith(basePrefix + "/") ? p.slice(basePrefix.length) : p;
2120
2167
  let bootstrapIndex = 0;
2121
2168
  for (const fileName of htmlFileNames) {
2122
2169
  let htmlAsset = bundle[fileName];
@@ -2127,9 +2174,11 @@ const addEntry = ({ entryName, entryPath, fileName, inject = "entry", forceClien
2127
2174
  let rewritten = false;
2128
2175
  htmlContent = htmlContent.replace(scriptRegex, (scriptTag, entrySrc) => {
2129
2176
  rewritten = true;
2130
- 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);
2131
2180
  const bootstrapHash = createHash("sha256").update(bootstrapSource).digest("hex").slice(0, 8);
2132
- const bootstrapFileName = `mf-entry-bootstrap-${bootstrapIndex++}-${bootstrapHash}.js`;
2181
+ const bootstrapFileName = `${bootstrapDir}mf-entry-bootstrap-${bootstrapIndex++}-${bootstrapHash}.js`;
2133
2182
  const bootstrapRef = this.emitFile({
2134
2183
  type: "asset",
2135
2184
  fileName: bootstrapFileName,
@@ -3260,41 +3309,44 @@ const Manifest = () => {
3260
3309
  if (req.url?.replace(/\?.*/, "") === (viteConfig.base + mfManifestName).replace(/^\/?/, "/")) {
3261
3310
  res.setHeader("Content-Type", "application/json");
3262
3311
  res.setHeader("Access-Control-Allow-Origin", "*");
3263
- res.end(JSON.stringify({
3264
- ...generateMFManifest({}, disableAssetsAnalyze),
3265
- id: name,
3266
- name,
3267
- metaData: {
3312
+ (async () => {
3313
+ const manifest = await applyManifestAdditionalData({
3314
+ ...generateMFManifest({}, disableAssetsAnalyze),
3315
+ id: name,
3268
3316
  name,
3269
- type: "app",
3270
- buildInfo: {
3271
- buildVersion: getBuildVersion(),
3272
- buildName: name
3273
- },
3274
- remoteEntry: {
3275
- name: filename,
3276
- path: "",
3277
- type: "module"
3278
- },
3279
- ssrRemoteEntry: {
3280
- name: getSsrRemoteEntryFileName(filename),
3281
- path: "/__mf_ssr__/",
3282
- type: "module"
3283
- },
3284
- varRemoteEntry: varFilename ? {
3285
- name: varFilename,
3286
- path: "",
3287
- type: "var"
3288
- } : void 0,
3289
- types: {
3290
- path: "",
3291
- name: ""
3292
- },
3293
- globalName: name,
3294
- pluginVersion: "0.2.5",
3295
- publicPath
3296
- }
3297
- }));
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);
3298
3350
  } else next();
3299
3351
  });
3300
3352
  }
@@ -3339,16 +3391,20 @@ const Manifest = () => {
3339
3391
  if (mfOptions.bundleAllCSS) addCssAssetsToAllExports(filesMap, allCssAssets);
3340
3392
  filesMap = deduplicateAssets(filesMap);
3341
3393
  }
3394
+ const manifest = await applyManifestAdditionalData(generateMFManifest(filesMap, disableAssetsAnalyze), void 0);
3342
3395
  this.emitFile({
3343
3396
  type: "asset",
3344
3397
  fileName: mfManifestName,
3345
- source: JSON.stringify(generateMFManifest(filesMap, disableAssetsAnalyze))
3346
- });
3347
- if (mfManifestStatsName) this.emitFile({
3348
- type: "asset",
3349
- fileName: mfManifestStatsName,
3350
- source: JSON.stringify(generateMFStats(filesMap, bundle, disableAssetsAnalyze))
3398
+ source: JSON.stringify(manifest)
3351
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
+ }
3352
3408
  }
3353
3409
  }];
3354
3410
  /**
@@ -3447,8 +3503,7 @@ const Manifest = () => {
3447
3503
  ...disableAssetsAnalyze ? {} : { exposes }
3448
3504
  };
3449
3505
  }
3450
- function generateMFStats(preloadMap, bundle, disableAssetsAnalyze = false) {
3451
- const baseManifest = generateMFManifest(preloadMap, disableAssetsAnalyze);
3506
+ function generateMFStats(manifest, preloadMap, bundle, disableAssetsAnalyze = false) {
3452
3507
  const bundleSummary = Object.entries(bundle).map(([fileName, chunkOrAsset]) => ({
3453
3508
  fileName,
3454
3509
  type: chunkOrAsset.type,
@@ -3456,11 +3511,22 @@ const Manifest = () => {
3456
3511
  size: typeof chunkOrAsset.code === "string" ? chunkOrAsset.code.length : chunkOrAsset.source?.length || void 0
3457
3512
  }));
3458
3513
  return {
3459
- ...baseManifest,
3514
+ ...manifest,
3460
3515
  buildOutput: bundleSummary,
3461
3516
  ...disableAssetsAnalyze ? {} : { assetAnalysis: preloadMap }
3462
3517
  };
3463
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
+ }
3464
3530
  };
3465
3531
  function getStatsFileName(manifestFileName) {
3466
3532
  const parsed = path$1.parse(manifestFileName);
@@ -3992,6 +4058,7 @@ function applyRewrites(code, imports, id) {
3992
4058
  let changed = false;
3993
4059
  let counter = 0;
3994
4060
  let namedProxyHelperDeclared = false;
4061
+ const dependencyPendingIds = [];
3995
4062
  const namedProxyHelper = `function __mfCreateNamedRemoteProxy(ns, key) {
3996
4063
  const target = function (...args) {
3997
4064
  const value = ns[key];
@@ -4013,12 +4080,18 @@ function applyRewrites(code, imports, id) {
4013
4080
  for (const imp of imports) switch (imp.kind) {
4014
4081
  case "static": {
4015
4082
  const src = JSON.stringify(imp.source);
4016
- if (imp.namespaceLocal && !imp.defaultLocal && imp.named.length === 0) ms.overwrite(imp.start, imp.end, `import { __moduleExports as ${imp.namespaceLocal} } from ${src};`);
4017
- 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 {
4018
4088
  const nsId = `__mf_ns_${counter++}`;
4089
+ const pendingId = `${nsId}_pending`;
4090
+ dependencyPendingIds.push(pendingId);
4019
4091
  const importParts = [];
4020
4092
  if (imp.defaultLocal) importParts.push(`default as ${imp.defaultLocal}`);
4021
4093
  importParts.push(`__moduleExports as ${nsId}`);
4094
+ importParts.push(`__mf_remote_pending as ${pendingId}`);
4022
4095
  let rewrite = `import { ${importParts.join(", ")} } from ${src};`;
4023
4096
  if (imp.named.length > 0) {
4024
4097
  const isProxyId = `__mf_is_proxy_${counter++}`;
@@ -4044,6 +4117,8 @@ function applyRewrites(code, imports, id) {
4044
4117
  case "reexport": {
4045
4118
  const src = JSON.stringify(imp.source);
4046
4119
  const nsId = `__mf_ns_${counter++}`;
4120
+ const pendingId = `${nsId}_pending`;
4121
+ dependencyPendingIds.push(pendingId);
4047
4122
  const vars = imp.specifiers.map((s) => {
4048
4123
  const tmp = `__mf_re_${counter++}`;
4049
4124
  return {
@@ -4051,10 +4126,11 @@ function applyRewrites(code, imports, id) {
4051
4126
  tmp
4052
4127
  };
4053
4128
  });
4054
- const importLine = `import { __moduleExports as ${nsId} } from ${src};`;
4055
- 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});`;
4056
4132
  const exportLine = `export { ${vars.map((v) => `${v.tmp} as ${v.exported}`).join(", ")} };`;
4057
- 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}`);
4058
4134
  changed = true;
4059
4135
  break;
4060
4136
  }
@@ -4067,6 +4143,7 @@ function applyRewrites(code, imports, id) {
4067
4143
  break;
4068
4144
  }
4069
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(", ")}]);`);
4070
4147
  return {
4071
4148
  code: ms.toString(),
4072
4149
  map: ms.generateMap(id)
@@ -4916,7 +4993,6 @@ export default __mfShared.default ?? __mfShared;`
4916
4993
  if (options.runtimePlugins.some((p) => {
4917
4994
  return (typeof p === "string" ? p : p[0]) === "@module-federation/vite/ssrEntryLoader";
4918
4995
  })) return;
4919
- const pluginRequire = createRequire(import.meta.url);
4920
4996
  const projectRequire = createRequire(new URL(`file://${config.root}/package.json`));
4921
4997
  const sharedKeys = Object.keys(options.shared ?? {});
4922
4998
  const commonSharedPkgs = [
@@ -4934,12 +5010,12 @@ export default __mfShared.default ?? __mfShared;`
4934
5010
  resolvedShared[pkg] = projectRequire.resolve(pkg);
4935
5011
  } catch {
4936
5012
  try {
4937
- resolvedShared[pkg] = pluginRequire.resolve(pkg);
5013
+ resolvedShared[pkg] = resolveImportPath(pkg);
4938
5014
  } catch {}
4939
5015
  }
4940
5016
  const ssrEntryLoaderSpecifier = "@module-federation/vite/ssrEntryLoader";
4941
5017
  try {
4942
- pluginRequire.resolve(ssrEntryLoaderSpecifier);
5018
+ resolveImportPath(ssrEntryLoaderSpecifier);
4943
5019
  options.runtimePlugins.push([ssrEntryLoaderSpecifier, { resolvedShared }]);
4944
5020
  } catch {}
4945
5021
  }
@@ -4948,7 +5024,7 @@ export default __mfShared.default ?? __mfShared;`
4948
5024
  const SSR_ONLY_PLUGINS = new Set(["@module-federation/vite/ssrEntryLoader"]);
4949
5025
  function loadPluginDts(options) {
4950
5026
  if (options.dts === false) return [];
4951
- return [import("./pluginDts-DDx4TPN8.mjs").then(({ default: pluginDts }) => pluginDts(options))];
5027
+ return [import("./pluginDts-Bgdw5ODE.js").then(({ default: pluginDts }) => pluginDts(options))];
4952
5028
  }
4953
5029
  function federation(mfUserOptions) {
4954
5030
  if (isTestEnv()) return [];
@@ -5268,11 +5344,9 @@ function federation(mfUserOptions) {
5268
5344
  _options: options,
5269
5345
  config(config, { command: _command }) {
5270
5346
  const isRolldown = getIsRolldown(this);
5271
- let implementation = options.implementation;
5272
- if (isRolldown) implementation = implementation.replace(/\.cjs(\.js)?$/, ".js");
5273
5347
  appendResolveAlias(config, {
5274
5348
  find: "@module-federation/runtime",
5275
- replacement: implementation
5349
+ replacement: options.implementation
5276
5350
  });
5277
5351
  config.build ||= {};
5278
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;
package/package.json CHANGED
@@ -1,30 +1,25 @@
1
1
  {
2
2
  "name": "@module-federation/vite",
3
- "version": "1.16.4",
3
+ "version": "1.16.5",
4
4
  "description": "Vite plugin for Module Federation",
5
5
  "type": "module",
6
- "main": "./lib/index.cjs",
7
- "module": "./lib/index.mjs",
8
- "types": "./lib/index.d.mts",
6
+ "main": "./lib/index.js",
7
+ "module": "./lib/index.js",
8
+ "types": "./lib/index.d.ts",
9
9
  "exports": {
10
10
  ".": {
11
- "types": {
12
- "import": "./lib/index.d.mts",
13
- "require": "./lib/index.d.cts"
14
- },
15
- "import": "./lib/index.mjs",
16
- "require": "./lib/index.cjs"
11
+ "types": "./lib/index.d.ts",
12
+ "default": "./lib/index.js"
17
13
  },
18
14
  "./ssrEntryLoader": {
19
- "types": {
20
- "import": "./lib/utils/ssrEntryLoader.d.mts",
21
- "require": "./lib/utils/ssrEntryLoader.d.cts"
22
- },
23
- "import": "./lib/utils/ssrEntryLoader.mjs",
24
- "require": "./lib/utils/ssrEntryLoader.cjs"
15
+ "types": "./lib/utils/ssrEntryLoader.d.ts",
16
+ "default": "./lib/utils/ssrEntryLoader.js"
25
17
  },
26
18
  "./package.json": "./package.json"
27
19
  },
20
+ "engines": {
21
+ "node": "^20.19.0 || >=22.12.0"
22
+ },
28
23
  "files": [
29
24
  "lib/**/*"
30
25
  ],
@@ -48,9 +43,7 @@
48
43
  "multi-example": "pnpm clean && pnpm --filter 'multi-example-*' --parallel run start",
49
44
  "test": "vitest run --dir src",
50
45
  "test:integration": "vitest run integration",
51
- "e2e": "playwright test",
52
- "changeset": "changeset",
53
- "changeset:status": "changeset status"
46
+ "e2e": "playwright test"
54
47
  },
55
48
  "repository": {
56
49
  "type": "git",
@@ -85,7 +78,6 @@
85
78
  "pathe": "2.0.3"
86
79
  },
87
80
  "devDependencies": {
88
- "@changesets/cli": "2.30.0",
89
81
  "@playwright/test": "1.58.2",
90
82
  "@types/node": "25.3.3",
91
83
  "husky": "9.1.7",