@atlaspack/bundler-default 2.14.5-canary.138 → 2.14.5-canary.139
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/DefaultBundler.d.ts +18 -0
- package/lib/DefaultBundler.js +7 -4
- package/lib/MonolithicBundler.d.ts +2 -0
- package/lib/bundleMerge.d.ts +9 -0
- package/lib/bundleMerge.js +4 -3
- package/lib/bundlerConfig.d.ts +27 -0
- package/lib/bundlerConfig.js +3 -2
- package/lib/decorateLegacyGraph.d.ts +3 -0
- package/lib/decorateLegacyGraph.js +4 -0
- package/lib/idealGraph.d.ts +40 -0
- package/lib/idealGraph.js +32 -5
- package/lib/memoize.d.ts +2 -0
- package/lib/memoize.js +1 -2
- package/package.json +15 -11
- package/src/{DefaultBundler.js → DefaultBundler.ts} +21 -7
- package/src/{MonolithicBundler.js → MonolithicBundler.ts} +0 -1
- package/src/{bundleMerge.js → bundleMerge.ts} +16 -19
- package/src/{bundlerConfig.js → bundlerConfig.ts} +43 -44
- package/src/{decorateLegacyGraph.js → decorateLegacyGraph.ts} +4 -3
- package/src/{idealGraph.js → idealGraph.ts} +120 -80
- package/src/{memoize.js → memoize.ts} +3 -6
- package/tsconfig.json +4 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Bundler } from '@atlaspack/plugin';
|
|
2
|
+
/**
|
|
3
|
+
*
|
|
4
|
+
* The Bundler works by creating an IdealGraph, which contains a BundleGraph that models bundles
|
|
5
|
+
* connected to other bundles by what references them, and thus models BundleGroups.
|
|
6
|
+
*
|
|
7
|
+
* First, we enter `bundle({bundleGraph, config})`. Here, "bundleGraph" is actually just the
|
|
8
|
+
* assetGraph turned into a type `MutableBundleGraph`, which will then be mutated in decorate,
|
|
9
|
+
* and turned into what we expect the bundleGraph to be as per the old (default) bundler structure
|
|
10
|
+
* & what the rest of Atlaspack expects a BundleGraph to be.
|
|
11
|
+
*
|
|
12
|
+
* `bundle({bundleGraph, config})` First gets a Mapping of target to entries, In most cases there is
|
|
13
|
+
* only one target, and one or more entries. (Targets are pertinent in monorepos or projects where you
|
|
14
|
+
* will have two or more distDirs, or output folders.) Then calls create IdealGraph and Decorate per target.
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
declare const _default: Bundler<unknown>;
|
|
18
|
+
export default _default;
|
package/lib/DefaultBundler.js
CHANGED
|
@@ -59,6 +59,7 @@ var _default = exports.default = new (_plugin().Bundler)({
|
|
|
59
59
|
logger
|
|
60
60
|
}) {
|
|
61
61
|
let targetMap = getEntryByTarget(bundleGraph); // Organize entries by target output folder/ distDir
|
|
62
|
+
// @ts-expect-error TS2304
|
|
62
63
|
let graphs = [];
|
|
63
64
|
for (let entries of targetMap.values()) {
|
|
64
65
|
let singleFileEntries = new Map();
|
|
@@ -75,9 +76,7 @@ var _default = exports.default = new (_plugin().Bundler)({
|
|
|
75
76
|
}
|
|
76
77
|
|
|
77
78
|
// Create separate bundleGraphs per distDir
|
|
78
|
-
graphs.push(
|
|
79
|
-
// $FlowFixMe
|
|
80
|
-
(0, _idealGraph.createIdealGraph)(bundleGraph, config, idealGraphEntries, logger));
|
|
79
|
+
graphs.push((0, _idealGraph.createIdealGraph)(bundleGraph, config, idealGraphEntries, logger));
|
|
81
80
|
|
|
82
81
|
// Do this after the ideal graph so that the mutation of the bundleGraph doesn't
|
|
83
82
|
// interfere with the main bundling algorithm
|
|
@@ -96,7 +95,11 @@ function getEntryByTarget(bundleGraph) {
|
|
|
96
95
|
// Find entries from assetGraph per target
|
|
97
96
|
let targets = new (_utils().DefaultMap)(() => new Map());
|
|
98
97
|
bundleGraph.traverse({
|
|
99
|
-
enter(
|
|
98
|
+
enter(
|
|
99
|
+
// @ts-expect-error TS2304
|
|
100
|
+
node, context,
|
|
101
|
+
// @ts-expect-error TS2304
|
|
102
|
+
actions) {
|
|
100
103
|
if (node.type !== 'asset') {
|
|
101
104
|
return node;
|
|
102
105
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { NodeId } from '@atlaspack/graph';
|
|
2
|
+
import type { IdealBundleGraph } from './idealGraph';
|
|
3
|
+
export type MergeGroup = {
|
|
4
|
+
overlapThreshold?: number;
|
|
5
|
+
maxBundleSize?: number;
|
|
6
|
+
sourceBundles?: Array<NodeId>;
|
|
7
|
+
minBundlesInGroup?: number;
|
|
8
|
+
};
|
|
9
|
+
export declare function findMergeCandidates(bundleGraph: IdealBundleGraph, bundles: Array<NodeId>, config: Array<MergeGroup>): Array<Array<NodeId>>;
|
package/lib/bundleMerge.js
CHANGED
|
@@ -38,6 +38,7 @@ function getBundlesForBundleGroup(bundleGraph, bundleGroupId) {
|
|
|
38
38
|
let count = 0;
|
|
39
39
|
bundleGraph.traverse(nodeId => {
|
|
40
40
|
var _bundleGraph$getNode;
|
|
41
|
+
// @ts-expect-error TS2339
|
|
41
42
|
if (((_bundleGraph$getNode = bundleGraph.getNode(nodeId)) === null || _bundleGraph$getNode === void 0 ? void 0 : _bundleGraph$getNode.bundleBehavior) !== 'inline') {
|
|
42
43
|
count++;
|
|
43
44
|
}
|
|
@@ -118,9 +119,9 @@ function getPossibleMergeCandidates(bundleGraph, bundles) {
|
|
|
118
119
|
for (let j = i + 1; j < mergeCandidates.length; j++) {
|
|
119
120
|
let a = mergeCandidates[i];
|
|
120
121
|
let b = mergeCandidates[j];
|
|
121
|
-
|
|
122
|
-
//
|
|
123
|
-
a.bundle.internalizedAssets.equals(b.bundle.internalizedAssets)) {
|
|
122
|
+
|
|
123
|
+
// @ts-expect-error TS18048
|
|
124
|
+
if (a.bundle.internalizedAssets.equals(b.bundle.internalizedAssets)) {
|
|
124
125
|
uniquePairs.push([a, b]);
|
|
125
126
|
}
|
|
126
127
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Config, PluginOptions, PluginLogger } from '@atlaspack/types';
|
|
2
|
+
type Glob = string;
|
|
3
|
+
type ManualSharedBundles = Array<{
|
|
4
|
+
name: string;
|
|
5
|
+
assets: Array<Glob>;
|
|
6
|
+
types?: Array<string>;
|
|
7
|
+
root?: string;
|
|
8
|
+
split?: number;
|
|
9
|
+
}>;
|
|
10
|
+
export type MergeCandidates = Array<{
|
|
11
|
+
overlapThreshold?: number;
|
|
12
|
+
maxBundleSize?: number;
|
|
13
|
+
sourceBundles?: Array<string>;
|
|
14
|
+
minBundlesInGroup?: number;
|
|
15
|
+
}>;
|
|
16
|
+
export type ResolvedBundlerConfig = {
|
|
17
|
+
minBundles: number;
|
|
18
|
+
minBundleSize: number;
|
|
19
|
+
maxParallelRequests: number;
|
|
20
|
+
projectRoot: string;
|
|
21
|
+
disableSharedBundles: boolean;
|
|
22
|
+
manualSharedBundles: ManualSharedBundles;
|
|
23
|
+
loadConditionalBundlesInParallel?: boolean;
|
|
24
|
+
sharedBundleMerge?: MergeCandidates;
|
|
25
|
+
};
|
|
26
|
+
export declare function loadBundlerConfig(config: Config, options: PluginOptions, logger: PluginLogger): Promise<ResolvedBundlerConfig>;
|
|
27
|
+
export {};
|
package/lib/bundlerConfig.js
CHANGED
|
@@ -39,14 +39,13 @@ function resolveModeConfig(config, mode) {
|
|
|
39
39
|
for (const key of Object.keys(config)) {
|
|
40
40
|
if (key === 'development' || key === 'production') {
|
|
41
41
|
if (key === mode) {
|
|
42
|
+
// @ts-expect-error TS2322
|
|
42
43
|
modeConfig = config[key];
|
|
43
44
|
}
|
|
44
45
|
} else {
|
|
45
46
|
generalConfig[key] = config[key];
|
|
46
47
|
}
|
|
47
48
|
}
|
|
48
|
-
|
|
49
|
-
// $FlowFixMe Not sure how to convince flow here...
|
|
50
49
|
return {
|
|
51
50
|
...generalConfig,
|
|
52
51
|
...modeConfig
|
|
@@ -172,6 +171,7 @@ async function loadBundlerConfig(config, options, logger) {
|
|
|
172
171
|
...HTTP_OPTIONS['2'],
|
|
173
172
|
projectRoot: options.projectRoot
|
|
174
173
|
};
|
|
174
|
+
// @ts-expect-error TS2322
|
|
175
175
|
return modDefault;
|
|
176
176
|
}
|
|
177
177
|
(0, _assert().default)(((_conf = conf) === null || _conf === void 0 ? void 0 : _conf.contents) != null);
|
|
@@ -212,6 +212,7 @@ async function loadBundlerConfig(config, options, logger) {
|
|
|
212
212
|
prependKey: `/${(0, _diagnostic().encodeJSONKeyComponent)('@atlaspack/bundler-default')}`
|
|
213
213
|
}, '@atlaspack/bundler-default', 'Invalid config for @atlaspack/bundler-default');
|
|
214
214
|
let http = modeConfig.http ?? 2;
|
|
215
|
+
// @ts-expect-error TS7053
|
|
215
216
|
let defaults = HTTP_OPTIONS[http];
|
|
216
217
|
return {
|
|
217
218
|
minBundles: modeConfig.minBundles ?? defaults.minBundles,
|
|
@@ -179,6 +179,8 @@ function decorateLegacyGraph(idealGraph, bundleGraph) {
|
|
|
179
179
|
bundleGraph.createAssetReference(dependency, asset, legacyBundle);
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
|
+
|
|
183
|
+
// @ts-expect-error TS2488
|
|
182
184
|
for (let {
|
|
183
185
|
type,
|
|
184
186
|
from,
|
|
@@ -188,12 +190,14 @@ function decorateLegacyGraph(idealGraph, bundleGraph) {
|
|
|
188
190
|
if (sourceBundle === 'root') {
|
|
189
191
|
continue;
|
|
190
192
|
}
|
|
193
|
+
// @ts-expect-error TS2367
|
|
191
194
|
(0, _assert().default)(sourceBundle !== 'root');
|
|
192
195
|
let legacySourceBundle = (0, _nullthrows().default)(idealBundleToLegacyBundle.get(sourceBundle));
|
|
193
196
|
let targetBundle = (0, _nullthrows().default)(idealBundleGraph.getNode(to));
|
|
194
197
|
if (targetBundle === 'root') {
|
|
195
198
|
continue;
|
|
196
199
|
}
|
|
200
|
+
// @ts-expect-error TS2367
|
|
197
201
|
(0, _assert().default)(targetBundle !== 'root');
|
|
198
202
|
let legacyTargetBundle = (0, _nullthrows().default)(idealBundleToLegacyBundle.get(targetBundle));
|
|
199
203
|
if ((0, _featureFlags().getFeatureFlag)('conditionalBundlingApi') && type === _idealGraph.idealBundleGraphEdges.conditional) {
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { BitSet, ContentGraph, Graph, NodeId } from '@atlaspack/graph';
|
|
2
|
+
import type { Asset, BundleBehavior, Dependency, Environment, MutableBundleGraph, Target, PluginLogger } from '@atlaspack/types';
|
|
3
|
+
import { DefaultMap } from '@atlaspack/utils';
|
|
4
|
+
import type { ResolvedBundlerConfig } from './bundlerConfig';
|
|
5
|
+
export type Bundle = {
|
|
6
|
+
uniqueKey: string | null | undefined;
|
|
7
|
+
assets: Set<Asset>;
|
|
8
|
+
internalizedAssets?: BitSet;
|
|
9
|
+
bundleBehavior?: BundleBehavior | null | undefined;
|
|
10
|
+
needsStableName: boolean;
|
|
11
|
+
mainEntryAsset: Asset | null | undefined;
|
|
12
|
+
bundleRoots: Set<Asset>;
|
|
13
|
+
size: number;
|
|
14
|
+
sourceBundles: Set<NodeId>;
|
|
15
|
+
target: Target;
|
|
16
|
+
env: Environment;
|
|
17
|
+
type: string;
|
|
18
|
+
manualSharedBundle: string | null | undefined;
|
|
19
|
+
};
|
|
20
|
+
export type DependencyBundleGraph = ContentGraph<{
|
|
21
|
+
value: Bundle;
|
|
22
|
+
type: 'bundle';
|
|
23
|
+
} | {
|
|
24
|
+
value: Dependency;
|
|
25
|
+
type: 'dependency';
|
|
26
|
+
}, number>;
|
|
27
|
+
export declare const idealBundleGraphEdges: Readonly<{
|
|
28
|
+
default: 1;
|
|
29
|
+
conditional: 2;
|
|
30
|
+
}>;
|
|
31
|
+
export type IdealBundleGraph = Graph<Bundle | 'root', (typeof idealBundleGraphEdges)[keyof typeof idealBundleGraphEdges]>;
|
|
32
|
+
export type IdealGraph = {
|
|
33
|
+
assetReference: DefaultMap<Asset, Array<[Dependency, Bundle]>>;
|
|
34
|
+
assets: Array<Asset>;
|
|
35
|
+
bundleGraph: IdealBundleGraph;
|
|
36
|
+
bundleGroupBundleIds: Set<NodeId>;
|
|
37
|
+
dependencyBundleGraph: DependencyBundleGraph;
|
|
38
|
+
manualAssetToBundle: Map<Asset, NodeId>;
|
|
39
|
+
};
|
|
40
|
+
export declare function createIdealGraph(assetGraph: MutableBundleGraph, config: ResolvedBundlerConfig, entries: Map<Asset, Dependency>, logger: PluginLogger): IdealGraph;
|
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,
|
|
@@ -126,6 +127,7 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
126
127
|
let parentsToConfig = new (_utils().DefaultMap)(() => []);
|
|
127
128
|
for (let c of config.manualSharedBundles) {
|
|
128
129
|
if (c.root != null) {
|
|
130
|
+
// @ts-expect-error TS2345
|
|
129
131
|
parentsToConfig.get(_path().default.join(config.projectRoot, c.root)).push(c);
|
|
130
132
|
}
|
|
131
133
|
}
|
|
@@ -162,6 +164,7 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
162
164
|
// We track all matching MSB's for constant modules as they are never duplicated
|
|
163
165
|
// and need to be assigned to all matching bundles
|
|
164
166
|
if (node.value.meta.isConstantModule === true) {
|
|
167
|
+
// @ts-expect-error TS2345
|
|
165
168
|
constantModuleToMSB.get(node.value).push(c);
|
|
166
169
|
}
|
|
167
170
|
if (assetRegexes.some(regex => regex.test(projectRelativePath))) {
|
|
@@ -202,7 +205,9 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
202
205
|
* adding only that asset to each bundle, not its entire subgraph.
|
|
203
206
|
*/
|
|
204
207
|
assetGraph.traverse({
|
|
205
|
-
enter(node, context,
|
|
208
|
+
enter(node, context,
|
|
209
|
+
// @ts-expect-error TS2304
|
|
210
|
+
actions) {
|
|
206
211
|
if (node.type === 'asset') {
|
|
207
212
|
if ((context === null || context === void 0 ? void 0 : context.type) === 'dependency' && context !== null && context !== void 0 && context.value.isEntry && !entries.has(node.value)) {
|
|
208
213
|
// Skip whole subtrees of other targets by skipping those entries
|
|
@@ -287,7 +292,9 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
287
292
|
}), dependencyBundleGraph.addNodeByContentKeyIfNeeded(String(bundleId), {
|
|
288
293
|
value: bundle,
|
|
289
294
|
type: 'bundle'
|
|
290
|
-
}),
|
|
295
|
+
}),
|
|
296
|
+
// @ts-expect-error TS7053
|
|
297
|
+
dependencyPriorityEdges[dependency.priority]);
|
|
291
298
|
if ((0, _featureFlags().getFeatureFlag)('conditionalBundlingApi') && dependency.priority === 'conditional') {
|
|
292
299
|
let [referencingBundleRoot, bundleGroupNodeId] = (0, _nullthrows().default)(stack[stack.length - 1]);
|
|
293
300
|
let referencingBundleId = (0, _nullthrows().default)(bundleRoots.get(referencingBundleRoot))[0];
|
|
@@ -347,13 +354,16 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
347
354
|
}
|
|
348
355
|
assetReference.get(childAsset).push([dependency, bundle]);
|
|
349
356
|
} else {
|
|
357
|
+
// @ts-expect-error TS2322
|
|
350
358
|
bundleId = null;
|
|
351
359
|
}
|
|
352
360
|
if (manualSharedObject && bundleId != null) {
|
|
353
361
|
// MSB Step 5: At this point we've either created or found an existing MSB bundle
|
|
354
362
|
// add the asset if it doesn't already have it and set key
|
|
355
363
|
|
|
356
|
-
(0, _assert().default)(
|
|
364
|
+
(0, _assert().default)(
|
|
365
|
+
// @ts-expect-error TS2367
|
|
366
|
+
bundle !== 'root' && bundle != null && bundleId != null);
|
|
357
367
|
manualAssetToBundle.set(childAsset, bundleId);
|
|
358
368
|
if (!bundle.assets.has(childAsset)) {
|
|
359
369
|
// Add asset to bundle
|
|
@@ -374,6 +384,7 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
374
384
|
}
|
|
375
385
|
return node;
|
|
376
386
|
},
|
|
387
|
+
// @ts-expect-error TS2322
|
|
377
388
|
exit(node) {
|
|
378
389
|
var _stack;
|
|
379
390
|
if (((_stack = stack[stack.length - 1]) === null || _stack === void 0 ? void 0 : _stack[0]) === node.value) {
|
|
@@ -602,8 +613,11 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
602
613
|
}
|
|
603
614
|
function assignInlineConstants(parentAsset, bundle) {
|
|
604
615
|
for (let inlineConstant of inlineConstantDeps.get(parentAsset)) {
|
|
616
|
+
// @ts-expect-error TS2345
|
|
605
617
|
if (!bundle.assets.has(inlineConstant)) {
|
|
618
|
+
// @ts-expect-error TS2345
|
|
606
619
|
bundle.assets.add(inlineConstant);
|
|
620
|
+
// @ts-expect-error TS18046
|
|
607
621
|
bundle.size += inlineConstant.stats.size;
|
|
608
622
|
}
|
|
609
623
|
}
|
|
@@ -819,8 +833,9 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
819
833
|
if (modNum != null) {
|
|
820
834
|
for (let a of [...manualBundle.assets]) {
|
|
821
835
|
let numRep = getBigIntFromContentKey(a.id);
|
|
822
|
-
// $FlowFixMe Flow doesn't know about BigInt
|
|
823
836
|
let r = Number(numRep % BigInt(modNum));
|
|
837
|
+
|
|
838
|
+
// @ts-expect-error TS2345
|
|
824
839
|
remainderMap.get(r).push(a);
|
|
825
840
|
}
|
|
826
841
|
for (let i = 1; i < [...remainderMap.keys()].length; i++) {
|
|
@@ -842,8 +857,10 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
842
857
|
}
|
|
843
858
|
for (let sp of remainderMap.get(i)) {
|
|
844
859
|
bundle.assets.add(sp);
|
|
860
|
+
// @ts-expect-error TS2339
|
|
845
861
|
bundle.size += sp.stats.size;
|
|
846
862
|
manualBundle.assets.delete(sp);
|
|
863
|
+
// @ts-expect-error TS2339
|
|
847
864
|
manualBundle.size -= sp.stats.size;
|
|
848
865
|
}
|
|
849
866
|
}
|
|
@@ -856,12 +873,17 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
856
873
|
// match multiple MSB's
|
|
857
874
|
for (let [asset, msbs] of constantModuleToMSB.entries()) {
|
|
858
875
|
for (let manualSharedObject of msbs) {
|
|
876
|
+
// @ts-expect-error TS2339
|
|
859
877
|
let bundleId = manualSharedMap.get(manualSharedObject.name + ',js');
|
|
860
878
|
if (bundleId == null) continue;
|
|
861
879
|
let bundle = (0, _nullthrows().default)(bundleGraph.getNode(bundleId));
|
|
862
880
|
(0, _assert().default)(bundle != null && bundle !== 'root', 'We tried to use the root incorrectly');
|
|
881
|
+
|
|
882
|
+
// @ts-expect-error TS2345
|
|
863
883
|
if (!bundle.assets.has(asset)) {
|
|
884
|
+
// @ts-expect-error TS2345
|
|
864
885
|
bundle.assets.add(asset);
|
|
886
|
+
// @ts-expect-error TS18046
|
|
865
887
|
bundle.size += asset.stats.size;
|
|
866
888
|
}
|
|
867
889
|
}
|
|
@@ -912,6 +934,7 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
912
934
|
// Merge all bundles with the same chunk name into the first one.
|
|
913
935
|
let [firstBundleId, ...rest] = Array.from(bundleIds);
|
|
914
936
|
for (let bundleId of rest) {
|
|
937
|
+
// @ts-expect-error TS2345
|
|
915
938
|
mergeBundles(firstBundleId, bundleId);
|
|
916
939
|
}
|
|
917
940
|
}
|
|
@@ -947,6 +970,7 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
947
970
|
let numBundlesContributingToPRL = bundleIdsInGroup.reduce((count, b) => {
|
|
948
971
|
let bundle = (0, _nullthrows().default)(bundleGraph.getNode(b));
|
|
949
972
|
(0, _assert().default)(bundle !== 'root');
|
|
973
|
+
// @ts-expect-error TS2365
|
|
950
974
|
return count + (bundle.bundleBehavior !== 'inline');
|
|
951
975
|
}, 0);
|
|
952
976
|
if (numBundlesContributingToPRL > config.maxParallelRequests) {
|
|
@@ -976,7 +1000,9 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
976
1000
|
// Remove bundles until the bundle group is within the parallel request limit.
|
|
977
1001
|
while (sharedBundlesInGroup.length > 0 && numBundlesContributingToPRL > config.maxParallelRequests) {
|
|
978
1002
|
let bundleTuple = sharedBundlesInGroup.pop();
|
|
1003
|
+
// @ts-expect-error TS18048
|
|
979
1004
|
let bundleToRemove = bundleTuple.bundle;
|
|
1005
|
+
// @ts-expect-error TS18048
|
|
980
1006
|
let bundleIdToRemove = bundleTuple.id;
|
|
981
1007
|
//TODO add integration test where bundles in bunlde group > max parallel request limit & only remove a couple shared bundles
|
|
982
1008
|
// but total # bundles still exceeds limit due to non shared bundles
|
|
@@ -1027,6 +1053,8 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
1027
1053
|
bundleToKeep.assets.add(asset);
|
|
1028
1054
|
bundleToKeep.size += asset.stats.size;
|
|
1029
1055
|
let newAssetReference = assetReference.get(asset).map(([dep, bundle]) => bundle === bundleToRemove ? [dep, bundleToKeep] : [dep, bundle]);
|
|
1056
|
+
|
|
1057
|
+
// @ts-expect-error TS2345
|
|
1030
1058
|
assetReference.set(asset, newAssetReference);
|
|
1031
1059
|
}
|
|
1032
1060
|
|
|
@@ -1161,7 +1189,6 @@ function createIdealGraph(assetGraph, config, entries, logger) {
|
|
|
1161
1189
|
function getBigIntFromContentKey(contentKey) {
|
|
1162
1190
|
let b = Buffer.alloc(64);
|
|
1163
1191
|
b.write(contentKey);
|
|
1164
|
-
// $FlowFixMe Flow doesn't have BigInt types in this version
|
|
1165
1192
|
return b.readBigInt64BE();
|
|
1166
1193
|
}
|
|
1167
1194
|
// Fix asset order in source bundles as they are likely now incorrect after shared bundle deletion
|
package/lib/memoize.d.ts
ADDED
package/lib/memoize.js
CHANGED
|
@@ -13,7 +13,6 @@ function _manyKeysMap() {
|
|
|
13
13
|
return data;
|
|
14
14
|
}
|
|
15
15
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
16
|
-
// $FlowFixMe
|
|
17
16
|
let caches = [];
|
|
18
17
|
function clearCaches() {
|
|
19
18
|
for (let cache of caches) {
|
|
@@ -32,8 +31,8 @@ function memoize(fn) {
|
|
|
32
31
|
}
|
|
33
32
|
|
|
34
33
|
// Calculate the result and cache it
|
|
34
|
+
// @ts-expect-error TS2683
|
|
35
35
|
const result = fn.apply(this, args);
|
|
36
|
-
// $FlowFixMe
|
|
37
36
|
cache.set(args, result);
|
|
38
37
|
return result;
|
|
39
38
|
};
|
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.139+d2fd84977",
|
|
4
4
|
"license": "(MIT OR Apache-2.0)",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"publishConfig": {
|
|
@@ -10,20 +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.207+d2fd84977",
|
|
21
|
+
"@atlaspack/feature-flags": "2.14.1-canary.207+d2fd84977",
|
|
22
|
+
"@atlaspack/graph": "3.4.1-canary.207+d2fd84977",
|
|
23
|
+
"@atlaspack/plugin": "2.14.5-canary.139+d2fd84977",
|
|
24
|
+
"@atlaspack/rust": "3.2.1-canary.139+d2fd84977",
|
|
25
|
+
"@atlaspack/utils": "2.14.5-canary.139+d2fd84977",
|
|
25
26
|
"many-keys-map": "^1.0.3",
|
|
26
27
|
"nullthrows": "^1.1.1"
|
|
27
28
|
},
|
|
28
|
-
"
|
|
29
|
-
|
|
29
|
+
"scripts": {
|
|
30
|
+
"check-ts": "tsc --emitDeclarationOnly --rootDir src"
|
|
31
|
+
},
|
|
32
|
+
"gitHead": "d2fd849770fe6305e9c694bd97b1bd905abd9d94"
|
|
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();
|
|
@@ -49,7 +48,6 @@ export default (new Bundler({
|
|
|
49
48
|
|
|
50
49
|
// Create separate bundleGraphs per distDir
|
|
51
50
|
graphs.push(
|
|
52
|
-
// $FlowFixMe
|
|
53
51
|
createIdealGraph(bundleGraph, config, idealGraphEntries, logger),
|
|
54
52
|
);
|
|
55
53
|
|
|
@@ -65,7 +63,7 @@ export default (new Bundler({
|
|
|
65
63
|
}
|
|
66
64
|
},
|
|
67
65
|
optimize() {},
|
|
68
|
-
})
|
|
66
|
+
}) as Bundler<unknown>;
|
|
69
67
|
|
|
70
68
|
function getEntryByTarget(
|
|
71
69
|
bundleGraph: MutableBundleGraph,
|
|
@@ -75,7 +73,23 @@ function getEntryByTarget(
|
|
|
75
73
|
() => new Map(),
|
|
76
74
|
);
|
|
77
75
|
bundleGraph.traverse({
|
|
78
|
-
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
|
+
) {
|
|
79
93
|
if (node.type !== 'asset') {
|
|
80
94
|
return node;
|
|
81
95
|
}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// @flow strict-local
|
|
2
|
-
|
|
3
1
|
import invariant from 'assert';
|
|
4
2
|
import nullthrows from 'nullthrows';
|
|
5
3
|
import {ContentGraph} from '@atlaspack/graph';
|
|
@@ -14,6 +12,7 @@ function getBundlesForBundleGroup(
|
|
|
14
12
|
): number {
|
|
15
13
|
let count = 0;
|
|
16
14
|
bundleGraph.traverse((nodeId) => {
|
|
15
|
+
// @ts-expect-error TS2339
|
|
17
16
|
if (bundleGraph.getNode(nodeId)?.bundleBehavior !== 'inline') {
|
|
18
17
|
count++;
|
|
19
18
|
}
|
|
@@ -125,7 +124,7 @@ function getMergeClusters(
|
|
|
125
124
|
graph: ContentGraph<NodeId, EdgeType>,
|
|
126
125
|
candidates: Map<NodeId, EdgeType>,
|
|
127
126
|
): Array<Array<NodeId>> {
|
|
128
|
-
let clusters = [];
|
|
127
|
+
let clusters: Array<Array<NodeId>> = [];
|
|
129
128
|
|
|
130
129
|
for (let [candidate, edgeType] of candidates.entries()) {
|
|
131
130
|
let cluster: Array<NodeId> = [];
|
|
@@ -145,11 +144,11 @@ function getMergeClusters(
|
|
|
145
144
|
return clusters;
|
|
146
145
|
}
|
|
147
146
|
|
|
148
|
-
type MergeCandidate = {
|
|
149
|
-
bundle: Bundle
|
|
150
|
-
id: NodeId
|
|
151
|
-
contentKey: string
|
|
152
|
-
|
|
147
|
+
type MergeCandidate = {
|
|
148
|
+
bundle: Bundle;
|
|
149
|
+
id: NodeId;
|
|
150
|
+
contentKey: string;
|
|
151
|
+
};
|
|
153
152
|
function getPossibleMergeCandidates(
|
|
154
153
|
bundleGraph: IdealBundleGraph,
|
|
155
154
|
bundles: Array<NodeId>,
|
|
@@ -165,17 +164,15 @@ function getPossibleMergeCandidates(
|
|
|
165
164
|
};
|
|
166
165
|
});
|
|
167
166
|
|
|
168
|
-
const uniquePairs = [];
|
|
167
|
+
const uniquePairs: Array<[MergeCandidate, MergeCandidate]> = [];
|
|
169
168
|
|
|
170
169
|
for (let i = 0; i < mergeCandidates.length; i++) {
|
|
171
170
|
for (let j = i + 1; j < mergeCandidates.length; j++) {
|
|
172
171
|
let a = mergeCandidates[i];
|
|
173
172
|
let b = mergeCandidates[j];
|
|
174
173
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
a.bundle.internalizedAssets.equals(b.bundle.internalizedAssets)
|
|
178
|
-
) {
|
|
174
|
+
// @ts-expect-error TS18048
|
|
175
|
+
if (a.bundle.internalizedAssets.equals(b.bundle.internalizedAssets)) {
|
|
179
176
|
uniquePairs.push([a, b]);
|
|
180
177
|
}
|
|
181
178
|
}
|
|
@@ -183,12 +180,12 @@ function getPossibleMergeCandidates(
|
|
|
183
180
|
return uniquePairs;
|
|
184
181
|
}
|
|
185
182
|
|
|
186
|
-
export type MergeGroup = {
|
|
187
|
-
overlapThreshold?: number
|
|
188
|
-
maxBundleSize?: number
|
|
189
|
-
sourceBundles?: Array<NodeId
|
|
190
|
-
minBundlesInGroup?: number
|
|
191
|
-
|
|
183
|
+
export type MergeGroup = {
|
|
184
|
+
overlapThreshold?: number;
|
|
185
|
+
maxBundleSize?: number;
|
|
186
|
+
sourceBundles?: Array<NodeId>;
|
|
187
|
+
minBundlesInGroup?: number;
|
|
188
|
+
};
|
|
192
189
|
type EdgeType = number;
|
|
193
190
|
|
|
194
191
|
export function findMergeCandidates(
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// @flow strict-local
|
|
2
|
-
|
|
3
1
|
import {encodeJSONKeyComponent} from '@atlaspack/diagnostic';
|
|
4
2
|
import type {
|
|
5
3
|
Config,
|
|
@@ -8,62 +6,62 @@ import type {
|
|
|
8
6
|
PluginLogger,
|
|
9
7
|
} from '@atlaspack/types';
|
|
10
8
|
import {getFeatureFlag} from '@atlaspack/feature-flags';
|
|
11
|
-
import {
|
|
9
|
+
import {SchemaEntity, validateSchema} from '@atlaspack/utils';
|
|
12
10
|
import invariant from 'assert';
|
|
13
11
|
|
|
14
12
|
type Glob = string;
|
|
15
13
|
|
|
16
|
-
type ManualSharedBundles = Array<{
|
|
17
|
-
name: string
|
|
18
|
-
assets: Array<Glob
|
|
19
|
-
types?: Array<string
|
|
20
|
-
root?: string
|
|
21
|
-
split?: number
|
|
22
|
-
|
|
14
|
+
type ManualSharedBundles = Array<{
|
|
15
|
+
name: string;
|
|
16
|
+
assets: Array<Glob>;
|
|
17
|
+
types?: Array<string>;
|
|
18
|
+
root?: string;
|
|
19
|
+
split?: number;
|
|
20
|
+
}>;
|
|
23
21
|
|
|
24
|
-
export type MergeCandidates = Array<{
|
|
25
|
-
overlapThreshold?: number
|
|
26
|
-
maxBundleSize?: number
|
|
27
|
-
sourceBundles?: Array<string
|
|
28
|
-
minBundlesInGroup?: number
|
|
29
|
-
|
|
22
|
+
export type MergeCandidates = Array<{
|
|
23
|
+
overlapThreshold?: number;
|
|
24
|
+
maxBundleSize?: number;
|
|
25
|
+
sourceBundles?: Array<string>;
|
|
26
|
+
minBundlesInGroup?: number;
|
|
27
|
+
}>;
|
|
30
28
|
|
|
31
|
-
type BaseBundlerConfig = {
|
|
32
|
-
http?: number
|
|
33
|
-
minBundles?: number
|
|
34
|
-
minBundleSize?: number
|
|
35
|
-
maxParallelRequests?: number
|
|
36
|
-
disableSharedBundles?: boolean
|
|
37
|
-
manualSharedBundles?: ManualSharedBundles
|
|
38
|
-
loadConditionalBundlesInParallel?: boolean
|
|
39
|
-
sharedBundleMerge?: MergeCandidates
|
|
40
|
-
|
|
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
|
+
};
|
|
41
39
|
|
|
42
|
-
type BundlerConfig =
|
|
43
|
-
|
|
44
|
-
|} & BaseBundlerConfig;
|
|
40
|
+
type BundlerConfig = Partial<Record<BuildMode, BaseBundlerConfig>> &
|
|
41
|
+
BaseBundlerConfig;
|
|
45
42
|
|
|
46
|
-
export type ResolvedBundlerConfig = {
|
|
47
|
-
minBundles: number
|
|
48
|
-
minBundleSize: number
|
|
49
|
-
maxParallelRequests: number
|
|
50
|
-
projectRoot: string
|
|
51
|
-
disableSharedBundles: boolean
|
|
52
|
-
manualSharedBundles: ManualSharedBundles
|
|
53
|
-
loadConditionalBundlesInParallel?: boolean
|
|
54
|
-
sharedBundleMerge?: MergeCandidates
|
|
55
|
-
|
|
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
|
+
};
|
|
56
53
|
|
|
57
54
|
function resolveModeConfig(
|
|
58
55
|
config: BundlerConfig,
|
|
59
56
|
mode: BuildMode,
|
|
60
57
|
): BaseBundlerConfig {
|
|
61
|
-
let generalConfig = {};
|
|
62
|
-
let modeConfig = {};
|
|
58
|
+
let generalConfig: Record<string, any> = {};
|
|
59
|
+
let modeConfig: Record<string, any> = {};
|
|
63
60
|
|
|
64
61
|
for (const key of Object.keys(config)) {
|
|
65
62
|
if (key === 'development' || key === 'production') {
|
|
66
63
|
if (key === mode) {
|
|
64
|
+
// @ts-expect-error TS2322
|
|
67
65
|
modeConfig = config[key];
|
|
68
66
|
}
|
|
69
67
|
} else {
|
|
@@ -71,7 +69,6 @@ function resolveModeConfig(
|
|
|
71
69
|
}
|
|
72
70
|
}
|
|
73
71
|
|
|
74
|
-
// $FlowFixMe Not sure how to convince flow here...
|
|
75
72
|
return {
|
|
76
73
|
...generalConfig,
|
|
77
74
|
...modeConfig,
|
|
@@ -96,7 +93,7 @@ const HTTP_OPTIONS = {
|
|
|
96
93
|
disableSharedBundles: false,
|
|
97
94
|
sharedBundleMerge: [],
|
|
98
95
|
},
|
|
99
|
-
};
|
|
96
|
+
} as const;
|
|
100
97
|
|
|
101
98
|
const CONFIG_SCHEMA: SchemaEntity = {
|
|
102
99
|
type: 'object',
|
|
@@ -203,7 +200,8 @@ export async function loadBundlerConfig(
|
|
|
203
200
|
const modDefault = {
|
|
204
201
|
...HTTP_OPTIONS['2'],
|
|
205
202
|
projectRoot: options.projectRoot,
|
|
206
|
-
};
|
|
203
|
+
} as const;
|
|
204
|
+
// @ts-expect-error TS2322
|
|
207
205
|
return modDefault;
|
|
208
206
|
}
|
|
209
207
|
|
|
@@ -266,6 +264,7 @@ export async function loadBundlerConfig(
|
|
|
266
264
|
);
|
|
267
265
|
|
|
268
266
|
let http = modeConfig.http ?? 2;
|
|
267
|
+
// @ts-expect-error TS7053
|
|
269
268
|
let defaults = HTTP_OPTIONS[http];
|
|
270
269
|
|
|
271
270
|
return {
|
|
@@ -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,
|
|
@@ -213,11 +211,13 @@ export function decorateLegacyGraph(
|
|
|
213
211
|
}
|
|
214
212
|
}
|
|
215
213
|
|
|
214
|
+
// @ts-expect-error TS2488
|
|
216
215
|
for (let {type, from, to} of idealBundleGraph.getAllEdges()) {
|
|
217
216
|
let sourceBundle = nullthrows(idealBundleGraph.getNode(from));
|
|
218
217
|
if (sourceBundle === 'root') {
|
|
219
218
|
continue;
|
|
220
219
|
}
|
|
220
|
+
// @ts-expect-error TS2367
|
|
221
221
|
invariant(sourceBundle !== 'root');
|
|
222
222
|
|
|
223
223
|
let legacySourceBundle = nullthrows(
|
|
@@ -228,6 +228,7 @@ export function decorateLegacyGraph(
|
|
|
228
228
|
if (targetBundle === 'root') {
|
|
229
229
|
continue;
|
|
230
230
|
}
|
|
231
|
+
// @ts-expect-error TS2367
|
|
231
232
|
invariant(targetBundle !== 'root');
|
|
232
233
|
let legacyTargetBundle = nullthrows(
|
|
233
234
|
idealBundleToLegacyBundle.get(targetBundle),
|
|
@@ -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,38 +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,
|
|
24
|
+
import {findMergeCandidates, MergeGroup} from './bundleMerge';
|
|
27
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
|
-
bundleRoots: Set<Asset
|
|
40
|
-
size: number
|
|
41
|
-
sourceBundles: Set<NodeId
|
|
42
|
-
target: Target
|
|
43
|
-
env: Environment
|
|
44
|
-
type: string
|
|
45
|
-
manualSharedBundle:
|
|
46
|
-
|
|
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
|
+
};
|
|
47
45
|
|
|
48
46
|
export type DependencyBundleGraph = ContentGraph<
|
|
49
|
-
| {
|
|
50
|
-
value: Bundle
|
|
51
|
-
type: 'bundle'
|
|
52
|
-
|
|
53
|
-
| {
|
|
54
|
-
value: Dependency
|
|
55
|
-
type: 'dependency'
|
|
56
|
-
|
|
57
|
-
number
|
|
47
|
+
| {
|
|
48
|
+
value: Bundle;
|
|
49
|
+
type: 'bundle';
|
|
50
|
+
}
|
|
51
|
+
| {
|
|
52
|
+
value: Dependency;
|
|
53
|
+
type: 'dependency';
|
|
54
|
+
},
|
|
55
|
+
number
|
|
58
56
|
>;
|
|
59
57
|
|
|
60
58
|
const dependencyPriorityEdges = {
|
|
@@ -62,7 +60,7 @@ const dependencyPriorityEdges = {
|
|
|
62
60
|
parallel: 2,
|
|
63
61
|
lazy: 3,
|
|
64
62
|
conditional: 4,
|
|
65
|
-
};
|
|
63
|
+
} as const;
|
|
66
64
|
|
|
67
65
|
export const idealBundleGraphEdges = Object.freeze({
|
|
68
66
|
default: 1,
|
|
@@ -71,20 +69,20 @@ export const idealBundleGraphEdges = Object.freeze({
|
|
|
71
69
|
|
|
72
70
|
export type IdealBundleGraph = Graph<
|
|
73
71
|
Bundle | 'root',
|
|
74
|
-
|
|
72
|
+
(typeof idealBundleGraphEdges)[keyof typeof idealBundleGraphEdges]
|
|
75
73
|
>;
|
|
76
74
|
|
|
77
75
|
// IdealGraph is the structure we will pass to decorate,
|
|
78
76
|
// which mutates the assetGraph into the bundleGraph we would
|
|
79
77
|
// expect from default bundler
|
|
80
|
-
export type IdealGraph = {
|
|
81
|
-
assetReference: DefaultMap<Asset, Array<[Dependency, Bundle]
|
|
82
|
-
assets: Array<Asset
|
|
83
|
-
bundleGraph: IdealBundleGraph
|
|
84
|
-
bundleGroupBundleIds: Set<NodeId
|
|
85
|
-
dependencyBundleGraph: DependencyBundleGraph
|
|
86
|
-
manualAssetToBundle: Map<Asset, NodeId
|
|
87
|
-
|
|
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
|
+
};
|
|
88
86
|
|
|
89
87
|
function isNonRootBundle(
|
|
90
88
|
bundle?: Bundle | 'root' | null,
|
|
@@ -108,7 +106,7 @@ export function createIdealGraph(
|
|
|
108
106
|
let dependencyBundleGraph: DependencyBundleGraph = new ContentGraph();
|
|
109
107
|
let assetReference: DefaultMap<
|
|
110
108
|
Asset,
|
|
111
|
-
Array<[Dependency, Bundle]
|
|
109
|
+
Array<[Dependency, Bundle]>
|
|
112
110
|
> = new DefaultMap(() => []);
|
|
113
111
|
|
|
114
112
|
// A Graph of Bundles and a root node (dummy string), which models only Bundles, and connections to their
|
|
@@ -122,8 +120,9 @@ export function createIdealGraph(
|
|
|
122
120
|
};
|
|
123
121
|
// Graph that models bundleRoots, with parallel & async deps only to inform reachability
|
|
124
122
|
let bundleRootGraph: Graph<
|
|
125
|
-
|
|
126
|
-
|
|
123
|
+
// asset index
|
|
124
|
+
number,
|
|
125
|
+
(typeof bundleRootEdgeTypes)[keyof typeof bundleRootEdgeTypes]
|
|
127
126
|
> = new Graph();
|
|
128
127
|
let assetToBundleRootNodeId = new Map<BundleRoot, number>();
|
|
129
128
|
|
|
@@ -157,7 +156,7 @@ export function createIdealGraph(
|
|
|
157
156
|
bundleGroupBundleIds.add(nodeId);
|
|
158
157
|
}
|
|
159
158
|
|
|
160
|
-
let assets = [];
|
|
159
|
+
let assets: Array<Asset> = [];
|
|
161
160
|
let assetToIndex = new Map<Asset, number>();
|
|
162
161
|
|
|
163
162
|
function makeManualAssetToConfigLookup() {
|
|
@@ -172,6 +171,7 @@ export function createIdealGraph(
|
|
|
172
171
|
|
|
173
172
|
for (let c of config.manualSharedBundles) {
|
|
174
173
|
if (c.root != null) {
|
|
174
|
+
// @ts-expect-error TS2345
|
|
175
175
|
parentsToConfig.get(path.join(config.projectRoot, c.root)).push(c);
|
|
176
176
|
}
|
|
177
177
|
}
|
|
@@ -219,6 +219,7 @@ export function createIdealGraph(
|
|
|
219
219
|
// We track all matching MSB's for constant modules as they are never duplicated
|
|
220
220
|
// and need to be assigned to all matching bundles
|
|
221
221
|
if (node.value.meta.isConstantModule === true) {
|
|
222
|
+
// @ts-expect-error TS2345
|
|
222
223
|
constantModuleToMSB.get(node.value).push(c);
|
|
223
224
|
}
|
|
224
225
|
|
|
@@ -252,14 +253,14 @@ export function createIdealGraph(
|
|
|
252
253
|
makeManualAssetToConfigLookup();
|
|
253
254
|
let manualBundleToInternalizedAsset: DefaultMap<
|
|
254
255
|
NodeId,
|
|
255
|
-
Array<Asset
|
|
256
|
+
Array<Asset>
|
|
256
257
|
> = new DefaultMap(() => []);
|
|
257
258
|
|
|
258
259
|
let mergeSourceBundleLookup = new Map<string, NodeId>();
|
|
259
260
|
let mergeSourceBundleAssets = new Set(
|
|
260
261
|
config.sharedBundleMerge?.flatMap(
|
|
261
262
|
(c) =>
|
|
262
|
-
c.sourceBundles?.map((assetMatch) =>
|
|
263
|
+
c.sourceBundles?.map((assetMatch: string) =>
|
|
263
264
|
path.join(config.projectRoot, assetMatch),
|
|
264
265
|
) ?? [],
|
|
265
266
|
),
|
|
@@ -272,7 +273,27 @@ export function createIdealGraph(
|
|
|
272
273
|
*/
|
|
273
274
|
assetGraph.traverse(
|
|
274
275
|
{
|
|
275
|
-
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
|
+
) {
|
|
276
297
|
if (node.type === 'asset') {
|
|
277
298
|
if (
|
|
278
299
|
context?.type === 'dependency' &&
|
|
@@ -399,6 +420,7 @@ export function createIdealGraph(
|
|
|
399
420
|
type: 'bundle',
|
|
400
421
|
},
|
|
401
422
|
),
|
|
423
|
+
// @ts-expect-error TS7053
|
|
402
424
|
dependencyPriorityEdges[dependency.priority],
|
|
403
425
|
);
|
|
404
426
|
|
|
@@ -510,6 +532,7 @@ export function createIdealGraph(
|
|
|
510
532
|
|
|
511
533
|
assetReference.get(childAsset).push([dependency, bundle]);
|
|
512
534
|
} else {
|
|
535
|
+
// @ts-expect-error TS2322
|
|
513
536
|
bundleId = null;
|
|
514
537
|
}
|
|
515
538
|
if (manualSharedObject && bundleId != null) {
|
|
@@ -517,6 +540,7 @@ export function createIdealGraph(
|
|
|
517
540
|
// add the asset if it doesn't already have it and set key
|
|
518
541
|
|
|
519
542
|
invariant(
|
|
543
|
+
// @ts-expect-error TS2367
|
|
520
544
|
bundle !== 'root' && bundle != null && bundleId != null,
|
|
521
545
|
);
|
|
522
546
|
|
|
@@ -543,7 +567,8 @@ export function createIdealGraph(
|
|
|
543
567
|
}
|
|
544
568
|
return node;
|
|
545
569
|
},
|
|
546
|
-
|
|
570
|
+
// @ts-expect-error TS2322
|
|
571
|
+
exit(node: BundleGraphTraversable) {
|
|
547
572
|
if (stack[stack.length - 1]?.[0] === node.value) {
|
|
548
573
|
stack.pop();
|
|
549
574
|
}
|
|
@@ -592,20 +617,20 @@ export function createIdealGraph(
|
|
|
592
617
|
|
|
593
618
|
// reachableRoots is an array of bit sets for each asset. Each bit set
|
|
594
619
|
// indicates which bundle roots are reachable from that asset synchronously.
|
|
595
|
-
let reachableRoots = [];
|
|
620
|
+
let reachableRoots: Array<BitSet> = [];
|
|
596
621
|
for (let i = 0; i < assets.length; i++) {
|
|
597
622
|
reachableRoots.push(new BitSet(bundleRootGraph.nodes.length));
|
|
598
623
|
}
|
|
599
624
|
|
|
600
625
|
// reachableAssets is the inverse mapping of reachableRoots. For each bundle root,
|
|
601
626
|
// it contains a bit set that indicates which assets are reachable from it.
|
|
602
|
-
let reachableAssets = [];
|
|
627
|
+
let reachableAssets: Array<BitSet> = [];
|
|
603
628
|
|
|
604
629
|
// ancestorAssets maps bundle roots to the set of all assets available to it at runtime,
|
|
605
630
|
// including in earlier parallel bundles. These are intersected through all paths to
|
|
606
631
|
// the bundle to ensure that the available assets are always present no matter in which
|
|
607
632
|
// order the bundles are loaded.
|
|
608
|
-
let ancestorAssets = [];
|
|
633
|
+
let ancestorAssets: Array<null | BitSet> = [];
|
|
609
634
|
|
|
610
635
|
let inlineConstantDeps = new DefaultMap(() => new Set());
|
|
611
636
|
|
|
@@ -834,8 +859,11 @@ export function createIdealGraph(
|
|
|
834
859
|
|
|
835
860
|
function assignInlineConstants(parentAsset: Asset, bundle: Bundle) {
|
|
836
861
|
for (let inlineConstant of inlineConstantDeps.get(parentAsset)) {
|
|
862
|
+
// @ts-expect-error TS2345
|
|
837
863
|
if (!bundle.assets.has(inlineConstant)) {
|
|
864
|
+
// @ts-expect-error TS2345
|
|
838
865
|
bundle.assets.add(inlineConstant);
|
|
866
|
+
// @ts-expect-error TS18046
|
|
839
867
|
bundle.size += inlineConstant.stats.size;
|
|
840
868
|
}
|
|
841
869
|
}
|
|
@@ -895,7 +923,7 @@ export function createIdealGraph(
|
|
|
895
923
|
let bundle;
|
|
896
924
|
let bundleId;
|
|
897
925
|
let manualSharedBundleKey = manualSharedObject.name + ',' + asset.type;
|
|
898
|
-
let sourceBundles = [];
|
|
926
|
+
let sourceBundles: Array<NodeId> = [];
|
|
899
927
|
reachable.forEach((id) => {
|
|
900
928
|
sourceBundles.push(nullthrows(bundleRoots.get(assets[id]))[0]);
|
|
901
929
|
});
|
|
@@ -1010,7 +1038,7 @@ export function createIdealGraph(
|
|
|
1010
1038
|
});
|
|
1011
1039
|
}
|
|
1012
1040
|
|
|
1013
|
-
let reachableArray = [];
|
|
1041
|
+
let reachableArray: Array<Asset> = [];
|
|
1014
1042
|
reachable.forEach((id) => {
|
|
1015
1043
|
reachableArray.push(assets[id]);
|
|
1016
1044
|
});
|
|
@@ -1105,9 +1133,9 @@ export function createIdealGraph(
|
|
|
1105
1133
|
if (modNum != null) {
|
|
1106
1134
|
for (let a of [...manualBundle.assets]) {
|
|
1107
1135
|
let numRep = getBigIntFromContentKey(a.id);
|
|
1108
|
-
// $FlowFixMe Flow doesn't know about BigInt
|
|
1109
1136
|
let r = Number(numRep % BigInt(modNum));
|
|
1110
1137
|
|
|
1138
|
+
// @ts-expect-error TS2345
|
|
1111
1139
|
remainderMap.get(r).push(a);
|
|
1112
1140
|
}
|
|
1113
1141
|
|
|
@@ -1130,8 +1158,10 @@ export function createIdealGraph(
|
|
|
1130
1158
|
}
|
|
1131
1159
|
for (let sp of remainderMap.get(i)) {
|
|
1132
1160
|
bundle.assets.add(sp);
|
|
1161
|
+
// @ts-expect-error TS2339
|
|
1133
1162
|
bundle.size += sp.stats.size;
|
|
1134
1163
|
manualBundle.assets.delete(sp);
|
|
1164
|
+
// @ts-expect-error TS2339
|
|
1135
1165
|
manualBundle.size -= sp.stats.size;
|
|
1136
1166
|
}
|
|
1137
1167
|
}
|
|
@@ -1144,6 +1174,7 @@ export function createIdealGraph(
|
|
|
1144
1174
|
// match multiple MSB's
|
|
1145
1175
|
for (let [asset, msbs] of constantModuleToMSB.entries()) {
|
|
1146
1176
|
for (let manualSharedObject of msbs) {
|
|
1177
|
+
// @ts-expect-error TS2339
|
|
1147
1178
|
let bundleId = manualSharedMap.get(manualSharedObject.name + ',js');
|
|
1148
1179
|
if (bundleId == null) continue;
|
|
1149
1180
|
let bundle = nullthrows(bundleGraph.getNode(bundleId));
|
|
@@ -1152,8 +1183,11 @@ export function createIdealGraph(
|
|
|
1152
1183
|
'We tried to use the root incorrectly',
|
|
1153
1184
|
);
|
|
1154
1185
|
|
|
1186
|
+
// @ts-expect-error TS2345
|
|
1155
1187
|
if (!bundle.assets.has(asset)) {
|
|
1188
|
+
// @ts-expect-error TS2345
|
|
1156
1189
|
bundle.assets.add(asset);
|
|
1190
|
+
// @ts-expect-error TS18046
|
|
1157
1191
|
bundle.size += asset.stats.size;
|
|
1158
1192
|
}
|
|
1159
1193
|
}
|
|
@@ -1227,6 +1261,7 @@ export function createIdealGraph(
|
|
|
1227
1261
|
// Merge all bundles with the same chunk name into the first one.
|
|
1228
1262
|
let [firstBundleId, ...rest] = Array.from(bundleIds);
|
|
1229
1263
|
for (let bundleId of rest) {
|
|
1264
|
+
// @ts-expect-error TS2345
|
|
1230
1265
|
mergeBundles(firstBundleId, bundleId);
|
|
1231
1266
|
}
|
|
1232
1267
|
}
|
|
@@ -1267,6 +1302,7 @@ export function createIdealGraph(
|
|
|
1267
1302
|
let numBundlesContributingToPRL = bundleIdsInGroup.reduce((count, b) => {
|
|
1268
1303
|
let bundle = nullthrows(bundleGraph.getNode(b));
|
|
1269
1304
|
invariant(bundle !== 'root');
|
|
1305
|
+
// @ts-expect-error TS2365
|
|
1270
1306
|
return count + (bundle.bundleBehavior !== 'inline');
|
|
1271
1307
|
}, 0);
|
|
1272
1308
|
|
|
@@ -1302,7 +1338,9 @@ export function createIdealGraph(
|
|
|
1302
1338
|
numBundlesContributingToPRL > config.maxParallelRequests
|
|
1303
1339
|
) {
|
|
1304
1340
|
let bundleTuple = sharedBundlesInGroup.pop();
|
|
1341
|
+
// @ts-expect-error TS18048
|
|
1305
1342
|
let bundleToRemove = bundleTuple.bundle;
|
|
1343
|
+
// @ts-expect-error TS18048
|
|
1306
1344
|
let bundleIdToRemove = bundleTuple.id;
|
|
1307
1345
|
//TODO add integration test where bundles in bunlde group > max parallel request limit & only remove a couple shared bundles
|
|
1308
1346
|
// but total # bundles still exceeds limit due to non shared bundles
|
|
@@ -1374,10 +1412,11 @@ export function createIdealGraph(
|
|
|
1374
1412
|
|
|
1375
1413
|
let newAssetReference = assetReference
|
|
1376
1414
|
.get(asset)
|
|
1377
|
-
.map(([dep, bundle]) =>
|
|
1415
|
+
.map(([dep, bundle]: [any, any]) =>
|
|
1378
1416
|
bundle === bundleToRemove ? [dep, bundleToKeep] : [dep, bundle],
|
|
1379
1417
|
);
|
|
1380
1418
|
|
|
1419
|
+
// @ts-expect-error TS2345
|
|
1381
1420
|
assetReference.set(asset, newAssetReference);
|
|
1382
1421
|
}
|
|
1383
1422
|
|
|
@@ -1541,20 +1580,22 @@ export function createIdealGraph(
|
|
|
1541
1580
|
let clusters = findMergeCandidates(
|
|
1542
1581
|
bundleGraph,
|
|
1543
1582
|
Array.from(sharedBundles),
|
|
1544
|
-
mergeConfig.map(
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1583
|
+
mergeConfig.map(
|
|
1584
|
+
(config): MergeGroup => ({
|
|
1585
|
+
...config,
|
|
1586
|
+
sourceBundles: config.sourceBundles?.map((assetMatch: string) => {
|
|
1587
|
+
let sourceBundleNodeId = mergeSourceBundleLookup.get(assetMatch);
|
|
1588
|
+
|
|
1589
|
+
if (sourceBundleNodeId == null) {
|
|
1590
|
+
throw new Error(
|
|
1591
|
+
`Source bundle ${assetMatch} not found in merge source bundle lookup`,
|
|
1592
|
+
);
|
|
1593
|
+
}
|
|
1554
1594
|
|
|
1555
|
-
|
|
1595
|
+
return sourceBundleNodeId;
|
|
1596
|
+
}),
|
|
1556
1597
|
}),
|
|
1557
|
-
|
|
1598
|
+
),
|
|
1558
1599
|
);
|
|
1559
1600
|
|
|
1560
1601
|
let mergedBundles = new Set();
|
|
@@ -1574,10 +1615,9 @@ export function createIdealGraph(
|
|
|
1574
1615
|
}
|
|
1575
1616
|
}
|
|
1576
1617
|
|
|
1577
|
-
function getBigIntFromContentKey(contentKey) {
|
|
1618
|
+
function getBigIntFromContentKey(contentKey: string) {
|
|
1578
1619
|
let b = Buffer.alloc(64);
|
|
1579
1620
|
b.write(contentKey);
|
|
1580
|
-
// $FlowFixMe Flow doesn't have BigInt types in this version
|
|
1581
1621
|
return b.readBigInt64BE();
|
|
1582
1622
|
}
|
|
1583
1623
|
// Fix asset order in source bundles as they are likely now incorrect after shared bundle deletion
|
|
@@ -1604,8 +1644,8 @@ export function createIdealGraph(
|
|
|
1604
1644
|
bundleRootGraph.removeNode(bundleRootId);
|
|
1605
1645
|
}
|
|
1606
1646
|
}
|
|
1607
|
-
function getBundlesForBundleGroup(bundleGroupId) {
|
|
1608
|
-
let bundlesInABundleGroup = [];
|
|
1647
|
+
function getBundlesForBundleGroup(bundleGroupId: NodeId) {
|
|
1648
|
+
let bundlesInABundleGroup: Array<NodeId> = [];
|
|
1609
1649
|
bundleGraph.traverse((nodeId) => {
|
|
1610
1650
|
bundlesInABundleGroup.push(nodeId);
|
|
1611
1651
|
}, bundleGroupId);
|
|
@@ -1686,17 +1726,17 @@ export function createIdealGraph(
|
|
|
1686
1726
|
};
|
|
1687
1727
|
}
|
|
1688
1728
|
|
|
1689
|
-
function createBundle(opts: {
|
|
1690
|
-
asset?: Asset
|
|
1691
|
-
bundleBehavior?:
|
|
1692
|
-
env?: Environment
|
|
1693
|
-
manualSharedBundle?:
|
|
1694
|
-
needsStableName?: boolean
|
|
1695
|
-
sourceBundles?: Set<NodeId
|
|
1696
|
-
target: Target
|
|
1697
|
-
type?: string
|
|
1698
|
-
uniqueKey?: string
|
|
1699
|
-
|
|
1729
|
+
function createBundle(opts: {
|
|
1730
|
+
asset?: Asset;
|
|
1731
|
+
bundleBehavior?: BundleBehavior | null | undefined;
|
|
1732
|
+
env?: Environment;
|
|
1733
|
+
manualSharedBundle?: string | null | undefined;
|
|
1734
|
+
needsStableName?: boolean;
|
|
1735
|
+
sourceBundles?: Set<NodeId>;
|
|
1736
|
+
target: Target;
|
|
1737
|
+
type?: string;
|
|
1738
|
+
uniqueKey?: string;
|
|
1739
|
+
}): Bundle {
|
|
1700
1740
|
if (opts.asset == null) {
|
|
1701
1741
|
return {
|
|
1702
1742
|
assets: new Set(),
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
// @flow strict
|
|
2
|
-
|
|
3
|
-
// $FlowFixMe
|
|
4
1
|
import ManyKeysMap from 'many-keys-map';
|
|
5
2
|
|
|
6
|
-
let caches = [];
|
|
3
|
+
let caches: Array<any> = [];
|
|
7
4
|
|
|
8
5
|
export function clearCaches() {
|
|
9
6
|
for (let cache of caches) {
|
|
@@ -11,7 +8,7 @@ export function clearCaches() {
|
|
|
11
8
|
}
|
|
12
9
|
}
|
|
13
10
|
|
|
14
|
-
export function memoize<Args
|
|
11
|
+
export function memoize<Args extends Array<unknown>, Return>(
|
|
15
12
|
fn: (...args: Args) => Return,
|
|
16
13
|
): (...args: Args) => Return {
|
|
17
14
|
let cache = new ManyKeysMap();
|
|
@@ -26,8 +23,8 @@ export function memoize<Args: Array<mixed>, Return>(
|
|
|
26
23
|
}
|
|
27
24
|
|
|
28
25
|
// Calculate the result and cache it
|
|
26
|
+
// @ts-expect-error TS2683
|
|
29
27
|
const result = fn.apply(this, args);
|
|
30
|
-
// $FlowFixMe
|
|
31
28
|
cache.set(args, result);
|
|
32
29
|
|
|
33
30
|
return result;
|
package/tsconfig.json
ADDED