rollup 3.21.6 → 3.22.0-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 CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  /*
4
4
  @license
5
- Rollup.js v3.21.6
6
- Tue, 09 May 2023 20:05:04 GMT - commit fa5af3756fbabec7e9a5d082550c710c491e85e9
5
+ Rollup.js v3.22.0-0
6
+ Sat, 13 May 2023 13:21:30 GMT - commit b7e90ac1d307b0549254f282ccf7eb7ead6f93de
7
7
 
8
8
  https://github.com/rollup/rollup
9
9
 
package/dist/es/rollup.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v3.21.6
4
- Tue, 09 May 2023 20:05:04 GMT - commit fa5af3756fbabec7e9a5d082550c710c491e85e9
3
+ Rollup.js v3.22.0-0
4
+ Sat, 13 May 2023 13:21:30 GMT - commit b7e90ac1d307b0549254f282ccf7eb7ead6f93de
5
5
 
6
6
  https://github.com/rollup/rollup
7
7
 
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v3.21.6
4
- Tue, 09 May 2023 20:05:04 GMT - commit fa5af3756fbabec7e9a5d082550c710c491e85e9
3
+ Rollup.js v3.22.0-0
4
+ Sat, 13 May 2023 13:21:30 GMT - commit b7e90ac1d307b0549254f282ccf7eb7ead6f93de
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.21.6";
19
+ var version$1 = "3.22.0-0";
20
20
 
21
21
  const comma = ','.charCodeAt(0);
22
22
  const semicolon = ';'.charCodeAt(0);
@@ -13451,6 +13451,16 @@ class Module {
13451
13451
  this.addLocationToLogProps(properties, pos);
13452
13452
  return error(properties);
13453
13453
  }
13454
+ // sum up the length of all ast nodes that are included
13455
+ estimateSize() {
13456
+ let size = 0;
13457
+ for (const node of this.ast.body) {
13458
+ if (node.included) {
13459
+ size += node.end - node.start;
13460
+ }
13461
+ }
13462
+ return size;
13463
+ }
13454
13464
  getAllExportNames() {
13455
13465
  if (this.allExportNames) {
13456
13466
  return this.allExportNames;
@@ -15488,13 +15498,18 @@ class Chunk {
15488
15498
  }
15489
15499
  canModuleBeFacade(module, exposedVariables) {
15490
15500
  const moduleExportNamesByVariable = module.getExportNamesByVariable();
15501
+ // All exports of this chunk need to be exposed by the candidate module
15491
15502
  for (const exposedVariable of this.exports) {
15492
15503
  if (!moduleExportNamesByVariable.has(exposedVariable)) {
15493
15504
  return false;
15494
15505
  }
15495
15506
  }
15507
+ // Additionally, we need to expose namespaces of dynamic entries that are not the facade module and exports from other entry modules
15496
15508
  for (const exposedVariable of exposedVariables) {
15497
- if (!(moduleExportNamesByVariable.has(exposedVariable) || exposedVariable.module === module)) {
15509
+ if (!(exposedVariable.module === module ||
15510
+ moduleExportNamesByVariable.has(exposedVariable) ||
15511
+ (exposedVariable instanceof SyntheticNamedExportVariable &&
15512
+ moduleExportNamesByVariable.has(exposedVariable.getBaseVariable())))) {
15498
15513
  return false;
15499
15514
  }
15500
15515
  }
@@ -15549,7 +15564,10 @@ class Chunk {
15549
15564
  for (const module of entryModules) {
15550
15565
  if (module.preserveSignature) {
15551
15566
  for (const exportedVariable of module.getExportNamesByVariable().keys()) {
15552
- exposedVariables.add(exportedVariable);
15567
+ // We need to expose all entry exports from this chunk
15568
+ if (this.chunkByModule.get(exportedVariable.module) === this) {
15569
+ exposedVariables.add(exportedVariable);
15570
+ }
15553
15571
  }
15554
15572
  }
15555
15573
  }
@@ -16526,11 +16544,14 @@ function getChunkAssignments(entries, manualChunkAliasByEntry, minChunkSize) {
16526
16544
  const { chunkDefinitions, modulesInManualChunks } = getChunkDefinitionsFromManualChunks(manualChunkAliasByEntry);
16527
16545
  const { allEntries, dependentEntriesByModule, dynamicallyDependentEntriesByDynamicEntry, dynamicImportsByEntry } = analyzeModuleGraph(entries);
16528
16546
  // Each chunk is identified by its position in this array
16529
- const initialChunks = Object.values(getChunksBySignature(getModulesWithDependentEntries(dependentEntriesByModule, modulesInManualChunks)));
16547
+ const initialChunks = getChunksFromDependentEntries(getModulesWithDependentEntries(dependentEntriesByModule, modulesInManualChunks));
16530
16548
  // This mutates initialChunks but also clears
16531
16549
  // dynamicallyDependentEntriesByDynamicEntry as side effect
16532
16550
  removeUnnecessaryDependentEntries(initialChunks, dynamicallyDependentEntriesByDynamicEntry, dynamicImportsByEntry, allEntries);
16533
- chunkDefinitions.push(...createChunks(allEntries, getChunksBySignature(initialChunks), minChunkSize));
16551
+ chunkDefinitions.push(...getOptimizedChunks(getChunksFromDependentEntries(initialChunks), allEntries.length, minChunkSize).map(({ modules }) => ({
16552
+ alias: null,
16553
+ modules
16554
+ })));
16534
16555
  return chunkDefinitions;
16535
16556
  }
16536
16557
  function getChunkDefinitionsFromManualChunks(manualChunkAliasByEntry) {
@@ -16636,7 +16657,7 @@ function getDynamicallyDependentEntriesByDynamicEntry(dependentEntriesByModule,
16636
16657
  }
16637
16658
  return dynamicallyDependentEntriesByDynamicEntry;
16638
16659
  }
16639
- function getChunksBySignature(modulesWithDependentEntries) {
16660
+ function getChunksFromDependentEntries(modulesWithDependentEntries) {
16640
16661
  var _a;
16641
16662
  const chunkModules = Object.create(null);
16642
16663
  for (const { dependentEntries, modules } of modulesWithDependentEntries) {
@@ -16649,7 +16670,7 @@ function getChunksBySignature(modulesWithDependentEntries) {
16649
16670
  modules: []
16650
16671
  })).modules.push(...modules);
16651
16672
  }
16652
- return chunkModules;
16673
+ return Object.values(chunkModules);
16653
16674
  }
16654
16675
  function* getModulesWithDependentEntries(dependentEntriesByModule, modulesInManualChunks) {
16655
16676
  for (const [module, dependentEntries] of dependentEntriesByModule) {
@@ -16707,17 +16728,6 @@ function removeUnnecessaryDependentEntries(chunks, dynamicallyDependentEntriesBy
16707
16728
  chunkMask <<= 1n;
16708
16729
  }
16709
16730
  }
16710
- function createChunks(allEntries, chunkModulesBySignature, minChunkSize) {
16711
- return minChunkSize === 0
16712
- ? Object.values(chunkModulesBySignature).map(({ modules }) => ({
16713
- alias: null,
16714
- modules
16715
- }))
16716
- : getOptimizedChunks(chunkModulesBySignature, allEntries.length, minChunkSize).map(({ modules }) => ({
16717
- alias: null,
16718
- modules
16719
- }));
16720
- }
16721
16731
  /**
16722
16732
  * This function tries to get rid of small chunks by merging them with other
16723
16733
  * chunks.
@@ -16760,239 +16770,272 @@ function createChunks(allEntries, chunkModulesBySignature, minChunkSize) {
16760
16770
  * dependency side effects are AF.
16761
16771
  * For entry chunks, dependency and correlated side effects are the same.
16762
16772
  *
16763
- * With these concepts, merging chunks is allowed if the correlated side effects
16764
- * of each entry do not change. Thus, we are allowed to merge two chunks if
16773
+ * With these concepts, merging chunks is allowed if the correlated side
16774
+ * effects of each entry do not change. Thus, we are allowed to merge two
16775
+ * chunks if
16776
+ *
16765
16777
  * a) the dependency side effects of each chunk are a subset of the correlated
16766
16778
  * side effects of the other chunk, so no additional side effects are
16767
16779
  * triggered for any entry, or
16768
- * b) The signature of chunk A is a subset of the signature of chunk B while the
16769
- * dependency side effects of A are a subset of the correlated side effects
16770
- * of B. Because in that scenario, whenever A is loaded, B is loaded as well.
16771
- * But there are cases when B is loaded where A is not loaded. So if we merge
16772
- * the chunks, all dependency side effects of A will be added to the
16773
- * correlated side effects of B, and as the latter is not allowed to change,
16774
- * the former need to be a subset of the latter.
16780
+ * b) The dependent entry points of chunk A are a subset of the dependent entry
16781
+ * points of chunk B while the dependency side effects of A are a subset of
16782
+ * the correlated side effects of B. Because in that scenario, whenever A is
16783
+ * loaded, B is loaded as well. But there are cases when B is loaded where A
16784
+ * is not loaded. So if we merge the chunks, all dependency side effects of
16785
+ * A will be added to the correlated side effects of B, and as the latter is
16786
+ * not allowed to change, the former need to be a subset of the latter.
16775
16787
  *
16776
- * Another consideration when merging small chunks into other chunks is to avoid
16788
+ * Another consideration when merging small chunks into other chunks is to
16789
+ * avoid
16777
16790
  * that too much additional code is loaded. This is achieved when the dependent
16778
- * entries of the small chunk are a subset of the dependent entries of the other
16791
+ * entries of the small chunk are a subset of the dependent entries of the
16792
+ * other
16779
16793
  * chunk. Because then when the small chunk is loaded, the other chunk was
16780
16794
  * loaded/in memory anyway, so at most when the other chunk is loaded, the
16781
16795
  * additional size of the small chunk is loaded unnecessarily.
16782
16796
  *
16783
16797
  * So the algorithm performs merges in two passes:
16798
+ *
16784
16799
  * 1. First we try to merge small chunks A only into other chunks B if the
16785
16800
  * dependent entries of A are a subset of the dependent entries of B and the
16786
16801
  * dependency side effects of A are a subset of the correlated side effects
16787
16802
  * of B.
16788
16803
  * 2. Only then for all remaining small chunks, we look for arbitrary merges
16789
- * following the above rules (a) and (b), starting with the smallest chunks
16790
- * to look for possible merge targets.
16804
+ * following the rule (a), starting with the smallest chunks to look for
16805
+ * possible merge targets.
16791
16806
  */
16792
- // TODO instead of picking the "closest" chunk, we could actually use a
16793
- // technique similar to what we do for side effects to compare the size of the
16794
- // static dependencies that are not part of the correlated dependencies
16795
- function getOptimizedChunks(chunkModulesBySignature, numberOfEntries, minChunkSize) {
16807
+ function getOptimizedChunks(initialChunks, numberOfEntries, minChunkSize) {
16796
16808
  timeStart('optimize chunks', 3);
16797
- const chunkPartition = getPartitionedChunks(chunkModulesBySignature, numberOfEntries, minChunkSize);
16798
- console.log('Before eliminating small chunks, there were\n', Object.keys(chunkModulesBySignature).length, 'chunks, of which\n', chunkPartition.small.size, 'were below minChunkSize.');
16809
+ const chunkPartition = getPartitionedChunks(initialChunks, numberOfEntries, minChunkSize);
16810
+ if (!chunkPartition) {
16811
+ timeEnd('optimize chunks', 3);
16812
+ return initialChunks; // the actual modules
16813
+ }
16814
+ minChunkSize > 1 &&
16815
+ console.log('Before eliminating small chunks, there were\n', initialChunks.length, 'chunks, of which\n', chunkPartition.small.size, 'were below minChunkSize.');
16799
16816
  if (chunkPartition.small.size > 0) {
16800
16817
  mergeChunks(chunkPartition, minChunkSize);
16801
16818
  }
16802
- console.log('After merging chunks,\n', chunkPartition.small.size + chunkPartition.big.size, 'chunks remain, of which\n', chunkPartition.small.size, 'are below minChunkSize.');
16819
+ minChunkSize > 1 &&
16820
+ console.log('After merging chunks,\n', chunkPartition.small.size + chunkPartition.big.size, 'chunks remain, of which\n', chunkPartition.small.size, 'are below minChunkSize.');
16803
16821
  timeEnd('optimize chunks', 3);
16804
16822
  return [...chunkPartition.small, ...chunkPartition.big];
16805
16823
  }
16806
- function getPartitionedChunks(chunkModulesBySignature, numberOfEntries, minChunkSize) {
16824
+ function getPartitionedChunks(initialChunks, numberOfEntries, minChunkSize) {
16807
16825
  const smallChunks = [];
16808
16826
  const bigChunks = [];
16809
16827
  const chunkByModule = new Map();
16810
- const sideEffectsByEntry = [];
16811
- for (let index = 0; index < numberOfEntries; index++) {
16812
- sideEffectsByEntry.push(new Set());
16813
- }
16814
- for (const [signature, { dependentEntries, modules }] of Object.entries(chunkModulesBySignature)) {
16828
+ const sizeByAtom = [];
16829
+ let sideEffectAtoms = 0n;
16830
+ let containedAtoms = 1n;
16831
+ for (const { dependentEntries, modules } of initialChunks) {
16815
16832
  const chunkDescription = {
16816
- correlatedSideEffects: new Set(),
16833
+ containedAtoms,
16834
+ correlatedAtoms: 0n,
16817
16835
  dependencies: new Set(),
16818
16836
  dependentChunks: new Set(),
16819
16837
  dependentEntries,
16820
16838
  modules,
16821
16839
  pure: true,
16822
- sideEffects: new Set(),
16823
16840
  size: 0
16824
16841
  };
16825
16842
  let size = 0;
16826
16843
  let pure = true;
16827
16844
  for (const module of modules) {
16828
16845
  chunkByModule.set(module, chunkDescription);
16829
- pure && (pure = !module.hasEffects());
16830
16846
  // Unfortunately, we cannot take tree-shaking into account here because
16831
- // rendering did not happen yet
16832
- size += module.originalCode.length;
16847
+ // rendering did not happen yet, but we can detect empty modules
16848
+ if (module.isIncluded()) {
16849
+ pure && (pure = !module.hasEffects());
16850
+ // we use a trivial size for the default minChunkSize to improve
16851
+ // performance
16852
+ size += minChunkSize > 1 ? module.estimateSize() : 1;
16853
+ }
16833
16854
  }
16834
16855
  chunkDescription.pure = pure;
16835
16856
  chunkDescription.size = size;
16857
+ sizeByAtom.push(size);
16836
16858
  if (!pure) {
16837
- for (const entryIndex of dependentEntries) {
16838
- sideEffectsByEntry[entryIndex].add(signature);
16839
- }
16840
- // In the beginning, each chunk is only its own side effect. After
16841
- // merging, additional side effects can accumulate.
16842
- chunkDescription.sideEffects.add(signature);
16859
+ sideEffectAtoms |= containedAtoms;
16843
16860
  }
16844
16861
  (size < minChunkSize ? smallChunks : bigChunks).push(chunkDescription);
16862
+ containedAtoms <<= 1n;
16845
16863
  }
16846
- sortChunksAndAddDependenciesAndEffects([bigChunks, smallChunks], chunkByModule, sideEffectsByEntry);
16864
+ // If there are no small chunks, we will not optimize
16865
+ if (smallChunks.length === 0) {
16866
+ return null;
16867
+ }
16868
+ sideEffectAtoms |= addChunkDependenciesAndAtomsAndGetSideEffectAtoms([bigChunks, smallChunks], chunkByModule, numberOfEntries, containedAtoms);
16847
16869
  return {
16848
16870
  big: new Set(bigChunks),
16871
+ sideEffectAtoms,
16872
+ sizeByAtom,
16849
16873
  small: new Set(smallChunks)
16850
16874
  };
16851
16875
  }
16852
- function sortChunksAndAddDependenciesAndEffects(chunkLists, chunkByModule, sideEffectsByEntry) {
16876
+ function mergeChunks(chunkPartition, minChunkSize) {
16877
+ const { small } = chunkPartition;
16878
+ for (const mergedChunk of small) {
16879
+ const bestTargetChunk = findBestMergeTarget(mergedChunk, chunkPartition,
16880
+ // In the default case, we do not accept size increases
16881
+ minChunkSize <= 1 ? 1 : Infinity);
16882
+ if (bestTargetChunk) {
16883
+ const { containedAtoms, correlatedAtoms, modules, pure, size } = mergedChunk;
16884
+ small.delete(mergedChunk);
16885
+ getChunksInPartition(bestTargetChunk, minChunkSize, chunkPartition).delete(bestTargetChunk);
16886
+ bestTargetChunk.modules.push(...modules);
16887
+ bestTargetChunk.size += size;
16888
+ bestTargetChunk.pure && (bestTargetChunk.pure = pure);
16889
+ const { dependencies, dependentChunks, dependentEntries } = bestTargetChunk;
16890
+ bestTargetChunk.correlatedAtoms &= correlatedAtoms;
16891
+ bestTargetChunk.containedAtoms |= containedAtoms;
16892
+ for (const entry of mergedChunk.dependentEntries) {
16893
+ dependentEntries.add(entry);
16894
+ }
16895
+ for (const dependency of mergedChunk.dependencies) {
16896
+ dependencies.add(dependency);
16897
+ dependency.dependentChunks.delete(mergedChunk);
16898
+ dependency.dependentChunks.add(bestTargetChunk);
16899
+ }
16900
+ for (const dependentChunk of mergedChunk.dependentChunks) {
16901
+ dependentChunks.add(dependentChunk);
16902
+ dependentChunk.dependencies.delete(mergedChunk);
16903
+ dependentChunk.dependencies.add(bestTargetChunk);
16904
+ }
16905
+ dependencies.delete(bestTargetChunk);
16906
+ dependentChunks.delete(bestTargetChunk);
16907
+ getChunksInPartition(bestTargetChunk, minChunkSize, chunkPartition).add(bestTargetChunk);
16908
+ }
16909
+ }
16910
+ }
16911
+ function addChunkDependenciesAndAtomsAndGetSideEffectAtoms(chunkLists, chunkByModule, numberOfEntries, nextAtomSignature) {
16912
+ const signatureByExternalModule = new Map();
16913
+ let sideEffectAtoms = 0n;
16914
+ const atomsByEntry = [];
16915
+ for (let index = 0; index < numberOfEntries; index++) {
16916
+ atomsByEntry.push(0n);
16917
+ }
16853
16918
  for (const chunks of chunkLists) {
16854
16919
  chunks.sort(compareChunkSize);
16855
16920
  for (const chunk of chunks) {
16856
- const { dependencies, modules, correlatedSideEffects, dependentEntries } = chunk;
16921
+ const { dependencies, dependentEntries, modules } = chunk;
16857
16922
  for (const module of modules) {
16858
16923
  for (const dependency of module.getDependenciesToBeIncluded()) {
16859
- const dependencyChunk = chunkByModule.get(dependency);
16860
- if (dependencyChunk && dependencyChunk !== chunk) {
16861
- dependencies.add(dependencyChunk);
16862
- dependencyChunk.dependentChunks.add(chunk);
16863
- }
16864
- }
16865
- }
16866
- let firstEntry = true;
16867
- // Correlated side effects is the intersection of all entry side effects
16868
- for (const entryIndex of dependentEntries) {
16869
- const entryEffects = sideEffectsByEntry[entryIndex];
16870
- if (firstEntry) {
16871
- for (const sideEffect of entryEffects) {
16872
- correlatedSideEffects.add(sideEffect);
16924
+ if (dependency instanceof ExternalModule) {
16925
+ if (dependency.info.moduleSideEffects) {
16926
+ chunk.containedAtoms |= getOrCreate(signatureByExternalModule, dependency, () => {
16927
+ const signature = nextAtomSignature;
16928
+ nextAtomSignature <<= 1n;
16929
+ sideEffectAtoms |= signature;
16930
+ return signature;
16931
+ });
16932
+ }
16873
16933
  }
16874
- firstEntry = false;
16875
- }
16876
- else {
16877
- for (const sideEffect of correlatedSideEffects) {
16878
- if (!entryEffects.has(sideEffect)) {
16879
- correlatedSideEffects.delete(sideEffect);
16934
+ else {
16935
+ const dependencyChunk = chunkByModule.get(dependency);
16936
+ if (dependencyChunk && dependencyChunk !== chunk) {
16937
+ dependencies.add(dependencyChunk);
16938
+ dependencyChunk.dependentChunks.add(chunk);
16880
16939
  }
16881
16940
  }
16882
16941
  }
16883
16942
  }
16943
+ const { containedAtoms } = chunk;
16944
+ for (const entryIndex of dependentEntries) {
16945
+ atomsByEntry[entryIndex] |= containedAtoms;
16946
+ }
16884
16947
  }
16885
16948
  }
16886
- }
16887
- function compareChunkSize({ size: sizeA }, { size: sizeB }) {
16888
- return sizeA - sizeB;
16889
- }
16890
- function mergeChunks(chunkPartition, minChunkSize) {
16891
- for (const allowArbitraryMerges of [false, true]) {
16892
- for (const mergedChunk of chunkPartition.small) {
16893
- let closestChunk = null;
16894
- let closestChunkDistance = Infinity;
16895
- const { modules, pure, size } = mergedChunk;
16896
- for (const targetChunk of concatLazy([chunkPartition.small, chunkPartition.big])) {
16897
- if (mergedChunk === targetChunk)
16898
- continue;
16899
- // If both chunks are small, we also allow for unrelated merges during
16900
- // the first pass
16901
- const onlySubsetMerge = !allowArbitraryMerges && targetChunk.size >= minChunkSize;
16902
- const distance = getChunkEntryDistance(mergedChunk, targetChunk, onlySubsetMerge);
16903
- if (distance < closestChunkDistance &&
16904
- isValidMerge(mergedChunk, targetChunk, onlySubsetMerge)) {
16905
- closestChunk = targetChunk;
16906
- closestChunkDistance = distance;
16907
- }
16908
- }
16909
- if (closestChunk) {
16910
- chunkPartition.small.delete(mergedChunk);
16911
- getChunksInPartition(closestChunk, minChunkSize, chunkPartition).delete(closestChunk);
16912
- closestChunk.modules.push(...modules);
16913
- closestChunk.size += size;
16914
- closestChunk.pure && (closestChunk.pure = pure);
16915
- const { correlatedSideEffects, dependencies, dependentChunks, dependentEntries, sideEffects } = closestChunk;
16916
- for (const sideEffect of correlatedSideEffects) {
16917
- if (!mergedChunk.correlatedSideEffects.has(sideEffect)) {
16918
- correlatedSideEffects.delete(sideEffect);
16919
- }
16920
- }
16921
- for (const entry of mergedChunk.dependentEntries) {
16922
- dependentEntries.add(entry);
16923
- }
16924
- for (const sideEffect of mergedChunk.sideEffects) {
16925
- sideEffects.add(sideEffect);
16926
- }
16927
- for (const dependency of mergedChunk.dependencies) {
16928
- dependencies.add(dependency);
16929
- dependency.dependentChunks.delete(mergedChunk);
16930
- dependency.dependentChunks.add(closestChunk);
16931
- }
16932
- for (const dependentChunk of mergedChunk.dependentChunks) {
16933
- dependentChunks.add(dependentChunk);
16934
- dependentChunk.dependencies.delete(mergedChunk);
16935
- dependentChunk.dependencies.add(closestChunk);
16936
- }
16937
- dependencies.delete(closestChunk);
16938
- dependentChunks.delete(closestChunk);
16939
- getChunksInPartition(closestChunk, minChunkSize, chunkPartition).add(closestChunk);
16949
+ for (const chunks of chunkLists) {
16950
+ for (const chunk of chunks) {
16951
+ const { dependentEntries } = chunk;
16952
+ // Correlated atoms are the intersection of all entry atoms
16953
+ chunk.correlatedAtoms = -1n;
16954
+ for (const entryIndex of dependentEntries) {
16955
+ chunk.correlatedAtoms &= atomsByEntry[entryIndex];
16940
16956
  }
16941
16957
  }
16942
16958
  }
16959
+ return sideEffectAtoms;
16943
16960
  }
16944
- // Merging will not produce cycles if none of the direct non-merged dependencies
16945
- // of a chunk have the other chunk as a transitive dependency
16946
- function isValidMerge(mergedChunk, targetChunk, onlySubsetMerge) {
16947
- return !(hasTransitiveDependencyOrNonCorrelatedSideEffect(mergedChunk, targetChunk, true) ||
16948
- hasTransitiveDependencyOrNonCorrelatedSideEffect(targetChunk, mergedChunk, !onlySubsetMerge));
16949
- }
16950
- function hasTransitiveDependencyOrNonCorrelatedSideEffect(dependentChunk, dependencyChunk, checkSideEffects) {
16951
- const { correlatedSideEffects } = dependencyChunk;
16952
- if (checkSideEffects) {
16953
- for (const sideEffect of dependentChunk.sideEffects) {
16954
- if (!correlatedSideEffects.has(sideEffect)) {
16955
- return true;
16956
- }
16961
+ function findBestMergeTarget(mergedChunk, { big, sideEffectAtoms, sizeByAtom, small }, smallestAdditionalSize) {
16962
+ let bestTargetChunk = null;
16963
+ // In the default case, we do not accept size increases
16964
+ for (const targetChunk of concatLazy([small, big])) {
16965
+ if (mergedChunk === targetChunk)
16966
+ continue;
16967
+ const additionalSizeAfterMerge = getAdditionalSizeAfterMerge(mergedChunk, targetChunk, smallestAdditionalSize, sideEffectAtoms, sizeByAtom);
16968
+ if (additionalSizeAfterMerge < smallestAdditionalSize) {
16969
+ bestTargetChunk = targetChunk;
16970
+ if (additionalSizeAfterMerge === 0)
16971
+ break;
16972
+ smallestAdditionalSize = additionalSizeAfterMerge;
16957
16973
  }
16958
16974
  }
16975
+ return bestTargetChunk;
16976
+ }
16977
+ function getChunksInPartition(chunk, minChunkSize, chunkPartition) {
16978
+ return chunk.size < minChunkSize ? chunkPartition.small : chunkPartition.big;
16979
+ }
16980
+ function compareChunkSize({ size: sizeA }, { size: sizeB }) {
16981
+ return sizeA - sizeB;
16982
+ }
16983
+ /**
16984
+ * Determine the additional unused code size that would be added by merging the
16985
+ * two chunks. This is not an exact measurement but rather an upper bound. If
16986
+ * the merge produces cycles or adds non-correlated side effects, `Infinity`
16987
+ * is returned.
16988
+ * Merging will not produce cycles if none of the direct non-merged
16989
+ * dependencies of a chunk have the other chunk as a transitive dependency.
16990
+ */
16991
+ function getAdditionalSizeAfterMerge(mergedChunk, targetChunk,
16992
+ // The maximum additional unused code size allowed to be added by the merge,
16993
+ // taking dependencies into account, needs to be below this number
16994
+ currentAdditionalSize, sideEffectAtoms, sizeByAtom) {
16995
+ const firstSize = getAdditionalSizeIfNoTransitiveDependencyOrNonCorrelatedSideEffect(mergedChunk, targetChunk, currentAdditionalSize, sideEffectAtoms, sizeByAtom);
16996
+ return firstSize < currentAdditionalSize
16997
+ ? firstSize +
16998
+ getAdditionalSizeIfNoTransitiveDependencyOrNonCorrelatedSideEffect(targetChunk, mergedChunk, currentAdditionalSize - firstSize, sideEffectAtoms, sizeByAtom)
16999
+ : Infinity;
17000
+ }
17001
+ function getAdditionalSizeIfNoTransitiveDependencyOrNonCorrelatedSideEffect(dependentChunk, dependencyChunk, currentAdditionalSize, sideEffectAtoms, sizeByAtom) {
17002
+ const { correlatedAtoms } = dependencyChunk;
17003
+ let dependencyAtoms = dependentChunk.containedAtoms;
17004
+ const dependentContainedSideEffects = dependencyAtoms & sideEffectAtoms;
17005
+ if ((correlatedAtoms & dependentContainedSideEffects) !== dependentContainedSideEffects) {
17006
+ return Infinity;
17007
+ }
16959
17008
  const chunksToCheck = new Set(dependentChunk.dependencies);
16960
- for (const { dependencies, sideEffects } of chunksToCheck) {
17009
+ for (const { dependencies, containedAtoms } of chunksToCheck) {
17010
+ dependencyAtoms |= containedAtoms;
17011
+ const containedSideEffects = containedAtoms & sideEffectAtoms;
17012
+ if ((correlatedAtoms & containedSideEffects) !== containedSideEffects) {
17013
+ return Infinity;
17014
+ }
16961
17015
  for (const dependency of dependencies) {
16962
17016
  if (dependency === dependencyChunk) {
16963
- return true;
17017
+ return Infinity;
16964
17018
  }
16965
17019
  chunksToCheck.add(dependency);
16966
17020
  }
16967
- if (checkSideEffects) {
16968
- for (const sideEffect of sideEffects) {
16969
- if (!correlatedSideEffects.has(sideEffect)) {
16970
- return true;
16971
- }
16972
- }
16973
- }
16974
17021
  }
16975
- return false;
16976
- }
16977
- function getChunksInPartition(chunk, minChunkSize, chunkPartition) {
16978
- return chunk.size < minChunkSize ? chunkPartition.small : chunkPartition.big;
17022
+ return getAtomsSizeIfBelowLimit(dependencyAtoms & ~correlatedAtoms, currentAdditionalSize, sizeByAtom);
16979
17023
  }
16980
- function getChunkEntryDistance({ dependentEntries: sourceEntries }, { dependentEntries: targetEntries }, enforceSubest) {
16981
- let distance = 0;
16982
- for (const entryIndex of targetEntries) {
16983
- if (!sourceEntries.has(entryIndex)) {
16984
- distance++;
17024
+ function getAtomsSizeIfBelowLimit(atoms, currentAdditionalSize, sizeByAtom) {
17025
+ let size = 0;
17026
+ let atomIndex = 0;
17027
+ let atomSignature = 1n;
17028
+ const { length } = sizeByAtom;
17029
+ for (; atomIndex < length; atomIndex++) {
17030
+ if ((atoms & atomSignature) === atomSignature) {
17031
+ size += sizeByAtom[atomIndex];
16985
17032
  }
16986
- }
16987
- for (const entryIndex of sourceEntries) {
16988
- if (!targetEntries.has(entryIndex)) {
16989
- if (enforceSubest) {
16990
- return Infinity;
16991
- }
16992
- distance++;
17033
+ atomSignature <<= 1n;
17034
+ if (size >= currentAdditionalSize) {
17035
+ return Infinity;
16993
17036
  }
16994
17037
  }
16995
- return distance;
17038
+ return size;
16996
17039
  }
16997
17040
 
16998
17041
  // ported from https://github.com/substack/node-commondir
@@ -25465,7 +25508,7 @@ async function normalizeOutputOptions(config, inputOptions, unsetInputOptions) {
25465
25508
  entryFileNames: getEntryFileNames(config, unsetOptions),
25466
25509
  esModule: config.esModule ?? 'if-default-prop',
25467
25510
  experimentalDeepDynamicChunkOptimization: getExperimentalDeepDynamicChunkOptimization(config, inputOptions),
25468
- experimentalMinChunkSize: config.experimentalMinChunkSize || 0,
25511
+ experimentalMinChunkSize: config.experimentalMinChunkSize ?? 1,
25469
25512
  exports: getExports(config, unsetOptions),
25470
25513
  extend: config.extend || false,
25471
25514
  externalImportAssertions: config.externalImportAssertions ?? true,
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v3.21.6
4
- Tue, 09 May 2023 20:05:04 GMT - commit fa5af3756fbabec7e9a5d082550c710c491e85e9
3
+ Rollup.js v3.22.0-0
4
+ Sat, 13 May 2023 13:21:30 GMT - commit b7e90ac1d307b0549254f282ccf7eb7ead6f93de
5
5
 
6
6
  https://github.com/rollup/rollup
7
7
 
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v3.21.6
4
- Tue, 09 May 2023 20:05:04 GMT - commit fa5af3756fbabec7e9a5d082550c710c491e85e9
3
+ Rollup.js v3.22.0-0
4
+ Sat, 13 May 2023 13:21:30 GMT - commit b7e90ac1d307b0549254f282ccf7eb7ead6f93de
5
5
 
6
6
  https://github.com/rollup/rollup
7
7
 
package/dist/rollup.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v3.21.6
4
- Tue, 09 May 2023 20:05:04 GMT - commit fa5af3756fbabec7e9a5d082550c710c491e85e9
3
+ Rollup.js v3.22.0-0
4
+ Sat, 13 May 2023 13:21:30 GMT - commit b7e90ac1d307b0549254f282ccf7eb7ead6f93de
5
5
 
6
6
  https://github.com/rollup/rollup
7
7
 
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v3.21.6
4
- Tue, 09 May 2023 20:05:04 GMT - commit fa5af3756fbabec7e9a5d082550c710c491e85e9
3
+ Rollup.js v3.22.0-0
4
+ Sat, 13 May 2023 13:21:30 GMT - commit b7e90ac1d307b0549254f282ccf7eb7ead6f93de
5
5
 
6
6
  https://github.com/rollup/rollup
7
7
 
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v3.21.6
4
- Tue, 09 May 2023 20:05:04 GMT - commit fa5af3756fbabec7e9a5d082550c710c491e85e9
3
+ Rollup.js v3.22.0-0
4
+ Sat, 13 May 2023 13:21:30 GMT - commit b7e90ac1d307b0549254f282ccf7eb7ead6f93de
5
5
 
6
6
  https://github.com/rollup/rollup
7
7
 
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v3.21.6
4
- Tue, 09 May 2023 20:05:04 GMT - commit fa5af3756fbabec7e9a5d082550c710c491e85e9
3
+ Rollup.js v3.22.0-0
4
+ Sat, 13 May 2023 13:21:30 GMT - commit b7e90ac1d307b0549254f282ccf7eb7ead6f93de
5
5
 
6
6
  https://github.com/rollup/rollup
7
7
 
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v3.21.6
4
- Tue, 09 May 2023 20:05:04 GMT - commit fa5af3756fbabec7e9a5d082550c710c491e85e9
3
+ Rollup.js v3.22.0-0
4
+ Sat, 13 May 2023 13:21:30 GMT - commit b7e90ac1d307b0549254f282ccf7eb7ead6f93de
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.21.6";
34
+ var version$1 = "3.22.0-0";
35
35
 
36
36
  function ensureArray$1(items) {
37
37
  if (Array.isArray(items)) {
@@ -13946,6 +13946,16 @@ class Module {
13946
13946
  this.addLocationToLogProps(properties, pos);
13947
13947
  return error(properties);
13948
13948
  }
13949
+ // sum up the length of all ast nodes that are included
13950
+ estimateSize() {
13951
+ let size = 0;
13952
+ for (const node of this.ast.body) {
13953
+ if (node.included) {
13954
+ size += node.end - node.start;
13955
+ }
13956
+ }
13957
+ return size;
13958
+ }
13949
13959
  getAllExportNames() {
13950
13960
  if (this.allExportNames) {
13951
13961
  return this.allExportNames;
@@ -15983,13 +15993,18 @@ class Chunk {
15983
15993
  }
15984
15994
  canModuleBeFacade(module, exposedVariables) {
15985
15995
  const moduleExportNamesByVariable = module.getExportNamesByVariable();
15996
+ // All exports of this chunk need to be exposed by the candidate module
15986
15997
  for (const exposedVariable of this.exports) {
15987
15998
  if (!moduleExportNamesByVariable.has(exposedVariable)) {
15988
15999
  return false;
15989
16000
  }
15990
16001
  }
16002
+ // Additionally, we need to expose namespaces of dynamic entries that are not the facade module and exports from other entry modules
15991
16003
  for (const exposedVariable of exposedVariables) {
15992
- if (!(moduleExportNamesByVariable.has(exposedVariable) || exposedVariable.module === module)) {
16004
+ if (!(exposedVariable.module === module ||
16005
+ moduleExportNamesByVariable.has(exposedVariable) ||
16006
+ (exposedVariable instanceof SyntheticNamedExportVariable &&
16007
+ moduleExportNamesByVariable.has(exposedVariable.getBaseVariable())))) {
15993
16008
  return false;
15994
16009
  }
15995
16010
  }
@@ -16044,7 +16059,10 @@ class Chunk {
16044
16059
  for (const module of entryModules) {
16045
16060
  if (module.preserveSignature) {
16046
16061
  for (const exportedVariable of module.getExportNamesByVariable().keys()) {
16047
- exposedVariables.add(exportedVariable);
16062
+ // We need to expose all entry exports from this chunk
16063
+ if (this.chunkByModule.get(exportedVariable.module) === this) {
16064
+ exposedVariables.add(exportedVariable);
16065
+ }
16048
16066
  }
16049
16067
  }
16050
16068
  }
@@ -17021,11 +17039,14 @@ function getChunkAssignments(entries, manualChunkAliasByEntry, minChunkSize) {
17021
17039
  const { chunkDefinitions, modulesInManualChunks } = getChunkDefinitionsFromManualChunks(manualChunkAliasByEntry);
17022
17040
  const { allEntries, dependentEntriesByModule, dynamicallyDependentEntriesByDynamicEntry, dynamicImportsByEntry } = analyzeModuleGraph(entries);
17023
17041
  // Each chunk is identified by its position in this array
17024
- const initialChunks = Object.values(getChunksBySignature(getModulesWithDependentEntries(dependentEntriesByModule, modulesInManualChunks)));
17042
+ const initialChunks = getChunksFromDependentEntries(getModulesWithDependentEntries(dependentEntriesByModule, modulesInManualChunks));
17025
17043
  // This mutates initialChunks but also clears
17026
17044
  // dynamicallyDependentEntriesByDynamicEntry as side effect
17027
17045
  removeUnnecessaryDependentEntries(initialChunks, dynamicallyDependentEntriesByDynamicEntry, dynamicImportsByEntry, allEntries);
17028
- chunkDefinitions.push(...createChunks(allEntries, getChunksBySignature(initialChunks), minChunkSize));
17046
+ chunkDefinitions.push(...getOptimizedChunks(getChunksFromDependentEntries(initialChunks), allEntries.length, minChunkSize).map(({ modules }) => ({
17047
+ alias: null,
17048
+ modules
17049
+ })));
17029
17050
  return chunkDefinitions;
17030
17051
  }
17031
17052
  function getChunkDefinitionsFromManualChunks(manualChunkAliasByEntry) {
@@ -17131,7 +17152,7 @@ function getDynamicallyDependentEntriesByDynamicEntry(dependentEntriesByModule,
17131
17152
  }
17132
17153
  return dynamicallyDependentEntriesByDynamicEntry;
17133
17154
  }
17134
- function getChunksBySignature(modulesWithDependentEntries) {
17155
+ function getChunksFromDependentEntries(modulesWithDependentEntries) {
17135
17156
  var _a;
17136
17157
  const chunkModules = Object.create(null);
17137
17158
  for (const { dependentEntries, modules } of modulesWithDependentEntries) {
@@ -17144,7 +17165,7 @@ function getChunksBySignature(modulesWithDependentEntries) {
17144
17165
  modules: []
17145
17166
  })).modules.push(...modules);
17146
17167
  }
17147
- return chunkModules;
17168
+ return Object.values(chunkModules);
17148
17169
  }
17149
17170
  function* getModulesWithDependentEntries(dependentEntriesByModule, modulesInManualChunks) {
17150
17171
  for (const [module, dependentEntries] of dependentEntriesByModule) {
@@ -17202,17 +17223,6 @@ function removeUnnecessaryDependentEntries(chunks, dynamicallyDependentEntriesBy
17202
17223
  chunkMask <<= 1n;
17203
17224
  }
17204
17225
  }
17205
- function createChunks(allEntries, chunkModulesBySignature, minChunkSize) {
17206
- return minChunkSize === 0
17207
- ? Object.values(chunkModulesBySignature).map(({ modules }) => ({
17208
- alias: null,
17209
- modules
17210
- }))
17211
- : getOptimizedChunks(chunkModulesBySignature, allEntries.length, minChunkSize).map(({ modules }) => ({
17212
- alias: null,
17213
- modules
17214
- }));
17215
- }
17216
17226
  /**
17217
17227
  * This function tries to get rid of small chunks by merging them with other
17218
17228
  * chunks.
@@ -17255,239 +17265,272 @@ function createChunks(allEntries, chunkModulesBySignature, minChunkSize) {
17255
17265
  * dependency side effects are AF.
17256
17266
  * For entry chunks, dependency and correlated side effects are the same.
17257
17267
  *
17258
- * With these concepts, merging chunks is allowed if the correlated side effects
17259
- * of each entry do not change. Thus, we are allowed to merge two chunks if
17268
+ * With these concepts, merging chunks is allowed if the correlated side
17269
+ * effects of each entry do not change. Thus, we are allowed to merge two
17270
+ * chunks if
17271
+ *
17260
17272
  * a) the dependency side effects of each chunk are a subset of the correlated
17261
17273
  * side effects of the other chunk, so no additional side effects are
17262
17274
  * triggered for any entry, or
17263
- * b) The signature of chunk A is a subset of the signature of chunk B while the
17264
- * dependency side effects of A are a subset of the correlated side effects
17265
- * of B. Because in that scenario, whenever A is loaded, B is loaded as well.
17266
- * But there are cases when B is loaded where A is not loaded. So if we merge
17267
- * the chunks, all dependency side effects of A will be added to the
17268
- * correlated side effects of B, and as the latter is not allowed to change,
17269
- * the former need to be a subset of the latter.
17275
+ * b) The dependent entry points of chunk A are a subset of the dependent entry
17276
+ * points of chunk B while the dependency side effects of A are a subset of
17277
+ * the correlated side effects of B. Because in that scenario, whenever A is
17278
+ * loaded, B is loaded as well. But there are cases when B is loaded where A
17279
+ * is not loaded. So if we merge the chunks, all dependency side effects of
17280
+ * A will be added to the correlated side effects of B, and as the latter is
17281
+ * not allowed to change, the former need to be a subset of the latter.
17270
17282
  *
17271
- * Another consideration when merging small chunks into other chunks is to avoid
17283
+ * Another consideration when merging small chunks into other chunks is to
17284
+ * avoid
17272
17285
  * that too much additional code is loaded. This is achieved when the dependent
17273
- * entries of the small chunk are a subset of the dependent entries of the other
17286
+ * entries of the small chunk are a subset of the dependent entries of the
17287
+ * other
17274
17288
  * chunk. Because then when the small chunk is loaded, the other chunk was
17275
17289
  * loaded/in memory anyway, so at most when the other chunk is loaded, the
17276
17290
  * additional size of the small chunk is loaded unnecessarily.
17277
17291
  *
17278
17292
  * So the algorithm performs merges in two passes:
17293
+ *
17279
17294
  * 1. First we try to merge small chunks A only into other chunks B if the
17280
17295
  * dependent entries of A are a subset of the dependent entries of B and the
17281
17296
  * dependency side effects of A are a subset of the correlated side effects
17282
17297
  * of B.
17283
17298
  * 2. Only then for all remaining small chunks, we look for arbitrary merges
17284
- * following the above rules (a) and (b), starting with the smallest chunks
17285
- * to look for possible merge targets.
17299
+ * following the rule (a), starting with the smallest chunks to look for
17300
+ * possible merge targets.
17286
17301
  */
17287
- // TODO instead of picking the "closest" chunk, we could actually use a
17288
- // technique similar to what we do for side effects to compare the size of the
17289
- // static dependencies that are not part of the correlated dependencies
17290
- function getOptimizedChunks(chunkModulesBySignature, numberOfEntries, minChunkSize) {
17302
+ function getOptimizedChunks(initialChunks, numberOfEntries, minChunkSize) {
17291
17303
  timeStart('optimize chunks', 3);
17292
- const chunkPartition = getPartitionedChunks(chunkModulesBySignature, numberOfEntries, minChunkSize);
17293
- console.log('Before eliminating small chunks, there were\n', Object.keys(chunkModulesBySignature).length, 'chunks, of which\n', chunkPartition.small.size, 'were below minChunkSize.');
17304
+ const chunkPartition = getPartitionedChunks(initialChunks, numberOfEntries, minChunkSize);
17305
+ if (!chunkPartition) {
17306
+ timeEnd('optimize chunks', 3);
17307
+ return initialChunks; // the actual modules
17308
+ }
17309
+ minChunkSize > 1 &&
17310
+ console.log('Before eliminating small chunks, there were\n', initialChunks.length, 'chunks, of which\n', chunkPartition.small.size, 'were below minChunkSize.');
17294
17311
  if (chunkPartition.small.size > 0) {
17295
17312
  mergeChunks(chunkPartition, minChunkSize);
17296
17313
  }
17297
- console.log('After merging chunks,\n', chunkPartition.small.size + chunkPartition.big.size, 'chunks remain, of which\n', chunkPartition.small.size, 'are below minChunkSize.');
17314
+ minChunkSize > 1 &&
17315
+ console.log('After merging chunks,\n', chunkPartition.small.size + chunkPartition.big.size, 'chunks remain, of which\n', chunkPartition.small.size, 'are below minChunkSize.');
17298
17316
  timeEnd('optimize chunks', 3);
17299
17317
  return [...chunkPartition.small, ...chunkPartition.big];
17300
17318
  }
17301
- function getPartitionedChunks(chunkModulesBySignature, numberOfEntries, minChunkSize) {
17319
+ function getPartitionedChunks(initialChunks, numberOfEntries, minChunkSize) {
17302
17320
  const smallChunks = [];
17303
17321
  const bigChunks = [];
17304
17322
  const chunkByModule = new Map();
17305
- const sideEffectsByEntry = [];
17306
- for (let index = 0; index < numberOfEntries; index++) {
17307
- sideEffectsByEntry.push(new Set());
17308
- }
17309
- for (const [signature, { dependentEntries, modules }] of Object.entries(chunkModulesBySignature)) {
17323
+ const sizeByAtom = [];
17324
+ let sideEffectAtoms = 0n;
17325
+ let containedAtoms = 1n;
17326
+ for (const { dependentEntries, modules } of initialChunks) {
17310
17327
  const chunkDescription = {
17311
- correlatedSideEffects: new Set(),
17328
+ containedAtoms,
17329
+ correlatedAtoms: 0n,
17312
17330
  dependencies: new Set(),
17313
17331
  dependentChunks: new Set(),
17314
17332
  dependentEntries,
17315
17333
  modules,
17316
17334
  pure: true,
17317
- sideEffects: new Set(),
17318
17335
  size: 0
17319
17336
  };
17320
17337
  let size = 0;
17321
17338
  let pure = true;
17322
17339
  for (const module of modules) {
17323
17340
  chunkByModule.set(module, chunkDescription);
17324
- pure && (pure = !module.hasEffects());
17325
17341
  // Unfortunately, we cannot take tree-shaking into account here because
17326
- // rendering did not happen yet
17327
- size += module.originalCode.length;
17342
+ // rendering did not happen yet, but we can detect empty modules
17343
+ if (module.isIncluded()) {
17344
+ pure && (pure = !module.hasEffects());
17345
+ // we use a trivial size for the default minChunkSize to improve
17346
+ // performance
17347
+ size += minChunkSize > 1 ? module.estimateSize() : 1;
17348
+ }
17328
17349
  }
17329
17350
  chunkDescription.pure = pure;
17330
17351
  chunkDescription.size = size;
17352
+ sizeByAtom.push(size);
17331
17353
  if (!pure) {
17332
- for (const entryIndex of dependentEntries) {
17333
- sideEffectsByEntry[entryIndex].add(signature);
17334
- }
17335
- // In the beginning, each chunk is only its own side effect. After
17336
- // merging, additional side effects can accumulate.
17337
- chunkDescription.sideEffects.add(signature);
17354
+ sideEffectAtoms |= containedAtoms;
17338
17355
  }
17339
17356
  (size < minChunkSize ? smallChunks : bigChunks).push(chunkDescription);
17357
+ containedAtoms <<= 1n;
17340
17358
  }
17341
- sortChunksAndAddDependenciesAndEffects([bigChunks, smallChunks], chunkByModule, sideEffectsByEntry);
17359
+ // If there are no small chunks, we will not optimize
17360
+ if (smallChunks.length === 0) {
17361
+ return null;
17362
+ }
17363
+ sideEffectAtoms |= addChunkDependenciesAndAtomsAndGetSideEffectAtoms([bigChunks, smallChunks], chunkByModule, numberOfEntries, containedAtoms);
17342
17364
  return {
17343
17365
  big: new Set(bigChunks),
17366
+ sideEffectAtoms,
17367
+ sizeByAtom,
17344
17368
  small: new Set(smallChunks)
17345
17369
  };
17346
17370
  }
17347
- function sortChunksAndAddDependenciesAndEffects(chunkLists, chunkByModule, sideEffectsByEntry) {
17371
+ function mergeChunks(chunkPartition, minChunkSize) {
17372
+ const { small } = chunkPartition;
17373
+ for (const mergedChunk of small) {
17374
+ const bestTargetChunk = findBestMergeTarget(mergedChunk, chunkPartition,
17375
+ // In the default case, we do not accept size increases
17376
+ minChunkSize <= 1 ? 1 : Infinity);
17377
+ if (bestTargetChunk) {
17378
+ const { containedAtoms, correlatedAtoms, modules, pure, size } = mergedChunk;
17379
+ small.delete(mergedChunk);
17380
+ getChunksInPartition(bestTargetChunk, minChunkSize, chunkPartition).delete(bestTargetChunk);
17381
+ bestTargetChunk.modules.push(...modules);
17382
+ bestTargetChunk.size += size;
17383
+ bestTargetChunk.pure && (bestTargetChunk.pure = pure);
17384
+ const { dependencies, dependentChunks, dependentEntries } = bestTargetChunk;
17385
+ bestTargetChunk.correlatedAtoms &= correlatedAtoms;
17386
+ bestTargetChunk.containedAtoms |= containedAtoms;
17387
+ for (const entry of mergedChunk.dependentEntries) {
17388
+ dependentEntries.add(entry);
17389
+ }
17390
+ for (const dependency of mergedChunk.dependencies) {
17391
+ dependencies.add(dependency);
17392
+ dependency.dependentChunks.delete(mergedChunk);
17393
+ dependency.dependentChunks.add(bestTargetChunk);
17394
+ }
17395
+ for (const dependentChunk of mergedChunk.dependentChunks) {
17396
+ dependentChunks.add(dependentChunk);
17397
+ dependentChunk.dependencies.delete(mergedChunk);
17398
+ dependentChunk.dependencies.add(bestTargetChunk);
17399
+ }
17400
+ dependencies.delete(bestTargetChunk);
17401
+ dependentChunks.delete(bestTargetChunk);
17402
+ getChunksInPartition(bestTargetChunk, minChunkSize, chunkPartition).add(bestTargetChunk);
17403
+ }
17404
+ }
17405
+ }
17406
+ function addChunkDependenciesAndAtomsAndGetSideEffectAtoms(chunkLists, chunkByModule, numberOfEntries, nextAtomSignature) {
17407
+ const signatureByExternalModule = new Map();
17408
+ let sideEffectAtoms = 0n;
17409
+ const atomsByEntry = [];
17410
+ for (let index = 0; index < numberOfEntries; index++) {
17411
+ atomsByEntry.push(0n);
17412
+ }
17348
17413
  for (const chunks of chunkLists) {
17349
17414
  chunks.sort(compareChunkSize);
17350
17415
  for (const chunk of chunks) {
17351
- const { dependencies, modules, correlatedSideEffects, dependentEntries } = chunk;
17416
+ const { dependencies, dependentEntries, modules } = chunk;
17352
17417
  for (const module of modules) {
17353
17418
  for (const dependency of module.getDependenciesToBeIncluded()) {
17354
- const dependencyChunk = chunkByModule.get(dependency);
17355
- if (dependencyChunk && dependencyChunk !== chunk) {
17356
- dependencies.add(dependencyChunk);
17357
- dependencyChunk.dependentChunks.add(chunk);
17358
- }
17359
- }
17360
- }
17361
- let firstEntry = true;
17362
- // Correlated side effects is the intersection of all entry side effects
17363
- for (const entryIndex of dependentEntries) {
17364
- const entryEffects = sideEffectsByEntry[entryIndex];
17365
- if (firstEntry) {
17366
- for (const sideEffect of entryEffects) {
17367
- correlatedSideEffects.add(sideEffect);
17419
+ if (dependency instanceof ExternalModule) {
17420
+ if (dependency.info.moduleSideEffects) {
17421
+ chunk.containedAtoms |= getOrCreate(signatureByExternalModule, dependency, () => {
17422
+ const signature = nextAtomSignature;
17423
+ nextAtomSignature <<= 1n;
17424
+ sideEffectAtoms |= signature;
17425
+ return signature;
17426
+ });
17427
+ }
17368
17428
  }
17369
- firstEntry = false;
17370
- }
17371
- else {
17372
- for (const sideEffect of correlatedSideEffects) {
17373
- if (!entryEffects.has(sideEffect)) {
17374
- correlatedSideEffects.delete(sideEffect);
17429
+ else {
17430
+ const dependencyChunk = chunkByModule.get(dependency);
17431
+ if (dependencyChunk && dependencyChunk !== chunk) {
17432
+ dependencies.add(dependencyChunk);
17433
+ dependencyChunk.dependentChunks.add(chunk);
17375
17434
  }
17376
17435
  }
17377
17436
  }
17378
17437
  }
17438
+ const { containedAtoms } = chunk;
17439
+ for (const entryIndex of dependentEntries) {
17440
+ atomsByEntry[entryIndex] |= containedAtoms;
17441
+ }
17379
17442
  }
17380
17443
  }
17381
- }
17382
- function compareChunkSize({ size: sizeA }, { size: sizeB }) {
17383
- return sizeA - sizeB;
17384
- }
17385
- function mergeChunks(chunkPartition, minChunkSize) {
17386
- for (const allowArbitraryMerges of [false, true]) {
17387
- for (const mergedChunk of chunkPartition.small) {
17388
- let closestChunk = null;
17389
- let closestChunkDistance = Infinity;
17390
- const { modules, pure, size } = mergedChunk;
17391
- for (const targetChunk of concatLazy([chunkPartition.small, chunkPartition.big])) {
17392
- if (mergedChunk === targetChunk)
17393
- continue;
17394
- // If both chunks are small, we also allow for unrelated merges during
17395
- // the first pass
17396
- const onlySubsetMerge = !allowArbitraryMerges && targetChunk.size >= minChunkSize;
17397
- const distance = getChunkEntryDistance(mergedChunk, targetChunk, onlySubsetMerge);
17398
- if (distance < closestChunkDistance &&
17399
- isValidMerge(mergedChunk, targetChunk, onlySubsetMerge)) {
17400
- closestChunk = targetChunk;
17401
- closestChunkDistance = distance;
17402
- }
17403
- }
17404
- if (closestChunk) {
17405
- chunkPartition.small.delete(mergedChunk);
17406
- getChunksInPartition(closestChunk, minChunkSize, chunkPartition).delete(closestChunk);
17407
- closestChunk.modules.push(...modules);
17408
- closestChunk.size += size;
17409
- closestChunk.pure && (closestChunk.pure = pure);
17410
- const { correlatedSideEffects, dependencies, dependentChunks, dependentEntries, sideEffects } = closestChunk;
17411
- for (const sideEffect of correlatedSideEffects) {
17412
- if (!mergedChunk.correlatedSideEffects.has(sideEffect)) {
17413
- correlatedSideEffects.delete(sideEffect);
17414
- }
17415
- }
17416
- for (const entry of mergedChunk.dependentEntries) {
17417
- dependentEntries.add(entry);
17418
- }
17419
- for (const sideEffect of mergedChunk.sideEffects) {
17420
- sideEffects.add(sideEffect);
17421
- }
17422
- for (const dependency of mergedChunk.dependencies) {
17423
- dependencies.add(dependency);
17424
- dependency.dependentChunks.delete(mergedChunk);
17425
- dependency.dependentChunks.add(closestChunk);
17426
- }
17427
- for (const dependentChunk of mergedChunk.dependentChunks) {
17428
- dependentChunks.add(dependentChunk);
17429
- dependentChunk.dependencies.delete(mergedChunk);
17430
- dependentChunk.dependencies.add(closestChunk);
17431
- }
17432
- dependencies.delete(closestChunk);
17433
- dependentChunks.delete(closestChunk);
17434
- getChunksInPartition(closestChunk, minChunkSize, chunkPartition).add(closestChunk);
17444
+ for (const chunks of chunkLists) {
17445
+ for (const chunk of chunks) {
17446
+ const { dependentEntries } = chunk;
17447
+ // Correlated atoms are the intersection of all entry atoms
17448
+ chunk.correlatedAtoms = -1n;
17449
+ for (const entryIndex of dependentEntries) {
17450
+ chunk.correlatedAtoms &= atomsByEntry[entryIndex];
17435
17451
  }
17436
17452
  }
17437
17453
  }
17454
+ return sideEffectAtoms;
17438
17455
  }
17439
- // Merging will not produce cycles if none of the direct non-merged dependencies
17440
- // of a chunk have the other chunk as a transitive dependency
17441
- function isValidMerge(mergedChunk, targetChunk, onlySubsetMerge) {
17442
- return !(hasTransitiveDependencyOrNonCorrelatedSideEffect(mergedChunk, targetChunk, true) ||
17443
- hasTransitiveDependencyOrNonCorrelatedSideEffect(targetChunk, mergedChunk, !onlySubsetMerge));
17444
- }
17445
- function hasTransitiveDependencyOrNonCorrelatedSideEffect(dependentChunk, dependencyChunk, checkSideEffects) {
17446
- const { correlatedSideEffects } = dependencyChunk;
17447
- if (checkSideEffects) {
17448
- for (const sideEffect of dependentChunk.sideEffects) {
17449
- if (!correlatedSideEffects.has(sideEffect)) {
17450
- return true;
17451
- }
17456
+ function findBestMergeTarget(mergedChunk, { big, sideEffectAtoms, sizeByAtom, small }, smallestAdditionalSize) {
17457
+ let bestTargetChunk = null;
17458
+ // In the default case, we do not accept size increases
17459
+ for (const targetChunk of concatLazy([small, big])) {
17460
+ if (mergedChunk === targetChunk)
17461
+ continue;
17462
+ const additionalSizeAfterMerge = getAdditionalSizeAfterMerge(mergedChunk, targetChunk, smallestAdditionalSize, sideEffectAtoms, sizeByAtom);
17463
+ if (additionalSizeAfterMerge < smallestAdditionalSize) {
17464
+ bestTargetChunk = targetChunk;
17465
+ if (additionalSizeAfterMerge === 0)
17466
+ break;
17467
+ smallestAdditionalSize = additionalSizeAfterMerge;
17452
17468
  }
17453
17469
  }
17470
+ return bestTargetChunk;
17471
+ }
17472
+ function getChunksInPartition(chunk, minChunkSize, chunkPartition) {
17473
+ return chunk.size < minChunkSize ? chunkPartition.small : chunkPartition.big;
17474
+ }
17475
+ function compareChunkSize({ size: sizeA }, { size: sizeB }) {
17476
+ return sizeA - sizeB;
17477
+ }
17478
+ /**
17479
+ * Determine the additional unused code size that would be added by merging the
17480
+ * two chunks. This is not an exact measurement but rather an upper bound. If
17481
+ * the merge produces cycles or adds non-correlated side effects, `Infinity`
17482
+ * is returned.
17483
+ * Merging will not produce cycles if none of the direct non-merged
17484
+ * dependencies of a chunk have the other chunk as a transitive dependency.
17485
+ */
17486
+ function getAdditionalSizeAfterMerge(mergedChunk, targetChunk,
17487
+ // The maximum additional unused code size allowed to be added by the merge,
17488
+ // taking dependencies into account, needs to be below this number
17489
+ currentAdditionalSize, sideEffectAtoms, sizeByAtom) {
17490
+ const firstSize = getAdditionalSizeIfNoTransitiveDependencyOrNonCorrelatedSideEffect(mergedChunk, targetChunk, currentAdditionalSize, sideEffectAtoms, sizeByAtom);
17491
+ return firstSize < currentAdditionalSize
17492
+ ? firstSize +
17493
+ getAdditionalSizeIfNoTransitiveDependencyOrNonCorrelatedSideEffect(targetChunk, mergedChunk, currentAdditionalSize - firstSize, sideEffectAtoms, sizeByAtom)
17494
+ : Infinity;
17495
+ }
17496
+ function getAdditionalSizeIfNoTransitiveDependencyOrNonCorrelatedSideEffect(dependentChunk, dependencyChunk, currentAdditionalSize, sideEffectAtoms, sizeByAtom) {
17497
+ const { correlatedAtoms } = dependencyChunk;
17498
+ let dependencyAtoms = dependentChunk.containedAtoms;
17499
+ const dependentContainedSideEffects = dependencyAtoms & sideEffectAtoms;
17500
+ if ((correlatedAtoms & dependentContainedSideEffects) !== dependentContainedSideEffects) {
17501
+ return Infinity;
17502
+ }
17454
17503
  const chunksToCheck = new Set(dependentChunk.dependencies);
17455
- for (const { dependencies, sideEffects } of chunksToCheck) {
17504
+ for (const { dependencies, containedAtoms } of chunksToCheck) {
17505
+ dependencyAtoms |= containedAtoms;
17506
+ const containedSideEffects = containedAtoms & sideEffectAtoms;
17507
+ if ((correlatedAtoms & containedSideEffects) !== containedSideEffects) {
17508
+ return Infinity;
17509
+ }
17456
17510
  for (const dependency of dependencies) {
17457
17511
  if (dependency === dependencyChunk) {
17458
- return true;
17512
+ return Infinity;
17459
17513
  }
17460
17514
  chunksToCheck.add(dependency);
17461
17515
  }
17462
- if (checkSideEffects) {
17463
- for (const sideEffect of sideEffects) {
17464
- if (!correlatedSideEffects.has(sideEffect)) {
17465
- return true;
17466
- }
17467
- }
17468
- }
17469
17516
  }
17470
- return false;
17471
- }
17472
- function getChunksInPartition(chunk, minChunkSize, chunkPartition) {
17473
- return chunk.size < minChunkSize ? chunkPartition.small : chunkPartition.big;
17517
+ return getAtomsSizeIfBelowLimit(dependencyAtoms & ~correlatedAtoms, currentAdditionalSize, sizeByAtom);
17474
17518
  }
17475
- function getChunkEntryDistance({ dependentEntries: sourceEntries }, { dependentEntries: targetEntries }, enforceSubest) {
17476
- let distance = 0;
17477
- for (const entryIndex of targetEntries) {
17478
- if (!sourceEntries.has(entryIndex)) {
17479
- distance++;
17519
+ function getAtomsSizeIfBelowLimit(atoms, currentAdditionalSize, sizeByAtom) {
17520
+ let size = 0;
17521
+ let atomIndex = 0;
17522
+ let atomSignature = 1n;
17523
+ const { length } = sizeByAtom;
17524
+ for (; atomIndex < length; atomIndex++) {
17525
+ if ((atoms & atomSignature) === atomSignature) {
17526
+ size += sizeByAtom[atomIndex];
17480
17527
  }
17481
- }
17482
- for (const entryIndex of sourceEntries) {
17483
- if (!targetEntries.has(entryIndex)) {
17484
- if (enforceSubest) {
17485
- return Infinity;
17486
- }
17487
- distance++;
17528
+ atomSignature <<= 1n;
17529
+ if (size >= currentAdditionalSize) {
17530
+ return Infinity;
17488
17531
  }
17489
17532
  }
17490
- return distance;
17533
+ return size;
17491
17534
  }
17492
17535
 
17493
17536
  // ported from https://github.com/substack/node-commondir
@@ -25864,7 +25907,7 @@ async function normalizeOutputOptions(config, inputOptions, unsetInputOptions) {
25864
25907
  entryFileNames: getEntryFileNames(config, unsetOptions),
25865
25908
  esModule: config.esModule ?? 'if-default-prop',
25866
25909
  experimentalDeepDynamicChunkOptimization: getExperimentalDeepDynamicChunkOptimization(config, inputOptions),
25867
- experimentalMinChunkSize: config.experimentalMinChunkSize || 0,
25910
+ experimentalMinChunkSize: config.experimentalMinChunkSize ?? 1,
25868
25911
  exports: getExports(config, unsetOptions),
25869
25912
  extend: config.extend || false,
25870
25913
  externalImportAssertions: config.externalImportAssertions ?? true,
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v3.21.6
4
- Tue, 09 May 2023 20:05:04 GMT - commit fa5af3756fbabec7e9a5d082550c710c491e85e9
3
+ Rollup.js v3.22.0-0
4
+ Sat, 13 May 2023 13:21:30 GMT - commit b7e90ac1d307b0549254f282ccf7eb7ead6f93de
5
5
 
6
6
  https://github.com/rollup/rollup
7
7
 
@@ -434,7 +434,7 @@ async function watch(command) {
434
434
  const configFile = command.config ? await cli.getConfigPath(command.config) : null;
435
435
  const runWatchHook = createWatchHooks(command);
436
436
  onExit(close);
437
- process$2.on('uncaughtException', close);
437
+ process$2.on('uncaughtException', closeWithError);
438
438
  if (!process$2.stdin.isTTY) {
439
439
  process$2.stdin.on('end', close);
440
440
  process$2.stdin.resume();
@@ -533,7 +533,7 @@ async function watch(command) {
533
533
  });
534
534
  }
535
535
  async function close(code) {
536
- process$2.removeListener('uncaughtException', close);
536
+ process$2.removeListener('uncaughtException', closeWithError);
537
537
  // removing a non-existent listener is a no-op
538
538
  process$2.stdin.removeListener('end', close);
539
539
  if (watcher)
@@ -545,6 +545,10 @@ async function watch(command) {
545
545
  // return a promise that never resolves to keep the process running
546
546
  return new Promise(() => { });
547
547
  }
548
+ function closeWithError(error) {
549
+ error.name = `Uncaught ${error.name}`;
550
+ rollup.handleError(error);
551
+ }
548
552
 
549
553
  exports.watch = watch;
550
554
  //# sourceMappingURL=watch-cli.js.map
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v3.21.6
4
- Tue, 09 May 2023 20:05:04 GMT - commit fa5af3756fbabec7e9a5d082550c710c491e85e9
3
+ Rollup.js v3.22.0-0
4
+ Sat, 13 May 2023 13:21:30 GMT - commit b7e90ac1d307b0549254f282ccf7eb7ead6f93de
5
5
 
6
6
  https://github.com/rollup/rollup
7
7
 
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v3.21.6
4
- Tue, 09 May 2023 20:05:04 GMT - commit fa5af3756fbabec7e9a5d082550c710c491e85e9
3
+ Rollup.js v3.22.0-0
4
+ Sat, 13 May 2023 13:21:30 GMT - commit b7e90ac1d307b0549254f282ccf7eb7ead6f93de
5
5
 
6
6
  https://github.com/rollup/rollup
7
7
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rollup",
3
- "version": "3.21.6",
3
+ "version": "3.22.0-0",
4
4
  "description": "Next-generation ES module bundler",
5
5
  "main": "dist/rollup.js",
6
6
  "module": "dist/es/rollup.js",