@module-federation/vite 1.0.0-alpha-6cae9ab → 1.0.0-alpha-f87d7d3

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
@@ -23,7 +23,7 @@ https://module-federation.io/guide/basic/webpack.html
23
23
  // vite.config.js
24
24
  import { defineConfig } from 'vite';
25
25
  import vue from '@vitejs/plugin-vue';
26
- import { federation } from 'module-federation-vite';
26
+ import { federation } from '@module-federation/vite';
27
27
  import topLevelAwait from 'vite-plugin-top-level-await';
28
28
 
29
29
  // https://vitejs.dev/config/
@@ -43,7 +43,7 @@ export default defineConfig({
43
43
  // }
44
44
  },
45
45
  exposes: {
46
- App: './src/App.vue',
46
+ './App': './src/App.vue',
47
47
  },
48
48
  filename: 'dd/remoteEntry.js',
49
49
  shared: {
@@ -59,7 +59,7 @@ export default defineConfig({
59
59
  server: {
60
60
  port: 5173,
61
61
  // dev mode please set origin
62
- origin: "http://localhost:5173"
62
+ origin: 'http://localhost:5173',
63
63
  },
64
64
  build: {
65
65
  target: 'chrome89',
package/lib/index.cjs CHANGED
@@ -1,6 +1,7 @@
1
1
  var fs = require('fs');
2
2
  var path = require('pathe');
3
3
  var pluginutils = require('@rollup/pluginutils');
4
+ var defu = require('defu');
4
5
  var estreeWalker = require('estree-walker');
5
6
  var MagicString = require('magic-string');
6
7
 
@@ -29,7 +30,8 @@ var path__namespace = /*#__PURE__*/_interopNamespace(path);
29
30
  var MagicString__default = /*#__PURE__*/_interopDefaultLegacy(MagicString);
30
31
 
31
32
  var addEntry = function addEntry(_ref) {
32
- var entryPath = _ref.entryPath,
33
+ var entryName = _ref.entryName,
34
+ entryPath = _ref.entryPath,
33
35
  fileName = _ref.fileName;
34
36
  var entryFiles = [];
35
37
  var htmlFilePath;
@@ -78,7 +80,9 @@ var addEntry = function addEntry(_ref) {
78
80
  buildStart: function buildStart() {
79
81
  var _this$emitFile;
80
82
  var hasHash = fileName == null || fileName.includes == null ? void 0 : fileName.includes("[hash");
81
- this.emitFile((_this$emitFile = {}, _this$emitFile[hasHash ? "name" : "fileName"] = fileName, _this$emitFile.type = 'chunk', _this$emitFile.id = entryPath, _this$emitFile.preserveSignature = 'strict', _this$emitFile));
83
+ this.emitFile((_this$emitFile = {
84
+ name: entryName
85
+ }, _this$emitFile[hasHash ? "name" : "fileName"] = fileName, _this$emitFile.type = 'chunk', _this$emitFile.id = entryPath, _this$emitFile.preserveSignature = 'strict', _this$emitFile));
82
86
  if (htmlFilePath) {
83
87
  var htmlContent = fs__namespace.readFileSync(htmlFilePath, 'utf-8');
84
88
  var scriptRegex = /<script\s+[^>]*src=["']([^"']+)["'][^>]*>/gi;
@@ -99,6 +103,48 @@ var addEntry = function addEntry(_ref) {
99
103
  }];
100
104
  };
101
105
 
106
+ var _resolve,
107
+ promise = new Promise(function (resolve, reject) {
108
+ _resolve = resolve;
109
+ });
110
+ var parsePromise = promise;
111
+ var parseStartSet = new Set();
112
+ var parseEndSet = new Set();
113
+ function pluginModuleParseEnd (excludeFn) {
114
+ return [{
115
+ name: "_",
116
+ apply: "serve",
117
+ config: function config() {
118
+ // No waiting in development mode
119
+ _resolve(1);
120
+ }
121
+ }, {
122
+ enforce: "pre",
123
+ name: "parseStart",
124
+ apply: "build",
125
+ load: function load(id) {
126
+ if (excludeFn(id)) {
127
+ return;
128
+ }
129
+ parseStartSet.add(id);
130
+ }
131
+ }, {
132
+ enforce: "post",
133
+ name: "parseEnd",
134
+ apply: "build",
135
+ moduleParsed: function moduleParsed(module) {
136
+ var id = module.id;
137
+ if (excludeFn(id)) {
138
+ return;
139
+ }
140
+ parseEndSet.add(id);
141
+ if (parseStartSet.size === parseEndSet.size) {
142
+ _resolve(1);
143
+ }
144
+ }
145
+ }];
146
+ }
147
+
102
148
  function normalizeExposesItem(key, item) {
103
149
  var importPath = '';
104
150
  if (typeof item === 'string') {
@@ -149,7 +195,7 @@ function normalizeRemoteItem(key, remote) {
149
195
  entryGlobalName: key
150
196
  }, remote);
151
197
  }
152
- function removePathFromNpmPackage(packageString) {
198
+ function removePathFromNpmPackage$1(packageString) {
153
199
  // 匹配npm包名的正则表达式,忽略路径部分
154
200
  var regex = /^(?:@[^/]+\/)?[^/]+/;
155
201
  // 使用正则表达式匹配并提取包名
@@ -160,7 +206,7 @@ function removePathFromNpmPackage(packageString) {
160
206
  function normalizeShareItem(key, shareItem) {
161
207
  var version;
162
208
  try {
163
- version = require(path__namespace.join(removePathFromNpmPackage(key), 'package.json')).version;
209
+ version = require(path__namespace.join(removePathFromNpmPackage$1(key), 'package.json')).version;
164
210
  } catch (e) {
165
211
  console.log(e);
166
212
  }
@@ -233,61 +279,138 @@ function normalizeModuleFederationOptions(options) {
233
279
  }
234
280
 
235
281
  /**
236
- * Even the resolveId hook cannot interfere with vite pre-build,
237
- * and adding query parameter virtual modules will also fail.
238
- * You can only proxy to the real file through alias
282
+ * Escaping rules:
283
+ * Convert using the format __${mapping}__, where _ and $ are not allowed in npm package names but can be used in variable names.
284
+ * @ => 1
285
+ * / => 2
286
+ * - => 3
287
+ * . => 4
239
288
  */
240
- var emptyNpmDir = path.resolve(require.resolve("an-empty-js-file"), "../");
241
289
  /**
242
- * The original shared module is proxied by getLoadShareModulePath, and the new shared module is prebuilt here
290
+ * @param {*} name "@scope/xx-xx.xx" => "__$1__scope__$2__xx__$3__xx$__4__xx"
243
291
  */
244
- var cacheMap2 = {};
245
- function getPreBuildLibPath(pkg) {
246
- if (!cacheMap2[pkg]) cacheMap2[pkg] = "__mf__prebuildwrap_" + npmPackageNameToFileName(pkg) + ".js";
247
- var filename = cacheMap2[pkg];
248
- return filename;
249
- }
250
- function getLocalSharedImportMapFileName() {
251
- var _getNormalizeModuleFe = getNormalizeModuleFederationOptions(),
252
- name = _getNormalizeModuleFe.name;
253
- return npmPackageNameToFileName(name) + "_" + "__mf__localSharedImportMap.js";
254
- }
255
- // Only npm package name import can trigger pre-build, absolute path cannot
256
- function getLocalSharedImportMapId() {
257
- return "an-empty-js-file/" + getLocalSharedImportMapFileName();
292
+ function packageNameEncode(name) {
293
+ if (typeof name !== "string") throw new Error("A string package name is required");
294
+ return name.replace(/\@/g, "__$1__").replace(/\//g, "__$2__").replace(/\-/g, "__$3__").replace(/\./g, "__$4__");
258
295
  }
259
- function getLocalSharedImportMapPath() {
260
- return path.resolve(emptyNpmDir, getLocalSharedImportMapFileName());
296
+ /**
297
+ * @param {*} global "__$1__scope__$2__xx__$3__xx$__4__xx" => "@scope/xx-xx.xx"
298
+ */
299
+ function packageNameDecode(global) {
300
+ if (typeof global !== "string") throw new Error("A string global variable name is required");
301
+ return global.replace(/\_\_\$1\_\_/g, "@").replace(/\_\_\$2\_\_/g, "/").replace(/\_\_\$3\_\_/g, "-").replace(/\_\_\$4\_\_/g, ".");
261
302
  }
262
- function writeLocalSharedImportMap(pkgList) {
263
- fs.writeFileSync(getLocalSharedImportMapPath(), "\n export default {\n " + pkgList.map(function (pkg) {
264
- return "\n " + JSON.stringify(pkg) + ": async () => {\n let pkg = await import(\"" + getPreBuildLibPath(pkg) + "\")\n return pkg\n }\n ";
265
- }).join(",") + "\n }\n ");
303
+ function removePathFromNpmPackage(packageString) {
304
+ // Regular expression to match npm package name, ignoring path parts
305
+ var regex = /^(?:@[^/]+\/)?[^/]+/;
306
+ // Use regular expression to match and extract the package name
307
+ var match = packageString.match(regex);
308
+ // Return the matched package name or the original string if no match is found
309
+ return match ? match[0] : packageString;
266
310
  }
311
+
312
+ var nodeModulesDir = path.resolve("./node_modules");
313
+ var virtualPackageName = "__mf__virtual";
314
+ try {
315
+ fs.mkdirSync(path.resolve(nodeModulesDir, virtualPackageName));
316
+ } catch (e) {}
317
+ fs.writeFileSync(path.resolve(nodeModulesDir, virtualPackageName, "empty.js"), "");
318
+ fs.writeFileSync(path.resolve(nodeModulesDir, virtualPackageName, "package.json"), JSON.stringify({
319
+ name: virtualPackageName,
320
+ main: "empty.js"
321
+ }));
322
+ /**
323
+ * Physically generate files as virtual modules under node_modules/__mf__virtual/*
324
+ */
325
+ var VirtualModule = /*#__PURE__*/function () {
326
+ function VirtualModule(name) {
327
+ this.originName = void 0;
328
+ this.originName = name;
329
+ }
330
+ var _proto = VirtualModule.prototype;
331
+ _proto.getPath = function getPath() {
332
+ return path.resolve(nodeModulesDir, this.getImportId());
333
+ };
334
+ _proto.getImportId = function getImportId() {
335
+ return virtualPackageName + "/" + packageNameEncode(this.originName);
336
+ };
337
+ _proto.writeSync = function writeSync(code) {
338
+ fs.writeFileSync(this.getPath() + ".js", code);
339
+ };
340
+ _proto.write = function write(code) {
341
+ fs.writeFile(this.getPath() + ".js", code, function () {});
342
+ };
343
+ return VirtualModule;
344
+ }();
345
+
267
346
  /**
268
- * generate loadShare virtual module
347
+ * Even the resolveId hook cannot interfere with vite pre-build,
348
+ * and adding query parameter virtual modules will also fail.
349
+ * You can only proxy to the real file through alias
269
350
  */
270
- var cacheMap1 = {};
351
+ // *** __prebuild__
352
+
353
+ var generateLocalSharedImportMap = function generateLocalSharedImportMap() {
354
+ return Promise.resolve(parsePromise).then(function () {
355
+ var options = getNormalizeModuleFederationOptions();
356
+ return "\n const localSharedImportMap = {\n " + Array.from(shareds).map(function (pkg) {
357
+ return "\n " + JSON.stringify(pkg) + ": async () => {\n let pkg = await import(\"" + getPreBuildLibImportId(pkg) + "\")\n return pkg\n }\n ";
358
+ }).join(",") + "\n }\n const localShared = {\n " + Array.from(shareds).map(function (key) {
359
+ var shareItem = options.shared[removePathFromNpmPackage(key)] || options.shared[removePathFromNpmPackage(key) + "/"];
360
+ return "\n " + JSON.stringify(key) + ": {\n name: " + JSON.stringify(key) + ",\n version: " + JSON.stringify(shareItem.version) + ",\n scope: [" + JSON.stringify(shareItem.scope) + "],\n loaded: false,\n from: " + JSON.stringify(options.name) + ",\n async get () {\n localShared[" + JSON.stringify(key) + "].loaded = true\n const {" + JSON.stringify(key) + ": pkgDynamicImport} = localSharedImportMap \n const res = await pkgDynamicImport()\n const exportModule = {...res}\n // All npm packages pre-built by vite will be converted to esm\n Object.defineProperty(exportModule, \"__esModule\", {\n value: true,\n enumerable: false\n })\n return function () {\n return exportModule\n }\n },\n shareConfig: {\n singleton: " + shareItem.shareConfig.singleton + ",\n requiredVersion: " + JSON.stringify(shareItem.shareConfig.requiredVersion) + "\n }\n }\n ";
361
+ }).join(',') + "\n }\n export default localShared\n ";
362
+ });
363
+ };
364
+ // *** __loadShare__
365
+ var writeLocalSharedImportMap = function writeLocalSharedImportMap() {
366
+ try {
367
+ var sharedCount = shareds.size;
368
+ return Promise.resolve(function () {
369
+ if (prevSharedCount !== sharedCount) {
370
+ prevSharedCount = sharedCount;
371
+ var _writeSync = localSharedImportMapModule.writeSync;
372
+ return Promise.resolve(generateLocalSharedImportMap()).then(function (_generateLocalSharedI) {
373
+ return _writeSync.call(localSharedImportMapModule, _generateLocalSharedI);
374
+ });
375
+ }
376
+ }());
377
+ } catch (e) {
378
+ return Promise.reject(e);
379
+ }
380
+ };
381
+ var preBuildCacheMap = {};
382
+ var PREBUILD_TAG = "__prebuild__";
383
+ function writePreBuildLibPath(pkg) {
384
+ if (!preBuildCacheMap[pkg]) preBuildCacheMap[pkg] = new VirtualModule(PREBUILD_TAG + pkg);
385
+ preBuildCacheMap[pkg].writeSync("");
386
+ }
387
+ function getPreBuildLibImportId(pkg) {
388
+ if (!preBuildCacheMap[pkg]) preBuildCacheMap[pkg] = new VirtualModule(PREBUILD_TAG + pkg);
389
+ var importId = preBuildCacheMap[pkg].getImportId();
390
+ return importId;
391
+ }
392
+ var shareds = new Set();
393
+ function addShare(pkg) {
394
+ shareds.add(pkg);
395
+ }
396
+ // *** Expose locally provided shared modules here
397
+ var localSharedImportMapModule = new VirtualModule("localSharedImportMap");
398
+ localSharedImportMapModule.writeSync("");
399
+ function getLocalSharedImportMapId() {
400
+ return localSharedImportMapModule.getPath();
401
+ }
402
+ var prevSharedCount = 0;
403
+ var LOAD_SHARE_TAG = "__loadShare__";
404
+ var loadShareCacheMap = {};
271
405
  function getLoadShareModulePath(pkg) {
272
- var _getNormalizeModuleFe2 = getNormalizeModuleFederationOptions(),
273
- name = _getNormalizeModuleFe2.name;
274
- if (!cacheMap1[pkg]) cacheMap1[pkg] = npmPackageNameToFileName(name) + "_" + ("__mf__loadShare_" + npmPackageNameToFileName(pkg) + ".js");
275
- var filename = cacheMap1[pkg];
276
- return path.resolve(emptyNpmDir, filename);
406
+ if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = new VirtualModule(LOAD_SHARE_TAG + pkg);
407
+ var filepath = loadShareCacheMap[pkg].getPath();
408
+ return filepath;
277
409
  }
278
410
  function writeLoadShareModule(pkg, shareItem, command) {
279
- fs.writeFileSync(getLoadShareModulePath(pkg), "\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 res = 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 ");
280
- }
281
- function npmPackageNameToFileName(packageName) {
282
- // 1. 去掉包名前的 "@"
283
- // 2. 将包名中的 "/" 替换为 "__" 以避免文件路径问题
284
- // 3. 去掉不合法的文件名字符
285
- return packageName.replace(/^@/, '') // 移除作用域前缀 "@"
286
- .replace(/\//g, '__') // 将 "/" 替换为 "__"
287
- .replace(/[^a-zA-Z0-9_.-]/g, '_'); // 替换其他非法字符为 "_"
411
+ 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 {loadShare} = require(\"@module-federation/runtime\")\n const res = 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 ");
288
412
  }
289
413
 
290
- var emptyPath = require.resolve('an-empty-js-file');
291
414
  var REMOTE_ENTRY_ID = 'REMOTE_ENTRY_ID';
292
415
  function generateRemoteEntry(options) {
293
416
  var pluginImportNames = options.runtimePlugins.map(function (p, i) {
@@ -297,30 +420,25 @@ function generateRemoteEntry(options) {
297
420
  return item[1];
298
421
  }).join('\n') + "\n\n const exposesMap = {\n " + Object.keys(options.exposes).map(function (key) {
299
422
  return "\n " + JSON.stringify(key) + ": async () => {\n const importModule = await import(" + JSON.stringify(options.exposes[key]["import"]) + ")\n const exportModule = {}\n Object.assign(exportModule, importModule)\n Object.defineProperty(exportModule, \"__esModule\", {\n value: true,\n enumerable: false\n })\n return exportModule\n }\n ";
300
- }).join(',') + "\n }\n import localSharedImportMap from \"" + getLocalSharedImportMapId() + "\"\n async function init(shared = {}) {\n const localShared = {\n " + Object.keys(options.shared).map(function (key) {
301
- var shareItem = options.shared[key];
302
- return "\n " + JSON.stringify(key) + ": {\n name: " + JSON.stringify(shareItem.name) + ",\n version: " + JSON.stringify(shareItem.version) + ",\n scope: [" + JSON.stringify(shareItem.scope) + "],\n loaded: false,\n from: " + JSON.stringify(options.name) + ",\n async get () {\n localShared[" + JSON.stringify(key) + "].loaded = true\n const {" + JSON.stringify(key) + ": pkgDynamicImport} = localSharedImportMap \n const res = await pkgDynamicImport()\n const exportModule = {...res}\n // All npm packages pre-built by vite will be converted to esm\n Object.defineProperty(exportModule, \"__esModule\", {\n value: true,\n enumerable: false\n })\n return function () {\n return exportModule\n }\n },\n shareConfig: {\n singleton: " + shareItem.shareConfig.singleton + ",\n requiredVersion: " + JSON.stringify(shareItem.shareConfig.requiredVersion) + "\n }\n }\n ";
303
- }).join(',') + "\n }\n const initRes = runtimeInit({\n name: " + JSON.stringify(options.name) + ",\n remotes: [" + Object.keys(options.remotes).map(function (key) {
423
+ }).join(',') + "\n }\n import localSharedImportMap from \"" + getLocalSharedImportMapId() + "\"\n async function init(shared = {}) {\n const initRes = runtimeInit({\n name: " + JSON.stringify(options.name) + ",\n remotes: [" + Object.keys(options.remotes).map(function (key) {
304
424
  var remote = options.remotes[key];
305
425
  return "\n {\n entryGlobalName: " + JSON.stringify(remote.entryGlobalName) + ",\n name: " + JSON.stringify(remote.name) + ",\n type: " + JSON.stringify(remote.type) + ",\n entry: " + JSON.stringify(remote.entry) + ",\n }\n ";
306
- }).join(',') + "\n ],\n shared: localShared,\n plugins: [" + pluginImportNames.map(function (item) {
426
+ }).join(',') + "\n ],\n shared: localSharedImportMap,\n plugins: [" + pluginImportNames.map(function (item) {
307
427
  return item[0] + "()";
308
428
  }).join(', ') + "]\n });\n initRes.initShareScopeMap('" + options.shareScope + "', shared);\n return initRes\n }\n\n function getExposes(moduleName) {\n if (!(moduleName in exposesMap)) throw new Error(`Module ${moduleName} does not exist in container.`)\n return (exposesMap[moduleName])().then(res => () => res)\n }\n export {\n init,\n getExposes as get\n }\n ";
309
429
  }
310
- var WRAP_REMOTE_ENTRY_QUERY_STR = '__mf__wrapRemoteEntry__';
311
- var WRAP_REMOTE_ENTRY_PATH = emptyPath + '?' + WRAP_REMOTE_ENTRY_QUERY_STR;
312
- function generateWrapRemoteEntry() {
313
- return "\n import {init, get} from \"" + REMOTE_ENTRY_ID + "\"\n export {init, get}\n ";
314
- }
430
+ var wrapRemoteEntryModule = new VirtualModule("wrapRemoteEntry");
431
+ wrapRemoteEntryModule.writeSync("\nimport {init, get} from \"" + REMOTE_ENTRY_ID + "\"\nexport {init, get}\n");
432
+ var WRAP_REMOTE_ENTRY_QUERY_STR = wrapRemoteEntryModule.getImportId();
433
+ var WRAP_REMOTE_ENTRY_PATH = wrapRemoteEntryModule.getPath();
315
434
  /**
316
435
  * Inject entry file, automatically init when used as host,
317
436
  * and will not inject remoteEntry
318
437
  */
319
- var HOST_AUTO_INIT_QUERY_STR = '__mf__isHostInit';
320
- var HOST_AUTO_INIT_PATH = emptyPath + '?' + HOST_AUTO_INIT_QUERY_STR;
321
- function generateWrapHostInit() {
322
- return "\n import {init} from \"" + REMOTE_ENTRY_ID + "\"\n init()\n ";
323
- }
438
+ var hostAutoInitModule = new VirtualModule("hostAutoInit");
439
+ hostAutoInitModule.writeSync("\n import {init} from \"" + REMOTE_ENTRY_ID + "\"\n init()\n ");
440
+ var HOST_AUTO_INIT_QUERY_STR = hostAutoInitModule.getImportId();
441
+ var HOST_AUTO_INIT_PATH = hostAutoInitModule.getPath();
324
442
 
325
443
  var filter$1 = pluginutils.createFilter();
326
444
  function pluginProxyRemoteEntry () {
@@ -343,12 +461,6 @@ function pluginProxyRemoteEntry () {
343
461
  if (id.includes(REMOTE_ENTRY_ID)) {
344
462
  return Promise.resolve(generateRemoteEntry(getNormalizeModuleFederationOptions()));
345
463
  }
346
- if (id.includes(WRAP_REMOTE_ENTRY_QUERY_STR)) {
347
- return Promise.resolve(generateWrapRemoteEntry());
348
- }
349
- if (id.includes(HOST_AUTO_INIT_QUERY_STR)) {
350
- return Promise.resolve(generateWrapHostInit());
351
- }
352
464
  return Promise.resolve();
353
465
  } catch (e) {
354
466
  return Promise.reject(e);
@@ -357,6 +469,8 @@ function pluginProxyRemoteEntry () {
357
469
  };
358
470
  }
359
471
 
472
+ var remoteVirtualModule = new VirtualModule("remoteModule");
473
+ remoteVirtualModule.writeSync("");
360
474
  function generateRemotes(id, command) {
361
475
  return {
362
476
  code: "\n import {loadRemote} from \"@module-federation/runtime\"\n const exportModule = await loadRemote(" + JSON.stringify(id) + ")\n " + (command === "build" && "\n export default 'default' in (exportModule || {}) ? exportModule.default : undefined\n export const __mf__dynamicExports = exportModule\n " || "") + "\n " + (command !== "build" && "\n export default exportModule\n " || "") + "\n ",
@@ -384,10 +498,11 @@ function pluginProxyRemotes (options) {
384
498
  find: new RegExp("(" + remote.name + "(/.*|$)?)"),
385
499
  replacement: '$1',
386
500
  customResolver: function customResolver(source) {
501
+ var requestPath = remoteVirtualModule.getImportId() + '?__moduleRemote__=' + encodeURIComponent(source);
387
502
  if (!_config.optimizeDeps) _config.optimizeDeps = {};
388
503
  if (!_config.optimizeDeps.needsInterop) _config.optimizeDeps.needsInterop = [];
389
- if (_config.optimizeDeps.needsInterop.indexOf(source) === -1) _config.optimizeDeps.needsInterop.push(source);
390
- return this.resolve(require.resolve('an-empty-js-file') + '?__moduleRemote__=' + encodeURIComponent(source));
504
+ if (_config.optimizeDeps.needsInterop.indexOf(requestPath) === -1) _config.optimizeDeps.needsInterop.push(requestPath);
505
+ return this.resolve(requestPath);
391
506
  }
392
507
  });
393
508
  });
@@ -413,49 +528,164 @@ function pluginProxyRemotes (options) {
413
528
  };
414
529
  }
415
530
 
531
+ /**
532
+ * example:
533
+ * const store = new PromiseStore<number>();
534
+ * store.get("example").then((result) => {
535
+ * console.log("Result from example:", result); // 42
536
+ * });
537
+ * setTimeout(() => {
538
+ * store.set("example", Promise.resolve(42));
539
+ * }, 2000);
540
+ */
541
+ var PromiseStore = /*#__PURE__*/function () {
542
+ function PromiseStore() {
543
+ this.promiseMap = new Map();
544
+ this.resolveMap = new Map();
545
+ }
546
+ var _proto = PromiseStore.prototype;
547
+ _proto.set = function set(id, promise) {
548
+ if (this.resolveMap.has(id)) {
549
+ promise.then(this.resolveMap.get(id));
550
+ this.resolveMap["delete"](id);
551
+ }
552
+ this.promiseMap.set(id, promise);
553
+ };
554
+ _proto.get = function get(id) {
555
+ var _this = this;
556
+ if (this.promiseMap.has(id)) {
557
+ return this.promiseMap.get(id);
558
+ }
559
+ var pendingPromise = new Promise(function (resolve) {
560
+ _this.resolveMap.set(id, resolve);
561
+ });
562
+ this.promiseMap.set(id, pendingPromise);
563
+ return pendingPromise;
564
+ };
565
+ return PromiseStore;
566
+ }();
567
+
568
+ function wrapManualChunks(output, manualChunksCb) {
569
+ if (!output.manualChunks) output.manualChunks = {};
570
+ var wrapManualChunks = function wrapManualChunks(original) {
571
+ return function (id) {
572
+ var args = [].slice.call(arguments, 1);
573
+ var customRes = manualChunksCb == null ? void 0 : manualChunksCb.apply(void 0, [id].concat(args));
574
+ if (customRes) return customRes;
575
+ if (typeof original === 'function') {
576
+ return original.apply(void 0, [id].concat(args));
577
+ }
578
+ if (typeof original === 'object' && original) {
579
+ return original[id];
580
+ }
581
+ };
582
+ };
583
+ output.manualChunks = wrapManualChunks(output.manualChunks);
584
+ }
585
+
416
586
  function proxySharedModule(options) {
417
587
  var _options$shared = options.shared,
418
588
  shared = _options$shared === void 0 ? {} : _options$shared,
419
589
  include = options.include,
420
590
  exclude = options.exclude;
421
591
  var filterFunction = pluginutils.createFilter(include, exclude);
422
- writeLocalSharedImportMap(Object.keys(shared));
423
592
  return [{
424
- name: 'preBuildShared',
593
+ name: "generateLocalSharedImportMap",
594
+ enforce: "post",
595
+ resolveId: function resolveId(id) {
596
+ if (id.includes(getLocalSharedImportMapId())) return id;
597
+ },
598
+ load: function load(id) {
599
+ if (id.includes(getLocalSharedImportMapId())) {
600
+ return generateLocalSharedImportMap();
601
+ }
602
+ },
603
+ transform: function transform(code, id) {
604
+ if (id.includes(getLocalSharedImportMapId())) {
605
+ return generateLocalSharedImportMap();
606
+ }
607
+ }
608
+ }, {
609
+ name: 'proxyPreBuildShared',
425
610
  enforce: 'post',
426
611
  config: function config(_config, _ref) {
427
612
  var _config$resolve$alias, _config$resolve$alias2;
428
613
  var command = _ref.command;
429
- // config?.optimizeDeps?.include?.push?.("an-empty-js-file");
430
- // config.optimizeDeps.needsInterop.push('an-empty-js-file');
614
+ if (!_config.build) _config.build = {};
615
+ if (!_config.build.rollupOptions) _config.build.rollupOptions = {};
616
+ var rollupOptions = _config.build.rollupOptions;
617
+ if (!rollupOptions.output) rollupOptions.output = {};
618
+ wrapManualChunks(_config.build.rollupOptions.output, function (id) {
619
+ // https://github.com/module-federation/vite/issues/40#issuecomment-2311434503
620
+ if (id.includes('/preload-helper.js')) {
621
+ return "preload-helper";
622
+ }
623
+ if (id.includes("node_modules/@module-federation/runtime")) {
624
+ return "@module-federation/runtime";
625
+ }
626
+ });
431
627
  (_config$resolve$alias = _config.resolve.alias).push.apply(_config$resolve$alias, Object.keys(shared).map(function (key) {
432
- var _config$optimizeDeps;
433
- _config == null || (_config$optimizeDeps = _config.optimizeDeps) == null || (_config$optimizeDeps = _config$optimizeDeps.include) == null || _config$optimizeDeps.push == null || _config$optimizeDeps.push(getPreBuildLibPath(key));
434
- // write proxyFile
435
- writeLoadShareModule(key, shared[key], command);
436
- var preBuildLibPath = getLoadShareModulePath(key);
628
+ var pattern = key.endsWith("/") ? "(^" + key.replace(/\/$/, "") + "(/.+)?$)" : "(^" + key + "$)";
437
629
  return {
438
- // Intercept all dependency requests to the proxy module
439
- // Dependency requests issued by localSharedImportMap are allowed without proxying.
440
- find: new RegExp("^" + key + "$"),
441
- replacement: preBuildLibPath,
630
+ // Intercept all shared requests and proxy them to loadShare
631
+ find: new RegExp(pattern),
632
+ replacement: "$1",
442
633
  customResolver: function customResolver(source, importer) {
443
- if (importer.includes("node_modules/" + key + "/")) {
444
- return this.resolve(key);
445
- }
446
- return this.resolve(preBuildLibPath);
634
+ var _config$optimizeDeps;
635
+ var loadSharePath = getLoadShareModulePath(source);
636
+ _config == null || (_config$optimizeDeps = _config.optimizeDeps) == null || (_config$optimizeDeps = _config$optimizeDeps.needsInterop) == null || _config$optimizeDeps.push(loadSharePath);
637
+ writeLoadShareModule(source, shared[key], command);
638
+ writePreBuildLibPath(source);
639
+ addShare(source);
640
+ writeLocalSharedImportMap();
641
+ return this.resolve(loadSharePath);
447
642
  }
448
643
  };
449
644
  }));
645
+ var savePrebuild = new PromiseStore();
450
646
  (_config$resolve$alias2 = _config.resolve.alias).push.apply(_config$resolve$alias2, Object.keys(shared).map(function (key) {
451
- return {
452
- find: new RegExp("^" + getPreBuildLibPath(key) + "$"),
647
+ return command === "build" ? {
648
+ find: new RegExp(virtualPackageName + "/" + PREBUILD_TAG + "(.+)"),
649
+ replacement: function replacement(_, $1) {
650
+ return packageNameDecode($1);
651
+ }
652
+ } : {
653
+ find: new RegExp(virtualPackageName + "/" + PREBUILD_TAG + "(.+)"),
654
+ replacement: "$1",
453
655
  customResolver: function customResolver(source, importer) {
454
- return this.resolve(key);
656
+ try {
657
+ var _this = this;
658
+ if (importer.includes(LOAD_SHARE_TAG)) {
659
+ // save pre-bunding module id
660
+ savePrebuild.set(source, _this.resolve(packageNameDecode(source)).then(function (item) {
661
+ return item.id;
662
+ }));
663
+ }
664
+ // Fix localSharedImportMap import id
665
+ var _resolve = _this.resolve;
666
+ return Promise.resolve(savePrebuild.get(source)).then(function (_savePrebuild$get) {
667
+ return Promise.resolve(_resolve.call(_this, _savePrebuild$get));
668
+ });
669
+ } catch (e) {
670
+ return Promise.reject(e);
671
+ }
455
672
  }
456
673
  };
457
674
  }));
458
675
  }
676
+ }, {
677
+ name: "watchLocalSharedImportMap",
678
+ apply: "serve",
679
+ config: function config(_config2) {
680
+ _config2.server = defu.defu(_config2.server, {
681
+ watch: {
682
+ ignored: []
683
+ }
684
+ });
685
+ var watch = _config2.server.watch;
686
+ watch.ignored = [].concat(watch.ignored);
687
+ watch.ignored.push("!**/node_modules/" + localSharedImportMapModule.getImportId() + ".js");
688
+ }
459
689
  }, {
460
690
  name: "prebuild-top-level-await",
461
691
  apply: "serve",
@@ -475,7 +705,6 @@ function proxySharedModule(options) {
475
705
  var magicString = new MagicString__default["default"](code);
476
706
  estreeWalker.walk(ast, {
477
707
  enter: function enter(node) {
478
- // 处理命名导出
479
708
  if (node.type === 'ExportNamedDeclaration' && node.specifiers) {
480
709
  var exportSpecifiers = node.specifiers.map(function (specifier) {
481
710
  return specifier.exported.name;
@@ -491,7 +720,6 @@ function proxySharedModule(options) {
491
720
  var replacement = proxyStatements + "\nexport { " + exportStatements + " };";
492
721
  magicString.overwrite(start, end, replacement);
493
722
  }
494
- // 处理默认导出
495
723
  if (node.type === 'ExportDefaultDeclaration') {
496
724
  var declaration = node.declaration;
497
725
  var _start = node.start;
@@ -499,14 +727,14 @@ function proxySharedModule(options) {
499
727
  var proxyStatement;
500
728
  var exportStatement = 'default';
501
729
  if (declaration.type === 'Identifier') {
502
- // 处理标识符 (如: export default foo;)
730
+ // example: export default foo;
503
731
  proxyStatement = "\n const __mfproxy__awaitdefault = await " + declaration.name + "();\n const __mfproxy__default = __mfproxy__awaitdefault;\n ";
504
732
  } else if (declaration.type === 'CallExpression' || declaration.type === 'FunctionDeclaration') {
505
- // 处理调用表达式或函数声明 (如: export default someFunction();)
733
+ // example: export default someFunction();
506
734
  var declarationCode = code.slice(declaration.start, declaration.end);
507
735
  proxyStatement = "\n const __mfproxy__awaitdefault = await (" + declarationCode + ");\n const __mfproxy__default = __mfproxy__awaitdefault;\n ";
508
736
  } else {
509
- // 其他类型 (可以根据需要添加更多处理逻辑)
737
+ // other
510
738
  proxyStatement = "\n const __mfproxy__awaitdefault = await (" + code.slice(declaration.start, declaration.end) + ");\n const __mfproxy__default = __mfproxy__awaitdefault;\n ";
511
739
  }
512
740
  var _replacement = proxyStatement + "\nexport { __mfproxy__default as " + exportStatement + " };";
@@ -543,39 +771,6 @@ var aliasToArrayPlugin = {
543
771
  }
544
772
  };
545
773
 
546
- var normalizeBuildPlugin = (function (singleChunkModules) {
547
- return {
548
- name: 'normalizeBuild',
549
- config: function config(_config, _ref) {
550
- if (!_config.build) _config.build = {};
551
- if (!_config.build.rollupOptions) _config.build.rollupOptions = {};
552
- var rollupOptions = _config.build.rollupOptions;
553
- if (!rollupOptions.output) rollupOptions.output = {};
554
- normalizeManualChunks(rollupOptions.output, singleChunkModules);
555
- }
556
- };
557
- });
558
- function normalizeManualChunks(output, singleChunkModules) {
559
- var pattern = new RegExp("node_modules/(" + singleChunkModules.join('|') + ")/");
560
- if (!output.manualChunks) output.manualChunks = {};
561
- var wrapManualChunks = function wrapManualChunks(original) {
562
- return function (id) {
563
- var _ref2 = id.match(pattern) || [],
564
- moduleName = _ref2[1];
565
- if (moduleName) {
566
- return moduleName;
567
- }
568
- if (typeof original === 'function') {
569
- return original.apply(void 0, [id].concat([].slice.call(arguments, 1)));
570
- }
571
- if (typeof original === 'object' && original) {
572
- return original[id];
573
- }
574
- };
575
- };
576
- output.manualChunks = wrapManualChunks(output.manualChunks);
577
- }
578
-
579
774
  var normalizeOptimizeDepsPlugin = {
580
775
  name: 'normalizeOptimizeDeps',
581
776
  config: function config(_config, _ref) {
@@ -595,14 +790,16 @@ function federation(mfUserOptions) {
595
790
  shared = options.shared,
596
791
  filename = options.filename;
597
792
  if (!name) throw new Error("name is required");
598
- return [aliasToArrayPlugin, normalizeOptimizeDepsPlugin, normalizeBuildPlugin([].concat(Object.keys(shared), ["@module-federation/runtime"]))].concat(addEntry({
793
+ return [aliasToArrayPlugin, normalizeOptimizeDepsPlugin].concat(addEntry({
599
794
  entryName: 'remoteEntry',
600
795
  entryPath: WRAP_REMOTE_ENTRY_PATH,
601
796
  fileName: filename
602
797
  }), addEntry({
603
798
  entryName: 'hostInit',
604
799
  entryPath: HOST_AUTO_INIT_PATH
605
- }), [pluginProxyRemoteEntry(), pluginProxyRemotes(options)], proxySharedModule({
800
+ }), [pluginProxyRemoteEntry(), pluginProxyRemotes(options)], pluginModuleParseEnd(function (id) {
801
+ return id.includes(HOST_AUTO_INIT_QUERY_STR) || id.includes(WRAP_REMOTE_ENTRY_QUERY_STR) || id.includes(REMOTE_ENTRY_ID) || id.includes(getLocalSharedImportMapId());
802
+ }), proxySharedModule({
606
803
  shared: shared
607
804
  }), [{
608
805
  name: 'module-federation-vite',