rollup 3.12.1 → 3.13.0
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/dist/bin/rollup +2 -2
- package/dist/es/rollup.js +2 -2
- package/dist/es/shared/rollup.js +168 -64
- package/dist/es/shared/watch.js +2 -2
- package/dist/loadConfigFile.js +2 -2
- package/dist/rollup.js +2 -2
- package/dist/shared/index.js +2 -2
- package/dist/shared/loadConfigFile.js +2 -2
- package/dist/shared/rollup.js +168 -64
- package/dist/shared/watch-cli.js +2 -2
- package/dist/shared/watch.js +2 -2
- package/package.json +1 -1
package/dist/bin/rollup
CHANGED
package/dist/es/rollup.js
CHANGED
package/dist/es/shared/rollup.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
@license
|
|
3
|
-
Rollup.js v3.
|
|
4
|
-
|
|
3
|
+
Rollup.js v3.13.0
|
|
4
|
+
Fri, 03 Feb 2023 12:52:06 GMT - commit 45980b51bc13f52a9583d6c898814040f4ee9128
|
|
5
5
|
|
|
6
6
|
https://github.com/rollup/rollup
|
|
7
7
|
|
|
@@ -16,7 +16,7 @@ import { lstat, realpath, readdir, readFile, mkdir, writeFile } from 'node:fs/pr
|
|
|
16
16
|
import { EventEmitter } from 'node:events';
|
|
17
17
|
import * as tty from 'tty';
|
|
18
18
|
|
|
19
|
-
var version$1 = "3.
|
|
19
|
+
var version$1 = "3.13.0";
|
|
20
20
|
|
|
21
21
|
const comma = ','.charCodeAt(0);
|
|
22
22
|
const semicolon = ';'.charCodeAt(0);
|
|
@@ -11419,12 +11419,14 @@ class PrivateIdentifier extends NodeBase {
|
|
|
11419
11419
|
class Program extends NodeBase {
|
|
11420
11420
|
constructor() {
|
|
11421
11421
|
super(...arguments);
|
|
11422
|
-
this.hasCachedEffect =
|
|
11422
|
+
this.hasCachedEffect = null;
|
|
11423
|
+
}
|
|
11424
|
+
hasCachedEffects() {
|
|
11425
|
+
return this.hasCachedEffect === null
|
|
11426
|
+
? (this.hasCachedEffect = this.hasEffects(createHasEffectsContext()))
|
|
11427
|
+
: this.hasCachedEffect;
|
|
11423
11428
|
}
|
|
11424
11429
|
hasEffects(context) {
|
|
11425
|
-
// We are caching here to later more efficiently identify side-effect-free modules
|
|
11426
|
-
if (this.hasCachedEffect)
|
|
11427
|
-
return true;
|
|
11428
11430
|
for (const node of this.body) {
|
|
11429
11431
|
if (node.hasEffects(context)) {
|
|
11430
11432
|
return (this.hasCachedEffect = true);
|
|
@@ -13322,8 +13324,7 @@ class Module {
|
|
|
13322
13324
|
return [null];
|
|
13323
13325
|
}
|
|
13324
13326
|
hasEffects() {
|
|
13325
|
-
return
|
|
13326
|
-
(this.ast.included && this.ast.hasEffects(createHasEffectsContext())));
|
|
13327
|
+
return this.info.moduleSideEffects === 'no-treeshake' || this.ast.hasCachedEffects();
|
|
13327
13328
|
}
|
|
13328
13329
|
include() {
|
|
13329
13330
|
const context = createInclusionContext();
|
|
@@ -16041,7 +16042,7 @@ const resolveFileName = (dependency) => dependency.getFileName();
|
|
|
16041
16042
|
* their iterators. Useful when e.g. working with large sets or lists and when
|
|
16042
16043
|
* there is a chance that the iterators will not be fully exhausted.
|
|
16043
16044
|
*/
|
|
16044
|
-
function* concatLazy(
|
|
16045
|
+
function* concatLazy(iterables) {
|
|
16045
16046
|
for (const iterable of iterables) {
|
|
16046
16047
|
yield* iterable;
|
|
16047
16048
|
}
|
|
@@ -16182,47 +16183,11 @@ function createChunks(allEntries, assignedEntriesByModule, minChunkSize) {
|
|
|
16182
16183
|
alias: null,
|
|
16183
16184
|
modules
|
|
16184
16185
|
}))
|
|
16185
|
-
: getOptimizedChunks(chunkModulesBySignature, minChunkSize)
|
|
16186
|
-
|
|
16187
|
-
|
|
16188
|
-
|
|
16189
|
-
const { chunksToBeMerged, unmergeableChunks } = getMergeableChunks(chunkModulesBySignature, minChunkSize);
|
|
16190
|
-
for (const sourceChunk of chunksToBeMerged) {
|
|
16191
|
-
chunksToBeMerged.delete(sourceChunk);
|
|
16192
|
-
let closestChunk = null;
|
|
16193
|
-
let closestChunkDistance = Infinity;
|
|
16194
|
-
const { signature, size, modules } = sourceChunk;
|
|
16195
|
-
for (const targetChunk of concatLazy(chunksToBeMerged, unmergeableChunks)) {
|
|
16196
|
-
const distance = getSignatureDistance(signature, targetChunk.signature, !chunksToBeMerged.has(targetChunk));
|
|
16197
|
-
if (distance === 1) {
|
|
16198
|
-
closestChunk = targetChunk;
|
|
16199
|
-
break;
|
|
16200
|
-
}
|
|
16201
|
-
else if (distance < closestChunkDistance) {
|
|
16202
|
-
closestChunk = targetChunk;
|
|
16203
|
-
closestChunkDistance = distance;
|
|
16204
|
-
}
|
|
16205
|
-
}
|
|
16206
|
-
if (closestChunk) {
|
|
16207
|
-
closestChunk.modules.push(...modules);
|
|
16208
|
-
if (chunksToBeMerged.has(closestChunk)) {
|
|
16209
|
-
closestChunk.signature = mergeSignatures(signature, closestChunk.signature);
|
|
16210
|
-
if ((closestChunk.size += size) > minChunkSize) {
|
|
16211
|
-
chunksToBeMerged.delete(closestChunk);
|
|
16212
|
-
unmergeableChunks.push(closestChunk);
|
|
16213
|
-
}
|
|
16214
|
-
}
|
|
16215
|
-
}
|
|
16216
|
-
else {
|
|
16217
|
-
unmergeableChunks.push(sourceChunk);
|
|
16218
|
-
}
|
|
16219
|
-
}
|
|
16220
|
-
timeEnd('optimize chunks', 3);
|
|
16221
|
-
return unmergeableChunks;
|
|
16186
|
+
: getOptimizedChunks(chunkModulesBySignature, minChunkSize).map(({ modules }) => ({
|
|
16187
|
+
alias: null,
|
|
16188
|
+
modules
|
|
16189
|
+
}));
|
|
16222
16190
|
}
|
|
16223
|
-
const CHAR_DEPENDENT = 'X';
|
|
16224
|
-
const CHAR_INDEPENDENT = '_';
|
|
16225
|
-
const CHAR_CODE_DEPENDENT = CHAR_DEPENDENT.charCodeAt(0);
|
|
16226
16191
|
function getChunkModulesBySignature(assignedEntriesByModule, allEntries) {
|
|
16227
16192
|
const chunkModules = Object.create(null);
|
|
16228
16193
|
for (const [module, assignedEntries] of assignedEntriesByModule) {
|
|
@@ -16240,28 +16205,167 @@ function getChunkModulesBySignature(assignedEntriesByModule, allEntries) {
|
|
|
16240
16205
|
}
|
|
16241
16206
|
return chunkModules;
|
|
16242
16207
|
}
|
|
16243
|
-
|
|
16244
|
-
|
|
16245
|
-
|
|
16246
|
-
|
|
16208
|
+
/**
|
|
16209
|
+
* This function tries to get rid of small chunks by merging them with other
|
|
16210
|
+
* chunks. In order to merge chunks, one must obey the following rule:
|
|
16211
|
+
* - When merging several chunks, at most one of the chunks can have side
|
|
16212
|
+
* effects
|
|
16213
|
+
* - When one of the chunks has side effects, the entry points depending on that
|
|
16214
|
+
* chunk need to be a super set of the entry points depending on the other
|
|
16215
|
+
* chunks
|
|
16216
|
+
* - Pure chunks can always be merged
|
|
16217
|
+
* - We use the entry point dependence signature to calculate "chunk distance",
|
|
16218
|
+
* i.e. how likely it is that two chunks are loaded together
|
|
16219
|
+
*/
|
|
16220
|
+
function getOptimizedChunks(chunkModulesBySignature, minChunkSize) {
|
|
16221
|
+
timeStart('optimize chunks', 3);
|
|
16222
|
+
const chunkPartition = getPartitionedChunks(chunkModulesBySignature, minChunkSize);
|
|
16223
|
+
if (chunkPartition.small.sideEffect.size > 0) {
|
|
16224
|
+
mergeChunks(chunkPartition.small.sideEffect, [chunkPartition.small.pure, chunkPartition.big.pure], minChunkSize, chunkPartition);
|
|
16225
|
+
}
|
|
16226
|
+
if (chunkPartition.small.pure.size > 0) {
|
|
16227
|
+
mergeChunks(chunkPartition.small.pure, [chunkPartition.small.pure, chunkPartition.big.sideEffect, chunkPartition.big.pure], minChunkSize, chunkPartition);
|
|
16228
|
+
}
|
|
16229
|
+
timeEnd('optimize chunks', 3);
|
|
16230
|
+
return [
|
|
16231
|
+
...chunkPartition.small.sideEffect,
|
|
16232
|
+
...chunkPartition.small.pure,
|
|
16233
|
+
...chunkPartition.big.sideEffect,
|
|
16234
|
+
...chunkPartition.big.pure
|
|
16235
|
+
];
|
|
16236
|
+
}
|
|
16237
|
+
const CHAR_DEPENDENT = 'X';
|
|
16238
|
+
const CHAR_INDEPENDENT = '_';
|
|
16239
|
+
const CHAR_CODE_DEPENDENT = CHAR_DEPENDENT.charCodeAt(0);
|
|
16240
|
+
function getPartitionedChunks(chunkModulesBySignature, minChunkSize) {
|
|
16241
|
+
const smallPureChunks = [];
|
|
16242
|
+
const bigPureChunks = [];
|
|
16243
|
+
const smallSideEffectChunks = [];
|
|
16244
|
+
const bigSideEffectChunks = [];
|
|
16245
|
+
const chunkByModule = new Map();
|
|
16247
16246
|
for (const [signature, modules] of Object.entries(chunkModulesBySignature)) {
|
|
16247
|
+
const chunkDescription = {
|
|
16248
|
+
dependencies: new Set(),
|
|
16249
|
+
dependentChunks: new Set(),
|
|
16250
|
+
modules,
|
|
16251
|
+
pure: true,
|
|
16252
|
+
signature,
|
|
16253
|
+
size: 0
|
|
16254
|
+
};
|
|
16248
16255
|
let size = 0;
|
|
16249
|
-
|
|
16256
|
+
let pure = true;
|
|
16257
|
+
for (const module of modules) {
|
|
16258
|
+
chunkByModule.set(module, chunkDescription);
|
|
16259
|
+
pure && (pure = !module.hasEffects());
|
|
16260
|
+
// Unfortunately, we cannot take tree-shaking into account here because
|
|
16261
|
+
// rendering did not happen yet
|
|
16262
|
+
size += module.originalCode.length;
|
|
16263
|
+
}
|
|
16264
|
+
chunkDescription.pure = pure;
|
|
16265
|
+
chunkDescription.size = size;
|
|
16266
|
+
(size < minChunkSize
|
|
16267
|
+
? pure
|
|
16268
|
+
? smallPureChunks
|
|
16269
|
+
: smallSideEffectChunks
|
|
16270
|
+
: pure
|
|
16271
|
+
? bigPureChunks
|
|
16272
|
+
: bigSideEffectChunks).push(chunkDescription);
|
|
16273
|
+
}
|
|
16274
|
+
sortChunksAndAddDependencies([bigPureChunks, bigSideEffectChunks, smallPureChunks, smallSideEffectChunks], chunkByModule);
|
|
16275
|
+
return {
|
|
16276
|
+
big: { pure: new Set(bigPureChunks), sideEffect: new Set(bigSideEffectChunks) },
|
|
16277
|
+
small: { pure: new Set(smallPureChunks), sideEffect: new Set(smallSideEffectChunks) }
|
|
16278
|
+
};
|
|
16279
|
+
}
|
|
16280
|
+
function sortChunksAndAddDependencies(chunkLists, chunkByModule) {
|
|
16281
|
+
for (const chunks of chunkLists) {
|
|
16282
|
+
chunks.sort(compareChunks);
|
|
16283
|
+
for (const chunk of chunks) {
|
|
16284
|
+
const { dependencies, modules } = chunk;
|
|
16250
16285
|
for (const module of modules) {
|
|
16251
|
-
|
|
16252
|
-
|
|
16286
|
+
for (const dependency of module.getDependenciesToBeIncluded()) {
|
|
16287
|
+
const dependencyChunk = chunkByModule.get(dependency);
|
|
16288
|
+
if (dependencyChunk && dependencyChunk !== chunk) {
|
|
16289
|
+
dependencies.add(dependencyChunk);
|
|
16290
|
+
dependencyChunk.dependentChunks.add(chunk);
|
|
16291
|
+
}
|
|
16253
16292
|
}
|
|
16254
|
-
|
|
16255
|
-
|
|
16256
|
-
|
|
16293
|
+
}
|
|
16294
|
+
}
|
|
16295
|
+
}
|
|
16296
|
+
}
|
|
16297
|
+
function compareChunks({ size: sizeA }, { size: sizeB }) {
|
|
16298
|
+
return sizeA - sizeB;
|
|
16299
|
+
}
|
|
16300
|
+
function mergeChunks(chunksToBeMerged, targetChunks, minChunkSize, chunkPartition) {
|
|
16301
|
+
for (const mergedChunk of chunksToBeMerged) {
|
|
16302
|
+
let closestChunk = null;
|
|
16303
|
+
let closestChunkDistance = Infinity;
|
|
16304
|
+
const { signature, modules, pure, size } = mergedChunk;
|
|
16305
|
+
for (const targetChunk of concatLazy(targetChunks)) {
|
|
16306
|
+
if (mergedChunk === targetChunk)
|
|
16307
|
+
continue;
|
|
16308
|
+
// Possible improvement:
|
|
16309
|
+
// For dynamic entries depending on a pure chunk, it is safe to merge that
|
|
16310
|
+
// chunk into the chunk doing the dynamic import (i.e. into an "already
|
|
16311
|
+
// loaded chunk") even if it is not pure.
|
|
16312
|
+
// One way of handling this could be to add all "already loaded entries"
|
|
16313
|
+
// of the dynamic importers into the signature as well. That could also
|
|
16314
|
+
// change the way we do code-splitting for already loaded entries.
|
|
16315
|
+
const distance = pure
|
|
16316
|
+
? getSignatureDistance(signature, targetChunk.signature, !targetChunk.pure)
|
|
16317
|
+
: getSignatureDistance(targetChunk.signature, signature, true);
|
|
16318
|
+
if (distance < closestChunkDistance && isValidMerge(mergedChunk, targetChunk)) {
|
|
16319
|
+
if (distance === 1) {
|
|
16320
|
+
closestChunk = targetChunk;
|
|
16321
|
+
break;
|
|
16257
16322
|
}
|
|
16323
|
+
closestChunk = targetChunk;
|
|
16324
|
+
closestChunkDistance = distance;
|
|
16258
16325
|
}
|
|
16259
|
-
chunksToBeMerged.add({ alias, modules, signature, size });
|
|
16260
|
-
continue;
|
|
16261
16326
|
}
|
|
16262
|
-
|
|
16327
|
+
if (closestChunk) {
|
|
16328
|
+
chunksToBeMerged.delete(mergedChunk);
|
|
16329
|
+
getChunksInPartition(closestChunk, minChunkSize, chunkPartition).delete(closestChunk);
|
|
16330
|
+
closestChunk.modules.push(...modules);
|
|
16331
|
+
closestChunk.size += size;
|
|
16332
|
+
closestChunk.pure && (closestChunk.pure = pure);
|
|
16333
|
+
closestChunk.signature = mergeSignatures(signature, closestChunk.signature);
|
|
16334
|
+
const { dependencies, dependentChunks } = closestChunk;
|
|
16335
|
+
for (const dependency of mergedChunk.dependencies) {
|
|
16336
|
+
dependencies.add(dependency);
|
|
16337
|
+
}
|
|
16338
|
+
for (const dependentChunk of mergedChunk.dependentChunks) {
|
|
16339
|
+
dependentChunks.add(dependentChunk);
|
|
16340
|
+
dependentChunk.dependencies.delete(mergedChunk);
|
|
16341
|
+
dependentChunk.dependencies.add(closestChunk);
|
|
16342
|
+
}
|
|
16343
|
+
dependencies.delete(closestChunk);
|
|
16344
|
+
getChunksInPartition(closestChunk, minChunkSize, chunkPartition).add(closestChunk);
|
|
16345
|
+
}
|
|
16263
16346
|
}
|
|
16264
|
-
|
|
16347
|
+
}
|
|
16348
|
+
// Merging will not produce cycles if none of the direct non-merged dependencies
|
|
16349
|
+
// of a chunk have the other chunk as a transitive dependency
|
|
16350
|
+
function isValidMerge(mergedChunk, targetChunk) {
|
|
16351
|
+
return !(hasTransitiveDependency(mergedChunk, targetChunk) ||
|
|
16352
|
+
hasTransitiveDependency(targetChunk, mergedChunk));
|
|
16353
|
+
}
|
|
16354
|
+
function hasTransitiveDependency(dependentChunk, dependencyChunk) {
|
|
16355
|
+
const chunksToCheck = new Set(dependentChunk.dependencies);
|
|
16356
|
+
for (const { dependencies } of chunksToCheck) {
|
|
16357
|
+
for (const dependency of dependencies) {
|
|
16358
|
+
if (dependency === dependencyChunk) {
|
|
16359
|
+
return true;
|
|
16360
|
+
}
|
|
16361
|
+
chunksToCheck.add(dependency);
|
|
16362
|
+
}
|
|
16363
|
+
}
|
|
16364
|
+
return false;
|
|
16365
|
+
}
|
|
16366
|
+
function getChunksInPartition(chunk, minChunkSize, chunkPartition) {
|
|
16367
|
+
const subPartition = chunk.size < minChunkSize ? chunkPartition.small : chunkPartition.big;
|
|
16368
|
+
return chunk.pure ? subPartition.pure : subPartition.sideEffect;
|
|
16265
16369
|
}
|
|
16266
16370
|
function getSignatureDistance(sourceSignature, targetSignature, enforceSubset) {
|
|
16267
16371
|
let distance = 0;
|
package/dist/es/shared/watch.js
CHANGED
package/dist/loadConfigFile.js
CHANGED
package/dist/rollup.js
CHANGED
package/dist/shared/index.js
CHANGED
package/dist/shared/rollup.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
@license
|
|
3
|
-
Rollup.js v3.
|
|
4
|
-
|
|
3
|
+
Rollup.js v3.13.0
|
|
4
|
+
Fri, 03 Feb 2023 12:52:06 GMT - commit 45980b51bc13f52a9583d6c898814040f4ee9128
|
|
5
5
|
|
|
6
6
|
https://github.com/rollup/rollup
|
|
7
7
|
|
|
@@ -31,7 +31,7 @@ function _interopNamespaceDefault(e) {
|
|
|
31
31
|
|
|
32
32
|
const tty__namespace = /*#__PURE__*/_interopNamespaceDefault(tty);
|
|
33
33
|
|
|
34
|
-
var version$1 = "3.
|
|
34
|
+
var version$1 = "3.13.0";
|
|
35
35
|
|
|
36
36
|
function ensureArray$1(items) {
|
|
37
37
|
if (Array.isArray(items)) {
|
|
@@ -11937,12 +11937,14 @@ class PrivateIdentifier extends NodeBase {
|
|
|
11937
11937
|
class Program extends NodeBase {
|
|
11938
11938
|
constructor() {
|
|
11939
11939
|
super(...arguments);
|
|
11940
|
-
this.hasCachedEffect =
|
|
11940
|
+
this.hasCachedEffect = null;
|
|
11941
|
+
}
|
|
11942
|
+
hasCachedEffects() {
|
|
11943
|
+
return this.hasCachedEffect === null
|
|
11944
|
+
? (this.hasCachedEffect = this.hasEffects(createHasEffectsContext()))
|
|
11945
|
+
: this.hasCachedEffect;
|
|
11941
11946
|
}
|
|
11942
11947
|
hasEffects(context) {
|
|
11943
|
-
// We are caching here to later more efficiently identify side-effect-free modules
|
|
11944
|
-
if (this.hasCachedEffect)
|
|
11945
|
-
return true;
|
|
11946
11948
|
for (const node of this.body) {
|
|
11947
11949
|
if (node.hasEffects(context)) {
|
|
11948
11950
|
return (this.hasCachedEffect = true);
|
|
@@ -13840,8 +13842,7 @@ class Module {
|
|
|
13840
13842
|
return [null];
|
|
13841
13843
|
}
|
|
13842
13844
|
hasEffects() {
|
|
13843
|
-
return
|
|
13844
|
-
(this.ast.included && this.ast.hasEffects(createHasEffectsContext())));
|
|
13845
|
+
return this.info.moduleSideEffects === 'no-treeshake' || this.ast.hasCachedEffects();
|
|
13845
13846
|
}
|
|
13846
13847
|
include() {
|
|
13847
13848
|
const context = createInclusionContext();
|
|
@@ -16559,7 +16560,7 @@ const resolveFileName = (dependency) => dependency.getFileName();
|
|
|
16559
16560
|
* their iterators. Useful when e.g. working with large sets or lists and when
|
|
16560
16561
|
* there is a chance that the iterators will not be fully exhausted.
|
|
16561
16562
|
*/
|
|
16562
|
-
function* concatLazy(
|
|
16563
|
+
function* concatLazy(iterables) {
|
|
16563
16564
|
for (const iterable of iterables) {
|
|
16564
16565
|
yield* iterable;
|
|
16565
16566
|
}
|
|
@@ -16700,47 +16701,11 @@ function createChunks(allEntries, assignedEntriesByModule, minChunkSize) {
|
|
|
16700
16701
|
alias: null,
|
|
16701
16702
|
modules
|
|
16702
16703
|
}))
|
|
16703
|
-
: getOptimizedChunks(chunkModulesBySignature, minChunkSize)
|
|
16704
|
-
|
|
16705
|
-
|
|
16706
|
-
|
|
16707
|
-
const { chunksToBeMerged, unmergeableChunks } = getMergeableChunks(chunkModulesBySignature, minChunkSize);
|
|
16708
|
-
for (const sourceChunk of chunksToBeMerged) {
|
|
16709
|
-
chunksToBeMerged.delete(sourceChunk);
|
|
16710
|
-
let closestChunk = null;
|
|
16711
|
-
let closestChunkDistance = Infinity;
|
|
16712
|
-
const { signature, size, modules } = sourceChunk;
|
|
16713
|
-
for (const targetChunk of concatLazy(chunksToBeMerged, unmergeableChunks)) {
|
|
16714
|
-
const distance = getSignatureDistance(signature, targetChunk.signature, !chunksToBeMerged.has(targetChunk));
|
|
16715
|
-
if (distance === 1) {
|
|
16716
|
-
closestChunk = targetChunk;
|
|
16717
|
-
break;
|
|
16718
|
-
}
|
|
16719
|
-
else if (distance < closestChunkDistance) {
|
|
16720
|
-
closestChunk = targetChunk;
|
|
16721
|
-
closestChunkDistance = distance;
|
|
16722
|
-
}
|
|
16723
|
-
}
|
|
16724
|
-
if (closestChunk) {
|
|
16725
|
-
closestChunk.modules.push(...modules);
|
|
16726
|
-
if (chunksToBeMerged.has(closestChunk)) {
|
|
16727
|
-
closestChunk.signature = mergeSignatures(signature, closestChunk.signature);
|
|
16728
|
-
if ((closestChunk.size += size) > minChunkSize) {
|
|
16729
|
-
chunksToBeMerged.delete(closestChunk);
|
|
16730
|
-
unmergeableChunks.push(closestChunk);
|
|
16731
|
-
}
|
|
16732
|
-
}
|
|
16733
|
-
}
|
|
16734
|
-
else {
|
|
16735
|
-
unmergeableChunks.push(sourceChunk);
|
|
16736
|
-
}
|
|
16737
|
-
}
|
|
16738
|
-
timeEnd('optimize chunks', 3);
|
|
16739
|
-
return unmergeableChunks;
|
|
16704
|
+
: getOptimizedChunks(chunkModulesBySignature, minChunkSize).map(({ modules }) => ({
|
|
16705
|
+
alias: null,
|
|
16706
|
+
modules
|
|
16707
|
+
}));
|
|
16740
16708
|
}
|
|
16741
|
-
const CHAR_DEPENDENT = 'X';
|
|
16742
|
-
const CHAR_INDEPENDENT = '_';
|
|
16743
|
-
const CHAR_CODE_DEPENDENT = CHAR_DEPENDENT.charCodeAt(0);
|
|
16744
16709
|
function getChunkModulesBySignature(assignedEntriesByModule, allEntries) {
|
|
16745
16710
|
const chunkModules = Object.create(null);
|
|
16746
16711
|
for (const [module, assignedEntries] of assignedEntriesByModule) {
|
|
@@ -16758,28 +16723,167 @@ function getChunkModulesBySignature(assignedEntriesByModule, allEntries) {
|
|
|
16758
16723
|
}
|
|
16759
16724
|
return chunkModules;
|
|
16760
16725
|
}
|
|
16761
|
-
|
|
16762
|
-
|
|
16763
|
-
|
|
16764
|
-
|
|
16726
|
+
/**
|
|
16727
|
+
* This function tries to get rid of small chunks by merging them with other
|
|
16728
|
+
* chunks. In order to merge chunks, one must obey the following rule:
|
|
16729
|
+
* - When merging several chunks, at most one of the chunks can have side
|
|
16730
|
+
* effects
|
|
16731
|
+
* - When one of the chunks has side effects, the entry points depending on that
|
|
16732
|
+
* chunk need to be a super set of the entry points depending on the other
|
|
16733
|
+
* chunks
|
|
16734
|
+
* - Pure chunks can always be merged
|
|
16735
|
+
* - We use the entry point dependence signature to calculate "chunk distance",
|
|
16736
|
+
* i.e. how likely it is that two chunks are loaded together
|
|
16737
|
+
*/
|
|
16738
|
+
function getOptimizedChunks(chunkModulesBySignature, minChunkSize) {
|
|
16739
|
+
timeStart('optimize chunks', 3);
|
|
16740
|
+
const chunkPartition = getPartitionedChunks(chunkModulesBySignature, minChunkSize);
|
|
16741
|
+
if (chunkPartition.small.sideEffect.size > 0) {
|
|
16742
|
+
mergeChunks(chunkPartition.small.sideEffect, [chunkPartition.small.pure, chunkPartition.big.pure], minChunkSize, chunkPartition);
|
|
16743
|
+
}
|
|
16744
|
+
if (chunkPartition.small.pure.size > 0) {
|
|
16745
|
+
mergeChunks(chunkPartition.small.pure, [chunkPartition.small.pure, chunkPartition.big.sideEffect, chunkPartition.big.pure], minChunkSize, chunkPartition);
|
|
16746
|
+
}
|
|
16747
|
+
timeEnd('optimize chunks', 3);
|
|
16748
|
+
return [
|
|
16749
|
+
...chunkPartition.small.sideEffect,
|
|
16750
|
+
...chunkPartition.small.pure,
|
|
16751
|
+
...chunkPartition.big.sideEffect,
|
|
16752
|
+
...chunkPartition.big.pure
|
|
16753
|
+
];
|
|
16754
|
+
}
|
|
16755
|
+
const CHAR_DEPENDENT = 'X';
|
|
16756
|
+
const CHAR_INDEPENDENT = '_';
|
|
16757
|
+
const CHAR_CODE_DEPENDENT = CHAR_DEPENDENT.charCodeAt(0);
|
|
16758
|
+
function getPartitionedChunks(chunkModulesBySignature, minChunkSize) {
|
|
16759
|
+
const smallPureChunks = [];
|
|
16760
|
+
const bigPureChunks = [];
|
|
16761
|
+
const smallSideEffectChunks = [];
|
|
16762
|
+
const bigSideEffectChunks = [];
|
|
16763
|
+
const chunkByModule = new Map();
|
|
16765
16764
|
for (const [signature, modules] of Object.entries(chunkModulesBySignature)) {
|
|
16765
|
+
const chunkDescription = {
|
|
16766
|
+
dependencies: new Set(),
|
|
16767
|
+
dependentChunks: new Set(),
|
|
16768
|
+
modules,
|
|
16769
|
+
pure: true,
|
|
16770
|
+
signature,
|
|
16771
|
+
size: 0
|
|
16772
|
+
};
|
|
16766
16773
|
let size = 0;
|
|
16767
|
-
|
|
16774
|
+
let pure = true;
|
|
16775
|
+
for (const module of modules) {
|
|
16776
|
+
chunkByModule.set(module, chunkDescription);
|
|
16777
|
+
pure && (pure = !module.hasEffects());
|
|
16778
|
+
// Unfortunately, we cannot take tree-shaking into account here because
|
|
16779
|
+
// rendering did not happen yet
|
|
16780
|
+
size += module.originalCode.length;
|
|
16781
|
+
}
|
|
16782
|
+
chunkDescription.pure = pure;
|
|
16783
|
+
chunkDescription.size = size;
|
|
16784
|
+
(size < minChunkSize
|
|
16785
|
+
? pure
|
|
16786
|
+
? smallPureChunks
|
|
16787
|
+
: smallSideEffectChunks
|
|
16788
|
+
: pure
|
|
16789
|
+
? bigPureChunks
|
|
16790
|
+
: bigSideEffectChunks).push(chunkDescription);
|
|
16791
|
+
}
|
|
16792
|
+
sortChunksAndAddDependencies([bigPureChunks, bigSideEffectChunks, smallPureChunks, smallSideEffectChunks], chunkByModule);
|
|
16793
|
+
return {
|
|
16794
|
+
big: { pure: new Set(bigPureChunks), sideEffect: new Set(bigSideEffectChunks) },
|
|
16795
|
+
small: { pure: new Set(smallPureChunks), sideEffect: new Set(smallSideEffectChunks) }
|
|
16796
|
+
};
|
|
16797
|
+
}
|
|
16798
|
+
function sortChunksAndAddDependencies(chunkLists, chunkByModule) {
|
|
16799
|
+
for (const chunks of chunkLists) {
|
|
16800
|
+
chunks.sort(compareChunks);
|
|
16801
|
+
for (const chunk of chunks) {
|
|
16802
|
+
const { dependencies, modules } = chunk;
|
|
16768
16803
|
for (const module of modules) {
|
|
16769
|
-
|
|
16770
|
-
|
|
16804
|
+
for (const dependency of module.getDependenciesToBeIncluded()) {
|
|
16805
|
+
const dependencyChunk = chunkByModule.get(dependency);
|
|
16806
|
+
if (dependencyChunk && dependencyChunk !== chunk) {
|
|
16807
|
+
dependencies.add(dependencyChunk);
|
|
16808
|
+
dependencyChunk.dependentChunks.add(chunk);
|
|
16809
|
+
}
|
|
16771
16810
|
}
|
|
16772
|
-
|
|
16773
|
-
|
|
16774
|
-
|
|
16811
|
+
}
|
|
16812
|
+
}
|
|
16813
|
+
}
|
|
16814
|
+
}
|
|
16815
|
+
function compareChunks({ size: sizeA }, { size: sizeB }) {
|
|
16816
|
+
return sizeA - sizeB;
|
|
16817
|
+
}
|
|
16818
|
+
function mergeChunks(chunksToBeMerged, targetChunks, minChunkSize, chunkPartition) {
|
|
16819
|
+
for (const mergedChunk of chunksToBeMerged) {
|
|
16820
|
+
let closestChunk = null;
|
|
16821
|
+
let closestChunkDistance = Infinity;
|
|
16822
|
+
const { signature, modules, pure, size } = mergedChunk;
|
|
16823
|
+
for (const targetChunk of concatLazy(targetChunks)) {
|
|
16824
|
+
if (mergedChunk === targetChunk)
|
|
16825
|
+
continue;
|
|
16826
|
+
// Possible improvement:
|
|
16827
|
+
// For dynamic entries depending on a pure chunk, it is safe to merge that
|
|
16828
|
+
// chunk into the chunk doing the dynamic import (i.e. into an "already
|
|
16829
|
+
// loaded chunk") even if it is not pure.
|
|
16830
|
+
// One way of handling this could be to add all "already loaded entries"
|
|
16831
|
+
// of the dynamic importers into the signature as well. That could also
|
|
16832
|
+
// change the way we do code-splitting for already loaded entries.
|
|
16833
|
+
const distance = pure
|
|
16834
|
+
? getSignatureDistance(signature, targetChunk.signature, !targetChunk.pure)
|
|
16835
|
+
: getSignatureDistance(targetChunk.signature, signature, true);
|
|
16836
|
+
if (distance < closestChunkDistance && isValidMerge(mergedChunk, targetChunk)) {
|
|
16837
|
+
if (distance === 1) {
|
|
16838
|
+
closestChunk = targetChunk;
|
|
16839
|
+
break;
|
|
16775
16840
|
}
|
|
16841
|
+
closestChunk = targetChunk;
|
|
16842
|
+
closestChunkDistance = distance;
|
|
16776
16843
|
}
|
|
16777
|
-
chunksToBeMerged.add({ alias, modules, signature, size });
|
|
16778
|
-
continue;
|
|
16779
16844
|
}
|
|
16780
|
-
|
|
16845
|
+
if (closestChunk) {
|
|
16846
|
+
chunksToBeMerged.delete(mergedChunk);
|
|
16847
|
+
getChunksInPartition(closestChunk, minChunkSize, chunkPartition).delete(closestChunk);
|
|
16848
|
+
closestChunk.modules.push(...modules);
|
|
16849
|
+
closestChunk.size += size;
|
|
16850
|
+
closestChunk.pure && (closestChunk.pure = pure);
|
|
16851
|
+
closestChunk.signature = mergeSignatures(signature, closestChunk.signature);
|
|
16852
|
+
const { dependencies, dependentChunks } = closestChunk;
|
|
16853
|
+
for (const dependency of mergedChunk.dependencies) {
|
|
16854
|
+
dependencies.add(dependency);
|
|
16855
|
+
}
|
|
16856
|
+
for (const dependentChunk of mergedChunk.dependentChunks) {
|
|
16857
|
+
dependentChunks.add(dependentChunk);
|
|
16858
|
+
dependentChunk.dependencies.delete(mergedChunk);
|
|
16859
|
+
dependentChunk.dependencies.add(closestChunk);
|
|
16860
|
+
}
|
|
16861
|
+
dependencies.delete(closestChunk);
|
|
16862
|
+
getChunksInPartition(closestChunk, minChunkSize, chunkPartition).add(closestChunk);
|
|
16863
|
+
}
|
|
16781
16864
|
}
|
|
16782
|
-
|
|
16865
|
+
}
|
|
16866
|
+
// Merging will not produce cycles if none of the direct non-merged dependencies
|
|
16867
|
+
// of a chunk have the other chunk as a transitive dependency
|
|
16868
|
+
function isValidMerge(mergedChunk, targetChunk) {
|
|
16869
|
+
return !(hasTransitiveDependency(mergedChunk, targetChunk) ||
|
|
16870
|
+
hasTransitiveDependency(targetChunk, mergedChunk));
|
|
16871
|
+
}
|
|
16872
|
+
function hasTransitiveDependency(dependentChunk, dependencyChunk) {
|
|
16873
|
+
const chunksToCheck = new Set(dependentChunk.dependencies);
|
|
16874
|
+
for (const { dependencies } of chunksToCheck) {
|
|
16875
|
+
for (const dependency of dependencies) {
|
|
16876
|
+
if (dependency === dependencyChunk) {
|
|
16877
|
+
return true;
|
|
16878
|
+
}
|
|
16879
|
+
chunksToCheck.add(dependency);
|
|
16880
|
+
}
|
|
16881
|
+
}
|
|
16882
|
+
return false;
|
|
16883
|
+
}
|
|
16884
|
+
function getChunksInPartition(chunk, minChunkSize, chunkPartition) {
|
|
16885
|
+
const subPartition = chunk.size < minChunkSize ? chunkPartition.small : chunkPartition.big;
|
|
16886
|
+
return chunk.pure ? subPartition.pure : subPartition.sideEffect;
|
|
16783
16887
|
}
|
|
16784
16888
|
function getSignatureDistance(sourceSignature, targetSignature, enforceSubset) {
|
|
16785
16889
|
let distance = 0;
|
package/dist/shared/watch-cli.js
CHANGED
package/dist/shared/watch.js
CHANGED