@module-federation/runtime 0.0.0-next-20241101093646 → 0.0.0-next-20241104024700

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/dist/index.esm.js CHANGED
@@ -1,8 +1,8 @@
1
- import { _ as _extends, a as _object_without_properties_loose } from './polyfills.esm.js';
2
- import { isBrowserEnv, loadScriptNode, composeKeyWithSeparator, loadScript, safeToString, createLink, createScript, getResourceUrl, isManifestProvider, generateSnapshotFromManifest, warn } from '@module-federation/sdk';
1
+ import { a as _extends, _ as _object_without_properties_loose } from './polyfills.esm.js';
2
+ import { isBrowserEnv, loadScriptNode, composeKeyWithSeparator, loadScript, safeToString, createLink, createScript, getResourceUrl, isManifestProvider, generateSnapshotFromManifest, warn as warn$1 } from '@module-federation/sdk';
3
3
  export { loadScript, loadScriptNode } from '@module-federation/sdk';
4
- import { w as globalLoading, D as DEFAULT_REMOTE_TYPE, x as DEFAULT_SCOPE, o as getRemoteEntryExports, y as assert, z as getFMId, B as processModuleAlias, C as isRemoteInfoWithEntry, E as isPureRemoteEntry, F as getRemoteEntryInfoFromSnapshot, H as error, h as getInfoWithoutType, t as getPreloaded, u as setPreloaded, g as getRegisteredShare, I as arrayOptions, k as getGlobalSnapshotInfoByModuleInfo, m as addGlobalSnapshot, l as setGlobalSnapshotInfoByModuleInfo, P as PluginSystem, A as AsyncHook, a as AsyncWaterfallHook, G as Global, i as getGlobalSnapshot, J as formatShareConfigs, K as getTargetSharedOptions, c as getGlobalShareScope, b as SyncWaterfallHook, L as addUniqueItem, S as SyncHook, v as registerPlugins$1, M as getBuilderId, f as setGlobalFederationConstructor, d as getGlobalFederationInstance, e as getGlobalFederationConstructor, s as setGlobalFederationInstance } from './share.esm.js';
5
- export { p as registerGlobalPlugins } from './share.esm.js';
4
+ import { o as getGlobalHostPlugins, t as globalLoading, D as DEFAULT_REMOTE_TYPE, u as DEFAULT_SCOPE, l as getRemoteEntryExports, v as assert, w as logger, x as getFMId, y as isObject, z as error, A as warn, B as isPlainObject, C as isRemoteInfoWithEntry, E as isPureRemoteEntry, F as getRemoteEntryInfoFromSnapshot, e as getInfoWithoutType, p as getPreloaded, q as setPreloaded, g as getRegisteredShare, H as arrayOptions, i as getGlobalSnapshotInfoByModuleInfo, k as addGlobalSnapshot, j as setGlobalSnapshotInfoByModuleInfo, G as Global, f as getGlobalSnapshot, I as formatShareConfigs, J as getTargetSharedOptions, a as getGlobalShareScope, K as addUniqueItem, L as getBuilderId, d as setGlobalFederationConstructor, b as getGlobalFederationInstance, c as getGlobalFederationConstructor, s as setGlobalFederationInstance } from './share.esm.js';
5
+ export { m as registerGlobalPlugins } from './share.esm.js';
6
6
 
7
7
  // Function to match a remote with its name and expose
8
8
  // id: pkgName(@federation/app1) + expose(button) = @federation/app1/button
@@ -68,6 +68,26 @@ function matchRemote(remotes, nameOrAlias) {
68
68
  return;
69
69
  }
70
70
 
71
+ function registerPlugins$1(plugins, hookInstances) {
72
+ const globalPlugins = getGlobalHostPlugins();
73
+ // Incorporate global plugins
74
+ if (globalPlugins.length > 0) {
75
+ globalPlugins.forEach((plugin)=>{
76
+ if (plugins == null ? void 0 : plugins.find((item)=>item.name !== plugin.name)) {
77
+ plugins.push(plugin);
78
+ }
79
+ });
80
+ }
81
+ if (plugins && plugins.length > 0) {
82
+ plugins.forEach((plugin)=>{
83
+ hookInstances.forEach((hookInstance)=>{
84
+ hookInstance.applyPlugin(plugin);
85
+ });
86
+ });
87
+ }
88
+ return plugins;
89
+ }
90
+
71
91
  async function loadEsmEntry({ entry, remoteEntryExports }) {
72
92
  return new Promise((resolve, reject)=>{
73
93
  try {
@@ -285,7 +305,7 @@ let Module = class Module {
285
305
  origin: this.host
286
306
  });
287
307
  if (typeof (remoteEntryExports == null ? void 0 : remoteEntryExports.init) === 'undefined') {
288
- console.error('The remote entry interface does not contain "init"', '\n', 'Ensure the name of this remote is not reserved or in use. Check if anything already exists on window[nameOfRemote]', '\n', 'Ensure that window[nameOfRemote] is returning a {get,init} object.');
308
+ logger.error('The remote entry interface does not contain "init"', '\n', 'Ensure the name of this remote is not reserved or in use. Check if anything already exists on window[nameOfRemote]', '\n', 'Ensure that window[nameOfRemote] is returning a {get,init} object.');
289
309
  }
290
310
  await remoteEntryExports.init(initContainerOptions.shareScope, initContainerOptions.initScope, initContainerOptions.remoteEntryInitOptions);
291
311
  await this.host.hooks.lifecycle.initContainer.emit(_extends({}, initContainerOptions, {
@@ -296,12 +316,18 @@ let Module = class Module {
296
316
  }
297
317
  this.lib = remoteEntryExports;
298
318
  this.inited = true;
319
+ let moduleFactory;
320
+ moduleFactory = await this.host.loaderHook.lifecycle.getModuleFactory.emit({
321
+ remoteEntryExports,
322
+ expose,
323
+ moduleInfo: this.remoteInfo
324
+ });
299
325
  // get exposeGetter
300
- const moduleFactory = await remoteEntryExports.get(expose);
326
+ if (!moduleFactory) {
327
+ moduleFactory = await remoteEntryExports.get(expose);
328
+ }
301
329
  assert(moduleFactory, `${getFMId(this.remoteInfo)} remote don't export ${expose}.`);
302
- // keep symbol for module name always one format
303
- const symbolName = processModuleAlias(this.remoteInfo.name, expose);
304
- const wrapModuleFactory = this.wraperFactory(moduleFactory, symbolName);
330
+ const wrapModuleFactory = this.wraperFactory(moduleFactory, id);
305
331
  if (!loadFactory) {
306
332
  return wrapModuleFactory;
307
333
  }
@@ -341,6 +367,191 @@ let Module = class Module {
341
367
  }
342
368
  };
343
369
 
370
+ class SyncHook {
371
+ on(fn) {
372
+ if (typeof fn === 'function') {
373
+ this.listeners.add(fn);
374
+ }
375
+ }
376
+ once(fn) {
377
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
378
+ const self = this;
379
+ this.on(function wrapper(...args) {
380
+ self.remove(wrapper);
381
+ // eslint-disable-next-line prefer-spread
382
+ return fn.apply(null, args);
383
+ });
384
+ }
385
+ emit(...data) {
386
+ let result;
387
+ if (this.listeners.size > 0) {
388
+ // eslint-disable-next-line prefer-spread
389
+ this.listeners.forEach((fn)=>{
390
+ result = fn(...data);
391
+ });
392
+ }
393
+ return result;
394
+ }
395
+ remove(fn) {
396
+ this.listeners.delete(fn);
397
+ }
398
+ removeAll() {
399
+ this.listeners.clear();
400
+ }
401
+ constructor(type){
402
+ this.type = '';
403
+ this.listeners = new Set();
404
+ if (type) {
405
+ this.type = type;
406
+ }
407
+ }
408
+ }
409
+
410
+ class AsyncHook extends SyncHook {
411
+ emit(...data) {
412
+ let result;
413
+ const ls = Array.from(this.listeners);
414
+ if (ls.length > 0) {
415
+ let i = 0;
416
+ const call = (prev)=>{
417
+ if (prev === false) {
418
+ return false; // Abort process
419
+ } else if (i < ls.length) {
420
+ return Promise.resolve(ls[i++].apply(null, data)).then(call);
421
+ } else {
422
+ return prev;
423
+ }
424
+ };
425
+ result = call();
426
+ }
427
+ return Promise.resolve(result);
428
+ }
429
+ }
430
+
431
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
432
+ function checkReturnData(originalData, returnedData) {
433
+ if (!isObject(returnedData)) {
434
+ return false;
435
+ }
436
+ if (originalData !== returnedData) {
437
+ // eslint-disable-next-line no-restricted-syntax
438
+ for(const key in originalData){
439
+ if (!(key in returnedData)) {
440
+ return false;
441
+ }
442
+ }
443
+ }
444
+ return true;
445
+ }
446
+ class SyncWaterfallHook extends SyncHook {
447
+ emit(data) {
448
+ if (!isObject(data)) {
449
+ error(`The data for the "${this.type}" hook should be an object.`);
450
+ }
451
+ for (const fn of this.listeners){
452
+ try {
453
+ const tempData = fn(data);
454
+ if (checkReturnData(data, tempData)) {
455
+ data = tempData;
456
+ } else {
457
+ this.onerror(`A plugin returned an unacceptable value for the "${this.type}" type.`);
458
+ break;
459
+ }
460
+ } catch (e) {
461
+ warn(e);
462
+ this.onerror(e);
463
+ }
464
+ }
465
+ return data;
466
+ }
467
+ constructor(type){
468
+ super(), this.onerror = error;
469
+ this.type = type;
470
+ }
471
+ }
472
+
473
+ class AsyncWaterfallHook extends SyncHook {
474
+ emit(data) {
475
+ if (!isObject(data)) {
476
+ error(`The response data for the "${this.type}" hook must be an object.`);
477
+ }
478
+ const ls = Array.from(this.listeners);
479
+ if (ls.length > 0) {
480
+ let i = 0;
481
+ const processError = (e)=>{
482
+ warn(e);
483
+ this.onerror(e);
484
+ return data;
485
+ };
486
+ const call = (prevData)=>{
487
+ if (checkReturnData(data, prevData)) {
488
+ data = prevData;
489
+ if (i < ls.length) {
490
+ try {
491
+ return Promise.resolve(ls[i++](data)).then(call, processError);
492
+ } catch (e) {
493
+ return processError(e);
494
+ }
495
+ }
496
+ } else {
497
+ this.onerror(`A plugin returned an incorrect value for the "${this.type}" type.`);
498
+ }
499
+ return data;
500
+ };
501
+ return Promise.resolve(call(data));
502
+ }
503
+ return Promise.resolve(data);
504
+ }
505
+ constructor(type){
506
+ super(), this.onerror = error;
507
+ this.type = type;
508
+ }
509
+ }
510
+
511
+ class PluginSystem {
512
+ applyPlugin(plugin) {
513
+ assert(isPlainObject(plugin), 'Plugin configuration is invalid.');
514
+ // The plugin's name is mandatory and must be unique
515
+ const pluginName = plugin.name;
516
+ assert(pluginName, 'A name must be provided by the plugin.');
517
+ if (!this.registerPlugins[pluginName]) {
518
+ this.registerPlugins[pluginName] = plugin;
519
+ Object.keys(this.lifecycle).forEach((key)=>{
520
+ const pluginLife = plugin[key];
521
+ if (pluginLife) {
522
+ this.lifecycle[key].on(pluginLife);
523
+ }
524
+ });
525
+ }
526
+ }
527
+ removePlugin(pluginName) {
528
+ assert(pluginName, 'A name is required.');
529
+ const plugin = this.registerPlugins[pluginName];
530
+ assert(plugin, `The plugin "${pluginName}" is not registered.`);
531
+ Object.keys(plugin).forEach((key)=>{
532
+ if (key !== 'name') {
533
+ this.lifecycle[key].remove(plugin[key]);
534
+ }
535
+ });
536
+ }
537
+ // eslint-disable-next-line @typescript-eslint/no-shadow
538
+ inherit({ lifecycle, registerPlugins }) {
539
+ Object.keys(lifecycle).forEach((hookName)=>{
540
+ assert(!this.lifecycle[hookName], `The hook "${hookName}" has a conflict and cannot be inherited.`);
541
+ this.lifecycle[hookName] = lifecycle[hookName];
542
+ });
543
+ Object.keys(registerPlugins).forEach((pluginName)=>{
544
+ assert(!this.registerPlugins[pluginName], `The plugin "${pluginName}" has a conflict and cannot be inherited.`);
545
+ this.applyPlugin(registerPlugins[pluginName]);
546
+ });
547
+ }
548
+ constructor(lifecycle){
549
+ this.registerPlugins = {};
550
+ this.lifecycle = lifecycle;
551
+ this.lifecycleKeys = Object.keys(lifecycle);
552
+ }
553
+ }
554
+
344
555
  function defaultPreloadArgs(preloadConfig) {
345
556
  return _extends({
346
557
  resourceCategory: 'sync',
@@ -854,8 +1065,6 @@ class SnapshotHandler {
854
1065
  remoteSnapshot,
855
1066
  globalSnapshot
856
1067
  });
857
- let mSnapshot;
858
- let gSnapshot;
859
1068
  // global snapshot includes manifest or module info includes manifest
860
1069
  if (globalRemoteSnapshot) {
861
1070
  if (isManifestProvider(globalRemoteSnapshot)) {
@@ -867,8 +1076,10 @@ class SnapshotHandler {
867
1076
  // Therefore, set the snapshot key to the global address of the actual request
868
1077
  entry: remoteEntry
869
1078
  }), moduleSnapshot);
870
- mSnapshot = moduleSnapshot;
871
- gSnapshot = globalSnapshotRes;
1079
+ return {
1080
+ remoteSnapshot: moduleSnapshot,
1081
+ globalSnapshot: globalSnapshotRes
1082
+ };
872
1083
  } else {
873
1084
  const { remoteSnapshot: remoteSnapshotRes } = await this.hooks.lifecycle.loadRemoteSnapshot.emit({
874
1085
  options: this.HostInstance.options,
@@ -876,8 +1087,10 @@ class SnapshotHandler {
876
1087
  remoteSnapshot: globalRemoteSnapshot,
877
1088
  from: 'global'
878
1089
  });
879
- mSnapshot = remoteSnapshotRes;
880
- gSnapshot = globalSnapshotRes;
1090
+ return {
1091
+ remoteSnapshot: remoteSnapshotRes,
1092
+ globalSnapshot: globalSnapshotRes
1093
+ };
881
1094
  }
882
1095
  } else {
883
1096
  if (isRemoteInfoWithEntry(moduleInfo)) {
@@ -891,8 +1104,10 @@ class SnapshotHandler {
891
1104
  remoteSnapshot: moduleSnapshot,
892
1105
  from: 'global'
893
1106
  });
894
- mSnapshot = remoteSnapshotRes;
895
- gSnapshot = globalSnapshotRes;
1107
+ return {
1108
+ remoteSnapshot: remoteSnapshotRes,
1109
+ globalSnapshot: globalSnapshotRes
1110
+ };
896
1111
  } else {
897
1112
  error(`
898
1113
  Cannot get remoteSnapshot with the name: '${moduleInfo.name}', version: '${moduleInfo.version}' from __FEDERATION__.moduleInfo. The following reasons may be causing the problem:\n
@@ -902,15 +1117,6 @@ class SnapshotHandler {
902
1117
  `);
903
1118
  }
904
1119
  }
905
- await this.hooks.lifecycle.afterLoadSnapshot.emit({
906
- options,
907
- moduleInfo,
908
- remoteSnapshot: mSnapshot
909
- });
910
- return {
911
- remoteSnapshot: mSnapshot,
912
- globalSnapshot: gSnapshot
913
- };
914
1120
  }
915
1121
  getGlobalRemoteInfo(moduleInfo) {
916
1122
  return getGlobalRemoteInfo(moduleInfo, this.HostInstance);
@@ -963,8 +1169,7 @@ class SnapshotHandler {
963
1169
  this.hooks = new PluginSystem({
964
1170
  beforeLoadRemoteSnapshot: new AsyncHook('beforeLoadRemoteSnapshot'),
965
1171
  loadSnapshot: new AsyncWaterfallHook('loadGlobalSnapshot'),
966
- loadRemoteSnapshot: new AsyncWaterfallHook('loadRemoteSnapshot'),
967
- afterLoadSnapshot: new AsyncWaterfallHook('afterLoadSnapshot')
1172
+ loadRemoteSnapshot: new AsyncWaterfallHook('loadRemoteSnapshot')
968
1173
  });
969
1174
  this.manifestLoading = Global.__FEDERATION__.__MANIFEST_LOADING__;
970
1175
  this.HostInstance = HostInstance;
@@ -1566,7 +1771,7 @@ class RemoteHandler {
1566
1771
  origin: host
1567
1772
  });
1568
1773
  }
1569
- warn(messages.join(' '));
1774
+ warn$1(messages.join(' '));
1570
1775
  }
1571
1776
  }
1572
1777
  removeRemote(remote) {
@@ -1668,7 +1873,7 @@ class RemoteHandler {
1668
1873
  host.moduleCache.delete(remote.name);
1669
1874
  }
1670
1875
  } catch (err) {
1671
- console.log('removeRemote fail: ', err);
1876
+ logger.log('removeRemote fail: ', err);
1672
1877
  }
1673
1878
  }
1674
1879
  constructor(host){
@@ -1795,7 +2000,7 @@ class FederationHost {
1795
2000
  // maybe will change, temporarily for internal use only
1796
2001
  initContainer: new AsyncWaterfallHook('initContainer')
1797
2002
  });
1798
- this.version = "0.6.11";
2003
+ this.version = "0.6.15";
1799
2004
  this.moduleCache = new Map();
1800
2005
  this.loaderHook = new PluginSystem({
1801
2006
  // FIXME: may not be suitable , not open to the public yet
@@ -1803,13 +2008,8 @@ class FederationHost {
1803
2008
  createScript: new SyncHook(),
1804
2009
  createLink: new SyncHook(),
1805
2010
  // only work for manifest , so not open to the public yet
1806
- fetch: new AsyncHook()
1807
- });
1808
- this.bridgeHook = new PluginSystem({
1809
- beforeBridgeRender: new SyncHook(),
1810
- afterBridgeRender: new SyncHook(),
1811
- beforeBridgeDestroy: new SyncHook(),
1812
- afterBridgeDestroy: new SyncHook()
2011
+ fetch: new AsyncHook(),
2012
+ getModuleFactory: new AsyncHook()
1813
2013
  });
1814
2014
  // TODO: Validate the details of the options
1815
2015
  // Initialize options with default values
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@module-federation/runtime",
3
- "version": "0.6.11",
3
+ "version": "0.6.15",
4
4
  "author": "zhouxiao <codingzx@gmail.com>",
5
5
  "main": "./index.cjs.js",
6
6
  "module": "./index.esm.js",
@@ -22,4 +22,4 @@ function _object_without_properties_loose(source, excluded) {
22
22
  return target;
23
23
  }
24
24
 
25
- export { _extends as _, _object_without_properties_loose as a };
25
+ export { _object_without_properties_loose as _, _extends as a };