webpack 5.14.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.

Files changed (71) hide show
  1. package/bin/webpack.js +0 -0
  2. package/hot/lazy-compilation-node.js +38 -0
  3. package/hot/lazy-compilation-web.js +74 -0
  4. package/lib/AutomaticPrefetchPlugin.js +14 -7
  5. package/lib/CacheFacade.js +1 -0
  6. package/lib/ChunkGraph.js +132 -19
  7. package/lib/CodeGenerationResults.js +43 -8
  8. package/lib/Compilation.js +253 -149
  9. package/lib/Compiler.js +7 -2
  10. package/lib/ContextModule.js +2 -2
  11. package/lib/Dependency.js +1 -7
  12. package/lib/ExportsInfo.js +23 -5
  13. package/lib/ExternalModuleFactoryPlugin.js +46 -3
  14. package/lib/FileSystemInfo.js +192 -137
  15. package/lib/HotModuleReplacementPlugin.js +76 -29
  16. package/lib/IgnoreErrorModuleFactory.js +39 -0
  17. package/lib/Module.js +2 -3
  18. package/lib/NormalModuleFactory.js +27 -8
  19. package/lib/Template.js +32 -23
  20. package/lib/WebpackIsIncludedPlugin.js +85 -0
  21. package/lib/WebpackOptionsApply.js +27 -5
  22. package/lib/cache/PackFileCacheStrategy.js +5 -1
  23. package/lib/config/defaults.js +18 -18
  24. package/lib/config/normalization.js +44 -9
  25. package/lib/debug/ProfilingPlugin.js +20 -1
  26. package/lib/dependencies/AMDDefineDependency.js +1 -1
  27. package/lib/dependencies/AMDPlugin.js +6 -7
  28. package/lib/dependencies/CommonJsImportsParserPlugin.js +43 -1
  29. package/lib/dependencies/CommonJsPlugin.js +1 -6
  30. package/lib/dependencies/ContextDependencyHelpers.js +3 -2
  31. package/lib/dependencies/ExportsInfoDependency.js +0 -20
  32. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +1 -2
  33. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +0 -29
  34. package/lib/dependencies/HarmonyImportDependency.js +0 -41
  35. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +2 -3
  36. package/lib/dependencies/HarmonyImportSpecifierDependency.js +2 -36
  37. package/lib/dependencies/HarmonyModulesPlugin.js +2 -2
  38. package/lib/dependencies/ImportPlugin.js +1 -6
  39. package/lib/dependencies/JsonExportsDependency.js +0 -1
  40. package/lib/dependencies/ModuleDecoratorDependency.js +0 -1
  41. package/lib/dependencies/NullDependency.js +0 -8
  42. package/lib/dependencies/ProvidedDependency.js +0 -1
  43. package/lib/dependencies/StaticExportsDependency.js +0 -12
  44. package/lib/dependencies/SystemPlugin.js +0 -4
  45. package/lib/dependencies/URLDependency.js +45 -3
  46. package/lib/dependencies/URLPlugin.js +33 -7
  47. package/lib/dependencies/WebpackIsIncludedDependency.js +80 -0
  48. package/lib/hmr/LazyCompilationPlugin.js +348 -0
  49. package/lib/hmr/lazyCompilationBackend.js +86 -0
  50. package/lib/javascript/JavascriptModulesPlugin.js +4 -3
  51. package/lib/javascript/JavascriptParser.js +20 -5
  52. package/lib/library/AssignLibraryPlugin.js +13 -4
  53. package/lib/library/EnableLibraryPlugin.js +12 -0
  54. package/lib/optimize/ConcatenatedModule.js +0 -12
  55. package/lib/optimize/InnerGraph.js +32 -0
  56. package/lib/optimize/SplitChunksPlugin.js +4 -1
  57. package/lib/serialization/ObjectMiddleware.js +7 -5
  58. package/lib/sharing/ProvideSharedModule.js +1 -1
  59. package/lib/sharing/ShareRuntimeModule.js +2 -2
  60. package/lib/stats/DefaultStatsPresetPlugin.js +1 -0
  61. package/lib/util/MapHelpers.js +22 -0
  62. package/lib/util/binarySearchBounds.js +86 -0
  63. package/lib/util/createHash.js +13 -7
  64. package/lib/util/internalSerializables.js +2 -0
  65. package/lib/util/processAsyncTree.js +61 -0
  66. package/lib/util/runtime.js +12 -1
  67. package/package.json +3 -3
  68. package/schemas/WebpackOptions.json +330 -140
  69. package/schemas/plugins/container/ContainerPlugin.json +2 -1
  70. package/schemas/plugins/container/ModuleFederationPlugin.json +2 -1
  71. package/types.d.ts +320 -121
@@ -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
  */
@@ -2683,18 +2740,6 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
2683
2740
  * @returns {void}
2684
2741
  */
2685
2742
  removeReasonsOfDependencyBlock(module, block) {
2686
- const chunkGraph = this.chunkGraph;
2687
- const iteratorDependency = d => {
2688
- if (!d.module) {
2689
- return;
2690
- }
2691
- if (d.module.removeReason(module, d)) {
2692
- for (const chunk of chunkGraph.getModuleChunksIterable(d.module)) {
2693
- this.patchChunksAfterReasonRemoval(d.module, chunk);
2694
- }
2695
- }
2696
- };
2697
-
2698
2743
  if (block.blocks) {
2699
2744
  for (const b of block.blocks) {
2700
2745
  this.removeReasonsOfDependencyBlock(module, b);
@@ -2702,7 +2747,20 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
2702
2747
  }
2703
2748
 
2704
2749
  if (block.dependencies) {
2705
- for (const dep of block.dependencies) iteratorDependency(dep);
2750
+ for (const dep of block.dependencies) {
2751
+ const originalModule = this.moduleGraph.getModule(dep);
2752
+ if (originalModule) {
2753
+ this.moduleGraph.removeConnection(dep);
2754
+
2755
+ if (this.chunkGraph) {
2756
+ for (const chunk of this.chunkGraph.getModuleChunks(
2757
+ originalModule
2758
+ )) {
2759
+ this.patchChunksAfterReasonRemoval(originalModule, chunk);
2760
+ }
2761
+ }
2762
+ }
2763
+ }
2706
2764
  }
2707
2765
  }
2708
2766
 
@@ -2730,11 +2788,15 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
2730
2788
  * @returns {void}
2731
2789
  */
2732
2790
  removeChunkFromDependencies(block, chunk) {
2791
+ /**
2792
+ * @param {Dependency} d dependency to (maybe) patch up
2793
+ */
2733
2794
  const iteratorDependency = d => {
2734
- if (!d.module) {
2795
+ const depModule = this.moduleGraph.getModule(d);
2796
+ if (!depModule) {
2735
2797
  return;
2736
2798
  }
2737
- this.patchChunksAfterReasonRemoval(d.module, chunk);
2799
+ this.patchChunksAfterReasonRemoval(depModule, chunk);
2738
2800
  };
2739
2801
 
2740
2802
  const blocks = block.blocks;
@@ -2813,20 +2875,14 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
2813
2875
  for (const module of this.modules) {
2814
2876
  for (const runtime of chunkGraph.getModuleRuntimes(module)) {
2815
2877
  statModulesHashed++;
2816
- const moduleHash = createHash(hashFunction);
2817
- module.updateHash(moduleHash, {
2818
- chunkGraph,
2819
- runtime,
2820
- runtimeTemplate
2821
- });
2822
- const moduleHashDigest = /** @type {string} */ (moduleHash.digest(
2823
- hashDigest
2824
- ));
2825
- chunkGraph.setModuleHashes(
2878
+ this._createModuleHash(
2826
2879
  module,
2880
+ chunkGraph,
2827
2881
  runtime,
2828
- moduleHashDigest,
2829
- moduleHashDigest.substr(0, hashDigestLength)
2882
+ hashFunction,
2883
+ runtimeTemplate,
2884
+ hashDigest,
2885
+ hashDigestLength
2830
2886
  );
2831
2887
  }
2832
2888
  }
@@ -2837,6 +2893,33 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
2837
2893
  );
2838
2894
  }
2839
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
+
2840
2923
  createHash() {
2841
2924
  this.logger.time("hashing: initialize hash");
2842
2925
  const chunkGraph = this.chunkGraph;
@@ -2917,31 +3000,49 @@ This prevents using hashes of each other and should be avoided.`
2917
3000
  });
2918
3001
  this.logger.timeEnd("hashing: sort chunks");
2919
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();
2920
3007
  const processChunk = chunk => {
2921
3008
  // Last minute module hash generation for modules that depend on chunk hashes
2922
3009
  this.logger.time("hashing: hash runtime modules");
3010
+ const runtime = chunk.runtime;
2923
3011
  for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
2924
- if (!chunkGraph.hasModuleHashes(module, chunk.runtime)) {
2925
- const moduleHash = createHash(hashFunction);
2926
- module.updateHash(moduleHash, {
2927
- chunkGraph,
2928
- runtime: chunk.runtime,
2929
- runtimeTemplate
2930
- });
2931
- const moduleHashDigest = /** @type {string} */ (moduleHash.digest(
2932
- hashDigest
2933
- ));
2934
- chunkGraph.setModuleHashes(
3012
+ if (!chunkGraph.hasModuleHashes(module, runtime)) {
3013
+ const hash = this._createModuleHash(
2935
3014
  module,
2936
- chunk.runtime,
2937
- moduleHashDigest,
2938
- moduleHashDigest.substr(0, hashDigestLength)
3015
+ chunkGraph,
3016
+ runtime,
3017
+ hashFunction,
3018
+ runtimeTemplate,
3019
+ hashDigest,
3020
+ hashDigestLength
2939
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);
2940
3041
  }
2941
3042
  }
2942
3043
  this.logger.timeAggregate("hashing: hash runtime modules");
2943
- const chunkHash = createHash(hashFunction);
2944
3044
  this.logger.time("hashing: hash chunks");
3045
+ const chunkHash = createHash(hashFunction);
2945
3046
  try {
2946
3047
  if (outputOptions.hashSalt) {
2947
3048
  chunkHash.update(outputOptions.hashSalt);
@@ -2994,12 +3095,14 @@ This prevents using hashes of each other and should be avoided.`
2994
3095
  const moduleHashDigest = /** @type {string} */ (moduleHash.digest(
2995
3096
  hashDigest
2996
3097
  ));
3098
+ const oldHash = chunkGraph.getModuleHash(module, chunk.runtime);
2997
3099
  chunkGraph.setModuleHashes(
2998
3100
  module,
2999
3101
  chunk.runtime,
3000
3102
  moduleHashDigest,
3001
3103
  moduleHashDigest.substr(0, hashDigestLength)
3002
3104
  );
3105
+ codeGenerationJobsMap.get(oldHash).get(module).hash = moduleHashDigest;
3003
3106
  }
3004
3107
  const chunkHash = createHash(hashFunction);
3005
3108
  chunkHash.update(chunk.hash);
@@ -3012,6 +3115,7 @@ This prevents using hashes of each other and should be avoided.`
3012
3115
  this.hooks.contentHash.call(chunk);
3013
3116
  }
3014
3117
  this.logger.timeEnd("hashing: process full hash modules");
3118
+ return codeGenerationJobs;
3015
3119
  }
3016
3120
 
3017
3121
  /**
package/lib/Compiler.js CHANGED
@@ -168,6 +168,8 @@ class Compiler {
168
168
  invalid: new SyncHook(["filename", "changeTime"]),
169
169
  /** @type {SyncHook<[]>} */
170
170
  watchClose: new SyncHook([]),
171
+ /** @type {AsyncSeriesHook<[]>} */
172
+ shutdown: new AsyncSeriesHook([]),
171
173
 
172
174
  /** @type {SyncBailHook<[string, string, any[]], true>} */
173
175
  infrastructureLog: new SyncBailHook(["origin", "type", "args"]),
@@ -997,7 +999,7 @@ ${other}`);
997
999
  context: this.options.context,
998
1000
  fs: this.inputFileSystem,
999
1001
  resolverFactory: this.resolverFactory,
1000
- options: this.options.module || {},
1002
+ options: this.options.module,
1001
1003
  associatedObjectForCache: this.root,
1002
1004
  layers: this.options.experiments.layers
1003
1005
  });
@@ -1075,7 +1077,10 @@ ${other}`);
1075
1077
  * @returns {void}
1076
1078
  */
1077
1079
  close(callback) {
1078
- this.cache.shutdown(callback);
1080
+ this.hooks.shutdown.callAsync(err => {
1081
+ if (err) return callback(err);
1082
+ this.cache.shutdown(callback);
1083
+ });
1079
1084
  }
1080
1085
  }
1081
1086
 
@@ -16,9 +16,9 @@ const {
16
16
  compareLocations,
17
17
  concatComparators,
18
18
  compareSelect,
19
- keepOriginalOrder
19
+ keepOriginalOrder,
20
+ compareModulesById
20
21
  } = require("./util/comparators");
21
- const { compareModulesById } = require("./util/comparators");
22
22
  const { contextify, parseResource } = require("./util/identifier");
23
23
  const makeSerializable = require("./util/makeSerializable");
24
24
 
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
@@ -457,7 +457,6 @@ class ExportsInfo {
457
457
  case UsageState.NoInfo:
458
458
  return null;
459
459
  case UsageState.Unknown:
460
- return true;
461
460
  case UsageState.OnlyPropertiesUsed:
462
461
  case UsageState.Used:
463
462
  return true;
@@ -685,15 +684,27 @@ class ExportsInfo {
685
684
  * @returns {void}
686
685
  */
687
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);
688
699
  for (const exportInfo of this.orderedExports) {
689
700
  if (exportInfo.hasInfo(this._otherExportsInfo, runtime)) {
690
- exportInfo.updateHash(hash, runtime);
701
+ exportInfo._updateHash(hash, runtime, set);
691
702
  }
692
703
  }
693
- this._sideEffectsOnlyInfo.updateHash(hash, runtime);
694
- this._otherExportsInfo.updateHash(hash, runtime);
704
+ this._sideEffectsOnlyInfo._updateHash(hash, runtime, set);
705
+ this._otherExportsInfo._updateHash(hash, runtime, set);
695
706
  if (this._redirectTo !== undefined) {
696
- this._redirectTo.updateHash(hash, runtime);
707
+ this._redirectTo._updateHash(hash, runtime, set);
697
708
  }
698
709
  }
699
710
 
@@ -1339,10 +1350,17 @@ class ExportInfo {
1339
1350
  }
1340
1351
 
1341
1352
  updateHash(hash, runtime) {
1353
+ this._updateHash(hash, runtime, new Set());
1354
+ }
1355
+
1356
+ _updateHash(hash, runtime, alreadyVisitedExportsInfo) {
1342
1357
  hash.update(`${this._usedName || this.name}`);
1343
1358
  hash.update(`${this.getUsed(runtime)}`);
1344
1359
  hash.update(`${this.provided}`);
1345
1360
  hash.update(`${this.terminalBinding}`);
1361
+ if (this.exportsInfo && !alreadyVisitedExportsInfo.has(this.exportsInfo)) {
1362
+ this.exportsInfo._updateHash(hash, runtime, alreadyVisitedExportsInfo);
1363
+ }
1346
1364
  }
1347
1365
 
1348
1366
  getUsedInfo() {