@atlaspack/bundler-default 2.14.5-canary.136 → 2.14.5-canary.137
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/lib/decorateLegacyGraph.js +20 -3
- package/lib/idealGraph.js +144 -8
- package/package.json +8 -8
- package/src/decorateLegacyGraph.js +21 -3
- package/src/idealGraph.js +223 -16
|
@@ -42,11 +42,13 @@ function decorateLegacyGraph(idealGraph, bundleGraph) {
|
|
|
42
42
|
bundleGroupBundleIds,
|
|
43
43
|
manualAssetToBundle
|
|
44
44
|
} = idealGraph;
|
|
45
|
+
// This line can be deleted once supportWebpackChunkName feature flag is removed.
|
|
45
46
|
let entryBundleToBundleGroup = new Map();
|
|
46
47
|
// Step Create Bundles: Create bundle groups, bundles, and shared bundles and add assets to them
|
|
47
48
|
for (let [bundleNodeId, idealBundle] of idealBundleGraph.nodes.entries()) {
|
|
48
49
|
if (!idealBundle || idealBundle === 'root') continue;
|
|
49
50
|
let entryAsset = idealBundle.mainEntryAsset;
|
|
51
|
+
// This line can be deleted once supportWebpackChunkName feature flag is removed.
|
|
50
52
|
let bundleGroup;
|
|
51
53
|
let bundle;
|
|
52
54
|
if (bundleGroupBundleIds.has(bundleNodeId)) {
|
|
@@ -57,19 +59,33 @@ function decorateLegacyGraph(idealGraph, bundleGraph) {
|
|
|
57
59
|
return dependency.value;
|
|
58
60
|
});
|
|
59
61
|
(0, _assert().default)(entryAsset != null, 'Processing a bundleGroup with no entry asset');
|
|
62
|
+
let bundleGroups = new Map();
|
|
60
63
|
for (let dependency of dependencies) {
|
|
61
64
|
bundleGroup = bundleGraph.createBundleGroup(dependency, idealBundle.target);
|
|
65
|
+
bundleGroups.set(bundleGroup.entryAssetId, bundleGroup);
|
|
66
|
+
}
|
|
67
|
+
if ((0, _featureFlags().getFeatureFlag)('supportWebpackChunkName')) {
|
|
68
|
+
(0, _assert().default)(bundleGroups.size > 0, 'No bundle groups created');
|
|
69
|
+
} else {
|
|
70
|
+
(0, _assert().default)(bundleGroup);
|
|
71
|
+
entryBundleToBundleGroup.set(bundleNodeId, bundleGroup);
|
|
62
72
|
}
|
|
63
|
-
(0, _assert().default)(bundleGroup);
|
|
64
|
-
entryBundleToBundleGroup.set(bundleNodeId, bundleGroup);
|
|
65
73
|
bundle = (0, _nullthrows().default)(bundleGraph.createBundle({
|
|
66
74
|
entryAsset: (0, _nullthrows().default)(entryAsset),
|
|
75
|
+
bundleRoots: Array.from(idealBundle.bundleRoots),
|
|
67
76
|
needsStableName: idealBundle.needsStableName,
|
|
68
77
|
bundleBehavior: idealBundle.bundleBehavior,
|
|
69
78
|
target: idealBundle.target,
|
|
70
79
|
manualSharedBundle: idealBundle.manualSharedBundle
|
|
71
80
|
}));
|
|
72
|
-
|
|
81
|
+
if ((0, _featureFlags().getFeatureFlag)('supportWebpackChunkName')) {
|
|
82
|
+
for (let bundleGroup of bundleGroups.values()) {
|
|
83
|
+
bundleGraph.addBundleToBundleGroup(bundle, bundleGroup);
|
|
84
|
+
}
|
|
85
|
+
} else {
|
|
86
|
+
(0, _assert().default)(bundleGroup);
|
|
87
|
+
bundleGraph.addBundleToBundleGroup(bundle, bundleGroup);
|
|
88
|
+
}
|
|
73
89
|
} else if (idealBundle.sourceBundles.size > 0 && !idealBundle.mainEntryAsset) {
|
|
74
90
|
let uniqueKey = idealBundle.uniqueKey != null ? idealBundle.uniqueKey : [...idealBundle.assets].map(asset => asset.id).join(',');
|
|
75
91
|
bundle = (0, _nullthrows().default)(bundleGraph.createBundle({
|
|
@@ -95,6 +111,7 @@ function decorateLegacyGraph(idealGraph, bundleGraph) {
|
|
|
95
111
|
(0, _assert().default)(entryAsset != null);
|
|
96
112
|
bundle = (0, _nullthrows().default)(bundleGraph.createBundle({
|
|
97
113
|
entryAsset,
|
|
114
|
+
bundleRoots: Array.from(idealBundle.bundleRoots),
|
|
98
115
|
needsStableName: idealBundle.needsStableName,
|
|
99
116
|
bundleBehavior: idealBundle.bundleBehavior,
|
|
100
117
|
target: idealBundle.target,
|
package/lib/idealGraph.js
CHANGED
|
@@ -65,6 +65,11 @@ const idealBundleGraphEdges = exports.idealBundleGraphEdges = Object.freeze({
|
|
|
65
65
|
// which mutates the assetGraph into the bundleGraph we would
|
|
66
66
|
// expect from default bundler
|
|
67
67
|
|
|
68
|
+
function isNonRootBundle(bundle, message) {
|
|
69
|
+
let existingBundle = (0, _nullthrows().default)(bundle, message);
|
|
70
|
+
(0, _assert().default)(existingBundle !== 'root', "Bundle cannot be 'root'");
|
|
71
|
+
return existingBundle;
|
|
72
|
+
}
|
|
68
73
|
function createIdealGraph(assetGraph, config, entries, logger) {
|
|
69
74
|
var _config$sharedBundleM;
|
|
70
75
|
// Asset to the bundle and group it's an entry of
|
|
@@ -796,6 +801,8 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
796
801
|
}
|
|
797
802
|
}
|
|
798
803
|
let manualSharedBundleIds = new Set([...manualSharedMap.values()]);
|
|
804
|
+
let modifiedSourceBundles = new Set();
|
|
805
|
+
|
|
799
806
|
// Step split manual shared bundles for those that have the "split" property set
|
|
800
807
|
let remainderMap = new (_utils().DefaultMap)(() => []);
|
|
801
808
|
for (let id of manualSharedMap.values()) {
|
|
@@ -859,6 +866,56 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
859
866
|
}
|
|
860
867
|
}
|
|
861
868
|
}
|
|
869
|
+
if ((0, _featureFlags().getFeatureFlag)('supportWebpackChunkName')) {
|
|
870
|
+
// Merge webpack chunk name bundles
|
|
871
|
+
let chunkNameBundles = new (_utils().DefaultMap)(() => new Set());
|
|
872
|
+
for (let [nodeId, node] of dependencyBundleGraph.nodes.entries()) {
|
|
873
|
+
var _bundleNode$value$mai;
|
|
874
|
+
// meta.chunkName is set by the Rust transformer, so we just need to find
|
|
875
|
+
// bundles that have a chunkName set.
|
|
876
|
+
if (!node || node.type !== 'dependency' || node.value.meta.chunkName == null) {
|
|
877
|
+
continue;
|
|
878
|
+
}
|
|
879
|
+
let connectedBundles = dependencyBundleGraph.getNodeIdsConnectedFrom(nodeId, dependencyPriorityEdges[node.value.priority]);
|
|
880
|
+
if (connectedBundles.length === 0) {
|
|
881
|
+
continue;
|
|
882
|
+
}
|
|
883
|
+
(0, _assert().default)(connectedBundles.length === 1, 'Expected webpackChunkName dependency to be connected to no more than one bundle');
|
|
884
|
+
let bundleId = connectedBundles[0];
|
|
885
|
+
let bundleNode = dependencyBundleGraph.getNode(bundleId);
|
|
886
|
+
(0, _assert().default)(bundleNode != null && bundleNode.type === 'bundle');
|
|
887
|
+
|
|
888
|
+
// If a bundle does not have a main entry asset, it's somehow just a
|
|
889
|
+
// shared bundle, and will be merged/deleted by other means.
|
|
890
|
+
if (bundleNode.value.mainEntryAsset == null) {
|
|
891
|
+
continue;
|
|
892
|
+
}
|
|
893
|
+
let bundleNodeId = null;
|
|
894
|
+
let mainEntryAssetId = (_bundleNode$value$mai = bundleNode.value.mainEntryAsset) === null || _bundleNode$value$mai === void 0 ? void 0 : _bundleNode$value$mai.id;
|
|
895
|
+
if (mainEntryAssetId != null) {
|
|
896
|
+
bundleNodeId = bundles.get(mainEntryAssetId);
|
|
897
|
+
}
|
|
898
|
+
if (bundleNodeId == null) {
|
|
899
|
+
continue;
|
|
900
|
+
}
|
|
901
|
+
chunkNameBundles.get(node.value.meta.chunkName)
|
|
902
|
+
// DependencyBundleGraph uses content keys as node ids, so we can use that
|
|
903
|
+
// to get the bundle id.
|
|
904
|
+
.add(bundleNodeId);
|
|
905
|
+
}
|
|
906
|
+
for (let [chunkName, bundleIds] of chunkNameBundles.entries()) {
|
|
907
|
+
// The `[request]` placeholder is not yet supported
|
|
908
|
+
if (bundleIds.size <= 1 || typeof chunkName === 'string' && chunkName.includes('[request]')) {
|
|
909
|
+
continue; // Nothing to merge
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
// Merge all bundles with the same chunk name into the first one.
|
|
913
|
+
let [firstBundleId, ...rest] = Array.from(bundleIds);
|
|
914
|
+
for (let bundleId of rest) {
|
|
915
|
+
mergeBundles(firstBundleId, bundleId);
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
}
|
|
862
919
|
|
|
863
920
|
// Step merge shared bundles that meet the overlap threshold
|
|
864
921
|
// This step is skipped by default as the threshold defaults to 1
|
|
@@ -877,7 +934,7 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
877
934
|
}
|
|
878
935
|
|
|
879
936
|
// Step Remove Shared Bundles: Remove shared bundles from bundle groups that hit the parallel request limit.
|
|
880
|
-
|
|
937
|
+
|
|
881
938
|
if (config.disableSharedBundles === false) {
|
|
882
939
|
for (let bundleGroupId of bundleGraph.getNodeIdsConnectedFrom(rootNodeId)) {
|
|
883
940
|
// Find shared bundles in this bundle group.
|
|
@@ -962,10 +1019,10 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
962
1019
|
}
|
|
963
1020
|
}
|
|
964
1021
|
}
|
|
965
|
-
function mergeBundles(
|
|
966
|
-
let bundleToKeep = (
|
|
967
|
-
let bundleToRemove = (
|
|
968
|
-
|
|
1022
|
+
function mergeBundles(bundleToKeepId, bundleToRemoveId) {
|
|
1023
|
+
let bundleToKeep = isNonRootBundle(bundleGraph.getNode(bundleToKeepId), `Bundle ${bundleToKeepId} not found`);
|
|
1024
|
+
let bundleToRemove = isNonRootBundle(bundleGraph.getNode(bundleToRemoveId), `Bundle ${bundleToRemoveId} not found`);
|
|
1025
|
+
modifiedSourceBundles.add(bundleToKeep);
|
|
969
1026
|
for (let asset of bundleToRemove.assets) {
|
|
970
1027
|
bundleToKeep.assets.add(asset);
|
|
971
1028
|
bundleToKeep.size += asset.stats.size;
|
|
@@ -974,8 +1031,20 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
974
1031
|
}
|
|
975
1032
|
|
|
976
1033
|
// Merge any internalized assets
|
|
977
|
-
(0,
|
|
978
|
-
|
|
1034
|
+
if ((0, _featureFlags().getFeatureFlag)('supportWebpackChunkName')) {
|
|
1035
|
+
if (bundleToKeep.internalizedAssets != null) {
|
|
1036
|
+
if (bundleToRemove.internalizedAssets != null) {
|
|
1037
|
+
bundleToKeep.internalizedAssets.intersect(bundleToRemove.internalizedAssets);
|
|
1038
|
+
} else {
|
|
1039
|
+
bundleToKeep.internalizedAssets.clear();
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
} else {
|
|
1043
|
+
(0, _assert().default)(bundleToKeep.internalizedAssets && bundleToRemove.internalizedAssets, 'All shared bundles should have internalized assets');
|
|
1044
|
+
bundleToKeep.internalizedAssets.union(bundleToRemove.internalizedAssets);
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
// Merge and clean up source bundles
|
|
979
1048
|
for (let sourceBundleId of bundleToRemove.sourceBundles) {
|
|
980
1049
|
if (bundleToKeep.sourceBundles.has(sourceBundleId)) {
|
|
981
1050
|
continue;
|
|
@@ -983,6 +1052,66 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
983
1052
|
bundleToKeep.sourceBundles.add(sourceBundleId);
|
|
984
1053
|
bundleGraph.addEdge(sourceBundleId, bundleToKeepId);
|
|
985
1054
|
}
|
|
1055
|
+
if ((0, _featureFlags().getFeatureFlag)('supportWebpackChunkName')) {
|
|
1056
|
+
bundleToKeep.sourceBundles.delete(bundleToRemoveId);
|
|
1057
|
+
for (let bundle of bundleGraph.getNodeIdsConnectedFrom(bundleToRemoveId)) {
|
|
1058
|
+
let bundleNode = (0, _nullthrows().default)(bundleGraph.getNode(bundle));
|
|
1059
|
+
if (bundleNode === 'root') {
|
|
1060
|
+
continue;
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
// If the bundle is a source bundle, add it to the bundle to keep
|
|
1064
|
+
if (bundleNode.sourceBundles.has(bundleToRemoveId)) {
|
|
1065
|
+
bundleNode.sourceBundles.add(bundleToKeepId);
|
|
1066
|
+
bundleNode.sourceBundles.delete(bundleToRemoveId);
|
|
1067
|
+
bundleGraph.addEdge(bundleToKeepId, bundle);
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
// Merge bundle roots
|
|
1072
|
+
for (let bundleRoot of bundleToRemove.bundleRoots) {
|
|
1073
|
+
bundleToKeep.bundleRoots.add(bundleRoot);
|
|
1074
|
+
}
|
|
1075
|
+
if (bundleToRemove.mainEntryAsset != null) {
|
|
1076
|
+
(0, _assert().default)(bundleToKeep.mainEntryAsset != null);
|
|
1077
|
+
|
|
1078
|
+
// Merge the bundles in bundle group
|
|
1079
|
+
let bundlesInRemoveBundleGroup = getBundlesForBundleGroup(bundleToRemoveId);
|
|
1080
|
+
for (let bundleIdInGroup of bundlesInRemoveBundleGroup) {
|
|
1081
|
+
if (bundleIdInGroup === bundleToRemoveId) {
|
|
1082
|
+
continue;
|
|
1083
|
+
}
|
|
1084
|
+
bundleGraph.addEdge(bundleToKeepId, bundleIdInGroup);
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
// Remove old bundle group
|
|
1088
|
+
bundleGroupBundleIds.delete(bundleToRemoveId);
|
|
1089
|
+
|
|
1090
|
+
// Clean up bundle roots
|
|
1091
|
+
let bundleRootToRemoveNodeId = (0, _nullthrows().default)(assetToBundleRootNodeId.get((0, _nullthrows().default)(bundleToRemove.mainEntryAsset)));
|
|
1092
|
+
let bundleRootToKeepNodeId = (0, _nullthrows().default)(assetToBundleRootNodeId.get((0, _nullthrows().default)(bundleToKeep.mainEntryAsset)));
|
|
1093
|
+
for (let nodeId of bundleRootGraph.getNodeIdsConnectedTo(bundleRootToRemoveNodeId)) {
|
|
1094
|
+
bundleRootGraph.addEdge(nodeId, bundleRootToKeepNodeId);
|
|
1095
|
+
bundleRootGraph.removeEdge(nodeId, bundleRootToRemoveNodeId);
|
|
1096
|
+
}
|
|
1097
|
+
for (let nodeId of bundleRootGraph.getNodeIdsConnectedFrom(bundleRootToRemoveNodeId)) {
|
|
1098
|
+
bundleRootGraph.addEdge(bundleRootToKeepNodeId, nodeId);
|
|
1099
|
+
bundleRootGraph.removeEdge(bundleRootToRemoveNodeId, nodeId);
|
|
1100
|
+
}
|
|
1101
|
+
bundleRoots.set((0, _nullthrows().default)(bundleToRemove.mainEntryAsset), [bundleToKeepId, bundleToKeepId]);
|
|
1102
|
+
|
|
1103
|
+
// Merge dependency bundle graph
|
|
1104
|
+
for (let dependencyNodeId of dependencyBundleGraph.getNodeIdsConnectedTo(dependencyBundleGraph.getNodeIdByContentKey(String(bundleToRemoveId)), _graph().ALL_EDGE_TYPES)) {
|
|
1105
|
+
let dependencyNode = (0, _nullthrows().default)(dependencyBundleGraph.getNode(dependencyNodeId));
|
|
1106
|
+
(0, _assert().default)(dependencyNode.type === 'dependency');
|
|
1107
|
+
|
|
1108
|
+
// Add dependency to the bundle to keep
|
|
1109
|
+
dependencyBundleGraph.addEdge(dependencyNodeId, dependencyBundleGraph.getNodeIdByContentKey(String(bundleToKeepId)), dependencyPriorityEdges[dependencyNode.value.priority]);
|
|
1110
|
+
// Remove dependency from the bundle to remove
|
|
1111
|
+
dependencyBundleGraph.removeEdge(dependencyNodeId, dependencyBundleGraph.getNodeIdByContentKey(String(bundleToRemoveId)), dependencyPriorityEdges[dependencyNode.value.priority]);
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
986
1115
|
bundleGraph.removeNode(bundleToRemoveId);
|
|
987
1116
|
}
|
|
988
1117
|
function mergeOverlapBundles(mergeConfig) {
|
|
@@ -1017,11 +1146,16 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
1017
1146
|
})
|
|
1018
1147
|
};
|
|
1019
1148
|
}));
|
|
1149
|
+
let mergedBundles = new Set();
|
|
1020
1150
|
for (let cluster of clusters) {
|
|
1021
1151
|
let [mergeTarget, ...rest] = cluster;
|
|
1022
1152
|
for (let bundleIdToMerge of rest) {
|
|
1023
|
-
mergeBundles(
|
|
1153
|
+
mergeBundles(mergeTarget, bundleIdToMerge);
|
|
1024
1154
|
}
|
|
1155
|
+
mergedBundles.add(mergeTarget);
|
|
1156
|
+
}
|
|
1157
|
+
if ((0, _featureFlags().getFeatureFlag)('supportWebpackChunkName')) {
|
|
1158
|
+
return mergedBundles;
|
|
1025
1159
|
}
|
|
1026
1160
|
}
|
|
1027
1161
|
function getBigIntFromContentKey(contentKey) {
|
|
@@ -1122,6 +1256,7 @@ function createBundle(opts) {
|
|
|
1122
1256
|
bundleBehavior: opts.bundleBehavior,
|
|
1123
1257
|
env: (0, _nullthrows().default)(opts.env),
|
|
1124
1258
|
mainEntryAsset: null,
|
|
1259
|
+
bundleRoots: new Set(),
|
|
1125
1260
|
manualSharedBundle: opts.manualSharedBundle,
|
|
1126
1261
|
needsStableName: Boolean(opts.needsStableName),
|
|
1127
1262
|
size: 0,
|
|
@@ -1137,6 +1272,7 @@ function createBundle(opts) {
|
|
|
1137
1272
|
bundleBehavior: opts.bundleBehavior ?? asset.bundleBehavior,
|
|
1138
1273
|
env: opts.env ?? asset.env,
|
|
1139
1274
|
mainEntryAsset: asset,
|
|
1275
|
+
bundleRoots: new Set([asset]),
|
|
1140
1276
|
manualSharedBundle: opts.manualSharedBundle,
|
|
1141
1277
|
needsStableName: Boolean(opts.needsStableName),
|
|
1142
1278
|
size: asset.stats.size,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaspack/bundler-default",
|
|
3
|
-
"version": "2.14.5-canary.
|
|
3
|
+
"version": "2.14.5-canary.137+069de478e",
|
|
4
4
|
"license": "(MIT OR Apache-2.0)",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"publishConfig": {
|
|
@@ -16,14 +16,14 @@
|
|
|
16
16
|
"node": ">= 16.0.0"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@atlaspack/diagnostic": "2.14.1-canary.
|
|
20
|
-
"@atlaspack/feature-flags": "2.14.1-canary.
|
|
21
|
-
"@atlaspack/graph": "3.4.1-canary.
|
|
22
|
-
"@atlaspack/plugin": "2.14.5-canary.
|
|
23
|
-
"@atlaspack/rust": "3.2.1-canary.
|
|
24
|
-
"@atlaspack/utils": "2.14.5-canary.
|
|
19
|
+
"@atlaspack/diagnostic": "2.14.1-canary.205+069de478e",
|
|
20
|
+
"@atlaspack/feature-flags": "2.14.1-canary.205+069de478e",
|
|
21
|
+
"@atlaspack/graph": "3.4.1-canary.205+069de478e",
|
|
22
|
+
"@atlaspack/plugin": "2.14.5-canary.137+069de478e",
|
|
23
|
+
"@atlaspack/rust": "3.2.1-canary.137+069de478e",
|
|
24
|
+
"@atlaspack/utils": "2.14.5-canary.137+069de478e",
|
|
25
25
|
"many-keys-map": "^1.0.3",
|
|
26
26
|
"nullthrows": "^1.1.1"
|
|
27
27
|
},
|
|
28
|
-
"gitHead": "
|
|
28
|
+
"gitHead": "069de478e64fb5889f6f2ce023eb510782767fbd"
|
|
29
29
|
}
|
|
@@ -25,11 +25,13 @@ export function decorateLegacyGraph(
|
|
|
25
25
|
bundleGroupBundleIds,
|
|
26
26
|
manualAssetToBundle,
|
|
27
27
|
} = idealGraph;
|
|
28
|
+
// This line can be deleted once supportWebpackChunkName feature flag is removed.
|
|
28
29
|
let entryBundleToBundleGroup: Map<NodeId, BundleGroup> = new Map();
|
|
29
30
|
// Step Create Bundles: Create bundle groups, bundles, and shared bundles and add assets to them
|
|
30
31
|
for (let [bundleNodeId, idealBundle] of idealBundleGraph.nodes.entries()) {
|
|
31
32
|
if (!idealBundle || idealBundle === 'root') continue;
|
|
32
33
|
let entryAsset = idealBundle.mainEntryAsset;
|
|
34
|
+
// This line can be deleted once supportWebpackChunkName feature flag is removed.
|
|
33
35
|
let bundleGroup;
|
|
34
36
|
let bundle;
|
|
35
37
|
|
|
@@ -52,18 +54,26 @@ export function decorateLegacyGraph(
|
|
|
52
54
|
entryAsset != null,
|
|
53
55
|
'Processing a bundleGroup with no entry asset',
|
|
54
56
|
);
|
|
57
|
+
|
|
58
|
+
let bundleGroups = new Map();
|
|
55
59
|
for (let dependency of dependencies) {
|
|
56
60
|
bundleGroup = bundleGraph.createBundleGroup(
|
|
57
61
|
dependency,
|
|
58
62
|
idealBundle.target,
|
|
59
63
|
);
|
|
64
|
+
bundleGroups.set(bundleGroup.entryAssetId, bundleGroup);
|
|
65
|
+
}
|
|
66
|
+
if (getFeatureFlag('supportWebpackChunkName')) {
|
|
67
|
+
invariant(bundleGroups.size > 0, 'No bundle groups created');
|
|
68
|
+
} else {
|
|
69
|
+
invariant(bundleGroup);
|
|
70
|
+
entryBundleToBundleGroup.set(bundleNodeId, bundleGroup);
|
|
60
71
|
}
|
|
61
|
-
invariant(bundleGroup);
|
|
62
|
-
entryBundleToBundleGroup.set(bundleNodeId, bundleGroup);
|
|
63
72
|
|
|
64
73
|
bundle = nullthrows(
|
|
65
74
|
bundleGraph.createBundle({
|
|
66
75
|
entryAsset: nullthrows(entryAsset),
|
|
76
|
+
bundleRoots: Array.from(idealBundle.bundleRoots),
|
|
67
77
|
needsStableName: idealBundle.needsStableName,
|
|
68
78
|
bundleBehavior: idealBundle.bundleBehavior,
|
|
69
79
|
target: idealBundle.target,
|
|
@@ -71,7 +81,14 @@ export function decorateLegacyGraph(
|
|
|
71
81
|
}),
|
|
72
82
|
);
|
|
73
83
|
|
|
74
|
-
|
|
84
|
+
if (getFeatureFlag('supportWebpackChunkName')) {
|
|
85
|
+
for (let bundleGroup of bundleGroups.values()) {
|
|
86
|
+
bundleGraph.addBundleToBundleGroup(bundle, bundleGroup);
|
|
87
|
+
}
|
|
88
|
+
} else {
|
|
89
|
+
invariant(bundleGroup);
|
|
90
|
+
bundleGraph.addBundleToBundleGroup(bundle, bundleGroup);
|
|
91
|
+
}
|
|
75
92
|
} else if (
|
|
76
93
|
idealBundle.sourceBundles.size > 0 &&
|
|
77
94
|
!idealBundle.mainEntryAsset
|
|
@@ -109,6 +126,7 @@ export function decorateLegacyGraph(
|
|
|
109
126
|
bundle = nullthrows(
|
|
110
127
|
bundleGraph.createBundle({
|
|
111
128
|
entryAsset,
|
|
129
|
+
bundleRoots: Array.from(idealBundle.bundleRoots),
|
|
112
130
|
needsStableName: idealBundle.needsStableName,
|
|
113
131
|
bundleBehavior: idealBundle.bundleBehavior,
|
|
114
132
|
target: idealBundle.target,
|
package/src/idealGraph.js
CHANGED
|
@@ -36,6 +36,7 @@ export type Bundle = {|
|
|
|
36
36
|
bundleBehavior?: ?BundleBehavior,
|
|
37
37
|
needsStableName: boolean,
|
|
38
38
|
mainEntryAsset: ?Asset,
|
|
39
|
+
bundleRoots: Set<Asset>,
|
|
39
40
|
size: number,
|
|
40
41
|
sourceBundles: Set<NodeId>,
|
|
41
42
|
target: Target,
|
|
@@ -85,6 +86,16 @@ export type IdealGraph = {|
|
|
|
85
86
|
manualAssetToBundle: Map<Asset, NodeId>,
|
|
86
87
|
|};
|
|
87
88
|
|
|
89
|
+
function isNonRootBundle(
|
|
90
|
+
bundle?: Bundle | 'root' | null,
|
|
91
|
+
message?: string,
|
|
92
|
+
): Bundle {
|
|
93
|
+
let existingBundle = nullthrows(bundle, message);
|
|
94
|
+
invariant(existingBundle !== 'root', "Bundle cannot be 'root'");
|
|
95
|
+
|
|
96
|
+
return existingBundle;
|
|
97
|
+
}
|
|
98
|
+
|
|
88
99
|
export function createIdealGraph(
|
|
89
100
|
assetGraph: MutableBundleGraph,
|
|
90
101
|
config: ResolvedBundlerConfig,
|
|
@@ -1074,6 +1085,8 @@ export function createIdealGraph(
|
|
|
1074
1085
|
}
|
|
1075
1086
|
|
|
1076
1087
|
let manualSharedBundleIds = new Set([...manualSharedMap.values()]);
|
|
1088
|
+
let modifiedSourceBundles = new Set<Bundle>();
|
|
1089
|
+
|
|
1077
1090
|
// Step split manual shared bundles for those that have the "split" property set
|
|
1078
1091
|
let remainderMap = new DefaultMap(() => []);
|
|
1079
1092
|
for (let id of manualSharedMap.values()) {
|
|
@@ -1146,6 +1159,79 @@ export function createIdealGraph(
|
|
|
1146
1159
|
}
|
|
1147
1160
|
}
|
|
1148
1161
|
|
|
1162
|
+
if (getFeatureFlag('supportWebpackChunkName')) {
|
|
1163
|
+
// Merge webpack chunk name bundles
|
|
1164
|
+
let chunkNameBundles = new DefaultMap(() => new Set());
|
|
1165
|
+
for (let [nodeId, node] of dependencyBundleGraph.nodes.entries()) {
|
|
1166
|
+
// meta.chunkName is set by the Rust transformer, so we just need to find
|
|
1167
|
+
// bundles that have a chunkName set.
|
|
1168
|
+
if (
|
|
1169
|
+
!node ||
|
|
1170
|
+
node.type !== 'dependency' ||
|
|
1171
|
+
node.value.meta.chunkName == null
|
|
1172
|
+
) {
|
|
1173
|
+
continue;
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
let connectedBundles = dependencyBundleGraph.getNodeIdsConnectedFrom(
|
|
1177
|
+
nodeId,
|
|
1178
|
+
dependencyPriorityEdges[node.value.priority],
|
|
1179
|
+
);
|
|
1180
|
+
|
|
1181
|
+
if (connectedBundles.length === 0) {
|
|
1182
|
+
continue;
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
invariant(
|
|
1186
|
+
connectedBundles.length === 1,
|
|
1187
|
+
'Expected webpackChunkName dependency to be connected to no more than one bundle',
|
|
1188
|
+
);
|
|
1189
|
+
|
|
1190
|
+
let bundleId = connectedBundles[0];
|
|
1191
|
+
let bundleNode = dependencyBundleGraph.getNode(bundleId);
|
|
1192
|
+
invariant(bundleNode != null && bundleNode.type === 'bundle');
|
|
1193
|
+
|
|
1194
|
+
// If a bundle does not have a main entry asset, it's somehow just a
|
|
1195
|
+
// shared bundle, and will be merged/deleted by other means.
|
|
1196
|
+
if (bundleNode.value.mainEntryAsset == null) {
|
|
1197
|
+
continue;
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
let bundleNodeId = null;
|
|
1201
|
+
let mainEntryAssetId = bundleNode.value.mainEntryAsset?.id;
|
|
1202
|
+
|
|
1203
|
+
if (mainEntryAssetId != null) {
|
|
1204
|
+
bundleNodeId = bundles.get(mainEntryAssetId);
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
if (bundleNodeId == null) {
|
|
1208
|
+
continue;
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
chunkNameBundles
|
|
1212
|
+
.get(node.value.meta.chunkName)
|
|
1213
|
+
// DependencyBundleGraph uses content keys as node ids, so we can use that
|
|
1214
|
+
// to get the bundle id.
|
|
1215
|
+
.add(bundleNodeId);
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
for (let [chunkName, bundleIds] of chunkNameBundles.entries()) {
|
|
1219
|
+
// The `[request]` placeholder is not yet supported
|
|
1220
|
+
if (
|
|
1221
|
+
bundleIds.size <= 1 ||
|
|
1222
|
+
(typeof chunkName === 'string' && chunkName.includes('[request]'))
|
|
1223
|
+
) {
|
|
1224
|
+
continue; // Nothing to merge
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
// Merge all bundles with the same chunk name into the first one.
|
|
1228
|
+
let [firstBundleId, ...rest] = Array.from(bundleIds);
|
|
1229
|
+
for (let bundleId of rest) {
|
|
1230
|
+
mergeBundles(firstBundleId, bundleId);
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1149
1235
|
// Step merge shared bundles that meet the overlap threshold
|
|
1150
1236
|
// This step is skipped by default as the threshold defaults to 1
|
|
1151
1237
|
if (config.sharedBundleMerge && config.sharedBundleMerge.length > 0) {
|
|
@@ -1168,7 +1254,6 @@ export function createIdealGraph(
|
|
|
1168
1254
|
}
|
|
1169
1255
|
|
|
1170
1256
|
// Step Remove Shared Bundles: Remove shared bundles from bundle groups that hit the parallel request limit.
|
|
1171
|
-
let modifiedSourceBundles = new Set();
|
|
1172
1257
|
|
|
1173
1258
|
if (config.disableSharedBundles === false) {
|
|
1174
1259
|
for (let bundleGroupId of bundleGraph.getNodeIdsConnectedFrom(rootNodeId)) {
|
|
@@ -1273,15 +1358,16 @@ export function createIdealGraph(
|
|
|
1273
1358
|
}
|
|
1274
1359
|
}
|
|
1275
1360
|
|
|
1276
|
-
function mergeBundles(
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1361
|
+
function mergeBundles(bundleToKeepId: NodeId, bundleToRemoveId: NodeId) {
|
|
1362
|
+
let bundleToKeep = isNonRootBundle(
|
|
1363
|
+
bundleGraph.getNode(bundleToKeepId),
|
|
1364
|
+
`Bundle ${bundleToKeepId} not found`,
|
|
1365
|
+
);
|
|
1366
|
+
let bundleToRemove = isNonRootBundle(
|
|
1367
|
+
bundleGraph.getNode(bundleToRemoveId),
|
|
1368
|
+
`Bundle ${bundleToRemoveId} not found`,
|
|
1369
|
+
);
|
|
1370
|
+
modifiedSourceBundles.add(bundleToKeep);
|
|
1285
1371
|
for (let asset of bundleToRemove.assets) {
|
|
1286
1372
|
bundleToKeep.assets.add(asset);
|
|
1287
1373
|
bundleToKeep.size += asset.stats.size;
|
|
@@ -1296,12 +1382,25 @@ export function createIdealGraph(
|
|
|
1296
1382
|
}
|
|
1297
1383
|
|
|
1298
1384
|
// Merge any internalized assets
|
|
1299
|
-
|
|
1300
|
-
bundleToKeep.internalizedAssets
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1385
|
+
if (getFeatureFlag('supportWebpackChunkName')) {
|
|
1386
|
+
if (bundleToKeep.internalizedAssets != null) {
|
|
1387
|
+
if (bundleToRemove.internalizedAssets != null) {
|
|
1388
|
+
bundleToKeep.internalizedAssets.intersect(
|
|
1389
|
+
bundleToRemove.internalizedAssets,
|
|
1390
|
+
);
|
|
1391
|
+
} else {
|
|
1392
|
+
bundleToKeep.internalizedAssets.clear();
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
} else {
|
|
1396
|
+
invariant(
|
|
1397
|
+
bundleToKeep.internalizedAssets && bundleToRemove.internalizedAssets,
|
|
1398
|
+
'All shared bundles should have internalized assets',
|
|
1399
|
+
);
|
|
1400
|
+
bundleToKeep.internalizedAssets.union(bundleToRemove.internalizedAssets);
|
|
1401
|
+
}
|
|
1304
1402
|
|
|
1403
|
+
// Merge and clean up source bundles
|
|
1305
1404
|
for (let sourceBundleId of bundleToRemove.sourceBundles) {
|
|
1306
1405
|
if (bundleToKeep.sourceBundles.has(sourceBundleId)) {
|
|
1307
1406
|
continue;
|
|
@@ -1311,6 +1410,104 @@ export function createIdealGraph(
|
|
|
1311
1410
|
bundleGraph.addEdge(sourceBundleId, bundleToKeepId);
|
|
1312
1411
|
}
|
|
1313
1412
|
|
|
1413
|
+
if (getFeatureFlag('supportWebpackChunkName')) {
|
|
1414
|
+
bundleToKeep.sourceBundles.delete(bundleToRemoveId);
|
|
1415
|
+
|
|
1416
|
+
for (let bundle of bundleGraph.getNodeIdsConnectedFrom(
|
|
1417
|
+
bundleToRemoveId,
|
|
1418
|
+
)) {
|
|
1419
|
+
let bundleNode = nullthrows(bundleGraph.getNode(bundle));
|
|
1420
|
+
if (bundleNode === 'root') {
|
|
1421
|
+
continue;
|
|
1422
|
+
}
|
|
1423
|
+
|
|
1424
|
+
// If the bundle is a source bundle, add it to the bundle to keep
|
|
1425
|
+
if (bundleNode.sourceBundles.has(bundleToRemoveId)) {
|
|
1426
|
+
bundleNode.sourceBundles.add(bundleToKeepId);
|
|
1427
|
+
bundleNode.sourceBundles.delete(bundleToRemoveId);
|
|
1428
|
+
bundleGraph.addEdge(bundleToKeepId, bundle);
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1432
|
+
// Merge bundle roots
|
|
1433
|
+
for (let bundleRoot of bundleToRemove.bundleRoots) {
|
|
1434
|
+
bundleToKeep.bundleRoots.add(bundleRoot);
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
if (bundleToRemove.mainEntryAsset != null) {
|
|
1438
|
+
invariant(bundleToKeep.mainEntryAsset != null);
|
|
1439
|
+
|
|
1440
|
+
// Merge the bundles in bundle group
|
|
1441
|
+
let bundlesInRemoveBundleGroup =
|
|
1442
|
+
getBundlesForBundleGroup(bundleToRemoveId);
|
|
1443
|
+
|
|
1444
|
+
for (let bundleIdInGroup of bundlesInRemoveBundleGroup) {
|
|
1445
|
+
if (bundleIdInGroup === bundleToRemoveId) {
|
|
1446
|
+
continue;
|
|
1447
|
+
}
|
|
1448
|
+
bundleGraph.addEdge(bundleToKeepId, bundleIdInGroup);
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
// Remove old bundle group
|
|
1452
|
+
bundleGroupBundleIds.delete(bundleToRemoveId);
|
|
1453
|
+
|
|
1454
|
+
// Clean up bundle roots
|
|
1455
|
+
let bundleRootToRemoveNodeId = nullthrows(
|
|
1456
|
+
assetToBundleRootNodeId.get(
|
|
1457
|
+
nullthrows(bundleToRemove.mainEntryAsset),
|
|
1458
|
+
),
|
|
1459
|
+
);
|
|
1460
|
+
let bundleRootToKeepNodeId = nullthrows(
|
|
1461
|
+
assetToBundleRootNodeId.get(nullthrows(bundleToKeep.mainEntryAsset)),
|
|
1462
|
+
);
|
|
1463
|
+
|
|
1464
|
+
for (let nodeId of bundleRootGraph.getNodeIdsConnectedTo(
|
|
1465
|
+
bundleRootToRemoveNodeId,
|
|
1466
|
+
)) {
|
|
1467
|
+
bundleRootGraph.addEdge(nodeId, bundleRootToKeepNodeId);
|
|
1468
|
+
bundleRootGraph.removeEdge(nodeId, bundleRootToRemoveNodeId);
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
for (let nodeId of bundleRootGraph.getNodeIdsConnectedFrom(
|
|
1472
|
+
bundleRootToRemoveNodeId,
|
|
1473
|
+
)) {
|
|
1474
|
+
bundleRootGraph.addEdge(bundleRootToKeepNodeId, nodeId);
|
|
1475
|
+
bundleRootGraph.removeEdge(bundleRootToRemoveNodeId, nodeId);
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1478
|
+
bundleRoots.set(nullthrows(bundleToRemove.mainEntryAsset), [
|
|
1479
|
+
bundleToKeepId,
|
|
1480
|
+
bundleToKeepId,
|
|
1481
|
+
]);
|
|
1482
|
+
|
|
1483
|
+
// Merge dependency bundle graph
|
|
1484
|
+
for (let dependencyNodeId of dependencyBundleGraph.getNodeIdsConnectedTo(
|
|
1485
|
+
dependencyBundleGraph.getNodeIdByContentKey(String(bundleToRemoveId)),
|
|
1486
|
+
ALL_EDGE_TYPES,
|
|
1487
|
+
)) {
|
|
1488
|
+
let dependencyNode = nullthrows(
|
|
1489
|
+
dependencyBundleGraph.getNode(dependencyNodeId),
|
|
1490
|
+
);
|
|
1491
|
+
invariant(dependencyNode.type === 'dependency');
|
|
1492
|
+
|
|
1493
|
+
// Add dependency to the bundle to keep
|
|
1494
|
+
dependencyBundleGraph.addEdge(
|
|
1495
|
+
dependencyNodeId,
|
|
1496
|
+
dependencyBundleGraph.getNodeIdByContentKey(String(bundleToKeepId)),
|
|
1497
|
+
dependencyPriorityEdges[dependencyNode.value.priority],
|
|
1498
|
+
);
|
|
1499
|
+
// Remove dependency from the bundle to remove
|
|
1500
|
+
dependencyBundleGraph.removeEdge(
|
|
1501
|
+
dependencyNodeId,
|
|
1502
|
+
dependencyBundleGraph.getNodeIdByContentKey(
|
|
1503
|
+
String(bundleToRemoveId),
|
|
1504
|
+
),
|
|
1505
|
+
dependencyPriorityEdges[dependencyNode.value.priority],
|
|
1506
|
+
);
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1314
1511
|
bundleGraph.removeNode(bundleToRemoveId);
|
|
1315
1512
|
}
|
|
1316
1513
|
|
|
@@ -1360,12 +1557,20 @@ export function createIdealGraph(
|
|
|
1360
1557
|
})),
|
|
1361
1558
|
);
|
|
1362
1559
|
|
|
1560
|
+
let mergedBundles = new Set();
|
|
1561
|
+
|
|
1363
1562
|
for (let cluster of clusters) {
|
|
1364
1563
|
let [mergeTarget, ...rest] = cluster;
|
|
1365
1564
|
|
|
1366
1565
|
for (let bundleIdToMerge of rest) {
|
|
1367
|
-
mergeBundles(
|
|
1566
|
+
mergeBundles(mergeTarget, bundleIdToMerge);
|
|
1368
1567
|
}
|
|
1568
|
+
|
|
1569
|
+
mergedBundles.add(mergeTarget);
|
|
1570
|
+
}
|
|
1571
|
+
|
|
1572
|
+
if (getFeatureFlag('supportWebpackChunkName')) {
|
|
1573
|
+
return mergedBundles;
|
|
1369
1574
|
}
|
|
1370
1575
|
}
|
|
1371
1576
|
|
|
@@ -1498,6 +1703,7 @@ function createBundle(opts: {|
|
|
|
1498
1703
|
bundleBehavior: opts.bundleBehavior,
|
|
1499
1704
|
env: nullthrows(opts.env),
|
|
1500
1705
|
mainEntryAsset: null,
|
|
1706
|
+
bundleRoots: new Set(),
|
|
1501
1707
|
manualSharedBundle: opts.manualSharedBundle,
|
|
1502
1708
|
needsStableName: Boolean(opts.needsStableName),
|
|
1503
1709
|
size: 0,
|
|
@@ -1514,6 +1720,7 @@ function createBundle(opts: {|
|
|
|
1514
1720
|
bundleBehavior: opts.bundleBehavior ?? asset.bundleBehavior,
|
|
1515
1721
|
env: opts.env ?? asset.env,
|
|
1516
1722
|
mainEntryAsset: asset,
|
|
1723
|
+
bundleRoots: new Set([asset]),
|
|
1517
1724
|
manualSharedBundle: opts.manualSharedBundle,
|
|
1518
1725
|
needsStableName: Boolean(opts.needsStableName),
|
|
1519
1726
|
size: asset.stats.size,
|