@module-federation/runtime-core 0.0.0-feat-modern-3-0-20251201041706 → 0.0.0-feat-shared-treeshake-poc-20251211025043
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.cjs.cjs +359 -145
- package/dist/index.cjs.cjs.map +1 -1
- package/dist/index.esm.js +359 -145
- package/dist/index.esm.js.map +1 -1
- package/dist/src/core.d.ts +5 -1
- package/dist/src/module/index.d.ts +2 -1
- package/dist/src/shared/index.d.ts +12 -3
- package/dist/src/type/config.d.ts +14 -1
- package/dist/src/utils/share.d.ts +27 -9
- package/package.json +3 -3
package/dist/index.cjs.cjs
CHANGED
|
@@ -201,7 +201,7 @@ function getGlobalFederationConstructor() {
|
|
|
201
201
|
function setGlobalFederationConstructor(FederationConstructor, isDebug = sdk.isDebugMode()) {
|
|
202
202
|
if (isDebug) {
|
|
203
203
|
CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR__ = FederationConstructor;
|
|
204
|
-
CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR_VERSION__ = "0.0.0-feat-
|
|
204
|
+
CurrentGlobal.__FEDERATION__.__DEBUG_CONSTRUCTOR_VERSION__ = "0.0.0-feat-shared-treeshake-poc-20251211025043";
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
207
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
@@ -808,6 +808,9 @@ function formatShare(shareArgs, from, name, shareStrategy) {
|
|
|
808
808
|
throw new Error(`Can not get shared '${name}'!`);
|
|
809
809
|
});
|
|
810
810
|
}
|
|
811
|
+
if (shareArgs.shareConfig?.eager && shareArgs.treeshake) {
|
|
812
|
+
throw new Error('Can not set "eager:true" and "treeshake" at the same time!');
|
|
813
|
+
}
|
|
811
814
|
return {
|
|
812
815
|
deps: [],
|
|
813
816
|
useIn: [],
|
|
@@ -828,37 +831,67 @@ function formatShare(shareArgs, from, name, shareStrategy) {
|
|
|
828
831
|
? shareArgs.scope
|
|
829
832
|
: [shareArgs.scope ?? 'default'],
|
|
830
833
|
strategy: (shareArgs.strategy ?? shareStrategy) || 'version-first',
|
|
834
|
+
treeshake: shareArgs.treeshake
|
|
835
|
+
? {
|
|
836
|
+
...shareArgs.treeshake,
|
|
837
|
+
strategy: shareArgs.treeshake.strategy ?? 'server',
|
|
838
|
+
status: shareArgs.treeshake.status ?? 1 /* TreeshakeStatus.UNKNOWN */,
|
|
839
|
+
useIn: [],
|
|
840
|
+
}
|
|
841
|
+
: undefined,
|
|
831
842
|
};
|
|
832
843
|
}
|
|
833
|
-
function formatShareConfigs(
|
|
834
|
-
const shareArgs =
|
|
835
|
-
const from =
|
|
836
|
-
const
|
|
844
|
+
function formatShareConfigs(prevOptions, newOptions) {
|
|
845
|
+
const shareArgs = newOptions.shared || {};
|
|
846
|
+
const from = newOptions.name;
|
|
847
|
+
const newShareInfos = Object.keys(shareArgs).reduce((res, pkgName) => {
|
|
837
848
|
const arrayShareArgs = arrayOptions(shareArgs[pkgName]);
|
|
838
849
|
res[pkgName] = res[pkgName] || [];
|
|
839
850
|
arrayShareArgs.forEach((shareConfig) => {
|
|
840
|
-
res[pkgName].push(formatShare(shareConfig, from, pkgName,
|
|
851
|
+
res[pkgName].push(formatShare(shareConfig, from, pkgName, newOptions.shareStrategy));
|
|
841
852
|
});
|
|
842
853
|
return res;
|
|
843
854
|
}, {});
|
|
844
|
-
const
|
|
845
|
-
...
|
|
855
|
+
const allShareInfos = {
|
|
856
|
+
...prevOptions.shared,
|
|
846
857
|
};
|
|
847
|
-
Object.keys(
|
|
848
|
-
if (!
|
|
849
|
-
|
|
858
|
+
Object.keys(newShareInfos).forEach((shareKey) => {
|
|
859
|
+
if (!allShareInfos[shareKey]) {
|
|
860
|
+
allShareInfos[shareKey] = newShareInfos[shareKey];
|
|
850
861
|
}
|
|
851
862
|
else {
|
|
852
|
-
|
|
853
|
-
const isSameVersion =
|
|
863
|
+
newShareInfos[shareKey].forEach((newUserSharedOptions) => {
|
|
864
|
+
const isSameVersion = allShareInfos[shareKey].find((sharedVal) => sharedVal.version === newUserSharedOptions.version);
|
|
854
865
|
if (!isSameVersion) {
|
|
855
|
-
|
|
866
|
+
allShareInfos[shareKey].push(newUserSharedOptions);
|
|
856
867
|
}
|
|
857
868
|
});
|
|
858
869
|
}
|
|
859
870
|
});
|
|
860
|
-
return {
|
|
871
|
+
return { allShareInfos, newShareInfos };
|
|
861
872
|
}
|
|
873
|
+
function shouldUseTreeshake(treeshake, usedExports) {
|
|
874
|
+
if (!treeshake) {
|
|
875
|
+
return false;
|
|
876
|
+
}
|
|
877
|
+
const { status, strategy } = treeshake;
|
|
878
|
+
if (status === 0 /* TreeshakeStatus.NO_USE */) {
|
|
879
|
+
return false;
|
|
880
|
+
}
|
|
881
|
+
if (status === 2 /* TreeshakeStatus.CALCULATED */) {
|
|
882
|
+
return true;
|
|
883
|
+
}
|
|
884
|
+
if (strategy === 'infer') {
|
|
885
|
+
if (!usedExports) {
|
|
886
|
+
return true;
|
|
887
|
+
}
|
|
888
|
+
return isMatchUsedExports(treeshake, usedExports);
|
|
889
|
+
}
|
|
890
|
+
return false;
|
|
891
|
+
}
|
|
892
|
+
/**
|
|
893
|
+
* compare version a and b, return true if a is less than b
|
|
894
|
+
*/
|
|
862
895
|
function versionLt(a, b) {
|
|
863
896
|
const transformInvalidVersion = (version) => {
|
|
864
897
|
const isNumberVersion = !Number.isNaN(Number(version));
|
|
@@ -904,19 +937,79 @@ const isLoaded = (shared) => {
|
|
|
904
937
|
const isLoading = (shared) => {
|
|
905
938
|
return Boolean(shared.loading);
|
|
906
939
|
};
|
|
907
|
-
|
|
940
|
+
const isMatchUsedExports = (treeshake, usedExports) => {
|
|
941
|
+
if (!treeshake || !usedExports) {
|
|
942
|
+
return false;
|
|
943
|
+
}
|
|
944
|
+
const { usedExports: treeshakeUsedExports } = treeshake;
|
|
945
|
+
if (!treeshakeUsedExports) {
|
|
946
|
+
return false;
|
|
947
|
+
}
|
|
948
|
+
if (usedExports.every((e) => treeshakeUsedExports.includes(e))) {
|
|
949
|
+
return true;
|
|
950
|
+
}
|
|
951
|
+
return false;
|
|
952
|
+
};
|
|
953
|
+
function findSingletonVersionOrderByVersion(shareScopeMap, scope, pkgName, treeshake) {
|
|
908
954
|
const versions = shareScopeMap[scope][pkgName];
|
|
955
|
+
let version = '';
|
|
956
|
+
let useTreeshake = shouldUseTreeshake(treeshake);
|
|
957
|
+
// return false means use prev version
|
|
909
958
|
const callback = function (prev, cur) {
|
|
959
|
+
if (useTreeshake) {
|
|
960
|
+
if (!versions[prev].treeshake) {
|
|
961
|
+
return true;
|
|
962
|
+
}
|
|
963
|
+
if (!versions[cur].treeshake) {
|
|
964
|
+
return false;
|
|
965
|
+
}
|
|
966
|
+
return !isLoaded(versions[prev].treeshake) && versionLt(prev, cur);
|
|
967
|
+
}
|
|
910
968
|
return !isLoaded(versions[prev]) && versionLt(prev, cur);
|
|
911
969
|
};
|
|
912
|
-
|
|
970
|
+
if (useTreeshake) {
|
|
971
|
+
version = findVersion(shareScopeMap[scope][pkgName], callback);
|
|
972
|
+
if (version) {
|
|
973
|
+
return {
|
|
974
|
+
version,
|
|
975
|
+
useTreeshake,
|
|
976
|
+
};
|
|
977
|
+
}
|
|
978
|
+
useTreeshake = false;
|
|
979
|
+
}
|
|
980
|
+
return {
|
|
981
|
+
version: findVersion(shareScopeMap[scope][pkgName], callback),
|
|
982
|
+
useTreeshake,
|
|
983
|
+
};
|
|
913
984
|
}
|
|
914
|
-
|
|
985
|
+
const isLoadingOrLoaded = (shared) => {
|
|
986
|
+
return isLoaded(shared) || isLoading(shared);
|
|
987
|
+
};
|
|
988
|
+
function findSingletonVersionOrderByLoaded(shareScopeMap, scope, pkgName, treeshake) {
|
|
915
989
|
const versions = shareScopeMap[scope][pkgName];
|
|
990
|
+
let version = '';
|
|
991
|
+
let useTreeshake = shouldUseTreeshake(treeshake);
|
|
992
|
+
// return false means use prev version
|
|
916
993
|
const callback = function (prev, cur) {
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
994
|
+
if (useTreeshake) {
|
|
995
|
+
if (!versions[prev].treeshake) {
|
|
996
|
+
return true;
|
|
997
|
+
}
|
|
998
|
+
if (!versions[cur].treeshake) {
|
|
999
|
+
return false;
|
|
1000
|
+
}
|
|
1001
|
+
if (isLoadingOrLoaded(versions[cur].treeshake)) {
|
|
1002
|
+
if (isLoadingOrLoaded(versions[prev].treeshake)) {
|
|
1003
|
+
return Boolean(versionLt(prev, cur));
|
|
1004
|
+
}
|
|
1005
|
+
else {
|
|
1006
|
+
return true;
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
if (isLoadingOrLoaded(versions[prev].treeshake)) {
|
|
1010
|
+
return false;
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
920
1013
|
if (isLoadingOrLoaded(versions[cur])) {
|
|
921
1014
|
if (isLoadingOrLoaded(versions[prev])) {
|
|
922
1015
|
return Boolean(versionLt(prev, cur));
|
|
@@ -930,7 +1023,20 @@ function findSingletonVersionOrderByLoaded(shareScopeMap, scope, pkgName) {
|
|
|
930
1023
|
}
|
|
931
1024
|
return versionLt(prev, cur);
|
|
932
1025
|
};
|
|
933
|
-
|
|
1026
|
+
if (useTreeshake) {
|
|
1027
|
+
version = findVersion(shareScopeMap[scope][pkgName], callback);
|
|
1028
|
+
if (version) {
|
|
1029
|
+
return {
|
|
1030
|
+
version,
|
|
1031
|
+
useTreeshake,
|
|
1032
|
+
};
|
|
1033
|
+
}
|
|
1034
|
+
useTreeshake = false;
|
|
1035
|
+
}
|
|
1036
|
+
return {
|
|
1037
|
+
version: findVersion(shareScopeMap[scope][pkgName], callback),
|
|
1038
|
+
useTreeshake,
|
|
1039
|
+
};
|
|
934
1040
|
}
|
|
935
1041
|
function getFindShareFunction(strategy) {
|
|
936
1042
|
if (strategy === 'loaded-first') {
|
|
@@ -942,7 +1048,7 @@ function getRegisteredShare(localShareScopeMap, pkgName, shareInfo, resolveShare
|
|
|
942
1048
|
if (!localShareScopeMap) {
|
|
943
1049
|
return;
|
|
944
1050
|
}
|
|
945
|
-
const { shareConfig, scope = DEFAULT_SCOPE, strategy } = shareInfo;
|
|
1051
|
+
const { shareConfig, scope = DEFAULT_SCOPE, strategy, treeshake } = shareInfo;
|
|
946
1052
|
const scopes = Array.isArray(scope) ? scope : [scope];
|
|
947
1053
|
for (const sc of scopes) {
|
|
948
1054
|
if (shareConfig &&
|
|
@@ -950,14 +1056,13 @@ function getRegisteredShare(localShareScopeMap, pkgName, shareInfo, resolveShare
|
|
|
950
1056
|
localShareScopeMap[sc][pkgName]) {
|
|
951
1057
|
const { requiredVersion } = shareConfig;
|
|
952
1058
|
const findShareFunction = getFindShareFunction(strategy);
|
|
953
|
-
const maxOrSingletonVersion = findShareFunction(localShareScopeMap, sc, pkgName);
|
|
954
|
-
//@ts-ignore
|
|
1059
|
+
const { version: maxOrSingletonVersion, useTreeshake } = findShareFunction(localShareScopeMap, sc, pkgName, treeshake);
|
|
955
1060
|
const defaultResolver = () => {
|
|
1061
|
+
const shared = localShareScopeMap[sc][pkgName][maxOrSingletonVersion];
|
|
956
1062
|
if (shareConfig.singleton) {
|
|
957
1063
|
if (typeof requiredVersion === 'string' &&
|
|
958
1064
|
!satisfy(maxOrSingletonVersion, requiredVersion)) {
|
|
959
|
-
const msg = `Version ${maxOrSingletonVersion} from ${maxOrSingletonVersion &&
|
|
960
|
-
localShareScopeMap[sc][pkgName][maxOrSingletonVersion].from} of shared singleton module ${pkgName} does not satisfy the requirement of ${shareInfo.from} which needs ${requiredVersion})`;
|
|
1065
|
+
const msg = `Version ${maxOrSingletonVersion} from ${maxOrSingletonVersion && shared.from} of shared singleton module ${pkgName} does not satisfy the requirement of ${shareInfo.from} which needs ${requiredVersion})`;
|
|
961
1066
|
if (shareConfig.strictVersion) {
|
|
962
1067
|
error(msg);
|
|
963
1068
|
}
|
|
@@ -965,21 +1070,48 @@ function getRegisteredShare(localShareScopeMap, pkgName, shareInfo, resolveShare
|
|
|
965
1070
|
warn(msg);
|
|
966
1071
|
}
|
|
967
1072
|
}
|
|
968
|
-
return
|
|
1073
|
+
return {
|
|
1074
|
+
shared,
|
|
1075
|
+
useTreeshake,
|
|
1076
|
+
};
|
|
969
1077
|
}
|
|
970
1078
|
else {
|
|
971
1079
|
if (requiredVersion === false || requiredVersion === '*') {
|
|
972
|
-
return
|
|
1080
|
+
return {
|
|
1081
|
+
shared,
|
|
1082
|
+
useTreeshake,
|
|
1083
|
+
};
|
|
973
1084
|
}
|
|
974
1085
|
if (satisfy(maxOrSingletonVersion, requiredVersion)) {
|
|
975
|
-
return
|
|
1086
|
+
return {
|
|
1087
|
+
shared,
|
|
1088
|
+
useTreeshake,
|
|
1089
|
+
};
|
|
1090
|
+
}
|
|
1091
|
+
const _usedTreeshake = shouldUseTreeshake(treeshake);
|
|
1092
|
+
if (_usedTreeshake) {
|
|
1093
|
+
for (const [versionKey, versionValue] of Object.entries(localShareScopeMap[sc][pkgName])) {
|
|
1094
|
+
if (!shouldUseTreeshake(versionValue.treeshake, treeshake?.usedExports)) {
|
|
1095
|
+
continue;
|
|
1096
|
+
}
|
|
1097
|
+
if (satisfy(versionKey, requiredVersion)) {
|
|
1098
|
+
return {
|
|
1099
|
+
shared: versionValue,
|
|
1100
|
+
useTreeshake: _usedTreeshake,
|
|
1101
|
+
};
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
976
1104
|
}
|
|
977
1105
|
for (const [versionKey, versionValue] of Object.entries(localShareScopeMap[sc][pkgName])) {
|
|
978
1106
|
if (satisfy(versionKey, requiredVersion)) {
|
|
979
|
-
return
|
|
1107
|
+
return {
|
|
1108
|
+
shared: versionValue,
|
|
1109
|
+
useTreeshake: false,
|
|
1110
|
+
};
|
|
980
1111
|
}
|
|
981
1112
|
}
|
|
982
1113
|
}
|
|
1114
|
+
return;
|
|
983
1115
|
};
|
|
984
1116
|
const params = {
|
|
985
1117
|
shareScopeMap: localShareScopeMap,
|
|
@@ -987,6 +1119,7 @@ function getRegisteredShare(localShareScopeMap, pkgName, shareInfo, resolveShare
|
|
|
987
1119
|
pkgName,
|
|
988
1120
|
version: maxOrSingletonVersion,
|
|
989
1121
|
GlobalFederation: Global.__FEDERATION__,
|
|
1122
|
+
shareInfo,
|
|
990
1123
|
resolver: defaultResolver,
|
|
991
1124
|
};
|
|
992
1125
|
const resolveShared = resolveShare.emit(params) || params;
|
|
@@ -1008,13 +1141,47 @@ function getTargetSharedOptions(options) {
|
|
|
1008
1141
|
shareVersionMap[shared.version] = shared;
|
|
1009
1142
|
});
|
|
1010
1143
|
const callback = function (prev, cur) {
|
|
1011
|
-
return
|
|
1144
|
+
return (
|
|
1145
|
+
// TODO: consider multiple treeshake shared scenes
|
|
1146
|
+
!isLoaded(shareVersionMap[prev]) && versionLt(prev, cur));
|
|
1012
1147
|
};
|
|
1013
1148
|
const maxVersion = findVersion(shareVersionMap, callback);
|
|
1014
1149
|
return shareVersionMap[maxVersion];
|
|
1015
1150
|
};
|
|
1016
1151
|
const resolver = extraOptions?.resolver ?? defaultResolver;
|
|
1017
|
-
|
|
1152
|
+
const isPlainObject = (val) => {
|
|
1153
|
+
return val !== null && typeof val === 'object' && !Array.isArray(val);
|
|
1154
|
+
};
|
|
1155
|
+
const merge = (...sources) => {
|
|
1156
|
+
const out = {};
|
|
1157
|
+
for (const src of sources) {
|
|
1158
|
+
if (!src)
|
|
1159
|
+
continue;
|
|
1160
|
+
for (const [key, value] of Object.entries(src)) {
|
|
1161
|
+
const prev = out[key];
|
|
1162
|
+
if (isPlainObject(prev) && isPlainObject(value)) {
|
|
1163
|
+
out[key] = merge(prev, value);
|
|
1164
|
+
}
|
|
1165
|
+
else if (value !== undefined) {
|
|
1166
|
+
out[key] = value;
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
return out;
|
|
1171
|
+
};
|
|
1172
|
+
return merge(resolver(shareInfos[pkgName]), extraOptions?.customShareInfo);
|
|
1173
|
+
}
|
|
1174
|
+
const addUseIn = (shared, from) => {
|
|
1175
|
+
if (!shared.useIn) {
|
|
1176
|
+
shared.useIn = [];
|
|
1177
|
+
}
|
|
1178
|
+
addUniqueItem(shared.useIn, from);
|
|
1179
|
+
};
|
|
1180
|
+
function directShare(shared, useTreeshake) {
|
|
1181
|
+
if (useTreeshake && shared.treeshake) {
|
|
1182
|
+
return shared.treeshake;
|
|
1183
|
+
}
|
|
1184
|
+
return shared;
|
|
1018
1185
|
}
|
|
1019
1186
|
|
|
1020
1187
|
function getBuilderId() {
|
|
@@ -1526,6 +1693,40 @@ var helpers = {
|
|
|
1526
1693
|
},
|
|
1527
1694
|
};
|
|
1528
1695
|
|
|
1696
|
+
function createRemoteEntryInitOptions(remoteInfo, hostShareScopeMap) {
|
|
1697
|
+
const localShareScopeMap = hostShareScopeMap;
|
|
1698
|
+
const shareScopeKeys = Array.isArray(remoteInfo.shareScope)
|
|
1699
|
+
? remoteInfo.shareScope
|
|
1700
|
+
: [remoteInfo.shareScope];
|
|
1701
|
+
if (!shareScopeKeys.length) {
|
|
1702
|
+
shareScopeKeys.push('default');
|
|
1703
|
+
}
|
|
1704
|
+
shareScopeKeys.forEach((shareScopeKey) => {
|
|
1705
|
+
if (!localShareScopeMap[shareScopeKey]) {
|
|
1706
|
+
localShareScopeMap[shareScopeKey] = {};
|
|
1707
|
+
}
|
|
1708
|
+
});
|
|
1709
|
+
const remoteEntryInitOptions = {
|
|
1710
|
+
version: remoteInfo.version || '',
|
|
1711
|
+
shareScopeKeys: Array.isArray(remoteInfo.shareScope)
|
|
1712
|
+
? shareScopeKeys
|
|
1713
|
+
: remoteInfo.shareScope || 'default',
|
|
1714
|
+
};
|
|
1715
|
+
// Help to find host instance
|
|
1716
|
+
Object.defineProperty(remoteEntryInitOptions, 'shareScopeMap', {
|
|
1717
|
+
value: localShareScopeMap,
|
|
1718
|
+
// remoteEntryInitOptions will be traversed and assigned during container init, ,so this attribute is not allowed to be traversed
|
|
1719
|
+
enumerable: false,
|
|
1720
|
+
});
|
|
1721
|
+
// TODO: compate legacy init params, should use shareScopeMap if exist
|
|
1722
|
+
const shareScope = localShareScopeMap[shareScopeKeys[0]];
|
|
1723
|
+
const initScope = [];
|
|
1724
|
+
return {
|
|
1725
|
+
remoteEntryInitOptions,
|
|
1726
|
+
shareScope,
|
|
1727
|
+
initScope,
|
|
1728
|
+
};
|
|
1729
|
+
}
|
|
1529
1730
|
class Module {
|
|
1530
1731
|
constructor({ remoteInfo, host, }) {
|
|
1531
1732
|
this.inited = false;
|
|
@@ -1537,8 +1738,7 @@ class Module {
|
|
|
1537
1738
|
if (this.remoteEntryExports) {
|
|
1538
1739
|
return this.remoteEntryExports;
|
|
1539
1740
|
}
|
|
1540
|
-
|
|
1541
|
-
remoteEntryExports = await getRemoteEntry({
|
|
1741
|
+
const remoteEntryExports = await getRemoteEntry({
|
|
1542
1742
|
origin: this.host,
|
|
1543
1743
|
remoteInfo: this.remoteInfo,
|
|
1544
1744
|
remoteEntryExports: this.remoteEntryExports,
|
|
@@ -1553,33 +1753,7 @@ class Module {
|
|
|
1553
1753
|
// Get remoteEntry.js
|
|
1554
1754
|
const remoteEntryExports = await this.getEntry();
|
|
1555
1755
|
if (!this.inited) {
|
|
1556
|
-
const
|
|
1557
|
-
const shareScopeKeys = Array.isArray(this.remoteInfo.shareScope)
|
|
1558
|
-
? this.remoteInfo.shareScope
|
|
1559
|
-
: [this.remoteInfo.shareScope];
|
|
1560
|
-
if (!shareScopeKeys.length) {
|
|
1561
|
-
shareScopeKeys.push('default');
|
|
1562
|
-
}
|
|
1563
|
-
shareScopeKeys.forEach((shareScopeKey) => {
|
|
1564
|
-
if (!localShareScopeMap[shareScopeKey]) {
|
|
1565
|
-
localShareScopeMap[shareScopeKey] = {};
|
|
1566
|
-
}
|
|
1567
|
-
});
|
|
1568
|
-
// TODO: compate legacy init params, should use shareScopeMap if exist
|
|
1569
|
-
const shareScope = localShareScopeMap[shareScopeKeys[0]];
|
|
1570
|
-
const initScope = [];
|
|
1571
|
-
const remoteEntryInitOptions = {
|
|
1572
|
-
version: this.remoteInfo.version || '',
|
|
1573
|
-
shareScopeKeys: Array.isArray(this.remoteInfo.shareScope)
|
|
1574
|
-
? shareScopeKeys
|
|
1575
|
-
: this.remoteInfo.shareScope || 'default',
|
|
1576
|
-
};
|
|
1577
|
-
// Help to find host instance
|
|
1578
|
-
Object.defineProperty(remoteEntryInitOptions, 'shareScopeMap', {
|
|
1579
|
-
value: localShareScopeMap,
|
|
1580
|
-
// remoteEntryInitOptions will be traversed and assigned during container init, ,so this attribute is not allowed to be traversed
|
|
1581
|
-
enumerable: false,
|
|
1582
|
-
});
|
|
1756
|
+
const { remoteEntryInitOptions, shareScope, initScope } = createRemoteEntryInitOptions(this.remoteInfo, this.host.shareScopeMap);
|
|
1583
1757
|
const initContainerOptions = await this.host.hooks.lifecycle.beforeInitContainer.emit({
|
|
1584
1758
|
shareScope,
|
|
1585
1759
|
// @ts-ignore shareScopeMap will be set by Object.defineProperty
|
|
@@ -2059,7 +2233,7 @@ function generatePreloadAssets(origin, preloadOptions, remote, globalSnapshot, r
|
|
|
2059
2233
|
}, true, memo, remoteSnapshot);
|
|
2060
2234
|
if (remoteSnapshot.shared && remoteSnapshot.shared.length > 0) {
|
|
2061
2235
|
const collectSharedAssets = (shareInfo, snapshotShared) => {
|
|
2062
|
-
const registeredShared = getRegisteredShare(origin.shareScopeMap, snapshotShared.sharedName, shareInfo, origin.sharedHandler.hooks.lifecycle.resolveShare);
|
|
2236
|
+
const { shared: registeredShared } = getRegisteredShare(origin.shareScopeMap, snapshotShared.sharedName, shareInfo, origin.sharedHandler.hooks.lifecycle.resolveShare) || {};
|
|
2063
2237
|
// If the global share does not exist, or the lib function does not exist, it means that the shared has not been loaded yet and can be preloaded.
|
|
2064
2238
|
if (registeredShared && typeof registeredShared.lib === 'function') {
|
|
2065
2239
|
snapshotShared.assets.js.sync.forEach((asset) => {
|
|
@@ -2350,6 +2524,7 @@ class SnapshotHandler {
|
|
|
2350
2524
|
class SharedHandler {
|
|
2351
2525
|
constructor(host) {
|
|
2352
2526
|
this.hooks = new PluginSystem({
|
|
2527
|
+
beforeRegisterShare: new SyncWaterfallHook('beforeRegisterShare'),
|
|
2353
2528
|
afterResolve: new AsyncWaterfallHook('afterResolve'),
|
|
2354
2529
|
beforeLoadShare: new AsyncWaterfallHook('beforeLoadShare'),
|
|
2355
2530
|
// not used yet
|
|
@@ -2365,12 +2540,17 @@ class SharedHandler {
|
|
|
2365
2540
|
}
|
|
2366
2541
|
// register shared in shareScopeMap
|
|
2367
2542
|
registerShared(globalOptions, userOptions) {
|
|
2368
|
-
const {
|
|
2369
|
-
const sharedKeys = Object.keys(
|
|
2543
|
+
const { newShareInfos, allShareInfos } = formatShareConfigs(globalOptions, userOptions);
|
|
2544
|
+
const sharedKeys = Object.keys(newShareInfos);
|
|
2370
2545
|
sharedKeys.forEach((sharedKey) => {
|
|
2371
|
-
const sharedVals =
|
|
2546
|
+
const sharedVals = newShareInfos[sharedKey];
|
|
2372
2547
|
sharedVals.forEach((sharedVal) => {
|
|
2373
2548
|
sharedVal.scope.forEach((sc) => {
|
|
2549
|
+
this.hooks.lifecycle.beforeRegisterShare.emit({
|
|
2550
|
+
origin: this.host,
|
|
2551
|
+
pkgName: sharedKey,
|
|
2552
|
+
shared: sharedVal,
|
|
2553
|
+
});
|
|
2374
2554
|
const registeredShared = this.shareScopeMap[sc]?.[sharedKey];
|
|
2375
2555
|
if (!registeredShared) {
|
|
2376
2556
|
this.setShared({
|
|
@@ -2386,8 +2566,8 @@ class SharedHandler {
|
|
|
2386
2566
|
});
|
|
2387
2567
|
});
|
|
2388
2568
|
return {
|
|
2389
|
-
|
|
2390
|
-
|
|
2569
|
+
newShareInfos,
|
|
2570
|
+
allShareInfos,
|
|
2391
2571
|
};
|
|
2392
2572
|
}
|
|
2393
2573
|
async loadShare(pkgName, extraOptions) {
|
|
@@ -2418,61 +2598,59 @@ class SharedHandler {
|
|
|
2418
2598
|
const { shareInfo: shareOptionsRes } = loadShareRes;
|
|
2419
2599
|
// Assert that shareInfoRes exists, if not, throw an error
|
|
2420
2600
|
assert(shareOptionsRes, `Cannot find ${pkgName} Share in the ${host.options.name}. Please ensure that the ${pkgName} Share parameters have been injected`);
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
if (
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
!registeredShared.loaded) {
|
|
2436
|
-
const factory = await registeredShared.loading;
|
|
2437
|
-
registeredShared.loaded = true;
|
|
2438
|
-
if (!registeredShared.lib) {
|
|
2439
|
-
registeredShared.lib = factory;
|
|
2440
|
-
}
|
|
2441
|
-
addUseIn(registeredShared);
|
|
2442
|
-
return factory;
|
|
2443
|
-
}
|
|
2444
|
-
else if (registeredShared) {
|
|
2445
|
-
const asyncLoadProcess = async () => {
|
|
2446
|
-
const factory = await registeredShared.get();
|
|
2447
|
-
addUseIn(registeredShared);
|
|
2448
|
-
registeredShared.loaded = true;
|
|
2449
|
-
registeredShared.lib = factory;
|
|
2601
|
+
const { shared: registeredShared, useTreeshake } = getRegisteredShare(this.shareScopeMap, pkgName, shareOptionsRes, this.hooks.lifecycle.resolveShare) || {};
|
|
2602
|
+
if (registeredShared) {
|
|
2603
|
+
const targetShared = directShare(registeredShared, useTreeshake);
|
|
2604
|
+
if (targetShared.lib) {
|
|
2605
|
+
addUseIn(targetShared, host.options.name);
|
|
2606
|
+
return targetShared.lib;
|
|
2607
|
+
}
|
|
2608
|
+
else if (targetShared.loading && !targetShared.loaded) {
|
|
2609
|
+
const factory = await targetShared.loading;
|
|
2610
|
+
targetShared.loaded = true;
|
|
2611
|
+
if (!targetShared.lib) {
|
|
2612
|
+
targetShared.lib = factory;
|
|
2613
|
+
}
|
|
2614
|
+
addUseIn(targetShared, host.options.name);
|
|
2450
2615
|
return factory;
|
|
2451
|
-
}
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2616
|
+
}
|
|
2617
|
+
else {
|
|
2618
|
+
const asyncLoadProcess = async () => {
|
|
2619
|
+
const factory = await targetShared.get();
|
|
2620
|
+
addUseIn(targetShared, host.options.name);
|
|
2621
|
+
targetShared.loaded = true;
|
|
2622
|
+
targetShared.lib = factory;
|
|
2623
|
+
return factory;
|
|
2624
|
+
};
|
|
2625
|
+
const loading = asyncLoadProcess();
|
|
2626
|
+
this.setShared({
|
|
2627
|
+
pkgName,
|
|
2628
|
+
loaded: false,
|
|
2629
|
+
shared: registeredShared,
|
|
2630
|
+
from: host.options.name,
|
|
2631
|
+
lib: null,
|
|
2632
|
+
loading,
|
|
2633
|
+
treeshake: useTreeshake ? targetShared : undefined,
|
|
2634
|
+
});
|
|
2635
|
+
return loading;
|
|
2636
|
+
}
|
|
2462
2637
|
}
|
|
2463
2638
|
else {
|
|
2464
2639
|
if (extraOptions?.customShareInfo) {
|
|
2465
2640
|
return false;
|
|
2466
2641
|
}
|
|
2642
|
+
const _useTreeshake = shouldUseTreeshake(shareOptionsRes.treeshake);
|
|
2643
|
+
const targetShared = directShare(shareOptionsRes, _useTreeshake);
|
|
2467
2644
|
const asyncLoadProcess = async () => {
|
|
2468
|
-
const factory = await
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
addUseIn(
|
|
2472
|
-
const gShared = getRegisteredShare(this.shareScopeMap, pkgName, shareOptionsRes, this.hooks.lifecycle.resolveShare);
|
|
2645
|
+
const factory = await targetShared.get();
|
|
2646
|
+
targetShared.lib = factory;
|
|
2647
|
+
targetShared.loaded = true;
|
|
2648
|
+
addUseIn(targetShared, host.options.name);
|
|
2649
|
+
const { shared: gShared, useTreeshake: gUseTreeshake } = getRegisteredShare(this.shareScopeMap, pkgName, shareOptionsRes, this.hooks.lifecycle.resolveShare) || {};
|
|
2473
2650
|
if (gShared) {
|
|
2474
|
-
|
|
2475
|
-
|
|
2651
|
+
const targetGShared = directShare(gShared, gUseTreeshake);
|
|
2652
|
+
targetGShared.lib = factory;
|
|
2653
|
+
targetGShared.loaded = true;
|
|
2476
2654
|
gShared.from = shareOptionsRes.from;
|
|
2477
2655
|
}
|
|
2478
2656
|
return factory;
|
|
@@ -2485,6 +2663,7 @@ class SharedHandler {
|
|
|
2485
2663
|
from: host.options.name,
|
|
2486
2664
|
lib: null,
|
|
2487
2665
|
loading,
|
|
2666
|
+
treeshake: _useTreeshake ? targetShared : undefined,
|
|
2488
2667
|
});
|
|
2489
2668
|
return loading;
|
|
2490
2669
|
}
|
|
@@ -2524,19 +2703,20 @@ class SharedHandler {
|
|
|
2524
2703
|
const { version, eager } = shared;
|
|
2525
2704
|
scope[name] = scope[name] || {};
|
|
2526
2705
|
const versions = scope[name];
|
|
2527
|
-
const activeVersion = versions[version];
|
|
2706
|
+
const activeVersion = versions[version] && directShare(versions[version]);
|
|
2528
2707
|
const activeVersionEager = Boolean(activeVersion &&
|
|
2529
|
-
(
|
|
2708
|
+
(('eager' in activeVersion && activeVersion.eager) ||
|
|
2709
|
+
('shareConfig' in activeVersion &&
|
|
2710
|
+
activeVersion.shareConfig?.eager)));
|
|
2530
2711
|
if (!activeVersion ||
|
|
2531
2712
|
(activeVersion.strategy !== 'loaded-first' &&
|
|
2532
2713
|
!activeVersion.loaded &&
|
|
2533
2714
|
(Boolean(!eager) !== !activeVersionEager
|
|
2534
2715
|
? eager
|
|
2535
|
-
: hostName >
|
|
2716
|
+
: hostName > versions[version].from))) {
|
|
2536
2717
|
versions[version] = shared;
|
|
2537
2718
|
}
|
|
2538
2719
|
};
|
|
2539
|
-
const initFn = (mod) => mod && mod.init && mod.init(shareScope[shareScopeName], initScope);
|
|
2540
2720
|
const initRemoteModule = async (key) => {
|
|
2541
2721
|
const { module } = await host.remoteHandler.getRemoteModuleAndOptions({
|
|
2542
2722
|
id: key,
|
|
@@ -2557,6 +2737,12 @@ class SharedHandler {
|
|
|
2557
2737
|
}));
|
|
2558
2738
|
}
|
|
2559
2739
|
if (!module.inited) {
|
|
2740
|
+
const initFn = (mod) => {
|
|
2741
|
+
const { remoteEntryInitOptions } = createRemoteEntryInitOptions(module.remoteInfo, host.shareScopeMap);
|
|
2742
|
+
return (mod &&
|
|
2743
|
+
mod.init &&
|
|
2744
|
+
mod.init(shareScope[shareScopeName], initScope, remoteEntryInitOptions));
|
|
2745
|
+
};
|
|
2560
2746
|
await initFn(remoteEntryExports);
|
|
2561
2747
|
module.inited = true;
|
|
2562
2748
|
}
|
|
@@ -2597,16 +2783,10 @@ class SharedHandler {
|
|
|
2597
2783
|
this.initializeSharing(shareScope, { strategy: shareOptions.strategy });
|
|
2598
2784
|
});
|
|
2599
2785
|
}
|
|
2600
|
-
const registeredShared = getRegisteredShare(this.shareScopeMap, pkgName, shareOptions, this.hooks.lifecycle.resolveShare);
|
|
2601
|
-
const addUseIn = (shared) => {
|
|
2602
|
-
if (!shared.useIn) {
|
|
2603
|
-
shared.useIn = [];
|
|
2604
|
-
}
|
|
2605
|
-
addUniqueItem(shared.useIn, host.options.name);
|
|
2606
|
-
};
|
|
2786
|
+
const { shared: registeredShared, useTreeshake } = getRegisteredShare(this.shareScopeMap, pkgName, shareOptions, this.hooks.lifecycle.resolveShare) || {};
|
|
2607
2787
|
if (registeredShared) {
|
|
2608
2788
|
if (typeof registeredShared.lib === 'function') {
|
|
2609
|
-
addUseIn(registeredShared);
|
|
2789
|
+
addUseIn(registeredShared, host.options.name);
|
|
2610
2790
|
if (!registeredShared.loaded) {
|
|
2611
2791
|
registeredShared.loaded = true;
|
|
2612
2792
|
if (registeredShared.from === host.options.name) {
|
|
@@ -2618,7 +2798,7 @@ class SharedHandler {
|
|
|
2618
2798
|
if (typeof registeredShared.get === 'function') {
|
|
2619
2799
|
const module = registeredShared.get();
|
|
2620
2800
|
if (!(module instanceof Promise)) {
|
|
2621
|
-
addUseIn(registeredShared);
|
|
2801
|
+
addUseIn(registeredShared, host.options.name);
|
|
2622
2802
|
this.setShared({
|
|
2623
2803
|
pkgName,
|
|
2624
2804
|
loaded: true,
|
|
@@ -2662,6 +2842,39 @@ class SharedHandler {
|
|
|
2662
2842
|
}
|
|
2663
2843
|
initShareScopeMap(scopeName, shareScope, extraOptions = {}) {
|
|
2664
2844
|
const { host } = this;
|
|
2845
|
+
// const existedShareScope = this.shareScopeMap[scopeName];
|
|
2846
|
+
// if (existedShareScope) {
|
|
2847
|
+
// Object.entries(shareScope).forEach(([pkgName, newVersions]) => {
|
|
2848
|
+
// const existedShareMap = existedShareScope[pkgName];
|
|
2849
|
+
// if (!existedShareMap) {
|
|
2850
|
+
// return;
|
|
2851
|
+
// }
|
|
2852
|
+
// Object.entries(existedShareMap).forEach(([version, existedShared]) => {
|
|
2853
|
+
// if (!shareScope[pkgName][version]) {
|
|
2854
|
+
// shareScope[pkgName][version] = existedShared;
|
|
2855
|
+
// }
|
|
2856
|
+
// // const newShared = newVersions[version];
|
|
2857
|
+
// // if (
|
|
2858
|
+
// // newShared &&
|
|
2859
|
+
// // newShared.treeshakeStatus === TreeshakeStatus.UNKNOWN &&
|
|
2860
|
+
// // newShared.usedExports &&
|
|
2861
|
+
// // existedShared.usedExports &&
|
|
2862
|
+
// // existedShared.usedExports.some(
|
|
2863
|
+
// // (exportName) => !newShared.usedExports?.includes(exportName),
|
|
2864
|
+
// // )
|
|
2865
|
+
// // ) {
|
|
2866
|
+
// // newShared.treeshakeStatus = TreeshakeStatus.NO_USE;
|
|
2867
|
+
// // newShared._noMatchedUsedExports =
|
|
2868
|
+
// // existedShared._noMatchedUsedExports || [];
|
|
2869
|
+
// // const item: NoMatchedUsedExportsItem = [existedShared.from];
|
|
2870
|
+
// // if (isDebugMode() && existedShared.usedExports) {
|
|
2871
|
+
// // item.push(existedShared.usedExports);
|
|
2872
|
+
// // }
|
|
2873
|
+
// // newShared._noMatchedUsedExports.push(item);
|
|
2874
|
+
// // }
|
|
2875
|
+
// });
|
|
2876
|
+
// });
|
|
2877
|
+
// }
|
|
2665
2878
|
this.shareScopeMap[scopeName] = shareScope;
|
|
2666
2879
|
this.hooks.lifecycle.initContainerShareScopeMap.emit({
|
|
2667
2880
|
shareScope,
|
|
@@ -2671,9 +2884,20 @@ class SharedHandler {
|
|
|
2671
2884
|
hostShareScopeMap: extraOptions.hostShareScopeMap,
|
|
2672
2885
|
});
|
|
2673
2886
|
}
|
|
2674
|
-
setShared({ pkgName, shared, from, lib, loading, loaded, get, }) {
|
|
2887
|
+
setShared({ pkgName, shared, from, lib, loading, loaded, get, treeshake, }) {
|
|
2675
2888
|
const { version, scope = 'default', ...shareInfo } = shared;
|
|
2676
2889
|
const scopes = Array.isArray(scope) ? scope : [scope];
|
|
2890
|
+
const mergeAttrs = (shared) => {
|
|
2891
|
+
const merge = (s, key, val) => {
|
|
2892
|
+
if (val && !s[key]) {
|
|
2893
|
+
s[key] = val;
|
|
2894
|
+
}
|
|
2895
|
+
};
|
|
2896
|
+
const targetShared = (treeshake ? shared.treeshake : shared);
|
|
2897
|
+
merge(targetShared, 'loaded', loaded);
|
|
2898
|
+
merge(targetShared, 'loading', loading);
|
|
2899
|
+
merge(targetShared, 'get', get);
|
|
2900
|
+
};
|
|
2677
2901
|
scopes.forEach((sc) => {
|
|
2678
2902
|
if (!this.shareScopeMap[sc]) {
|
|
2679
2903
|
this.shareScopeMap[sc] = {};
|
|
@@ -2687,21 +2911,10 @@ class SharedHandler {
|
|
|
2687
2911
|
scope: [sc],
|
|
2688
2912
|
...shareInfo,
|
|
2689
2913
|
lib,
|
|
2690
|
-
loaded,
|
|
2691
|
-
loading,
|
|
2692
2914
|
};
|
|
2693
|
-
if (get) {
|
|
2694
|
-
this.shareScopeMap[sc][pkgName][version].get = get;
|
|
2695
|
-
}
|
|
2696
|
-
return;
|
|
2697
2915
|
}
|
|
2698
2916
|
const registeredShared = this.shareScopeMap[sc][pkgName][version];
|
|
2699
|
-
|
|
2700
|
-
registeredShared.loading = loading;
|
|
2701
|
-
}
|
|
2702
|
-
if (loaded && !registeredShared.loaded) {
|
|
2703
|
-
registeredShared.loaded = loaded;
|
|
2704
|
-
}
|
|
2917
|
+
mergeAttrs(registeredShared);
|
|
2705
2918
|
if (from && registeredShared.from !== from) {
|
|
2706
2919
|
registeredShared.from = from;
|
|
2707
2920
|
}
|
|
@@ -2729,6 +2942,7 @@ class RemoteHandler {
|
|
|
2729
2942
|
generatePreloadAssets: new AsyncHook('generatePreloadAssets'),
|
|
2730
2943
|
// not used yet
|
|
2731
2944
|
afterPreloadRemote: new AsyncHook(),
|
|
2945
|
+
// TODO: Move to loaderHook
|
|
2732
2946
|
loadEntry: new AsyncHook(),
|
|
2733
2947
|
});
|
|
2734
2948
|
this.host = host;
|
|
@@ -3077,7 +3291,7 @@ class ModuleFederation {
|
|
|
3077
3291
|
// maybe will change, temporarily for internal use only
|
|
3078
3292
|
initContainer: new AsyncWaterfallHook('initContainer'),
|
|
3079
3293
|
});
|
|
3080
|
-
this.version = "0.0.0-feat-
|
|
3294
|
+
this.version = "0.0.0-feat-shared-treeshake-poc-20251211025043";
|
|
3081
3295
|
this.moduleCache = new Map();
|
|
3082
3296
|
this.loaderHook = new PluginSystem({
|
|
3083
3297
|
// FIXME: may not be suitable , not open to the public yet
|
|
@@ -3158,7 +3372,7 @@ class ModuleFederation {
|
|
|
3158
3372
|
this.sharedHandler.initShareScopeMap(scopeName, shareScope, extraOptions);
|
|
3159
3373
|
}
|
|
3160
3374
|
formatOptions(globalOptions, userOptions) {
|
|
3161
|
-
const { shared
|
|
3375
|
+
const { allShareInfos: shared} = formatShareConfigs(globalOptions, userOptions);
|
|
3162
3376
|
const { userOptions: userOptionsRes, options: globalOptionsRes } = this.hooks.lifecycle.beforeInit.emit({
|
|
3163
3377
|
origin: this,
|
|
3164
3378
|
userOptions,
|
|
@@ -3166,7 +3380,7 @@ class ModuleFederation {
|
|
|
3166
3380
|
shareInfo: shared,
|
|
3167
3381
|
});
|
|
3168
3382
|
const remotes = this.remoteHandler.formatAndRegisterRemote(globalOptionsRes, userOptionsRes);
|
|
3169
|
-
const {
|
|
3383
|
+
const { allShareInfos } = this.sharedHandler.registerShared(globalOptionsRes, userOptionsRes);
|
|
3170
3384
|
const plugins = [...globalOptionsRes.plugins];
|
|
3171
3385
|
if (userOptionsRes.plugins) {
|
|
3172
3386
|
userOptionsRes.plugins.forEach((plugin) => {
|
|
@@ -3180,7 +3394,7 @@ class ModuleFederation {
|
|
|
3180
3394
|
...userOptions,
|
|
3181
3395
|
plugins,
|
|
3182
3396
|
remotes,
|
|
3183
|
-
shared:
|
|
3397
|
+
shared: allShareInfos,
|
|
3184
3398
|
};
|
|
3185
3399
|
this.hooks.lifecycle.init.emit({
|
|
3186
3400
|
origin: this,
|