@module-federation/runtime 1.0.0-canary.1 → 1.0.0-canary.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/index.cjs.js +100 -99
- package/index.esm.js +100 -99
- package/package.json +2 -3
- package/share.cjs.js +23 -28
- package/share.esm.js +23 -28
- package/src/core.d.ts +3 -3
- package/src/utils/hooks/syncWaterfallHook.d.ts +1 -1
package/index.cjs.js
CHANGED
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var share = require('./share.cjs.js');
|
|
6
6
|
|
|
7
|
+
// Function to get the URL of a resource
|
|
7
8
|
function getResourceUrl(module, sourceUrl) {
|
|
8
9
|
if ('getPublicPath' in module) {
|
|
9
10
|
const publicPath = new Function(module.getPublicPath)();
|
|
@@ -11,19 +12,20 @@ function getResourceUrl(module, sourceUrl) {
|
|
|
11
12
|
} else if ('publicPath' in module) {
|
|
12
13
|
return `${module.publicPath}${sourceUrl}`;
|
|
13
14
|
} else {
|
|
14
|
-
console.warn('
|
|
15
|
+
console.warn('Unable to retrieve resource URL. If in debug mode, this warning can be disregarded.', module, sourceUrl);
|
|
15
16
|
return '';
|
|
16
17
|
}
|
|
17
18
|
}
|
|
19
|
+
// Function to match a remote with its name and expose
|
|
18
20
|
// id: pkgName(@federation/app1) + expose(button) = @federation/app1/button
|
|
19
21
|
// id: alias(app1) + expose(button) = app1/button
|
|
20
22
|
// id: alias(app1/utils) + expose(loadash/sort) = app1/utils/loadash/sort
|
|
21
23
|
function matchRemoteWithNameAndExpose(remotes, id) {
|
|
22
24
|
for (const remote of remotes){
|
|
23
25
|
// match pkgName
|
|
24
|
-
const
|
|
26
|
+
const isNameMatched = id.startsWith(remote.name);
|
|
25
27
|
let expose = id.replace(remote.name, '');
|
|
26
|
-
if (
|
|
28
|
+
if (isNameMatched) {
|
|
27
29
|
if (expose.startsWith('/')) {
|
|
28
30
|
const pkgNameOrAlias = remote.name;
|
|
29
31
|
expose = `.${expose}`;
|
|
@@ -41,9 +43,9 @@ function matchRemoteWithNameAndExpose(remotes, id) {
|
|
|
41
43
|
}
|
|
42
44
|
}
|
|
43
45
|
// match alias
|
|
44
|
-
const
|
|
46
|
+
const isAliasMatched = remote.alias && id.startsWith(remote.alias);
|
|
45
47
|
let exposeWithAlias = remote.alias && id.replace(remote.alias, '');
|
|
46
|
-
if (remote.alias &&
|
|
48
|
+
if (remote.alias && isAliasMatched) {
|
|
47
49
|
if (exposeWithAlias && exposeWithAlias.startsWith('/')) {
|
|
48
50
|
const pkgNameOrAlias = remote.alias;
|
|
49
51
|
exposeWithAlias = `.${exposeWithAlias}`;
|
|
@@ -63,14 +65,15 @@ function matchRemoteWithNameAndExpose(remotes, id) {
|
|
|
63
65
|
}
|
|
64
66
|
return;
|
|
65
67
|
}
|
|
68
|
+
// Function to match a remote with its name or alias
|
|
66
69
|
function matchRemote(remotes, nameOrAlias) {
|
|
67
70
|
for (const remote of remotes){
|
|
68
|
-
const
|
|
69
|
-
if (
|
|
71
|
+
const isNameMatched = nameOrAlias === remote.name;
|
|
72
|
+
if (isNameMatched) {
|
|
70
73
|
return remote;
|
|
71
74
|
}
|
|
72
|
-
const
|
|
73
|
-
if (
|
|
75
|
+
const isAliasMatched = remote.alias && nameOrAlias === remote.alias;
|
|
76
|
+
if (isAliasMatched) {
|
|
74
77
|
return remote;
|
|
75
78
|
}
|
|
76
79
|
}
|
|
@@ -78,7 +81,7 @@ function matchRemote(remotes, nameOrAlias) {
|
|
|
78
81
|
}
|
|
79
82
|
|
|
80
83
|
function createScript(url, cb, attrs, createScriptHook) {
|
|
81
|
-
//
|
|
84
|
+
// Retrieve the existing script element by its src attribute
|
|
82
85
|
let script = null;
|
|
83
86
|
let needAttach = true;
|
|
84
87
|
const scripts = document.getElementsByTagName('script');
|
|
@@ -115,7 +118,7 @@ function createScript(url, cb, attrs, createScriptHook) {
|
|
|
115
118
|
}
|
|
116
119
|
const onScriptComplete = (prev, // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
117
120
|
event)=>{
|
|
118
|
-
//
|
|
121
|
+
// Prevent memory leaks in IE.
|
|
119
122
|
if (script) {
|
|
120
123
|
script.onerror = null;
|
|
121
124
|
script.onload = null;
|
|
@@ -148,7 +151,7 @@ function loadScript(url, info) {
|
|
|
148
151
|
|
|
149
152
|
function registerPlugins(plugins, hookInstances) {
|
|
150
153
|
const globalPlugins = share.getGlobalHostPlugins();
|
|
151
|
-
//
|
|
154
|
+
// Incorporate global plugins
|
|
152
155
|
if (globalPlugins.length > 0) {
|
|
153
156
|
globalPlugins.forEach((plugin)=>{
|
|
154
157
|
if (plugins == null ? void 0 : plugins.find((item)=>item.name !== plugin.name)) {
|
|
@@ -419,7 +422,7 @@ var simpleJoinRemoteEntry = function simpleJoinRemoteEntry(rPath, rName) {
|
|
|
419
422
|
}
|
|
420
423
|
return "".concat(transformedPath, "/").concat(rName);
|
|
421
424
|
};
|
|
422
|
-
//
|
|
425
|
+
// Priority: overrides > remotes
|
|
423
426
|
// eslint-disable-next-line max-lines-per-function
|
|
424
427
|
function generateSnapshotFromManifest(manifest) {
|
|
425
428
|
var options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
|
|
@@ -434,13 +437,13 @@ function generateSnapshotFromManifest(manifest) {
|
|
|
434
437
|
};
|
|
435
438
|
var overridesKeys = Object.keys(overrides);
|
|
436
439
|
var remotesInfo = {};
|
|
437
|
-
// If remotes are not
|
|
440
|
+
// If remotes are not provided, only the remotes in the manifest will be read
|
|
438
441
|
if (!Object.keys(remotes).length) {
|
|
439
442
|
var _manifest_remotes;
|
|
440
443
|
remotesInfo = ((_manifest_remotes = manifest.remotes) === null || _manifest_remotes === void 0 ? void 0 : _manifest_remotes.reduce(function(res, next) {
|
|
441
444
|
var matchedVersion;
|
|
442
445
|
var name = next.federationContainerName;
|
|
443
|
-
// overrides
|
|
446
|
+
// overrides have higher priority
|
|
444
447
|
if (overridesKeys.includes(name)) {
|
|
445
448
|
matchedVersion = overrides[name];
|
|
446
449
|
} else {
|
|
@@ -456,7 +459,7 @@ function generateSnapshotFromManifest(manifest) {
|
|
|
456
459
|
return res;
|
|
457
460
|
}, {})) || {};
|
|
458
461
|
}
|
|
459
|
-
// If remotes (deploy scenario) are specified,
|
|
462
|
+
// If remotes (deploy scenario) are specified, they need to be traversed again
|
|
460
463
|
Object.keys(remotes).forEach(function(key) {
|
|
461
464
|
return remotesInfo[key] = {
|
|
462
465
|
// overrides will override dependencies
|
|
@@ -531,10 +534,10 @@ async function loadEntryScript({ name, globalName, entry, createScriptHook }) {
|
|
|
531
534
|
}).then(()=>{
|
|
532
535
|
const { remoteEntryKey, entryExports } = share.getRemoteEntryExports(name, globalName);
|
|
533
536
|
share.assert(entryExports, `
|
|
534
|
-
|
|
535
|
-
|
|
537
|
+
Unable to use the ${name}'s '${entry}' URL with ${remoteEntryKey}'s globalName to get remoteEntry exports.
|
|
538
|
+
Possible reasons could be:\n
|
|
536
539
|
1. '${entry}' is not the correct URL, or the remoteEntry resource or name is incorrect.\n
|
|
537
|
-
2.
|
|
540
|
+
2. ${remoteEntryKey} cannot be used to get remoteEntry exports in the window object.
|
|
538
541
|
`);
|
|
539
542
|
return entryExports;
|
|
540
543
|
});
|
|
@@ -708,14 +711,14 @@ class AsyncHook extends SyncHook {
|
|
|
708
711
|
}
|
|
709
712
|
|
|
710
713
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
711
|
-
function checkReturnData(
|
|
712
|
-
if (!share.isObject(
|
|
714
|
+
function checkReturnData(originalData, returnedData) {
|
|
715
|
+
if (!share.isObject(returnedData)) {
|
|
713
716
|
return false;
|
|
714
717
|
}
|
|
715
|
-
if (
|
|
718
|
+
if (originalData !== returnedData) {
|
|
716
719
|
// eslint-disable-next-line no-restricted-syntax
|
|
717
|
-
for(const key in
|
|
718
|
-
if (!(key in
|
|
720
|
+
for(const key in originalData){
|
|
721
|
+
if (!(key in returnedData)) {
|
|
719
722
|
return false;
|
|
720
723
|
}
|
|
721
724
|
}
|
|
@@ -725,7 +728,7 @@ function checkReturnData(originData, returnData) {
|
|
|
725
728
|
class SyncWaterfallHook extends SyncHook {
|
|
726
729
|
emit(data) {
|
|
727
730
|
if (!share.isObject(data)) {
|
|
728
|
-
share.error(`"${this.type}" hook
|
|
731
|
+
share.error(`The data for the "${this.type}" hook should be an object.`);
|
|
729
732
|
}
|
|
730
733
|
for (const fn of this.listeners){
|
|
731
734
|
try {
|
|
@@ -733,7 +736,7 @@ class SyncWaterfallHook extends SyncHook {
|
|
|
733
736
|
if (checkReturnData(data, tempData)) {
|
|
734
737
|
data = tempData;
|
|
735
738
|
} else {
|
|
736
|
-
this.onerror(`
|
|
739
|
+
this.onerror(`A plugin returned an unacceptable value for the "${this.type}" type.`);
|
|
737
740
|
break;
|
|
738
741
|
}
|
|
739
742
|
} catch (e) {
|
|
@@ -753,7 +756,7 @@ class SyncWaterfallHook extends SyncHook {
|
|
|
753
756
|
class AsyncWaterfallHook extends SyncHook {
|
|
754
757
|
emit(data) {
|
|
755
758
|
if (!share.isObject(data)) {
|
|
756
|
-
share.error(`"${this.type}" hook
|
|
759
|
+
share.error(`The response data for the "${this.type}" hook must be an object.`);
|
|
757
760
|
}
|
|
758
761
|
const ls = Array.from(this.listeners);
|
|
759
762
|
if (ls.length > 0) {
|
|
@@ -774,7 +777,7 @@ class AsyncWaterfallHook extends SyncHook {
|
|
|
774
777
|
}
|
|
775
778
|
}
|
|
776
779
|
} else {
|
|
777
|
-
this.onerror(`
|
|
780
|
+
this.onerror(`A plugin returned an incorrect value for the "${this.type}" type.`);
|
|
778
781
|
}
|
|
779
782
|
return data;
|
|
780
783
|
};
|
|
@@ -791,10 +794,10 @@ class AsyncWaterfallHook extends SyncHook {
|
|
|
791
794
|
|
|
792
795
|
class PluginSystem {
|
|
793
796
|
usePlugin(plugin) {
|
|
794
|
-
share.assert(share.isPlainObject(plugin), '
|
|
795
|
-
// The plugin name is
|
|
797
|
+
share.assert(share.isPlainObject(plugin), 'Plugin configuration is invalid.');
|
|
798
|
+
// The plugin's name is mandatory and must be unique
|
|
796
799
|
const pluginName = plugin.name;
|
|
797
|
-
share.assert(pluginName, '
|
|
800
|
+
share.assert(pluginName, 'A name must be provided by the plugin.');
|
|
798
801
|
if (!this.registerPlugins[pluginName]) {
|
|
799
802
|
this.registerPlugins[pluginName] = plugin;
|
|
800
803
|
Object.keys(this.lifecycle).forEach((key)=>{
|
|
@@ -806,9 +809,9 @@ class PluginSystem {
|
|
|
806
809
|
}
|
|
807
810
|
}
|
|
808
811
|
removePlugin(pluginName) {
|
|
809
|
-
share.assert(pluginName, '
|
|
812
|
+
share.assert(pluginName, 'A name is required.');
|
|
810
813
|
const plugin = this.registerPlugins[pluginName];
|
|
811
|
-
share.assert(plugin, `plugin "${pluginName}" is not registered.`);
|
|
814
|
+
share.assert(plugin, `The plugin "${pluginName}" is not registered.`);
|
|
812
815
|
Object.keys(plugin).forEach((key)=>{
|
|
813
816
|
if (key !== 'name') {
|
|
814
817
|
this.lifecycle[key].remove(plugin[key]);
|
|
@@ -818,11 +821,11 @@ class PluginSystem {
|
|
|
818
821
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
819
822
|
inherit({ lifecycle, registerPlugins }) {
|
|
820
823
|
Object.keys(lifecycle).forEach((hookName)=>{
|
|
821
|
-
share.assert(!this.lifecycle[hookName], `"${hookName}"
|
|
824
|
+
share.assert(!this.lifecycle[hookName], `The hook "${hookName}" has a conflict and cannot be inherited.`);
|
|
822
825
|
this.lifecycle[hookName] = lifecycle[hookName];
|
|
823
826
|
});
|
|
824
827
|
Object.keys(registerPlugins).forEach((pluginName)=>{
|
|
825
|
-
share.assert(!this.registerPlugins[pluginName], `"${pluginName}"
|
|
828
|
+
share.assert(!this.registerPlugins[pluginName], `The plugin "${pluginName}" has a conflict and cannot be inherited.`);
|
|
826
829
|
this.usePlugin(registerPlugins[pluginName]);
|
|
827
830
|
});
|
|
828
831
|
}
|
|
@@ -841,13 +844,12 @@ function defaultPreloadArgs(preloadConfig) {
|
|
|
841
844
|
}, preloadConfig);
|
|
842
845
|
}
|
|
843
846
|
function formatPreloadArgs(remotes, preloadArgs) {
|
|
844
|
-
// let preloadOps: PreloadOptions;
|
|
845
847
|
return preloadArgs.map((args)=>{
|
|
846
848
|
const remoteInfo = matchRemote(remotes, args.nameOrAlias);
|
|
847
|
-
share.assert(remoteInfo, `
|
|
849
|
+
share.assert(remoteInfo, `Unable to preload ${args.nameOrAlias} as it is not included in ${!remoteInfo && share.safeToString({
|
|
848
850
|
remoteInfo,
|
|
849
851
|
remotes
|
|
850
|
-
})}
|
|
852
|
+
})}`);
|
|
851
853
|
return {
|
|
852
854
|
remote: remoteInfo,
|
|
853
855
|
preloadConfig: defaultPreloadArgs(args)
|
|
@@ -933,7 +935,7 @@ function preloadAssets(remoteInfo, host, assets) {
|
|
|
933
935
|
|
|
934
936
|
function assignRemoteInfo(remoteInfo, remoteSnapshot) {
|
|
935
937
|
if (!('remoteEntry' in remoteSnapshot) || !remoteSnapshot.remoteEntry) {
|
|
936
|
-
share.error(`The remoteEntry
|
|
938
|
+
share.error(`The attribute remoteEntry of ${name} must not be undefined.`);
|
|
937
939
|
}
|
|
938
940
|
const { remoteEntry } = remoteSnapshot;
|
|
939
941
|
const entryUrl = getResourceUrl(remoteSnapshot, remoteEntry);
|
|
@@ -951,7 +953,7 @@ function snapshotPlugin() {
|
|
|
951
953
|
if (!share.isRemoteInfoWithEntry(remote) || !share.isPureRemoteEntry(remote)) {
|
|
952
954
|
const { remoteSnapshot, globalSnapshot } = await origin.snapshotHandler.loadRemoteSnapshotInfo(remote);
|
|
953
955
|
assignRemoteInfo(remoteInfo, remoteSnapshot);
|
|
954
|
-
//
|
|
956
|
+
// preloading assets
|
|
955
957
|
const preloadOptions = {
|
|
956
958
|
remote,
|
|
957
959
|
preloadConfig: {
|
|
@@ -1002,22 +1004,22 @@ function splitId(id) {
|
|
|
1002
1004
|
};
|
|
1003
1005
|
}
|
|
1004
1006
|
}
|
|
1005
|
-
// Traverse all nodes
|
|
1007
|
+
// Traverse all nodes in moduleInfo and traverse the entire snapshot
|
|
1006
1008
|
function traverseModuleInfo(globalSnapshot, remoteInfo, traverse, isRoot, memo = {}, remoteSnapshot, getModuleInfoHook) {
|
|
1007
1009
|
const id = share.getFMId(remoteInfo);
|
|
1008
1010
|
const { value: snapshotValue } = share.getInfoWithoutType(globalSnapshot, id, getModuleInfoHook);
|
|
1009
|
-
const
|
|
1010
|
-
if (
|
|
1011
|
-
traverse(
|
|
1012
|
-
if (
|
|
1013
|
-
const remoteKeys = Object.keys(
|
|
1011
|
+
const effectiveRemoteSnapshot = remoteSnapshot || snapshotValue;
|
|
1012
|
+
if (effectiveRemoteSnapshot && !isManifestProvider(effectiveRemoteSnapshot)) {
|
|
1013
|
+
traverse(effectiveRemoteSnapshot, remoteInfo, isRoot);
|
|
1014
|
+
if (effectiveRemoteSnapshot.remotesInfo) {
|
|
1015
|
+
const remoteKeys = Object.keys(effectiveRemoteSnapshot.remotesInfo);
|
|
1014
1016
|
for (const key of remoteKeys){
|
|
1015
1017
|
if (memo[key]) {
|
|
1016
1018
|
continue;
|
|
1017
1019
|
}
|
|
1018
1020
|
memo[key] = true;
|
|
1019
1021
|
const subRemoteInfo = splitId(key);
|
|
1020
|
-
const remoteValue =
|
|
1022
|
+
const remoteValue = effectiveRemoteSnapshot.remotesInfo[key];
|
|
1021
1023
|
traverseModuleInfo(globalSnapshot, {
|
|
1022
1024
|
name: subRemoteInfo.name,
|
|
1023
1025
|
version: remoteValue.matchedVersion
|
|
@@ -1086,7 +1088,7 @@ function generatePreloadAssets(origin, preloadOptions, remote, globalSnapshot, r
|
|
|
1086
1088
|
return assets;
|
|
1087
1089
|
}, []);
|
|
1088
1090
|
}
|
|
1089
|
-
function
|
|
1091
|
+
function handleAssets(assets) {
|
|
1090
1092
|
const assetsRes = assets.map((asset)=>getResourceUrl(moduleInfoSnapshot, asset));
|
|
1091
1093
|
if (preloadConfig.filter) {
|
|
1092
1094
|
return assetsRes.filter(preloadConfig.filter);
|
|
@@ -1097,21 +1099,20 @@ function generatePreloadAssets(origin, preloadOptions, remote, globalSnapshot, r
|
|
|
1097
1099
|
const assetsLength = moduleAssetsInfo.length;
|
|
1098
1100
|
for(let index = 0; index < assetsLength; index++){
|
|
1099
1101
|
const assetsInfo = moduleAssetsInfo[index];
|
|
1100
|
-
// for (const assetsInfo of moduleAssetsInfo) {
|
|
1101
1102
|
const exposeFullPath = `${remoteInfo.name}/${assetsInfo.moduleName}`;
|
|
1102
1103
|
const preloaded = share.getPreloaded(exposeFullPath);
|
|
1103
1104
|
if (preloaded) {
|
|
1104
1105
|
continue;
|
|
1105
1106
|
}
|
|
1106
1107
|
if (preloadConfig.resourceCategory === 'all') {
|
|
1107
|
-
cssAssets.push(...
|
|
1108
|
-
cssAssets.push(...
|
|
1109
|
-
jsAssets.push(...
|
|
1110
|
-
jsAssets.push(...
|
|
1108
|
+
cssAssets.push(...handleAssets(assetsInfo.assets.css.async));
|
|
1109
|
+
cssAssets.push(...handleAssets(assetsInfo.assets.css.sync));
|
|
1110
|
+
jsAssets.push(...handleAssets(assetsInfo.assets.js.async));
|
|
1111
|
+
jsAssets.push(...handleAssets(assetsInfo.assets.js.sync));
|
|
1111
1112
|
// eslint-disable-next-line no-constant-condition
|
|
1112
1113
|
} else if (preloadConfig.resourceCategory = 'sync') {
|
|
1113
|
-
cssAssets.push(...
|
|
1114
|
-
jsAssets.push(...
|
|
1114
|
+
cssAssets.push(...handleAssets(assetsInfo.assets.css.sync));
|
|
1115
|
+
jsAssets.push(...handleAssets(assetsInfo.assets.js.sync));
|
|
1115
1116
|
}
|
|
1116
1117
|
share.setPreloaded(exposeFullPath);
|
|
1117
1118
|
}
|
|
@@ -1223,10 +1224,8 @@ class SnapshotHandler {
|
|
|
1223
1224
|
options,
|
|
1224
1225
|
moduleInfo
|
|
1225
1226
|
});
|
|
1226
|
-
// In
|
|
1227
|
-
//
|
|
1228
|
-
// In the dynamic loadRemote scenario, incomplete remotesInfo delivery may occur. In this case, the remotesInfo in the host needs to be completed in the snapshot at runtime.
|
|
1229
|
-
// Ensure the integrity of the snapshot, and at the same time help the chrome plug-in correctly identify all producer modules, ensuring that proxyable producer modules will not be missing
|
|
1227
|
+
// In dynamic loadRemote scenarios, incomplete remotesInfo delivery may occur. In such cases, the remotesInfo in the host needs to be completed in the snapshot at runtime.
|
|
1228
|
+
// This ensures the snapshot's integrity and helps the chrome plugin correctly identify all producer modules, ensuring that proxyable producer modules will not be missing.
|
|
1230
1229
|
if (hostSnapshot && 'remotesInfo' in hostSnapshot && !share.getInfoWithoutType(hostSnapshot.remotesInfo, moduleInfo.name, (target, key)=>{
|
|
1231
1230
|
const res = this.HostInstance.loaderHook.lifecycle.getModuleInfo.emit({
|
|
1232
1231
|
target,
|
|
@@ -1253,7 +1252,7 @@ class SnapshotHandler {
|
|
|
1253
1252
|
remoteSnapshot,
|
|
1254
1253
|
globalSnapshot
|
|
1255
1254
|
});
|
|
1256
|
-
// global snapshot
|
|
1255
|
+
// global snapshot includes manifest or module info includes manifest
|
|
1257
1256
|
if (globalRemoteSnapshot) {
|
|
1258
1257
|
if (isManifestProvider(globalRemoteSnapshot)) {
|
|
1259
1258
|
const moduleSnapshot = await this.getManifestJson(globalRemoteSnapshot.remoteEntry, moduleInfo, {});
|
|
@@ -1378,7 +1377,7 @@ class SnapshotHandler {
|
|
|
1378
1377
|
try {
|
|
1379
1378
|
const res = await fetch(manifestUrl);
|
|
1380
1379
|
manifestJson = await res.json();
|
|
1381
|
-
share.assert(manifestJson.metaData && manifestJson.exposes && manifestJson.shared, `${manifestUrl} is not federation manifest`);
|
|
1380
|
+
share.assert(manifestJson.metaData && manifestJson.exposes && manifestJson.shared, `${manifestUrl} is not a federation manifest`);
|
|
1382
1381
|
this.manifestCache.set(manifestUrl, manifestJson);
|
|
1383
1382
|
return manifestJson;
|
|
1384
1383
|
} catch (err) {
|
|
@@ -1430,9 +1429,10 @@ class FederationHost {
|
|
|
1430
1429
|
// overrideSharedOptions(shareScope: GlobalShareScope[string]): void {}
|
|
1431
1430
|
async loadShare(pkgName, customShareInfo) {
|
|
1432
1431
|
var _this_options_shared;
|
|
1433
|
-
//
|
|
1434
|
-
//
|
|
1435
|
-
//
|
|
1432
|
+
// This function performs the following steps:
|
|
1433
|
+
// 1. Checks if the currently loaded share already exists, if not, it throws an error
|
|
1434
|
+
// 2. Searches globally for a matching share, if found, it uses it directly
|
|
1435
|
+
// 3. If not found, it retrieves it from the current share and stores the obtained share globally.
|
|
1436
1436
|
const shareInfo = Object.assign({}, (_this_options_shared = this.options.shared) == null ? void 0 : _this_options_shared[pkgName], customShareInfo);
|
|
1437
1437
|
const loadShareRes = await this.hooks.lifecycle.beforeLoadShare.emit({
|
|
1438
1438
|
pkgName,
|
|
@@ -1441,8 +1441,9 @@ class FederationHost {
|
|
|
1441
1441
|
origin: this
|
|
1442
1442
|
});
|
|
1443
1443
|
const { shareInfo: shareInfoRes } = loadShareRes;
|
|
1444
|
-
|
|
1445
|
-
|
|
1444
|
+
// Assert that shareInfoRes exists, if not, throw an error
|
|
1445
|
+
share.assert(shareInfoRes, `Cannot find ${pkgName} Share in the ${this.options.name}. Please ensure that the ${pkgName} Share parameters have been injected`);
|
|
1446
|
+
// Retrieve from cache
|
|
1446
1447
|
const globalShare = share.getGlobalShare(pkgName, shareInfoRes);
|
|
1447
1448
|
if (globalShare && globalShare.lib) {
|
|
1448
1449
|
share.addUniqueItem(globalShare.useIn, this.options.name);
|
|
@@ -1498,10 +1499,10 @@ class FederationHost {
|
|
|
1498
1499
|
return loading;
|
|
1499
1500
|
}
|
|
1500
1501
|
}
|
|
1501
|
-
//
|
|
1502
|
-
// 1. If the loaded shared already exists globally, then
|
|
1503
|
-
// 2. If lib exists in local shared,
|
|
1504
|
-
// 3. If the local get returns something other than Promise, then
|
|
1502
|
+
// The lib function will only be available if the shared set by eager or runtime init is set or the shared is successfully loaded.
|
|
1503
|
+
// 1. If the loaded shared already exists globally, then it will be reused
|
|
1504
|
+
// 2. If lib exists in local shared, it will be used directly
|
|
1505
|
+
// 3. If the local get returns something other than Promise, then it will be used directly
|
|
1505
1506
|
loadShareSync(pkgName) {
|
|
1506
1507
|
var _this_options_shared;
|
|
1507
1508
|
const shareInfo = (_this_options_shared = this.options.shared) == null ? void 0 : _this_options_shared[pkgName];
|
|
@@ -1526,10 +1527,10 @@ class FederationHost {
|
|
|
1526
1527
|
const module = shareInfo.get();
|
|
1527
1528
|
if (module instanceof Promise) {
|
|
1528
1529
|
throw new Error(`
|
|
1529
|
-
The loadShareSync function
|
|
1530
|
-
|
|
1531
|
-
1.
|
|
1532
|
-
2.
|
|
1530
|
+
The loadShareSync function was unable to load ${pkgName}. The ${pkgName} could not be found in ${this.options.name}.
|
|
1531
|
+
Possible reasons for failure: \n
|
|
1532
|
+
1. The ${pkgName} share was registered with the 'get' attribute, but loadShare was not used beforehand.\n
|
|
1533
|
+
2. The ${pkgName} share was not registered with the 'lib' attribute.\n
|
|
1533
1534
|
`);
|
|
1534
1535
|
}
|
|
1535
1536
|
shareInfo.lib = module;
|
|
@@ -1543,10 +1544,10 @@ class FederationHost {
|
|
|
1543
1544
|
return shareInfo.lib;
|
|
1544
1545
|
}
|
|
1545
1546
|
throw new Error(`
|
|
1546
|
-
The loadShareSync function
|
|
1547
|
-
|
|
1548
|
-
1.
|
|
1549
|
-
2.
|
|
1547
|
+
The loadShareSync function was unable to load ${pkgName}. The ${pkgName} could not be found in ${this.options.name}.
|
|
1548
|
+
Possible reasons for failure: \n
|
|
1549
|
+
1. The ${pkgName} share was registered with the 'get' attribute, but loadShare was not used beforehand.\n
|
|
1550
|
+
2. The ${pkgName} share was not registered with the 'lib' attribute.\n
|
|
1550
1551
|
`);
|
|
1551
1552
|
}
|
|
1552
1553
|
async _getRemoteModuleAndOptions(id) {
|
|
@@ -1558,10 +1559,10 @@ class FederationHost {
|
|
|
1558
1559
|
const { id: idRes } = loadRemoteArgs;
|
|
1559
1560
|
const remoteSplitInfo = matchRemoteWithNameAndExpose(this.options.remotes, idRes);
|
|
1560
1561
|
share.assert(remoteSplitInfo, `
|
|
1561
|
-
|
|
1562
|
-
1. ${idRes} was not
|
|
1563
|
-
2.
|
|
1564
|
-
3. The 'beforeLoadRemote' hook was provided but did not return the correct 'remoteInfo' when
|
|
1562
|
+
Unable to locate ${idRes} in ${this.options.name}. Potential reasons for failure include:\n
|
|
1563
|
+
1. ${idRes} was not included in the 'remotes' parameter of ${this.options.name}.\n
|
|
1564
|
+
2. ${idRes} could not be found in the 'remotes' of ${this.options.name} with either 'name' or 'alias' attributes.
|
|
1565
|
+
3. The 'beforeLoadRemote' hook was provided but did not return the correct 'remoteInfo' when attempting to load ${idRes}.
|
|
1565
1566
|
`);
|
|
1566
1567
|
const { remote: rawRemote } = remoteSplitInfo;
|
|
1567
1568
|
const remoteInfo = getRemoteInfo(rawRemote);
|
|
@@ -1573,7 +1574,7 @@ class FederationHost {
|
|
|
1573
1574
|
remoteInfo
|
|
1574
1575
|
}));
|
|
1575
1576
|
const { remote, expose } = matchInfo;
|
|
1576
|
-
share.assert(remote && expose, `The 'beforeLoadRemote' hook was
|
|
1577
|
+
share.assert(remote && expose, `The 'beforeLoadRemote' hook was executed, but it failed to return the correct 'remote' and 'expose' values while loading ${idRes}.`);
|
|
1577
1578
|
let module = this.moduleCache.get(remote.name);
|
|
1578
1579
|
const moduleOptions = {
|
|
1579
1580
|
hostInfo: {
|
|
@@ -1602,10 +1603,10 @@ class FederationHost {
|
|
|
1602
1603
|
const { loadFactory = true } = options || {
|
|
1603
1604
|
loadFactory: true
|
|
1604
1605
|
};
|
|
1605
|
-
// 1.
|
|
1606
|
-
// 2. Request the snapshot information of the current host and store the obtained snapshot information
|
|
1607
|
-
// 3.
|
|
1608
|
-
// 4. After
|
|
1606
|
+
// 1. Validate the parameters of the retrieved module. There are two module request methods: pkgName + expose and alias + expose.
|
|
1607
|
+
// 2. Request the snapshot information of the current host and globally store the obtained snapshot information. The retrieved module information is partially offline and partially online. The online module information will retrieve the modules used online.
|
|
1608
|
+
// 3. Retrieve the detailed information of the current module from global (remoteEntry address, expose resource address)
|
|
1609
|
+
// 4. After retrieving remoteEntry, call the init of the module, and then retrieve the exported content of the module through get
|
|
1609
1610
|
// id: pkgName(@federation/app1) + expose(button) = @federation/app1/button
|
|
1610
1611
|
// id: alias(app1) + expose(button) = app1/button
|
|
1611
1612
|
// id: alias(app1/utils) + expose(loadash/sort) = app1/utils/loadash/sort
|
|
@@ -1659,23 +1660,23 @@ class FederationHost {
|
|
|
1659
1660
|
}));
|
|
1660
1661
|
}
|
|
1661
1662
|
/**
|
|
1662
|
-
*
|
|
1663
|
-
*
|
|
1664
|
-
*
|
|
1663
|
+
* This function initializes the sharing sequence (executed only once per share scope).
|
|
1664
|
+
* It accepts one argument, the name of the share scope.
|
|
1665
|
+
* If the share scope does not exist, it creates one.
|
|
1665
1666
|
*/ // eslint-disable-next-line @typescript-eslint/member-ordering
|
|
1666
1667
|
initializeSharing(shareScopeName = share.DEFAULT_SCOPE) {
|
|
1667
1668
|
const shareScopeLoading = share.Global.__FEDERATION__.__SHARE_SCOPE_LOADING__;
|
|
1668
1669
|
const shareScope = share.Global.__FEDERATION__.__SHARE__;
|
|
1669
1670
|
const hostName = this.options.name;
|
|
1670
|
-
// only
|
|
1671
|
+
// Executes only once
|
|
1671
1672
|
if (shareScopeLoading[shareScopeName]) {
|
|
1672
1673
|
return shareScopeLoading[shareScopeName];
|
|
1673
1674
|
}
|
|
1674
|
-
//
|
|
1675
|
+
// Creates a new share scope if necessary
|
|
1675
1676
|
if (!shareScope[shareScopeName]) {
|
|
1676
1677
|
shareScope[shareScopeName] = {};
|
|
1677
1678
|
}
|
|
1678
|
-
//
|
|
1679
|
+
// Executes all initialization snippets from all accessible modules
|
|
1679
1680
|
const scope = shareScope[shareScopeName];
|
|
1680
1681
|
const register = (name, shared)=>{
|
|
1681
1682
|
const { version, eager } = shared;
|
|
@@ -1723,8 +1724,8 @@ class FederationHost {
|
|
|
1723
1724
|
const remotes = userRemotes.reduce((res, remote)=>{
|
|
1724
1725
|
if (!res.find((item)=>item.name === remote.name)) {
|
|
1725
1726
|
if (remote.alias) {
|
|
1726
|
-
//
|
|
1727
|
-
//
|
|
1727
|
+
// Validate if alias equals the prefix of remote.name and remote.alias, if so, throw an error
|
|
1728
|
+
// As multi-level path references cannot guarantee unique names, alias being a prefix of remote.name is not supported
|
|
1728
1729
|
const findEqual = res.find((item)=>{
|
|
1729
1730
|
var _item_alias;
|
|
1730
1731
|
return remote.alias && (item.name.startsWith(remote.alias) || ((_item_alias = item.alias) == null ? void 0 : _item_alias.startsWith(remote.alias)));
|
|
@@ -1741,7 +1742,7 @@ class FederationHost {
|
|
|
1741
1742
|
remote.shareScope = share.DEFAULT_SCOPE;
|
|
1742
1743
|
}
|
|
1743
1744
|
if (!remote.type) {
|
|
1744
|
-
// FIXME: The build plugin
|
|
1745
|
+
// FIXME: The build plugin needs to support this field
|
|
1745
1746
|
remote.type = share.DEFAULT_REMOTE_TYPE;
|
|
1746
1747
|
}
|
|
1747
1748
|
res.push(remote);
|
|
@@ -1846,7 +1847,7 @@ class FederationHost {
|
|
|
1846
1847
|
generatePreloadAssets: new AsyncHook('generatePreloadAssets'),
|
|
1847
1848
|
afterPreloadRemote: new AsyncHook()
|
|
1848
1849
|
});
|
|
1849
|
-
this.version = '0.0.
|
|
1850
|
+
this.version = '1.0.0-canary.2';
|
|
1850
1851
|
this.moduleCache = new Map();
|
|
1851
1852
|
this.loaderHook = new PluginSystem({
|
|
1852
1853
|
// FIXME: may not be suitable
|
|
@@ -1854,8 +1855,8 @@ class FederationHost {
|
|
|
1854
1855
|
createScript: new SyncHook()
|
|
1855
1856
|
});
|
|
1856
1857
|
this.loadingShare = {};
|
|
1857
|
-
// TODO:
|
|
1858
|
-
//
|
|
1858
|
+
// TODO: Validate the details of the options
|
|
1859
|
+
// Initialize options with default values
|
|
1859
1860
|
const defaultOptions = {
|
|
1860
1861
|
id: share.getBuilderId(),
|
|
1861
1862
|
name: userOptions.name,
|