@atlaspack/bundler-default 2.14.5-canary.14 → 2.14.5-canary.140
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/CHANGELOG.md +302 -0
- package/lib/DefaultBundler.d.ts +18 -0
- package/lib/DefaultBundler.js +6 -1
- package/lib/MonolithicBundler.d.ts +2 -0
- package/lib/bundleMerge.d.ts +9 -0
- package/lib/bundleMerge.js +107 -37
- package/lib/bundlerConfig.d.ts +27 -0
- package/lib/bundlerConfig.js +49 -9
- package/lib/decorateLegacyGraph.d.ts +3 -0
- package/lib/decorateLegacyGraph.js +24 -3
- package/lib/idealGraph.d.ts +40 -0
- package/lib/idealGraph.js +217 -36
- package/lib/memoize.d.ts +2 -0
- package/lib/memoize.js +39 -0
- package/package.json +16 -11
- package/src/{DefaultBundler.js → DefaultBundler.ts} +21 -6
- package/src/{MonolithicBundler.js → MonolithicBundler.ts} +0 -1
- package/src/bundleMerge.ts +245 -0
- package/src/{bundlerConfig.js → bundlerConfig.ts} +87 -49
- package/src/{decorateLegacyGraph.js → decorateLegacyGraph.ts} +25 -6
- package/src/{idealGraph.js → idealGraph.ts} +367 -94
- package/src/memoize.ts +32 -0
- package/tsconfig.json +4 -0
- package/src/bundleMerge.js +0 -103
package/lib/idealGraph.js
CHANGED
|
@@ -50,6 +50,7 @@ function _nullthrows() {
|
|
|
50
50
|
var _bundleMerge = require("./bundleMerge");
|
|
51
51
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
52
52
|
/* BundleRoot - An asset that is the main entry of a Bundle. */
|
|
53
|
+
|
|
53
54
|
const dependencyPriorityEdges = {
|
|
54
55
|
sync: 1,
|
|
55
56
|
parallel: 2,
|
|
@@ -65,7 +66,13 @@ const idealBundleGraphEdges = exports.idealBundleGraphEdges = Object.freeze({
|
|
|
65
66
|
// which mutates the assetGraph into the bundleGraph we would
|
|
66
67
|
// expect from default bundler
|
|
67
68
|
|
|
69
|
+
function isNonRootBundle(bundle, message) {
|
|
70
|
+
let existingBundle = (0, _nullthrows().default)(bundle, message);
|
|
71
|
+
(0, _assert().default)(existingBundle !== 'root', "Bundle cannot be 'root'");
|
|
72
|
+
return existingBundle;
|
|
73
|
+
}
|
|
68
74
|
function createIdealGraph(assetGraph, config, entries, logger) {
|
|
75
|
+
var _config$sharedBundleM;
|
|
69
76
|
// Asset to the bundle and group it's an entry of
|
|
70
77
|
let bundleRoots = new Map();
|
|
71
78
|
let bundles = new Map();
|
|
@@ -108,15 +115,7 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
108
115
|
}
|
|
109
116
|
let assets = [];
|
|
110
117
|
let assetToIndex = new Map();
|
|
111
|
-
|
|
112
|
-
let manualSharedMap = new Map();
|
|
113
|
-
// May need a map to be able to look up NON- bundle root assets which need special case instructions
|
|
114
|
-
// Use this when placing assets into bundles, to avoid duplication
|
|
115
|
-
let manualAssetToBundle = new Map();
|
|
116
|
-
let {
|
|
117
|
-
manualAssetToConfig,
|
|
118
|
-
constantModuleToMSB
|
|
119
|
-
} = function makeManualAssetToConfigLookup() {
|
|
118
|
+
function makeManualAssetToConfigLookup() {
|
|
120
119
|
let manualAssetToConfig = new Map();
|
|
121
120
|
let constantModuleToMSB = new (_utils().DefaultMap)(() => []);
|
|
122
121
|
if (config.manualSharedBundles.length === 0) {
|
|
@@ -128,6 +127,7 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
128
127
|
let parentsToConfig = new (_utils().DefaultMap)(() => []);
|
|
129
128
|
for (let c of config.manualSharedBundles) {
|
|
130
129
|
if (c.root != null) {
|
|
130
|
+
// @ts-expect-error TS2345
|
|
131
131
|
parentsToConfig.get(_path().default.join(config.projectRoot, c.root)).push(c);
|
|
132
132
|
}
|
|
133
133
|
}
|
|
@@ -160,17 +160,16 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
160
160
|
assetGraph.traverse((node, _, actions) => {
|
|
161
161
|
if (node.type === 'asset' && (!Array.isArray(c.types) || c.types.includes(node.value.type))) {
|
|
162
162
|
let projectRelativePath = _path().default.relative(config.projectRoot, node.value.filePath);
|
|
163
|
-
if (!assetRegexes.some(regex => regex.test(projectRelativePath))) {
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
163
|
|
|
167
164
|
// We track all matching MSB's for constant modules as they are never duplicated
|
|
168
165
|
// and need to be assigned to all matching bundles
|
|
169
166
|
if (node.value.meta.isConstantModule === true) {
|
|
167
|
+
// @ts-expect-error TS2345
|
|
170
168
|
constantModuleToMSB.get(node.value).push(c);
|
|
171
169
|
}
|
|
172
|
-
|
|
173
|
-
|
|
170
|
+
if (assetRegexes.some(regex => regex.test(projectRelativePath))) {
|
|
171
|
+
manualAssetToConfig.set(node.value, c);
|
|
172
|
+
}
|
|
174
173
|
}
|
|
175
174
|
if (node.type === 'dependency' && (node.value.priority === 'lazy' || (0, _featureFlags().getFeatureFlag)('conditionalBundlingApi') && node.value.priority === 'conditional') && parentAsset) {
|
|
176
175
|
// Don't walk past the bundle group assets
|
|
@@ -182,8 +181,23 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
182
181
|
manualAssetToConfig,
|
|
183
182
|
constantModuleToMSB
|
|
184
183
|
};
|
|
185
|
-
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
//Manual is a map of the user-given name to the bundle node Id that corresponds to ALL the assets that match any glob in that user-specified array
|
|
187
|
+
let manualSharedMap = new Map();
|
|
188
|
+
// May need a map to be able to look up NON- bundle root assets which need special case instructions
|
|
189
|
+
// Use this when placing assets into bundles, to avoid duplication
|
|
190
|
+
let manualAssetToBundle = new Map();
|
|
191
|
+
let {
|
|
192
|
+
manualAssetToConfig,
|
|
193
|
+
constantModuleToMSB
|
|
194
|
+
} = makeManualAssetToConfigLookup();
|
|
186
195
|
let manualBundleToInternalizedAsset = new (_utils().DefaultMap)(() => []);
|
|
196
|
+
let mergeSourceBundleLookup = new Map();
|
|
197
|
+
let mergeSourceBundleAssets = new Set((_config$sharedBundleM = config.sharedBundleMerge) === null || _config$sharedBundleM === void 0 ? void 0 : _config$sharedBundleM.flatMap(c => {
|
|
198
|
+
var _c$sourceBundles;
|
|
199
|
+
return ((_c$sourceBundles = c.sourceBundles) === null || _c$sourceBundles === void 0 ? void 0 : _c$sourceBundles.map(assetMatch => _path().default.join(config.projectRoot, assetMatch))) ?? [];
|
|
200
|
+
}));
|
|
187
201
|
|
|
188
202
|
/**
|
|
189
203
|
* Step Create Bundles: Traverse the assetGraph (aka MutableBundleGraph) and create bundles
|
|
@@ -191,7 +205,9 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
191
205
|
* adding only that asset to each bundle, not its entire subgraph.
|
|
192
206
|
*/
|
|
193
207
|
assetGraph.traverse({
|
|
194
|
-
enter(node, context,
|
|
208
|
+
enter(node, context,
|
|
209
|
+
// @ts-expect-error TS2304
|
|
210
|
+
actions) {
|
|
195
211
|
if (node.type === 'asset') {
|
|
196
212
|
if ((context === null || context === void 0 ? void 0 : context.type) === 'dependency' && context !== null && context !== void 0 && context.value.isEntry && !entries.has(node.value)) {
|
|
197
213
|
// Skip whole subtrees of other targets by skipping those entries
|
|
@@ -250,6 +266,11 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
250
266
|
bundleRoots.set(childAsset, [bundleId, bundleId]);
|
|
251
267
|
bundleGroupBundleIds.add(bundleId);
|
|
252
268
|
bundleGraph.addEdge(bundleGraphRootNodeId, bundleId);
|
|
269
|
+
// If this asset is relevant for merging then track it's source
|
|
270
|
+
// bundle id for later
|
|
271
|
+
if (mergeSourceBundleAssets.has(childAsset.filePath)) {
|
|
272
|
+
mergeSourceBundleLookup.set(_path().default.relative(config.projectRoot, childAsset.filePath), bundleId);
|
|
273
|
+
}
|
|
253
274
|
if (manualSharedObject) {
|
|
254
275
|
// MSB Step 4: If this was the first instance of a match, mark mainAsset for internalization
|
|
255
276
|
// since MSBs should not have main entry assets
|
|
@@ -271,7 +292,9 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
271
292
|
}), dependencyBundleGraph.addNodeByContentKeyIfNeeded(String(bundleId), {
|
|
272
293
|
value: bundle,
|
|
273
294
|
type: 'bundle'
|
|
274
|
-
}),
|
|
295
|
+
}),
|
|
296
|
+
// @ts-expect-error TS7053
|
|
297
|
+
dependencyPriorityEdges[dependency.priority]);
|
|
275
298
|
if ((0, _featureFlags().getFeatureFlag)('conditionalBundlingApi') && dependency.priority === 'conditional') {
|
|
276
299
|
let [referencingBundleRoot, bundleGroupNodeId] = (0, _nullthrows().default)(stack[stack.length - 1]);
|
|
277
300
|
let referencingBundleId = (0, _nullthrows().default)(bundleRoots.get(referencingBundleRoot))[0];
|
|
@@ -331,13 +354,16 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
331
354
|
}
|
|
332
355
|
assetReference.get(childAsset).push([dependency, bundle]);
|
|
333
356
|
} else {
|
|
357
|
+
// @ts-expect-error TS2322
|
|
334
358
|
bundleId = null;
|
|
335
359
|
}
|
|
336
360
|
if (manualSharedObject && bundleId != null) {
|
|
337
361
|
// MSB Step 5: At this point we've either created or found an existing MSB bundle
|
|
338
362
|
// add the asset if it doesn't already have it and set key
|
|
339
363
|
|
|
340
|
-
(0, _assert().default)(
|
|
364
|
+
(0, _assert().default)(
|
|
365
|
+
// @ts-expect-error TS2367
|
|
366
|
+
bundle !== 'root' && bundle != null && bundleId != null);
|
|
341
367
|
manualAssetToBundle.set(childAsset, bundleId);
|
|
342
368
|
if (!bundle.assets.has(childAsset)) {
|
|
343
369
|
// Add asset to bundle
|
|
@@ -358,6 +384,7 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
358
384
|
}
|
|
359
385
|
return node;
|
|
360
386
|
},
|
|
387
|
+
// @ts-expect-error TS2322
|
|
361
388
|
exit(node) {
|
|
362
389
|
var _stack;
|
|
363
390
|
if (((_stack = stack[stack.length - 1]) === null || _stack === void 0 ? void 0 : _stack[0]) === node.value) {
|
|
@@ -586,8 +613,11 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
586
613
|
}
|
|
587
614
|
function assignInlineConstants(parentAsset, bundle) {
|
|
588
615
|
for (let inlineConstant of inlineConstantDeps.get(parentAsset)) {
|
|
616
|
+
// @ts-expect-error TS2345
|
|
589
617
|
if (!bundle.assets.has(inlineConstant)) {
|
|
618
|
+
// @ts-expect-error TS2345
|
|
590
619
|
bundle.assets.add(inlineConstant);
|
|
620
|
+
// @ts-expect-error TS18046
|
|
591
621
|
bundle.size += inlineConstant.stats.size;
|
|
592
622
|
}
|
|
593
623
|
}
|
|
@@ -785,6 +815,8 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
785
815
|
}
|
|
786
816
|
}
|
|
787
817
|
let manualSharedBundleIds = new Set([...manualSharedMap.values()]);
|
|
818
|
+
let modifiedSourceBundles = new Set();
|
|
819
|
+
|
|
788
820
|
// Step split manual shared bundles for those that have the "split" property set
|
|
789
821
|
let remainderMap = new (_utils().DefaultMap)(() => []);
|
|
790
822
|
for (let id of manualSharedMap.values()) {
|
|
@@ -801,8 +833,9 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
801
833
|
if (modNum != null) {
|
|
802
834
|
for (let a of [...manualBundle.assets]) {
|
|
803
835
|
let numRep = getBigIntFromContentKey(a.id);
|
|
804
|
-
// $FlowFixMe Flow doesn't know about BigInt
|
|
805
836
|
let r = Number(numRep % BigInt(modNum));
|
|
837
|
+
|
|
838
|
+
// @ts-expect-error TS2345
|
|
806
839
|
remainderMap.get(r).push(a);
|
|
807
840
|
}
|
|
808
841
|
for (let i = 1; i < [...remainderMap.keys()].length; i++) {
|
|
@@ -824,8 +857,10 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
824
857
|
}
|
|
825
858
|
for (let sp of remainderMap.get(i)) {
|
|
826
859
|
bundle.assets.add(sp);
|
|
860
|
+
// @ts-expect-error TS2339
|
|
827
861
|
bundle.size += sp.stats.size;
|
|
828
862
|
manualBundle.assets.delete(sp);
|
|
863
|
+
// @ts-expect-error TS2339
|
|
829
864
|
manualBundle.size -= sp.stats.size;
|
|
830
865
|
}
|
|
831
866
|
}
|
|
@@ -838,21 +873,77 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
838
873
|
// match multiple MSB's
|
|
839
874
|
for (let [asset, msbs] of constantModuleToMSB.entries()) {
|
|
840
875
|
for (let manualSharedObject of msbs) {
|
|
876
|
+
// @ts-expect-error TS2339
|
|
841
877
|
let bundleId = manualSharedMap.get(manualSharedObject.name + ',js');
|
|
842
878
|
if (bundleId == null) continue;
|
|
843
879
|
let bundle = (0, _nullthrows().default)(bundleGraph.getNode(bundleId));
|
|
844
880
|
(0, _assert().default)(bundle != null && bundle !== 'root', 'We tried to use the root incorrectly');
|
|
881
|
+
|
|
882
|
+
// @ts-expect-error TS2345
|
|
845
883
|
if (!bundle.assets.has(asset)) {
|
|
884
|
+
// @ts-expect-error TS2345
|
|
846
885
|
bundle.assets.add(asset);
|
|
886
|
+
// @ts-expect-error TS18046
|
|
847
887
|
bundle.size += asset.stats.size;
|
|
848
888
|
}
|
|
849
889
|
}
|
|
850
890
|
}
|
|
891
|
+
if ((0, _featureFlags().getFeatureFlag)('supportWebpackChunkName')) {
|
|
892
|
+
// Merge webpack chunk name bundles
|
|
893
|
+
let chunkNameBundles = new (_utils().DefaultMap)(() => new Set());
|
|
894
|
+
for (let [nodeId, node] of dependencyBundleGraph.nodes.entries()) {
|
|
895
|
+
var _bundleNode$value$mai;
|
|
896
|
+
// meta.chunkName is set by the Rust transformer, so we just need to find
|
|
897
|
+
// bundles that have a chunkName set.
|
|
898
|
+
if (!node || node.type !== 'dependency' || node.value.meta.chunkName == null) {
|
|
899
|
+
continue;
|
|
900
|
+
}
|
|
901
|
+
let connectedBundles = dependencyBundleGraph.getNodeIdsConnectedFrom(nodeId, dependencyPriorityEdges[node.value.priority]);
|
|
902
|
+
if (connectedBundles.length === 0) {
|
|
903
|
+
continue;
|
|
904
|
+
}
|
|
905
|
+
(0, _assert().default)(connectedBundles.length === 1, 'Expected webpackChunkName dependency to be connected to no more than one bundle');
|
|
906
|
+
let bundleId = connectedBundles[0];
|
|
907
|
+
let bundleNode = dependencyBundleGraph.getNode(bundleId);
|
|
908
|
+
(0, _assert().default)(bundleNode != null && bundleNode.type === 'bundle');
|
|
909
|
+
|
|
910
|
+
// If a bundle does not have a main entry asset, it's somehow just a
|
|
911
|
+
// shared bundle, and will be merged/deleted by other means.
|
|
912
|
+
if (bundleNode.value.mainEntryAsset == null) {
|
|
913
|
+
continue;
|
|
914
|
+
}
|
|
915
|
+
let bundleNodeId = null;
|
|
916
|
+
let mainEntryAssetId = (_bundleNode$value$mai = bundleNode.value.mainEntryAsset) === null || _bundleNode$value$mai === void 0 ? void 0 : _bundleNode$value$mai.id;
|
|
917
|
+
if (mainEntryAssetId != null) {
|
|
918
|
+
bundleNodeId = bundles.get(mainEntryAssetId);
|
|
919
|
+
}
|
|
920
|
+
if (bundleNodeId == null) {
|
|
921
|
+
continue;
|
|
922
|
+
}
|
|
923
|
+
chunkNameBundles.get(node.value.meta.chunkName)
|
|
924
|
+
// DependencyBundleGraph uses content keys as node ids, so we can use that
|
|
925
|
+
// to get the bundle id.
|
|
926
|
+
.add(bundleNodeId);
|
|
927
|
+
}
|
|
928
|
+
for (let [chunkName, bundleIds] of chunkNameBundles.entries()) {
|
|
929
|
+
// The `[request]` placeholder is not yet supported
|
|
930
|
+
if (bundleIds.size <= 1 || typeof chunkName === 'string' && chunkName.includes('[request]')) {
|
|
931
|
+
continue; // Nothing to merge
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
// Merge all bundles with the same chunk name into the first one.
|
|
935
|
+
let [firstBundleId, ...rest] = Array.from(bundleIds);
|
|
936
|
+
for (let bundleId of rest) {
|
|
937
|
+
// @ts-expect-error TS2345
|
|
938
|
+
mergeBundles(firstBundleId, bundleId);
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
}
|
|
851
942
|
|
|
852
943
|
// Step merge shared bundles that meet the overlap threshold
|
|
853
944
|
// This step is skipped by default as the threshold defaults to 1
|
|
854
|
-
if (config.
|
|
855
|
-
mergeOverlapBundles();
|
|
945
|
+
if (config.sharedBundleMerge && config.sharedBundleMerge.length > 0) {
|
|
946
|
+
mergeOverlapBundles(config.sharedBundleMerge);
|
|
856
947
|
}
|
|
857
948
|
|
|
858
949
|
// Step Merge Share Bundles: Merge any shared bundles under the minimum bundle size back into
|
|
@@ -866,7 +957,7 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
866
957
|
}
|
|
867
958
|
|
|
868
959
|
// Step Remove Shared Bundles: Remove shared bundles from bundle groups that hit the parallel request limit.
|
|
869
|
-
|
|
960
|
+
|
|
870
961
|
if (config.disableSharedBundles === false) {
|
|
871
962
|
for (let bundleGroupId of bundleGraph.getNodeIdsConnectedFrom(rootNodeId)) {
|
|
872
963
|
// Find shared bundles in this bundle group.
|
|
@@ -879,6 +970,7 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
879
970
|
let numBundlesContributingToPRL = bundleIdsInGroup.reduce((count, b) => {
|
|
880
971
|
let bundle = (0, _nullthrows().default)(bundleGraph.getNode(b));
|
|
881
972
|
(0, _assert().default)(bundle !== 'root');
|
|
973
|
+
// @ts-expect-error TS2365
|
|
882
974
|
return count + (bundle.bundleBehavior !== 'inline');
|
|
883
975
|
}, 0);
|
|
884
976
|
if (numBundlesContributingToPRL > config.maxParallelRequests) {
|
|
@@ -908,7 +1000,9 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
908
1000
|
// Remove bundles until the bundle group is within the parallel request limit.
|
|
909
1001
|
while (sharedBundlesInGroup.length > 0 && numBundlesContributingToPRL > config.maxParallelRequests) {
|
|
910
1002
|
let bundleTuple = sharedBundlesInGroup.pop();
|
|
1003
|
+
// @ts-expect-error TS18048
|
|
911
1004
|
let bundleToRemove = bundleTuple.bundle;
|
|
1005
|
+
// @ts-expect-error TS18048
|
|
912
1006
|
let bundleIdToRemove = bundleTuple.id;
|
|
913
1007
|
//TODO add integration test where bundles in bunlde group > max parallel request limit & only remove a couple shared bundles
|
|
914
1008
|
// but total # bundles still exceeds limit due to non shared bundles
|
|
@@ -951,16 +1045,34 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
951
1045
|
}
|
|
952
1046
|
}
|
|
953
1047
|
}
|
|
954
|
-
function mergeBundles(
|
|
955
|
-
let bundleToKeep = (
|
|
956
|
-
let bundleToRemove = (
|
|
957
|
-
|
|
1048
|
+
function mergeBundles(bundleToKeepId, bundleToRemoveId) {
|
|
1049
|
+
let bundleToKeep = isNonRootBundle(bundleGraph.getNode(bundleToKeepId), `Bundle ${bundleToKeepId} not found`);
|
|
1050
|
+
let bundleToRemove = isNonRootBundle(bundleGraph.getNode(bundleToRemoveId), `Bundle ${bundleToRemoveId} not found`);
|
|
1051
|
+
modifiedSourceBundles.add(bundleToKeep);
|
|
958
1052
|
for (let asset of bundleToRemove.assets) {
|
|
959
1053
|
bundleToKeep.assets.add(asset);
|
|
960
1054
|
bundleToKeep.size += asset.stats.size;
|
|
961
1055
|
let newAssetReference = assetReference.get(asset).map(([dep, bundle]) => bundle === bundleToRemove ? [dep, bundleToKeep] : [dep, bundle]);
|
|
1056
|
+
|
|
1057
|
+
// @ts-expect-error TS2345
|
|
962
1058
|
assetReference.set(asset, newAssetReference);
|
|
963
1059
|
}
|
|
1060
|
+
|
|
1061
|
+
// Merge any internalized assets
|
|
1062
|
+
if ((0, _featureFlags().getFeatureFlag)('supportWebpackChunkName')) {
|
|
1063
|
+
if (bundleToKeep.internalizedAssets != null) {
|
|
1064
|
+
if (bundleToRemove.internalizedAssets != null) {
|
|
1065
|
+
bundleToKeep.internalizedAssets.intersect(bundleToRemove.internalizedAssets);
|
|
1066
|
+
} else {
|
|
1067
|
+
bundleToKeep.internalizedAssets.clear();
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
} else {
|
|
1071
|
+
(0, _assert().default)(bundleToKeep.internalizedAssets && bundleToRemove.internalizedAssets, 'All shared bundles should have internalized assets');
|
|
1072
|
+
bundleToKeep.internalizedAssets.union(bundleToRemove.internalizedAssets);
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
// Merge and clean up source bundles
|
|
964
1076
|
for (let sourceBundleId of bundleToRemove.sourceBundles) {
|
|
965
1077
|
if (bundleToKeep.sourceBundles.has(sourceBundleId)) {
|
|
966
1078
|
continue;
|
|
@@ -968,18 +1080,69 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
968
1080
|
bundleToKeep.sourceBundles.add(sourceBundleId);
|
|
969
1081
|
bundleGraph.addEdge(sourceBundleId, bundleToKeepId);
|
|
970
1082
|
}
|
|
1083
|
+
if ((0, _featureFlags().getFeatureFlag)('supportWebpackChunkName')) {
|
|
1084
|
+
bundleToKeep.sourceBundles.delete(bundleToRemoveId);
|
|
1085
|
+
for (let bundle of bundleGraph.getNodeIdsConnectedFrom(bundleToRemoveId)) {
|
|
1086
|
+
let bundleNode = (0, _nullthrows().default)(bundleGraph.getNode(bundle));
|
|
1087
|
+
if (bundleNode === 'root') {
|
|
1088
|
+
continue;
|
|
1089
|
+
}
|
|
971
1090
|
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
1091
|
+
// If the bundle is a source bundle, add it to the bundle to keep
|
|
1092
|
+
if (bundleNode.sourceBundles.has(bundleToRemoveId)) {
|
|
1093
|
+
bundleNode.sourceBundles.add(bundleToKeepId);
|
|
1094
|
+
bundleNode.sourceBundles.delete(bundleToRemoveId);
|
|
1095
|
+
bundleGraph.addEdge(bundleToKeepId, bundle);
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
// Merge bundle roots
|
|
1100
|
+
for (let bundleRoot of bundleToRemove.bundleRoots) {
|
|
1101
|
+
bundleToKeep.bundleRoots.add(bundleRoot);
|
|
1102
|
+
}
|
|
1103
|
+
if (bundleToRemove.mainEntryAsset != null) {
|
|
1104
|
+
(0, _assert().default)(bundleToKeep.mainEntryAsset != null);
|
|
1105
|
+
|
|
1106
|
+
// Merge the bundles in bundle group
|
|
1107
|
+
let bundlesInRemoveBundleGroup = getBundlesForBundleGroup(bundleToRemoveId);
|
|
1108
|
+
for (let bundleIdInGroup of bundlesInRemoveBundleGroup) {
|
|
1109
|
+
if (bundleIdInGroup === bundleToRemoveId) {
|
|
1110
|
+
continue;
|
|
1111
|
+
}
|
|
1112
|
+
bundleGraph.addEdge(bundleToKeepId, bundleIdInGroup);
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
// Remove old bundle group
|
|
1116
|
+
bundleGroupBundleIds.delete(bundleToRemoveId);
|
|
1117
|
+
|
|
1118
|
+
// Clean up bundle roots
|
|
1119
|
+
let bundleRootToRemoveNodeId = (0, _nullthrows().default)(assetToBundleRootNodeId.get((0, _nullthrows().default)(bundleToRemove.mainEntryAsset)));
|
|
1120
|
+
let bundleRootToKeepNodeId = (0, _nullthrows().default)(assetToBundleRootNodeId.get((0, _nullthrows().default)(bundleToKeep.mainEntryAsset)));
|
|
1121
|
+
for (let nodeId of bundleRootGraph.getNodeIdsConnectedTo(bundleRootToRemoveNodeId)) {
|
|
1122
|
+
bundleRootGraph.addEdge(nodeId, bundleRootToKeepNodeId);
|
|
1123
|
+
bundleRootGraph.removeEdge(nodeId, bundleRootToRemoveNodeId);
|
|
1124
|
+
}
|
|
1125
|
+
for (let nodeId of bundleRootGraph.getNodeIdsConnectedFrom(bundleRootToRemoveNodeId)) {
|
|
1126
|
+
bundleRootGraph.addEdge(bundleRootToKeepNodeId, nodeId);
|
|
1127
|
+
bundleRootGraph.removeEdge(bundleRootToRemoveNodeId, nodeId);
|
|
1128
|
+
}
|
|
1129
|
+
bundleRoots.set((0, _nullthrows().default)(bundleToRemove.mainEntryAsset), [bundleToKeepId, bundleToKeepId]);
|
|
1130
|
+
|
|
1131
|
+
// Merge dependency bundle graph
|
|
1132
|
+
for (let dependencyNodeId of dependencyBundleGraph.getNodeIdsConnectedTo(dependencyBundleGraph.getNodeIdByContentKey(String(bundleToRemoveId)), _graph().ALL_EDGE_TYPES)) {
|
|
1133
|
+
let dependencyNode = (0, _nullthrows().default)(dependencyBundleGraph.getNode(dependencyNodeId));
|
|
1134
|
+
(0, _assert().default)(dependencyNode.type === 'dependency');
|
|
1135
|
+
|
|
1136
|
+
// Add dependency to the bundle to keep
|
|
1137
|
+
dependencyBundleGraph.addEdge(dependencyNodeId, dependencyBundleGraph.getNodeIdByContentKey(String(bundleToKeepId)), dependencyPriorityEdges[dependencyNode.value.priority]);
|
|
1138
|
+
// Remove dependency from the bundle to remove
|
|
1139
|
+
dependencyBundleGraph.removeEdge(dependencyNodeId, dependencyBundleGraph.getNodeIdByContentKey(String(bundleToRemoveId)), dependencyPriorityEdges[dependencyNode.value.priority]);
|
|
1140
|
+
}
|
|
978
1141
|
}
|
|
979
1142
|
}
|
|
980
1143
|
bundleGraph.removeNode(bundleToRemoveId);
|
|
981
1144
|
}
|
|
982
|
-
function mergeOverlapBundles() {
|
|
1145
|
+
function mergeOverlapBundles(mergeConfig) {
|
|
983
1146
|
// Find all shared bundles
|
|
984
1147
|
let sharedBundles = new Set();
|
|
985
1148
|
bundleGraph.traverse(nodeId => {
|
|
@@ -998,18 +1161,34 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
998
1161
|
sharedBundles.add(nodeId);
|
|
999
1162
|
}
|
|
1000
1163
|
});
|
|
1001
|
-
let clusters = (0, _bundleMerge.findMergeCandidates)(bundleGraph, Array.from(sharedBundles), config
|
|
1164
|
+
let clusters = (0, _bundleMerge.findMergeCandidates)(bundleGraph, Array.from(sharedBundles), mergeConfig.map(config => {
|
|
1165
|
+
var _config$sourceBundles;
|
|
1166
|
+
return {
|
|
1167
|
+
...config,
|
|
1168
|
+
sourceBundles: (_config$sourceBundles = config.sourceBundles) === null || _config$sourceBundles === void 0 ? void 0 : _config$sourceBundles.map(assetMatch => {
|
|
1169
|
+
let sourceBundleNodeId = mergeSourceBundleLookup.get(assetMatch);
|
|
1170
|
+
if (sourceBundleNodeId == null) {
|
|
1171
|
+
throw new Error(`Source bundle ${assetMatch} not found in merge source bundle lookup`);
|
|
1172
|
+
}
|
|
1173
|
+
return sourceBundleNodeId;
|
|
1174
|
+
})
|
|
1175
|
+
};
|
|
1176
|
+
}));
|
|
1177
|
+
let mergedBundles = new Set();
|
|
1002
1178
|
for (let cluster of clusters) {
|
|
1003
1179
|
let [mergeTarget, ...rest] = cluster;
|
|
1004
1180
|
for (let bundleIdToMerge of rest) {
|
|
1005
|
-
mergeBundles(
|
|
1181
|
+
mergeBundles(mergeTarget, bundleIdToMerge);
|
|
1006
1182
|
}
|
|
1183
|
+
mergedBundles.add(mergeTarget);
|
|
1184
|
+
}
|
|
1185
|
+
if ((0, _featureFlags().getFeatureFlag)('supportWebpackChunkName')) {
|
|
1186
|
+
return mergedBundles;
|
|
1007
1187
|
}
|
|
1008
1188
|
}
|
|
1009
1189
|
function getBigIntFromContentKey(contentKey) {
|
|
1010
1190
|
let b = Buffer.alloc(64);
|
|
1011
1191
|
b.write(contentKey);
|
|
1012
|
-
// $FlowFixMe Flow doesn't have BigInt types in this version
|
|
1013
1192
|
return b.readBigInt64BE();
|
|
1014
1193
|
}
|
|
1015
1194
|
// Fix asset order in source bundles as they are likely now incorrect after shared bundle deletion
|
|
@@ -1104,6 +1283,7 @@ function createBundle(opts) {
|
|
|
1104
1283
|
bundleBehavior: opts.bundleBehavior,
|
|
1105
1284
|
env: (0, _nullthrows().default)(opts.env),
|
|
1106
1285
|
mainEntryAsset: null,
|
|
1286
|
+
bundleRoots: new Set(),
|
|
1107
1287
|
manualSharedBundle: opts.manualSharedBundle,
|
|
1108
1288
|
needsStableName: Boolean(opts.needsStableName),
|
|
1109
1289
|
size: 0,
|
|
@@ -1119,6 +1299,7 @@ function createBundle(opts) {
|
|
|
1119
1299
|
bundleBehavior: opts.bundleBehavior ?? asset.bundleBehavior,
|
|
1120
1300
|
env: opts.env ?? asset.env,
|
|
1121
1301
|
mainEntryAsset: asset,
|
|
1302
|
+
bundleRoots: new Set([asset]),
|
|
1122
1303
|
manualSharedBundle: opts.manualSharedBundle,
|
|
1123
1304
|
needsStableName: Boolean(opts.needsStableName),
|
|
1124
1305
|
size: asset.stats.size,
|
package/lib/memoize.d.ts
ADDED
package/lib/memoize.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.clearCaches = clearCaches;
|
|
7
|
+
exports.memoize = memoize;
|
|
8
|
+
function _manyKeysMap() {
|
|
9
|
+
const data = _interopRequireDefault(require("many-keys-map"));
|
|
10
|
+
_manyKeysMap = function () {
|
|
11
|
+
return data;
|
|
12
|
+
};
|
|
13
|
+
return data;
|
|
14
|
+
}
|
|
15
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
16
|
+
let caches = [];
|
|
17
|
+
function clearCaches() {
|
|
18
|
+
for (let cache of caches) {
|
|
19
|
+
cache.clear();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function memoize(fn) {
|
|
23
|
+
let cache = new (_manyKeysMap().default)();
|
|
24
|
+
caches.push(cache);
|
|
25
|
+
return function (...args) {
|
|
26
|
+
// Navigate through the cache hierarchy
|
|
27
|
+
let cached = cache.get(args);
|
|
28
|
+
if (cached !== undefined) {
|
|
29
|
+
// If the result is cached, return it
|
|
30
|
+
return cached;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Calculate the result and cache it
|
|
34
|
+
// @ts-expect-error TS2683
|
|
35
|
+
const result = fn.apply(this, args);
|
|
36
|
+
cache.set(args, result);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
}
|
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.140+43fdd2238",
|
|
4
4
|
"license": "(MIT OR Apache-2.0)",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"publishConfig": {
|
|
@@ -10,19 +10,24 @@
|
|
|
10
10
|
"type": "git",
|
|
11
11
|
"url": "https://github.com/atlassian-labs/atlaspack.git"
|
|
12
12
|
},
|
|
13
|
-
"main": "lib/DefaultBundler.js",
|
|
14
|
-
"source": "src/DefaultBundler.
|
|
13
|
+
"main": "./lib/DefaultBundler.js",
|
|
14
|
+
"source": "./src/DefaultBundler.ts",
|
|
15
|
+
"types": "./lib/DefaultBundler.d.ts",
|
|
15
16
|
"engines": {
|
|
16
17
|
"node": ">= 16.0.0"
|
|
17
18
|
},
|
|
18
19
|
"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.
|
|
20
|
+
"@atlaspack/diagnostic": "2.14.1-canary.208+43fdd2238",
|
|
21
|
+
"@atlaspack/feature-flags": "2.14.1-canary.208+43fdd2238",
|
|
22
|
+
"@atlaspack/graph": "3.4.1-canary.208+43fdd2238",
|
|
23
|
+
"@atlaspack/plugin": "2.14.5-canary.140+43fdd2238",
|
|
24
|
+
"@atlaspack/rust": "3.2.1-canary.140+43fdd2238",
|
|
25
|
+
"@atlaspack/utils": "2.14.5-canary.140+43fdd2238",
|
|
26
|
+
"many-keys-map": "^1.0.3",
|
|
25
27
|
"nullthrows": "^1.1.1"
|
|
26
28
|
},
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
+
"scripts": {
|
|
30
|
+
"check-ts": "tsc --emitDeclarationOnly --rootDir src"
|
|
31
|
+
},
|
|
32
|
+
"gitHead": "43fdd223860fbc97af17d68c65419b97412cb888"
|
|
33
|
+
}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// @flow strict-local
|
|
2
|
-
|
|
3
1
|
import {Bundler} from '@atlaspack/plugin';
|
|
4
2
|
import type {Asset, Dependency, MutableBundleGraph} from '@atlaspack/types';
|
|
5
3
|
import {DefaultMap} from '@atlaspack/utils';
|
|
@@ -25,14 +23,15 @@ import {addJSMonolithBundle} from './MonolithicBundler';
|
|
|
25
23
|
* will have two or more distDirs, or output folders.) Then calls create IdealGraph and Decorate per target.
|
|
26
24
|
*
|
|
27
25
|
*/
|
|
28
|
-
export default
|
|
26
|
+
export default new Bundler({
|
|
29
27
|
loadConfig({config, options, logger}) {
|
|
30
28
|
return loadBundlerConfig(config, options, logger);
|
|
31
29
|
},
|
|
32
30
|
|
|
33
31
|
bundle({bundleGraph, config, logger}) {
|
|
34
32
|
let targetMap = getEntryByTarget(bundleGraph); // Organize entries by target output folder/ distDir
|
|
35
|
-
|
|
33
|
+
// @ts-expect-error TS2304
|
|
34
|
+
let graphs: Array<IdealGraph> = [];
|
|
36
35
|
|
|
37
36
|
for (let entries of targetMap.values()) {
|
|
38
37
|
let singleFileEntries = new Map();
|
|
@@ -64,7 +63,7 @@ export default (new Bundler({
|
|
|
64
63
|
}
|
|
65
64
|
},
|
|
66
65
|
optimize() {},
|
|
67
|
-
})
|
|
66
|
+
}) as Bundler<unknown>;
|
|
68
67
|
|
|
69
68
|
function getEntryByTarget(
|
|
70
69
|
bundleGraph: MutableBundleGraph,
|
|
@@ -74,7 +73,23 @@ function getEntryByTarget(
|
|
|
74
73
|
() => new Map(),
|
|
75
74
|
);
|
|
76
75
|
bundleGraph.traverse({
|
|
77
|
-
enter(
|
|
76
|
+
enter(
|
|
77
|
+
// @ts-expect-error TS2304
|
|
78
|
+
node: BundleGraphTraversable,
|
|
79
|
+
context:
|
|
80
|
+
| {
|
|
81
|
+
readonly type: 'asset';
|
|
82
|
+
value: Asset;
|
|
83
|
+
}
|
|
84
|
+
| null
|
|
85
|
+
| undefined
|
|
86
|
+
| {
|
|
87
|
+
readonly type: 'dependency';
|
|
88
|
+
value: Dependency;
|
|
89
|
+
},
|
|
90
|
+
// @ts-expect-error TS2304
|
|
91
|
+
actions: TraversalActions,
|
|
92
|
+
) {
|
|
78
93
|
if (node.type !== 'asset') {
|
|
79
94
|
return node;
|
|
80
95
|
}
|