@module-federation/vite 1.9.1 → 1.9.3

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
@@ -171,6 +171,101 @@ var addEntry = function addEntry(_ref) {
171
171
  }];
172
172
  };
173
173
 
174
+ function _arrayLikeToArray(r, a) {
175
+ (null == a || a > r.length) && (a = r.length);
176
+ for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
177
+ return n;
178
+ }
179
+ function _createForOfIteratorHelperLoose(r, e) {
180
+ var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
181
+ if (t) return (t = t.call(r)).next.bind(t);
182
+ if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
183
+ t && (r = t);
184
+ var o = 0;
185
+ return function () {
186
+ return o >= r.length ? {
187
+ done: !0
188
+ } : {
189
+ done: !1,
190
+ value: r[o++]
191
+ };
192
+ };
193
+ }
194
+ throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
195
+ }
196
+ function _extends() {
197
+ return _extends = Object.assign ? Object.assign.bind() : function (n) {
198
+ for (var e = 1; e < arguments.length; e++) {
199
+ var t = arguments[e];
200
+ for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
201
+ }
202
+ return n;
203
+ }, _extends.apply(null, arguments);
204
+ }
205
+ function _unsupportedIterableToArray(r, a) {
206
+ if (r) {
207
+ if ("string" == typeof r) return _arrayLikeToArray(r, a);
208
+ var t = {}.toString.call(r).slice(8, -1);
209
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
210
+ }
211
+ }
212
+
213
+ /**
214
+ * Check if user-defined alias conflicts with shared modules
215
+ * This should run after aliasToArrayPlugin to ensure alias is an array
216
+ */
217
+ function checkAliasConflicts(options) {
218
+ var _options$shared = options.shared,
219
+ shared = _options$shared === void 0 ? {} : _options$shared;
220
+ var sharedKeys = Object.keys(shared);
221
+ return {
222
+ name: 'check-alias-conflicts',
223
+ configResolved: function configResolved(config) {
224
+ var _config$resolve;
225
+ if (sharedKeys.length === 0) return;
226
+ var userAliases = ((_config$resolve = config.resolve) == null ? void 0 : _config$resolve.alias) || [];
227
+ var conflicts = [];
228
+ for (var _i = 0, _sharedKeys = sharedKeys; _i < _sharedKeys.length; _i++) {
229
+ var sharedKey = _sharedKeys[_i];
230
+ for (var _iterator = _createForOfIteratorHelperLoose(userAliases), _step; !(_step = _iterator()).done;) {
231
+ var aliasEntry = _step.value;
232
+ var findPattern = aliasEntry.find;
233
+ var replacement = aliasEntry.replacement;
234
+ // Skip if replacement is not a string (e.g., customResolver)
235
+ if (typeof replacement !== 'string') continue;
236
+ // Skip Module Federation internal aliases (used for proxying shared modules)
237
+ // These are generated with replacement '$1' and should not trigger warnings
238
+ if (replacement === '$1') continue;
239
+ // Check if alias pattern matches the shared module
240
+ var isMatch = false;
241
+ if (typeof findPattern === 'string') {
242
+ isMatch = findPattern === sharedKey || sharedKey.startsWith(findPattern + '/');
243
+ } else if (findPattern instanceof RegExp) {
244
+ isMatch = findPattern.test(sharedKey);
245
+ }
246
+ if (isMatch) {
247
+ conflicts.push({
248
+ sharedModule: sharedKey,
249
+ alias: String(findPattern),
250
+ target: replacement
251
+ });
252
+ }
253
+ }
254
+ }
255
+ if (conflicts.length > 0) {
256
+ config.logger.warn('\n[Module Federation] Detected alias conflicts with shared modules:');
257
+ conflicts.forEach(function (_ref) {
258
+ var sharedModule = _ref.sharedModule,
259
+ alias = _ref.alias,
260
+ target = _ref.target;
261
+ config.logger.warn(" - Shared module \"" + sharedModule + "\" is aliased by \"" + alias + "\" to \"" + target + "\"");
262
+ });
263
+ config.logger.warn(" This may cause runtime errors as the shared module will bypass Module Federation's sharing mechanism.");
264
+ }
265
+ }
266
+ };
267
+ }
268
+
174
269
  /**
175
270
  * Solve the problem that dev mode dependency prebunding does not support top-level await syntax
176
271
  */
@@ -247,45 +342,6 @@ function PluginDevProxyModuleTopLevelAwait() {
247
342
  };
248
343
  }
249
344
 
250
- function _arrayLikeToArray(r, a) {
251
- (null == a || a > r.length) && (a = r.length);
252
- for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
253
- return n;
254
- }
255
- function _createForOfIteratorHelperLoose(r, e) {
256
- var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
257
- if (t) return (t = t.call(r)).next.bind(t);
258
- if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
259
- t && (r = t);
260
- var o = 0;
261
- return function () {
262
- return o >= r.length ? {
263
- done: !0
264
- } : {
265
- done: !1,
266
- value: r[o++]
267
- };
268
- };
269
- }
270
- throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
271
- }
272
- function _extends() {
273
- return _extends = Object.assign ? Object.assign.bind() : function (n) {
274
- for (var e = 1; e < arguments.length; e++) {
275
- var t = arguments[e];
276
- for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
277
- }
278
- return n;
279
- }, _extends.apply(null, arguments);
280
- }
281
- function _unsupportedIterableToArray(r, a) {
282
- if (r) {
283
- if ("string" == typeof r) return _arrayLikeToArray(r, a);
284
- var t = {}.toString.call(r).slice(8, -1);
285
- return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
286
- }
287
- }
288
-
289
345
  function normalizeExposesItem(key, item) {
290
346
  var importPath = '';
291
347
  if (typeof item === 'string') {
@@ -662,7 +718,9 @@ function generateExposes() {
662
718
 
663
719
  var virtualRuntimeInitStatus = new VirtualModule('runtimeInit');
664
720
  function writeRuntimeInitStatus() {
665
- virtualRuntimeInitStatus.writeSync("\n let initResolve, initReject\n const initPromise = new Promise((re, rj) => {\n initResolve = re\n initReject = rj\n })\n module.exports = {\n initPromise,\n initResolve,\n initReject\n }\n ");
721
+ // Use globalThis singleton to ensure only one initPromise exists
722
+ var globalKey = "__mf_init__" + virtualRuntimeInitStatus.getImportId() + "__";
723
+ virtualRuntimeInitStatus.writeSync("\n const globalKey = " + JSON.stringify(globalKey) + "\n if (!globalThis[globalKey]) {\n let initResolve, initReject\n const initPromise = new Promise((re, rj) => {\n initResolve = re\n initReject = rj\n })\n globalThis[globalKey] = {\n initPromise,\n initResolve,\n initReject\n }\n }\n module.exports = globalThis[globalKey]\n ");
666
724
  }
667
725
 
668
726
  var cacheRemoteMap = {};
@@ -686,7 +744,7 @@ function getUsedRemotesMap() {
686
744
  return usedRemotesMap;
687
745
  }
688
746
  function generateRemotes(id, command) {
689
- return "\n const {loadRemote} = require(\"@module-federation/runtime\")\n const {initPromise} = require(\"" + virtualRuntimeInitStatus.getImportId() + "\")\n const res = initPromise.then(_ => loadRemote(" + JSON.stringify(id) + "))\n const exportModule = " + (command !== 'build' ? '/*mf top-level-await placeholder replacement mf*/' : 'await ') + "initPromise.then(_ => res)\n module.exports = exportModule\n ";
747
+ return "\n const {initPromise} = require(\"" + virtualRuntimeInitStatus.getImportId() + "\")\n const res = initPromise.then(runtime => runtime.loadRemote(" + JSON.stringify(id) + "))\n const exportModule = " + (command !== 'build' ? '/*mf top-level-await placeholder replacement mf*/' : 'await ') + "initPromise.then(_ => res)\n module.exports = exportModule\n ";
690
748
  }
691
749
 
692
750
  /**
@@ -715,7 +773,7 @@ function getLoadShareModulePath(pkg) {
715
773
  return filepath;
716
774
  }
717
775
  function writeLoadShareModule(pkg, shareItem, command) {
718
- 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 ");
776
+ loadShareCacheMap[pkg].writeSync("\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 {initPromise} = require(\"" + virtualRuntimeInitStatus.getImportId() + "\")\n const res = initPromise.then(runtime => runtime.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 }))\n const exportModule = " + (command !== 'build' ? '/*mf top-level-await placeholder replacement mf*/' : 'await ') + "res.then(factory => factory())\n module.exports = exportModule\n ");
719
777
  }
720
778
 
721
779
  var usedShares = new Set();
@@ -1557,7 +1615,9 @@ function federation(mfUserOptions) {
1557
1615
  VirtualModule.ensureVirtualPackageExists();
1558
1616
  initVirtualModules();
1559
1617
  }
1560
- }, aliasToArrayPlugin, normalizeOptimizeDepsPlugin].concat(addEntry({
1618
+ }, aliasToArrayPlugin, checkAliasConflicts({
1619
+ shared: shared
1620
+ }), normalizeOptimizeDepsPlugin].concat(addEntry({
1561
1621
  entryName: 'remoteEntry',
1562
1622
  entryPath: REMOTE_ENTRY_ID,
1563
1623
  fileName: filename
package/lib/index.esm.js CHANGED
@@ -147,6 +147,101 @@ var addEntry = function addEntry(_ref) {
147
147
  }];
148
148
  };
149
149
 
150
+ function _arrayLikeToArray(r, a) {
151
+ (null == a || a > r.length) && (a = r.length);
152
+ for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
153
+ return n;
154
+ }
155
+ function _createForOfIteratorHelperLoose(r, e) {
156
+ var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
157
+ if (t) return (t = t.call(r)).next.bind(t);
158
+ if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
159
+ t && (r = t);
160
+ var o = 0;
161
+ return function () {
162
+ return o >= r.length ? {
163
+ done: !0
164
+ } : {
165
+ done: !1,
166
+ value: r[o++]
167
+ };
168
+ };
169
+ }
170
+ throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
171
+ }
172
+ function _extends() {
173
+ return _extends = Object.assign ? Object.assign.bind() : function (n) {
174
+ for (var e = 1; e < arguments.length; e++) {
175
+ var t = arguments[e];
176
+ for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
177
+ }
178
+ return n;
179
+ }, _extends.apply(null, arguments);
180
+ }
181
+ function _unsupportedIterableToArray(r, a) {
182
+ if (r) {
183
+ if ("string" == typeof r) return _arrayLikeToArray(r, a);
184
+ var t = {}.toString.call(r).slice(8, -1);
185
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
186
+ }
187
+ }
188
+
189
+ /**
190
+ * Check if user-defined alias conflicts with shared modules
191
+ * This should run after aliasToArrayPlugin to ensure alias is an array
192
+ */
193
+ function checkAliasConflicts(options) {
194
+ var _options$shared = options.shared,
195
+ shared = _options$shared === void 0 ? {} : _options$shared;
196
+ var sharedKeys = Object.keys(shared);
197
+ return {
198
+ name: 'check-alias-conflicts',
199
+ configResolved: function configResolved(config) {
200
+ var _config$resolve;
201
+ if (sharedKeys.length === 0) return;
202
+ var userAliases = ((_config$resolve = config.resolve) == null ? void 0 : _config$resolve.alias) || [];
203
+ var conflicts = [];
204
+ for (var _i = 0, _sharedKeys = sharedKeys; _i < _sharedKeys.length; _i++) {
205
+ var sharedKey = _sharedKeys[_i];
206
+ for (var _iterator = _createForOfIteratorHelperLoose(userAliases), _step; !(_step = _iterator()).done;) {
207
+ var aliasEntry = _step.value;
208
+ var findPattern = aliasEntry.find;
209
+ var replacement = aliasEntry.replacement;
210
+ // Skip if replacement is not a string (e.g., customResolver)
211
+ if (typeof replacement !== 'string') continue;
212
+ // Skip Module Federation internal aliases (used for proxying shared modules)
213
+ // These are generated with replacement '$1' and should not trigger warnings
214
+ if (replacement === '$1') continue;
215
+ // Check if alias pattern matches the shared module
216
+ var isMatch = false;
217
+ if (typeof findPattern === 'string') {
218
+ isMatch = findPattern === sharedKey || sharedKey.startsWith(findPattern + '/');
219
+ } else if (findPattern instanceof RegExp) {
220
+ isMatch = findPattern.test(sharedKey);
221
+ }
222
+ if (isMatch) {
223
+ conflicts.push({
224
+ sharedModule: sharedKey,
225
+ alias: String(findPattern),
226
+ target: replacement
227
+ });
228
+ }
229
+ }
230
+ }
231
+ if (conflicts.length > 0) {
232
+ config.logger.warn('\n[Module Federation] Detected alias conflicts with shared modules:');
233
+ conflicts.forEach(function (_ref) {
234
+ var sharedModule = _ref.sharedModule,
235
+ alias = _ref.alias,
236
+ target = _ref.target;
237
+ config.logger.warn(" - Shared module \"" + sharedModule + "\" is aliased by \"" + alias + "\" to \"" + target + "\"");
238
+ });
239
+ config.logger.warn(" This may cause runtime errors as the shared module will bypass Module Federation's sharing mechanism.");
240
+ }
241
+ }
242
+ };
243
+ }
244
+
150
245
  /**
151
246
  * Solve the problem that dev mode dependency prebunding does not support top-level await syntax
152
247
  */
@@ -223,45 +318,6 @@ function PluginDevProxyModuleTopLevelAwait() {
223
318
  };
224
319
  }
225
320
 
226
- function _arrayLikeToArray(r, a) {
227
- (null == a || a > r.length) && (a = r.length);
228
- for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
229
- return n;
230
- }
231
- function _createForOfIteratorHelperLoose(r, e) {
232
- var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
233
- if (t) return (t = t.call(r)).next.bind(t);
234
- if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
235
- t && (r = t);
236
- var o = 0;
237
- return function () {
238
- return o >= r.length ? {
239
- done: !0
240
- } : {
241
- done: !1,
242
- value: r[o++]
243
- };
244
- };
245
- }
246
- throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
247
- }
248
- function _extends() {
249
- return _extends = Object.assign ? Object.assign.bind() : function (n) {
250
- for (var e = 1; e < arguments.length; e++) {
251
- var t = arguments[e];
252
- for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
253
- }
254
- return n;
255
- }, _extends.apply(null, arguments);
256
- }
257
- function _unsupportedIterableToArray(r, a) {
258
- if (r) {
259
- if ("string" == typeof r) return _arrayLikeToArray(r, a);
260
- var t = {}.toString.call(r).slice(8, -1);
261
- return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
262
- }
263
- }
264
-
265
321
  function normalizeExposesItem(key, item) {
266
322
  var importPath = '';
267
323
  if (typeof item === 'string') {
@@ -638,7 +694,9 @@ function generateExposes() {
638
694
 
639
695
  var virtualRuntimeInitStatus = new VirtualModule('runtimeInit');
640
696
  function writeRuntimeInitStatus() {
641
- virtualRuntimeInitStatus.writeSync("\n let initResolve, initReject\n const initPromise = new Promise((re, rj) => {\n initResolve = re\n initReject = rj\n })\n module.exports = {\n initPromise,\n initResolve,\n initReject\n }\n ");
697
+ // Use globalThis singleton to ensure only one initPromise exists
698
+ var globalKey = "__mf_init__" + virtualRuntimeInitStatus.getImportId() + "__";
699
+ virtualRuntimeInitStatus.writeSync("\n const globalKey = " + JSON.stringify(globalKey) + "\n if (!globalThis[globalKey]) {\n let initResolve, initReject\n const initPromise = new Promise((re, rj) => {\n initResolve = re\n initReject = rj\n })\n globalThis[globalKey] = {\n initPromise,\n initResolve,\n initReject\n }\n }\n module.exports = globalThis[globalKey]\n ");
642
700
  }
643
701
 
644
702
  var cacheRemoteMap = {};
@@ -662,7 +720,7 @@ function getUsedRemotesMap() {
662
720
  return usedRemotesMap;
663
721
  }
664
722
  function generateRemotes(id, command) {
665
- return "\n const {loadRemote} = require(\"@module-federation/runtime\")\n const {initPromise} = require(\"" + virtualRuntimeInitStatus.getImportId() + "\")\n const res = initPromise.then(_ => loadRemote(" + JSON.stringify(id) + "))\n const exportModule = " + (command !== 'build' ? '/*mf top-level-await placeholder replacement mf*/' : 'await ') + "initPromise.then(_ => res)\n module.exports = exportModule\n ";
723
+ return "\n const {initPromise} = require(\"" + virtualRuntimeInitStatus.getImportId() + "\")\n const res = initPromise.then(runtime => runtime.loadRemote(" + JSON.stringify(id) + "))\n const exportModule = " + (command !== 'build' ? '/*mf top-level-await placeholder replacement mf*/' : 'await ') + "initPromise.then(_ => res)\n module.exports = exportModule\n ";
666
724
  }
667
725
 
668
726
  /**
@@ -691,7 +749,7 @@ function getLoadShareModulePath(pkg) {
691
749
  return filepath;
692
750
  }
693
751
  function writeLoadShareModule(pkg, shareItem, command) {
694
- 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 ");
752
+ loadShareCacheMap[pkg].writeSync("\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 {initPromise} = require(\"" + virtualRuntimeInitStatus.getImportId() + "\")\n const res = initPromise.then(runtime => runtime.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 }))\n const exportModule = " + (command !== 'build' ? '/*mf top-level-await placeholder replacement mf*/' : 'await ') + "res.then(factory => factory())\n module.exports = exportModule\n ");
695
753
  }
696
754
 
697
755
  var usedShares = new Set();
@@ -1533,7 +1591,9 @@ function federation(mfUserOptions) {
1533
1591
  VirtualModule.ensureVirtualPackageExists();
1534
1592
  initVirtualModules();
1535
1593
  }
1536
- }, aliasToArrayPlugin, normalizeOptimizeDepsPlugin].concat(addEntry({
1594
+ }, aliasToArrayPlugin, checkAliasConflicts({
1595
+ shared: shared
1596
+ }), normalizeOptimizeDepsPlugin].concat(addEntry({
1537
1597
  entryName: 'remoteEntry',
1538
1598
  entryPath: REMOTE_ENTRY_ID,
1539
1599
  fileName: filename
@@ -147,6 +147,62 @@ const addEntry = ({
147
147
  }];
148
148
  };
149
149
 
150
+ /**
151
+ * Check if user-defined alias conflicts with shared modules
152
+ * This should run after aliasToArrayPlugin to ensure alias is an array
153
+ */
154
+ function checkAliasConflicts(options) {
155
+ const {
156
+ shared = {}
157
+ } = options;
158
+ const sharedKeys = Object.keys(shared);
159
+ return {
160
+ name: 'check-alias-conflicts',
161
+ configResolved(config) {
162
+ var _config$resolve;
163
+ if (sharedKeys.length === 0) return;
164
+ const userAliases = ((_config$resolve = config.resolve) == null ? void 0 : _config$resolve.alias) || [];
165
+ const conflicts = [];
166
+ for (const sharedKey of sharedKeys) {
167
+ for (const aliasEntry of userAliases) {
168
+ const findPattern = aliasEntry.find;
169
+ const replacement = aliasEntry.replacement;
170
+ // Skip if replacement is not a string (e.g., customResolver)
171
+ if (typeof replacement !== 'string') continue;
172
+ // Skip Module Federation internal aliases (used for proxying shared modules)
173
+ // These are generated with replacement '$1' and should not trigger warnings
174
+ if (replacement === '$1') continue;
175
+ // Check if alias pattern matches the shared module
176
+ let isMatch = false;
177
+ if (typeof findPattern === 'string') {
178
+ isMatch = findPattern === sharedKey || sharedKey.startsWith(findPattern + '/');
179
+ } else if (findPattern instanceof RegExp) {
180
+ isMatch = findPattern.test(sharedKey);
181
+ }
182
+ if (isMatch) {
183
+ conflicts.push({
184
+ sharedModule: sharedKey,
185
+ alias: String(findPattern),
186
+ target: replacement
187
+ });
188
+ }
189
+ }
190
+ }
191
+ if (conflicts.length > 0) {
192
+ config.logger.warn('\n[Module Federation] Detected alias conflicts with shared modules:');
193
+ conflicts.forEach(({
194
+ sharedModule,
195
+ alias,
196
+ target
197
+ }) => {
198
+ config.logger.warn(` - Shared module "${sharedModule}" is aliased by "${alias}" to "${target}"`);
199
+ });
200
+ config.logger.warn(" This may cause runtime errors as the shared module will bypass Module Federation's sharing mechanism.");
201
+ }
202
+ }
203
+ };
204
+ }
205
+
150
206
  /**
151
207
  * Solve the problem that dev mode dependency prebunding does not support top-level await syntax
152
208
  */
@@ -612,17 +668,23 @@ function generateExposes() {
612
668
 
613
669
  const virtualRuntimeInitStatus = new VirtualModule('runtimeInit');
614
670
  function writeRuntimeInitStatus() {
671
+ // Use globalThis singleton to ensure only one initPromise exists
672
+ const globalKey = `__mf_init__${virtualRuntimeInitStatus.getImportId()}__`;
615
673
  virtualRuntimeInitStatus.writeSync(`
616
- let initResolve, initReject
617
- const initPromise = new Promise((re, rj) => {
618
- initResolve = re
619
- initReject = rj
620
- })
621
- module.exports = {
622
- initPromise,
623
- initResolve,
624
- initReject
674
+ const globalKey = ${JSON.stringify(globalKey)}
675
+ if (!globalThis[globalKey]) {
676
+ let initResolve, initReject
677
+ const initPromise = new Promise((re, rj) => {
678
+ initResolve = re
679
+ initReject = rj
680
+ })
681
+ globalThis[globalKey] = {
682
+ initPromise,
683
+ initResolve,
684
+ initReject
685
+ }
625
686
  }
687
+ module.exports = globalThis[globalKey]
626
688
  `);
627
689
  }
628
690
 
@@ -648,9 +710,8 @@ function getUsedRemotesMap() {
648
710
  }
649
711
  function generateRemotes(id, command) {
650
712
  return `
651
- const {loadRemote} = require("@module-federation/runtime")
652
713
  const {initPromise} = require("${virtualRuntimeInitStatus.getImportId()}")
653
- const res = initPromise.then(_ => loadRemote(${JSON.stringify(id)}))
714
+ const res = initPromise.then(runtime => runtime.loadRemote(${JSON.stringify(id)}))
654
715
  const exportModule = ${command !== 'build' ? '/*mf top-level-await placeholder replacement mf*/' : 'await '}initPromise.then(_ => res)
655
716
  module.exports = exportModule
656
717
  `;
@@ -683,18 +744,17 @@ function getLoadShareModulePath(pkg) {
683
744
  }
684
745
  function writeLoadShareModule(pkg, shareItem, command) {
685
746
  loadShareCacheMap[pkg].writeSync(`
686
-
687
747
  ;() => import(${JSON.stringify(getPreBuildLibImportId(pkg))}).catch(() => {});
688
748
  // dev uses dynamic import to separate chunks
689
749
  ${command !== 'build' ? `;() => import(${JSON.stringify(pkg)}).catch(() => {});` : ''}
690
- const {loadShare} = require("@module-federation/runtime")
691
750
  const {initPromise} = require("${virtualRuntimeInitStatus.getImportId()}")
692
- const res = initPromise.then(_ => loadShare(${JSON.stringify(pkg)}, {
693
- customShareInfo: {shareConfig:{
694
- singleton: ${shareItem.shareConfig.singleton},
695
- strictVersion: ${shareItem.shareConfig.strictVersion},
696
- requiredVersion: ${JSON.stringify(shareItem.shareConfig.requiredVersion)}
697
- }}}))
751
+ const res = initPromise.then(runtime => runtime.loadShare(${JSON.stringify(pkg)}, {
752
+ customShareInfo: {shareConfig:{
753
+ singleton: ${shareItem.shareConfig.singleton},
754
+ strictVersion: ${shareItem.shareConfig.strictVersion},
755
+ requiredVersion: ${JSON.stringify(shareItem.shareConfig.requiredVersion)}
756
+ }}
757
+ }))
698
758
  const exportModule = ${command !== 'build' ? '/*mf top-level-await placeholder replacement mf*/' : 'await '}res.then(factory => factory())
699
759
  module.exports = exportModule
700
760
  `);
@@ -1601,7 +1661,9 @@ function federation(mfUserOptions) {
1601
1661
  VirtualModule.ensureVirtualPackageExists();
1602
1662
  initVirtualModules();
1603
1663
  }
1604
- }, aliasToArrayPlugin, normalizeOptimizeDepsPlugin, ...addEntry({
1664
+ }, aliasToArrayPlugin, checkAliasConflicts({
1665
+ shared
1666
+ }), normalizeOptimizeDepsPlugin, ...addEntry({
1605
1667
  entryName: 'remoteEntry',
1606
1668
  entryPath: REMOTE_ENTRY_ID,
1607
1669
  fileName: filename
package/lib/index.umd.js CHANGED
@@ -169,6 +169,101 @@
169
169
  }];
170
170
  };
171
171
 
172
+ function _arrayLikeToArray(r, a) {
173
+ (null == a || a > r.length) && (a = r.length);
174
+ for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
175
+ return n;
176
+ }
177
+ function _createForOfIteratorHelperLoose(r, e) {
178
+ var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
179
+ if (t) return (t = t.call(r)).next.bind(t);
180
+ if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
181
+ t && (r = t);
182
+ var o = 0;
183
+ return function () {
184
+ return o >= r.length ? {
185
+ done: !0
186
+ } : {
187
+ done: !1,
188
+ value: r[o++]
189
+ };
190
+ };
191
+ }
192
+ throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
193
+ }
194
+ function _extends() {
195
+ return _extends = Object.assign ? Object.assign.bind() : function (n) {
196
+ for (var e = 1; e < arguments.length; e++) {
197
+ var t = arguments[e];
198
+ for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
199
+ }
200
+ return n;
201
+ }, _extends.apply(null, arguments);
202
+ }
203
+ function _unsupportedIterableToArray(r, a) {
204
+ if (r) {
205
+ if ("string" == typeof r) return _arrayLikeToArray(r, a);
206
+ var t = {}.toString.call(r).slice(8, -1);
207
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
208
+ }
209
+ }
210
+
211
+ /**
212
+ * Check if user-defined alias conflicts with shared modules
213
+ * This should run after aliasToArrayPlugin to ensure alias is an array
214
+ */
215
+ function checkAliasConflicts(options) {
216
+ var _options$shared = options.shared,
217
+ shared = _options$shared === void 0 ? {} : _options$shared;
218
+ var sharedKeys = Object.keys(shared);
219
+ return {
220
+ name: 'check-alias-conflicts',
221
+ configResolved: function configResolved(config) {
222
+ var _config$resolve;
223
+ if (sharedKeys.length === 0) return;
224
+ var userAliases = ((_config$resolve = config.resolve) == null ? void 0 : _config$resolve.alias) || [];
225
+ var conflicts = [];
226
+ for (var _i = 0, _sharedKeys = sharedKeys; _i < _sharedKeys.length; _i++) {
227
+ var sharedKey = _sharedKeys[_i];
228
+ for (var _iterator = _createForOfIteratorHelperLoose(userAliases), _step; !(_step = _iterator()).done;) {
229
+ var aliasEntry = _step.value;
230
+ var findPattern = aliasEntry.find;
231
+ var replacement = aliasEntry.replacement;
232
+ // Skip if replacement is not a string (e.g., customResolver)
233
+ if (typeof replacement !== 'string') continue;
234
+ // Skip Module Federation internal aliases (used for proxying shared modules)
235
+ // These are generated with replacement '$1' and should not trigger warnings
236
+ if (replacement === '$1') continue;
237
+ // Check if alias pattern matches the shared module
238
+ var isMatch = false;
239
+ if (typeof findPattern === 'string') {
240
+ isMatch = findPattern === sharedKey || sharedKey.startsWith(findPattern + '/');
241
+ } else if (findPattern instanceof RegExp) {
242
+ isMatch = findPattern.test(sharedKey);
243
+ }
244
+ if (isMatch) {
245
+ conflicts.push({
246
+ sharedModule: sharedKey,
247
+ alias: String(findPattern),
248
+ target: replacement
249
+ });
250
+ }
251
+ }
252
+ }
253
+ if (conflicts.length > 0) {
254
+ config.logger.warn('\n[Module Federation] Detected alias conflicts with shared modules:');
255
+ conflicts.forEach(function (_ref) {
256
+ var sharedModule = _ref.sharedModule,
257
+ alias = _ref.alias,
258
+ target = _ref.target;
259
+ config.logger.warn(" - Shared module \"" + sharedModule + "\" is aliased by \"" + alias + "\" to \"" + target + "\"");
260
+ });
261
+ config.logger.warn(" This may cause runtime errors as the shared module will bypass Module Federation's sharing mechanism.");
262
+ }
263
+ }
264
+ };
265
+ }
266
+
172
267
  /**
173
268
  * Solve the problem that dev mode dependency prebunding does not support top-level await syntax
174
269
  */
@@ -245,45 +340,6 @@
245
340
  };
246
341
  }
247
342
 
248
- function _arrayLikeToArray(r, a) {
249
- (null == a || a > r.length) && (a = r.length);
250
- for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
251
- return n;
252
- }
253
- function _createForOfIteratorHelperLoose(r, e) {
254
- var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
255
- if (t) return (t = t.call(r)).next.bind(t);
256
- if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
257
- t && (r = t);
258
- var o = 0;
259
- return function () {
260
- return o >= r.length ? {
261
- done: !0
262
- } : {
263
- done: !1,
264
- value: r[o++]
265
- };
266
- };
267
- }
268
- throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
269
- }
270
- function _extends() {
271
- return _extends = Object.assign ? Object.assign.bind() : function (n) {
272
- for (var e = 1; e < arguments.length; e++) {
273
- var t = arguments[e];
274
- for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
275
- }
276
- return n;
277
- }, _extends.apply(null, arguments);
278
- }
279
- function _unsupportedIterableToArray(r, a) {
280
- if (r) {
281
- if ("string" == typeof r) return _arrayLikeToArray(r, a);
282
- var t = {}.toString.call(r).slice(8, -1);
283
- return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
284
- }
285
- }
286
-
287
343
  function normalizeExposesItem(key, item) {
288
344
  var importPath = '';
289
345
  if (typeof item === 'string') {
@@ -660,7 +716,9 @@
660
716
 
661
717
  var virtualRuntimeInitStatus = new VirtualModule('runtimeInit');
662
718
  function writeRuntimeInitStatus() {
663
- virtualRuntimeInitStatus.writeSync("\n let initResolve, initReject\n const initPromise = new Promise((re, rj) => {\n initResolve = re\n initReject = rj\n })\n module.exports = {\n initPromise,\n initResolve,\n initReject\n }\n ");
719
+ // Use globalThis singleton to ensure only one initPromise exists
720
+ var globalKey = "__mf_init__" + virtualRuntimeInitStatus.getImportId() + "__";
721
+ virtualRuntimeInitStatus.writeSync("\n const globalKey = " + JSON.stringify(globalKey) + "\n if (!globalThis[globalKey]) {\n let initResolve, initReject\n const initPromise = new Promise((re, rj) => {\n initResolve = re\n initReject = rj\n })\n globalThis[globalKey] = {\n initPromise,\n initResolve,\n initReject\n }\n }\n module.exports = globalThis[globalKey]\n ");
664
722
  }
665
723
 
666
724
  var cacheRemoteMap = {};
@@ -684,7 +742,7 @@
684
742
  return usedRemotesMap;
685
743
  }
686
744
  function generateRemotes(id, command) {
687
- return "\n const {loadRemote} = require(\"@module-federation/runtime\")\n const {initPromise} = require(\"" + virtualRuntimeInitStatus.getImportId() + "\")\n const res = initPromise.then(_ => loadRemote(" + JSON.stringify(id) + "))\n const exportModule = " + (command !== 'build' ? '/*mf top-level-await placeholder replacement mf*/' : 'await ') + "initPromise.then(_ => res)\n module.exports = exportModule\n ";
745
+ return "\n const {initPromise} = require(\"" + virtualRuntimeInitStatus.getImportId() + "\")\n const res = initPromise.then(runtime => runtime.loadRemote(" + JSON.stringify(id) + "))\n const exportModule = " + (command !== 'build' ? '/*mf top-level-await placeholder replacement mf*/' : 'await ') + "initPromise.then(_ => res)\n module.exports = exportModule\n ";
688
746
  }
689
747
 
690
748
  /**
@@ -713,7 +771,7 @@
713
771
  return filepath;
714
772
  }
715
773
  function writeLoadShareModule(pkg, shareItem, command) {
716
- 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 ");
774
+ loadShareCacheMap[pkg].writeSync("\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 {initPromise} = require(\"" + virtualRuntimeInitStatus.getImportId() + "\")\n const res = initPromise.then(runtime => runtime.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 }))\n const exportModule = " + (command !== 'build' ? '/*mf top-level-await placeholder replacement mf*/' : 'await ') + "res.then(factory => factory())\n module.exports = exportModule\n ");
717
775
  }
718
776
 
719
777
  var usedShares = new Set();
@@ -1555,7 +1613,9 @@
1555
1613
  VirtualModule.ensureVirtualPackageExists();
1556
1614
  initVirtualModules();
1557
1615
  }
1558
- }, aliasToArrayPlugin, normalizeOptimizeDepsPlugin].concat(addEntry({
1616
+ }, aliasToArrayPlugin, checkAliasConflicts({
1617
+ shared: shared
1618
+ }), normalizeOptimizeDepsPlugin].concat(addEntry({
1559
1619
  entryName: 'remoteEntry',
1560
1620
  entryPath: REMOTE_ENTRY_ID,
1561
1621
  fileName: filename
@@ -0,0 +1,9 @@
1
+ import type { Plugin } from 'vite';
2
+ import { NormalizedShared } from '../utils/normalizeModuleFederationOptions';
3
+ /**
4
+ * Check if user-defined alias conflicts with shared modules
5
+ * This should run after aliasToArrayPlugin to ensure alias is an array
6
+ */
7
+ export declare function checkAliasConflicts(options: {
8
+ shared?: NormalizedShared;
9
+ }): Plugin;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@module-federation/vite",
3
- "version": "1.9.1",
3
+ "version": "1.9.3",
4
4
  "description": "Vite plugin for Module Federation",
5
5
  "type": "module",
6
6
  "source": "src/index.ts",
@@ -46,8 +46,8 @@
46
46
  "homepage": "https://github.com/module-federation/vite#readme",
47
47
  "packageManager": "pnpm@9.1.3",
48
48
  "dependencies": {
49
- "@module-federation/runtime": "^0.18.3",
50
- "@module-federation/sdk": "^0.18.3",
49
+ "@module-federation/runtime": "^0.21.6",
50
+ "@module-federation/sdk": "^0.21.6",
51
51
  "@rollup/pluginutils": "^5.1.0",
52
52
  "defu": "^6.1.4",
53
53
  "estree-walker": "^2",