@atlaspack/bundler-default 2.14.5-canary.36 → 2.14.5-canary.361

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.
Files changed (37) hide show
  1. package/CHANGELOG.md +613 -0
  2. package/dist/DefaultBundler.js +84 -0
  3. package/dist/MonolithicBundler.js +68 -0
  4. package/dist/bundleMerge.js +137 -0
  5. package/dist/bundlerConfig.js +223 -0
  6. package/dist/decorateLegacyGraph.js +189 -0
  7. package/dist/idealGraph.js +1471 -0
  8. package/dist/memoize.js +31 -0
  9. package/dist/stats.js +69 -0
  10. package/lib/DefaultBundler.js +6 -1
  11. package/lib/MonolithicBundler.js +11 -3
  12. package/lib/bundleMerge.js +106 -37
  13. package/lib/bundlerConfig.js +52 -6
  14. package/lib/decorateLegacyGraph.js +24 -3
  15. package/lib/idealGraph.js +410 -55
  16. package/lib/memoize.js +39 -0
  17. package/lib/stats.js +85 -0
  18. package/lib/types/DefaultBundler.d.ts +18 -0
  19. package/lib/types/MonolithicBundler.d.ts +2 -0
  20. package/lib/types/bundleMerge.d.ts +9 -0
  21. package/lib/types/bundlerConfig.d.ts +36 -0
  22. package/lib/types/decorateLegacyGraph.d.ts +3 -0
  23. package/lib/types/idealGraph.d.ts +40 -0
  24. package/lib/types/memoize.d.ts +2 -0
  25. package/lib/types/stats.d.ts +16 -0
  26. package/package.json +20 -12
  27. package/src/{DefaultBundler.js → DefaultBundler.ts} +21 -6
  28. package/src/{MonolithicBundler.js → MonolithicBundler.ts} +17 -5
  29. package/src/bundleMerge.ts +250 -0
  30. package/src/{bundlerConfig.js → bundlerConfig.ts} +106 -45
  31. package/src/{decorateLegacyGraph.js → decorateLegacyGraph.ts} +26 -7
  32. package/src/{idealGraph.js → idealGraph.ts} +729 -137
  33. package/src/memoize.ts +32 -0
  34. package/src/stats.ts +97 -0
  35. package/tsconfig.json +30 -0
  36. package/tsconfig.tsbuildinfo +1 -0
  37. package/src/bundleMerge.js +0 -103
@@ -1,62 +1,78 @@
1
- // @flow strict-local
2
-
3
1
  import {encodeJSONKeyComponent} from '@atlaspack/diagnostic';
4
2
  import type {
5
3
  Config,
6
4
  PluginOptions,
7
5
  BuildMode,
8
6
  PluginLogger,
9
- } from '@atlaspack/types';
7
+ } from '@atlaspack/types-internal';
10
8
  import {getFeatureFlag} from '@atlaspack/feature-flags';
11
- import {type SchemaEntity, validateSchema} from '@atlaspack/utils';
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
- type BaseBundlerConfig = {|
25
- http?: number,
26
- minBundles?: number,
27
- minBundleSize?: number,
28
- maxParallelRequests?: number,
29
- disableSharedBundles?: boolean,
30
- manualSharedBundles?: ManualSharedBundles,
31
- loadConditionalBundlesInParallel?: boolean,
32
- sharedBundleMergeThreshold?: number,
33
- |};
22
+ export type SharedBundleMergeCandidates = Array<{
23
+ overlapThreshold?: number;
24
+ maxBundleSize?: number;
25
+ sourceBundles?: Array<string>;
26
+ minBundlesInGroup?: number;
27
+ }>;
34
28
 
35
- type BundlerConfig = {|
36
- [mode: BuildMode]: BaseBundlerConfig,
37
- |} & BaseBundlerConfig;
29
+ export interface AsyncBundleMerge {
30
+ /** Consider all async bundles smaller than this for merging */
31
+ bundleSize: number;
32
+ /** The max bytes allowed to be potentially overfetched due to a merge */
33
+ maxOverfetchSize: number;
34
+ /** Bundles to ignore from merging */
35
+ ignore?: Array<Glob>;
36
+ }
38
37
 
39
- export type ResolvedBundlerConfig = {|
40
- minBundles: number,
41
- minBundleSize: number,
42
- maxParallelRequests: number,
43
- projectRoot: string,
44
- disableSharedBundles: boolean,
45
- manualSharedBundles: ManualSharedBundles,
46
- loadConditionalBundlesInParallel?: boolean,
47
- sharedBundleMergeThreshold: number,
48
- |};
38
+ type BaseBundlerConfig = {
39
+ http?: number;
40
+ minBundles?: number;
41
+ minBundleSize?: number;
42
+ maxParallelRequests?: number;
43
+ disableSharedBundles?: boolean;
44
+ manualSharedBundles?: ManualSharedBundles;
45
+ loadConditionalBundlesInParallel?: boolean;
46
+ sharedBundleMerge?: SharedBundleMergeCandidates;
47
+ asyncBundleMerge?: AsyncBundleMerge;
48
+ };
49
+
50
+ type BundlerConfig = Partial<Record<BuildMode, BaseBundlerConfig>> &
51
+ BaseBundlerConfig;
52
+
53
+ export type ResolvedBundlerConfig = {
54
+ minBundles: number;
55
+ minBundleSize: number;
56
+ maxParallelRequests: number;
57
+ projectRoot: string;
58
+ disableSharedBundles: boolean;
59
+ manualSharedBundles: ManualSharedBundles;
60
+ loadConditionalBundlesInParallel?: boolean;
61
+ sharedBundleMerge?: SharedBundleMergeCandidates;
62
+ asyncBundleMerge?: AsyncBundleMerge;
63
+ };
49
64
 
50
65
  function resolveModeConfig(
51
66
  config: BundlerConfig,
52
67
  mode: BuildMode,
53
68
  ): BaseBundlerConfig {
54
- let generalConfig = {};
55
- let modeConfig = {};
69
+ let generalConfig: Record<string, any> = {};
70
+ let modeConfig: Record<string, any> = {};
56
71
 
57
72
  for (const key of Object.keys(config)) {
58
73
  if (key === 'development' || key === 'production') {
59
74
  if (key === mode) {
75
+ // @ts-expect-error TS2322
60
76
  modeConfig = config[key];
61
77
  }
62
78
  } else {
@@ -64,7 +80,6 @@ function resolveModeConfig(
64
80
  }
65
81
  }
66
82
 
67
- // $FlowFixMe Not sure how to convince flow here...
68
83
  return {
69
84
  ...generalConfig,
70
85
  ...modeConfig,
@@ -79,7 +94,7 @@ const HTTP_OPTIONS = {
79
94
  minBundleSize: 30000,
80
95
  maxParallelRequests: 6,
81
96
  disableSharedBundles: false,
82
- sharedBundleMergeThreshold: 1,
97
+ sharedBundleMerge: [],
83
98
  },
84
99
  '2': {
85
100
  minBundles: 1,
@@ -87,9 +102,9 @@ const HTTP_OPTIONS = {
87
102
  minBundleSize: 20000,
88
103
  maxParallelRequests: 25,
89
104
  disableSharedBundles: false,
90
- sharedBundleMergeThreshold: 1,
105
+ sharedBundleMerge: [],
91
106
  },
92
- };
107
+ } as const;
93
108
 
94
109
  const CONFIG_SCHEMA: SchemaEntity = {
95
110
  type: 'object',
@@ -129,6 +144,50 @@ const CONFIG_SCHEMA: SchemaEntity = {
129
144
  additionalProperties: false,
130
145
  },
131
146
  },
147
+ sharedBundleMerge: {
148
+ type: 'array',
149
+ items: {
150
+ type: 'object',
151
+ properties: {
152
+ overlapThreshold: {
153
+ type: 'number',
154
+ },
155
+ maxBundleSize: {
156
+ type: 'number',
157
+ },
158
+ sourceBundles: {
159
+ type: 'array',
160
+ items: {
161
+ type: 'string',
162
+ },
163
+ },
164
+ minBundlesInGroup: {
165
+ type: 'number',
166
+ },
167
+ },
168
+ additionalProperties: false,
169
+ },
170
+ },
171
+ asyncBundleMerge: {
172
+ type: 'object',
173
+ properties: {
174
+ bundleSize: {
175
+ type: 'number',
176
+ required: true,
177
+ },
178
+ maxOverfetchSize: {
179
+ type: 'number',
180
+ required: true,
181
+ },
182
+ ignore: {
183
+ type: 'array',
184
+ items: {
185
+ type: 'string',
186
+ },
187
+ },
188
+ },
189
+ additionalProperties: false,
190
+ },
132
191
  minBundles: {
133
192
  type: 'number',
134
193
  },
@@ -172,7 +231,8 @@ export async function loadBundlerConfig(
172
231
  const modDefault = {
173
232
  ...HTTP_OPTIONS['2'],
174
233
  projectRoot: options.projectRoot,
175
- };
234
+ } as const;
235
+ // @ts-expect-error TS2322
176
236
  return modDefault;
177
237
  }
178
238
 
@@ -226,7 +286,7 @@ export async function loadBundlerConfig(
226
286
  CONFIG_SCHEMA,
227
287
  {
228
288
  data: modeConfig,
229
- source: await options.inputFS.readFile(conf.filePath, 'utf8'),
289
+ source: () => options.inputFS.readFileSync(conf.filePath, 'utf8'),
230
290
  filePath: conf.filePath,
231
291
  prependKey: `/${encodeJSONKeyComponent('@atlaspack/bundler-default')}`,
232
292
  },
@@ -235,14 +295,15 @@ export async function loadBundlerConfig(
235
295
  );
236
296
 
237
297
  let http = modeConfig.http ?? 2;
298
+ // @ts-expect-error TS7053
238
299
  let defaults = HTTP_OPTIONS[http];
239
300
 
240
301
  return {
241
302
  minBundles: modeConfig.minBundles ?? defaults.minBundles,
242
303
  minBundleSize: modeConfig.minBundleSize ?? defaults.minBundleSize,
243
- sharedBundleMergeThreshold:
244
- modeConfig.sharedBundleMergeThreshold ??
245
- defaults.sharedBundleMergeThreshold,
304
+ sharedBundleMerge:
305
+ modeConfig.sharedBundleMerge ?? defaults.sharedBundleMerge,
306
+ asyncBundleMerge: modeConfig.asyncBundleMerge,
246
307
  maxParallelRequests:
247
308
  modeConfig.maxParallelRequests ?? defaults.maxParallelRequests,
248
309
  projectRoot: options.projectRoot,
@@ -1,11 +1,9 @@
1
- // @flow strict-local
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,
7
5
  MutableBundleGraph,
8
- } from '@atlaspack/types';
6
+ } from '@atlaspack/types-internal';
9
7
  import {getFeatureFlag} from '@atlaspack/feature-flags';
10
8
  import invariant from 'assert';
11
9
  import nullthrows from 'nullthrows';
@@ -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
- bundleGraph.addBundleToBundleGroup(bundle, bundleGroup);
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),