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