webpack 5.53.0 → 5.54.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 (51) 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 +207 -16
  6. package/lib/Compiler.js +9 -1
  7. package/lib/DependencyTemplates.js +8 -2
  8. package/lib/EvalDevToolModulePlugin.js +2 -1
  9. package/lib/EvalSourceMapDevToolPlugin.js +2 -1
  10. package/lib/ExternalModule.js +18 -9
  11. package/lib/FileSystemInfo.js +101 -170
  12. package/lib/FlagDependencyExportsPlugin.js +43 -16
  13. package/lib/JavascriptMetaInfoPlugin.js +6 -1
  14. package/lib/MemCache.js +45 -0
  15. package/lib/ModuleFilenameHelpers.js +21 -7
  16. package/lib/SourceMapDevToolPlugin.js +7 -3
  17. package/lib/WebpackOptionsApply.js +19 -1
  18. package/lib/cache/PackFileCacheStrategy.js +2 -1
  19. package/lib/cache/getLazyHashedEtag.js +35 -8
  20. package/lib/config/defaults.js +18 -7
  21. package/lib/dependencies/CachedConstDependency.js +4 -3
  22. package/lib/dependencies/ConstDependency.js +12 -4
  23. package/lib/dependencies/JsonExportsDependency.js +7 -1
  24. package/lib/dependencies/ModuleDecoratorDependency.js +5 -2
  25. package/lib/dependencies/ProvidedDependency.js +6 -2
  26. package/lib/dependencies/PureExpressionDependency.js +5 -1
  27. package/lib/dependencies/RuntimeRequirementsDependency.js +5 -1
  28. package/lib/ids/IdHelpers.js +21 -8
  29. package/lib/ids/NamedChunkIdsPlugin.js +3 -0
  30. package/lib/ids/NamedModuleIdsPlugin.js +3 -1
  31. package/lib/index.js +6 -0
  32. package/lib/javascript/BasicEvaluatedExpression.js +3 -0
  33. package/lib/javascript/JavascriptParser.js +22 -4
  34. package/lib/javascript/JavascriptParserHelpers.js +0 -2
  35. package/lib/optimize/ConcatenatedModule.js +25 -4
  36. package/lib/optimize/InnerGraph.js +22 -2
  37. package/lib/optimize/ModuleConcatenationPlugin.js +2 -1
  38. package/lib/schemes/HttpUriPlugin.js +1 -2
  39. package/lib/serialization/BinaryMiddleware.js +11 -2
  40. package/lib/serialization/FileMiddleware.js +24 -7
  41. package/lib/serialization/ObjectMiddleware.js +19 -8
  42. package/lib/util/createHash.js +10 -0
  43. package/lib/util/hash/BatchedHash.js +65 -0
  44. package/lib/util/hash/xxhash64.js +154 -0
  45. package/lib/util/serialization.js +4 -4
  46. package/package.json +10 -6
  47. package/schemas/WebpackOptions.check.js +1 -1
  48. package/schemas/WebpackOptions.json +12 -0
  49. package/schemas/plugins/HashedModuleIdsPlugin.check.js +1 -1
  50. package/schemas/plugins/HashedModuleIdsPlugin.json +20 -2
  51. package/types.d.ts +157 -10
@@ -28,12 +28,14 @@ class FlagDependencyExportsPlugin {
28
28
  compilation => {
29
29
  const moduleGraph = compilation.moduleGraph;
30
30
  const cache = compilation.getCache("FlagDependencyExportsPlugin");
31
+ const { moduleMemCaches } = compilation;
31
32
  compilation.hooks.finishModules.tapAsync(
32
33
  "FlagDependencyExportsPlugin",
33
34
  (modules, callback) => {
34
35
  const logger = compilation.getLogger(
35
36
  "webpack.FlagDependencyExportsPlugin"
36
37
  );
38
+ let statRestoredFromMemCache = 0;
37
39
  let statRestoredFromCache = 0;
38
40
  let statNoExports = 0;
39
41
  let statFlaggedUncached = 0;
@@ -58,16 +60,22 @@ class FlagDependencyExportsPlugin {
58
60
  return callback();
59
61
  }
60
62
  }
61
- if (
62
- module.buildInfo.cacheable !== true ||
63
- typeof module.buildInfo.hash !== "string"
64
- ) {
63
+ if (typeof module.buildInfo.hash !== "string") {
65
64
  statFlaggedUncached++;
66
65
  // Enqueue uncacheable module for determining the exports
67
66
  queue.enqueue(module);
68
67
  exportsInfo.setHasProvideInfo();
69
68
  return callback();
70
69
  }
70
+ const memCache = moduleMemCaches && moduleMemCaches.get(module);
71
+ const memCacheValue = memCache && memCache.get(this, module);
72
+ if (memCacheValue !== undefined) {
73
+ statRestoredFromMemCache++;
74
+ moduleGraph
75
+ .getExportsInfo(module)
76
+ .restoreProvided(memCacheValue);
77
+ return callback();
78
+ }
71
79
  cache.get(
72
80
  module.identifier(),
73
81
  module.buildInfo.hash,
@@ -94,7 +102,9 @@ class FlagDependencyExportsPlugin {
94
102
  if (err) return callback(err);
95
103
 
96
104
  /** @type {Set<Module>} */
97
- const modulesToStore = new Set();
105
+ const modulesToStorePersistent = new Set();
106
+ /** @type {Set<Module>} */
107
+ const modulesToStoreTransient = new Set();
98
108
 
99
109
  /** @type {Map<Module, Set<Module>>} */
100
110
  const dependencies = new Map();
@@ -328,7 +338,9 @@ class FlagDependencyExportsPlugin {
328
338
  }
329
339
 
330
340
  if (cacheable) {
331
- modulesToStore.add(module);
341
+ modulesToStorePersistent.add(module);
342
+ } else {
343
+ modulesToStoreTransient.add(module);
332
344
  }
333
345
 
334
346
  if (changed) {
@@ -340,11 +352,12 @@ class FlagDependencyExportsPlugin {
340
352
  logger.log(
341
353
  `${Math.round(
342
354
  (100 * (statFlaggedUncached + statNotCached)) /
343
- (statRestoredFromCache +
355
+ (statRestoredFromMemCache +
356
+ statRestoredFromCache +
344
357
  statNotCached +
345
358
  statFlaggedUncached +
346
359
  statNoExports)
347
- )}% of exports of modules have been determined (${statNoExports} no declared exports, ${statNotCached} not cached, ${statFlaggedUncached} flagged uncacheable, ${statRestoredFromCache} from cache, ${
360
+ )}% 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
361
  statQueueItemsProcessed -
349
362
  statNotCached -
350
363
  statFlaggedUncached
@@ -353,26 +366,40 @@ class FlagDependencyExportsPlugin {
353
366
 
354
367
  logger.time("store provided exports into cache");
355
368
  asyncLib.each(
356
- modulesToStore,
369
+ modulesToStorePersistent,
357
370
  (module, callback) => {
358
- if (
359
- module.buildInfo.cacheable !== true ||
360
- typeof module.buildInfo.hash !== "string"
361
- ) {
371
+ if (typeof module.buildInfo.hash !== "string") {
362
372
  // not cacheable
363
373
  return callback();
364
374
  }
375
+ const cachedData = moduleGraph
376
+ .getExportsInfo(module)
377
+ .getRestoreProvidedData();
378
+ const memCache =
379
+ moduleMemCaches && moduleMemCaches.get(module);
380
+ if (memCache) {
381
+ memCache.set(this, module, cachedData);
382
+ }
365
383
  cache.store(
366
384
  module.identifier(),
367
385
  module.buildInfo.hash,
368
- moduleGraph
369
- .getExportsInfo(module)
370
- .getRestoreProvidedData(),
386
+ cachedData,
371
387
  callback
372
388
  );
373
389
  },
374
390
  err => {
375
391
  logger.timeEnd("store provided exports into cache");
392
+ if (moduleMemCaches) {
393
+ for (const module of modulesToStoreTransient) {
394
+ const memCache = moduleMemCaches.get(module);
395
+ if (memCache) {
396
+ const cachedData = moduleGraph
397
+ .getExportsInfo(module)
398
+ .getRestoreProvidedData();
399
+ memCache.set(this, module, cachedData);
400
+ }
401
+ }
402
+ }
376
403
  callback(err);
377
404
  }
378
405
  );
@@ -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 =
@@ -0,0 +1,45 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Tobias Koppers @sokra
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const WeakTupleMap = require("./util/WeakTupleMap");
9
+
10
+ class MemCache {
11
+ constructor() {
12
+ this._cache = new WeakTupleMap();
13
+ }
14
+
15
+ /**
16
+ * @template {any[]} T
17
+ * @template V
18
+ * @param {T} args arguments
19
+ * @returns {V | undefined} cached value
20
+ */
21
+ get(...args) {
22
+ return this._cache.get(...args);
23
+ }
24
+
25
+ /**
26
+ * @template {[...any[], any]} T
27
+ * @param {T} args arguments
28
+ * @returns {void}
29
+ */
30
+ set(...args) {
31
+ this._cache.set(...args);
32
+ }
33
+
34
+ /**
35
+ * @template {[...any[], (...args: any[]) => V]} T
36
+ * @template V
37
+ * @param {T} args arguments
38
+ * @returns {V} computed value or cached
39
+ */
40
+ provide(...args) {
41
+ return this._cache.provide(...args);
42
+ }
43
+ }
44
+
45
+ module.exports = MemCache;
@@ -8,6 +8,11 @@
8
8
  const createHash = require("./util/createHash");
9
9
  const memoize = require("./util/memoize");
10
10
 
11
+ /** @typedef {import("./ChunkGraph")} ChunkGraph */
12
+ /** @typedef {import("./Module")} Module */
13
+ /** @typedef {import("./RequestShortener")} RequestShortener */
14
+ /** @typedef {typeof import("./util/Hash")} Hash */
15
+
11
16
  const ModuleFilenameHelpers = exports;
12
17
 
13
18
  // TODO webpack 6: consider removing these
@@ -53,9 +58,9 @@ const getBefore = (strFn, token) => {
53
58
  };
54
59
  };
55
60
 
56
- const getHash = strFn => {
61
+ const getHash = (strFn, hashFunction) => {
57
62
  return () => {
58
- const hash = createHash("md4");
63
+ const hash = createHash(hashFunction);
59
64
  hash.update(strFn());
60
65
  const digest = /** @type {string} */ (hash.digest("hex"));
61
66
  return digest.substr(0, 4);
@@ -91,10 +96,20 @@ const lazyObject = obj => {
91
96
 
92
97
  const REGEXP = /\[\\*([\w-]+)\\*\]/gi;
93
98
 
99
+ /**
100
+ *
101
+ * @param {Module | string} module the module
102
+ * @param {TODO} options options
103
+ * @param {Object} contextInfo context info
104
+ * @param {RequestShortener} contextInfo.requestShortener requestShortener
105
+ * @param {ChunkGraph} contextInfo.chunkGraph chunk graph
106
+ * @param {string | Hash} contextInfo.hashFunction the hash function to use
107
+ * @returns {string} the filename
108
+ */
94
109
  ModuleFilenameHelpers.createFilename = (
95
- module,
110
+ module = "",
96
111
  options,
97
- { requestShortener, chunkGraph }
112
+ { requestShortener, chunkGraph, hashFunction = "md4" }
98
113
  ) => {
99
114
  const opts = {
100
115
  namespace: "",
@@ -111,13 +126,12 @@ ModuleFilenameHelpers.createFilename = (
111
126
  let identifier;
112
127
  let moduleId;
113
128
  let shortIdentifier;
114
- if (module === undefined) module = "";
115
129
  if (typeof module === "string") {
116
130
  shortIdentifier = memoize(() => requestShortener.shorten(module));
117
131
  identifier = shortIdentifier;
118
132
  moduleId = () => "";
119
133
  absoluteResourcePath = () => module.split("!").pop();
120
- hash = getHash(identifier);
134
+ hash = getHash(identifier, hashFunction);
121
135
  } else {
122
136
  shortIdentifier = memoize(() =>
123
137
  module.readableIdentifier(requestShortener)
@@ -125,7 +139,7 @@ ModuleFilenameHelpers.createFilename = (
125
139
  identifier = memoize(() => requestShortener.shorten(module.identifier()));
126
140
  moduleId = () => chunkGraph.getModuleId(module);
127
141
  absoluteResourcePath = () => module.identifier().split("!").pop();
128
- hash = getHash(identifier);
142
+ hash = getHash(identifier, hashFunction);
129
143
  }
130
144
  const resource = memoize(() => shortIdentifier().split("!").pop());
131
145
 
@@ -297,7 +297,8 @@ class SourceMapDevToolPlugin {
297
297
  },
298
298
  {
299
299
  requestShortener,
300
- chunkGraph
300
+ chunkGraph,
301
+ hashFunction: compilation.outputOptions.hashFunction
301
302
  }
302
303
  )
303
304
  );
@@ -358,7 +359,8 @@ class SourceMapDevToolPlugin {
358
359
  },
359
360
  {
360
361
  requestShortener,
361
- chunkGraph
362
+ chunkGraph,
363
+ hashFunction: compilation.outputOptions.hashFunction
362
364
  }
363
365
  );
364
366
  hasName = usedNamesSet.has(sourceName);
@@ -442,7 +444,9 @@ class SourceMapDevToolPlugin {
442
444
  const sourceMapContentHash =
443
445
  usesContentHash &&
444
446
  /** @type {string} */ (
445
- createHash("md4").update(sourceMapString).digest("hex")
447
+ createHash(compilation.outputOptions.hashFunction)
448
+ .update(sourceMapString)
449
+ .digest("hex")
446
450
  );
447
451
  const pathParams = {
448
452
  chunk,
@@ -431,7 +431,9 @@ class WebpackOptionsApply extends OptionsApply {
431
431
  "hashed",
432
432
  "deterministic"
433
433
  ).apply(compiler);
434
- new HashedModuleIdsPlugin().apply(compiler);
434
+ new HashedModuleIdsPlugin({
435
+ hashFunction: options.output.hashFunction
436
+ }).apply(compiler);
435
437
  break;
436
438
  }
437
439
  case "deterministic": {
@@ -542,6 +544,14 @@ class WebpackOptionsApply extends OptionsApply {
542
544
  const MemoryCachePlugin = require("./cache/MemoryCachePlugin");
543
545
  new MemoryCachePlugin().apply(compiler);
544
546
  }
547
+ if (cacheOptions.cacheUnaffected) {
548
+ if (!options.experiments.cacheUnaffected) {
549
+ throw new Error(
550
+ "'cache.cacheUnaffected: true' is only allowed when 'experiments.cacheUnaffected' is enabled"
551
+ );
552
+ }
553
+ compiler.moduleMemCaches = new WeakMap();
554
+ }
545
555
  break;
546
556
  }
547
557
  case "filesystem": {
@@ -561,6 +571,14 @@ class WebpackOptionsApply extends OptionsApply {
561
571
  maxGenerations: cacheOptions.maxMemoryGenerations
562
572
  }).apply(compiler);
563
573
  }
574
+ if (cacheOptions.memoryCacheUnaffected) {
575
+ if (!options.experiments.cacheUnaffected) {
576
+ throw new Error(
577
+ "'cache.memoryCacheUnaffected: true' is only allowed when 'experiments.cacheUnaffected' is enabled"
578
+ );
579
+ }
580
+ compiler.moduleMemCaches = new WeakMap();
581
+ }
564
582
  switch (cacheOptions.store) {
565
583
  case "pack": {
566
584
  const IdleFileCachePlugin = require("./cache/IdleFileCachePlugin");
@@ -995,7 +995,8 @@ class PackFileCacheStrategy {
995
995
  this.fileSystemInfo = new FileSystemInfo(fs, {
996
996
  managedPaths: snapshot.managedPaths,
997
997
  immutablePaths: snapshot.immutablePaths,
998
- logger: logger.getChildLogger("webpack.FileSystemInfo")
998
+ logger: logger.getChildLogger("webpack.FileSystemInfo"),
999
+ hashFunction: compiler.options.output.hashFunction
999
1000
  });
1000
1001
  this.compiler = compiler;
1001
1002
  this.context = context;
@@ -8,6 +8,7 @@
8
8
  const createHash = require("../util/createHash");
9
9
 
10
10
  /** @typedef {import("../util/Hash")} Hash */
11
+ /** @typedef {typeof import("../util/Hash")} HashConstructor */
11
12
 
12
13
  /**
13
14
  * @typedef {Object} HashableObject
@@ -17,10 +18,12 @@ const createHash = require("../util/createHash");
17
18
  class LazyHashedEtag {
18
19
  /**
19
20
  * @param {HashableObject} obj object with updateHash method
21
+ * @param {string | HashConstructor} hashFunction the hash function to use
20
22
  */
21
- constructor(obj) {
23
+ constructor(obj, hashFunction = "md4") {
22
24
  this._obj = obj;
23
25
  this._hash = undefined;
26
+ this._hashFunction = hashFunction;
24
27
  }
25
28
 
26
29
  /**
@@ -28,7 +31,7 @@ class LazyHashedEtag {
28
31
  */
29
32
  toString() {
30
33
  if (this._hash === undefined) {
31
- const hash = createHash("md4");
34
+ const hash = createHash(this._hashFunction);
32
35
  this._obj.updateHash(hash);
33
36
  this._hash = /** @type {string} */ (hash.digest("base64"));
34
37
  }
@@ -36,18 +39,42 @@ class LazyHashedEtag {
36
39
  }
37
40
  }
38
41
 
39
- /** @type {WeakMap<HashableObject, LazyHashedEtag>} */
40
- const map = new WeakMap();
42
+ /** @type {Map<string | HashConstructor, WeakMap<HashableObject, LazyHashedEtag>>} */
43
+ const mapStrings = new Map();
44
+
45
+ /** @type {WeakMap<HashConstructor, WeakMap<HashableObject, LazyHashedEtag>>} */
46
+ const mapObjects = new WeakMap();
41
47
 
42
48
  /**
43
49
  * @param {HashableObject} obj object with updateHash method
50
+ * @param {string | HashConstructor} hashFunction the hash function to use
44
51
  * @returns {LazyHashedEtag} etag
45
52
  */
46
- const getter = obj => {
47
- const hash = map.get(obj);
53
+ const getter = (obj, hashFunction = "md4") => {
54
+ let innerMap;
55
+ if (typeof hashFunction === "string") {
56
+ innerMap = mapStrings.get(hashFunction);
57
+ if (innerMap === undefined) {
58
+ const newHash = new LazyHashedEtag(obj, hashFunction);
59
+ innerMap = new WeakMap();
60
+ innerMap.set(obj, newHash);
61
+ mapStrings.set(hashFunction, innerMap);
62
+ return newHash;
63
+ }
64
+ } else {
65
+ innerMap = mapObjects.get(hashFunction);
66
+ if (innerMap === undefined) {
67
+ const newHash = new LazyHashedEtag(obj, hashFunction);
68
+ innerMap = new WeakMap();
69
+ innerMap.set(obj, newHash);
70
+ mapObjects.set(hashFunction, innerMap);
71
+ return newHash;
72
+ }
73
+ }
74
+ const hash = innerMap.get(obj);
48
75
  if (hash !== undefined) return hash;
49
- const newHash = new LazyHashedEtag(obj);
50
- map.set(obj, newHash);
76
+ const newHash = new LazyHashedEtag(obj, hashFunction);
77
+ innerMap.set(obj, newHash);
51
78
  return newHash;
52
79
  };
53
80
 
@@ -159,20 +159,21 @@ const applyWebpackOptionsDefaults = options => {
159
159
  D(options, "recordsInputPath", false);
160
160
  D(options, "recordsOutputPath", false);
161
161
 
162
+ applyExperimentsDefaults(options.experiments, { production, development });
163
+
162
164
  F(options, "cache", () =>
163
165
  development ? { type: /** @type {"memory"} */ ("memory") } : false
164
166
  );
165
167
  applyCacheDefaults(options.cache, {
166
168
  name: name || "default",
167
169
  mode: mode || "production",
168
- development
170
+ development,
171
+ cacheUnaffected: options.experiments.cacheUnaffected
169
172
  });
170
173
  const cache = !!options.cache;
171
174
 
172
175
  applySnapshotDefaults(options.snapshot, { production });
173
176
 
174
- applyExperimentsDefaults(options.experiments, { production, development });
175
-
176
177
  applyModuleDefaults(options.module, {
177
178
  cache,
178
179
  syncWebAssembly: options.experiments.syncWebAssembly,
@@ -190,7 +191,8 @@ const applyWebpackOptionsDefaults = options => {
190
191
  outputModule: options.experiments.outputModule,
191
192
  development,
192
193
  entry: options.entry,
193
- module: options.module
194
+ module: options.module,
195
+ futureDefaults: options.experiments.futureDefaults
194
196
  });
195
197
 
196
198
  applyExternalsPresetsDefaults(options.externalsPresets, {
@@ -266,6 +268,7 @@ const applyExperimentsDefaults = (experiments, { production, development }) => {
266
268
  D(experiments, "lazyCompilation", false);
267
269
  D(experiments, "buildHttp", false);
268
270
  D(experiments, "futureDefaults", false);
271
+ D(experiments, "cacheUnaffected", experiments.futureDefaults);
269
272
 
270
273
  if (typeof experiments.buildHttp === "object") {
271
274
  D(experiments.buildHttp, "frozen", production);
@@ -279,9 +282,13 @@ const applyExperimentsDefaults = (experiments, { production, development }) => {
279
282
  * @param {string} options.name name
280
283
  * @param {string} options.mode mode
281
284
  * @param {boolean} options.development is development mode
285
+ * @param {boolean} options.cacheUnaffected the cacheUnaffected experiment is enabled
282
286
  * @returns {void}
283
287
  */
284
- const applyCacheDefaults = (cache, { name, mode, development }) => {
288
+ const applyCacheDefaults = (
289
+ cache,
290
+ { name, mode, development, cacheUnaffected }
291
+ ) => {
285
292
  if (cache === false) return;
286
293
  switch (cache.type) {
287
294
  case "filesystem":
@@ -325,12 +332,14 @@ const applyCacheDefaults = (cache, { name, mode, development }) => {
325
332
  D(cache, "maxMemoryGenerations", development ? 5 : Infinity);
326
333
  D(cache, "maxAge", 1000 * 60 * 60 * 24 * 60); // 1 month
327
334
  D(cache, "allowCollectingMemory", development);
335
+ D(cache, "memoryCacheUnaffected", development && cacheUnaffected);
328
336
  D(cache.buildDependencies, "defaultWebpack", [
329
337
  path.resolve(__dirname, "..") + path.sep
330
338
  ]);
331
339
  break;
332
340
  case "memory":
333
341
  D(cache, "maxGenerations", Infinity);
342
+ D(cache, "cacheUnaffected", development && cacheUnaffected);
334
343
  break;
335
344
  }
336
345
  };
@@ -580,6 +589,7 @@ const applyModuleDefaults = (
580
589
  * @param {boolean} options.development is development mode
581
590
  * @param {Entry} options.entry entry option
582
591
  * @param {ModuleOptions} options.module module option
592
+ * @param {boolean} options.futureDefaults is future defaults enabled
583
593
  * @returns {void}
584
594
  */
585
595
  const applyOutputDefaults = (
@@ -591,7 +601,8 @@ const applyOutputDefaults = (
591
601
  outputModule,
592
602
  development,
593
603
  entry,
594
- module
604
+ module,
605
+ futureDefaults
595
606
  }
596
607
  ) => {
597
608
  /**
@@ -788,7 +799,7 @@ const applyOutputDefaults = (
788
799
  : ""
789
800
  );
790
801
  D(output, "chunkLoadTimeout", 120000);
791
- D(output, "hashFunction", "md4");
802
+ D(output, "hashFunction", futureDefaults ? "xxhash64" : "md4");
792
803
  D(output, "hashDigest", "hex");
793
804
  D(output, "hashDigestLength", 20);
794
805
  D(output, "strictModuleExceptionHandling", false);
@@ -27,6 +27,7 @@ class CachedConstDependency extends NullDependency {
27
27
  this.expression = expression;
28
28
  this.range = range;
29
29
  this.identifier = identifier;
30
+ this._hashUpdate = undefined;
30
31
  }
31
32
 
32
33
  /**
@@ -36,9 +37,9 @@ class CachedConstDependency extends NullDependency {
36
37
  * @returns {void}
37
38
  */
38
39
  updateHash(hash, context) {
39
- hash.update(this.identifier + "");
40
- hash.update(this.range + "");
41
- hash.update(this.expression + "");
40
+ if (this._hashUpdate === undefined)
41
+ this._hashUpdate = "" + this.identifier + this.range + this.expression;
42
+ hash.update(this._hashUpdate);
42
43
  }
43
44
 
44
45
  serialize(context) {
@@ -30,6 +30,7 @@ class ConstDependency extends NullDependency {
30
30
  this.runtimeRequirements = runtimeRequirements
31
31
  ? new Set(runtimeRequirements)
32
32
  : null;
33
+ this._hashUpdate = undefined;
33
34
  }
34
35
 
35
36
  /**
@@ -39,10 +40,17 @@ class ConstDependency extends NullDependency {
39
40
  * @returns {void}
40
41
  */
41
42
  updateHash(hash, context) {
42
- hash.update(this.range + "");
43
- hash.update(this.expression + "");
44
- if (this.runtimeRequirements)
45
- hash.update(Array.from(this.runtimeRequirements).join() + "");
43
+ if (this._hashUpdate === undefined) {
44
+ let hashUpdate = "" + this.range + "|" + this.expression;
45
+ if (this.runtimeRequirements) {
46
+ for (const item of this.runtimeRequirements) {
47
+ hashUpdate += "|";
48
+ hashUpdate += item;
49
+ }
50
+ }
51
+ this._hashUpdate = hashUpdate;
52
+ }
53
+ hash.update(this._hashUpdate);
46
54
  }
47
55
 
48
56
  /**
@@ -47,6 +47,7 @@ class JsonExportsDependency extends NullDependency {
47
47
  constructor(exports) {
48
48
  super();
49
49
  this.exports = exports;
50
+ this._hashUpdate = undefined;
50
51
  }
51
52
 
52
53
  get type() {
@@ -72,7 +73,12 @@ class JsonExportsDependency extends NullDependency {
72
73
  * @returns {void}
73
74
  */
74
75
  updateHash(hash, context) {
75
- hash.update(this.exports ? JSON.stringify(this.exports) : "undefined");
76
+ if (this._hashUpdate === undefined) {
77
+ this._hashUpdate = this.exports
78
+ ? JSON.stringify(this.exports)
79
+ : "undefined";
80
+ }
81
+ hash.update(this._hashUpdate);
76
82
  }
77
83
 
78
84
  serialize(context) {
@@ -30,6 +30,7 @@ class ModuleDecoratorDependency extends NullDependency {
30
30
  super();
31
31
  this.decorator = decorator;
32
32
  this.allowExportsAccess = allowExportsAccess;
33
+ this._hashUpdate = undefined;
33
34
  }
34
35
 
35
36
  /**
@@ -69,8 +70,10 @@ class ModuleDecoratorDependency extends NullDependency {
69
70
  * @returns {void}
70
71
  */
71
72
  updateHash(hash, context) {
72
- hash.update(this.decorator);
73
- hash.update(`${this.allowExportsAccess}`);
73
+ if (this._hashUpdate === undefined) {
74
+ this._hashUpdate = `${this.decorator}${this.allowExportsAccess}`;
75
+ }
76
+ hash.update(this._hashUpdate);
74
77
  }
75
78
 
76
79
  serialize(context) {
@@ -34,6 +34,7 @@ class ProvidedDependency extends ModuleDependency {
34
34
  this.identifier = identifier;
35
35
  this.path = path;
36
36
  this.range = range;
37
+ this._hashUpdate = undefined;
37
38
  }
38
39
 
39
40
  get type() {
@@ -51,8 +52,11 @@ class ProvidedDependency extends ModuleDependency {
51
52
  * @returns {void}
52
53
  */
53
54
  updateHash(hash, context) {
54
- hash.update(this.identifier);
55
- hash.update(this.path ? this.path.join(",") : "null");
55
+ if (this._hashUpdate === undefined) {
56
+ this._hashUpdate =
57
+ this.identifier + (this.path ? this.path.join(",") : "null");
58
+ }
59
+ hash.update(this._hashUpdate);
56
60
  }
57
61
 
58
62
  serialize(context) {
@@ -28,6 +28,7 @@ class PureExpressionDependency extends NullDependency {
28
28
  this.range = range;
29
29
  /** @type {Set<string> | false} */
30
30
  this.usedByExports = false;
31
+ this._hashUpdate = undefined;
31
32
  }
32
33
 
33
34
  /**
@@ -37,7 +38,10 @@ class PureExpressionDependency extends NullDependency {
37
38
  * @returns {void}
38
39
  */
39
40
  updateHash(hash, context) {
40
- hash.update(this.range + "");
41
+ if (this._hashUpdate === undefined) {
42
+ this._hashUpdate = this.range + "";
43
+ }
44
+ hash.update(this._hashUpdate);
41
45
  }
42
46
 
43
47
  /**
@@ -23,6 +23,7 @@ class RuntimeRequirementsDependency extends NullDependency {
23
23
  constructor(runtimeRequirements) {
24
24
  super();
25
25
  this.runtimeRequirements = new Set(runtimeRequirements);
26
+ this._hashUpdate = undefined;
26
27
  }
27
28
 
28
29
  /**
@@ -32,7 +33,10 @@ class RuntimeRequirementsDependency extends NullDependency {
32
33
  * @returns {void}
33
34
  */
34
35
  updateHash(hash, context) {
35
- hash.update(Array.from(this.runtimeRequirements).join() + "");
36
+ if (this._hashUpdate === undefined) {
37
+ this._hashUpdate = Array.from(this.runtimeRequirements).join() + "";
38
+ }
39
+ hash.update(this._hashUpdate);
36
40
  }
37
41
 
38
42
  serialize(context) {