@module-federation/vite 1.7.2 → 1.8.1

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
@@ -465,6 +465,7 @@ function normalizeModuleFederationOptions(options) {
465
465
  dev: options.dev,
466
466
  dts: options.dts,
467
467
  getPublicPath: options.getPublicPath,
468
+ publicPath: options.publicPath,
468
469
  shareStrategy: options.shareStrategy || 'version-first',
469
470
  ignoreOrigin: options.ignoreOrigin || false,
470
471
  virtualModuleDir: options.virtualModuleDir || '__mf__virtual'
@@ -555,6 +556,16 @@ var cacheMap = {};
555
556
  /**
556
557
  * Physically generate files as virtual modules under node_modules/__mf__virtual/*
557
558
  */
559
+ function assertModuleFound(tag, str) {
560
+ if (str === void 0) {
561
+ str = '';
562
+ }
563
+ var module = VirtualModule.findModule(tag, str);
564
+ if (!module) {
565
+ throw new Error("Module Federation shared module '" + str + "' not found. Please ensure it's installed as a dependency in your package.json.");
566
+ }
567
+ return module;
568
+ }
558
569
  var VirtualModule = /*#__PURE__*/function () {
559
570
  function VirtualModule(name, tag, suffix) {
560
571
  if (tag === void 0) {
@@ -694,7 +705,7 @@ function getLoadShareModulePath(pkg) {
694
705
  return filepath;
695
706
  }
696
707
  function writeLoadShareModule(pkg, shareItem, command) {
697
- loadShareCacheMap[pkg].writeSync("\n \n ;() => import(" + JSON.stringify(getPreBuildLibImportId(pkg)) + ").catch(() => {});\n // dev uses dynamic import to separate chunks\n " + (command !== 'build' ? ";() => import(" + JSON.stringify(pkg) + ").catch(() => {});" : '') + "\n const {loadShare} = require(\"@module-federation/runtime\")\n const {initPromise} = require(\"" + virtualRuntimeInitStatus.getImportId() + "\")\n const res = initPromise.then(_ => loadShare(" + JSON.stringify(pkg) + ", {\n customShareInfo: {shareConfig:{\n singleton: " + shareItem.shareConfig.singleton + ",\n strictVersion: " + shareItem.shareConfig.strictVersion + ",\n requiredVersion: " + JSON.stringify(shareItem.shareConfig.requiredVersion) + "\n }}}))\n const exportModule = " + (command !== 'build' ? '/*mf top-level-await placeholder replacement mf*/' : 'await ') + "res.then(factory => factory())\n module.exports = exportModule\n ");
708
+ loadShareCacheMap[pkg].writeSync("\n\n ;() => import(" + JSON.stringify(getPreBuildLibImportId(pkg)) + ").catch(() => {});\n // dev uses dynamic import to separate chunks\n " + (command !== 'build' ? ";() => import(" + JSON.stringify(pkg) + ").catch(() => {});" : '') + "\n const {loadShare} = require(\"@module-federation/runtime\")\n const {initPromise} = require(\"" + virtualRuntimeInitStatus.getImportId() + "\")\n const res = initPromise.then(_ => loadShare(" + JSON.stringify(pkg) + ", {\n customShareInfo: {shareConfig:{\n singleton: " + shareItem.shareConfig.singleton + ",\n strictVersion: " + shareItem.shareConfig.strictVersion + ",\n requiredVersion: " + JSON.stringify(shareItem.shareConfig.requiredVersion) + "\n }}}))\n const exportModule = " + (command !== 'build' ? '/*mf top-level-await placeholder replacement mf*/' : 'await ') + "res.then(factory => factory())\n module.exports = exportModule\n ");
698
709
  }
699
710
 
700
711
  var usedShares = new Set();
@@ -919,6 +930,30 @@ var buildFileToShareKeyMap = function buildFileToShareKeyMap(shareKeys, resolveF
919
930
  }
920
931
  };
921
932
 
933
+ /**
934
+ * Resolves the public path for remote entries
935
+ * @param options - Module Federation options
936
+ * @param viteBase - Vite's base config value
937
+ * @param originalBase - Original base config before any transformations
938
+ * @returns The resolved public path
939
+ */
940
+ function resolvePublicPath(options, viteBase, originalBase) {
941
+ // Use explicitly set publicPath if provided
942
+ if (options.publicPath) {
943
+ return options.publicPath;
944
+ }
945
+ // Handle empty original base case
946
+ if (originalBase === '') {
947
+ return 'auto';
948
+ }
949
+ // Use viteBase if available, ensuring it ends with a slash
950
+ if (viteBase) {
951
+ return viteBase.replace(/\/?$/, '/');
952
+ }
953
+ // Fallback to auto if no base is specified
954
+ return 'auto';
955
+ }
956
+
922
957
  var Manifest = function Manifest() {
923
958
  var mfOptions = getNormalizeModuleFederationOptions();
924
959
  var name = mfOptions.name,
@@ -1034,7 +1069,7 @@ var Manifest = function Manifest() {
1034
1069
  if (_command === 'serve') {
1035
1070
  base = (config.server.origin || '') + config.base;
1036
1071
  }
1037
- publicPath = _originalConfigBase === '' ? 'auto' : base ? base.replace(/\/?$/, '/') : 'auto';
1072
+ publicPath = resolvePublicPath(mfOptions, base, _originalConfigBase);
1038
1073
  },
1039
1074
  /**
1040
1075
  * Generates the module federation manifest file
@@ -1300,7 +1335,8 @@ function pluginProxyRemoteEntry () {
1300
1335
  if (_command === 'serve') {
1301
1336
  var _viteConfig$server, _viteConfig$server2;
1302
1337
  var host = typeof ((_viteConfig$server = viteConfig.server) == null ? void 0 : _viteConfig$server.host) === 'string' && viteConfig.server.host !== '0.0.0.0' ? viteConfig.server.host : 'localhost';
1303
- return Promise.resolve("\n const origin = (window && " + !options.ignoreOrigin + ") ? window.origin : \"//" + host + ":" + ((_viteConfig$server2 = viteConfig.server) == null ? void 0 : _viteConfig$server2.port) + "\"\n const remoteEntryPromise = await import(origin + \"" + (viteConfig.base + options.filename) + "\")\n // __tla only serves as a hack for vite-plugin-top-level-await. \n Promise.resolve(remoteEntryPromise)\n .then(remoteEntry => {\n return Promise.resolve(remoteEntry.__tla)\n .then(remoteEntry.init).catch(remoteEntry.init)\n })\n ");
1338
+ var publicPath = JSON.stringify(resolvePublicPath(options, viteConfig.base) + options.filename);
1339
+ return Promise.resolve("\n const origin = (window && " + !options.ignoreOrigin + ") ? window.origin : \"//" + host + ":" + ((_viteConfig$server2 = viteConfig.server) == null ? void 0 : _viteConfig$server2.port) + "\"\n const remoteEntryPromise = await import(origin + " + publicPath + ")\n // __tla only serves as a hack for vite-plugin-top-level-await.\n Promise.resolve(remoteEntryPromise)\n .then(remoteEntry => {\n return Promise.resolve(remoteEntry.__tla)\n .then(remoteEntry.init).catch(remoteEntry.init)\n })\n ");
1304
1340
  }
1305
1341
  return Promise.resolve(code);
1306
1342
  }
@@ -1424,7 +1460,8 @@ function proxySharedModule(options) {
1424
1460
  return command === 'build' ? {
1425
1461
  find: new RegExp("(.*" + PREBUILD_TAG + ".*)"),
1426
1462
  replacement: function replacement($1) {
1427
- var pkgName = VirtualModule.findModule(PREBUILD_TAG, $1).name;
1463
+ var module = assertModuleFound(PREBUILD_TAG, $1);
1464
+ var pkgName = module.name;
1428
1465
  return pkgName;
1429
1466
  }
1430
1467
  } : {
@@ -1433,7 +1470,8 @@ function proxySharedModule(options) {
1433
1470
  customResolver: function customResolver(source, importer) {
1434
1471
  try {
1435
1472
  var _this = this;
1436
- var pkgName = VirtualModule.findModule(PREBUILD_TAG, source).name;
1473
+ var module = assertModuleFound(PREBUILD_TAG, source);
1474
+ var pkgName = module.name;
1437
1475
  return Promise.resolve(_this.resolve(pkgName, importer).then(function (item) {
1438
1476
  return item.id;
1439
1477
  })).then(function (result) {
package/lib/index.esm.js CHANGED
@@ -441,6 +441,7 @@ function normalizeModuleFederationOptions(options) {
441
441
  dev: options.dev,
442
442
  dts: options.dts,
443
443
  getPublicPath: options.getPublicPath,
444
+ publicPath: options.publicPath,
444
445
  shareStrategy: options.shareStrategy || 'version-first',
445
446
  ignoreOrigin: options.ignoreOrigin || false,
446
447
  virtualModuleDir: options.virtualModuleDir || '__mf__virtual'
@@ -531,6 +532,16 @@ var cacheMap = {};
531
532
  /**
532
533
  * Physically generate files as virtual modules under node_modules/__mf__virtual/*
533
534
  */
535
+ function assertModuleFound(tag, str) {
536
+ if (str === void 0) {
537
+ str = '';
538
+ }
539
+ var module = VirtualModule.findModule(tag, str);
540
+ if (!module) {
541
+ throw new Error("Module Federation shared module '" + str + "' not found. Please ensure it's installed as a dependency in your package.json.");
542
+ }
543
+ return module;
544
+ }
534
545
  var VirtualModule = /*#__PURE__*/function () {
535
546
  function VirtualModule(name, tag, suffix) {
536
547
  if (tag === void 0) {
@@ -670,7 +681,7 @@ function getLoadShareModulePath(pkg) {
670
681
  return filepath;
671
682
  }
672
683
  function writeLoadShareModule(pkg, shareItem, command) {
673
- loadShareCacheMap[pkg].writeSync("\n \n ;() => import(" + JSON.stringify(getPreBuildLibImportId(pkg)) + ").catch(() => {});\n // dev uses dynamic import to separate chunks\n " + (command !== 'build' ? ";() => import(" + JSON.stringify(pkg) + ").catch(() => {});" : '') + "\n const {loadShare} = require(\"@module-federation/runtime\")\n const {initPromise} = require(\"" + virtualRuntimeInitStatus.getImportId() + "\")\n const res = initPromise.then(_ => loadShare(" + JSON.stringify(pkg) + ", {\n customShareInfo: {shareConfig:{\n singleton: " + shareItem.shareConfig.singleton + ",\n strictVersion: " + shareItem.shareConfig.strictVersion + ",\n requiredVersion: " + JSON.stringify(shareItem.shareConfig.requiredVersion) + "\n }}}))\n const exportModule = " + (command !== 'build' ? '/*mf top-level-await placeholder replacement mf*/' : 'await ') + "res.then(factory => factory())\n module.exports = exportModule\n ");
684
+ loadShareCacheMap[pkg].writeSync("\n\n ;() => import(" + JSON.stringify(getPreBuildLibImportId(pkg)) + ").catch(() => {});\n // dev uses dynamic import to separate chunks\n " + (command !== 'build' ? ";() => import(" + JSON.stringify(pkg) + ").catch(() => {});" : '') + "\n const {loadShare} = require(\"@module-federation/runtime\")\n const {initPromise} = require(\"" + virtualRuntimeInitStatus.getImportId() + "\")\n const res = initPromise.then(_ => loadShare(" + JSON.stringify(pkg) + ", {\n customShareInfo: {shareConfig:{\n singleton: " + shareItem.shareConfig.singleton + ",\n strictVersion: " + shareItem.shareConfig.strictVersion + ",\n requiredVersion: " + JSON.stringify(shareItem.shareConfig.requiredVersion) + "\n }}}))\n const exportModule = " + (command !== 'build' ? '/*mf top-level-await placeholder replacement mf*/' : 'await ') + "res.then(factory => factory())\n module.exports = exportModule\n ");
674
685
  }
675
686
 
676
687
  var usedShares = new Set();
@@ -895,6 +906,30 @@ var buildFileToShareKeyMap = function buildFileToShareKeyMap(shareKeys, resolveF
895
906
  }
896
907
  };
897
908
 
909
+ /**
910
+ * Resolves the public path for remote entries
911
+ * @param options - Module Federation options
912
+ * @param viteBase - Vite's base config value
913
+ * @param originalBase - Original base config before any transformations
914
+ * @returns The resolved public path
915
+ */
916
+ function resolvePublicPath(options, viteBase, originalBase) {
917
+ // Use explicitly set publicPath if provided
918
+ if (options.publicPath) {
919
+ return options.publicPath;
920
+ }
921
+ // Handle empty original base case
922
+ if (originalBase === '') {
923
+ return 'auto';
924
+ }
925
+ // Use viteBase if available, ensuring it ends with a slash
926
+ if (viteBase) {
927
+ return viteBase.replace(/\/?$/, '/');
928
+ }
929
+ // Fallback to auto if no base is specified
930
+ return 'auto';
931
+ }
932
+
898
933
  var Manifest = function Manifest() {
899
934
  var mfOptions = getNormalizeModuleFederationOptions();
900
935
  var name = mfOptions.name,
@@ -1010,7 +1045,7 @@ var Manifest = function Manifest() {
1010
1045
  if (_command === 'serve') {
1011
1046
  base = (config.server.origin || '') + config.base;
1012
1047
  }
1013
- publicPath = _originalConfigBase === '' ? 'auto' : base ? base.replace(/\/?$/, '/') : 'auto';
1048
+ publicPath = resolvePublicPath(mfOptions, base, _originalConfigBase);
1014
1049
  },
1015
1050
  /**
1016
1051
  * Generates the module federation manifest file
@@ -1276,7 +1311,8 @@ function pluginProxyRemoteEntry () {
1276
1311
  if (_command === 'serve') {
1277
1312
  var _viteConfig$server, _viteConfig$server2;
1278
1313
  var host = typeof ((_viteConfig$server = viteConfig.server) == null ? void 0 : _viteConfig$server.host) === 'string' && viteConfig.server.host !== '0.0.0.0' ? viteConfig.server.host : 'localhost';
1279
- return Promise.resolve("\n const origin = (window && " + !options.ignoreOrigin + ") ? window.origin : \"//" + host + ":" + ((_viteConfig$server2 = viteConfig.server) == null ? void 0 : _viteConfig$server2.port) + "\"\n const remoteEntryPromise = await import(origin + \"" + (viteConfig.base + options.filename) + "\")\n // __tla only serves as a hack for vite-plugin-top-level-await. \n Promise.resolve(remoteEntryPromise)\n .then(remoteEntry => {\n return Promise.resolve(remoteEntry.__tla)\n .then(remoteEntry.init).catch(remoteEntry.init)\n })\n ");
1314
+ var publicPath = JSON.stringify(resolvePublicPath(options, viteConfig.base) + options.filename);
1315
+ return Promise.resolve("\n const origin = (window && " + !options.ignoreOrigin + ") ? window.origin : \"//" + host + ":" + ((_viteConfig$server2 = viteConfig.server) == null ? void 0 : _viteConfig$server2.port) + "\"\n const remoteEntryPromise = await import(origin + " + publicPath + ")\n // __tla only serves as a hack for vite-plugin-top-level-await.\n Promise.resolve(remoteEntryPromise)\n .then(remoteEntry => {\n return Promise.resolve(remoteEntry.__tla)\n .then(remoteEntry.init).catch(remoteEntry.init)\n })\n ");
1280
1316
  }
1281
1317
  return Promise.resolve(code);
1282
1318
  }
@@ -1400,7 +1436,8 @@ function proxySharedModule(options) {
1400
1436
  return command === 'build' ? {
1401
1437
  find: new RegExp("(.*" + PREBUILD_TAG + ".*)"),
1402
1438
  replacement: function replacement($1) {
1403
- var pkgName = VirtualModule.findModule(PREBUILD_TAG, $1).name;
1439
+ var module = assertModuleFound(PREBUILD_TAG, $1);
1440
+ var pkgName = module.name;
1404
1441
  return pkgName;
1405
1442
  }
1406
1443
  } : {
@@ -1409,7 +1446,8 @@ function proxySharedModule(options) {
1409
1446
  customResolver: function customResolver(source, importer) {
1410
1447
  try {
1411
1448
  var _this = this;
1412
- var pkgName = VirtualModule.findModule(PREBUILD_TAG, source).name;
1449
+ var module = assertModuleFound(PREBUILD_TAG, source);
1450
+ var pkgName = module.name;
1413
1451
  return Promise.resolve(_this.resolve(pkgName, importer).then(function (item) {
1414
1452
  return item.id;
1415
1453
  })).then(function (result) {
@@ -411,6 +411,7 @@ function normalizeModuleFederationOptions(options) {
411
411
  dev: options.dev,
412
412
  dts: options.dts,
413
413
  getPublicPath: options.getPublicPath,
414
+ publicPath: options.publicPath,
414
415
  shareStrategy: options.shareStrategy || 'version-first',
415
416
  ignoreOrigin: options.ignoreOrigin || false,
416
417
  virtualModuleDir: options.virtualModuleDir || '__mf__virtual'
@@ -499,6 +500,13 @@ const cacheMap = {};
499
500
  /**
500
501
  * Physically generate files as virtual modules under node_modules/__mf__virtual/*
501
502
  */
503
+ function assertModuleFound(tag, str = '') {
504
+ const module = VirtualModule.findModule(tag, str);
505
+ if (!module) {
506
+ throw new Error(`Module Federation shared module '${str}' not found. Please ensure it's installed as a dependency in your package.json.`);
507
+ }
508
+ return module;
509
+ }
502
510
  class VirtualModule {
503
511
  /**
504
512
  * Set the root path for finding node_modules
@@ -662,7 +670,7 @@ function getLoadShareModulePath(pkg) {
662
670
  }
663
671
  function writeLoadShareModule(pkg, shareItem, command) {
664
672
  loadShareCacheMap[pkg].writeSync(`
665
-
673
+
666
674
  ;() => import(${JSON.stringify(getPreBuildLibImportId(pkg))}).catch(() => {});
667
675
  // dev uses dynamic import to separate chunks
668
676
  ${command !== 'build' ? `;() => import(${JSON.stringify(pkg)}).catch(() => {});` : ''}
@@ -971,6 +979,30 @@ const buildFileToShareKeyMap = async (shareKeys, resolveFn) => {
971
979
  return fileToShareKey;
972
980
  };
973
981
 
982
+ /**
983
+ * Resolves the public path for remote entries
984
+ * @param options - Module Federation options
985
+ * @param viteBase - Vite's base config value
986
+ * @param originalBase - Original base config before any transformations
987
+ * @returns The resolved public path
988
+ */
989
+ function resolvePublicPath(options, viteBase, originalBase) {
990
+ // Use explicitly set publicPath if provided
991
+ if (options.publicPath) {
992
+ return options.publicPath;
993
+ }
994
+ // Handle empty original base case
995
+ if (originalBase === '') {
996
+ return 'auto';
997
+ }
998
+ // Use viteBase if available, ensuring it ends with a slash
999
+ if (viteBase) {
1000
+ return viteBase.replace(/\/?$/, '/');
1001
+ }
1002
+ // Fallback to auto if no base is specified
1003
+ return 'auto';
1004
+ }
1005
+
974
1006
  const Manifest = () => {
975
1007
  const mfOptions = getNormalizeModuleFederationOptions();
976
1008
  const {
@@ -1089,7 +1121,7 @@ const Manifest = () => {
1089
1121
  if (_command === 'serve') {
1090
1122
  base = (config.server.origin || '') + config.base;
1091
1123
  }
1092
- publicPath = _originalConfigBase === '' ? 'auto' : base ? base.replace(/\/?$/, '/') : 'auto';
1124
+ publicPath = resolvePublicPath(mfOptions, base, _originalConfigBase);
1093
1125
  },
1094
1126
  /**
1095
1127
  * Generates the module federation manifest file
@@ -1332,10 +1364,11 @@ function pluginProxyRemoteEntry () {
1332
1364
  if (_command === 'serve') {
1333
1365
  var _viteConfig$server, _viteConfig$server2;
1334
1366
  const host = typeof ((_viteConfig$server = viteConfig.server) == null ? void 0 : _viteConfig$server.host) === 'string' && viteConfig.server.host !== '0.0.0.0' ? viteConfig.server.host : 'localhost';
1367
+ const publicPath = JSON.stringify(resolvePublicPath(options, viteConfig.base) + options.filename);
1335
1368
  return `
1336
1369
  const origin = (window && ${!options.ignoreOrigin}) ? window.origin : "//${host}:${(_viteConfig$server2 = viteConfig.server) == null ? void 0 : _viteConfig$server2.port}"
1337
- const remoteEntryPromise = await import(origin + "${viteConfig.base + options.filename}")
1338
- // __tla only serves as a hack for vite-plugin-top-level-await.
1370
+ const remoteEntryPromise = await import(origin + ${publicPath})
1371
+ // __tla only serves as a hack for vite-plugin-top-level-await.
1339
1372
  Promise.resolve(remoteEntryPromise)
1340
1373
  .then(remoteEntry => {
1341
1374
  return Promise.resolve(remoteEntry.__tla)
@@ -1460,14 +1493,16 @@ function proxySharedModule(options) {
1460
1493
  return command === 'build' ? {
1461
1494
  find: new RegExp(`(.*${PREBUILD_TAG}.*)`),
1462
1495
  replacement: function ($1) {
1463
- const pkgName = VirtualModule.findModule(PREBUILD_TAG, $1).name;
1496
+ const module = assertModuleFound(PREBUILD_TAG, $1);
1497
+ const pkgName = module.name;
1464
1498
  return pkgName;
1465
1499
  }
1466
1500
  } : {
1467
1501
  find: new RegExp(`(.*${PREBUILD_TAG}.*)`),
1468
1502
  replacement: '$1',
1469
1503
  async customResolver(source, importer) {
1470
- const pkgName = VirtualModule.findModule(PREBUILD_TAG, source).name;
1504
+ const module = assertModuleFound(PREBUILD_TAG, source);
1505
+ const pkgName = module.name;
1471
1506
  const result = await this.resolve(pkgName, importer).then(item => item.id);
1472
1507
  if (!result.includes(_config.cacheDir)) {
1473
1508
  // save pre-bunding module id
package/lib/index.umd.js CHANGED
@@ -463,6 +463,7 @@
463
463
  dev: options.dev,
464
464
  dts: options.dts,
465
465
  getPublicPath: options.getPublicPath,
466
+ publicPath: options.publicPath,
466
467
  shareStrategy: options.shareStrategy || 'version-first',
467
468
  ignoreOrigin: options.ignoreOrigin || false,
468
469
  virtualModuleDir: options.virtualModuleDir || '__mf__virtual'
@@ -553,6 +554,16 @@
553
554
  /**
554
555
  * Physically generate files as virtual modules under node_modules/__mf__virtual/*
555
556
  */
557
+ function assertModuleFound(tag, str) {
558
+ if (str === void 0) {
559
+ str = '';
560
+ }
561
+ var module = VirtualModule.findModule(tag, str);
562
+ if (!module) {
563
+ throw new Error("Module Federation shared module '" + str + "' not found. Please ensure it's installed as a dependency in your package.json.");
564
+ }
565
+ return module;
566
+ }
556
567
  var VirtualModule = /*#__PURE__*/function () {
557
568
  function VirtualModule(name, tag, suffix) {
558
569
  if (tag === void 0) {
@@ -692,7 +703,7 @@
692
703
  return filepath;
693
704
  }
694
705
  function writeLoadShareModule(pkg, shareItem, command) {
695
- loadShareCacheMap[pkg].writeSync("\n \n ;() => import(" + JSON.stringify(getPreBuildLibImportId(pkg)) + ").catch(() => {});\n // dev uses dynamic import to separate chunks\n " + (command !== 'build' ? ";() => import(" + JSON.stringify(pkg) + ").catch(() => {});" : '') + "\n const {loadShare} = require(\"@module-federation/runtime\")\n const {initPromise} = require(\"" + virtualRuntimeInitStatus.getImportId() + "\")\n const res = initPromise.then(_ => loadShare(" + JSON.stringify(pkg) + ", {\n customShareInfo: {shareConfig:{\n singleton: " + shareItem.shareConfig.singleton + ",\n strictVersion: " + shareItem.shareConfig.strictVersion + ",\n requiredVersion: " + JSON.stringify(shareItem.shareConfig.requiredVersion) + "\n }}}))\n const exportModule = " + (command !== 'build' ? '/*mf top-level-await placeholder replacement mf*/' : 'await ') + "res.then(factory => factory())\n module.exports = exportModule\n ");
706
+ loadShareCacheMap[pkg].writeSync("\n\n ;() => import(" + JSON.stringify(getPreBuildLibImportId(pkg)) + ").catch(() => {});\n // dev uses dynamic import to separate chunks\n " + (command !== 'build' ? ";() => import(" + JSON.stringify(pkg) + ").catch(() => {});" : '') + "\n const {loadShare} = require(\"@module-federation/runtime\")\n const {initPromise} = require(\"" + virtualRuntimeInitStatus.getImportId() + "\")\n const res = initPromise.then(_ => loadShare(" + JSON.stringify(pkg) + ", {\n customShareInfo: {shareConfig:{\n singleton: " + shareItem.shareConfig.singleton + ",\n strictVersion: " + shareItem.shareConfig.strictVersion + ",\n requiredVersion: " + JSON.stringify(shareItem.shareConfig.requiredVersion) + "\n }}}))\n const exportModule = " + (command !== 'build' ? '/*mf top-level-await placeholder replacement mf*/' : 'await ') + "res.then(factory => factory())\n module.exports = exportModule\n ");
696
707
  }
697
708
 
698
709
  var usedShares = new Set();
@@ -917,6 +928,30 @@
917
928
  }
918
929
  };
919
930
 
931
+ /**
932
+ * Resolves the public path for remote entries
933
+ * @param options - Module Federation options
934
+ * @param viteBase - Vite's base config value
935
+ * @param originalBase - Original base config before any transformations
936
+ * @returns The resolved public path
937
+ */
938
+ function resolvePublicPath(options, viteBase, originalBase) {
939
+ // Use explicitly set publicPath if provided
940
+ if (options.publicPath) {
941
+ return options.publicPath;
942
+ }
943
+ // Handle empty original base case
944
+ if (originalBase === '') {
945
+ return 'auto';
946
+ }
947
+ // Use viteBase if available, ensuring it ends with a slash
948
+ if (viteBase) {
949
+ return viteBase.replace(/\/?$/, '/');
950
+ }
951
+ // Fallback to auto if no base is specified
952
+ return 'auto';
953
+ }
954
+
920
955
  var Manifest = function Manifest() {
921
956
  var mfOptions = getNormalizeModuleFederationOptions();
922
957
  var name = mfOptions.name,
@@ -1032,7 +1067,7 @@
1032
1067
  if (_command === 'serve') {
1033
1068
  base = (config.server.origin || '') + config.base;
1034
1069
  }
1035
- publicPath = _originalConfigBase === '' ? 'auto' : base ? base.replace(/\/?$/, '/') : 'auto';
1070
+ publicPath = resolvePublicPath(mfOptions, base, _originalConfigBase);
1036
1071
  },
1037
1072
  /**
1038
1073
  * Generates the module federation manifest file
@@ -1298,7 +1333,8 @@
1298
1333
  if (_command === 'serve') {
1299
1334
  var _viteConfig$server, _viteConfig$server2;
1300
1335
  var host = typeof ((_viteConfig$server = viteConfig.server) == null ? void 0 : _viteConfig$server.host) === 'string' && viteConfig.server.host !== '0.0.0.0' ? viteConfig.server.host : 'localhost';
1301
- return Promise.resolve("\n const origin = (window && " + !options.ignoreOrigin + ") ? window.origin : \"//" + host + ":" + ((_viteConfig$server2 = viteConfig.server) == null ? void 0 : _viteConfig$server2.port) + "\"\n const remoteEntryPromise = await import(origin + \"" + (viteConfig.base + options.filename) + "\")\n // __tla only serves as a hack for vite-plugin-top-level-await. \n Promise.resolve(remoteEntryPromise)\n .then(remoteEntry => {\n return Promise.resolve(remoteEntry.__tla)\n .then(remoteEntry.init).catch(remoteEntry.init)\n })\n ");
1336
+ var publicPath = JSON.stringify(resolvePublicPath(options, viteConfig.base) + options.filename);
1337
+ return Promise.resolve("\n const origin = (window && " + !options.ignoreOrigin + ") ? window.origin : \"//" + host + ":" + ((_viteConfig$server2 = viteConfig.server) == null ? void 0 : _viteConfig$server2.port) + "\"\n const remoteEntryPromise = await import(origin + " + publicPath + ")\n // __tla only serves as a hack for vite-plugin-top-level-await.\n Promise.resolve(remoteEntryPromise)\n .then(remoteEntry => {\n return Promise.resolve(remoteEntry.__tla)\n .then(remoteEntry.init).catch(remoteEntry.init)\n })\n ");
1302
1338
  }
1303
1339
  return Promise.resolve(code);
1304
1340
  }
@@ -1422,7 +1458,8 @@
1422
1458
  return command === 'build' ? {
1423
1459
  find: new RegExp("(.*" + PREBUILD_TAG + ".*)"),
1424
1460
  replacement: function replacement($1) {
1425
- var pkgName = VirtualModule.findModule(PREBUILD_TAG, $1).name;
1461
+ var module = assertModuleFound(PREBUILD_TAG, $1);
1462
+ var pkgName = module.name;
1426
1463
  return pkgName;
1427
1464
  }
1428
1465
  } : {
@@ -1431,7 +1468,8 @@
1431
1468
  customResolver: function customResolver(source, importer) {
1432
1469
  try {
1433
1470
  var _this = this;
1434
- var pkgName = VirtualModule.findModule(PREBUILD_TAG, source).name;
1471
+ var module = assertModuleFound(PREBUILD_TAG, source);
1472
+ var pkgName = module.name;
1435
1473
  return Promise.resolve(_this.resolve(pkgName, importer).then(function (item) {
1436
1474
  return item.id;
1437
1475
  })).then(function (result) {
@@ -2,6 +2,7 @@ export declare function getSuffix(name: string): string;
2
2
  /**
3
3
  * Physically generate files as virtual modules under node_modules/__mf__virtual/*
4
4
  */
5
+ export declare function assertModuleFound(tag: string, str?: string): VirtualModule;
5
6
  export default class VirtualModule {
6
7
  name: string;
7
8
  tag: string;
@@ -0,0 +1,2 @@
1
+ import type { NormalizedModuleFederationOptions } from '../normalizeModuleFederationOptions';
2
+ export declare function getDefaultMockOptions(overrides?: Partial<NormalizedModuleFederationOptions>): NormalizedModuleFederationOptions;
@@ -0,0 +1 @@
1
+ export {};
@@ -36,6 +36,11 @@ export type ModuleFederationOptions = {
36
36
  remotes?: Record<string, string | RemoteObjectConfig> | undefined;
37
37
  runtime?: any;
38
38
  shareScope?: string;
39
+ /**
40
+ * Override the public path used for remote entries
41
+ * Defaults to Vite's base config or "auto" if base is empty
42
+ */
43
+ publicPath?: string;
39
44
  shared?: string[] | Record<string, string | {
40
45
  name?: string;
41
46
  version?: string;
@@ -70,6 +75,7 @@ export interface NormalizedModuleFederationOptions {
70
75
  dts?: boolean | PluginDtsOptions;
71
76
  shareStrategy: ShareStrategy;
72
77
  getPublicPath?: string;
78
+ publicPath?: string;
73
79
  ignoreOrigin?: boolean;
74
80
  virtualModuleDir: string;
75
81
  }
@@ -0,0 +1,9 @@
1
+ import { NormalizedModuleFederationOptions } from './normalizeModuleFederationOptions';
2
+ /**
3
+ * Resolves the public path for remote entries
4
+ * @param options - Module Federation options
5
+ * @param viteBase - Vite's base config value
6
+ * @param originalBase - Original base config before any transformations
7
+ * @returns The resolved public path
8
+ */
9
+ export declare function resolvePublicPath(options: NormalizedModuleFederationOptions, viteBase: string, originalBase?: string): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@module-federation/vite",
3
- "version": "1.7.2",
3
+ "version": "1.8.1",
4
4
  "description": "Vite plugin for Module Federation",
5
5
  "type": "module",
6
6
  "source": "src/index.ts",
@@ -9,22 +9,6 @@
9
9
  "files": [
10
10
  "lib/**/*"
11
11
  ],
12
- "scripts": {
13
- "prepare": "husky install",
14
- "fmt": "prettier --write src",
15
- "fmt.check": "prettier --check src",
16
- "format": "pretty-quick",
17
- "dev": "microbundle watch --no-sourcemap --compress=false",
18
- "build": "rimraf lib && microbundle --no-sourcemap --compress=false",
19
- "dev-rv": "pnpm -filter 'examples-rust-vite*' run dev",
20
- "preview-rv": "pnpm -filter 'examples-rust-vite*' run preview",
21
- "dev-vv": "pnpm -filter 'examples-vite-vite*' run dev",
22
- "dev-nv": "pnpm -filter 'examples-nuxt-vite-host' -filter 'examples-vite-vite-remote' run dev",
23
- "preview-vv": "pnpm -filter 'examples-vite-vite*' run preview",
24
- "multi-example": "pnpm --filter \"multi-example-*\" --parallel run start",
25
- "test": "vitest",
26
- "e2e": "playwright test"
27
- },
28
12
  "repository": {
29
13
  "type": "git",
30
14
  "url": "git+https://github.com/module-federation/vite.git"
@@ -44,7 +28,6 @@
44
28
  "url": "https://github.com/module-federation/vite/issues"
45
29
  },
46
30
  "homepage": "https://github.com/module-federation/vite#readme",
47
- "packageManager": "pnpm@9.1.3",
48
31
  "dependencies": {
49
32
  "@module-federation/runtime": "^0.17.1",
50
33
  "@rollup/pluginutils": "^5.1.0",
@@ -66,5 +49,20 @@
66
49
  "vite": "^5.4.3",
67
50
  "vitest": "^2.1.1",
68
51
  "wait-on": "^8.0.1"
52
+ },
53
+ "scripts": {
54
+ "fmt": "prettier --write src",
55
+ "fmt.check": "prettier --check src",
56
+ "format": "pretty-quick",
57
+ "dev": "microbundle watch --no-sourcemap --compress=false",
58
+ "build": "rimraf lib && microbundle --no-sourcemap --compress=false",
59
+ "dev-rv": "pnpm -filter 'examples-rust-vite*' run dev",
60
+ "preview-rv": "pnpm -filter 'examples-rust-vite*' run preview",
61
+ "dev-vv": "pnpm -filter 'examples-vite-vite*' run dev",
62
+ "dev-nv": "pnpm -filter 'examples-nuxt-vite-host' -filter 'examples-vite-vite-remote' run dev",
63
+ "preview-vv": "pnpm -filter 'examples-vite-vite*' run preview",
64
+ "multi-example": "pnpm --filter \"multi-example-*\" --parallel run start",
65
+ "test": "vitest",
66
+ "e2e": "playwright test"
69
67
  }
70
- }
68
+ }