webpack 5.55.0 → 5.57.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.

@@ -66,9 +66,10 @@ class AsyncDependenciesBlock extends DependenciesBlock {
66
66
  if (this._stringifiedGroupOptions === undefined) {
67
67
  this._stringifiedGroupOptions = JSON.stringify(this.groupOptions);
68
68
  }
69
- hash.update(this._stringifiedGroupOptions);
70
69
  const chunkGroup = chunkGraph.getBlockChunkGroup(this);
71
- hash.update(chunkGroup ? chunkGroup.id : "");
70
+ hash.update(
71
+ `${this._stringifiedGroupOptions}${chunkGroup ? chunkGroup.id : ""}`
72
+ );
72
73
  super.updateHash(hash, context);
73
74
  }
74
75
 
package/lib/Chunk.js CHANGED
@@ -539,9 +539,9 @@ class Chunk {
539
539
  * @returns {void}
540
540
  */
541
541
  updateHash(hash, chunkGraph) {
542
- hash.update(`${this.id} `);
543
- hash.update(this.ids ? this.ids.join(",") : "");
544
- hash.update(`${this.name || ""} `);
542
+ hash.update(
543
+ `${this.id} ${this.ids ? this.ids.join() : ""} ${this.name || ""} `
544
+ );
545
545
  const xor = new StringXor();
546
546
  for (const m of chunkGraph.getChunkModulesIterable(this)) {
547
547
  xor.add(chunkGraph.getModuleHash(m, this.runtime));
@@ -550,9 +550,7 @@ class Chunk {
550
550
  const entryModules =
551
551
  chunkGraph.getChunkEntryModulesWithChunkGroupIterable(this);
552
552
  for (const [m, chunkGroup] of entryModules) {
553
- hash.update("entry");
554
- hash.update(`${chunkGraph.getModuleId(m)}`);
555
- hash.update(chunkGroup.id);
553
+ hash.update(`entry${chunkGraph.getModuleId(m)}${chunkGroup.id}`);
556
554
  }
557
555
  }
558
556
 
package/lib/ChunkGraph.js CHANGED
@@ -1499,8 +1499,7 @@ Caller might not support runtime-dependent code generation (opt-out via optimiza
1499
1499
  }
1500
1500
  const graphHash = cgm.graphHashes.provide(runtime, () => {
1501
1501
  const hash = createHash(this._hashFunction);
1502
- hash.update(`${cgm.id}`);
1503
- hash.update(`${this.moduleGraph.isAsync(module)}`);
1502
+ hash.update(`${cgm.id}${this.moduleGraph.isAsync(module)}`);
1504
1503
  this.moduleGraph.getExportsInfo(module).updateHash(hash, runtime);
1505
1504
  return BigInt(`0x${/** @type {string} */ (hash.digest("hex"))}`);
1506
1505
  });
@@ -78,7 +78,7 @@ const {
78
78
  createFakeHook
79
79
  } = require("./util/deprecation");
80
80
  const processAsyncTree = require("./util/processAsyncTree");
81
- const { getRuntimeKey, RuntimeSpecMap } = require("./util/runtime");
81
+ const { getRuntimeKey } = require("./util/runtime");
82
82
  const { isSourceEqual } = require("./util/source");
83
83
 
84
84
  /** @template T @typedef {import("tapable").AsArray<T>} AsArray<T> */
@@ -917,8 +917,10 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
917
917
  };
918
918
  defineRemovedModuleTemplates(this.moduleTemplates);
919
919
 
920
- /** @type {WeakMap<Module, WeakTupleMap<any, any>> | undefined} */
920
+ /** @type {Map<Module, WeakTupleMap<any, any>> | undefined} */
921
921
  this.moduleMemCaches = undefined;
922
+ /** @type {Map<Module, WeakTupleMap<any, any>> | undefined} */
923
+ this.moduleMemCaches2 = undefined;
922
924
  this.moduleGraph = new ModuleGraph();
923
925
  /** @type {ChunkGraph} */
924
926
  this.chunkGraph = undefined;
@@ -2169,7 +2171,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
2169
2171
  const moduleMemCacheCache = this.compiler.moduleMemCaches;
2170
2172
  if (!moduleMemCacheCache) return;
2171
2173
  if (!this.moduleMemCaches) {
2172
- this.moduleMemCaches = new WeakMap();
2174
+ this.moduleMemCaches = new Map();
2173
2175
  this.moduleGraph.setModuleMemCaches(this.moduleMemCaches);
2174
2176
  }
2175
2177
  const { moduleGraph, moduleMemCaches } = this;
@@ -2178,43 +2180,96 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
2178
2180
  let statNew = 0;
2179
2181
  let statChanged = 0;
2180
2182
  let statUnchanged = 0;
2181
- let statWithoutHash = 0;
2182
- for (const module of modules) {
2183
- const hash = module.buildInfo && module.buildInfo.hash;
2184
- if (typeof hash === "string") {
2185
- const cachedMemCache = moduleMemCacheCache.get(module);
2186
- if (cachedMemCache === undefined) {
2187
- // create a new entry
2188
- const memCache = new WeakTupleMap();
2189
- moduleMemCacheCache.set(module, {
2190
- hash: hash,
2191
- memCache
2192
- });
2193
- moduleMemCaches.set(module, memCache);
2194
- affectedModules.add(module);
2195
- statNew++;
2196
- } else if (cachedMemCache.hash === hash) {
2197
- // keep the old mem cache
2198
- moduleMemCaches.set(module, cachedMemCache.memCache);
2199
- statUnchanged++;
2183
+ let statReferencesChanged = 0;
2184
+ let statWithoutBuild = 0;
2185
+
2186
+ const computeReferences = module => {
2187
+ /** @type {WeakMap<Dependency, Module>} */
2188
+ let references = undefined;
2189
+ for (const connection of moduleGraph.getOutgoingConnections(module)) {
2190
+ const d = connection.dependency;
2191
+ const m = connection.module;
2192
+ if (!d || !m || unsafeCacheDependencies.has(d)) continue;
2193
+ if (references === undefined) references = new WeakMap();
2194
+ references.set(d, m);
2195
+ }
2196
+ return references;
2197
+ };
2198
+
2199
+ /**
2200
+ * @param {Module} module the module
2201
+ * @param {WeakMap<Dependency, Module>} references references
2202
+ * @returns {boolean} true, when the references differ
2203
+ */
2204
+ const compareReferences = (module, references) => {
2205
+ if (references === undefined) return true;
2206
+ for (const connection of moduleGraph.getOutgoingConnections(module)) {
2207
+ const d = connection.dependency;
2208
+ if (!d) continue;
2209
+ const entry = references.get(d);
2210
+ if (entry === undefined) continue;
2211
+ if (entry !== connection.module) return false;
2212
+ }
2213
+ return true;
2214
+ };
2215
+
2216
+ const modulesWithoutCache = new Set(modules);
2217
+ for (const [module, cachedMemCache] of moduleMemCacheCache) {
2218
+ if (modulesWithoutCache.has(module)) {
2219
+ const buildInfo = module.buildInfo;
2220
+ if (buildInfo) {
2221
+ if (cachedMemCache.buildInfo !== buildInfo) {
2222
+ // use a new one
2223
+ const memCache = new WeakTupleMap();
2224
+ moduleMemCaches.set(module, memCache);
2225
+ affectedModules.add(module);
2226
+ cachedMemCache.buildInfo = buildInfo;
2227
+ cachedMemCache.references = computeReferences(module);
2228
+ cachedMemCache.memCache = memCache;
2229
+ statChanged++;
2230
+ } else if (!compareReferences(module, cachedMemCache.references)) {
2231
+ // use a new one
2232
+ const memCache = new WeakTupleMap();
2233
+ moduleMemCaches.set(module, memCache);
2234
+ affectedModules.add(module);
2235
+ cachedMemCache.references = computeReferences(module);
2236
+ cachedMemCache.memCache = memCache;
2237
+ statReferencesChanged++;
2238
+ } else {
2239
+ // keep the old mem cache
2240
+ moduleMemCaches.set(module, cachedMemCache.memCache);
2241
+ statUnchanged++;
2242
+ }
2200
2243
  } else {
2201
- // use a new one
2202
- const memCache = new WeakTupleMap();
2203
- moduleMemCacheCache.set(module, {
2204
- hash: hash,
2205
- memCache
2206
- });
2207
- moduleMemCaches.set(module, memCache);
2208
- affectedModules.add(module);
2209
- cachedMemCache.hash = hash;
2210
- cachedMemCache.memCache = memCache;
2211
- statChanged++;
2244
+ infectedModules.add(module);
2245
+ moduleMemCacheCache.delete(module);
2246
+ statWithoutBuild++;
2212
2247
  }
2248
+ modulesWithoutCache.delete(module);
2249
+ } else {
2250
+ moduleMemCacheCache.delete(module);
2251
+ }
2252
+ }
2253
+
2254
+ for (const module of modulesWithoutCache) {
2255
+ const buildInfo = module.buildInfo && module.buildInfo.buildInfo;
2256
+ if (buildInfo) {
2257
+ // create a new entry
2258
+ const memCache = new WeakTupleMap();
2259
+ moduleMemCacheCache.set(module, {
2260
+ buildInfo,
2261
+ references: computeReferences(module),
2262
+ memCache
2263
+ });
2264
+ moduleMemCaches.set(module, memCache);
2265
+ affectedModules.add(module);
2266
+ statNew++;
2213
2267
  } else {
2214
2268
  infectedModules.add(module);
2215
- statWithoutHash++;
2269
+ statWithoutBuild++;
2216
2270
  }
2217
2271
  }
2272
+
2218
2273
  const reduceAffectType = connections => {
2219
2274
  let affected = false;
2220
2275
  for (const { dependency } of connections) {
@@ -2261,7 +2316,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
2261
2316
  affectedModules.add(referencingModule);
2262
2317
  }
2263
2318
  const memCache = new WeakTupleMap();
2264
- const cache = moduleMemCacheCache.get(module);
2319
+ const cache = moduleMemCacheCache.get(referencingModule);
2265
2320
  cache.memCache = memCache;
2266
2321
  moduleMemCaches.set(referencingModule, memCache);
2267
2322
  }
@@ -2275,10 +2330,103 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
2275
2330
  infectedModules.size
2276
2331
  } infected of ${
2277
2332
  this.modules.size
2278
- }) modules flagged as affected (${statNew} new modules, ${statChanged} changed, ${statUnchanged} unchanged, ${statWithoutHash} without hash)`
2333
+ }) modules flagged as affected (${statNew} new modules, ${statChanged} changed, ${statReferencesChanged} references changed, ${statUnchanged} unchanged, ${statWithoutBuild} were not built)`
2279
2334
  );
2280
2335
  }
2281
2336
 
2337
+ _updateAffectedModulesWithIds() {
2338
+ const { moduleMemCaches } = this;
2339
+ if (!moduleMemCaches) return;
2340
+ const moduleMemCaches2 = (this.moduleMemCaches2 = new Map());
2341
+ const { moduleGraph, chunkGraph } = this;
2342
+ const key = "memCache2";
2343
+ /**
2344
+ * @param {Module} module module
2345
+ * @returns {{ modules?: Map<Module, string | number | undefined>, blocks?: (string | number)[] }} references
2346
+ */
2347
+ const computeReferences = module => {
2348
+ /** @type {Map<Module, string | number | undefined>} */
2349
+ let modules = undefined;
2350
+ /** @type {(string | number)[] | undefined} */
2351
+ let blocks = undefined;
2352
+ const outgoing = moduleGraph.getOutgoingConnectionsByModule(module);
2353
+ if (outgoing !== undefined) {
2354
+ for (const m of outgoing.keys()) {
2355
+ if (!m) continue;
2356
+ if (modules === undefined) modules = new Map();
2357
+ modules.set(m, chunkGraph.getModuleId(module));
2358
+ }
2359
+ }
2360
+ if (module.blocks.length > 0) {
2361
+ blocks = [];
2362
+ const queue = Array.from(module.blocks);
2363
+ for (const block of queue) {
2364
+ const chunkGroup = chunkGraph.getBlockChunkGroup(block);
2365
+ if (chunkGroup) {
2366
+ for (const chunk of chunkGroup.chunks) {
2367
+ blocks.push(chunk.id);
2368
+ }
2369
+ } else {
2370
+ blocks.push(null);
2371
+ }
2372
+ queue.push.apply(queue, block.blocks);
2373
+ }
2374
+ }
2375
+ return { modules, blocks };
2376
+ };
2377
+ /**
2378
+ * @param {Module} module module
2379
+ * @param {Object} references references
2380
+ * @param {Map<Module, string | number>=} references.modules modules
2381
+ * @param {(string | number)[]=} references.blocks blocks
2382
+ * @returns {boolean} ok?
2383
+ */
2384
+ const compareReferences = (module, { modules, blocks }) => {
2385
+ if (modules !== undefined) {
2386
+ for (const [module, id] of modules) {
2387
+ if (chunkGraph.getModuleId(module) !== id) return false;
2388
+ }
2389
+ }
2390
+ if (blocks !== undefined) {
2391
+ const queue = Array.from(module.blocks);
2392
+ let i = 0;
2393
+ for (const block of queue) {
2394
+ const chunkGroup = chunkGraph.getBlockChunkGroup(block);
2395
+ if (chunkGroup) {
2396
+ for (const chunk of chunkGroup.chunks) {
2397
+ if (i >= blocks.length || blocks[i++] !== chunk.id) return false;
2398
+ }
2399
+ } else {
2400
+ if (i >= blocks.length || blocks[i++] !== null) return false;
2401
+ }
2402
+ queue.push.apply(queue, block.blocks);
2403
+ }
2404
+ if (i !== blocks.length) return false;
2405
+ }
2406
+ return true;
2407
+ };
2408
+
2409
+ for (const [module, memCache] of moduleMemCaches) {
2410
+ /** @type {{ references: { modules?: Map<Module, string | number | undefined>, blocks?: (string | number)[]}, memCache: WeakTupleMap<any[], any> }} */
2411
+ const cache = memCache.get(key);
2412
+ if (cache === undefined) {
2413
+ const memCache2 = new WeakTupleMap();
2414
+ memCache.set(key, {
2415
+ references: computeReferences(module),
2416
+ memCache: memCache2
2417
+ });
2418
+ moduleMemCaches2.set(module, memCache2);
2419
+ } else if (!compareReferences(module, cache.references)) {
2420
+ const memCache = new WeakTupleMap();
2421
+ cache.references = computeReferences(module);
2422
+ cache.memCache = memCache;
2423
+ moduleMemCaches2.set(module, memCache);
2424
+ } else {
2425
+ moduleMemCaches2.set(module, cache.memCache);
2426
+ }
2427
+ }
2428
+ }
2429
+
2282
2430
  finish(callback) {
2283
2431
  this.factorizeQueue.clear();
2284
2432
  if (this.profile) {
@@ -2523,6 +2671,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
2523
2671
  this.assetsInfo.clear();
2524
2672
  this.moduleGraph.removeAllModuleAttributes();
2525
2673
  this.moduleGraph.unfreeze();
2674
+ this.moduleMemCaches2 = undefined;
2526
2675
  }
2527
2676
 
2528
2677
  /**
@@ -2740,6 +2889,8 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
2740
2889
 
2741
2890
  this.assignRuntimeIds();
2742
2891
 
2892
+ this._updateAffectedModulesWithIds();
2893
+
2743
2894
  this.sortItemsWithChunkIds();
2744
2895
 
2745
2896
  if (shouldRecord) {
@@ -3083,28 +3234,19 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
3083
3234
  chunkGraphEntries = this._getChunkGraphEntries()
3084
3235
  } = {}) {
3085
3236
  const context = { chunkGraph, codeGenerationResults };
3086
- const { moduleMemCaches } = this;
3237
+ const { moduleMemCaches2 } = this;
3087
3238
  this.logger.time("runtime requirements.modules");
3088
3239
  const additionalModuleRuntimeRequirements =
3089
3240
  this.hooks.additionalModuleRuntimeRequirements;
3090
3241
  const runtimeRequirementInModule = this.hooks.runtimeRequirementInModule;
3091
3242
  for (const module of modules) {
3092
3243
  if (chunkGraph.getNumberOfModuleChunks(module) > 0) {
3093
- const memCache =
3094
- moduleMemCaches &&
3095
- // modules with async blocks depend on the chunk graph and can't be cached that way
3096
- module.blocks.length === 0 &&
3097
- moduleMemCaches.get(module);
3098
- /** @type {RuntimeSpecMap<Set<string>>} */
3099
- const moduleRuntimeRequirementsMemCache =
3100
- memCache &&
3101
- memCache.provide(
3102
- "moduleRuntimeRequirements",
3103
- () => new RuntimeSpecMap()
3104
- );
3244
+ const memCache = moduleMemCaches2 && moduleMemCaches2.get(module);
3105
3245
  for (const runtime of chunkGraph.getModuleRuntimes(module)) {
3106
- if (moduleRuntimeRequirementsMemCache) {
3107
- const cached = moduleRuntimeRequirementsMemCache.get(runtime);
3246
+ if (memCache) {
3247
+ const cached = memCache.get(
3248
+ `moduleRuntimeRequirements-${getRuntimeKey(runtime)}`
3249
+ );
3108
3250
  if (cached !== undefined) {
3109
3251
  if (cached !== null) {
3110
3252
  chunkGraph.addModuleRuntimeRequirements(
@@ -3125,8 +3267,11 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
3125
3267
  } else if (additionalModuleRuntimeRequirements.isUsed()) {
3126
3268
  set = new Set();
3127
3269
  } else {
3128
- if (moduleRuntimeRequirementsMemCache) {
3129
- moduleRuntimeRequirementsMemCache.set(runtime, null);
3270
+ if (memCache) {
3271
+ memCache.set(
3272
+ `moduleRuntimeRequirements-${getRuntimeKey(runtime)}`,
3273
+ null
3274
+ );
3130
3275
  }
3131
3276
  continue;
3132
3277
  }
@@ -3137,12 +3282,18 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
3137
3282
  if (hook !== undefined) hook.call(module, set, context);
3138
3283
  }
3139
3284
  if (set.size === 0) {
3140
- if (moduleRuntimeRequirementsMemCache) {
3141
- moduleRuntimeRequirementsMemCache.set(runtime, null);
3285
+ if (memCache) {
3286
+ memCache.set(
3287
+ `moduleRuntimeRequirements-${getRuntimeKey(runtime)}`,
3288
+ null
3289
+ );
3142
3290
  }
3143
3291
  } else {
3144
- if (moduleRuntimeRequirementsMemCache) {
3145
- moduleRuntimeRequirementsMemCache.set(runtime, set);
3292
+ if (memCache) {
3293
+ memCache.set(
3294
+ `moduleRuntimeRequirements-${getRuntimeKey(runtime)}`,
3295
+ set
3296
+ );
3146
3297
  chunkGraph.addModuleRuntimeRequirements(
3147
3298
  module,
3148
3299
  runtime,
@@ -3547,21 +3698,13 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
3547
3698
  createModuleHashes() {
3548
3699
  let statModulesHashed = 0;
3549
3700
  let statModulesFromCache = 0;
3550
- const { chunkGraph, runtimeTemplate, moduleMemCaches } = this;
3701
+ const { chunkGraph, runtimeTemplate, moduleMemCaches2 } = this;
3551
3702
  const { hashFunction, hashDigest, hashDigestLength } = this.outputOptions;
3552
3703
  for (const module of this.modules) {
3553
- const memCache =
3554
- moduleMemCaches &&
3555
- // modules with async blocks depend on the chunk graph and can't be cached that way
3556
- module.blocks.length === 0 &&
3557
- moduleMemCaches.get(module);
3558
- /** @type {RuntimeSpecMap<string>} */
3559
- const moduleHashesMemCache =
3560
- memCache &&
3561
- memCache.provide("moduleHashes", () => new RuntimeSpecMap());
3704
+ const memCache = moduleMemCaches2 && moduleMemCaches2.get(module);
3562
3705
  for (const runtime of chunkGraph.getModuleRuntimes(module)) {
3563
- if (moduleHashesMemCache) {
3564
- const digest = moduleHashesMemCache.get(runtime);
3706
+ if (memCache) {
3707
+ const digest = memCache.get(`moduleHash-${getRuntimeKey(runtime)}`);
3565
3708
  if (digest !== undefined) {
3566
3709
  chunkGraph.setModuleHashes(
3567
3710
  module,
@@ -3583,8 +3726,8 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
3583
3726
  hashDigest,
3584
3727
  hashDigestLength
3585
3728
  );
3586
- if (moduleHashesMemCache) {
3587
- moduleHashesMemCache.set(runtime, digest);
3729
+ if (memCache) {
3730
+ memCache.set(`moduleHash-${getRuntimeKey(runtime)}`, digest);
3588
3731
  }
3589
3732
  }
3590
3733
  }
package/lib/Compiler.js CHANGED
@@ -40,6 +40,7 @@ const { isSourceEqual } = require("./util/source");
40
40
  /** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
41
41
  /** @typedef {import("../declarations/WebpackOptions").WebpackPluginInstance} WebpackPluginInstance */
42
42
  /** @typedef {import("./Chunk")} Chunk */
43
+ /** @typedef {import("./Dependency")} Dependency */
43
44
  /** @typedef {import("./FileSystemInfo").FileSystemInfoEntry} FileSystemInfoEntry */
44
45
  /** @typedef {import("./Module")} Module */
45
46
  /** @typedef {import("./util/WeakTupleMap")} WeakTupleMap */
@@ -248,7 +249,7 @@ class Compiler {
248
249
 
249
250
  this.cache = new Cache();
250
251
 
251
- /** @type {WeakMap<Module, { hash: string, memCache: WeakTupleMap }> | undefined} */
252
+ /** @type {Map<Module, { buildInfo: object, references: WeakMap<Dependency, Module>, memCache: WeakTupleMap }> | undefined} */
252
253
  this.moduleMemCaches = undefined;
253
254
 
254
255
  this.compilerPath = "";
@@ -13,7 +13,7 @@ const {
13
13
  evaluateToString,
14
14
  toConstantDependency
15
15
  } = require("./javascript/JavascriptParserHelpers");
16
- const { provide } = require("./util/MapHelpers");
16
+ const createHash = require("./util/createHash");
17
17
 
18
18
  /** @typedef {import("estree").Expression} Expression */
19
19
  /** @typedef {import("./Compiler")} Compiler */
@@ -250,7 +250,7 @@ const toCacheVersion = code => {
250
250
  };
251
251
 
252
252
  const VALUE_DEP_PREFIX = "webpack/DefinePlugin ";
253
- const VALUE_DEP_MAIN = "webpack/DefinePlugin";
253
+ const VALUE_DEP_MAIN = "webpack/DefinePlugin_hash";
254
254
 
255
255
  class DefinePlugin {
256
256
  /**
@@ -286,12 +286,11 @@ class DefinePlugin {
286
286
  );
287
287
  const { runtimeTemplate } = compilation;
288
288
 
289
- const mainValue = /** @type {Set<string>} */ (
290
- provide(
291
- compilation.valueCacheVersions,
292
- VALUE_DEP_MAIN,
293
- () => new Set()
294
- )
289
+ const mainHash = createHash(compilation.outputOptions.hashFunction);
290
+ mainHash.update(
291
+ /** @type {string} */ (
292
+ compilation.valueCacheVersions.get(VALUE_DEP_MAIN)
293
+ ) || ""
295
294
  );
296
295
 
297
296
  /**
@@ -300,6 +299,7 @@ class DefinePlugin {
300
299
  * @returns {void}
301
300
  */
302
301
  const handler = parser => {
302
+ const mainValue = compilation.valueCacheVersions.get(VALUE_DEP_MAIN);
303
303
  parser.hooks.program.tap("DefinePlugin", () => {
304
304
  const { buildInfo } = parser.state.module;
305
305
  if (!buildInfo.valueDependencies)
@@ -565,7 +565,7 @@ class DefinePlugin {
565
565
  const code = definitions[key];
566
566
  const version = toCacheVersion(code);
567
567
  const name = VALUE_DEP_PREFIX + prefix + key;
568
- mainValue.add(name);
568
+ mainHash.update("|" + prefix + key);
569
569
  const oldVersion = compilation.valueCacheVersions.get(name);
570
570
  if (oldVersion === undefined) {
571
571
  compilation.valueCacheVersions.set(name, version);
@@ -589,6 +589,11 @@ class DefinePlugin {
589
589
  };
590
590
 
591
591
  walkDefinitionsForValues(definitions, "");
592
+
593
+ compilation.valueCacheVersions.set(
594
+ VALUE_DEP_MAIN,
595
+ /** @type {string} */ (mainHash.digest("hex").slice(0, 8))
596
+ );
592
597
  }
593
598
  );
594
599
  }
@@ -48,8 +48,7 @@ class DependencyTemplates {
48
48
  */
49
49
  updateHash(part) {
50
50
  const hash = createHash(this._hashFunction);
51
- hash.update(this._hash);
52
- hash.update(part);
51
+ hash.update(`${this._hash}${part}`);
53
52
  this._hash = /** @type {string} */ (hash.digest("hex"));
54
53
  }
55
54
 
package/lib/DllModule.js CHANGED
@@ -117,8 +117,7 @@ class DllModule extends Module {
117
117
  * @returns {void}
118
118
  */
119
119
  updateHash(hash, context) {
120
- hash.update("dll module");
121
- hash.update(this.name || "");
120
+ hash.update(`dll module${this.name || ""}`);
122
121
  super.updateHash(hash, context);
123
122
  }
124
123
 
@@ -1412,10 +1412,11 @@ class ExportInfo {
1412
1412
  }
1413
1413
 
1414
1414
  _updateHash(hash, runtime, alreadyVisitedExportsInfo) {
1415
- hash.update(`${this._usedName || this.name}`);
1416
- hash.update(`${this.getUsed(runtime)}`);
1417
- hash.update(`${this.provided}`);
1418
- hash.update(`${this.terminalBinding}`);
1415
+ hash.update(
1416
+ `${this._usedName || this.name}${this.getUsed(runtime)}${this.provided}${
1417
+ this.terminalBinding
1418
+ }`
1419
+ );
1419
1420
  if (this.exportsInfo && !alreadyVisitedExportsInfo.has(this.exportsInfo)) {
1420
1421
  this.exportsInfo._updateHash(hash, runtime, alreadyVisitedExportsInfo);
1421
1422
  }
@@ -32,6 +32,7 @@ const { register } = require("./util/serialization");
32
32
  /** @typedef {import("./Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
33
33
  /** @typedef {import("./Module").LibIdentOptions} LibIdentOptions */
34
34
  /** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */
35
+ /** @typedef {import("./NormalModuleFactory")} NormalModuleFactory */
35
36
  /** @typedef {import("./RequestShortener")} RequestShortener */
36
37
  /** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */
37
38
  /** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
@@ -497,6 +498,10 @@ class ExternalModule extends Module {
497
498
  callback();
498
499
  }
499
500
 
501
+ restoreFromUnsafeCache(unsafeCacheData, normalModuleFactory) {
502
+ this._restoreFromUnsafeCache(unsafeCacheData, normalModuleFactory);
503
+ }
504
+
500
505
  /**
501
506
  * @param {ConcatenationBailoutReasonContext} context context
502
507
  * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated
@@ -679,10 +684,10 @@ class ExternalModule extends Module {
679
684
  */
680
685
  updateHash(hash, context) {
681
686
  const { chunkGraph } = context;
682
- hash.update(this.externalType);
683
- hash.update(JSON.stringify(this.request));
684
687
  hash.update(
685
- JSON.stringify(Boolean(this.isOptional(chunkGraph.moduleGraph)))
688
+ `${this.externalType}${JSON.stringify(this.request)}${this.isOptional(
689
+ chunkGraph.moduleGraph
690
+ )}`
686
691
  );
687
692
  super.updateHash(hash, context);
688
693
  }
@@ -46,10 +46,15 @@ class FlagDependencyUsagePlugin {
46
46
  stage: STAGE_DEFAULT
47
47
  },
48
48
  modules => {
49
+ if (compilation.moduleMemCaches) {
50
+ throw new Error(
51
+ "optimization.usedExports can't be used with cacheUnaffected as export usage is a global effect"
52
+ );
53
+ }
54
+
49
55
  const logger = compilation.getLogger(
50
56
  "webpack.FlagDependencyUsagePlugin"
51
57
  );
52
-
53
58
  /** @type {Map<ExportsInfo, Module>} */
54
59
  const exportInfoToModuleMap = new Map();
55
60
 
@@ -29,7 +29,7 @@ const EMPTY_SET = new Set();
29
29
 
30
30
  /**
31
31
  * @param {SortableSet<ModuleGraphConnection>} set input
32
- * @returns {readonly Map<Module, readonly ModuleGraphConnection[]>} mapped by origin module
32
+ * @returns {readonly Map<Module | undefined, readonly ModuleGraphConnection[]>} mapped by origin module
33
33
  */
34
34
  const getConnectionsByOriginModule = set => {
35
35
  const map = new Map();
@@ -57,11 +57,41 @@ const getConnectionsByOriginModule = set => {
57
57
  return map;
58
58
  };
59
59
 
60
+ /**
61
+ * @param {SortableSet<ModuleGraphConnection>} set input
62
+ * @returns {readonly Map<Module | undefined, readonly ModuleGraphConnection[]>} mapped by module
63
+ */
64
+ const getConnectionsByModule = set => {
65
+ const map = new Map();
66
+ /** @type {Module | 0} */
67
+ let lastModule = 0;
68
+ /** @type {ModuleGraphConnection[]} */
69
+ let lastList = undefined;
70
+ for (const connection of set) {
71
+ const { module } = connection;
72
+ if (lastModule === module) {
73
+ lastList.push(connection);
74
+ } else {
75
+ lastModule = module;
76
+ const list = map.get(module);
77
+ if (list !== undefined) {
78
+ lastList = list;
79
+ list.push(connection);
80
+ } else {
81
+ const list = [connection];
82
+ lastList = list;
83
+ map.set(module, list);
84
+ }
85
+ }
86
+ }
87
+ return map;
88
+ };
89
+
60
90
  class ModuleGraphModule {
61
91
  constructor() {
62
92
  /** @type {SortableSet<ModuleGraphConnection>} */
63
93
  this.incomingConnections = new SortableSet();
64
- /** @type {Set<ModuleGraphConnection> | undefined} */
94
+ /** @type {SortableSet<ModuleGraphConnection> | undefined} */
65
95
  this.outgoingConnections = undefined;
66
96
  /** @type {Module | null} */
67
97
  this.issuer = undefined;
@@ -104,7 +134,7 @@ class ModuleGraph {
104
134
  /** @type {WeakTupleMap<any[], any>} */
105
135
  this._cache = undefined;
106
136
 
107
- /** @type {WeakMap<Module, WeakTupleMap<any, any>>} */
137
+ /** @type {Map<Module, WeakTupleMap<any, any>>} */
108
138
  this._moduleMemCaches = undefined;
109
139
  }
110
140
 
@@ -180,7 +210,7 @@ class ModuleGraph {
180
210
  }
181
211
  mgm._unassignedConnections.push(connection);
182
212
  if (mgm.outgoingConnections === undefined) {
183
- mgm.outgoingConnections = new Set();
213
+ mgm.outgoingConnections = new SortableSet();
184
214
  }
185
215
  mgm.outgoingConnections.add(connection);
186
216
  } else {
@@ -282,7 +312,7 @@ class ModuleGraph {
282
312
  const oldConnections = oldMgm.outgoingConnections;
283
313
  if (oldConnections !== undefined) {
284
314
  if (newMgm.outgoingConnections === undefined) {
285
- newMgm.outgoingConnections = new Set();
315
+ newMgm.outgoingConnections = new SortableSet();
286
316
  }
287
317
  const newConnections = newMgm.outgoingConnections;
288
318
  for (const connection of oldConnections) {
@@ -319,7 +349,7 @@ class ModuleGraph {
319
349
  const oldConnections = oldMgm.outgoingConnections;
320
350
  if (oldConnections !== undefined) {
321
351
  if (newMgm.outgoingConnections === undefined) {
322
- newMgm.outgoingConnections = new Set();
352
+ newMgm.outgoingConnections = new SortableSet();
323
353
  }
324
354
  const newConnections = newMgm.outgoingConnections;
325
355
  for (const connection of oldConnections) {
@@ -434,13 +464,24 @@ class ModuleGraph {
434
464
 
435
465
  /**
436
466
  * @param {Module} module the module
437
- * @returns {readonly Map<Module, readonly ModuleGraphConnection[]>} reasons why a module is included, in a map by source module
467
+ * @returns {readonly Map<Module | undefined, readonly ModuleGraphConnection[]>} reasons why a module is included, in a map by source module
438
468
  */
439
469
  getIncomingConnectionsByOriginModule(module) {
440
470
  const connections = this._getModuleGraphModule(module).incomingConnections;
441
471
  return connections.getFromUnorderedCache(getConnectionsByOriginModule);
442
472
  }
443
473
 
474
+ /**
475
+ * @param {Module} module the module
476
+ * @returns {readonly Map<Module | undefined, readonly ModuleGraphConnection[]> | undefined} connections to modules, in a map by module
477
+ */
478
+ getOutgoingConnectionsByModule(module) {
479
+ const connections = this._getModuleGraphModule(module).outgoingConnections;
480
+ return connections === undefined
481
+ ? undefined
482
+ : connections.getFromUnorderedCache(getConnectionsByModule);
483
+ }
484
+
444
485
  /**
445
486
  * @param {Module} module the module
446
487
  * @returns {ModuleProfile | null} the module profile
@@ -728,7 +769,7 @@ class ModuleGraph {
728
769
  }
729
770
 
730
771
  /**
731
- * @param {WeakMap<Module, WeakTupleMap<any, any>>} moduleMemCaches mem caches for modules for better caching
772
+ * @param {Map<Module, WeakTupleMap<any, any>>} moduleMemCaches mem caches for modules for better caching
732
773
  */
733
774
  setModuleMemCaches(moduleMemCaches) {
734
775
  this._moduleMemCaches = moduleMemCaches;
@@ -550,7 +550,7 @@ class WebpackOptionsApply extends OptionsApply {
550
550
  "'cache.cacheUnaffected: true' is only allowed when 'experiments.cacheUnaffected' is enabled"
551
551
  );
552
552
  }
553
- compiler.moduleMemCaches = new WeakMap();
553
+ compiler.moduleMemCaches = new Map();
554
554
  }
555
555
  break;
556
556
  }
@@ -577,7 +577,7 @@ class WebpackOptionsApply extends OptionsApply {
577
577
  "'cache.memoryCacheUnaffected: true' is only allowed when 'experiments.cacheUnaffected' is enabled"
578
578
  );
579
579
  }
580
- compiler.moduleMemCaches = new WeakMap();
580
+ compiler.moduleMemCaches = new Map();
581
581
  }
582
582
  switch (cacheOptions.store) {
583
583
  case "pack": {
@@ -137,11 +137,9 @@ class ArrayPushCallbackChunkFormatPlugin {
137
137
  "ArrayPushCallbackChunkFormatPlugin",
138
138
  (chunk, hash, { chunkGraph, runtimeTemplate }) => {
139
139
  if (chunk.hasRuntime()) return;
140
- hash.update("ArrayPushCallbackChunkFormatPlugin");
141
- hash.update("1");
142
- hash.update(`${runtimeTemplate.outputOptions.chunkLoadingGlobal}`);
143
- hash.update(`${runtimeTemplate.outputOptions.hotUpdateGlobal}`);
144
- hash.update(`${runtimeTemplate.outputOptions.globalObject}`);
140
+ hash.update(
141
+ `ArrayPushCallbackChunkFormatPlugin1${runtimeTemplate.outputOptions.chunkLoadingGlobal}${runtimeTemplate.outputOptions.hotUpdateGlobal}${runtimeTemplate.outputOptions.globalObject}`
142
+ );
145
143
  const entries = Array.from(
146
144
  chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)
147
145
  );
@@ -157,6 +157,11 @@ class MangleExportsPlugin {
157
157
  compilation.hooks.optimizeCodeGeneration.tap(
158
158
  "MangleExportsPlugin",
159
159
  modules => {
160
+ if (compilation.moduleMemCaches) {
161
+ throw new Error(
162
+ "optimization.mangleExports can't be used with cacheUnaffected as export mangling is a global effect"
163
+ );
164
+ }
160
165
  for (const module of modules) {
161
166
  const isNamespace =
162
167
  module.buildMeta && module.buildMeta.exportsType === "namespace";
@@ -8,41 +8,47 @@
8
8
  class StringXor {
9
9
  constructor() {
10
10
  this._value = undefined;
11
- this._buffer = undefined;
12
11
  }
13
12
 
13
+ /**
14
+ * @param {string} str string
15
+ * @returns {void}
16
+ */
14
17
  add(str) {
15
- let buf = this._buffer;
16
- let value;
17
- if (buf === undefined) {
18
- buf = this._buffer = Buffer.from(str, "latin1");
19
- this._value = Buffer.from(buf);
18
+ const len = str.length;
19
+ const value = this._value;
20
+ if (value === undefined) {
21
+ const newValue = (this._value = Buffer.allocUnsafe(len));
22
+ for (let i = 0; i < len; i++) {
23
+ newValue[i] = str.charCodeAt(i);
24
+ }
20
25
  return;
21
- } else if (buf.length !== str.length) {
22
- value = this._value;
23
- buf = this._buffer = Buffer.from(str, "latin1");
24
- if (value.length < buf.length) {
25
- this._value = Buffer.allocUnsafe(buf.length);
26
- value.copy(this._value);
27
- this._value.fill(0, value.length);
28
- value = this._value;
26
+ }
27
+ const valueLen = value.length;
28
+ if (valueLen < len) {
29
+ const newValue = (this._value = Buffer.allocUnsafe(len));
30
+ let i;
31
+ for (i = 0; i < valueLen; i++) {
32
+ newValue[i] = value[i] ^ str.charCodeAt(i);
33
+ }
34
+ for (; i < len; i++) {
35
+ newValue[i] = str.charCodeAt(i);
29
36
  }
30
37
  } else {
31
- value = this._value;
32
- buf.write(str, "latin1");
33
- }
34
- const len = buf.length;
35
- for (let i = 0; i < len; i++) {
36
- value[i] = value[i] ^ buf[i];
38
+ for (let i = 0; i < len; i++) {
39
+ value[i] = value[i] ^ str.charCodeAt(i);
40
+ }
37
41
  }
38
42
  }
39
43
 
40
44
  toString() {
41
- return this._value === undefined ? "" : this._value.toString("latin1");
45
+ const value = this._value;
46
+ return value === undefined ? "" : value.toString("latin1");
42
47
  }
43
48
 
44
49
  updateHash(hash) {
45
- if (this._value !== undefined) hash.update(this._value);
50
+ const value = this._value;
51
+ if (value !== undefined) hash.update(value);
46
52
  }
47
53
  }
48
54
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webpack",
3
- "version": "5.55.0",
3
+ "version": "5.57.0",
4
4
  "author": "Tobias Koppers @sokra",
5
5
  "description": "Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.",
6
6
  "license": "MIT",
package/types.d.ts CHANGED
@@ -1460,7 +1460,8 @@ declare class Compilation {
1460
1460
  chunkTemplate: ChunkTemplate;
1461
1461
  runtimeTemplate: RuntimeTemplate;
1462
1462
  moduleTemplates: { javascript: ModuleTemplate };
1463
- moduleMemCaches?: WeakMap<Module, WeakTupleMap<any, any>>;
1463
+ moduleMemCaches?: Map<Module, WeakTupleMap<any, any>>;
1464
+ moduleMemCaches2?: Map<Module, WeakTupleMap<any, any>>;
1464
1465
  moduleGraph: ModuleGraph;
1465
1466
  chunkGraph: ChunkGraph;
1466
1467
  codeGenerationResults: CodeGenerationResults;
@@ -1907,9 +1908,13 @@ declare class Compiler {
1907
1908
  context: string;
1908
1909
  requestShortener: RequestShortener;
1909
1910
  cache: Cache;
1910
- moduleMemCaches?: WeakMap<
1911
+ moduleMemCaches?: Map<
1911
1912
  Module,
1912
- { hash: string; memCache: WeakTupleMap<any, any> }
1913
+ {
1914
+ buildInfo: object;
1915
+ references: WeakMap<Dependency, Module>;
1916
+ memCache: WeakTupleMap<any, any>;
1917
+ }
1913
1918
  >;
1914
1919
  compilerPath: string;
1915
1920
  running: boolean;
@@ -3737,6 +3742,10 @@ declare class ExternalModule extends Module {
3737
3742
  request: string | string[] | Record<string, string | string[]>;
3738
3743
  externalType: string;
3739
3744
  userRequest: string;
3745
+ restoreFromUnsafeCache(
3746
+ unsafeCacheData?: any,
3747
+ normalModuleFactory?: any
3748
+ ): void;
3740
3749
  }
3741
3750
  declare interface ExternalModuleInfo {
3742
3751
  index: number;
@@ -6695,7 +6704,10 @@ declare class ModuleGraph {
6695
6704
  getOutgoingConnections(module: Module): Iterable<ModuleGraphConnection>;
6696
6705
  getIncomingConnectionsByOriginModule(
6697
6706
  module: Module
6698
- ): Map<Module, ReadonlyArray<ModuleGraphConnection>>;
6707
+ ): Map<undefined | Module, ReadonlyArray<ModuleGraphConnection>>;
6708
+ getOutgoingConnectionsByModule(
6709
+ module: Module
6710
+ ): undefined | Map<undefined | Module, ReadonlyArray<ModuleGraphConnection>>;
6699
6711
  getProfile(module: Module): null | ModuleProfile;
6700
6712
  setProfile(module: Module, profile: null | ModuleProfile): void;
6701
6713
  getIssuer(module: Module): null | Module;
@@ -6736,7 +6748,7 @@ declare class ModuleGraph {
6736
6748
  ...args: T
6737
6749
  ): V;
6738
6750
  setModuleMemCaches(
6739
- moduleMemCaches: WeakMap<Module, WeakTupleMap<any, any>>
6751
+ moduleMemCaches: Map<Module, WeakTupleMap<any, any>>
6740
6752
  ): void;
6741
6753
  dependencyCacheProvide(dependency: Dependency, ...args: any[]): any;
6742
6754
  static getModuleGraphForModule(