@atlaspack/bundler-default 2.14.5-canary.17 → 2.14.5-canary.170
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 +370 -0
- package/lib/DefaultBundler.js +6 -1
- package/lib/MonolithicBundler.js +2 -2
- package/lib/bundleMerge.js +106 -37
- package/lib/bundlerConfig.js +30 -5
- package/lib/decorateLegacyGraph.js +24 -3
- package/lib/idealGraph.js +227 -46
- package/lib/memoize.js +39 -0
- package/lib/types/DefaultBundler.d.ts +18 -0
- package/lib/types/MonolithicBundler.d.ts +2 -0
- package/lib/types/bundleMerge.d.ts +9 -0
- package/lib/types/bundlerConfig.d.ts +27 -0
- package/lib/types/decorateLegacyGraph.d.ts +3 -0
- package/lib/types/idealGraph.d.ts +40 -0
- package/lib/types/memoize.d.ts +2 -0
- package/package.json +17 -10
- package/src/{DefaultBundler.js → DefaultBundler.ts} +21 -6
- package/src/{MonolithicBundler.js → MonolithicBundler.ts} +10 -4
- package/src/bundleMerge.ts +250 -0
- package/src/{bundlerConfig.js → bundlerConfig.ts} +73 -44
- package/src/{decorateLegacyGraph.js → decorateLegacyGraph.ts} +26 -7
- package/src/{idealGraph.js → idealGraph.ts} +391 -102
- package/src/memoize.ts +32 -0
- package/tsconfig.json +4 -0
- package/src/bundleMerge.js +0 -103
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// @flow strict-local
|
|
2
|
-
|
|
3
1
|
import path from 'path';
|
|
4
2
|
|
|
5
3
|
import {getFeatureFlag} from '@atlaspack/feature-flags';
|
|
@@ -8,7 +6,7 @@ import {
|
|
|
8
6
|
BitSet,
|
|
9
7
|
ContentGraph,
|
|
10
8
|
Graph,
|
|
11
|
-
|
|
9
|
+
NodeId,
|
|
12
10
|
} from '@atlaspack/graph';
|
|
13
11
|
import type {
|
|
14
12
|
Asset,
|
|
@@ -23,37 +21,38 @@ import {DefaultMap, globToRegex} from '@atlaspack/utils';
|
|
|
23
21
|
import invariant from 'assert';
|
|
24
22
|
import nullthrows from 'nullthrows';
|
|
25
23
|
|
|
26
|
-
import {findMergeCandidates} from './bundleMerge';
|
|
27
|
-
import type {ResolvedBundlerConfig} from './bundlerConfig';
|
|
24
|
+
import {findMergeCandidates, MergeGroup} from './bundleMerge';
|
|
25
|
+
import type {ResolvedBundlerConfig, MergeCandidates} from './bundlerConfig';
|
|
28
26
|
|
|
29
27
|
/* BundleRoot - An asset that is the main entry of a Bundle. */
|
|
30
28
|
type BundleRoot = Asset;
|
|
31
29
|
|
|
32
|
-
export type Bundle = {
|
|
33
|
-
uniqueKey:
|
|
34
|
-
assets: Set<Asset
|
|
35
|
-
internalizedAssets?: BitSet
|
|
36
|
-
bundleBehavior?:
|
|
37
|
-
needsStableName: boolean
|
|
38
|
-
mainEntryAsset:
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
|
30
|
+
export type Bundle = {
|
|
31
|
+
uniqueKey: string | null | undefined;
|
|
32
|
+
assets: Set<Asset>;
|
|
33
|
+
internalizedAssets?: BitSet;
|
|
34
|
+
bundleBehavior?: BundleBehavior | null | undefined;
|
|
35
|
+
needsStableName: boolean;
|
|
36
|
+
mainEntryAsset: Asset | null | undefined;
|
|
37
|
+
bundleRoots: Set<Asset>;
|
|
38
|
+
size: number;
|
|
39
|
+
sourceBundles: Set<NodeId>;
|
|
40
|
+
target: Target;
|
|
41
|
+
env: Environment;
|
|
42
|
+
type: string;
|
|
43
|
+
manualSharedBundle: string | null | undefined; // for naming purposes;
|
|
44
|
+
};
|
|
46
45
|
|
|
47
46
|
export type DependencyBundleGraph = ContentGraph<
|
|
48
|
-
| {
|
|
49
|
-
value: Bundle
|
|
50
|
-
type: 'bundle'
|
|
51
|
-
|
|
52
|
-
| {
|
|
53
|
-
value: Dependency
|
|
54
|
-
type: 'dependency'
|
|
55
|
-
|
|
56
|
-
number
|
|
47
|
+
| {
|
|
48
|
+
value: Bundle;
|
|
49
|
+
type: 'bundle';
|
|
50
|
+
}
|
|
51
|
+
| {
|
|
52
|
+
value: Dependency;
|
|
53
|
+
type: 'dependency';
|
|
54
|
+
},
|
|
55
|
+
number
|
|
57
56
|
>;
|
|
58
57
|
|
|
59
58
|
const dependencyPriorityEdges = {
|
|
@@ -61,7 +60,7 @@ const dependencyPriorityEdges = {
|
|
|
61
60
|
parallel: 2,
|
|
62
61
|
lazy: 3,
|
|
63
62
|
conditional: 4,
|
|
64
|
-
};
|
|
63
|
+
} as const;
|
|
65
64
|
|
|
66
65
|
export const idealBundleGraphEdges = Object.freeze({
|
|
67
66
|
default: 1,
|
|
@@ -70,20 +69,30 @@ export const idealBundleGraphEdges = Object.freeze({
|
|
|
70
69
|
|
|
71
70
|
export type IdealBundleGraph = Graph<
|
|
72
71
|
Bundle | 'root',
|
|
73
|
-
|
|
72
|
+
(typeof idealBundleGraphEdges)[keyof typeof idealBundleGraphEdges]
|
|
74
73
|
>;
|
|
75
74
|
|
|
76
75
|
// IdealGraph is the structure we will pass to decorate,
|
|
77
76
|
// which mutates the assetGraph into the bundleGraph we would
|
|
78
77
|
// expect from default bundler
|
|
79
|
-
export type IdealGraph = {
|
|
80
|
-
assetReference: DefaultMap<Asset, Array<[Dependency, Bundle]
|
|
81
|
-
assets: Array<Asset
|
|
82
|
-
bundleGraph: IdealBundleGraph
|
|
83
|
-
bundleGroupBundleIds: Set<NodeId
|
|
84
|
-
dependencyBundleGraph: DependencyBundleGraph
|
|
85
|
-
manualAssetToBundle: Map<Asset, NodeId
|
|
86
|
-
|
|
78
|
+
export type IdealGraph = {
|
|
79
|
+
assetReference: DefaultMap<Asset, Array<[Dependency, Bundle]>>;
|
|
80
|
+
assets: Array<Asset>;
|
|
81
|
+
bundleGraph: IdealBundleGraph;
|
|
82
|
+
bundleGroupBundleIds: Set<NodeId>;
|
|
83
|
+
dependencyBundleGraph: DependencyBundleGraph;
|
|
84
|
+
manualAssetToBundle: Map<Asset, NodeId>;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
function isNonRootBundle(
|
|
88
|
+
bundle?: Bundle | 'root' | null,
|
|
89
|
+
message?: string,
|
|
90
|
+
): Bundle {
|
|
91
|
+
let existingBundle = nullthrows(bundle, message);
|
|
92
|
+
invariant(existingBundle !== 'root', "Bundle cannot be 'root'");
|
|
93
|
+
|
|
94
|
+
return existingBundle;
|
|
95
|
+
}
|
|
87
96
|
|
|
88
97
|
export function createIdealGraph(
|
|
89
98
|
assetGraph: MutableBundleGraph,
|
|
@@ -97,7 +106,7 @@ export function createIdealGraph(
|
|
|
97
106
|
let dependencyBundleGraph: DependencyBundleGraph = new ContentGraph();
|
|
98
107
|
let assetReference: DefaultMap<
|
|
99
108
|
Asset,
|
|
100
|
-
Array<[Dependency, Bundle]
|
|
109
|
+
Array<[Dependency, Bundle]>
|
|
101
110
|
> = new DefaultMap(() => []);
|
|
102
111
|
|
|
103
112
|
// A Graph of Bundles and a root node (dummy string), which models only Bundles, and connections to their
|
|
@@ -111,8 +120,9 @@ export function createIdealGraph(
|
|
|
111
120
|
};
|
|
112
121
|
// Graph that models bundleRoots, with parallel & async deps only to inform reachability
|
|
113
122
|
let bundleRootGraph: Graph<
|
|
114
|
-
|
|
115
|
-
|
|
123
|
+
// asset index
|
|
124
|
+
number,
|
|
125
|
+
(typeof bundleRootEdgeTypes)[keyof typeof bundleRootEdgeTypes]
|
|
116
126
|
> = new Graph();
|
|
117
127
|
let assetToBundleRootNodeId = new Map<BundleRoot, number>();
|
|
118
128
|
|
|
@@ -146,7 +156,7 @@ export function createIdealGraph(
|
|
|
146
156
|
bundleGroupBundleIds.add(nodeId);
|
|
147
157
|
}
|
|
148
158
|
|
|
149
|
-
let assets = [];
|
|
159
|
+
let assets: Array<Asset> = [];
|
|
150
160
|
let assetToIndex = new Map<Asset, number>();
|
|
151
161
|
|
|
152
162
|
function makeManualAssetToConfigLookup() {
|
|
@@ -161,6 +171,7 @@ export function createIdealGraph(
|
|
|
161
171
|
|
|
162
172
|
for (let c of config.manualSharedBundles) {
|
|
163
173
|
if (c.root != null) {
|
|
174
|
+
// @ts-expect-error TS2345
|
|
164
175
|
parentsToConfig.get(path.join(config.projectRoot, c.root)).push(c);
|
|
165
176
|
}
|
|
166
177
|
}
|
|
@@ -204,17 +215,17 @@ export function createIdealGraph(
|
|
|
204
215
|
config.projectRoot,
|
|
205
216
|
node.value.filePath,
|
|
206
217
|
);
|
|
207
|
-
if (!assetRegexes.some((regex) => regex.test(projectRelativePath))) {
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
218
|
|
|
211
219
|
// We track all matching MSB's for constant modules as they are never duplicated
|
|
212
220
|
// and need to be assigned to all matching bundles
|
|
213
221
|
if (node.value.meta.isConstantModule === true) {
|
|
222
|
+
// @ts-expect-error TS2345
|
|
214
223
|
constantModuleToMSB.get(node.value).push(c);
|
|
215
224
|
}
|
|
216
|
-
|
|
217
|
-
|
|
225
|
+
|
|
226
|
+
if (assetRegexes.some((regex) => regex.test(projectRelativePath))) {
|
|
227
|
+
manualAssetToConfig.set(node.value, c);
|
|
228
|
+
}
|
|
218
229
|
}
|
|
219
230
|
|
|
220
231
|
if (
|
|
@@ -242,9 +253,19 @@ export function createIdealGraph(
|
|
|
242
253
|
makeManualAssetToConfigLookup();
|
|
243
254
|
let manualBundleToInternalizedAsset: DefaultMap<
|
|
244
255
|
NodeId,
|
|
245
|
-
Array<Asset
|
|
256
|
+
Array<Asset>
|
|
246
257
|
> = new DefaultMap(() => []);
|
|
247
258
|
|
|
259
|
+
let mergeSourceBundleLookup = new Map<string, NodeId>();
|
|
260
|
+
let mergeSourceBundleAssets = new Set(
|
|
261
|
+
config.sharedBundleMerge?.flatMap(
|
|
262
|
+
(c) =>
|
|
263
|
+
c.sourceBundles?.map((assetMatch: string) =>
|
|
264
|
+
path.join(config.projectRoot, assetMatch),
|
|
265
|
+
) ?? [],
|
|
266
|
+
),
|
|
267
|
+
);
|
|
268
|
+
|
|
248
269
|
/**
|
|
249
270
|
* Step Create Bundles: Traverse the assetGraph (aka MutableBundleGraph) and create bundles
|
|
250
271
|
* for asset type changes, parallel, inline, and async or lazy dependencies,
|
|
@@ -252,7 +273,27 @@ export function createIdealGraph(
|
|
|
252
273
|
*/
|
|
253
274
|
assetGraph.traverse(
|
|
254
275
|
{
|
|
255
|
-
enter(
|
|
276
|
+
enter(
|
|
277
|
+
node: // @ts-expect-error TS2304
|
|
278
|
+
| BundleGraphTraversable
|
|
279
|
+
| {
|
|
280
|
+
readonly type: 'dependency';
|
|
281
|
+
value: Dependency;
|
|
282
|
+
},
|
|
283
|
+
context:
|
|
284
|
+
| {
|
|
285
|
+
readonly type: 'asset';
|
|
286
|
+
value: Asset;
|
|
287
|
+
}
|
|
288
|
+
| null
|
|
289
|
+
| undefined
|
|
290
|
+
| {
|
|
291
|
+
readonly type: 'dependency';
|
|
292
|
+
value: Dependency;
|
|
293
|
+
},
|
|
294
|
+
// @ts-expect-error TS2304
|
|
295
|
+
actions: TraversalActions,
|
|
296
|
+
) {
|
|
256
297
|
if (node.type === 'asset') {
|
|
257
298
|
if (
|
|
258
299
|
context?.type === 'dependency' &&
|
|
@@ -312,7 +353,8 @@ export function createIdealGraph(
|
|
|
312
353
|
dependency.priority === 'lazy' ||
|
|
313
354
|
(getFeatureFlag('conditionalBundlingApi') &&
|
|
314
355
|
node.value.priority === 'conditional') ||
|
|
315
|
-
childAsset.bundleBehavior === 'isolated' // An isolated Dependency, or Bundle must contain all assets it needs to load.
|
|
356
|
+
childAsset.bundleBehavior === 'isolated' || // An isolated Dependency, or Bundle must contain all assets it needs to load.
|
|
357
|
+
childAsset.bundleBehavior === 'inlineIsolated'
|
|
316
358
|
) {
|
|
317
359
|
if (bundleId == null) {
|
|
318
360
|
let firstBundleGroup = nullthrows(
|
|
@@ -325,7 +367,9 @@ export function createIdealGraph(
|
|
|
325
367
|
dependency.bundleBehavior ?? childAsset.bundleBehavior,
|
|
326
368
|
needsStableName:
|
|
327
369
|
dependency.bundleBehavior === 'inline' ||
|
|
328
|
-
childAsset.bundleBehavior === 'inline'
|
|
370
|
+
childAsset.bundleBehavior === 'inline' ||
|
|
371
|
+
dependency.bundleBehavior === 'inlineIsolated' ||
|
|
372
|
+
childAsset.bundleBehavior === 'inlineIsolated'
|
|
329
373
|
? false
|
|
330
374
|
: dependency.isEntry || dependency.needsStableName,
|
|
331
375
|
target: firstBundleGroup.target,
|
|
@@ -335,6 +379,14 @@ export function createIdealGraph(
|
|
|
335
379
|
bundleRoots.set(childAsset, [bundleId, bundleId]);
|
|
336
380
|
bundleGroupBundleIds.add(bundleId);
|
|
337
381
|
bundleGraph.addEdge(bundleGraphRootNodeId, bundleId);
|
|
382
|
+
// If this asset is relevant for merging then track it's source
|
|
383
|
+
// bundle id for later
|
|
384
|
+
if (mergeSourceBundleAssets.has(childAsset.filePath)) {
|
|
385
|
+
mergeSourceBundleLookup.set(
|
|
386
|
+
path.relative(config.projectRoot, childAsset.filePath),
|
|
387
|
+
bundleId,
|
|
388
|
+
);
|
|
389
|
+
}
|
|
338
390
|
if (manualSharedObject) {
|
|
339
391
|
// MSB Step 4: If this was the first instance of a match, mark mainAsset for internalization
|
|
340
392
|
// since MSBs should not have main entry assets
|
|
@@ -349,7 +401,8 @@ export function createIdealGraph(
|
|
|
349
401
|
if (
|
|
350
402
|
// If this dependency requests isolated, but the bundle is not,
|
|
351
403
|
// make the bundle isolated for all uses.
|
|
352
|
-
dependency.bundleBehavior === 'isolated'
|
|
404
|
+
(dependency.bundleBehavior === 'isolated' ||
|
|
405
|
+
dependency.bundleBehavior === 'inlineIsolated') &&
|
|
353
406
|
bundle.bundleBehavior == null
|
|
354
407
|
) {
|
|
355
408
|
bundle.bundleBehavior = dependency.bundleBehavior;
|
|
@@ -371,6 +424,7 @@ export function createIdealGraph(
|
|
|
371
424
|
type: 'bundle',
|
|
372
425
|
},
|
|
373
426
|
),
|
|
427
|
+
// @ts-expect-error TS7053
|
|
374
428
|
dependencyPriorityEdges[dependency.priority],
|
|
375
429
|
);
|
|
376
430
|
|
|
@@ -432,6 +486,7 @@ export function createIdealGraph(
|
|
|
432
486
|
needsStableName:
|
|
433
487
|
childAsset.bundleBehavior === 'inline' ||
|
|
434
488
|
dependency.bundleBehavior === 'inline' ||
|
|
489
|
+
dependency.bundleBehavior === 'inlineIsolated' ||
|
|
435
490
|
(dependency.priority === 'parallel' &&
|
|
436
491
|
!dependency.needsStableName)
|
|
437
492
|
? false
|
|
@@ -445,7 +500,8 @@ export function createIdealGraph(
|
|
|
445
500
|
if (
|
|
446
501
|
// If this dependency requests isolated, but the bundle is not,
|
|
447
502
|
// make the bundle isolated for all uses.
|
|
448
|
-
dependency.bundleBehavior === 'isolated'
|
|
503
|
+
(dependency.bundleBehavior === 'isolated' ||
|
|
504
|
+
dependency.bundleBehavior === 'inlineIsolated') &&
|
|
449
505
|
bundle.bundleBehavior == null
|
|
450
506
|
) {
|
|
451
507
|
bundle.bundleBehavior = dependency.bundleBehavior;
|
|
@@ -482,6 +538,7 @@ export function createIdealGraph(
|
|
|
482
538
|
|
|
483
539
|
assetReference.get(childAsset).push([dependency, bundle]);
|
|
484
540
|
} else {
|
|
541
|
+
// @ts-expect-error TS2322
|
|
485
542
|
bundleId = null;
|
|
486
543
|
}
|
|
487
544
|
if (manualSharedObject && bundleId != null) {
|
|
@@ -489,6 +546,7 @@ export function createIdealGraph(
|
|
|
489
546
|
// add the asset if it doesn't already have it and set key
|
|
490
547
|
|
|
491
548
|
invariant(
|
|
549
|
+
// @ts-expect-error TS2367
|
|
492
550
|
bundle !== 'root' && bundle != null && bundleId != null,
|
|
493
551
|
);
|
|
494
552
|
|
|
@@ -515,7 +573,8 @@ export function createIdealGraph(
|
|
|
515
573
|
}
|
|
516
574
|
return node;
|
|
517
575
|
},
|
|
518
|
-
|
|
576
|
+
// @ts-expect-error TS2322
|
|
577
|
+
exit(node: BundleGraphTraversable) {
|
|
519
578
|
if (stack[stack.length - 1]?.[0] === node.value) {
|
|
520
579
|
stack.pop();
|
|
521
580
|
}
|
|
@@ -564,20 +623,20 @@ export function createIdealGraph(
|
|
|
564
623
|
|
|
565
624
|
// reachableRoots is an array of bit sets for each asset. Each bit set
|
|
566
625
|
// indicates which bundle roots are reachable from that asset synchronously.
|
|
567
|
-
let reachableRoots = [];
|
|
626
|
+
let reachableRoots: Array<BitSet> = [];
|
|
568
627
|
for (let i = 0; i < assets.length; i++) {
|
|
569
628
|
reachableRoots.push(new BitSet(bundleRootGraph.nodes.length));
|
|
570
629
|
}
|
|
571
630
|
|
|
572
631
|
// reachableAssets is the inverse mapping of reachableRoots. For each bundle root,
|
|
573
632
|
// it contains a bit set that indicates which assets are reachable from it.
|
|
574
|
-
let reachableAssets = [];
|
|
633
|
+
let reachableAssets: Array<BitSet> = [];
|
|
575
634
|
|
|
576
635
|
// ancestorAssets maps bundle roots to the set of all assets available to it at runtime,
|
|
577
636
|
// including in earlier parallel bundles. These are intersected through all paths to
|
|
578
637
|
// the bundle to ensure that the available assets are always present no matter in which
|
|
579
638
|
// order the bundles are loaded.
|
|
580
|
-
let ancestorAssets = [];
|
|
639
|
+
let ancestorAssets: Array<null | BitSet> = [];
|
|
581
640
|
|
|
582
641
|
let inlineConstantDeps = new DefaultMap(() => new Set());
|
|
583
642
|
|
|
@@ -688,7 +747,10 @@ export function createIdealGraph(
|
|
|
688
747
|
// not true that a bundle's available assets = all assets of all the bundleGroups
|
|
689
748
|
// it belongs to. It's the intersection of those sets.
|
|
690
749
|
let available;
|
|
691
|
-
if (
|
|
750
|
+
if (
|
|
751
|
+
bundleRoot.bundleBehavior === 'isolated' ||
|
|
752
|
+
bundleRoot.bundleBehavior === 'inlineIsolated'
|
|
753
|
+
) {
|
|
692
754
|
available = new BitSet(assets.length);
|
|
693
755
|
} else {
|
|
694
756
|
available = nullthrows(ancestorAssets[nodeId]).clone();
|
|
@@ -772,7 +834,8 @@ export function createIdealGraph(
|
|
|
772
834
|
|
|
773
835
|
let parentRoots = bundleRootGraph.getNodeIdsConnectedTo(id, ALL_EDGE_TYPES);
|
|
774
836
|
let canDelete =
|
|
775
|
-
getBundleFromBundleRoot(bundleRoot).bundleBehavior !== 'isolated'
|
|
837
|
+
getBundleFromBundleRoot(bundleRoot).bundleBehavior !== 'isolated' &&
|
|
838
|
+
getBundleFromBundleRoot(bundleRoot).bundleBehavior !== 'inlineIsolated';
|
|
776
839
|
if (parentRoots.length === 0) continue;
|
|
777
840
|
for (let parentId of parentRoots) {
|
|
778
841
|
if (parentId === rootNodeId) {
|
|
@@ -806,8 +869,11 @@ export function createIdealGraph(
|
|
|
806
869
|
|
|
807
870
|
function assignInlineConstants(parentAsset: Asset, bundle: Bundle) {
|
|
808
871
|
for (let inlineConstant of inlineConstantDeps.get(parentAsset)) {
|
|
872
|
+
// @ts-expect-error TS2345
|
|
809
873
|
if (!bundle.assets.has(inlineConstant)) {
|
|
874
|
+
// @ts-expect-error TS2345
|
|
810
875
|
bundle.assets.add(inlineConstant);
|
|
876
|
+
// @ts-expect-error TS18046
|
|
811
877
|
bundle.size += inlineConstant.stats.size;
|
|
812
878
|
}
|
|
813
879
|
}
|
|
@@ -849,7 +915,8 @@ export function createIdealGraph(
|
|
|
849
915
|
!a.isBundleSplittable ||
|
|
850
916
|
(bundleRoots.get(a) &&
|
|
851
917
|
(getBundleFromBundleRoot(a).needsStableName ||
|
|
852
|
-
getBundleFromBundleRoot(a).bundleBehavior === 'isolated'
|
|
918
|
+
getBundleFromBundleRoot(a).bundleBehavior === 'isolated' ||
|
|
919
|
+
getBundleFromBundleRoot(a).bundleBehavior === 'inlineIsolated'))
|
|
853
920
|
) {
|
|
854
921
|
// Add asset to non-splittable bundles.
|
|
855
922
|
addAssetToBundleRoot(asset, a);
|
|
@@ -867,7 +934,7 @@ export function createIdealGraph(
|
|
|
867
934
|
let bundle;
|
|
868
935
|
let bundleId;
|
|
869
936
|
let manualSharedBundleKey = manualSharedObject.name + ',' + asset.type;
|
|
870
|
-
let sourceBundles = [];
|
|
937
|
+
let sourceBundles: Array<NodeId> = [];
|
|
871
938
|
reachable.forEach((id) => {
|
|
872
939
|
sourceBundles.push(nullthrows(bundleRoots.get(assets[id]))[0]);
|
|
873
940
|
});
|
|
@@ -982,7 +1049,7 @@ export function createIdealGraph(
|
|
|
982
1049
|
});
|
|
983
1050
|
}
|
|
984
1051
|
|
|
985
|
-
let reachableArray = [];
|
|
1052
|
+
let reachableArray: Array<Asset> = [];
|
|
986
1053
|
reachable.forEach((id) => {
|
|
987
1054
|
reachableArray.push(assets[id]);
|
|
988
1055
|
});
|
|
@@ -1057,6 +1124,8 @@ export function createIdealGraph(
|
|
|
1057
1124
|
}
|
|
1058
1125
|
|
|
1059
1126
|
let manualSharedBundleIds = new Set([...manualSharedMap.values()]);
|
|
1127
|
+
let modifiedSourceBundles = new Set<Bundle>();
|
|
1128
|
+
|
|
1060
1129
|
// Step split manual shared bundles for those that have the "split" property set
|
|
1061
1130
|
let remainderMap = new DefaultMap(() => []);
|
|
1062
1131
|
for (let id of manualSharedMap.values()) {
|
|
@@ -1075,9 +1144,9 @@ export function createIdealGraph(
|
|
|
1075
1144
|
if (modNum != null) {
|
|
1076
1145
|
for (let a of [...manualBundle.assets]) {
|
|
1077
1146
|
let numRep = getBigIntFromContentKey(a.id);
|
|
1078
|
-
// $FlowFixMe Flow doesn't know about BigInt
|
|
1079
1147
|
let r = Number(numRep % BigInt(modNum));
|
|
1080
1148
|
|
|
1149
|
+
// @ts-expect-error TS2345
|
|
1081
1150
|
remainderMap.get(r).push(a);
|
|
1082
1151
|
}
|
|
1083
1152
|
|
|
@@ -1100,8 +1169,10 @@ export function createIdealGraph(
|
|
|
1100
1169
|
}
|
|
1101
1170
|
for (let sp of remainderMap.get(i)) {
|
|
1102
1171
|
bundle.assets.add(sp);
|
|
1172
|
+
// @ts-expect-error TS2339
|
|
1103
1173
|
bundle.size += sp.stats.size;
|
|
1104
1174
|
manualBundle.assets.delete(sp);
|
|
1175
|
+
// @ts-expect-error TS2339
|
|
1105
1176
|
manualBundle.size -= sp.stats.size;
|
|
1106
1177
|
}
|
|
1107
1178
|
}
|
|
@@ -1114,6 +1185,7 @@ export function createIdealGraph(
|
|
|
1114
1185
|
// match multiple MSB's
|
|
1115
1186
|
for (let [asset, msbs] of constantModuleToMSB.entries()) {
|
|
1116
1187
|
for (let manualSharedObject of msbs) {
|
|
1188
|
+
// @ts-expect-error TS2339
|
|
1117
1189
|
let bundleId = manualSharedMap.get(manualSharedObject.name + ',js');
|
|
1118
1190
|
if (bundleId == null) continue;
|
|
1119
1191
|
let bundle = nullthrows(bundleGraph.getNode(bundleId));
|
|
@@ -1122,17 +1194,94 @@ export function createIdealGraph(
|
|
|
1122
1194
|
'We tried to use the root incorrectly',
|
|
1123
1195
|
);
|
|
1124
1196
|
|
|
1197
|
+
// @ts-expect-error TS2345
|
|
1125
1198
|
if (!bundle.assets.has(asset)) {
|
|
1199
|
+
// @ts-expect-error TS2345
|
|
1126
1200
|
bundle.assets.add(asset);
|
|
1201
|
+
// @ts-expect-error TS18046
|
|
1127
1202
|
bundle.size += asset.stats.size;
|
|
1128
1203
|
}
|
|
1129
1204
|
}
|
|
1130
1205
|
}
|
|
1131
1206
|
|
|
1207
|
+
if (getFeatureFlag('supportWebpackChunkName')) {
|
|
1208
|
+
// Merge webpack chunk name bundles
|
|
1209
|
+
let chunkNameBundles = new DefaultMap(() => new Set());
|
|
1210
|
+
for (let [nodeId, node] of dependencyBundleGraph.nodes.entries()) {
|
|
1211
|
+
// meta.chunkName is set by the Rust transformer, so we just need to find
|
|
1212
|
+
// bundles that have a chunkName set.
|
|
1213
|
+
if (
|
|
1214
|
+
!node ||
|
|
1215
|
+
node.type !== 'dependency' ||
|
|
1216
|
+
node.value.meta.chunkName == null
|
|
1217
|
+
) {
|
|
1218
|
+
continue;
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
let connectedBundles = dependencyBundleGraph.getNodeIdsConnectedFrom(
|
|
1222
|
+
nodeId,
|
|
1223
|
+
dependencyPriorityEdges[node.value.priority],
|
|
1224
|
+
);
|
|
1225
|
+
|
|
1226
|
+
if (connectedBundles.length === 0) {
|
|
1227
|
+
continue;
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
invariant(
|
|
1231
|
+
connectedBundles.length === 1,
|
|
1232
|
+
'Expected webpackChunkName dependency to be connected to no more than one bundle',
|
|
1233
|
+
);
|
|
1234
|
+
|
|
1235
|
+
let bundleId = connectedBundles[0];
|
|
1236
|
+
let bundleNode = dependencyBundleGraph.getNode(bundleId);
|
|
1237
|
+
invariant(bundleNode != null && bundleNode.type === 'bundle');
|
|
1238
|
+
|
|
1239
|
+
// If a bundle does not have a main entry asset, it's somehow just a
|
|
1240
|
+
// shared bundle, and will be merged/deleted by other means.
|
|
1241
|
+
if (bundleNode.value.mainEntryAsset == null) {
|
|
1242
|
+
continue;
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
let bundleNodeId = null;
|
|
1246
|
+
let mainEntryAssetId = bundleNode.value.mainEntryAsset?.id;
|
|
1247
|
+
|
|
1248
|
+
if (mainEntryAssetId != null) {
|
|
1249
|
+
bundleNodeId = bundles.get(mainEntryAssetId);
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
if (bundleNodeId == null) {
|
|
1253
|
+
continue;
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
chunkNameBundles
|
|
1257
|
+
.get(node.value.meta.chunkName)
|
|
1258
|
+
// DependencyBundleGraph uses content keys as node ids, so we can use that
|
|
1259
|
+
// to get the bundle id.
|
|
1260
|
+
.add(bundleNodeId);
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
for (let [chunkName, bundleIds] of chunkNameBundles.entries()) {
|
|
1264
|
+
// The `[request]` placeholder is not yet supported
|
|
1265
|
+
if (
|
|
1266
|
+
bundleIds.size <= 1 ||
|
|
1267
|
+
(typeof chunkName === 'string' && chunkName.includes('[request]'))
|
|
1268
|
+
) {
|
|
1269
|
+
continue; // Nothing to merge
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
// Merge all bundles with the same chunk name into the first one.
|
|
1273
|
+
let [firstBundleId, ...rest] = Array.from(bundleIds);
|
|
1274
|
+
for (let bundleId of rest) {
|
|
1275
|
+
// @ts-expect-error TS2345
|
|
1276
|
+
mergeBundles(firstBundleId, bundleId);
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1132
1281
|
// Step merge shared bundles that meet the overlap threshold
|
|
1133
1282
|
// This step is skipped by default as the threshold defaults to 1
|
|
1134
|
-
if (config.
|
|
1135
|
-
mergeOverlapBundles();
|
|
1283
|
+
if (config.sharedBundleMerge && config.sharedBundleMerge.length > 0) {
|
|
1284
|
+
mergeOverlapBundles(config.sharedBundleMerge);
|
|
1136
1285
|
}
|
|
1137
1286
|
|
|
1138
1287
|
// Step Merge Share Bundles: Merge any shared bundles under the minimum bundle size back into
|
|
@@ -1151,7 +1300,6 @@ export function createIdealGraph(
|
|
|
1151
1300
|
}
|
|
1152
1301
|
|
|
1153
1302
|
// Step Remove Shared Bundles: Remove shared bundles from bundle groups that hit the parallel request limit.
|
|
1154
|
-
let modifiedSourceBundles = new Set();
|
|
1155
1303
|
|
|
1156
1304
|
if (config.disableSharedBundles === false) {
|
|
1157
1305
|
for (let bundleGroupId of bundleGraph.getNodeIdsConnectedFrom(rootNodeId)) {
|
|
@@ -1165,7 +1313,13 @@ export function createIdealGraph(
|
|
|
1165
1313
|
let numBundlesContributingToPRL = bundleIdsInGroup.reduce((count, b) => {
|
|
1166
1314
|
let bundle = nullthrows(bundleGraph.getNode(b));
|
|
1167
1315
|
invariant(bundle !== 'root');
|
|
1168
|
-
return
|
|
1316
|
+
return (
|
|
1317
|
+
count +
|
|
1318
|
+
Number(
|
|
1319
|
+
bundle.bundleBehavior !== 'inline' &&
|
|
1320
|
+
bundle.bundleBehavior !== 'inlineIsolated',
|
|
1321
|
+
)
|
|
1322
|
+
);
|
|
1169
1323
|
}, 0);
|
|
1170
1324
|
|
|
1171
1325
|
if (numBundlesContributingToPRL > config.maxParallelRequests) {
|
|
@@ -1200,7 +1354,9 @@ export function createIdealGraph(
|
|
|
1200
1354
|
numBundlesContributingToPRL > config.maxParallelRequests
|
|
1201
1355
|
) {
|
|
1202
1356
|
let bundleTuple = sharedBundlesInGroup.pop();
|
|
1357
|
+
// @ts-expect-error TS18048
|
|
1203
1358
|
let bundleToRemove = bundleTuple.bundle;
|
|
1359
|
+
// @ts-expect-error TS18048
|
|
1204
1360
|
let bundleIdToRemove = bundleTuple.id;
|
|
1205
1361
|
//TODO add integration test where bundles in bunlde group > max parallel request limit & only remove a couple shared bundles
|
|
1206
1362
|
// but total # bundles still exceeds limit due to non shared bundles
|
|
@@ -1256,28 +1412,50 @@ export function createIdealGraph(
|
|
|
1256
1412
|
}
|
|
1257
1413
|
}
|
|
1258
1414
|
|
|
1259
|
-
function mergeBundles(
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1415
|
+
function mergeBundles(bundleToKeepId: NodeId, bundleToRemoveId: NodeId) {
|
|
1416
|
+
let bundleToKeep = isNonRootBundle(
|
|
1417
|
+
bundleGraph.getNode(bundleToKeepId),
|
|
1418
|
+
`Bundle ${bundleToKeepId} not found`,
|
|
1419
|
+
);
|
|
1420
|
+
let bundleToRemove = isNonRootBundle(
|
|
1421
|
+
bundleGraph.getNode(bundleToRemoveId),
|
|
1422
|
+
`Bundle ${bundleToRemoveId} not found`,
|
|
1423
|
+
);
|
|
1424
|
+
modifiedSourceBundles.add(bundleToKeep);
|
|
1268
1425
|
for (let asset of bundleToRemove.assets) {
|
|
1269
1426
|
bundleToKeep.assets.add(asset);
|
|
1270
1427
|
bundleToKeep.size += asset.stats.size;
|
|
1271
1428
|
|
|
1272
1429
|
let newAssetReference = assetReference
|
|
1273
1430
|
.get(asset)
|
|
1274
|
-
.map(([dep, bundle]) =>
|
|
1431
|
+
.map(([dep, bundle]: [any, any]) =>
|
|
1275
1432
|
bundle === bundleToRemove ? [dep, bundleToKeep] : [dep, bundle],
|
|
1276
1433
|
);
|
|
1277
1434
|
|
|
1435
|
+
// @ts-expect-error TS2345
|
|
1278
1436
|
assetReference.set(asset, newAssetReference);
|
|
1279
1437
|
}
|
|
1280
1438
|
|
|
1439
|
+
// Merge any internalized assets
|
|
1440
|
+
if (getFeatureFlag('supportWebpackChunkName')) {
|
|
1441
|
+
if (bundleToKeep.internalizedAssets != null) {
|
|
1442
|
+
if (bundleToRemove.internalizedAssets != null) {
|
|
1443
|
+
bundleToKeep.internalizedAssets.intersect(
|
|
1444
|
+
bundleToRemove.internalizedAssets,
|
|
1445
|
+
);
|
|
1446
|
+
} else {
|
|
1447
|
+
bundleToKeep.internalizedAssets.clear();
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
} else {
|
|
1451
|
+
invariant(
|
|
1452
|
+
bundleToKeep.internalizedAssets && bundleToRemove.internalizedAssets,
|
|
1453
|
+
'All shared bundles should have internalized assets',
|
|
1454
|
+
);
|
|
1455
|
+
bundleToKeep.internalizedAssets.union(bundleToRemove.internalizedAssets);
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
// Merge and clean up source bundles
|
|
1281
1459
|
for (let sourceBundleId of bundleToRemove.sourceBundles) {
|
|
1282
1460
|
if (bundleToKeep.sourceBundles.has(sourceBundleId)) {
|
|
1283
1461
|
continue;
|
|
@@ -1287,21 +1465,108 @@ export function createIdealGraph(
|
|
|
1287
1465
|
bundleGraph.addEdge(sourceBundleId, bundleToKeepId);
|
|
1288
1466
|
}
|
|
1289
1467
|
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1468
|
+
if (getFeatureFlag('supportWebpackChunkName')) {
|
|
1469
|
+
bundleToKeep.sourceBundles.delete(bundleToRemoveId);
|
|
1470
|
+
|
|
1471
|
+
for (let bundle of bundleGraph.getNodeIdsConnectedFrom(
|
|
1472
|
+
bundleToRemoveId,
|
|
1473
|
+
)) {
|
|
1474
|
+
let bundleNode = nullthrows(bundleGraph.getNode(bundle));
|
|
1475
|
+
if (bundleNode === 'root') {
|
|
1476
|
+
continue;
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
// If the bundle is a source bundle, add it to the bundle to keep
|
|
1480
|
+
if (bundleNode.sourceBundles.has(bundleToRemoveId)) {
|
|
1481
|
+
bundleNode.sourceBundles.add(bundleToKeepId);
|
|
1482
|
+
bundleNode.sourceBundles.delete(bundleToRemoveId);
|
|
1483
|
+
bundleGraph.addEdge(bundleToKeepId, bundle);
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1487
|
+
// Merge bundle roots
|
|
1488
|
+
for (let bundleRoot of bundleToRemove.bundleRoots) {
|
|
1489
|
+
bundleToKeep.bundleRoots.add(bundleRoot);
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1492
|
+
if (bundleToRemove.mainEntryAsset != null) {
|
|
1493
|
+
invariant(bundleToKeep.mainEntryAsset != null);
|
|
1494
|
+
|
|
1495
|
+
// Merge the bundles in bundle group
|
|
1496
|
+
let bundlesInRemoveBundleGroup =
|
|
1497
|
+
getBundlesForBundleGroup(bundleToRemoveId);
|
|
1498
|
+
|
|
1499
|
+
for (let bundleIdInGroup of bundlesInRemoveBundleGroup) {
|
|
1500
|
+
if (bundleIdInGroup === bundleToRemoveId) {
|
|
1501
|
+
continue;
|
|
1502
|
+
}
|
|
1503
|
+
bundleGraph.addEdge(bundleToKeepId, bundleIdInGroup);
|
|
1504
|
+
}
|
|
1505
|
+
|
|
1506
|
+
// Remove old bundle group
|
|
1507
|
+
bundleGroupBundleIds.delete(bundleToRemoveId);
|
|
1508
|
+
|
|
1509
|
+
// Clean up bundle roots
|
|
1510
|
+
let bundleRootToRemoveNodeId = nullthrows(
|
|
1511
|
+
assetToBundleRootNodeId.get(
|
|
1512
|
+
nullthrows(bundleToRemove.mainEntryAsset),
|
|
1513
|
+
),
|
|
1295
1514
|
);
|
|
1296
|
-
|
|
1297
|
-
|
|
1515
|
+
let bundleRootToKeepNodeId = nullthrows(
|
|
1516
|
+
assetToBundleRootNodeId.get(nullthrows(bundleToKeep.mainEntryAsset)),
|
|
1517
|
+
);
|
|
1518
|
+
|
|
1519
|
+
for (let nodeId of bundleRootGraph.getNodeIdsConnectedTo(
|
|
1520
|
+
bundleRootToRemoveNodeId,
|
|
1521
|
+
)) {
|
|
1522
|
+
bundleRootGraph.addEdge(nodeId, bundleRootToKeepNodeId);
|
|
1523
|
+
bundleRootGraph.removeEdge(nodeId, bundleRootToRemoveNodeId);
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
for (let nodeId of bundleRootGraph.getNodeIdsConnectedFrom(
|
|
1527
|
+
bundleRootToRemoveNodeId,
|
|
1528
|
+
)) {
|
|
1529
|
+
bundleRootGraph.addEdge(bundleRootToKeepNodeId, nodeId);
|
|
1530
|
+
bundleRootGraph.removeEdge(bundleRootToRemoveNodeId, nodeId);
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
bundleRoots.set(nullthrows(bundleToRemove.mainEntryAsset), [
|
|
1534
|
+
bundleToKeepId,
|
|
1535
|
+
bundleToKeepId,
|
|
1536
|
+
]);
|
|
1537
|
+
|
|
1538
|
+
// Merge dependency bundle graph
|
|
1539
|
+
for (let dependencyNodeId of dependencyBundleGraph.getNodeIdsConnectedTo(
|
|
1540
|
+
dependencyBundleGraph.getNodeIdByContentKey(String(bundleToRemoveId)),
|
|
1541
|
+
ALL_EDGE_TYPES,
|
|
1542
|
+
)) {
|
|
1543
|
+
let dependencyNode = nullthrows(
|
|
1544
|
+
dependencyBundleGraph.getNode(dependencyNodeId),
|
|
1545
|
+
);
|
|
1546
|
+
invariant(dependencyNode.type === 'dependency');
|
|
1547
|
+
|
|
1548
|
+
// Add dependency to the bundle to keep
|
|
1549
|
+
dependencyBundleGraph.addEdge(
|
|
1550
|
+
dependencyNodeId,
|
|
1551
|
+
dependencyBundleGraph.getNodeIdByContentKey(String(bundleToKeepId)),
|
|
1552
|
+
dependencyPriorityEdges[dependencyNode.value.priority],
|
|
1553
|
+
);
|
|
1554
|
+
// Remove dependency from the bundle to remove
|
|
1555
|
+
dependencyBundleGraph.removeEdge(
|
|
1556
|
+
dependencyNodeId,
|
|
1557
|
+
dependencyBundleGraph.getNodeIdByContentKey(
|
|
1558
|
+
String(bundleToRemoveId),
|
|
1559
|
+
),
|
|
1560
|
+
dependencyPriorityEdges[dependencyNode.value.priority],
|
|
1561
|
+
);
|
|
1562
|
+
}
|
|
1298
1563
|
}
|
|
1299
1564
|
}
|
|
1300
1565
|
|
|
1301
1566
|
bundleGraph.removeNode(bundleToRemoveId);
|
|
1302
1567
|
}
|
|
1303
1568
|
|
|
1304
|
-
function mergeOverlapBundles() {
|
|
1569
|
+
function mergeOverlapBundles(mergeConfig: MergeCandidates) {
|
|
1305
1570
|
// Find all shared bundles
|
|
1306
1571
|
let sharedBundles = new Set<NodeId>();
|
|
1307
1572
|
bundleGraph.traverse((nodeId) => {
|
|
@@ -1331,22 +1596,44 @@ export function createIdealGraph(
|
|
|
1331
1596
|
let clusters = findMergeCandidates(
|
|
1332
1597
|
bundleGraph,
|
|
1333
1598
|
Array.from(sharedBundles),
|
|
1334
|
-
|
|
1599
|
+
mergeConfig.map(
|
|
1600
|
+
(config): MergeGroup => ({
|
|
1601
|
+
...config,
|
|
1602
|
+
sourceBundles: config.sourceBundles?.map((assetMatch: string) => {
|
|
1603
|
+
let sourceBundleNodeId = mergeSourceBundleLookup.get(assetMatch);
|
|
1604
|
+
|
|
1605
|
+
if (sourceBundleNodeId == null) {
|
|
1606
|
+
throw new Error(
|
|
1607
|
+
`Source bundle ${assetMatch} not found in merge source bundle lookup`,
|
|
1608
|
+
);
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
return sourceBundleNodeId;
|
|
1612
|
+
}),
|
|
1613
|
+
}),
|
|
1614
|
+
),
|
|
1335
1615
|
);
|
|
1336
1616
|
|
|
1617
|
+
let mergedBundles = new Set();
|
|
1618
|
+
|
|
1337
1619
|
for (let cluster of clusters) {
|
|
1338
1620
|
let [mergeTarget, ...rest] = cluster;
|
|
1339
1621
|
|
|
1340
1622
|
for (let bundleIdToMerge of rest) {
|
|
1341
|
-
mergeBundles(
|
|
1623
|
+
mergeBundles(mergeTarget, bundleIdToMerge);
|
|
1342
1624
|
}
|
|
1625
|
+
|
|
1626
|
+
mergedBundles.add(mergeTarget);
|
|
1627
|
+
}
|
|
1628
|
+
|
|
1629
|
+
if (getFeatureFlag('supportWebpackChunkName')) {
|
|
1630
|
+
return mergedBundles;
|
|
1343
1631
|
}
|
|
1344
1632
|
}
|
|
1345
1633
|
|
|
1346
|
-
function getBigIntFromContentKey(contentKey) {
|
|
1634
|
+
function getBigIntFromContentKey(contentKey: string) {
|
|
1347
1635
|
let b = Buffer.alloc(64);
|
|
1348
1636
|
b.write(contentKey);
|
|
1349
|
-
// $FlowFixMe Flow doesn't have BigInt types in this version
|
|
1350
1637
|
return b.readBigInt64BE();
|
|
1351
1638
|
}
|
|
1352
1639
|
// Fix asset order in source bundles as they are likely now incorrect after shared bundle deletion
|
|
@@ -1373,8 +1660,8 @@ export function createIdealGraph(
|
|
|
1373
1660
|
bundleRootGraph.removeNode(bundleRootId);
|
|
1374
1661
|
}
|
|
1375
1662
|
}
|
|
1376
|
-
function getBundlesForBundleGroup(bundleGroupId) {
|
|
1377
|
-
let bundlesInABundleGroup = [];
|
|
1663
|
+
function getBundlesForBundleGroup(bundleGroupId: NodeId) {
|
|
1664
|
+
let bundlesInABundleGroup: Array<NodeId> = [];
|
|
1378
1665
|
bundleGraph.traverse((nodeId) => {
|
|
1379
1666
|
bundlesInABundleGroup.push(nodeId);
|
|
1380
1667
|
}, bundleGroupId);
|
|
@@ -1455,23 +1742,24 @@ export function createIdealGraph(
|
|
|
1455
1742
|
};
|
|
1456
1743
|
}
|
|
1457
1744
|
|
|
1458
|
-
function createBundle(opts: {
|
|
1459
|
-
asset?: Asset
|
|
1460
|
-
bundleBehavior?:
|
|
1461
|
-
env?: Environment
|
|
1462
|
-
manualSharedBundle?:
|
|
1463
|
-
needsStableName?: boolean
|
|
1464
|
-
sourceBundles?: Set<NodeId
|
|
1465
|
-
target: Target
|
|
1466
|
-
type?: string
|
|
1467
|
-
uniqueKey?: string
|
|
1468
|
-
|
|
1745
|
+
function createBundle(opts: {
|
|
1746
|
+
asset?: Asset;
|
|
1747
|
+
bundleBehavior?: BundleBehavior | null | undefined;
|
|
1748
|
+
env?: Environment;
|
|
1749
|
+
manualSharedBundle?: string | null | undefined;
|
|
1750
|
+
needsStableName?: boolean;
|
|
1751
|
+
sourceBundles?: Set<NodeId>;
|
|
1752
|
+
target: Target;
|
|
1753
|
+
type?: string;
|
|
1754
|
+
uniqueKey?: string;
|
|
1755
|
+
}): Bundle {
|
|
1469
1756
|
if (opts.asset == null) {
|
|
1470
1757
|
return {
|
|
1471
1758
|
assets: new Set(),
|
|
1472
1759
|
bundleBehavior: opts.bundleBehavior,
|
|
1473
1760
|
env: nullthrows(opts.env),
|
|
1474
1761
|
mainEntryAsset: null,
|
|
1762
|
+
bundleRoots: new Set(),
|
|
1475
1763
|
manualSharedBundle: opts.manualSharedBundle,
|
|
1476
1764
|
needsStableName: Boolean(opts.needsStableName),
|
|
1477
1765
|
size: 0,
|
|
@@ -1488,6 +1776,7 @@ function createBundle(opts: {|
|
|
|
1488
1776
|
bundleBehavior: opts.bundleBehavior ?? asset.bundleBehavior,
|
|
1489
1777
|
env: opts.env ?? asset.env,
|
|
1490
1778
|
mainEntryAsset: asset,
|
|
1779
|
+
bundleRoots: new Set([asset]),
|
|
1491
1780
|
manualSharedBundle: opts.manualSharedBundle,
|
|
1492
1781
|
needsStableName: Boolean(opts.needsStableName),
|
|
1493
1782
|
size: asset.stats.size,
|