@module-federation/vite 1.0.0 → 1.1.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.
@@ -12,13 +12,13 @@ const addEntry = ({
12
12
  entryPath,
13
13
  fileName
14
14
  }) => {
15
- const devEntryPath = entryPath.startsWith("virtual:mf") ? "/@id/" + entryPath : entryPath;
15
+ const devEntryPath = entryPath.startsWith('virtual:mf') ? '/@id/' + entryPath : entryPath;
16
16
  let entryFiles = [];
17
17
  let htmlFilePath;
18
18
  let _command;
19
19
  return [{
20
20
  name: 'add-entry',
21
- apply: "serve",
21
+ apply: 'serve',
22
22
  config(config, {
23
23
  command
24
24
  }) {
@@ -47,8 +47,8 @@ const addEntry = ({
47
47
  return c.replace('<head>', `<head><script type="module" src=${JSON.stringify(devEntryPath.replace(/.+?\:([/\\])[/\\]?/, '$1').replace(/\\\\?/g, '/'))}></script>`);
48
48
  }
49
49
  }, {
50
- name: "add-entry",
51
- enforce: "post",
50
+ name: 'add-entry',
51
+ enforce: 'post',
52
52
  configResolved(config) {
53
53
  const inputOptions = config.build.rollupOptions.input;
54
54
  if (!inputOptions) {
@@ -65,8 +65,8 @@ const addEntry = ({
65
65
  }
66
66
  },
67
67
  buildStart() {
68
- if (_command === "serve") return;
69
- const hasHash = fileName == null || fileName.includes == null ? void 0 : fileName.includes("[hash");
68
+ if (_command === 'serve') return;
69
+ const hasHash = fileName == null || fileName.includes == null ? void 0 : fileName.includes('[hash');
70
70
  const emitFileOptions = {
71
71
  name: entryName,
72
72
  type: 'chunk',
@@ -103,10 +103,10 @@ const addEntry = ({
103
103
  function PluginDevProxyModuleTopLevelAwait() {
104
104
  const filterFunction = createFilter();
105
105
  return {
106
- name: "dev-proxy-module-top-level-await",
107
- apply: "serve",
106
+ name: 'dev-proxy-module-top-level-await',
107
+ apply: 'serve',
108
108
  transform(code, id) {
109
- if (!code.includes("/*mf top-level-await placeholder replacement mf*/")) {
109
+ if (!code.includes('/*mf top-level-await placeholder replacement mf*/')) {
110
110
  return null;
111
111
  }
112
112
  if (!filterFunction(id)) return null;
@@ -174,6 +174,18 @@ function PluginDevProxyModuleTopLevelAwait() {
174
174
  };
175
175
  }
176
176
 
177
+ function _extends() {
178
+ return _extends = Object.assign ? Object.assign.bind() : function (n) {
179
+ for (var e = 1; e < arguments.length; e++) {
180
+ var t = arguments[e];
181
+ for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
182
+ }
183
+ return n;
184
+ }, _extends.apply(null, arguments);
185
+ }
186
+
187
+ const warn = message => message.split('\n').forEach(msg => console.warn('\x1b[33m%s\x1b[0m', msg));
188
+
177
189
  function normalizeExposesItem(key, item) {
178
190
  let importPath = '';
179
191
  if (typeof item === 'string') {
@@ -246,7 +258,7 @@ function normalizeShareItem(key, shareItem) {
246
258
  from: '',
247
259
  shareConfig: {
248
260
  singleton: false,
249
- requiredVersion: `^${version}` || '*'
261
+ requiredVersion: version ? `^${version}` : '*'
250
262
  }
251
263
  };
252
264
  }
@@ -257,7 +269,7 @@ function normalizeShareItem(key, shareItem) {
257
269
  scope: shareItem.shareScope || 'default',
258
270
  shareConfig: {
259
271
  singleton: shareItem.singleton || false,
260
- requiredVersion: shareItem.requiredVersion || `^${version}` || '*',
272
+ requiredVersion: shareItem.requiredVersion || (version ? `^${version}` : '*'),
261
273
  strictVersion: !!shareItem.strictVersion
262
274
  }
263
275
  };
@@ -283,13 +295,13 @@ function normalizeLibrary(library) {
283
295
  return library;
284
296
  }
285
297
  function normalizeManifest(manifest = false) {
286
- if (typeof manifest === "boolean") {
298
+ if (typeof manifest === 'boolean') {
287
299
  return manifest;
288
300
  }
289
301
  return Object.assign({
290
- filePath: "",
302
+ filePath: '',
291
303
  disableAssetsAnalyze: false,
292
- fileName: "mf-manifest.json"
304
+ fileName: 'mf-manifest.json'
293
305
  }, manifest);
294
306
  }
295
307
  let config;
@@ -298,10 +310,13 @@ function getNormalizeModuleFederationOptions() {
298
310
  }
299
311
  function getNormalizeShareItem(key) {
300
312
  const options = getNormalizeModuleFederationOptions();
301
- const shareItem = options.shared[removePathFromNpmPackage(key)] || options.shared[removePathFromNpmPackage(key) + "/"];
313
+ const shareItem = options.shared[removePathFromNpmPackage(key)] || options.shared[removePathFromNpmPackage(key) + '/'];
302
314
  return shareItem;
303
315
  }
304
316
  function normalizeModuleFederationOptions(options) {
317
+ if (options.getPublicPath) {
318
+ warn(`We are ignoring the getPublicPath options because they are natively supported by Vite\nwith the "experimental.renderBuiltUrl" configuration https://vitejs.dev/guide/build#advanced-base-options`);
319
+ }
305
320
  return config = {
306
321
  exposes: normalizeExposes(options.exposes),
307
322
  filename: options.filename || 'remoteEntry-[hash]',
@@ -313,11 +328,12 @@ function normalizeModuleFederationOptions(options) {
313
328
  shareScope: options.shareScope || 'default',
314
329
  shared: normalizeShared(options.shared),
315
330
  runtimePlugins: options.runtimePlugins || [],
316
- getPublicPath: options.getPublicPath,
317
331
  implementation: options.implementation,
318
332
  manifest: normalizeManifest(options.manifest),
319
333
  dev: options.dev,
320
- dts: options.dts
334
+ dts: options.dts,
335
+ getPublicPath: options.getPublicPath,
336
+ shareStrategy: options.shareStrategy
321
337
  };
322
338
  }
323
339
 
@@ -335,8 +351,8 @@ function normalizeModuleFederationOptions(options) {
335
351
  * @returns {string} - The encoded file name.
336
352
  */
337
353
  function packageNameEncode(name) {
338
- if (typeof name !== "string") throw new Error("A string package name is required");
339
- return name.replace(/@/g, "_mf_0_").replace(/\//g, "_mf_1_").replace(/-/g, "_mf_2_").replace(/\./g, "_mf_3_");
354
+ if (typeof name !== 'string') throw new Error('A string package name is required');
355
+ return name.replace(/@/g, '_mf_0_').replace(/\//g, '_mf_1_').replace(/-/g, '_mf_2_').replace(/\./g, '_mf_3_');
340
356
  }
341
357
  /**
342
358
  * Decodes an encoded file name back to the original package name.
@@ -344,8 +360,8 @@ function packageNameEncode(name) {
344
360
  * @returns {string} - The decoded package name.
345
361
  */
346
362
  function packageNameDecode(encoded) {
347
- if (typeof encoded !== "string") throw new Error("A string encoded file name is required");
348
- return encoded.replace(/_mf_0_/g, "@").replace(/_mf_1_/g, "/").replace(/_mf_2_/g, "-").replace(/_mf_3_/g, ".");
363
+ if (typeof encoded !== 'string') throw new Error('A string encoded file name is required');
364
+ return encoded.replace(/_mf_0_/g, '@').replace(/_mf_1_/g, '/').replace(/_mf_2_/g, '-').replace(/_mf_3_/g, '.');
349
365
  }
350
366
 
351
367
  /**
@@ -355,11 +371,11 @@ function getLocalSharedImportMapPath_temp() {
355
371
  const {
356
372
  name
357
373
  } = getNormalizeModuleFederationOptions();
358
- return path__default.resolve(".__mf__temp", packageNameEncode(name), "localSharedImportMap");
374
+ return path__default.resolve('.__mf__temp', packageNameEncode(name), 'localSharedImportMap');
359
375
  }
360
376
  function writeLocalSharedImportMap_temp(content) {
361
377
  const localSharedImportMapId = getLocalSharedImportMapPath_temp();
362
- createFile(localSharedImportMapId + ".js", "\n// Windows temporarily needs this file, https://github.com/module-federation/vite/issues/68\n" + content);
378
+ createFile(localSharedImportMapId + '.js', '\n// Windows temporarily needs this file, https://github.com/module-federation/vite/issues/68\n' + content);
363
379
  }
364
380
  function createFile(filePath, content) {
365
381
  const dir = path__default.dirname(filePath);
@@ -378,16 +394,16 @@ const nodeModulesDir = function findNodeModulesDir(startDir = process.cwd()) {
378
394
  }
379
395
  currentDir = dirname(currentDir);
380
396
  }
381
- return "";
397
+ return '';
382
398
  }();
383
- const virtualPackageName = "__mf__virtual";
399
+ const virtualPackageName = '__mf__virtual';
384
400
  if (!existsSync(resolve(nodeModulesDir, virtualPackageName))) {
385
401
  mkdirSync(resolve(nodeModulesDir, virtualPackageName));
386
402
  }
387
- writeFileSync(resolve(nodeModulesDir, virtualPackageName, "empty.js"), "");
388
- writeFileSync(resolve(nodeModulesDir, virtualPackageName, "package.json"), JSON.stringify({
403
+ writeFileSync(resolve(nodeModulesDir, virtualPackageName, 'empty.js'), '');
404
+ writeFileSync(resolve(nodeModulesDir, virtualPackageName, 'package.json'), JSON.stringify({
389
405
  name: virtualPackageName,
390
- main: "empty.js"
406
+ main: 'empty.js'
391
407
  }));
392
408
  const patternMap = {};
393
409
  const cacheMap = {};
@@ -395,13 +411,13 @@ const cacheMap = {};
395
411
  * Physically generate files as virtual modules under node_modules/__mf__virtual/*
396
412
  */
397
413
  class VirtualModule {
398
- static findModule(tag, str = "") {
414
+ static findModule(tag, str = '') {
399
415
  if (!patternMap[tag]) patternMap[tag] = new RegExp(`(.*${packageNameEncode(tag)}(.+?)${packageNameEncode(tag)}.*)`);
400
416
  const moduleName = (str.match(patternMap[tag]) || [])[2];
401
417
  if (moduleName) return cacheMap[tag][packageNameDecode(moduleName)];
402
418
  return undefined;
403
419
  }
404
- constructor(name, tag = '__mf_v__', suffix = "") {
420
+ constructor(name, tag = '__mf_v__', suffix = '') {
405
421
  var _name$split$slice$pop;
406
422
  this.name = void 0;
407
423
  this.tag = void 0;
@@ -409,7 +425,7 @@ class VirtualModule {
409
425
  this.inited = false;
410
426
  this.name = name;
411
427
  this.tag = tag;
412
- this.suffix = suffix || ((_name$split$slice$pop = name.split(".").slice(1).pop()) == null ? void 0 : _name$split$slice$pop.replace(/(.)/, ".$1")) || ".js";
428
+ this.suffix = suffix || ((_name$split$slice$pop = name.split('.').slice(1).pop()) == null ? void 0 : _name$split$slice$pop.replace(/(.)/, '.$1')) || '.js';
413
429
  if (!cacheMap[this.tag]) cacheMap[this.tag] = {};
414
430
  cacheMap[this.tag][this.name] = this;
415
431
  }
@@ -434,7 +450,30 @@ class VirtualModule {
434
450
  }
435
451
  }
436
452
 
437
- const virtualRuntimeInitStatus = new VirtualModule("runtimeInit");
453
+ const VIRTUAL_EXPOSES = 'virtual:mf-exposes';
454
+ function generateExposes() {
455
+ const options = getNormalizeModuleFederationOptions();
456
+ return `
457
+ export default {
458
+ ${Object.keys(options.exposes).map(key => {
459
+ return `
460
+ ${JSON.stringify(key)}: async () => {
461
+ const importModule = await import(${JSON.stringify(options.exposes[key].import)})
462
+ const exportModule = {}
463
+ Object.assign(exportModule, importModule)
464
+ Object.defineProperty(exportModule, "__esModule", {
465
+ value: true,
466
+ enumerable: false
467
+ })
468
+ return exportModule
469
+ }
470
+ `;
471
+ }).join(',')}
472
+ }
473
+ `;
474
+ }
475
+
476
+ const virtualRuntimeInitStatus = new VirtualModule('runtimeInit');
438
477
  function writeRuntimeInitStatus() {
439
478
  virtualRuntimeInitStatus.writeSync(`
440
479
  let initResolve, initReject
@@ -442,7 +481,7 @@ function writeRuntimeInitStatus() {
442
481
  initResolve = re
443
482
  initReject = rj
444
483
  })
445
- export {
484
+ module.exports = {
446
485
  initPromise,
447
486
  initResolve,
448
487
  initReject
@@ -454,7 +493,7 @@ const cacheRemoteMap = {};
454
493
  const LOAD_REMOTE_TAG = '__loadRemote__';
455
494
  function getRemoteVirtualModule(remote, command) {
456
495
  if (!cacheRemoteMap[remote]) {
457
- cacheRemoteMap[remote] = new VirtualModule(remote, LOAD_REMOTE_TAG, ".js");
496
+ cacheRemoteMap[remote] = new VirtualModule(remote, LOAD_REMOTE_TAG, '.js');
458
497
  cacheRemoteMap[remote].writeSync(generateRemotes(remote, command));
459
498
  }
460
499
  const virtual = cacheRemoteMap[remote];
@@ -475,7 +514,7 @@ function generateRemotes(id, command) {
475
514
  const {loadRemote} = require("@module-federation/runtime")
476
515
  const {initPromise} = require("${virtualRuntimeInitStatus.getImportId()}")
477
516
  const res = initPromise.then(_ => loadRemote(${JSON.stringify(id)}))
478
- const exportModule = ${command !== "build" ? "/*mf top-level-await placeholder replacement mf*/" : "await "}initPromise.then(_ => res)
517
+ const exportModule = ${command !== 'build' ? '/*mf top-level-await placeholder replacement mf*/' : 'await '}initPromise.then(_ => res)
479
518
  module.exports = exportModule
480
519
  `;
481
520
  }
@@ -487,10 +526,10 @@ function generateRemotes(id, command) {
487
526
  */
488
527
  // *** __prebuild__
489
528
  const preBuildCacheMap = {};
490
- const PREBUILD_TAG = "__prebuild__";
529
+ const PREBUILD_TAG = '__prebuild__';
491
530
  function writePreBuildLibPath(pkg) {
492
531
  if (!preBuildCacheMap[pkg]) preBuildCacheMap[pkg] = new VirtualModule(pkg, PREBUILD_TAG);
493
- preBuildCacheMap[pkg].writeSync("");
532
+ preBuildCacheMap[pkg].writeSync('');
494
533
  }
495
534
  function getPreBuildLibImportId(pkg) {
496
535
  if (!preBuildCacheMap[pkg]) preBuildCacheMap[pkg] = new VirtualModule(pkg, PREBUILD_TAG);
@@ -498,10 +537,10 @@ function getPreBuildLibImportId(pkg) {
498
537
  return importId;
499
538
  }
500
539
  // *** __loadShare__
501
- const LOAD_SHARE_TAG = "__loadShare__";
540
+ const LOAD_SHARE_TAG = '__loadShare__';
502
541
  const loadShareCacheMap = {};
503
542
  function getLoadShareModulePath(pkg) {
504
- if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = new VirtualModule(pkg, LOAD_SHARE_TAG, ".js");
543
+ if (!loadShareCacheMap[pkg]) loadShareCacheMap[pkg] = new VirtualModule(pkg, LOAD_SHARE_TAG, '.js');
505
544
  const filepath = loadShareCacheMap[pkg].getPath();
506
545
  return filepath;
507
546
  }
@@ -510,7 +549,7 @@ function writeLoadShareModule(pkg, shareItem, command) {
510
549
 
511
550
  ;() => import(${JSON.stringify(getPreBuildLibImportId(pkg))}).catch(() => {});
512
551
  // dev uses dynamic import to separate chunks
513
- ${command !== "build" ? `;() => import(${JSON.stringify(pkg)}).catch(() => {});` : ''}
552
+ ${command !== 'build' ? `;() => import(${JSON.stringify(pkg)}).catch(() => {});` : ''}
514
553
  const {loadShare} = require("@module-federation/runtime")
515
554
  const {initPromise} = require("${virtualRuntimeInitStatus.getImportId()}")
516
555
  const res = initPromise.then(_ => loadShare(${JSON.stringify(pkg)}, {
@@ -519,7 +558,7 @@ function writeLoadShareModule(pkg, shareItem, command) {
519
558
  strictVersion: ${shareItem.shareConfig.strictVersion},
520
559
  requiredVersion: ${JSON.stringify(shareItem.shareConfig.requiredVersion)}
521
560
  }}}))
522
- const exportModule = ${command !== "build" ? "/*mf top-level-await placeholder replacement mf*/" : "await "}res.then(factory => factory())
561
+ const exportModule = ${command !== 'build' ? '/*mf top-level-await placeholder replacement mf*/' : 'await '}res.then(factory => factory())
523
562
  module.exports = exportModule
524
563
  `);
525
564
  }
@@ -532,7 +571,7 @@ function addUsedShares(pkg) {
532
571
  usedShares.add(pkg);
533
572
  }
534
573
  // *** Expose locally provided shared modules here
535
- new VirtualModule("localSharedImportMap");
574
+ new VirtualModule('localSharedImportMap');
536
575
  function getLocalSharedImportMapPath() {
537
576
  return getLocalSharedImportMapPath_temp();
538
577
  // return localSharedImportMapModule.getPath()
@@ -555,7 +594,7 @@ function generateLocalSharedImportMap() {
555
594
  let pkg = await import("${getPreBuildLibImportId(pkg)}")
556
595
  return pkg
557
596
  }
558
- `).join(",")}
597
+ `).join(',')}
559
598
  }
560
599
  const usedShared = {
561
600
  ${Array.from(getUsedShares()).map(key => {
@@ -613,23 +652,7 @@ function generateRemoteEntry(options) {
613
652
  return `
614
653
  import {init as runtimeInit, loadRemote} from "@module-federation/runtime";
615
654
  ${pluginImportNames.map(item => item[1]).join('\n')}
616
-
617
- const exposesMap = {
618
- ${Object.keys(options.exposes).map(key => {
619
- return `
620
- ${JSON.stringify(key)}: async () => {
621
- const importModule = await import(${JSON.stringify(options.exposes[key].import)})
622
- const exportModule = {}
623
- Object.assign(exportModule, importModule)
624
- Object.defineProperty(exportModule, "__esModule", {
625
- value: true,
626
- enumerable: false
627
- })
628
- return exportModule
629
- }
630
- `;
631
- }).join(',')}
632
- }
655
+ import exposesMap from "${VIRTUAL_EXPOSES}"
633
656
  import {usedShared, usedRemotes} from "${getLocalSharedImportMapPath()}"
634
657
  import {
635
658
  initResolve
@@ -639,7 +662,8 @@ function generateRemoteEntry(options) {
639
662
  name: ${JSON.stringify(options.name)},
640
663
  remotes: usedRemotes,
641
664
  shared: usedShared,
642
- plugins: [${pluginImportNames.map(item => `${item[0]}()`).join(', ')}]
665
+ plugins: [${pluginImportNames.map(item => `${item[0]}()`).join(', ')}],
666
+ ${options.shareStrategy ? `shareStrategy: ${options.shareStrategy}` : ''}
643
667
  });
644
668
  initRes.initShareScopeMap('${options.shareScope}', shared);
645
669
  initResolve(initRes)
@@ -660,7 +684,7 @@ function generateRemoteEntry(options) {
660
684
  * Inject entry file, automatically init when used as host,
661
685
  * and will not inject remoteEntry
662
686
  */
663
- const hostAutoInitModule = new VirtualModule("hostAutoInit");
687
+ const hostAutoInitModule = new VirtualModule('hostAutoInit');
664
688
  function writeHostAutoInit() {
665
689
  hostAutoInitModule.writeSync(`
666
690
  import {init} from "${REMOTE_ENTRY_ID}"
@@ -685,14 +709,15 @@ const Manifest = () => {
685
709
  const {
686
710
  name,
687
711
  filename,
712
+ getPublicPath,
688
713
  manifest: manifestOptions
689
714
  } = mfOptions;
690
- let mfManifestName = "";
715
+ let mfManifestName = '';
691
716
  if (manifestOptions === true) {
692
- mfManifestName = "mf-manifest.json";
717
+ mfManifestName = 'mf-manifest.json';
693
718
  }
694
- if (typeof manifestOptions !== "boolean") {
695
- mfManifestName = join((manifestOptions == null ? void 0 : manifestOptions.filePath) || "", (manifestOptions == null ? void 0 : manifestOptions.fileName) || "");
719
+ if (typeof manifestOptions !== 'boolean') {
720
+ mfManifestName = join((manifestOptions == null ? void 0 : manifestOptions.filePath) || '', (manifestOptions == null ? void 0 : manifestOptions.fileName) || '');
696
721
  }
697
722
  let extensions;
698
723
  let root;
@@ -700,7 +725,7 @@ const Manifest = () => {
700
725
  let publicPath;
701
726
  let _command;
702
727
  return [{
703
- name: 'moddule-federation-manifest',
728
+ name: 'module-federation-manifest',
704
729
  apply: 'serve',
705
730
  configureServer(server) {
706
731
  server.middlewares.use((req, res, next) => {
@@ -708,10 +733,10 @@ const Manifest = () => {
708
733
  next();
709
734
  return;
710
735
  }
711
- if (req.url === mfManifestName.replace(/^\/?/, "/")) {
736
+ if (req.url === mfManifestName.replace(/^\/?/, '/')) {
712
737
  res.setHeader('Content-Type', 'application/json');
713
738
  res.setHeader('Access-Control-Allow-Origin', '*');
714
- res.end(JSON.stringify({
739
+ res.end(JSON.stringify(_extends({}, generateMFManifest({}), {
715
740
  id: name,
716
741
  name: name,
717
742
  metaData: {
@@ -738,68 +763,15 @@ const Manifest = () => {
738
763
  globalName: name,
739
764
  pluginVersion: '0.2.5',
740
765
  publicPath
741
- },
742
- shared: Array.from(getUsedShares()).map(shareKey => {
743
- const shareItem = getNormalizeShareItem(shareKey);
744
- return {
745
- id: `${name}:${shareKey}`,
746
- name: shareKey,
747
- version: shareItem.version,
748
- requiredVersion: shareItem.shareConfig.requiredVersion,
749
- assets: {
750
- js: {
751
- async: [],
752
- sync: []
753
- },
754
- css: {
755
- async: [],
756
- sync: []
757
- }
758
- }
759
- };
760
- }),
761
- remotes: function () {
762
- const remotes = [];
763
- const usedRemotesMap = getUsedRemotesMap();
764
- Object.keys(usedRemotesMap).forEach(remoteKey => {
765
- const usedModules = Array.from(usedRemotesMap[remoteKey]);
766
- usedModules.forEach(moduleKey => {
767
- remotes.push({
768
- federationContainerName: mfOptions.remotes[remoteKey].entry,
769
- moduleName: moduleKey.replace(remoteKey, '').replace('/', ''),
770
- alias: remoteKey,
771
- entry: '*'
772
- });
773
- });
774
- });
775
- return remotes;
776
- }(),
777
- exposes: Object.keys(mfOptions.exposes).map(key => {
778
- const formatKey = key.replace('./', '');
779
- return {
780
- id: name + ':' + formatKey,
781
- name: formatKey,
782
- assets: {
783
- js: {
784
- async: [],
785
- sync: []
786
- },
787
- css: {
788
- sync: [],
789
- async: []
790
- }
791
- },
792
- path: key
793
- };
794
- })
795
- }));
766
+ }
767
+ })));
796
768
  } else {
797
769
  next();
798
770
  }
799
771
  });
800
772
  }
801
773
  }, {
802
- name: 'moddule-federation-manifest',
774
+ name: 'module-federation-manifest',
803
775
  enforce: 'post',
804
776
  config(config, {
805
777
  command
@@ -811,10 +783,10 @@ const Manifest = () => {
811
783
  configResolved(config) {
812
784
  root = config.root;
813
785
  extensions = config.resolve.extensions || ['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json'];
814
- publicPath = config.base ? config.base.replace(/\/?$/, "/") : "auto";
815
- if (_command === "serve") {
786
+ publicPath = config.base ? config.base.replace(/\/?$/, '/') : 'auto';
787
+ if (_command === 'serve') {
816
788
  const origin = config.server.origin;
817
- publicPath = origin ? origin.replace(/\/?$/, "/") : "auto";
789
+ publicPath = origin ? origin.replace(/\/?$/, '/') : 'auto';
818
790
  }
819
791
  },
820
792
  async generateBundle(options, bundle) {
@@ -835,7 +807,7 @@ const Manifest = () => {
835
807
  };
836
808
  // 遍历打包生成的每个文件
837
809
  for (const [fileName, fileData] of Object.entries(bundle)) {
838
- if (mfOptions.filename.replace(/[\[\]]/g, "_") === fileData.name || fileData.name === "remoteEntry") {
810
+ if (mfOptions.filename.replace(/[\[\]]/g, '_') === fileData.name || fileData.name === 'remoteEntry') {
839
811
  remoteEntryFile = fileData.fileName;
840
812
  }
841
813
  if (fileData.type === 'chunk') {
@@ -845,7 +817,7 @@ const Manifest = () => {
845
817
  const relativeModulePath = relative(root, modulePath);
846
818
  // 检查模块是否在 preloadModules 列表中
847
819
  for (const preloadModule of exposesModules) {
848
- const formatPreloadModule = preloadModule.replace("./", "");
820
+ const formatPreloadModule = preloadModule.replace('./', '');
849
821
  if (isModuleMatched(relativeModulePath, formatPreloadModule)) {
850
822
  if (!filesContainingModules[preloadModule]) {
851
823
  filesContainingModules[preloadModule] = {
@@ -878,7 +850,7 @@ const Manifest = () => {
878
850
  }
879
851
  const fileToShareKey = {};
880
852
  await Promise.all(Array.from(getUsedShares()).map(async shareKey => {
881
- const file = (await this.resolve(getPreBuildLibImportId(shareKey))).id.split("?")[0];
853
+ const file = (await this.resolve(getPreBuildLibImportId(shareKey))).id.split('?')[0];
882
854
  fileToShareKey[file] = shareKey;
883
855
  }));
884
856
  // 遍历打包生成的每个文件
@@ -909,7 +881,7 @@ const Manifest = () => {
909
881
  this.emitFile({
910
882
  type: 'asset',
911
883
  fileName: mfManifestName,
912
- source: generateMFManifest(filesContainingModules)
884
+ source: JSON.stringify(generateMFManifest(filesContainingModules))
913
885
  });
914
886
  }
915
887
  }];
@@ -938,8 +910,7 @@ const Manifest = () => {
938
910
  });
939
911
  // @ts-ignore
940
912
  const shared = Array.from(getUsedShares()).map(shareKey => {
941
- // assets(.css, .jpg, .svg等)其他资源, 不重要, 暂未处理
942
- if (!preloadMap[shareKey]) return;
913
+ var _preloadMap$shareKey, _preloadMap$shareKey2;
943
914
  const shareItem = getNormalizeShareItem(shareKey);
944
915
  return {
945
916
  id: `${name}:${shareKey}`,
@@ -948,8 +919,8 @@ const Manifest = () => {
948
919
  requiredVersion: shareItem.shareConfig.requiredVersion,
949
920
  assets: {
950
921
  js: {
951
- async: preloadMap[shareKey].async,
952
- sync: preloadMap[shareKey].sync
922
+ async: (preloadMap == null || (_preloadMap$shareKey = preloadMap[shareKey]) == null ? void 0 : _preloadMap$shareKey.async) || [],
923
+ sync: (preloadMap == null || (_preloadMap$shareKey2 = preloadMap[shareKey]) == null ? void 0 : _preloadMap$shareKey2.sync) || []
953
924
  },
954
925
  css: {
955
926
  async: [],
@@ -959,17 +930,17 @@ const Manifest = () => {
959
930
  };
960
931
  }).filter(item => item);
961
932
  const exposes = Object.keys(options.exposes).map(key => {
933
+ var _preloadMap$sourceFil, _preloadMap$sourceFil2;
962
934
  // assets(.css, .jpg, .svg等)其他资源, 不重要, 暂未处理
963
935
  const formatKey = key.replace('./', '');
964
936
  const sourceFile = options.exposes[key].import;
965
- if (!preloadMap[sourceFile]) return;
966
937
  return {
967
938
  id: name + ':' + formatKey,
968
939
  name: formatKey,
969
940
  assets: {
970
941
  js: {
971
- async: preloadMap[sourceFile].async,
972
- sync: preloadMap[sourceFile].sync
942
+ async: (preloadMap == null || (_preloadMap$sourceFil = preloadMap[sourceFile]) == null ? void 0 : _preloadMap$sourceFil.async) || [],
943
+ sync: (preloadMap == null || (_preloadMap$sourceFil2 = preloadMap[sourceFile]) == null ? void 0 : _preloadMap$sourceFil2.sync) || []
973
944
  },
974
945
  css: {
975
946
  sync: [],
@@ -982,7 +953,7 @@ const Manifest = () => {
982
953
  const result = {
983
954
  id: name,
984
955
  name: name,
985
- metaData: {
956
+ metaData: _extends({
986
957
  name: name,
987
958
  type: 'app',
988
959
  buildInfo: {
@@ -998,14 +969,17 @@ const Manifest = () => {
998
969
  // "api": "@mf-types.d.ts"
999
970
  },
1000
971
  globalName: name,
1001
- pluginVersion: '0.2.5',
972
+ pluginVersion: '0.2.5'
973
+ }, !!getPublicPath ? {
974
+ getPublicPath
975
+ } : {
1002
976
  publicPath
1003
- },
977
+ }),
1004
978
  shared,
1005
979
  remotes,
1006
980
  exposes
1007
981
  };
1008
- return JSON.stringify(result);
982
+ return result;
1009
983
  }
1010
984
  };
1011
985
 
@@ -1014,20 +988,21 @@ let _resolve,
1014
988
  _resolve = resolve;
1015
989
  });
1016
990
  let parsePromise = promise;
991
+ let exposesParseEnd = false;
1017
992
  const parseStartSet = new Set();
1018
993
  const parseEndSet = new Set();
1019
994
  function pluginModuleParseEnd (excludeFn) {
1020
995
  return [{
1021
- name: "_",
1022
- apply: "serve",
996
+ name: '_',
997
+ apply: 'serve',
1023
998
  config() {
1024
999
  // No waiting in development mode
1025
1000
  _resolve(1);
1026
1001
  }
1027
1002
  }, {
1028
- enforce: "pre",
1029
- name: "parseStart",
1030
- apply: "build",
1003
+ enforce: 'pre',
1004
+ name: 'parseStart',
1005
+ apply: 'build',
1031
1006
  load(id) {
1032
1007
  if (excludeFn(id)) {
1033
1008
  return;
@@ -1035,16 +1010,20 @@ function pluginModuleParseEnd (excludeFn) {
1035
1010
  parseStartSet.add(id);
1036
1011
  }
1037
1012
  }, {
1038
- enforce: "post",
1039
- name: "parseEnd",
1040
- apply: "build",
1013
+ enforce: 'post',
1014
+ name: 'parseEnd',
1015
+ apply: 'build',
1041
1016
  moduleParsed(module) {
1042
1017
  const id = module.id;
1043
1018
  if (excludeFn(id)) {
1044
1019
  return;
1045
1020
  }
1021
+ if (id === VIRTUAL_EXPOSES) {
1022
+ // When the entry JS file is empty and only contains exposes export code, it’s necessary to wait for the exposes modules to be resolved in order to collect the dependencies being used.
1023
+ exposesParseEnd = true;
1024
+ }
1046
1025
  parseEndSet.add(id);
1047
- if (parseStartSet.size === parseEndSet.size) {
1026
+ if (exposesParseEnd && parseStartSet.size === parseEndSet.size) {
1048
1027
  _resolve(1);
1049
1028
  }
1050
1029
  }
@@ -1060,17 +1039,26 @@ function pluginProxyRemoteEntry () {
1060
1039
  if (id === REMOTE_ENTRY_ID) {
1061
1040
  return REMOTE_ENTRY_ID;
1062
1041
  }
1042
+ if (id === VIRTUAL_EXPOSES) {
1043
+ return VIRTUAL_EXPOSES;
1044
+ }
1063
1045
  },
1064
1046
  load(id) {
1065
1047
  if (id === REMOTE_ENTRY_ID) {
1066
1048
  return parsePromise.then(_ => generateRemoteEntry(getNormalizeModuleFederationOptions()));
1067
1049
  }
1050
+ if (id === VIRTUAL_EXPOSES) {
1051
+ return generateExposes();
1052
+ }
1068
1053
  },
1069
1054
  async transform(code, id) {
1070
1055
  if (!filter(id)) return;
1071
1056
  if (id.includes(REMOTE_ENTRY_ID)) {
1072
1057
  return parsePromise.then(_ => generateRemoteEntry(getNormalizeModuleFederationOptions()));
1073
1058
  }
1059
+ if (id === VIRTUAL_EXPOSES) {
1060
+ return generateExposes();
1061
+ }
1074
1062
  }
1075
1063
  };
1076
1064
  }
@@ -1081,7 +1069,7 @@ function pluginProxyRemotes (options) {
1081
1069
  remotes
1082
1070
  } = options;
1083
1071
  return {
1084
- name: "proxyRemotes",
1072
+ name: 'proxyRemotes',
1085
1073
  config(config, {
1086
1074
  command: _command
1087
1075
  }) {
@@ -1089,7 +1077,7 @@ function pluginProxyRemotes (options) {
1089
1077
  const remote = remotes[key];
1090
1078
  config.resolve.alias.push({
1091
1079
  find: new RegExp(`^(${remote.name}(\/.*|$))`),
1092
- replacement: "$1",
1080
+ replacement: '$1',
1093
1081
  customResolver(source) {
1094
1082
  const remoteModule = getRemoteVirtualModule(source, _command);
1095
1083
  addUsedRemote(remote.name, source);
@@ -1143,8 +1131,8 @@ function proxySharedModule(options) {
1143
1131
  } = options;
1144
1132
  let _config;
1145
1133
  return [{
1146
- name: "generateLocalSharedImportMap",
1147
- enforce: "post",
1134
+ name: 'generateLocalSharedImportMap',
1135
+ enforce: 'post',
1148
1136
  load(id) {
1149
1137
  if (id.includes(getLocalSharedImportMapPath())) {
1150
1138
  return parsePromise.then(_ => generateLocalSharedImportMap());
@@ -1165,11 +1153,11 @@ function proxySharedModule(options) {
1165
1153
  command
1166
1154
  }) {
1167
1155
  config.resolve.alias.push(...Object.keys(shared).map(key => {
1168
- const pattern = key.endsWith("/") ? `(^${key.replace(/\/$/, "")}(\/.+)?$)` : `(^${key}$)`;
1156
+ const pattern = key.endsWith('/') ? `(^${key.replace(/\/$/, '')}(\/.+)?$)` : `(^${key}$)`;
1169
1157
  return {
1170
1158
  // Intercept all shared requests and proxy them to loadShare
1171
1159
  find: new RegExp(pattern),
1172
- replacement: "$1",
1160
+ replacement: '$1',
1173
1161
  customResolver(source, importer) {
1174
1162
  if (/\.css$/.test(source)) return;
1175
1163
  const loadSharePath = getLoadShareModulePath(source);
@@ -1183,7 +1171,7 @@ function proxySharedModule(options) {
1183
1171
  }));
1184
1172
  const savePrebuild = new PromiseStore();
1185
1173
  config.resolve.alias.push(...Object.keys(shared).map(key => {
1186
- return command === "build" ? {
1174
+ return command === 'build' ? {
1187
1175
  find: new RegExp(`(.*${PREBUILD_TAG}.*)`),
1188
1176
  replacement: function ($1) {
1189
1177
  const pkgName = VirtualModule.findModule(PREBUILD_TAG, $1).name;
@@ -1191,7 +1179,7 @@ function proxySharedModule(options) {
1191
1179
  }
1192
1180
  } : {
1193
1181
  find: new RegExp(`(.*${PREBUILD_TAG}.*)`),
1194
- replacement: "$1",
1182
+ replacement: '$1',
1195
1183
  async customResolver(source, importer) {
1196
1184
  const pkgName = VirtualModule.findModule(PREBUILD_TAG, source).name;
1197
1185
  const result = await this.resolve(pkgName).then(item => item.id);
@@ -1206,8 +1194,8 @@ function proxySharedModule(options) {
1206
1194
  }));
1207
1195
  }
1208
1196
  }, {
1209
- name: "watchLocalSharedImportMap",
1210
- apply: "serve",
1197
+ name: 'watchLocalSharedImportMap',
1198
+ apply: 'serve',
1211
1199
  config(config) {
1212
1200
  config.optimizeDeps = defu(config.optimizeDeps, {
1213
1201
  exclude: [getLocalSharedImportMapPath()]
@@ -1271,7 +1259,7 @@ function federation(mfUserOptions) {
1271
1259
  shared,
1272
1260
  filename
1273
1261
  } = options;
1274
- if (!name) throw new Error("name is required");
1262
+ if (!name) throw new Error('name is required');
1275
1263
  return [aliasToArrayPlugin, normalizeOptimizeDepsPlugin, ...addEntry({
1276
1264
  entryName: 'remoteEntry',
1277
1265
  entryPath: REMOTE_ENTRY_ID,
@@ -1279,6 +1267,9 @@ function federation(mfUserOptions) {
1279
1267
  }), ...addEntry({
1280
1268
  entryName: 'hostInit',
1281
1269
  entryPath: getHostAutoInitPath()
1270
+ }), ...addEntry({
1271
+ entryName: 'virtualExposes',
1272
+ entryPath: VIRTUAL_EXPOSES
1282
1273
  }), pluginProxyRemoteEntry(), pluginProxyRemotes(options), ...pluginModuleParseEnd(id => {
1283
1274
  return id.includes(getHostAutoInitImportId()) || id.includes(REMOTE_ENTRY_ID) || id.includes(getLocalSharedImportMapPath());
1284
1275
  }), ...proxySharedModule({
@@ -1289,12 +1280,15 @@ function federation(mfUserOptions) {
1289
1280
  config(config, {
1290
1281
  command: _command
1291
1282
  }) {
1292
- var _config$optimizeDeps;
1283
+ var _config$optimizeDeps, _config$optimizeDeps2, _config$optimizeDeps3;
1284
+ // TODO: singleton
1293
1285
  config.resolve.alias.push({
1294
1286
  find: '@module-federation/runtime',
1295
1287
  replacement: require.resolve('@module-federation/runtime')
1296
1288
  });
1297
1289
  (_config$optimizeDeps = config.optimizeDeps) == null || (_config$optimizeDeps = _config$optimizeDeps.include) == null || _config$optimizeDeps.push('@module-federation/runtime');
1290
+ (_config$optimizeDeps2 = config.optimizeDeps) == null || (_config$optimizeDeps2 = _config$optimizeDeps2.include) == null || _config$optimizeDeps2.push('__mf__virtual');
1291
+ (_config$optimizeDeps3 = config.optimizeDeps) == null || (_config$optimizeDeps3 = _config$optimizeDeps3.needsInterop) == null || _config$optimizeDeps3.push('__mf__virtual');
1298
1292
  }
1299
1293
  }, ...Manifest()];
1300
1294
  }