@atlaspack/bundler-default 2.14.5-canary.14 → 2.14.5-canary.141
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
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import invariant from 'assert';
|
|
2
|
+
import nullthrows from 'nullthrows';
|
|
3
|
+
import {ContentGraph} from '@atlaspack/graph';
|
|
4
|
+
import type {NodeId} from '@atlaspack/graph';
|
|
5
|
+
import {setUnion, setIntersectStatic} from '@atlaspack/utils';
|
|
6
|
+
import type {Bundle, IdealBundleGraph} from './idealGraph';
|
|
7
|
+
import {memoize, clearCaches} from './memoize';
|
|
8
|
+
|
|
9
|
+
function getBundlesForBundleGroup(
|
|
10
|
+
bundleGraph: IdealBundleGraph,
|
|
11
|
+
bundleGroupId: NodeId,
|
|
12
|
+
): number {
|
|
13
|
+
let count = 0;
|
|
14
|
+
bundleGraph.traverse((nodeId) => {
|
|
15
|
+
// @ts-expect-error TS2339
|
|
16
|
+
if (bundleGraph.getNode(nodeId)?.bundleBehavior !== 'inline') {
|
|
17
|
+
count++;
|
|
18
|
+
}
|
|
19
|
+
}, bundleGroupId);
|
|
20
|
+
return count;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let getBundleOverlap = (
|
|
24
|
+
sourceBundlesA: Set<NodeId>,
|
|
25
|
+
sourceBundlesB: Set<NodeId>,
|
|
26
|
+
): number => {
|
|
27
|
+
let allSourceBundles = setUnion(sourceBundlesA, sourceBundlesB);
|
|
28
|
+
let sharedSourceBundles = setIntersectStatic(sourceBundlesA, sourceBundlesB);
|
|
29
|
+
|
|
30
|
+
return sharedSourceBundles.size / allSourceBundles.size;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// Returns a decimal showing the proportion source bundles are common to
|
|
34
|
+
// both bundles versus the total number of source bundles.
|
|
35
|
+
function checkBundleThreshold(
|
|
36
|
+
bundleA: MergeCandidate,
|
|
37
|
+
bundleB: MergeCandidate,
|
|
38
|
+
threshold: number,
|
|
39
|
+
): boolean {
|
|
40
|
+
return (
|
|
41
|
+
getBundleOverlap(
|
|
42
|
+
bundleA.bundle.sourceBundles,
|
|
43
|
+
bundleB.bundle.sourceBundles,
|
|
44
|
+
) >= threshold
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let checkSharedSourceBundles = memoize(
|
|
49
|
+
(bundle: Bundle, importantAncestorBundles: Array<NodeId>): boolean => {
|
|
50
|
+
return importantAncestorBundles.every((ancestorId) =>
|
|
51
|
+
bundle.sourceBundles.has(ancestorId),
|
|
52
|
+
);
|
|
53
|
+
},
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
let hasSuitableBundleGroup = memoize(
|
|
57
|
+
(
|
|
58
|
+
bundleGraph: IdealBundleGraph,
|
|
59
|
+
bundle: Bundle,
|
|
60
|
+
minBundlesInGroup: number,
|
|
61
|
+
): boolean => {
|
|
62
|
+
for (let sourceBundle of bundle.sourceBundles) {
|
|
63
|
+
let bundlesInGroup = getBundlesForBundleGroup(bundleGraph, sourceBundle);
|
|
64
|
+
|
|
65
|
+
if (bundlesInGroup >= minBundlesInGroup) {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return false;
|
|
70
|
+
},
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
function validMerge(
|
|
74
|
+
bundleGraph: IdealBundleGraph,
|
|
75
|
+
config: MergeGroup,
|
|
76
|
+
bundleA: MergeCandidate,
|
|
77
|
+
bundleB: MergeCandidate,
|
|
78
|
+
): boolean {
|
|
79
|
+
if (config.maxBundleSize != null) {
|
|
80
|
+
if (
|
|
81
|
+
bundleA.bundle.size > config.maxBundleSize ||
|
|
82
|
+
bundleB.bundle.size > config.maxBundleSize
|
|
83
|
+
) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (config.overlapThreshold != null) {
|
|
89
|
+
if (!checkBundleThreshold(bundleA, bundleB, config.overlapThreshold)) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (config.sourceBundles != null) {
|
|
95
|
+
if (
|
|
96
|
+
!checkSharedSourceBundles(bundleA.bundle, config.sourceBundles) ||
|
|
97
|
+
!checkSharedSourceBundles(bundleB.bundle, config.sourceBundles)
|
|
98
|
+
) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (config.minBundlesInGroup != null) {
|
|
104
|
+
if (
|
|
105
|
+
!hasSuitableBundleGroup(
|
|
106
|
+
bundleGraph,
|
|
107
|
+
bundleA.bundle,
|
|
108
|
+
config.minBundlesInGroup,
|
|
109
|
+
) ||
|
|
110
|
+
!hasSuitableBundleGroup(
|
|
111
|
+
bundleGraph,
|
|
112
|
+
bundleB.bundle,
|
|
113
|
+
config.minBundlesInGroup,
|
|
114
|
+
)
|
|
115
|
+
) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function getMergeClusters(
|
|
124
|
+
graph: ContentGraph<NodeId, EdgeType>,
|
|
125
|
+
candidates: Map<NodeId, EdgeType>,
|
|
126
|
+
): Array<Array<NodeId>> {
|
|
127
|
+
let clusters: Array<Array<NodeId>> = [];
|
|
128
|
+
|
|
129
|
+
for (let [candidate, edgeType] of candidates.entries()) {
|
|
130
|
+
let cluster: Array<NodeId> = [];
|
|
131
|
+
|
|
132
|
+
graph.traverse(
|
|
133
|
+
(nodeId) => {
|
|
134
|
+
cluster.push(nullthrows(graph.getNode(nodeId)));
|
|
135
|
+
// Remove node from candidates as it has already been processed
|
|
136
|
+
candidates.delete(nodeId);
|
|
137
|
+
},
|
|
138
|
+
candidate,
|
|
139
|
+
edgeType,
|
|
140
|
+
);
|
|
141
|
+
clusters.push(cluster);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return clusters;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
type MergeCandidate = {
|
|
148
|
+
bundle: Bundle;
|
|
149
|
+
id: NodeId;
|
|
150
|
+
contentKey: string;
|
|
151
|
+
};
|
|
152
|
+
function getPossibleMergeCandidates(
|
|
153
|
+
bundleGraph: IdealBundleGraph,
|
|
154
|
+
bundles: Array<NodeId>,
|
|
155
|
+
): Array<[MergeCandidate, MergeCandidate]> {
|
|
156
|
+
let mergeCandidates = bundles.map((bundleId) => {
|
|
157
|
+
let bundle = bundleGraph.getNode(bundleId);
|
|
158
|
+
invariant(bundle && bundle !== 'root', 'Bundle should exist');
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
id: bundleId,
|
|
162
|
+
bundle,
|
|
163
|
+
contentKey: bundleId.toString(),
|
|
164
|
+
};
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
const uniquePairs: Array<[MergeCandidate, MergeCandidate]> = [];
|
|
168
|
+
|
|
169
|
+
for (let i = 0; i < mergeCandidates.length; i++) {
|
|
170
|
+
for (let j = i + 1; j < mergeCandidates.length; j++) {
|
|
171
|
+
let a = mergeCandidates[i];
|
|
172
|
+
let b = mergeCandidates[j];
|
|
173
|
+
|
|
174
|
+
// @ts-expect-error TS18048
|
|
175
|
+
if (a.bundle.internalizedAssets.equals(b.bundle.internalizedAssets)) {
|
|
176
|
+
uniquePairs.push([a, b]);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return uniquePairs;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export type MergeGroup = {
|
|
184
|
+
overlapThreshold?: number;
|
|
185
|
+
maxBundleSize?: number;
|
|
186
|
+
sourceBundles?: Array<NodeId>;
|
|
187
|
+
minBundlesInGroup?: number;
|
|
188
|
+
};
|
|
189
|
+
type EdgeType = number;
|
|
190
|
+
|
|
191
|
+
export function findMergeCandidates(
|
|
192
|
+
bundleGraph: IdealBundleGraph,
|
|
193
|
+
bundles: Array<NodeId>,
|
|
194
|
+
config: Array<MergeGroup>,
|
|
195
|
+
): Array<Array<NodeId>> {
|
|
196
|
+
let graph = new ContentGraph<NodeId, EdgeType>();
|
|
197
|
+
let candidates = new Map<NodeId, EdgeType>();
|
|
198
|
+
|
|
199
|
+
let allPossibleMergeCandidates = getPossibleMergeCandidates(
|
|
200
|
+
bundleGraph,
|
|
201
|
+
bundles,
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
// Build graph of clustered merge candidates
|
|
205
|
+
for (let i = 0; i < config.length; i++) {
|
|
206
|
+
// Ensure edge type coresponds to config index
|
|
207
|
+
let edgeType = i + 1;
|
|
208
|
+
|
|
209
|
+
for (let group of allPossibleMergeCandidates) {
|
|
210
|
+
let candidateA = group[0];
|
|
211
|
+
let candidateB = group[1];
|
|
212
|
+
|
|
213
|
+
if (!validMerge(bundleGraph, config[i], candidateA, candidateB)) {
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
let bundleNode = graph.addNodeByContentKeyIfNeeded(
|
|
218
|
+
candidateA.contentKey,
|
|
219
|
+
candidateA.id,
|
|
220
|
+
);
|
|
221
|
+
let otherBundleNode = graph.addNodeByContentKeyIfNeeded(
|
|
222
|
+
candidateB.contentKey,
|
|
223
|
+
candidateB.id,
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
// Add edge in both directions
|
|
227
|
+
graph.addEdge(bundleNode, otherBundleNode, edgeType);
|
|
228
|
+
graph.addEdge(otherBundleNode, bundleNode, edgeType);
|
|
229
|
+
|
|
230
|
+
candidates.set(bundleNode, edgeType);
|
|
231
|
+
candidates.set(otherBundleNode, edgeType);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Remove bundles that have been allocated to a higher priority merge
|
|
235
|
+
allPossibleMergeCandidates = allPossibleMergeCandidates.filter(
|
|
236
|
+
(group) =>
|
|
237
|
+
!graph.hasContentKey(group[0].contentKey) &&
|
|
238
|
+
!graph.hasContentKey(group[1].contentKey),
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
clearCaches();
|
|
243
|
+
|
|
244
|
+
return getMergeClusters(graph, candidates);
|
|
245
|
+
}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// @flow strict-local
|
|
2
|
-
|
|
3
1
|
import {encodeJSONKeyComponent} from '@atlaspack/diagnostic';
|
|
4
2
|
import type {
|
|
5
3
|
Config,
|
|
@@ -7,55 +5,63 @@ import type {
|
|
|
7
5
|
BuildMode,
|
|
8
6
|
PluginLogger,
|
|
9
7
|
} from '@atlaspack/types';
|
|
10
|
-
import {
|
|
8
|
+
import {getFeatureFlag} from '@atlaspack/feature-flags';
|
|
9
|
+
import {SchemaEntity, validateSchema} from '@atlaspack/utils';
|
|
11
10
|
import invariant from 'assert';
|
|
12
11
|
|
|
13
12
|
type Glob = string;
|
|
14
13
|
|
|
15
|
-
type ManualSharedBundles = Array<{
|
|
16
|
-
name: string
|
|
17
|
-
assets: Array<Glob
|
|
18
|
-
types?: Array<string
|
|
19
|
-
root?: string
|
|
20
|
-
split?: number
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
type
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
14
|
+
type ManualSharedBundles = Array<{
|
|
15
|
+
name: string;
|
|
16
|
+
assets: Array<Glob>;
|
|
17
|
+
types?: Array<string>;
|
|
18
|
+
root?: string;
|
|
19
|
+
split?: number;
|
|
20
|
+
}>;
|
|
21
|
+
|
|
22
|
+
export type MergeCandidates = Array<{
|
|
23
|
+
overlapThreshold?: number;
|
|
24
|
+
maxBundleSize?: number;
|
|
25
|
+
sourceBundles?: Array<string>;
|
|
26
|
+
minBundlesInGroup?: number;
|
|
27
|
+
}>;
|
|
28
|
+
|
|
29
|
+
type BaseBundlerConfig = {
|
|
30
|
+
http?: number;
|
|
31
|
+
minBundles?: number;
|
|
32
|
+
minBundleSize?: number;
|
|
33
|
+
maxParallelRequests?: number;
|
|
34
|
+
disableSharedBundles?: boolean;
|
|
35
|
+
manualSharedBundles?: ManualSharedBundles;
|
|
36
|
+
loadConditionalBundlesInParallel?: boolean;
|
|
37
|
+
sharedBundleMerge?: MergeCandidates;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
type BundlerConfig = Partial<Record<BuildMode, BaseBundlerConfig>> &
|
|
41
|
+
BaseBundlerConfig;
|
|
42
|
+
|
|
43
|
+
export type ResolvedBundlerConfig = {
|
|
44
|
+
minBundles: number;
|
|
45
|
+
minBundleSize: number;
|
|
46
|
+
maxParallelRequests: number;
|
|
47
|
+
projectRoot: string;
|
|
48
|
+
disableSharedBundles: boolean;
|
|
49
|
+
manualSharedBundles: ManualSharedBundles;
|
|
50
|
+
loadConditionalBundlesInParallel?: boolean;
|
|
51
|
+
sharedBundleMerge?: MergeCandidates;
|
|
52
|
+
};
|
|
48
53
|
|
|
49
54
|
function resolveModeConfig(
|
|
50
55
|
config: BundlerConfig,
|
|
51
56
|
mode: BuildMode,
|
|
52
57
|
): BaseBundlerConfig {
|
|
53
|
-
let generalConfig = {};
|
|
54
|
-
let modeConfig = {};
|
|
58
|
+
let generalConfig: Record<string, any> = {};
|
|
59
|
+
let modeConfig: Record<string, any> = {};
|
|
55
60
|
|
|
56
61
|
for (const key of Object.keys(config)) {
|
|
57
62
|
if (key === 'development' || key === 'production') {
|
|
58
63
|
if (key === mode) {
|
|
64
|
+
// @ts-expect-error TS2322
|
|
59
65
|
modeConfig = config[key];
|
|
60
66
|
}
|
|
61
67
|
} else {
|
|
@@ -63,7 +69,6 @@ function resolveModeConfig(
|
|
|
63
69
|
}
|
|
64
70
|
}
|
|
65
71
|
|
|
66
|
-
// $FlowFixMe Not sure how to convince flow here...
|
|
67
72
|
return {
|
|
68
73
|
...generalConfig,
|
|
69
74
|
...modeConfig,
|
|
@@ -78,7 +83,7 @@ const HTTP_OPTIONS = {
|
|
|
78
83
|
minBundleSize: 30000,
|
|
79
84
|
maxParallelRequests: 6,
|
|
80
85
|
disableSharedBundles: false,
|
|
81
|
-
|
|
86
|
+
sharedBundleMerge: [],
|
|
82
87
|
},
|
|
83
88
|
'2': {
|
|
84
89
|
minBundles: 1,
|
|
@@ -86,9 +91,9 @@ const HTTP_OPTIONS = {
|
|
|
86
91
|
minBundleSize: 20000,
|
|
87
92
|
maxParallelRequests: 25,
|
|
88
93
|
disableSharedBundles: false,
|
|
89
|
-
|
|
94
|
+
sharedBundleMerge: [],
|
|
90
95
|
},
|
|
91
|
-
};
|
|
96
|
+
} as const;
|
|
92
97
|
|
|
93
98
|
const CONFIG_SCHEMA: SchemaEntity = {
|
|
94
99
|
type: 'object',
|
|
@@ -128,6 +133,30 @@ const CONFIG_SCHEMA: SchemaEntity = {
|
|
|
128
133
|
additionalProperties: false,
|
|
129
134
|
},
|
|
130
135
|
},
|
|
136
|
+
sharedBundleMerge: {
|
|
137
|
+
type: 'array',
|
|
138
|
+
items: {
|
|
139
|
+
type: 'object',
|
|
140
|
+
properties: {
|
|
141
|
+
overlapThreshold: {
|
|
142
|
+
type: 'number',
|
|
143
|
+
},
|
|
144
|
+
maxBundleSize: {
|
|
145
|
+
type: 'number',
|
|
146
|
+
},
|
|
147
|
+
sourceBundles: {
|
|
148
|
+
type: 'array',
|
|
149
|
+
items: {
|
|
150
|
+
type: 'string',
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
minBundlesInGroup: {
|
|
154
|
+
type: 'number',
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
additionalProperties: false,
|
|
158
|
+
},
|
|
159
|
+
},
|
|
131
160
|
minBundles: {
|
|
132
161
|
type: 'number',
|
|
133
162
|
},
|
|
@@ -155,15 +184,24 @@ export async function loadBundlerConfig(
|
|
|
155
184
|
options: PluginOptions,
|
|
156
185
|
logger: PluginLogger,
|
|
157
186
|
): Promise<ResolvedBundlerConfig> {
|
|
158
|
-
let conf
|
|
159
|
-
|
|
160
|
-
|
|
187
|
+
let conf;
|
|
188
|
+
|
|
189
|
+
if (getFeatureFlag('resolveBundlerConfigFromCwd')) {
|
|
190
|
+
conf = await config.getConfigFrom(`${process.cwd()}/index`, [], {
|
|
191
|
+
packageKey: '@atlaspack/bundler-default',
|
|
192
|
+
});
|
|
193
|
+
} else {
|
|
194
|
+
conf = await config.getConfig<BundlerConfig>([], {
|
|
195
|
+
packageKey: '@atlaspack/bundler-default',
|
|
196
|
+
});
|
|
197
|
+
}
|
|
161
198
|
|
|
162
199
|
if (!conf) {
|
|
163
200
|
const modDefault = {
|
|
164
201
|
...HTTP_OPTIONS['2'],
|
|
165
202
|
projectRoot: options.projectRoot,
|
|
166
|
-
};
|
|
203
|
+
} as const;
|
|
204
|
+
// @ts-expect-error TS2322
|
|
167
205
|
return modDefault;
|
|
168
206
|
}
|
|
169
207
|
|
|
@@ -226,14 +264,14 @@ export async function loadBundlerConfig(
|
|
|
226
264
|
);
|
|
227
265
|
|
|
228
266
|
let http = modeConfig.http ?? 2;
|
|
267
|
+
// @ts-expect-error TS7053
|
|
229
268
|
let defaults = HTTP_OPTIONS[http];
|
|
230
269
|
|
|
231
270
|
return {
|
|
232
271
|
minBundles: modeConfig.minBundles ?? defaults.minBundles,
|
|
233
272
|
minBundleSize: modeConfig.minBundleSize ?? defaults.minBundleSize,
|
|
234
|
-
|
|
235
|
-
modeConfig.
|
|
236
|
-
defaults.sharedBundleMergeThreshold,
|
|
273
|
+
sharedBundleMerge:
|
|
274
|
+
modeConfig.sharedBundleMerge ?? defaults.sharedBundleMerge,
|
|
237
275
|
maxParallelRequests:
|
|
238
276
|
modeConfig.maxParallelRequests ?? defaults.maxParallelRequests,
|
|
239
277
|
projectRoot: options.projectRoot,
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import {ALL_EDGE_TYPES, type NodeId} from '@atlaspack/graph';
|
|
1
|
+
import {ALL_EDGE_TYPES, NodeId} from '@atlaspack/graph';
|
|
4
2
|
import type {
|
|
5
3
|
Bundle as LegacyBundle,
|
|
6
4
|
BundleGroup,
|
|
@@ -25,11 +23,13 @@ export function decorateLegacyGraph(
|
|
|
25
23
|
bundleGroupBundleIds,
|
|
26
24
|
manualAssetToBundle,
|
|
27
25
|
} = idealGraph;
|
|
26
|
+
// This line can be deleted once supportWebpackChunkName feature flag is removed.
|
|
28
27
|
let entryBundleToBundleGroup: Map<NodeId, BundleGroup> = new Map();
|
|
29
28
|
// Step Create Bundles: Create bundle groups, bundles, and shared bundles and add assets to them
|
|
30
29
|
for (let [bundleNodeId, idealBundle] of idealBundleGraph.nodes.entries()) {
|
|
31
30
|
if (!idealBundle || idealBundle === 'root') continue;
|
|
32
31
|
let entryAsset = idealBundle.mainEntryAsset;
|
|
32
|
+
// This line can be deleted once supportWebpackChunkName feature flag is removed.
|
|
33
33
|
let bundleGroup;
|
|
34
34
|
let bundle;
|
|
35
35
|
|
|
@@ -52,18 +52,26 @@ export function decorateLegacyGraph(
|
|
|
52
52
|
entryAsset != null,
|
|
53
53
|
'Processing a bundleGroup with no entry asset',
|
|
54
54
|
);
|
|
55
|
+
|
|
56
|
+
let bundleGroups = new Map();
|
|
55
57
|
for (let dependency of dependencies) {
|
|
56
58
|
bundleGroup = bundleGraph.createBundleGroup(
|
|
57
59
|
dependency,
|
|
58
60
|
idealBundle.target,
|
|
59
61
|
);
|
|
62
|
+
bundleGroups.set(bundleGroup.entryAssetId, bundleGroup);
|
|
63
|
+
}
|
|
64
|
+
if (getFeatureFlag('supportWebpackChunkName')) {
|
|
65
|
+
invariant(bundleGroups.size > 0, 'No bundle groups created');
|
|
66
|
+
} else {
|
|
67
|
+
invariant(bundleGroup);
|
|
68
|
+
entryBundleToBundleGroup.set(bundleNodeId, bundleGroup);
|
|
60
69
|
}
|
|
61
|
-
invariant(bundleGroup);
|
|
62
|
-
entryBundleToBundleGroup.set(bundleNodeId, bundleGroup);
|
|
63
70
|
|
|
64
71
|
bundle = nullthrows(
|
|
65
72
|
bundleGraph.createBundle({
|
|
66
73
|
entryAsset: nullthrows(entryAsset),
|
|
74
|
+
bundleRoots: Array.from(idealBundle.bundleRoots),
|
|
67
75
|
needsStableName: idealBundle.needsStableName,
|
|
68
76
|
bundleBehavior: idealBundle.bundleBehavior,
|
|
69
77
|
target: idealBundle.target,
|
|
@@ -71,7 +79,14 @@ export function decorateLegacyGraph(
|
|
|
71
79
|
}),
|
|
72
80
|
);
|
|
73
81
|
|
|
74
|
-
|
|
82
|
+
if (getFeatureFlag('supportWebpackChunkName')) {
|
|
83
|
+
for (let bundleGroup of bundleGroups.values()) {
|
|
84
|
+
bundleGraph.addBundleToBundleGroup(bundle, bundleGroup);
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
invariant(bundleGroup);
|
|
88
|
+
bundleGraph.addBundleToBundleGroup(bundle, bundleGroup);
|
|
89
|
+
}
|
|
75
90
|
} else if (
|
|
76
91
|
idealBundle.sourceBundles.size > 0 &&
|
|
77
92
|
!idealBundle.mainEntryAsset
|
|
@@ -109,6 +124,7 @@ export function decorateLegacyGraph(
|
|
|
109
124
|
bundle = nullthrows(
|
|
110
125
|
bundleGraph.createBundle({
|
|
111
126
|
entryAsset,
|
|
127
|
+
bundleRoots: Array.from(idealBundle.bundleRoots),
|
|
112
128
|
needsStableName: idealBundle.needsStableName,
|
|
113
129
|
bundleBehavior: idealBundle.bundleBehavior,
|
|
114
130
|
target: idealBundle.target,
|
|
@@ -195,11 +211,13 @@ export function decorateLegacyGraph(
|
|
|
195
211
|
}
|
|
196
212
|
}
|
|
197
213
|
|
|
214
|
+
// @ts-expect-error TS2488
|
|
198
215
|
for (let {type, from, to} of idealBundleGraph.getAllEdges()) {
|
|
199
216
|
let sourceBundle = nullthrows(idealBundleGraph.getNode(from));
|
|
200
217
|
if (sourceBundle === 'root') {
|
|
201
218
|
continue;
|
|
202
219
|
}
|
|
220
|
+
// @ts-expect-error TS2367
|
|
203
221
|
invariant(sourceBundle !== 'root');
|
|
204
222
|
|
|
205
223
|
let legacySourceBundle = nullthrows(
|
|
@@ -210,6 +228,7 @@ export function decorateLegacyGraph(
|
|
|
210
228
|
if (targetBundle === 'root') {
|
|
211
229
|
continue;
|
|
212
230
|
}
|
|
231
|
+
// @ts-expect-error TS2367
|
|
213
232
|
invariant(targetBundle !== 'root');
|
|
214
233
|
let legacyTargetBundle = nullthrows(
|
|
215
234
|
idealBundleToLegacyBundle.get(targetBundle),
|