@module-federation/runtime 1.0.0-canary.1 → 1.0.0-canary.2
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 -2
- 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.esm.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { i as isStaticResourcesEqual, s as safeWrapper, g as getGlobalHostPlugins, _ as _extends, D as DEFAULT_REMOTE_TYPE, a as DEFAULT_SCOPE, b as globalLoading, c as getRemoteEntryExports, d as assert, e as safeToString$1, G as Global, f as getFMId, h as isObject, j as error, w as warn, k as isPlainObject, l as isRemoteInfoWithEntry, m as isPureRemoteEntry, n as getGlobalShare, o as getInfoWithoutType, p as getPreloaded, q as setPreloaded, r as getGlobalSnapshotInfoByModuleInfo, t as setGlobalSnapshotInfoByModuleInfo, u as getGlobalSnapshot, v as addUniqueItem, x as formatShareConfigs, y as isBrowserEnv$1, z as getGlobalShareScope, A as _object_without_properties_loose, B as getBuilderId, C as setGlobalFederationConstructor, E as getGlobalFederationInstance, F as getGlobalFederationConstructor, H as setGlobalFederationInstance } from './share.esm.js';
|
|
2
2
|
export { I as registerGlobalPlugins } from './share.esm.js';
|
|
3
3
|
|
|
4
|
+
// Function to get the URL of a resource
|
|
4
5
|
function getResourceUrl(module, sourceUrl) {
|
|
5
6
|
if ('getPublicPath' in module) {
|
|
6
7
|
const publicPath = new Function(module.getPublicPath)();
|
|
@@ -8,19 +9,20 @@ function getResourceUrl(module, sourceUrl) {
|
|
|
8
9
|
} else if ('publicPath' in module) {
|
|
9
10
|
return `${module.publicPath}${sourceUrl}`;
|
|
10
11
|
} else {
|
|
11
|
-
console.warn('
|
|
12
|
+
console.warn('Unable to retrieve resource URL. If in debug mode, this warning can be disregarded.', module, sourceUrl);
|
|
12
13
|
return '';
|
|
13
14
|
}
|
|
14
15
|
}
|
|
16
|
+
// Function to match a remote with its name and expose
|
|
15
17
|
// id: pkgName(@federation/app1) + expose(button) = @federation/app1/button
|
|
16
18
|
// id: alias(app1) + expose(button) = app1/button
|
|
17
19
|
// id: alias(app1/utils) + expose(loadash/sort) = app1/utils/loadash/sort
|
|
18
20
|
function matchRemoteWithNameAndExpose(remotes, id) {
|
|
19
21
|
for (const remote of remotes){
|
|
20
22
|
// match pkgName
|
|
21
|
-
const
|
|
23
|
+
const isNameMatched = id.startsWith(remote.name);
|
|
22
24
|
let expose = id.replace(remote.name, '');
|
|
23
|
-
if (
|
|
25
|
+
if (isNameMatched) {
|
|
24
26
|
if (expose.startsWith('/')) {
|
|
25
27
|
const pkgNameOrAlias = remote.name;
|
|
26
28
|
expose = `.${expose}`;
|
|
@@ -38,9 +40,9 @@ function matchRemoteWithNameAndExpose(remotes, id) {
|
|
|
38
40
|
}
|
|
39
41
|
}
|
|
40
42
|
// match alias
|
|
41
|
-
const
|
|
43
|
+
const isAliasMatched = remote.alias && id.startsWith(remote.alias);
|
|
42
44
|
let exposeWithAlias = remote.alias && id.replace(remote.alias, '');
|
|
43
|
-
if (remote.alias &&
|
|
45
|
+
if (remote.alias && isAliasMatched) {
|
|
44
46
|
if (exposeWithAlias && exposeWithAlias.startsWith('/')) {
|
|
45
47
|
const pkgNameOrAlias = remote.alias;
|
|
46
48
|
exposeWithAlias = `.${exposeWithAlias}`;
|
|
@@ -60,14 +62,15 @@ function matchRemoteWithNameAndExpose(remotes, id) {
|
|
|
60
62
|
}
|
|
61
63
|
return;
|
|
62
64
|
}
|
|
65
|
+
// Function to match a remote with its name or alias
|
|
63
66
|
function matchRemote(remotes, nameOrAlias) {
|
|
64
67
|
for (const remote of remotes){
|
|
65
|
-
const
|
|
66
|
-
if (
|
|
68
|
+
const isNameMatched = nameOrAlias === remote.name;
|
|
69
|
+
if (isNameMatched) {
|
|
67
70
|
return remote;
|
|
68
71
|
}
|
|
69
|
-
const
|
|
70
|
-
if (
|
|
72
|
+
const isAliasMatched = remote.alias && nameOrAlias === remote.alias;
|
|
73
|
+
if (isAliasMatched) {
|
|
71
74
|
return remote;
|
|
72
75
|
}
|
|
73
76
|
}
|
|
@@ -75,7 +78,7 @@ function matchRemote(remotes, nameOrAlias) {
|
|
|
75
78
|
}
|
|
76
79
|
|
|
77
80
|
function createScript(url, cb, attrs, createScriptHook) {
|
|
78
|
-
//
|
|
81
|
+
// Retrieve the existing script element by its src attribute
|
|
79
82
|
let script = null;
|
|
80
83
|
let needAttach = true;
|
|
81
84
|
const scripts = document.getElementsByTagName('script');
|
|
@@ -112,7 +115,7 @@ function createScript(url, cb, attrs, createScriptHook) {
|
|
|
112
115
|
}
|
|
113
116
|
const onScriptComplete = (prev, // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
114
117
|
event)=>{
|
|
115
|
-
//
|
|
118
|
+
// Prevent memory leaks in IE.
|
|
116
119
|
if (script) {
|
|
117
120
|
script.onerror = null;
|
|
118
121
|
script.onload = null;
|
|
@@ -145,7 +148,7 @@ function loadScript(url, info) {
|
|
|
145
148
|
|
|
146
149
|
function registerPlugins(plugins, hookInstances) {
|
|
147
150
|
const globalPlugins = getGlobalHostPlugins();
|
|
148
|
-
//
|
|
151
|
+
// Incorporate global plugins
|
|
149
152
|
if (globalPlugins.length > 0) {
|
|
150
153
|
globalPlugins.forEach((plugin)=>{
|
|
151
154
|
if (plugins == null ? void 0 : plugins.find((item)=>item.name !== plugin.name)) {
|
|
@@ -416,7 +419,7 @@ var simpleJoinRemoteEntry = function simpleJoinRemoteEntry(rPath, rName) {
|
|
|
416
419
|
}
|
|
417
420
|
return "".concat(transformedPath, "/").concat(rName);
|
|
418
421
|
};
|
|
419
|
-
//
|
|
422
|
+
// Priority: overrides > remotes
|
|
420
423
|
// eslint-disable-next-line max-lines-per-function
|
|
421
424
|
function generateSnapshotFromManifest(manifest) {
|
|
422
425
|
var options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
|
|
@@ -431,13 +434,13 @@ function generateSnapshotFromManifest(manifest) {
|
|
|
431
434
|
};
|
|
432
435
|
var overridesKeys = Object.keys(overrides);
|
|
433
436
|
var remotesInfo = {};
|
|
434
|
-
// If remotes are not
|
|
437
|
+
// If remotes are not provided, only the remotes in the manifest will be read
|
|
435
438
|
if (!Object.keys(remotes).length) {
|
|
436
439
|
var _manifest_remotes;
|
|
437
440
|
remotesInfo = ((_manifest_remotes = manifest.remotes) === null || _manifest_remotes === void 0 ? void 0 : _manifest_remotes.reduce(function(res, next) {
|
|
438
441
|
var matchedVersion;
|
|
439
442
|
var name = next.federationContainerName;
|
|
440
|
-
// overrides
|
|
443
|
+
// overrides have higher priority
|
|
441
444
|
if (overridesKeys.includes(name)) {
|
|
442
445
|
matchedVersion = overrides[name];
|
|
443
446
|
} else {
|
|
@@ -453,7 +456,7 @@ function generateSnapshotFromManifest(manifest) {
|
|
|
453
456
|
return res;
|
|
454
457
|
}, {})) || {};
|
|
455
458
|
}
|
|
456
|
-
// If remotes (deploy scenario) are specified,
|
|
459
|
+
// If remotes (deploy scenario) are specified, they need to be traversed again
|
|
457
460
|
Object.keys(remotes).forEach(function(key) {
|
|
458
461
|
return remotesInfo[key] = {
|
|
459
462
|
// overrides will override dependencies
|
|
@@ -528,10 +531,10 @@ async function loadEntryScript({ name, globalName, entry, createScriptHook }) {
|
|
|
528
531
|
}).then(()=>{
|
|
529
532
|
const { remoteEntryKey, entryExports } = getRemoteEntryExports(name, globalName);
|
|
530
533
|
assert(entryExports, `
|
|
531
|
-
|
|
532
|
-
|
|
534
|
+
Unable to use the ${name}'s '${entry}' URL with ${remoteEntryKey}'s globalName to get remoteEntry exports.
|
|
535
|
+
Possible reasons could be:\n
|
|
533
536
|
1. '${entry}' is not the correct URL, or the remoteEntry resource or name is incorrect.\n
|
|
534
|
-
2.
|
|
537
|
+
2. ${remoteEntryKey} cannot be used to get remoteEntry exports in the window object.
|
|
535
538
|
`);
|
|
536
539
|
return entryExports;
|
|
537
540
|
});
|
|
@@ -705,14 +708,14 @@ class AsyncHook extends SyncHook {
|
|
|
705
708
|
}
|
|
706
709
|
|
|
707
710
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
708
|
-
function checkReturnData(
|
|
709
|
-
if (!isObject(
|
|
711
|
+
function checkReturnData(originalData, returnedData) {
|
|
712
|
+
if (!isObject(returnedData)) {
|
|
710
713
|
return false;
|
|
711
714
|
}
|
|
712
|
-
if (
|
|
715
|
+
if (originalData !== returnedData) {
|
|
713
716
|
// eslint-disable-next-line no-restricted-syntax
|
|
714
|
-
for(const key in
|
|
715
|
-
if (!(key in
|
|
717
|
+
for(const key in originalData){
|
|
718
|
+
if (!(key in returnedData)) {
|
|
716
719
|
return false;
|
|
717
720
|
}
|
|
718
721
|
}
|
|
@@ -722,7 +725,7 @@ function checkReturnData(originData, returnData) {
|
|
|
722
725
|
class SyncWaterfallHook extends SyncHook {
|
|
723
726
|
emit(data) {
|
|
724
727
|
if (!isObject(data)) {
|
|
725
|
-
error(`"${this.type}" hook
|
|
728
|
+
error(`The data for the "${this.type}" hook should be an object.`);
|
|
726
729
|
}
|
|
727
730
|
for (const fn of this.listeners){
|
|
728
731
|
try {
|
|
@@ -730,7 +733,7 @@ class SyncWaterfallHook extends SyncHook {
|
|
|
730
733
|
if (checkReturnData(data, tempData)) {
|
|
731
734
|
data = tempData;
|
|
732
735
|
} else {
|
|
733
|
-
this.onerror(`
|
|
736
|
+
this.onerror(`A plugin returned an unacceptable value for the "${this.type}" type.`);
|
|
734
737
|
break;
|
|
735
738
|
}
|
|
736
739
|
} catch (e) {
|
|
@@ -750,7 +753,7 @@ class SyncWaterfallHook extends SyncHook {
|
|
|
750
753
|
class AsyncWaterfallHook extends SyncHook {
|
|
751
754
|
emit(data) {
|
|
752
755
|
if (!isObject(data)) {
|
|
753
|
-
error(`"${this.type}" hook
|
|
756
|
+
error(`The response data for the "${this.type}" hook must be an object.`);
|
|
754
757
|
}
|
|
755
758
|
const ls = Array.from(this.listeners);
|
|
756
759
|
if (ls.length > 0) {
|
|
@@ -771,7 +774,7 @@ class AsyncWaterfallHook extends SyncHook {
|
|
|
771
774
|
}
|
|
772
775
|
}
|
|
773
776
|
} else {
|
|
774
|
-
this.onerror(`
|
|
777
|
+
this.onerror(`A plugin returned an incorrect value for the "${this.type}" type.`);
|
|
775
778
|
}
|
|
776
779
|
return data;
|
|
777
780
|
};
|
|
@@ -788,10 +791,10 @@ class AsyncWaterfallHook extends SyncHook {
|
|
|
788
791
|
|
|
789
792
|
class PluginSystem {
|
|
790
793
|
usePlugin(plugin) {
|
|
791
|
-
assert(isPlainObject(plugin), '
|
|
792
|
-
// The plugin name is
|
|
794
|
+
assert(isPlainObject(plugin), 'Plugin configuration is invalid.');
|
|
795
|
+
// The plugin's name is mandatory and must be unique
|
|
793
796
|
const pluginName = plugin.name;
|
|
794
|
-
assert(pluginName, '
|
|
797
|
+
assert(pluginName, 'A name must be provided by the plugin.');
|
|
795
798
|
if (!this.registerPlugins[pluginName]) {
|
|
796
799
|
this.registerPlugins[pluginName] = plugin;
|
|
797
800
|
Object.keys(this.lifecycle).forEach((key)=>{
|
|
@@ -803,9 +806,9 @@ class PluginSystem {
|
|
|
803
806
|
}
|
|
804
807
|
}
|
|
805
808
|
removePlugin(pluginName) {
|
|
806
|
-
assert(pluginName, '
|
|
809
|
+
assert(pluginName, 'A name is required.');
|
|
807
810
|
const plugin = this.registerPlugins[pluginName];
|
|
808
|
-
assert(plugin, `plugin "${pluginName}" is not registered.`);
|
|
811
|
+
assert(plugin, `The plugin "${pluginName}" is not registered.`);
|
|
809
812
|
Object.keys(plugin).forEach((key)=>{
|
|
810
813
|
if (key !== 'name') {
|
|
811
814
|
this.lifecycle[key].remove(plugin[key]);
|
|
@@ -815,11 +818,11 @@ class PluginSystem {
|
|
|
815
818
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
816
819
|
inherit({ lifecycle, registerPlugins }) {
|
|
817
820
|
Object.keys(lifecycle).forEach((hookName)=>{
|
|
818
|
-
assert(!this.lifecycle[hookName], `"${hookName}"
|
|
821
|
+
assert(!this.lifecycle[hookName], `The hook "${hookName}" has a conflict and cannot be inherited.`);
|
|
819
822
|
this.lifecycle[hookName] = lifecycle[hookName];
|
|
820
823
|
});
|
|
821
824
|
Object.keys(registerPlugins).forEach((pluginName)=>{
|
|
822
|
-
assert(!this.registerPlugins[pluginName], `"${pluginName}"
|
|
825
|
+
assert(!this.registerPlugins[pluginName], `The plugin "${pluginName}" has a conflict and cannot be inherited.`);
|
|
823
826
|
this.usePlugin(registerPlugins[pluginName]);
|
|
824
827
|
});
|
|
825
828
|
}
|
|
@@ -838,13 +841,12 @@ function defaultPreloadArgs(preloadConfig) {
|
|
|
838
841
|
}, preloadConfig);
|
|
839
842
|
}
|
|
840
843
|
function formatPreloadArgs(remotes, preloadArgs) {
|
|
841
|
-
// let preloadOps: PreloadOptions;
|
|
842
844
|
return preloadArgs.map((args)=>{
|
|
843
845
|
const remoteInfo = matchRemote(remotes, args.nameOrAlias);
|
|
844
|
-
assert(remoteInfo, `
|
|
846
|
+
assert(remoteInfo, `Unable to preload ${args.nameOrAlias} as it is not included in ${!remoteInfo && safeToString$1({
|
|
845
847
|
remoteInfo,
|
|
846
848
|
remotes
|
|
847
|
-
})}
|
|
849
|
+
})}`);
|
|
848
850
|
return {
|
|
849
851
|
remote: remoteInfo,
|
|
850
852
|
preloadConfig: defaultPreloadArgs(args)
|
|
@@ -930,7 +932,7 @@ function preloadAssets(remoteInfo, host, assets) {
|
|
|
930
932
|
|
|
931
933
|
function assignRemoteInfo(remoteInfo, remoteSnapshot) {
|
|
932
934
|
if (!('remoteEntry' in remoteSnapshot) || !remoteSnapshot.remoteEntry) {
|
|
933
|
-
error(`The remoteEntry
|
|
935
|
+
error(`The attribute remoteEntry of ${name} must not be undefined.`);
|
|
934
936
|
}
|
|
935
937
|
const { remoteEntry } = remoteSnapshot;
|
|
936
938
|
const entryUrl = getResourceUrl(remoteSnapshot, remoteEntry);
|
|
@@ -948,7 +950,7 @@ function snapshotPlugin() {
|
|
|
948
950
|
if (!isRemoteInfoWithEntry(remote) || !isPureRemoteEntry(remote)) {
|
|
949
951
|
const { remoteSnapshot, globalSnapshot } = await origin.snapshotHandler.loadRemoteSnapshotInfo(remote);
|
|
950
952
|
assignRemoteInfo(remoteInfo, remoteSnapshot);
|
|
951
|
-
//
|
|
953
|
+
// preloading assets
|
|
952
954
|
const preloadOptions = {
|
|
953
955
|
remote,
|
|
954
956
|
preloadConfig: {
|
|
@@ -999,22 +1001,22 @@ function splitId(id) {
|
|
|
999
1001
|
};
|
|
1000
1002
|
}
|
|
1001
1003
|
}
|
|
1002
|
-
// Traverse all nodes
|
|
1004
|
+
// Traverse all nodes in moduleInfo and traverse the entire snapshot
|
|
1003
1005
|
function traverseModuleInfo(globalSnapshot, remoteInfo, traverse, isRoot, memo = {}, remoteSnapshot, getModuleInfoHook) {
|
|
1004
1006
|
const id = getFMId(remoteInfo);
|
|
1005
1007
|
const { value: snapshotValue } = getInfoWithoutType(globalSnapshot, id, getModuleInfoHook);
|
|
1006
|
-
const
|
|
1007
|
-
if (
|
|
1008
|
-
traverse(
|
|
1009
|
-
if (
|
|
1010
|
-
const remoteKeys = Object.keys(
|
|
1008
|
+
const effectiveRemoteSnapshot = remoteSnapshot || snapshotValue;
|
|
1009
|
+
if (effectiveRemoteSnapshot && !isManifestProvider(effectiveRemoteSnapshot)) {
|
|
1010
|
+
traverse(effectiveRemoteSnapshot, remoteInfo, isRoot);
|
|
1011
|
+
if (effectiveRemoteSnapshot.remotesInfo) {
|
|
1012
|
+
const remoteKeys = Object.keys(effectiveRemoteSnapshot.remotesInfo);
|
|
1011
1013
|
for (const key of remoteKeys){
|
|
1012
1014
|
if (memo[key]) {
|
|
1013
1015
|
continue;
|
|
1014
1016
|
}
|
|
1015
1017
|
memo[key] = true;
|
|
1016
1018
|
const subRemoteInfo = splitId(key);
|
|
1017
|
-
const remoteValue =
|
|
1019
|
+
const remoteValue = effectiveRemoteSnapshot.remotesInfo[key];
|
|
1018
1020
|
traverseModuleInfo(globalSnapshot, {
|
|
1019
1021
|
name: subRemoteInfo.name,
|
|
1020
1022
|
version: remoteValue.matchedVersion
|
|
@@ -1083,7 +1085,7 @@ function generatePreloadAssets(origin, preloadOptions, remote, globalSnapshot, r
|
|
|
1083
1085
|
return assets;
|
|
1084
1086
|
}, []);
|
|
1085
1087
|
}
|
|
1086
|
-
function
|
|
1088
|
+
function handleAssets(assets) {
|
|
1087
1089
|
const assetsRes = assets.map((asset)=>getResourceUrl(moduleInfoSnapshot, asset));
|
|
1088
1090
|
if (preloadConfig.filter) {
|
|
1089
1091
|
return assetsRes.filter(preloadConfig.filter);
|
|
@@ -1094,21 +1096,20 @@ function generatePreloadAssets(origin, preloadOptions, remote, globalSnapshot, r
|
|
|
1094
1096
|
const assetsLength = moduleAssetsInfo.length;
|
|
1095
1097
|
for(let index = 0; index < assetsLength; index++){
|
|
1096
1098
|
const assetsInfo = moduleAssetsInfo[index];
|
|
1097
|
-
// for (const assetsInfo of moduleAssetsInfo) {
|
|
1098
1099
|
const exposeFullPath = `${remoteInfo.name}/${assetsInfo.moduleName}`;
|
|
1099
1100
|
const preloaded = getPreloaded(exposeFullPath);
|
|
1100
1101
|
if (preloaded) {
|
|
1101
1102
|
continue;
|
|
1102
1103
|
}
|
|
1103
1104
|
if (preloadConfig.resourceCategory === 'all') {
|
|
1104
|
-
cssAssets.push(...
|
|
1105
|
-
cssAssets.push(...
|
|
1106
|
-
jsAssets.push(...
|
|
1107
|
-
jsAssets.push(...
|
|
1105
|
+
cssAssets.push(...handleAssets(assetsInfo.assets.css.async));
|
|
1106
|
+
cssAssets.push(...handleAssets(assetsInfo.assets.css.sync));
|
|
1107
|
+
jsAssets.push(...handleAssets(assetsInfo.assets.js.async));
|
|
1108
|
+
jsAssets.push(...handleAssets(assetsInfo.assets.js.sync));
|
|
1108
1109
|
// eslint-disable-next-line no-constant-condition
|
|
1109
1110
|
} else if (preloadConfig.resourceCategory = 'sync') {
|
|
1110
|
-
cssAssets.push(...
|
|
1111
|
-
jsAssets.push(...
|
|
1111
|
+
cssAssets.push(...handleAssets(assetsInfo.assets.css.sync));
|
|
1112
|
+
jsAssets.push(...handleAssets(assetsInfo.assets.js.sync));
|
|
1112
1113
|
}
|
|
1113
1114
|
setPreloaded(exposeFullPath);
|
|
1114
1115
|
}
|
|
@@ -1220,10 +1221,8 @@ class SnapshotHandler {
|
|
|
1220
1221
|
options,
|
|
1221
1222
|
moduleInfo
|
|
1222
1223
|
});
|
|
1223
|
-
// In
|
|
1224
|
-
//
|
|
1225
|
-
// 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.
|
|
1226
|
-
// 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
|
|
1224
|
+
// 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.
|
|
1225
|
+
// 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.
|
|
1227
1226
|
if (hostSnapshot && 'remotesInfo' in hostSnapshot && !getInfoWithoutType(hostSnapshot.remotesInfo, moduleInfo.name, (target, key)=>{
|
|
1228
1227
|
const res = this.HostInstance.loaderHook.lifecycle.getModuleInfo.emit({
|
|
1229
1228
|
target,
|
|
@@ -1250,7 +1249,7 @@ class SnapshotHandler {
|
|
|
1250
1249
|
remoteSnapshot,
|
|
1251
1250
|
globalSnapshot
|
|
1252
1251
|
});
|
|
1253
|
-
// global snapshot
|
|
1252
|
+
// global snapshot includes manifest or module info includes manifest
|
|
1254
1253
|
if (globalRemoteSnapshot) {
|
|
1255
1254
|
if (isManifestProvider(globalRemoteSnapshot)) {
|
|
1256
1255
|
const moduleSnapshot = await this.getManifestJson(globalRemoteSnapshot.remoteEntry, moduleInfo, {});
|
|
@@ -1375,7 +1374,7 @@ class SnapshotHandler {
|
|
|
1375
1374
|
try {
|
|
1376
1375
|
const res = await fetch(manifestUrl);
|
|
1377
1376
|
manifestJson = await res.json();
|
|
1378
|
-
assert(manifestJson.metaData && manifestJson.exposes && manifestJson.shared, `${manifestUrl} is not federation manifest`);
|
|
1377
|
+
assert(manifestJson.metaData && manifestJson.exposes && manifestJson.shared, `${manifestUrl} is not a federation manifest`);
|
|
1379
1378
|
this.manifestCache.set(manifestUrl, manifestJson);
|
|
1380
1379
|
return manifestJson;
|
|
1381
1380
|
} catch (err) {
|
|
@@ -1427,9 +1426,10 @@ class FederationHost {
|
|
|
1427
1426
|
// overrideSharedOptions(shareScope: GlobalShareScope[string]): void {}
|
|
1428
1427
|
async loadShare(pkgName, customShareInfo) {
|
|
1429
1428
|
var _this_options_shared;
|
|
1430
|
-
//
|
|
1431
|
-
//
|
|
1432
|
-
//
|
|
1429
|
+
// This function performs the following steps:
|
|
1430
|
+
// 1. Checks if the currently loaded share already exists, if not, it throws an error
|
|
1431
|
+
// 2. Searches globally for a matching share, if found, it uses it directly
|
|
1432
|
+
// 3. If not found, it retrieves it from the current share and stores the obtained share globally.
|
|
1433
1433
|
const shareInfo = Object.assign({}, (_this_options_shared = this.options.shared) == null ? void 0 : _this_options_shared[pkgName], customShareInfo);
|
|
1434
1434
|
const loadShareRes = await this.hooks.lifecycle.beforeLoadShare.emit({
|
|
1435
1435
|
pkgName,
|
|
@@ -1438,8 +1438,9 @@ class FederationHost {
|
|
|
1438
1438
|
origin: this
|
|
1439
1439
|
});
|
|
1440
1440
|
const { shareInfo: shareInfoRes } = loadShareRes;
|
|
1441
|
-
|
|
1442
|
-
|
|
1441
|
+
// Assert that shareInfoRes exists, if not, throw an error
|
|
1442
|
+
assert(shareInfoRes, `Cannot find ${pkgName} Share in the ${this.options.name}. Please ensure that the ${pkgName} Share parameters have been injected`);
|
|
1443
|
+
// Retrieve from cache
|
|
1443
1444
|
const globalShare = getGlobalShare(pkgName, shareInfoRes);
|
|
1444
1445
|
if (globalShare && globalShare.lib) {
|
|
1445
1446
|
addUniqueItem(globalShare.useIn, this.options.name);
|
|
@@ -1495,10 +1496,10 @@ class FederationHost {
|
|
|
1495
1496
|
return loading;
|
|
1496
1497
|
}
|
|
1497
1498
|
}
|
|
1498
|
-
//
|
|
1499
|
-
// 1. If the loaded shared already exists globally, then
|
|
1500
|
-
// 2. If lib exists in local shared,
|
|
1501
|
-
// 3. If the local get returns something other than Promise, then
|
|
1499
|
+
// The lib function will only be available if the shared set by eager or runtime init is set or the shared is successfully loaded.
|
|
1500
|
+
// 1. If the loaded shared already exists globally, then it will be reused
|
|
1501
|
+
// 2. If lib exists in local shared, it will be used directly
|
|
1502
|
+
// 3. If the local get returns something other than Promise, then it will be used directly
|
|
1502
1503
|
loadShareSync(pkgName) {
|
|
1503
1504
|
var _this_options_shared;
|
|
1504
1505
|
const shareInfo = (_this_options_shared = this.options.shared) == null ? void 0 : _this_options_shared[pkgName];
|
|
@@ -1523,10 +1524,10 @@ class FederationHost {
|
|
|
1523
1524
|
const module = shareInfo.get();
|
|
1524
1525
|
if (module instanceof Promise) {
|
|
1525
1526
|
throw new Error(`
|
|
1526
|
-
The loadShareSync function
|
|
1527
|
-
|
|
1528
|
-
1.
|
|
1529
|
-
2.
|
|
1527
|
+
The loadShareSync function was unable to load ${pkgName}. The ${pkgName} could not be found in ${this.options.name}.
|
|
1528
|
+
Possible reasons for failure: \n
|
|
1529
|
+
1. The ${pkgName} share was registered with the 'get' attribute, but loadShare was not used beforehand.\n
|
|
1530
|
+
2. The ${pkgName} share was not registered with the 'lib' attribute.\n
|
|
1530
1531
|
`);
|
|
1531
1532
|
}
|
|
1532
1533
|
shareInfo.lib = module;
|
|
@@ -1540,10 +1541,10 @@ class FederationHost {
|
|
|
1540
1541
|
return shareInfo.lib;
|
|
1541
1542
|
}
|
|
1542
1543
|
throw new Error(`
|
|
1543
|
-
The loadShareSync function
|
|
1544
|
-
|
|
1545
|
-
1.
|
|
1546
|
-
2.
|
|
1544
|
+
The loadShareSync function was unable to load ${pkgName}. The ${pkgName} could not be found in ${this.options.name}.
|
|
1545
|
+
Possible reasons for failure: \n
|
|
1546
|
+
1. The ${pkgName} share was registered with the 'get' attribute, but loadShare was not used beforehand.\n
|
|
1547
|
+
2. The ${pkgName} share was not registered with the 'lib' attribute.\n
|
|
1547
1548
|
`);
|
|
1548
1549
|
}
|
|
1549
1550
|
async _getRemoteModuleAndOptions(id) {
|
|
@@ -1555,10 +1556,10 @@ class FederationHost {
|
|
|
1555
1556
|
const { id: idRes } = loadRemoteArgs;
|
|
1556
1557
|
const remoteSplitInfo = matchRemoteWithNameAndExpose(this.options.remotes, idRes);
|
|
1557
1558
|
assert(remoteSplitInfo, `
|
|
1558
|
-
|
|
1559
|
-
1. ${idRes} was not
|
|
1560
|
-
2.
|
|
1561
|
-
3. The 'beforeLoadRemote' hook was provided but did not return the correct 'remoteInfo' when
|
|
1559
|
+
Unable to locate ${idRes} in ${this.options.name}. Potential reasons for failure include:\n
|
|
1560
|
+
1. ${idRes} was not included in the 'remotes' parameter of ${this.options.name}.\n
|
|
1561
|
+
2. ${idRes} could not be found in the 'remotes' of ${this.options.name} with either 'name' or 'alias' attributes.
|
|
1562
|
+
3. The 'beforeLoadRemote' hook was provided but did not return the correct 'remoteInfo' when attempting to load ${idRes}.
|
|
1562
1563
|
`);
|
|
1563
1564
|
const { remote: rawRemote } = remoteSplitInfo;
|
|
1564
1565
|
const remoteInfo = getRemoteInfo(rawRemote);
|
|
@@ -1570,7 +1571,7 @@ class FederationHost {
|
|
|
1570
1571
|
remoteInfo
|
|
1571
1572
|
}));
|
|
1572
1573
|
const { remote, expose } = matchInfo;
|
|
1573
|
-
assert(remote && expose, `The 'beforeLoadRemote' hook was
|
|
1574
|
+
assert(remote && expose, `The 'beforeLoadRemote' hook was executed, but it failed to return the correct 'remote' and 'expose' values while loading ${idRes}.`);
|
|
1574
1575
|
let module = this.moduleCache.get(remote.name);
|
|
1575
1576
|
const moduleOptions = {
|
|
1576
1577
|
hostInfo: {
|
|
@@ -1599,10 +1600,10 @@ class FederationHost {
|
|
|
1599
1600
|
const { loadFactory = true } = options || {
|
|
1600
1601
|
loadFactory: true
|
|
1601
1602
|
};
|
|
1602
|
-
// 1.
|
|
1603
|
-
// 2. Request the snapshot information of the current host and store the obtained snapshot information
|
|
1604
|
-
// 3.
|
|
1605
|
-
// 4. After
|
|
1603
|
+
// 1. Validate the parameters of the retrieved module. There are two module request methods: pkgName + expose and alias + expose.
|
|
1604
|
+
// 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.
|
|
1605
|
+
// 3. Retrieve the detailed information of the current module from global (remoteEntry address, expose resource address)
|
|
1606
|
+
// 4. After retrieving remoteEntry, call the init of the module, and then retrieve the exported content of the module through get
|
|
1606
1607
|
// id: pkgName(@federation/app1) + expose(button) = @federation/app1/button
|
|
1607
1608
|
// id: alias(app1) + expose(button) = app1/button
|
|
1608
1609
|
// id: alias(app1/utils) + expose(loadash/sort) = app1/utils/loadash/sort
|
|
@@ -1656,23 +1657,23 @@ class FederationHost {
|
|
|
1656
1657
|
}));
|
|
1657
1658
|
}
|
|
1658
1659
|
/**
|
|
1659
|
-
*
|
|
1660
|
-
*
|
|
1661
|
-
*
|
|
1660
|
+
* This function initializes the sharing sequence (executed only once per share scope).
|
|
1661
|
+
* It accepts one argument, the name of the share scope.
|
|
1662
|
+
* If the share scope does not exist, it creates one.
|
|
1662
1663
|
*/ // eslint-disable-next-line @typescript-eslint/member-ordering
|
|
1663
1664
|
initializeSharing(shareScopeName = DEFAULT_SCOPE) {
|
|
1664
1665
|
const shareScopeLoading = Global.__FEDERATION__.__SHARE_SCOPE_LOADING__;
|
|
1665
1666
|
const shareScope = Global.__FEDERATION__.__SHARE__;
|
|
1666
1667
|
const hostName = this.options.name;
|
|
1667
|
-
// only
|
|
1668
|
+
// Executes only once
|
|
1668
1669
|
if (shareScopeLoading[shareScopeName]) {
|
|
1669
1670
|
return shareScopeLoading[shareScopeName];
|
|
1670
1671
|
}
|
|
1671
|
-
//
|
|
1672
|
+
// Creates a new share scope if necessary
|
|
1672
1673
|
if (!shareScope[shareScopeName]) {
|
|
1673
1674
|
shareScope[shareScopeName] = {};
|
|
1674
1675
|
}
|
|
1675
|
-
//
|
|
1676
|
+
// Executes all initialization snippets from all accessible modules
|
|
1676
1677
|
const scope = shareScope[shareScopeName];
|
|
1677
1678
|
const register = (name, shared)=>{
|
|
1678
1679
|
const { version, eager } = shared;
|
|
@@ -1720,8 +1721,8 @@ class FederationHost {
|
|
|
1720
1721
|
const remotes = userRemotes.reduce((res, remote)=>{
|
|
1721
1722
|
if (!res.find((item)=>item.name === remote.name)) {
|
|
1722
1723
|
if (remote.alias) {
|
|
1723
|
-
//
|
|
1724
|
-
//
|
|
1724
|
+
// Validate if alias equals the prefix of remote.name and remote.alias, if so, throw an error
|
|
1725
|
+
// As multi-level path references cannot guarantee unique names, alias being a prefix of remote.name is not supported
|
|
1725
1726
|
const findEqual = res.find((item)=>{
|
|
1726
1727
|
var _item_alias;
|
|
1727
1728
|
return remote.alias && (item.name.startsWith(remote.alias) || ((_item_alias = item.alias) == null ? void 0 : _item_alias.startsWith(remote.alias)));
|
|
@@ -1738,7 +1739,7 @@ class FederationHost {
|
|
|
1738
1739
|
remote.shareScope = DEFAULT_SCOPE;
|
|
1739
1740
|
}
|
|
1740
1741
|
if (!remote.type) {
|
|
1741
|
-
// FIXME: The build plugin
|
|
1742
|
+
// FIXME: The build plugin needs to support this field
|
|
1742
1743
|
remote.type = DEFAULT_REMOTE_TYPE;
|
|
1743
1744
|
}
|
|
1744
1745
|
res.push(remote);
|
|
@@ -1843,7 +1844,7 @@ class FederationHost {
|
|
|
1843
1844
|
generatePreloadAssets: new AsyncHook('generatePreloadAssets'),
|
|
1844
1845
|
afterPreloadRemote: new AsyncHook()
|
|
1845
1846
|
});
|
|
1846
|
-
this.version = '0.0.1';
|
|
1847
|
+
this.version = '1.0.0-canary.1';
|
|
1847
1848
|
this.moduleCache = new Map();
|
|
1848
1849
|
this.loaderHook = new PluginSystem({
|
|
1849
1850
|
// FIXME: may not be suitable
|
|
@@ -1851,8 +1852,8 @@ class FederationHost {
|
|
|
1851
1852
|
createScript: new SyncHook()
|
|
1852
1853
|
});
|
|
1853
1854
|
this.loadingShare = {};
|
|
1854
|
-
// TODO:
|
|
1855
|
-
//
|
|
1855
|
+
// TODO: Validate the details of the options
|
|
1856
|
+
// Initialize options with default values
|
|
1856
1857
|
const defaultOptions = {
|
|
1857
1858
|
id: getBuilderId(),
|
|
1858
1859
|
name: userOptions.name,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@module-federation/runtime",
|
|
3
|
-
"version": "1.0.0-canary.
|
|
3
|
+
"version": "1.0.0-canary.2",
|
|
4
4
|
"author": "zhouxiao <codingzx@gmail.com>",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./index.cjs.js",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"./helpers.cjs.d.ts"
|
|
30
30
|
],
|
|
31
31
|
"type": [
|
|
32
|
-
"./
|
|
32
|
+
"./type.cjs.d.ts"
|
|
33
33
|
]
|
|
34
34
|
}
|
|
35
35
|
},
|