webpack 5.55.1 → 5.57.1

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
  });
@@ -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;
@@ -2179,7 +2181,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
2179
2181
  let statChanged = 0;
2180
2182
  let statUnchanged = 0;
2181
2183
  let statReferencesChanged = 0;
2182
- let statWithoutHash = 0;
2184
+ let statWithoutBuild = 0;
2183
2185
 
2184
2186
  const computeReferences = module => {
2185
2187
  /** @type {WeakMap<Dependency, Module>} */
@@ -2211,48 +2213,63 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
2211
2213
  return true;
2212
2214
  };
2213
2215
 
2214
- for (const module of modules) {
2215
- const hash = module.buildInfo && module.buildInfo.hash;
2216
- if (typeof hash === "string") {
2217
- const cachedMemCache = moduleMemCacheCache.get(module);
2218
- if (cachedMemCache === undefined) {
2219
- // create a new entry
2220
- const memCache = new WeakTupleMap();
2221
- moduleMemCacheCache.set(module, {
2222
- hash: hash,
2223
- references: computeReferences(module),
2224
- memCache
2225
- });
2226
- moduleMemCaches.set(module, memCache);
2227
- affectedModules.add(module);
2228
- statNew++;
2229
- } else if (cachedMemCache.hash !== hash) {
2230
- // use a new one
2231
- const memCache = new WeakTupleMap();
2232
- moduleMemCaches.set(module, memCache);
2233
- affectedModules.add(module);
2234
- cachedMemCache.hash = hash;
2235
- cachedMemCache.references = computeReferences(module);
2236
- cachedMemCache.memCache = memCache;
2237
- statChanged++;
2238
- } else if (!compareReferences(module, cachedMemCache.references)) {
2239
- // use a new one
2240
- const memCache = new WeakTupleMap();
2241
- moduleMemCaches.set(module, memCache);
2242
- affectedModules.add(module);
2243
- cachedMemCache.references = computeReferences(module);
2244
- cachedMemCache.memCache = memCache;
2245
- statReferencesChanged++;
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
+ }
2246
2243
  } else {
2247
- // keep the old mem cache
2248
- moduleMemCaches.set(module, cachedMemCache.memCache);
2249
- statUnchanged++;
2244
+ infectedModules.add(module);
2245
+ moduleMemCacheCache.delete(module);
2246
+ statWithoutBuild++;
2250
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;
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++;
2251
2267
  } else {
2252
2268
  infectedModules.add(module);
2253
- statWithoutHash++;
2269
+ statWithoutBuild++;
2254
2270
  }
2255
2271
  }
2272
+
2256
2273
  const reduceAffectType = connections => {
2257
2274
  let affected = false;
2258
2275
  for (const { dependency } of connections) {
@@ -2313,7 +2330,112 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
2313
2330
  infectedModules.size
2314
2331
  } infected of ${
2315
2332
  this.modules.size
2316
- }) modules flagged as affected (${statNew} new modules, ${statChanged} changed, ${statReferencesChanged} references 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)`
2334
+ );
2335
+ }
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
+ let statUnchanged = 0;
2344
+ let statChanged = 0;
2345
+ let statNew = 0;
2346
+ /**
2347
+ * @param {Module} module module
2348
+ * @returns {{ modules?: Map<Module, string | number | undefined>, blocks?: (string | number)[] }} references
2349
+ */
2350
+ const computeReferences = module => {
2351
+ /** @type {Map<Module, string | number | undefined>} */
2352
+ let modules = undefined;
2353
+ /** @type {(string | number)[] | undefined} */
2354
+ let blocks = undefined;
2355
+ const outgoing = moduleGraph.getOutgoingConnectionsByModule(module);
2356
+ if (outgoing !== undefined) {
2357
+ for (const m of outgoing.keys()) {
2358
+ if (!m) continue;
2359
+ if (modules === undefined) modules = new Map();
2360
+ modules.set(m, chunkGraph.getModuleId(m));
2361
+ }
2362
+ }
2363
+ if (module.blocks.length > 0) {
2364
+ blocks = [];
2365
+ const queue = Array.from(module.blocks);
2366
+ for (const block of queue) {
2367
+ const chunkGroup = chunkGraph.getBlockChunkGroup(block);
2368
+ if (chunkGroup) {
2369
+ for (const chunk of chunkGroup.chunks) {
2370
+ blocks.push(chunk.id);
2371
+ }
2372
+ } else {
2373
+ blocks.push(null);
2374
+ }
2375
+ queue.push.apply(queue, block.blocks);
2376
+ }
2377
+ }
2378
+ return { modules, blocks };
2379
+ };
2380
+ /**
2381
+ * @param {Module} module module
2382
+ * @param {Object} references references
2383
+ * @param {Map<Module, string | number>=} references.modules modules
2384
+ * @param {(string | number)[]=} references.blocks blocks
2385
+ * @returns {boolean} ok?
2386
+ */
2387
+ const compareReferences = (module, { modules, blocks }) => {
2388
+ if (modules !== undefined) {
2389
+ for (const [module, id] of modules) {
2390
+ if (chunkGraph.getModuleId(module) !== id) return false;
2391
+ }
2392
+ }
2393
+ if (blocks !== undefined) {
2394
+ const queue = Array.from(module.blocks);
2395
+ let i = 0;
2396
+ for (const block of queue) {
2397
+ const chunkGroup = chunkGraph.getBlockChunkGroup(block);
2398
+ if (chunkGroup) {
2399
+ for (const chunk of chunkGroup.chunks) {
2400
+ if (i >= blocks.length || blocks[i++] !== chunk.id) return false;
2401
+ }
2402
+ } else {
2403
+ if (i >= blocks.length || blocks[i++] !== null) return false;
2404
+ }
2405
+ queue.push.apply(queue, block.blocks);
2406
+ }
2407
+ if (i !== blocks.length) return false;
2408
+ }
2409
+ return true;
2410
+ };
2411
+
2412
+ for (const [module, memCache] of moduleMemCaches) {
2413
+ /** @type {{ references: { modules?: Map<Module, string | number | undefined>, blocks?: (string | number)[]}, memCache: WeakTupleMap<any[], any> }} */
2414
+ const cache = memCache.get(key);
2415
+ if (cache === undefined) {
2416
+ const memCache2 = new WeakTupleMap();
2417
+ memCache.set(key, {
2418
+ references: computeReferences(module),
2419
+ memCache: memCache2
2420
+ });
2421
+ moduleMemCaches2.set(module, memCache2);
2422
+ statNew++;
2423
+ } else if (!compareReferences(module, cache.references)) {
2424
+ const memCache = new WeakTupleMap();
2425
+ cache.references = computeReferences(module);
2426
+ cache.memCache = memCache;
2427
+ moduleMemCaches2.set(module, memCache);
2428
+ statChanged++;
2429
+ } else {
2430
+ moduleMemCaches2.set(module, cache.memCache);
2431
+ statUnchanged++;
2432
+ }
2433
+ }
2434
+
2435
+ this.logger.log(
2436
+ `${Math.round(
2437
+ (100 * statChanged) / (statNew + statChanged + statUnchanged)
2438
+ )}% modules flagged as affected by chunk graph (${statNew} new modules, ${statChanged} changed, ${statUnchanged} unchanged)`
2317
2439
  );
2318
2440
  }
2319
2441
 
@@ -2561,6 +2683,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
2561
2683
  this.assetsInfo.clear();
2562
2684
  this.moduleGraph.removeAllModuleAttributes();
2563
2685
  this.moduleGraph.unfreeze();
2686
+ this.moduleMemCaches2 = undefined;
2564
2687
  }
2565
2688
 
2566
2689
  /**
@@ -2778,6 +2901,8 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
2778
2901
 
2779
2902
  this.assignRuntimeIds();
2780
2903
 
2904
+ this._updateAffectedModulesWithIds();
2905
+
2781
2906
  this.sortItemsWithChunkIds();
2782
2907
 
2783
2908
  if (shouldRecord) {
@@ -3121,18 +3246,14 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
3121
3246
  chunkGraphEntries = this._getChunkGraphEntries()
3122
3247
  } = {}) {
3123
3248
  const context = { chunkGraph, codeGenerationResults };
3124
- const { moduleMemCaches } = this;
3249
+ const { moduleMemCaches2 } = this;
3125
3250
  this.logger.time("runtime requirements.modules");
3126
3251
  const additionalModuleRuntimeRequirements =
3127
3252
  this.hooks.additionalModuleRuntimeRequirements;
3128
3253
  const runtimeRequirementInModule = this.hooks.runtimeRequirementInModule;
3129
3254
  for (const module of modules) {
3130
3255
  if (chunkGraph.getNumberOfModuleChunks(module) > 0) {
3131
- const memCache =
3132
- moduleMemCaches &&
3133
- // modules with async blocks depend on the chunk graph and can't be cached that way
3134
- module.blocks.length === 0 &&
3135
- moduleMemCaches.get(module);
3256
+ const memCache = moduleMemCaches2 && moduleMemCaches2.get(module);
3136
3257
  for (const runtime of chunkGraph.getModuleRuntimes(module)) {
3137
3258
  if (memCache) {
3138
3259
  const cached = memCache.get(
@@ -3589,14 +3710,10 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
3589
3710
  createModuleHashes() {
3590
3711
  let statModulesHashed = 0;
3591
3712
  let statModulesFromCache = 0;
3592
- const { chunkGraph, runtimeTemplate, moduleMemCaches } = this;
3713
+ const { chunkGraph, runtimeTemplate, moduleMemCaches2 } = this;
3593
3714
  const { hashFunction, hashDigest, hashDigestLength } = this.outputOptions;
3594
3715
  for (const module of this.modules) {
3595
- const memCache =
3596
- moduleMemCaches &&
3597
- // modules with async blocks depend on the chunk graph and can't be cached that way
3598
- module.blocks.length === 0 &&
3599
- moduleMemCaches.get(module);
3716
+ const memCache = moduleMemCaches2 && moduleMemCaches2.get(module);
3600
3717
  for (const runtime of chunkGraph.getModuleRuntimes(module)) {
3601
3718
  if (memCache) {
3602
3719
  const digest = memCache.get(`moduleHash-${getRuntimeKey(runtime)}`);
package/lib/Compiler.js CHANGED
@@ -249,7 +249,7 @@ class Compiler {
249
249
 
250
250
  this.cache = new Cache();
251
251
 
252
- /** @type {WeakMap<Module, { hash: string, references: WeakMap<Dependency, Module>, memCache: WeakTupleMap }> | undefined} */
252
+ /** @type {Map<Module, { buildInfo: object, references: WeakMap<Dependency, Module>, memCache: WeakTupleMap }> | undefined} */
253
253
  this.moduleMemCaches = undefined;
254
254
 
255
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.1",
3
+ "version": "5.57.1",
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,10 +1908,10 @@ 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
1913
  {
1913
- hash: string;
1914
+ buildInfo: object;
1914
1915
  references: WeakMap<Dependency, Module>;
1915
1916
  memCache: WeakTupleMap<any, any>;
1916
1917
  }
@@ -3741,6 +3742,10 @@ declare class ExternalModule extends Module {
3741
3742
  request: string | string[] | Record<string, string | string[]>;
3742
3743
  externalType: string;
3743
3744
  userRequest: string;
3745
+ restoreFromUnsafeCache(
3746
+ unsafeCacheData?: any,
3747
+ normalModuleFactory?: any
3748
+ ): void;
3744
3749
  }
3745
3750
  declare interface ExternalModuleInfo {
3746
3751
  index: number;
@@ -6699,7 +6704,10 @@ declare class ModuleGraph {
6699
6704
  getOutgoingConnections(module: Module): Iterable<ModuleGraphConnection>;
6700
6705
  getIncomingConnectionsByOriginModule(
6701
6706
  module: Module
6702
- ): Map<Module, ReadonlyArray<ModuleGraphConnection>>;
6707
+ ): Map<undefined | Module, ReadonlyArray<ModuleGraphConnection>>;
6708
+ getOutgoingConnectionsByModule(
6709
+ module: Module
6710
+ ): undefined | Map<undefined | Module, ReadonlyArray<ModuleGraphConnection>>;
6703
6711
  getProfile(module: Module): null | ModuleProfile;
6704
6712
  setProfile(module: Module, profile: null | ModuleProfile): void;
6705
6713
  getIssuer(module: Module): null | Module;
@@ -6740,7 +6748,7 @@ declare class ModuleGraph {
6740
6748
  ...args: T
6741
6749
  ): V;
6742
6750
  setModuleMemCaches(
6743
- moduleMemCaches: WeakMap<Module, WeakTupleMap<any, any>>
6751
+ moduleMemCaches: Map<Module, WeakTupleMap<any, any>>
6744
6752
  ): void;
6745
6753
  dependencyCacheProvide(dependency: Dependency, ...args: any[]): any;
6746
6754
  static getModuleGraphForModule(