webpack 5.53.0 → 5.56.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.

Potentially problematic release.


This version of webpack might be problematic. Click here for more details.

Files changed (64) hide show
  1. package/lib/AsyncDependenciesBlock.js +9 -2
  2. package/lib/CacheFacade.js +10 -3
  3. package/lib/ChunkGraph.js +19 -8
  4. package/lib/CodeGenerationResults.js +7 -2
  5. package/lib/Compilation.js +586 -143
  6. package/lib/Compiler.js +13 -4
  7. package/lib/DefinePlugin.js +13 -8
  8. package/lib/Dependency.js +11 -0
  9. package/lib/DependencyTemplates.js +8 -2
  10. package/lib/EvalDevToolModulePlugin.js +2 -1
  11. package/lib/EvalSourceMapDevToolPlugin.js +2 -1
  12. package/lib/ExternalModule.js +18 -9
  13. package/lib/FileSystemInfo.js +101 -170
  14. package/lib/FlagDependencyExportsPlugin.js +25 -16
  15. package/lib/JavascriptMetaInfoPlugin.js +6 -1
  16. package/lib/ModuleFactory.js +1 -0
  17. package/lib/ModuleFilenameHelpers.js +21 -7
  18. package/lib/ModuleGraph.js +90 -21
  19. package/lib/NormalModuleFactory.js +8 -43
  20. package/lib/SourceMapDevToolPlugin.js +7 -3
  21. package/lib/WebpackOptionsApply.js +19 -1
  22. package/lib/cache/PackFileCacheStrategy.js +2 -1
  23. package/lib/cache/getLazyHashedEtag.js +35 -8
  24. package/lib/config/defaults.js +18 -7
  25. package/lib/dependencies/CachedConstDependency.js +4 -3
  26. package/lib/dependencies/CommonJsExportRequireDependency.js +19 -9
  27. package/lib/dependencies/CommonJsFullRequireDependency.js +11 -9
  28. package/lib/dependencies/ConstDependency.js +12 -4
  29. package/lib/dependencies/ContextDependency.js +8 -0
  30. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +179 -163
  31. package/lib/dependencies/HarmonyImportDependency.js +4 -1
  32. package/lib/dependencies/JsonExportsDependency.js +7 -1
  33. package/lib/dependencies/ModuleDecoratorDependency.js +5 -2
  34. package/lib/dependencies/ModuleDependency.js +8 -0
  35. package/lib/dependencies/NullDependency.js +8 -4
  36. package/lib/dependencies/ProvidedDependency.js +6 -2
  37. package/lib/dependencies/PureExpressionDependency.js +5 -1
  38. package/lib/dependencies/RuntimeRequirementsDependency.js +5 -1
  39. package/lib/dependencies/WebAssemblyExportImportedDependency.js +9 -0
  40. package/lib/ids/IdHelpers.js +21 -8
  41. package/lib/ids/NamedChunkIdsPlugin.js +3 -0
  42. package/lib/ids/NamedModuleIdsPlugin.js +3 -1
  43. package/lib/index.js +6 -0
  44. package/lib/javascript/BasicEvaluatedExpression.js +3 -0
  45. package/lib/javascript/JavascriptParser.js +22 -4
  46. package/lib/javascript/JavascriptParserHelpers.js +0 -2
  47. package/lib/optimize/ConcatenatedModule.js +25 -4
  48. package/lib/optimize/InnerGraph.js +22 -2
  49. package/lib/optimize/ModuleConcatenationPlugin.js +2 -1
  50. package/lib/schemes/HttpUriPlugin.js +1 -2
  51. package/lib/serialization/BinaryMiddleware.js +11 -2
  52. package/lib/serialization/FileMiddleware.js +24 -7
  53. package/lib/serialization/ObjectMiddleware.js +19 -8
  54. package/lib/util/WeakTupleMap.js +95 -92
  55. package/lib/util/createHash.js +10 -0
  56. package/lib/util/hash/BatchedHash.js +65 -0
  57. package/lib/util/hash/xxhash64.js +154 -0
  58. package/lib/util/serialization.js +4 -4
  59. package/package.json +10 -6
  60. package/schemas/WebpackOptions.check.js +1 -1
  61. package/schemas/WebpackOptions.json +12 -0
  62. package/schemas/plugins/HashedModuleIdsPlugin.check.js +1 -1
  63. package/schemas/plugins/HashedModuleIdsPlugin.json +20 -2
  64. package/types.d.ts +205 -20
@@ -16,6 +16,7 @@ const processAsyncTree = require("./util/processAsyncTree");
16
16
 
17
17
  /** @typedef {import("./WebpackError")} WebpackError */
18
18
  /** @typedef {import("./logging/Logger").Logger} Logger */
19
+ /** @typedef {typeof import("./util/Hash")} Hash */
19
20
  /** @typedef {import("./util/fs").IStats} IStats */
20
21
  /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
21
22
 
@@ -453,12 +454,14 @@ class SnapshotOptimization {
453
454
  * @param {function(Snapshot): boolean} has has value
454
455
  * @param {function(Snapshot): Map<string, T> | Set<string>} get get value
455
456
  * @param {function(Snapshot, Map<string, T> | Set<string>): void} set set value
457
+ * @param {boolean=} useStartTime use the start time of snapshots
456
458
  * @param {boolean=} isSet value is an Set instead of a Map
457
459
  */
458
- constructor(has, get, set, isSet = false) {
460
+ constructor(has, get, set, useStartTime = true, isSet = false) {
459
461
  this._has = has;
460
462
  this._get = get;
461
463
  this._set = set;
464
+ this._useStartTime = useStartTime;
462
465
  this._isSet = isSet;
463
466
  /** @type {Map<string, SnapshotOptimizationEntry>} */
464
467
  this._map = new Map();
@@ -488,24 +491,12 @@ class SnapshotOptimization {
488
491
  this._statReusedSharedSnapshots = 0;
489
492
  }
490
493
 
491
- storeUnsharedSnapshot(snapshot, locations) {
492
- if (locations === undefined) return;
493
- const optimizationEntry = {
494
- snapshot,
495
- shared: 0,
496
- snapshotContent: undefined,
497
- children: undefined
498
- };
499
- for (const path of locations) {
500
- this._map.set(path, optimizationEntry);
501
- }
502
- }
503
-
504
- optimize(capturedFiles, startTime, children) {
505
- /** @type {Set<string>} */
506
- const unsetOptimizationEntries = new Set();
507
- /** @type {Set<SnapshotOptimizationEntry>} */
508
- const checkedOptimizationEntries = new Set();
494
+ /**
495
+ * @param {Snapshot} newSnapshot snapshot
496
+ * @param {Set<string>} capturedFiles files to snapshot/share
497
+ * @returns {void}
498
+ */
499
+ optimize(newSnapshot, capturedFiles) {
509
500
  /**
510
501
  * @param {SnapshotOptimizationEntry} entry optimization entry
511
502
  * @returns {void}
@@ -530,22 +521,43 @@ class SnapshotOptimization {
530
521
  capturedFiles.delete(path);
531
522
  }
532
523
  };
524
+
525
+ /** @type {SnapshotOptimizationEntry} */
526
+ let newOptimizationEntry = undefined;
527
+
533
528
  const capturedFilesSize = capturedFiles.size;
534
- capturedFiles: for (const path of capturedFiles) {
529
+
530
+ /** @type {Set<SnapshotOptimizationEntry> | undefined} */
531
+ const optimizationEntries = new Set();
532
+
533
+ for (const path of capturedFiles) {
535
534
  const optimizationEntry = this._map.get(path);
536
535
  if (optimizationEntry === undefined) {
537
- unsetOptimizationEntries.add(path);
536
+ if (newOptimizationEntry === undefined) {
537
+ newOptimizationEntry = {
538
+ snapshot: newSnapshot,
539
+ shared: 0,
540
+ snapshotContent: undefined,
541
+ children: undefined
542
+ };
543
+ }
544
+ this._map.set(path, newOptimizationEntry);
538
545
  continue;
546
+ } else {
547
+ optimizationEntries.add(optimizationEntry);
539
548
  }
540
- if (checkedOptimizationEntries.has(optimizationEntry)) continue;
549
+ }
550
+
551
+ optimizationEntries: for (const optimizationEntry of optimizationEntries) {
541
552
  const snapshot = optimizationEntry.snapshot;
542
553
  if (optimizationEntry.shared > 0) {
543
554
  // It's a shared snapshot
544
555
  // We can't change it, so we can only use it when all files match
545
556
  // and startTime is compatible
546
557
  if (
547
- startTime &&
548
- (!snapshot.startTime || snapshot.startTime > startTime)
558
+ this._useStartTime &&
559
+ newSnapshot.startTime &&
560
+ (!snapshot.startTime || snapshot.startTime > newSnapshot.startTime)
549
561
  ) {
550
562
  continue;
551
563
  }
@@ -557,8 +569,7 @@ class SnapshotOptimization {
557
569
  if (!snapshotEntries.has(path)) {
558
570
  // File is not shared and can't be removed from the snapshot
559
571
  // because it's in a child of the snapshot
560
- checkedOptimizationEntries.add(optimizationEntry);
561
- continue capturedFiles;
572
+ continue optimizationEntries;
562
573
  }
563
574
  nonSharedFiles.add(path);
564
575
  continue;
@@ -567,7 +578,7 @@ class SnapshotOptimization {
567
578
  if (nonSharedFiles.size === 0) {
568
579
  // The complete snapshot is shared
569
580
  // add it as child
570
- children.add(snapshot);
581
+ newSnapshot.addChild(snapshot);
571
582
  increaseSharedAndStoreOptimizationEntry(optimizationEntry);
572
583
  this._statReusedSharedSnapshots++;
573
584
  } else {
@@ -575,8 +586,7 @@ class SnapshotOptimization {
575
586
  const sharedCount = snapshotContent.size - nonSharedFiles.size;
576
587
  if (sharedCount < MIN_COMMON_SNAPSHOT_SIZE) {
577
588
  // Common part it too small
578
- checkedOptimizationEntries.add(optimizationEntry);
579
- continue capturedFiles;
589
+ continue optimizationEntries;
580
590
  }
581
591
  // Extract common timestamps from both snapshots
582
592
  let commonMap;
@@ -598,9 +608,11 @@ class SnapshotOptimization {
598
608
  }
599
609
  // Create and attach snapshot
600
610
  const commonSnapshot = new Snapshot();
601
- commonSnapshot.setMergedStartTime(startTime, snapshot);
611
+ if (this._useStartTime) {
612
+ commonSnapshot.setMergedStartTime(newSnapshot.startTime, snapshot);
613
+ }
602
614
  this._set(commonSnapshot, commonMap);
603
- children.add(commonSnapshot);
615
+ newSnapshot.addChild(commonSnapshot);
604
616
  snapshot.addChild(commonSnapshot);
605
617
  // Create optimization entry
606
618
  const newEntry = {
@@ -620,6 +632,10 @@ class SnapshotOptimization {
620
632
  // We can extract a common shared snapshot
621
633
  // with all common files
622
634
  const snapshotEntries = this._get(snapshot);
635
+ if (snapshotEntries === undefined) {
636
+ // Incomplete snapshot, that can't be used
637
+ continue optimizationEntries;
638
+ }
623
639
  let commonMap;
624
640
  if (this._isSet) {
625
641
  commonMap = new Set();
@@ -645,14 +661,15 @@ class SnapshotOptimization {
645
661
 
646
662
  if (commonMap.size < MIN_COMMON_SNAPSHOT_SIZE) {
647
663
  // Common part it too small
648
- checkedOptimizationEntries.add(optimizationEntry);
649
- continue capturedFiles;
664
+ continue optimizationEntries;
650
665
  }
651
666
  // Create and attach snapshot
652
667
  const commonSnapshot = new Snapshot();
653
- commonSnapshot.setMergedStartTime(startTime, snapshot);
668
+ if (this._useStartTime) {
669
+ commonSnapshot.setMergedStartTime(newSnapshot.startTime, snapshot);
670
+ }
654
671
  this._set(commonSnapshot, commonMap);
655
- children.add(commonSnapshot);
672
+ newSnapshot.addChild(commonSnapshot);
656
673
  snapshot.addChild(commonSnapshot);
657
674
  // Remove files from snapshot
658
675
  for (const path of commonMap.keys()) snapshotEntries.delete(path);
@@ -668,12 +685,10 @@ class SnapshotOptimization {
668
685
  });
669
686
  this._statSharedSnapshots++;
670
687
  }
671
- checkedOptimizationEntries.add(optimizationEntry);
672
688
  }
673
689
  const unshared = capturedFiles.size;
674
690
  this._statItemsUnshared += unshared;
675
691
  this._statItemsShared += capturedFilesSize - unshared;
676
- return unsetOptimizationEntries;
677
692
  }
678
693
  }
679
694
 
@@ -842,12 +857,22 @@ class FileSystemInfo {
842
857
  * @param {Iterable<string>=} options.managedPaths paths that are only managed by a package manager
843
858
  * @param {Iterable<string>=} options.immutablePaths paths that are immutable
844
859
  * @param {Logger=} options.logger logger used to log invalid snapshots
860
+ * @param {string | Hash=} options.hashFunction the hash function to use
845
861
  */
846
- constructor(fs, { managedPaths = [], immutablePaths = [], logger } = {}) {
862
+ constructor(
863
+ fs,
864
+ {
865
+ managedPaths = [],
866
+ immutablePaths = [],
867
+ logger,
868
+ hashFunction = "md4"
869
+ } = {}
870
+ ) {
847
871
  this.fs = fs;
848
872
  this.logger = logger;
849
873
  this._remainingLogs = logger ? 40 : 0;
850
874
  this._loggedPaths = logger ? new Set() : undefined;
875
+ this._hashFunction = hashFunction;
851
876
  /** @type {WeakMap<Snapshot, boolean | (function(WebpackError=, boolean=): void)[]>} */
852
877
  this._snapshotCache = new WeakMap();
853
878
  this._fileTimestampsOptimization = new SnapshotOptimization(
@@ -858,7 +883,8 @@ class FileSystemInfo {
858
883
  this._fileHashesOptimization = new SnapshotOptimization(
859
884
  s => s.hasFileHashes(),
860
885
  s => s.fileHashes,
861
- (s, v) => s.setFileHashes(v)
886
+ (s, v) => s.setFileHashes(v),
887
+ false
862
888
  );
863
889
  this._fileTshsOptimization = new SnapshotOptimization(
864
890
  s => s.hasFileTshs(),
@@ -873,7 +899,8 @@ class FileSystemInfo {
873
899
  this._contextHashesOptimization = new SnapshotOptimization(
874
900
  s => s.hasContextHashes(),
875
901
  s => s.contextHashes,
876
- (s, v) => s.setContextHashes(v)
902
+ (s, v) => s.setContextHashes(v),
903
+ false
877
904
  );
878
905
  this._contextTshsOptimization = new SnapshotOptimization(
879
906
  s => s.hasContextTshs(),
@@ -883,29 +910,34 @@ class FileSystemInfo {
883
910
  this._missingExistenceOptimization = new SnapshotOptimization(
884
911
  s => s.hasMissingExistence(),
885
912
  s => s.missingExistence,
886
- (s, v) => s.setMissingExistence(v)
913
+ (s, v) => s.setMissingExistence(v),
914
+ false
887
915
  );
888
916
  this._managedItemInfoOptimization = new SnapshotOptimization(
889
917
  s => s.hasManagedItemInfo(),
890
918
  s => s.managedItemInfo,
891
- (s, v) => s.setManagedItemInfo(v)
919
+ (s, v) => s.setManagedItemInfo(v),
920
+ false
892
921
  );
893
922
  this._managedFilesOptimization = new SnapshotOptimization(
894
923
  s => s.hasManagedFiles(),
895
924
  s => s.managedFiles,
896
925
  (s, v) => s.setManagedFiles(v),
926
+ false,
897
927
  true
898
928
  );
899
929
  this._managedContextsOptimization = new SnapshotOptimization(
900
930
  s => s.hasManagedContexts(),
901
931
  s => s.managedContexts,
902
932
  (s, v) => s.setManagedContexts(v),
933
+ false,
903
934
  true
904
935
  );
905
936
  this._managedMissingOptimization = new SnapshotOptimization(
906
937
  s => s.hasManagedMissing(),
907
938
  s => s.managedMissing,
908
939
  (s, v) => s.setManagedMissing(v),
940
+ false,
909
941
  true
910
942
  );
911
943
  /** @type {StackedCacheMap<string, FileSystemInfoEntry | "ignore" | null>} */
@@ -1869,22 +1901,8 @@ class FileSystemInfo {
1869
1901
  /** @type {Set<Snapshot>} */
1870
1902
  const children = new Set();
1871
1903
 
1872
- /** @type {Set<string>} */
1873
- let unsharedFileTimestamps;
1874
- /** @type {Set<string>} */
1875
- let unsharedFileHashes;
1876
- /** @type {Set<string>} */
1877
- let unsharedFileTshs;
1878
- /** @type {Set<string>} */
1879
- let unsharedContextTimestamps;
1880
- /** @type {Set<string>} */
1881
- let unsharedContextHashes;
1882
- /** @type {Set<string>} */
1883
- let unsharedContextTshs;
1884
- /** @type {Set<string>} */
1885
- let unsharedMissingExistence;
1886
- /** @type {Set<string>} */
1887
- let unsharedManagedItemInfo;
1904
+ const snapshot = new Snapshot();
1905
+ if (startTime) snapshot.setStartTime(startTime);
1888
1906
 
1889
1907
  /** @type {Set<string>} */
1890
1908
  const managedItems = new Set();
@@ -1895,101 +1913,41 @@ class FileSystemInfo {
1895
1913
  let jobs = 1;
1896
1914
  const jobDone = () => {
1897
1915
  if (--jobs === 0) {
1898
- const snapshot = new Snapshot();
1899
- if (startTime) snapshot.setStartTime(startTime);
1900
1916
  if (fileTimestamps.size !== 0) {
1901
1917
  snapshot.setFileTimestamps(fileTimestamps);
1902
- this._fileTimestampsOptimization.storeUnsharedSnapshot(
1903
- snapshot,
1904
- unsharedFileTimestamps
1905
- );
1906
1918
  }
1907
1919
  if (fileHashes.size !== 0) {
1908
1920
  snapshot.setFileHashes(fileHashes);
1909
- this._fileHashesOptimization.storeUnsharedSnapshot(
1910
- snapshot,
1911
- unsharedFileHashes
1912
- );
1913
1921
  }
1914
1922
  if (fileTshs.size !== 0) {
1915
1923
  snapshot.setFileTshs(fileTshs);
1916
- this._fileTshsOptimization.storeUnsharedSnapshot(
1917
- snapshot,
1918
- unsharedFileTshs
1919
- );
1920
1924
  }
1921
1925
  if (contextTimestamps.size !== 0) {
1922
1926
  snapshot.setContextTimestamps(contextTimestamps);
1923
- this._contextTimestampsOptimization.storeUnsharedSnapshot(
1924
- snapshot,
1925
- unsharedContextTimestamps
1926
- );
1927
1927
  }
1928
1928
  if (contextHashes.size !== 0) {
1929
1929
  snapshot.setContextHashes(contextHashes);
1930
- this._contextHashesOptimization.storeUnsharedSnapshot(
1931
- snapshot,
1932
- unsharedContextHashes
1933
- );
1934
1930
  }
1935
1931
  if (contextTshs.size !== 0) {
1936
1932
  snapshot.setContextTshs(contextTshs);
1937
- this._contextTshsOptimization.storeUnsharedSnapshot(
1938
- snapshot,
1939
- unsharedContextTshs
1940
- );
1941
1933
  }
1942
1934
  if (missingExistence.size !== 0) {
1943
1935
  snapshot.setMissingExistence(missingExistence);
1944
- this._missingExistenceOptimization.storeUnsharedSnapshot(
1945
- snapshot,
1946
- unsharedMissingExistence
1947
- );
1948
1936
  }
1949
1937
  if (managedItemInfo.size !== 0) {
1950
1938
  snapshot.setManagedItemInfo(managedItemInfo);
1951
- this._managedItemInfoOptimization.storeUnsharedSnapshot(
1952
- snapshot,
1953
- unsharedManagedItemInfo
1954
- );
1955
1939
  }
1956
- const unsharedManagedFiles = this._managedFilesOptimization.optimize(
1957
- managedFiles,
1958
- undefined,
1959
- children
1960
- );
1940
+ this._managedFilesOptimization.optimize(snapshot, managedFiles);
1961
1941
  if (managedFiles.size !== 0) {
1962
1942
  snapshot.setManagedFiles(managedFiles);
1963
- this._managedFilesOptimization.storeUnsharedSnapshot(
1964
- snapshot,
1965
- unsharedManagedFiles
1966
- );
1967
1943
  }
1968
- const unsharedManagedContexts =
1969
- this._managedContextsOptimization.optimize(
1970
- managedContexts,
1971
- undefined,
1972
- children
1973
- );
1944
+ this._managedContextsOptimization.optimize(snapshot, managedContexts);
1974
1945
  if (managedContexts.size !== 0) {
1975
1946
  snapshot.setManagedContexts(managedContexts);
1976
- this._managedContextsOptimization.storeUnsharedSnapshot(
1977
- snapshot,
1978
- unsharedManagedContexts
1979
- );
1980
1947
  }
1981
- const unsharedManagedMissing =
1982
- this._managedMissingOptimization.optimize(
1983
- managedMissing,
1984
- undefined,
1985
- children
1986
- );
1948
+ this._managedMissingOptimization.optimize(snapshot, managedMissing);
1987
1949
  if (managedMissing.size !== 0) {
1988
1950
  snapshot.setManagedMissing(managedMissing);
1989
- this._managedMissingOptimization.storeUnsharedSnapshot(
1990
- snapshot,
1991
- unsharedManagedMissing
1992
- );
1993
1951
  }
1994
1952
  if (children.size !== 0) {
1995
1953
  snapshot.setChildren(children);
@@ -2037,11 +1995,7 @@ class FileSystemInfo {
2037
1995
  const capturedFiles = captureNonManaged(files, managedFiles);
2038
1996
  switch (mode) {
2039
1997
  case 3:
2040
- unsharedFileTshs = this._fileTshsOptimization.optimize(
2041
- capturedFiles,
2042
- undefined,
2043
- children
2044
- );
1998
+ this._fileTshsOptimization.optimize(snapshot, capturedFiles);
2045
1999
  for (const path of capturedFiles) {
2046
2000
  const cache = this._fileTshs.get(path);
2047
2001
  if (cache !== undefined) {
@@ -2065,11 +2019,7 @@ class FileSystemInfo {
2065
2019
  }
2066
2020
  break;
2067
2021
  case 2:
2068
- unsharedFileHashes = this._fileHashesOptimization.optimize(
2069
- capturedFiles,
2070
- undefined,
2071
- children
2072
- );
2022
+ this._fileHashesOptimization.optimize(snapshot, capturedFiles);
2073
2023
  for (const path of capturedFiles) {
2074
2024
  const cache = this._fileHashes.get(path);
2075
2025
  if (cache !== undefined) {
@@ -2093,11 +2043,7 @@ class FileSystemInfo {
2093
2043
  }
2094
2044
  break;
2095
2045
  case 1:
2096
- unsharedFileTimestamps = this._fileTimestampsOptimization.optimize(
2097
- capturedFiles,
2098
- startTime,
2099
- children
2100
- );
2046
+ this._fileTimestampsOptimization.optimize(snapshot, capturedFiles);
2101
2047
  for (const path of capturedFiles) {
2102
2048
  const cache = this._fileTimestamps.get(path);
2103
2049
  if (cache !== undefined) {
@@ -2131,11 +2077,7 @@ class FileSystemInfo {
2131
2077
  );
2132
2078
  switch (mode) {
2133
2079
  case 3:
2134
- unsharedContextTshs = this._contextTshsOptimization.optimize(
2135
- capturedDirectories,
2136
- undefined,
2137
- children
2138
- );
2080
+ this._contextTshsOptimization.optimize(snapshot, capturedDirectories);
2139
2081
  for (const path of capturedDirectories) {
2140
2082
  const cache = this._contextTshs.get(path);
2141
2083
  let resolved;
@@ -2168,10 +2110,9 @@ class FileSystemInfo {
2168
2110
  }
2169
2111
  break;
2170
2112
  case 2:
2171
- unsharedContextHashes = this._contextHashesOptimization.optimize(
2172
- capturedDirectories,
2173
- undefined,
2174
- children
2113
+ this._contextHashesOptimization.optimize(
2114
+ snapshot,
2115
+ capturedDirectories
2175
2116
  );
2176
2117
  for (const path of capturedDirectories) {
2177
2118
  const cache = this._contextHashes.get(path);
@@ -2205,12 +2146,10 @@ class FileSystemInfo {
2205
2146
  }
2206
2147
  break;
2207
2148
  case 1:
2208
- unsharedContextTimestamps =
2209
- this._contextTimestampsOptimization.optimize(
2210
- capturedDirectories,
2211
- startTime,
2212
- children
2213
- );
2149
+ this._contextTimestampsOptimization.optimize(
2150
+ snapshot,
2151
+ capturedDirectories
2152
+ );
2214
2153
  for (const path of capturedDirectories) {
2215
2154
  const cache = this._contextTimestamps.get(path);
2216
2155
  let resolved;
@@ -2246,11 +2185,7 @@ class FileSystemInfo {
2246
2185
  }
2247
2186
  if (missing) {
2248
2187
  const capturedMissing = captureNonManaged(missing, managedMissing);
2249
- unsharedMissingExistence = this._missingExistenceOptimization.optimize(
2250
- capturedMissing,
2251
- startTime,
2252
- children
2253
- );
2188
+ this._missingExistenceOptimization.optimize(snapshot, capturedMissing);
2254
2189
  for (const path of capturedMissing) {
2255
2190
  const cache = this._fileTimestamps.get(path);
2256
2191
  if (cache !== undefined) {
@@ -2275,11 +2210,7 @@ class FileSystemInfo {
2275
2210
  }
2276
2211
  }
2277
2212
  }
2278
- unsharedManagedItemInfo = this._managedItemInfoOptimization.optimize(
2279
- managedItems,
2280
- undefined,
2281
- children
2282
- );
2213
+ this._managedItemInfoOptimization.optimize(snapshot, managedItems);
2283
2214
  for (const path of managedItems) {
2284
2215
  const cache = this._managedItems.get(path);
2285
2216
  if (cache !== undefined) {
@@ -2873,7 +2804,7 @@ class FileSystemInfo {
2873
2804
  return callback(err);
2874
2805
  }
2875
2806
 
2876
- const hash = createHash("md4");
2807
+ const hash = createHash(this._hashFunction);
2877
2808
 
2878
2809
  hash.update(content);
2879
2810
 
@@ -3056,7 +2987,7 @@ class FileSystemInfo {
3056
2987
  reduce: (files, tsEntries) => {
3057
2988
  let symlinks = undefined;
3058
2989
 
3059
- const hash = createHash("md4");
2990
+ const hash = createHash(this._hashFunction);
3060
2991
 
3061
2992
  for (const file of files) hash.update(file);
3062
2993
  let safeTime = 0;
@@ -3124,7 +3055,7 @@ class FileSystemInfo {
3124
3055
  },
3125
3056
  err => {
3126
3057
  if (err) return callback(err);
3127
- const hash = createHash("md4");
3058
+ const hash = createHash(this._hashFunction);
3128
3059
  hash.update(entry.timestampHash);
3129
3060
  if (entry.safeTime) {
3130
3061
  safeTime = Math.max(safeTime, entry.safeTime);
@@ -3174,7 +3105,7 @@ class FileSystemInfo {
3174
3105
  */
3175
3106
  reduce: (files, fileHashes) => {
3176
3107
  let symlinks = undefined;
3177
- const hash = createHash("md4");
3108
+ const hash = createHash(this._hashFunction);
3178
3109
 
3179
3110
  for (const file of files) hash.update(file);
3180
3111
  for (const entry of fileHashes) {
@@ -3223,7 +3154,7 @@ class FileSystemInfo {
3223
3154
  },
3224
3155
  err => {
3225
3156
  if (err) return callback(err);
3226
- const hash = createHash("md4");
3157
+ const hash = createHash(this._hashFunction);
3227
3158
  hash.update(entry.hash);
3228
3159
  hashes.sort();
3229
3160
  for (const h of hashes) {
@@ -3301,8 +3232,8 @@ class FileSystemInfo {
3301
3232
  reduce: (files, results) => {
3302
3233
  let symlinks = undefined;
3303
3234
 
3304
- const tsHash = createHash("md4");
3305
- const hash = createHash("md4");
3235
+ const tsHash = createHash(this._hashFunction);
3236
+ const hash = createHash(this._hashFunction);
3306
3237
 
3307
3238
  for (const file of files) {
3308
3239
  tsHash.update(file);
@@ -3380,8 +3311,8 @@ class FileSystemInfo {
3380
3311
  },
3381
3312
  err => {
3382
3313
  if (err) return callback(err);
3383
- const hash = createHash("md4");
3384
- const tsHash = createHash("md4");
3314
+ const hash = createHash(this._hashFunction);
3315
+ const tsHash = createHash(this._hashFunction);
3385
3316
  hash.update(entry.hash);
3386
3317
  if (entry.timestampHash) tsHash.update(entry.timestampHash);
3387
3318
  if (entry.safeTime) {
@@ -34,12 +34,15 @@ class FlagDependencyExportsPlugin {
34
34
  const logger = compilation.getLogger(
35
35
  "webpack.FlagDependencyExportsPlugin"
36
36
  );
37
+ let statRestoredFromMemCache = 0;
37
38
  let statRestoredFromCache = 0;
38
39
  let statNoExports = 0;
39
40
  let statFlaggedUncached = 0;
40
41
  let statNotCached = 0;
41
42
  let statQueueItemsProcessed = 0;
42
43
 
44
+ const { moduleMemCaches } = compilation;
45
+
43
46
  /** @type {Queue<Module>} */
44
47
  const queue = new Queue();
45
48
 
@@ -58,16 +61,20 @@ class FlagDependencyExportsPlugin {
58
61
  return callback();
59
62
  }
60
63
  }
61
- if (
62
- module.buildInfo.cacheable !== true ||
63
- typeof module.buildInfo.hash !== "string"
64
- ) {
64
+ if (typeof module.buildInfo.hash !== "string") {
65
65
  statFlaggedUncached++;
66
66
  // Enqueue uncacheable module for determining the exports
67
67
  queue.enqueue(module);
68
68
  exportsInfo.setHasProvideInfo();
69
69
  return callback();
70
70
  }
71
+ const memCache = moduleMemCaches && moduleMemCaches.get(module);
72
+ const memCacheValue = memCache && memCache.get(this);
73
+ if (memCacheValue !== undefined) {
74
+ statRestoredFromMemCache++;
75
+ exportsInfo.restoreProvided(memCacheValue);
76
+ return callback();
77
+ }
71
78
  cache.get(
72
79
  module.identifier(),
73
80
  module.buildInfo.hash,
@@ -76,9 +83,7 @@ class FlagDependencyExportsPlugin {
76
83
 
77
84
  if (result !== undefined) {
78
85
  statRestoredFromCache++;
79
- moduleGraph
80
- .getExportsInfo(module)
81
- .restoreProvided(result);
86
+ exportsInfo.restoreProvided(result);
82
87
  } else {
83
88
  statNotCached++;
84
89
  // Without cached info enqueue module for determining the exports
@@ -340,11 +345,12 @@ class FlagDependencyExportsPlugin {
340
345
  logger.log(
341
346
  `${Math.round(
342
347
  (100 * (statFlaggedUncached + statNotCached)) /
343
- (statRestoredFromCache +
348
+ (statRestoredFromMemCache +
349
+ statRestoredFromCache +
344
350
  statNotCached +
345
351
  statFlaggedUncached +
346
352
  statNoExports)
347
- )}% of exports of modules have been determined (${statNoExports} no declared exports, ${statNotCached} not cached, ${statFlaggedUncached} flagged uncacheable, ${statRestoredFromCache} from cache, ${
353
+ )}% of exports of modules have been determined (${statNoExports} no declared exports, ${statNotCached} not cached, ${statFlaggedUncached} flagged uncacheable, ${statRestoredFromCache} from cache, ${statRestoredFromMemCache} from mem cache, ${
348
354
  statQueueItemsProcessed -
349
355
  statNotCached -
350
356
  statFlaggedUncached
@@ -355,19 +361,22 @@ class FlagDependencyExportsPlugin {
355
361
  asyncLib.each(
356
362
  modulesToStore,
357
363
  (module, callback) => {
358
- if (
359
- module.buildInfo.cacheable !== true ||
360
- typeof module.buildInfo.hash !== "string"
361
- ) {
364
+ if (typeof module.buildInfo.hash !== "string") {
362
365
  // not cacheable
363
366
  return callback();
364
367
  }
368
+ const cachedData = moduleGraph
369
+ .getExportsInfo(module)
370
+ .getRestoreProvidedData();
371
+ const memCache =
372
+ moduleMemCaches && moduleMemCaches.get(module);
373
+ if (memCache) {
374
+ memCache.set(this, cachedData);
375
+ }
365
376
  cache.store(
366
377
  module.identifier(),
367
378
  module.buildInfo.hash,
368
- moduleGraph
369
- .getExportsInfo(module)
370
- .getRestoreProvidedData(),
379
+ cachedData,
371
380
  callback
372
381
  );
373
382
  },
@@ -28,7 +28,12 @@ class JavascriptMetaInfoPlugin {
28
28
  parser.hooks.call.for("eval").tap("JavascriptMetaInfoPlugin", () => {
29
29
  parser.state.module.buildInfo.moduleConcatenationBailout = "eval()";
30
30
  parser.state.module.buildInfo.usingEval = true;
31
- InnerGraph.bailout(parser.state);
31
+ const currentSymbol = InnerGraph.getTopLevelSymbol(parser.state);
32
+ if (currentSymbol) {
33
+ InnerGraph.addUsage(parser.state, null, currentSymbol);
34
+ } else {
35
+ InnerGraph.bailout(parser.state);
36
+ }
32
37
  });
33
38
  parser.hooks.finish.tap("JavascriptMetaInfoPlugin", () => {
34
39
  let topLevelDeclarations =
@@ -15,6 +15,7 @@
15
15
  * @property {Set<string>=} fileDependencies
16
16
  * @property {Set<string>=} contextDependencies
17
17
  * @property {Set<string>=} missingDependencies
18
+ * @property {boolean=} cacheable allow to use the unsafe cache
18
19
  */
19
20
 
20
21
  /**