webpack 5.17.0 → 5.18.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.

@@ -2173,77 +2173,83 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
2173
2173
 
2174
2174
  this.logger.time("hashing");
2175
2175
  this.hooks.beforeHash.call();
2176
- this.createHash();
2176
+ const codeGenerationJobs = this.createHash();
2177
2177
  this.hooks.afterHash.call();
2178
2178
  this.logger.timeEnd("hashing");
2179
2179
 
2180
- if (shouldRecord) {
2181
- this.logger.time("record hash");
2182
- this.hooks.recordHash.call(this.records);
2183
- this.logger.timeEnd("record hash");
2184
- }
2185
-
2186
- this.logger.time("module assets");
2187
- this.clearAssets();
2180
+ this._runCodeGenerationJobs(codeGenerationJobs, err => {
2181
+ if (err) {
2182
+ return callback(err);
2183
+ }
2188
2184
 
2189
- this.hooks.beforeModuleAssets.call();
2190
- this.createModuleAssets();
2191
- this.logger.timeEnd("module assets");
2185
+ if (shouldRecord) {
2186
+ this.logger.time("record hash");
2187
+ this.hooks.recordHash.call(this.records);
2188
+ this.logger.timeEnd("record hash");
2189
+ }
2192
2190
 
2193
- const cont = () => {
2194
- this.logger.time("process assets");
2195
- this.hooks.processAssets.callAsync(this.assets, err => {
2196
- if (err) {
2197
- return callback(
2198
- makeWebpackError(err, "Compilation.hooks.processAssets")
2199
- );
2200
- }
2201
- this.hooks.afterProcessAssets.call(this.assets);
2202
- this.logger.timeEnd("process assets");
2203
- this.assets = soonFrozenObjectDeprecation(
2204
- this.assets,
2205
- "Compilation.assets",
2206
- "DEP_WEBPACK_COMPILATION_ASSETS",
2207
- `BREAKING CHANGE: No more changes should happen to Compilation.assets after sealing the Compilation.
2208
- Do changes to assets earlier, e. g. in Compilation.hooks.processAssets.
2209
- Make sure to select an appropriate stage from Compilation.PROCESS_ASSETS_STAGE_*.`
2210
- );
2191
+ this.logger.time("module assets");
2192
+ this.clearAssets();
2211
2193
 
2212
- this.summarizeDependencies();
2213
- if (shouldRecord) {
2214
- this.hooks.record.call(this, this.records);
2215
- }
2194
+ this.hooks.beforeModuleAssets.call();
2195
+ this.createModuleAssets();
2196
+ this.logger.timeEnd("module assets");
2216
2197
 
2217
- if (this.hooks.needAdditionalSeal.call()) {
2218
- this.unseal();
2219
- return this.seal(callback);
2220
- }
2221
- return this.hooks.afterSeal.callAsync(err => {
2198
+ const cont = () => {
2199
+ this.logger.time("process assets");
2200
+ this.hooks.processAssets.callAsync(this.assets, err => {
2222
2201
  if (err) {
2223
2202
  return callback(
2224
- makeWebpackError(err, "Compilation.hooks.afterSeal")
2203
+ makeWebpackError(err, "Compilation.hooks.processAssets")
2225
2204
  );
2226
2205
  }
2227
- this.fileSystemInfo.logStatistics();
2228
- callback();
2206
+ this.hooks.afterProcessAssets.call(this.assets);
2207
+ this.logger.timeEnd("process assets");
2208
+ this.assets = soonFrozenObjectDeprecation(
2209
+ this.assets,
2210
+ "Compilation.assets",
2211
+ "DEP_WEBPACK_COMPILATION_ASSETS",
2212
+ `BREAKING CHANGE: No more changes should happen to Compilation.assets after sealing the Compilation.
2213
+ Do changes to assets earlier, e. g. in Compilation.hooks.processAssets.
2214
+ Make sure to select an appropriate stage from Compilation.PROCESS_ASSETS_STAGE_*.`
2215
+ );
2216
+
2217
+ this.summarizeDependencies();
2218
+ if (shouldRecord) {
2219
+ this.hooks.record.call(this, this.records);
2220
+ }
2221
+
2222
+ if (this.hooks.needAdditionalSeal.call()) {
2223
+ this.unseal();
2224
+ return this.seal(callback);
2225
+ }
2226
+ return this.hooks.afterSeal.callAsync(err => {
2227
+ if (err) {
2228
+ return callback(
2229
+ makeWebpackError(err, "Compilation.hooks.afterSeal")
2230
+ );
2231
+ }
2232
+ this.fileSystemInfo.logStatistics();
2233
+ callback();
2234
+ });
2229
2235
  });
2230
- });
2231
- };
2236
+ };
2232
2237
 
2233
- this.logger.time("create chunk assets");
2234
- if (this.hooks.shouldGenerateChunkAssets.call() !== false) {
2235
- this.hooks.beforeChunkAssets.call();
2236
- this.createChunkAssets(err => {
2238
+ this.logger.time("create chunk assets");
2239
+ if (this.hooks.shouldGenerateChunkAssets.call() !== false) {
2240
+ this.hooks.beforeChunkAssets.call();
2241
+ this.createChunkAssets(err => {
2242
+ this.logger.timeEnd("create chunk assets");
2243
+ if (err) {
2244
+ return callback(err);
2245
+ }
2246
+ cont();
2247
+ });
2248
+ } else {
2237
2249
  this.logger.timeEnd("create chunk assets");
2238
- if (err) {
2239
- return callback(err);
2240
- }
2241
2250
  cont();
2242
- });
2243
- } else {
2244
- this.logger.timeEnd("create chunk assets");
2245
- cont();
2246
- }
2251
+ }
2252
+ });
2247
2253
  });
2248
2254
  }
2249
2255
  );
@@ -2288,16 +2294,8 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
2288
2294
  }
2289
2295
 
2290
2296
  codeGeneration(callback) {
2291
- let statModulesFromCache = 0;
2292
- let statModulesGenerated = 0;
2293
- const {
2294
- chunkGraph,
2295
- moduleGraph,
2296
- dependencyTemplates,
2297
- runtimeTemplate
2298
- } = this;
2299
- const results = (this.codeGenerationResults = new CodeGenerationResults());
2300
- const errors = [];
2297
+ const { chunkGraph } = this;
2298
+ this.codeGenerationResults = new CodeGenerationResults();
2301
2299
  /** @type {{module: Module, hash: string, runtime: RuntimeSpec, runtimes: RuntimeSpec[]}[]} */
2302
2300
  const jobs = [];
2303
2301
  for (const module of this.modules) {
@@ -2324,52 +2322,41 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
2324
2322
  }
2325
2323
  }
2326
2324
 
2325
+ this._runCodeGenerationJobs(jobs, callback);
2326
+ }
2327
+
2328
+ _runCodeGenerationJobs(jobs, callback) {
2329
+ let statModulesFromCache = 0;
2330
+ let statModulesGenerated = 0;
2331
+ const {
2332
+ chunkGraph,
2333
+ moduleGraph,
2334
+ dependencyTemplates,
2335
+ runtimeTemplate
2336
+ } = this;
2337
+ const results = this.codeGenerationResults;
2338
+ const errors = [];
2327
2339
  asyncLib.eachLimit(
2328
2340
  jobs,
2329
2341
  this.options.parallelism,
2330
2342
  ({ module, hash, runtime, runtimes }, callback) => {
2331
- const cache = new MultiItemCache(
2332
- runtimes.map(runtime =>
2333
- this._codeGenerationCache.getItemCache(
2334
- `${module.identifier()}|${getRuntimeKey(runtime)}`,
2335
- `${hash}|${dependencyTemplates.getHash()}`
2336
- )
2337
- )
2338
- );
2339
- cache.get((err, cachedResult) => {
2340
- if (err) return callback(err);
2341
- let result;
2342
- if (!cachedResult) {
2343
- statModulesGenerated++;
2344
- try {
2345
- this.codeGeneratedModules.add(module);
2346
- result = module.codeGeneration({
2347
- chunkGraph,
2348
- moduleGraph,
2349
- dependencyTemplates,
2350
- runtimeTemplate,
2351
- runtime
2352
- });
2353
- } catch (err) {
2354
- errors.push(new CodeGenerationError(module, err));
2355
- result = cachedResult = {
2356
- sources: new Map(),
2357
- runtimeRequirements: null
2358
- };
2359
- }
2360
- } else {
2361
- statModulesFromCache++;
2362
- result = cachedResult;
2363
- }
2364
- for (const runtime of runtimes) {
2365
- results.add(module, runtime, result);
2366
- }
2367
- if (!cachedResult) {
2368
- cache.store(result, callback);
2369
- } else {
2370
- callback();
2343
+ this._codeGenerationModule(
2344
+ module,
2345
+ runtime,
2346
+ runtimes,
2347
+ hash,
2348
+ dependencyTemplates,
2349
+ chunkGraph,
2350
+ moduleGraph,
2351
+ runtimeTemplate,
2352
+ errors,
2353
+ results,
2354
+ (err, codeGenerated) => {
2355
+ if (codeGenerated) statModulesGenerated++;
2356
+ else statModulesFromCache++;
2357
+ callback(err);
2371
2358
  }
2372
- });
2359
+ );
2373
2360
  },
2374
2361
  err => {
2375
2362
  if (err) return callback(err);
@@ -2392,6 +2379,76 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
2392
2379
  );
2393
2380
  }
2394
2381
 
2382
+ /**
2383
+ * @param {Module} module module
2384
+ * @param {RuntimeSpec} runtime runtime
2385
+ * @param {RuntimeSpec[]} runtimes runtimes
2386
+ * @param {string} hash hash
2387
+ * @param {DependencyTemplates} dependencyTemplates dependencyTemplates
2388
+ * @param {ChunkGraph} chunkGraph chunkGraph
2389
+ * @param {ModuleGraph} moduleGraph moduleGraph
2390
+ * @param {RuntimeTemplate} runtimeTemplate runtimeTemplate
2391
+ * @param {WebpackError[]} errors errors
2392
+ * @param {CodeGenerationResults} results results
2393
+ * @param {function(WebpackError=, boolean=): void} callback callback
2394
+ */
2395
+ _codeGenerationModule(
2396
+ module,
2397
+ runtime,
2398
+ runtimes,
2399
+ hash,
2400
+ dependencyTemplates,
2401
+ chunkGraph,
2402
+ moduleGraph,
2403
+ runtimeTemplate,
2404
+ errors,
2405
+ results,
2406
+ callback
2407
+ ) {
2408
+ let codeGenerated = false;
2409
+ const cache = new MultiItemCache(
2410
+ runtimes.map(runtime =>
2411
+ this._codeGenerationCache.getItemCache(
2412
+ `${module.identifier()}|${getRuntimeKey(runtime)}`,
2413
+ `${hash}|${dependencyTemplates.getHash()}`
2414
+ )
2415
+ )
2416
+ );
2417
+ cache.get((err, cachedResult) => {
2418
+ if (err) return callback(err);
2419
+ let result;
2420
+ if (!cachedResult) {
2421
+ try {
2422
+ codeGenerated = true;
2423
+ this.codeGeneratedModules.add(module);
2424
+ result = module.codeGeneration({
2425
+ chunkGraph,
2426
+ moduleGraph,
2427
+ dependencyTemplates,
2428
+ runtimeTemplate,
2429
+ runtime
2430
+ });
2431
+ } catch (err) {
2432
+ errors.push(new CodeGenerationError(module, err));
2433
+ result = cachedResult = {
2434
+ sources: new Map(),
2435
+ runtimeRequirements: null
2436
+ };
2437
+ }
2438
+ } else {
2439
+ result = cachedResult;
2440
+ }
2441
+ for (const runtime of runtimes) {
2442
+ results.add(module, runtime, result);
2443
+ }
2444
+ if (!cachedResult) {
2445
+ cache.store(result, err => callback(err, codeGenerated));
2446
+ } else {
2447
+ callback(null, codeGenerated);
2448
+ }
2449
+ });
2450
+ }
2451
+
2395
2452
  /**
2396
2453
  * @returns {void}
2397
2454
  */
@@ -2818,20 +2875,14 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
2818
2875
  for (const module of this.modules) {
2819
2876
  for (const runtime of chunkGraph.getModuleRuntimes(module)) {
2820
2877
  statModulesHashed++;
2821
- const moduleHash = createHash(hashFunction);
2822
- module.updateHash(moduleHash, {
2823
- chunkGraph,
2824
- runtime,
2825
- runtimeTemplate
2826
- });
2827
- const moduleHashDigest = /** @type {string} */ (moduleHash.digest(
2828
- hashDigest
2829
- ));
2830
- chunkGraph.setModuleHashes(
2878
+ this._createModuleHash(
2831
2879
  module,
2880
+ chunkGraph,
2832
2881
  runtime,
2833
- moduleHashDigest,
2834
- moduleHashDigest.substr(0, hashDigestLength)
2882
+ hashFunction,
2883
+ runtimeTemplate,
2884
+ hashDigest,
2885
+ hashDigestLength
2835
2886
  );
2836
2887
  }
2837
2888
  }
@@ -2842,6 +2893,33 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
2842
2893
  );
2843
2894
  }
2844
2895
 
2896
+ _createModuleHash(
2897
+ module,
2898
+ chunkGraph,
2899
+ runtime,
2900
+ hashFunction,
2901
+ runtimeTemplate,
2902
+ hashDigest,
2903
+ hashDigestLength
2904
+ ) {
2905
+ const moduleHash = createHash(hashFunction);
2906
+ module.updateHash(moduleHash, {
2907
+ chunkGraph,
2908
+ runtime,
2909
+ runtimeTemplate
2910
+ });
2911
+ const moduleHashDigest = /** @type {string} */ (moduleHash.digest(
2912
+ hashDigest
2913
+ ));
2914
+ chunkGraph.setModuleHashes(
2915
+ module,
2916
+ runtime,
2917
+ moduleHashDigest,
2918
+ moduleHashDigest.substr(0, hashDigestLength)
2919
+ );
2920
+ return moduleHashDigest;
2921
+ }
2922
+
2845
2923
  createHash() {
2846
2924
  this.logger.time("hashing: initialize hash");
2847
2925
  const chunkGraph = this.chunkGraph;
@@ -2922,31 +3000,49 @@ This prevents using hashes of each other and should be avoided.`
2922
3000
  });
2923
3001
  this.logger.timeEnd("hashing: sort chunks");
2924
3002
  const fullHashChunks = new Set();
3003
+ /** @type {{module: Module, hash: string, runtime: RuntimeSpec, runtimes: RuntimeSpec[]}[]} */
3004
+ const codeGenerationJobs = [];
3005
+ /** @type {Map<string, Map<Module, {module: Module, hash: string, runtime: RuntimeSpec, runtimes: RuntimeSpec[]}>>} */
3006
+ const codeGenerationJobsMap = new Map();
2925
3007
  const processChunk = chunk => {
2926
3008
  // Last minute module hash generation for modules that depend on chunk hashes
2927
3009
  this.logger.time("hashing: hash runtime modules");
3010
+ const runtime = chunk.runtime;
2928
3011
  for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
2929
- if (!chunkGraph.hasModuleHashes(module, chunk.runtime)) {
2930
- const moduleHash = createHash(hashFunction);
2931
- module.updateHash(moduleHash, {
2932
- chunkGraph,
2933
- runtime: chunk.runtime,
2934
- runtimeTemplate
2935
- });
2936
- const moduleHashDigest = /** @type {string} */ (moduleHash.digest(
2937
- hashDigest
2938
- ));
2939
- chunkGraph.setModuleHashes(
3012
+ if (!chunkGraph.hasModuleHashes(module, runtime)) {
3013
+ const hash = this._createModuleHash(
2940
3014
  module,
2941
- chunk.runtime,
2942
- moduleHashDigest,
2943
- moduleHashDigest.substr(0, hashDigestLength)
3015
+ chunkGraph,
3016
+ runtime,
3017
+ hashFunction,
3018
+ runtimeTemplate,
3019
+ hashDigest,
3020
+ hashDigestLength
2944
3021
  );
3022
+ let hashMap = codeGenerationJobsMap.get(hash);
3023
+ if (hashMap) {
3024
+ const moduleJob = hashMap.get(module);
3025
+ if (moduleJob) {
3026
+ moduleJob.runtimes.push(runtime);
3027
+ continue;
3028
+ }
3029
+ } else {
3030
+ hashMap = new Map();
3031
+ codeGenerationJobsMap.set(hash, hashMap);
3032
+ }
3033
+ const job = {
3034
+ module,
3035
+ hash,
3036
+ runtime,
3037
+ runtimes: [runtime]
3038
+ };
3039
+ hashMap.set(module, job);
3040
+ codeGenerationJobs.push(job);
2945
3041
  }
2946
3042
  }
2947
3043
  this.logger.timeAggregate("hashing: hash runtime modules");
2948
- const chunkHash = createHash(hashFunction);
2949
3044
  this.logger.time("hashing: hash chunks");
3045
+ const chunkHash = createHash(hashFunction);
2950
3046
  try {
2951
3047
  if (outputOptions.hashSalt) {
2952
3048
  chunkHash.update(outputOptions.hashSalt);
@@ -2999,12 +3095,14 @@ This prevents using hashes of each other and should be avoided.`
2999
3095
  const moduleHashDigest = /** @type {string} */ (moduleHash.digest(
3000
3096
  hashDigest
3001
3097
  ));
3098
+ const oldHash = chunkGraph.getModuleHash(module, chunk.runtime);
3002
3099
  chunkGraph.setModuleHashes(
3003
3100
  module,
3004
3101
  chunk.runtime,
3005
3102
  moduleHashDigest,
3006
3103
  moduleHashDigest.substr(0, hashDigestLength)
3007
3104
  );
3105
+ codeGenerationJobsMap.get(oldHash).get(module).hash = moduleHashDigest;
3008
3106
  }
3009
3107
  const chunkHash = createHash(hashFunction);
3010
3108
  chunkHash.update(chunk.hash);
@@ -3017,6 +3115,7 @@ This prevents using hashes of each other and should be avoided.`
3017
3115
  this.hooks.contentHash.call(chunk);
3018
3116
  }
3019
3117
  this.logger.timeEnd("hashing: process full hash modules");
3118
+ return codeGenerationJobs;
3020
3119
  }
3021
3120
 
3022
3121
  /**
package/lib/Dependency.js CHANGED
@@ -167,13 +167,7 @@ class Dependency {
167
167
  * @param {UpdateHashContext} context context
168
168
  * @returns {void}
169
169
  */
170
- updateHash(hash, context) {
171
- const { chunkGraph } = context;
172
- const module = chunkGraph.moduleGraph.getModule(this);
173
- if (module) {
174
- hash.update(chunkGraph.getModuleId(module) + "");
175
- }
176
- }
170
+ updateHash(hash, context) {}
177
171
 
178
172
  /**
179
173
  * implement this method to allow the occurrence order plugin to count correctly
@@ -684,15 +684,27 @@ class ExportsInfo {
684
684
  * @returns {void}
685
685
  */
686
686
  updateHash(hash, runtime) {
687
+ this._updateHash(hash, runtime, new Set());
688
+ }
689
+
690
+ /**
691
+ * @param {Hash} hash the hash
692
+ * @param {RuntimeSpec} runtime the runtime
693
+ * @param {Set<ExportsInfo>} alreadyVisitedExportsInfo for circular references
694
+ * @returns {void}
695
+ */
696
+ _updateHash(hash, runtime, alreadyVisitedExportsInfo) {
697
+ const set = new Set(alreadyVisitedExportsInfo);
698
+ set.add(this);
687
699
  for (const exportInfo of this.orderedExports) {
688
700
  if (exportInfo.hasInfo(this._otherExportsInfo, runtime)) {
689
- exportInfo.updateHash(hash, runtime);
701
+ exportInfo._updateHash(hash, runtime, set);
690
702
  }
691
703
  }
692
- this._sideEffectsOnlyInfo.updateHash(hash, runtime);
693
- this._otherExportsInfo.updateHash(hash, runtime);
704
+ this._sideEffectsOnlyInfo._updateHash(hash, runtime, set);
705
+ this._otherExportsInfo._updateHash(hash, runtime, set);
694
706
  if (this._redirectTo !== undefined) {
695
- this._redirectTo.updateHash(hash, runtime);
707
+ this._redirectTo._updateHash(hash, runtime, set);
696
708
  }
697
709
  }
698
710
 
@@ -1338,10 +1350,17 @@ class ExportInfo {
1338
1350
  }
1339
1351
 
1340
1352
  updateHash(hash, runtime) {
1353
+ this._updateHash(hash, runtime, new Set());
1354
+ }
1355
+
1356
+ _updateHash(hash, runtime, alreadyVisitedExportsInfo) {
1341
1357
  hash.update(`${this._usedName || this.name}`);
1342
1358
  hash.update(`${this.getUsed(runtime)}`);
1343
1359
  hash.update(`${this.provided}`);
1344
1360
  hash.update(`${this.terminalBinding}`);
1361
+ if (this.exportsInfo && !alreadyVisitedExportsInfo.has(this.exportsInfo)) {
1362
+ this.exportsInfo._updateHash(hash, runtime, alreadyVisitedExportsInfo);
1363
+ }
1345
1364
  }
1346
1365
 
1347
1366
  getUsedInfo() {
@@ -39,6 +39,7 @@ const {
39
39
  /** @typedef {import("./Compiler")} Compiler */
40
40
  /** @typedef {import("./Module")} Module */
41
41
  /** @typedef {import("./RuntimeModule")} RuntimeModule */
42
+ /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
42
43
 
43
44
  /**
44
45
  * @typedef {Object} HMRJavascriptParserHooks
@@ -316,37 +317,61 @@ class HotModuleReplacementPlugin {
316
317
  /** @type {TupleSet<[Module, Chunk]>} */
317
318
  const updatedModules = new TupleSet();
318
319
  /** @type {TupleSet<[Module, Chunk]>} */
319
- const lazyHashedModules = new TupleSet();
320
+ const fullHashModules = new TupleSet();
321
+ /** @type {TupleSet<[Module, RuntimeSpec]>} */
322
+ const nonCodeGeneratedModules = new TupleSet();
320
323
  compilation.hooks.fullHash.tap("HotModuleReplacementPlugin", hash => {
321
324
  const chunkGraph = compilation.chunkGraph;
322
325
  const records = compilation.records;
323
326
  for (const chunk of compilation.chunks) {
324
- /** @type {Set<Module>} */
325
- const lazyHashedModulesInThisChunk = new Set();
326
- const fullHashModules = chunkGraph.getChunkFullHashModulesIterable(
327
+ const getModuleHash = module => {
328
+ if (
329
+ compilation.codeGenerationResults.has(module, chunk.runtime)
330
+ ) {
331
+ return compilation.codeGenerationResults.getHash(
332
+ module,
333
+ chunk.runtime
334
+ );
335
+ } else {
336
+ nonCodeGeneratedModules.add(module, chunk.runtime);
337
+ return chunkGraph.getModuleHash(module, chunk.runtime);
338
+ }
339
+ };
340
+ const fullHashModulesInThisChunk = chunkGraph.getChunkFullHashModulesSet(
327
341
  chunk
328
342
  );
329
- if (fullHashModules !== undefined) {
330
- for (const module of fullHashModules) {
331
- lazyHashedModules.add(module, chunk);
332
- lazyHashedModulesInThisChunk.add(module);
343
+ if (fullHashModulesInThisChunk !== undefined) {
344
+ for (const module of fullHashModulesInThisChunk) {
345
+ fullHashModules.add(module, chunk);
333
346
  }
334
347
  }
335
348
  const modules = chunkGraph.getChunkModulesIterable(chunk);
336
349
  if (modules !== undefined) {
337
- if (
338
- records.chunkModuleHashes &&
339
- records.fullHashChunkModuleHashes
340
- ) {
341
- for (const module of modules) {
342
- const key = `${chunk.id}|${module.identifier()}`;
343
- const hash = chunkGraph.getModuleHash(module, chunk.runtime);
344
- if (lazyHashedModulesInThisChunk.has(module)) {
345
- if (records.fullHashChunkModuleHashes[key] !== hash) {
346
- updatedModules.add(module, chunk);
350
+ if (records.chunkModuleHashes) {
351
+ if (fullHashModulesInThisChunk !== undefined) {
352
+ for (const module of modules) {
353
+ const key = `${chunk.id}|${module.identifier()}`;
354
+ const hash = getModuleHash(module);
355
+ if (
356
+ fullHashModulesInThisChunk.has(
357
+ /** @type {RuntimeModule} */ (module)
358
+ )
359
+ ) {
360
+ if (records.fullHashChunkModuleHashes[key] !== hash) {
361
+ updatedModules.add(module, chunk);
362
+ }
363
+ fullHashChunkModuleHashes[key] = hash;
364
+ } else {
365
+ if (records.chunkModuleHashes[key] !== hash) {
366
+ updatedModules.add(module, chunk);
367
+ }
368
+ chunkModuleHashes[key] = hash;
347
369
  }
348
- fullHashChunkModuleHashes[key] = hash;
349
- } else {
370
+ }
371
+ } else {
372
+ for (const module of modules) {
373
+ const key = `${chunk.id}|${module.identifier()}`;
374
+ const hash = getModuleHash(module);
350
375
  if (records.chunkModuleHashes[key] !== hash) {
351
376
  updatedModules.add(module, chunk);
352
377
  }
@@ -354,12 +379,24 @@ class HotModuleReplacementPlugin {
354
379
  }
355
380
  }
356
381
  } else {
357
- for (const module of modules) {
358
- const key = `${chunk.id}|${module.identifier()}`;
359
- const hash = chunkGraph.getModuleHash(module, chunk.runtime);
360
- if (lazyHashedModulesInThisChunk.has(module)) {
361
- fullHashChunkModuleHashes[key] = hash;
362
- } else {
382
+ if (fullHashModulesInThisChunk !== undefined) {
383
+ for (const module of modules) {
384
+ const key = `${chunk.id}|${module.identifier()}`;
385
+ const hash = getModuleHash(module);
386
+ if (
387
+ fullHashModulesInThisChunk.has(
388
+ /** @type {RuntimeModule} */ (module)
389
+ )
390
+ ) {
391
+ fullHashChunkModuleHashes[key] = hash;
392
+ } else {
393
+ chunkModuleHashes[key] = hash;
394
+ }
395
+ }
396
+ } else {
397
+ for (const module of modules) {
398
+ const key = `${chunk.id}|${module.identifier()}`;
399
+ const hash = getModuleHash(module);
363
400
  chunkModuleHashes[key] = hash;
364
401
  }
365
402
  }
@@ -388,9 +425,14 @@ class HotModuleReplacementPlugin {
388
425
  ) {
389
426
  return;
390
427
  }
391
- for (const [module, chunk] of lazyHashedModules) {
428
+ for (const [module, chunk] of fullHashModules) {
392
429
  const key = `${chunk.id}|${module.identifier()}`;
393
- const hash = chunkGraph.getModuleHash(module, chunk.runtime);
430
+ const hash = nonCodeGeneratedModules.has(module, chunk.runtime)
431
+ ? chunkGraph.getModuleHash(module, chunk.runtime)
432
+ : compilation.codeGenerationResults.getHash(
433
+ module,
434
+ chunk.runtime
435
+ );
394
436
  if (records.chunkModuleHashes[key] !== hash) {
395
437
  updatedModules.add(module, chunk);
396
438
  }
@@ -500,7 +542,12 @@ class HotModuleReplacementPlugin {
500
542
  const runtimes = chunkGraph.getModuleRuntimes(module);
501
543
  if (oldRuntime === newRuntime && runtimes.has(newRuntime)) {
502
544
  // Module is still in the same runtime combination
503
- const hash = chunkGraph.getModuleHash(module, newRuntime);
545
+ const hash = nonCodeGeneratedModules.has(module, newRuntime)
546
+ ? chunkGraph.getModuleHash(module, newRuntime)
547
+ : compilation.codeGenerationResults.getHash(
548
+ module,
549
+ newRuntime
550
+ );
504
551
  if (hash !== oldHash) {
505
552
  if (module.type === "runtime") {
506
553
  newRuntimeModules = newRuntimeModules || [];