webpack 5.69.1 → 5.72.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 (84) hide show
  1. package/hot/poll.js +1 -1
  2. package/hot/signal.js +1 -1
  3. package/lib/BannerPlugin.js +12 -4
  4. package/lib/Chunk.js +1 -1
  5. package/lib/ChunkGraph.js +93 -6
  6. package/lib/ChunkGroup.js +1 -1
  7. package/lib/CleanPlugin.js +64 -18
  8. package/lib/Compilation.js +51 -25
  9. package/lib/Compiler.js +16 -3
  10. package/lib/ConstPlugin.js +2 -2
  11. package/lib/ContextModule.js +121 -34
  12. package/lib/ContextModuleFactory.js +65 -25
  13. package/lib/DelegatedModuleFactoryPlugin.js +1 -1
  14. package/lib/Dependency.js +7 -0
  15. package/lib/EntryOptionPlugin.js +1 -0
  16. package/lib/ErrorHelpers.js +2 -2
  17. package/lib/ExportsInfo.js +1 -1
  18. package/lib/ExternalModuleFactoryPlugin.js +4 -4
  19. package/lib/FileSystemInfo.js +8 -0
  20. package/lib/Generator.js +1 -0
  21. package/lib/LoaderOptionsPlugin.js +1 -1
  22. package/lib/Module.js +3 -0
  23. package/lib/ModuleFilenameHelpers.js +3 -3
  24. package/lib/ModuleHashingError.js +29 -0
  25. package/lib/NodeStuffPlugin.js +10 -0
  26. package/lib/NormalModule.js +26 -20
  27. package/lib/NormalModuleFactory.js +17 -10
  28. package/lib/ProgressPlugin.js +3 -4
  29. package/lib/RuntimePlugin.js +18 -0
  30. package/lib/RuntimeTemplate.js +1 -0
  31. package/lib/WebpackOptionsApply.js +2 -0
  32. package/lib/asset/AssetGenerator.js +155 -40
  33. package/lib/asset/AssetParser.js +1 -0
  34. package/lib/asset/AssetSourceGenerator.js +31 -6
  35. package/lib/asset/AssetSourceParser.js +1 -0
  36. package/lib/cache/PackFileCacheStrategy.js +8 -4
  37. package/lib/cache/ResolverCachePlugin.js +89 -28
  38. package/lib/config/browserslistTargetHandler.js +3 -5
  39. package/lib/config/defaults.js +9 -1
  40. package/lib/config/normalization.js +1 -0
  41. package/lib/container/RemoteRuntimeModule.js +8 -7
  42. package/lib/dependencies/CommonJsExportsParserPlugin.js +1 -2
  43. package/lib/dependencies/ContextDependencyHelpers.js +3 -3
  44. package/lib/dependencies/ContextElementDependency.js +33 -1
  45. package/lib/dependencies/HarmonyAcceptImportDependency.js +5 -3
  46. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +95 -0
  47. package/lib/dependencies/HarmonyExportInitFragment.js +4 -1
  48. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +127 -43
  49. package/lib/dependencies/HarmonyImportSpecifierDependency.js +22 -8
  50. package/lib/dependencies/HarmonyModulesPlugin.js +10 -0
  51. package/lib/dependencies/ImportContextDependency.js +0 -2
  52. package/lib/dependencies/ImportMetaContextDependency.js +35 -0
  53. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +252 -0
  54. package/lib/dependencies/ImportMetaContextPlugin.js +59 -0
  55. package/lib/dependencies/LoaderPlugin.js +2 -0
  56. package/lib/dependencies/RequireContextDependency.js +0 -16
  57. package/lib/esm/ModuleChunkLoadingPlugin.js +3 -1
  58. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +24 -8
  59. package/lib/hmr/HotModuleReplacement.runtime.js +29 -14
  60. package/lib/hmr/JavascriptHotModuleReplacement.runtime.js +4 -3
  61. package/lib/ids/HashedModuleIdsPlugin.js +2 -2
  62. package/lib/ids/IdHelpers.js +1 -1
  63. package/lib/javascript/BasicEvaluatedExpression.js +5 -2
  64. package/lib/javascript/JavascriptParser.js +66 -40
  65. package/lib/library/UmdLibraryPlugin.js +5 -3
  66. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +22 -7
  67. package/lib/node/RequireChunkLoadingRuntimeModule.js +22 -7
  68. package/lib/optimize/ConcatenatedModule.js +2 -1
  69. package/lib/optimize/ModuleConcatenationPlugin.js +20 -1
  70. package/lib/runtime/BaseUriRuntimeModule.js +31 -0
  71. package/lib/schemes/HttpUriPlugin.js +44 -3
  72. package/lib/stats/DefaultStatsFactoryPlugin.js +1 -1
  73. package/lib/util/internalSerializables.js +4 -0
  74. package/lib/web/JsonpChunkLoadingRuntimeModule.js +17 -6
  75. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +30 -20
  76. package/module.d.ts +15 -0
  77. package/package.json +2 -2
  78. package/schemas/WebpackOptions.check.js +1 -1
  79. package/schemas/WebpackOptions.json +17 -1
  80. package/schemas/plugins/BannerPlugin.check.js +1 -1
  81. package/schemas/plugins/BannerPlugin.json +4 -0
  82. package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
  83. package/schemas/plugins/schemes/HttpUriPlugin.json +4 -0
  84. package/types.d.ts +202 -84
package/hot/poll.js CHANGED
@@ -4,7 +4,7 @@
4
4
  */
5
5
  /*globals __resourceQuery */
6
6
  if (module.hot) {
7
- var hotPollInterval = +__resourceQuery.substr(1) || 10 * 60 * 1000;
7
+ var hotPollInterval = +__resourceQuery.slice(1) || 10 * 60 * 1000;
8
8
  var log = require("./log");
9
9
 
10
10
  var checkForUpdate = function checkForUpdate(fromUpdate) {
package/hot/signal.js CHANGED
@@ -45,7 +45,7 @@ if (module.hot) {
45
45
  });
46
46
  };
47
47
 
48
- process.on(__resourceQuery.substr(1) || "SIGUSR2", function () {
48
+ process.on(__resourceQuery.slice(1) || "SIGUSR2", function () {
49
49
  if (module.hot.status() !== "idle") {
50
50
  log(
51
51
  "warning",
@@ -77,6 +77,7 @@ class BannerPlugin {
77
77
  undefined,
78
78
  options
79
79
  );
80
+ const cache = new WeakMap();
80
81
 
81
82
  compiler.hooks.compilation.tap("BannerPlugin", compilation => {
82
83
  compilation.hooks.processAssets.tap(
@@ -102,10 +103,17 @@ class BannerPlugin {
102
103
 
103
104
  const comment = compilation.getPath(banner, data);
104
105
 
105
- compilation.updateAsset(
106
- file,
107
- old => new ConcatSource(comment, "\n", old)
108
- );
106
+ compilation.updateAsset(file, old => {
107
+ let cached = cache.get(old);
108
+ if (!cached || cached.comment !== comment) {
109
+ const source = options.footer
110
+ ? new ConcatSource(old, "\n", comment)
111
+ : new ConcatSource(comment, "\n", old);
112
+ cache.set(old, { source, comment });
113
+ return source;
114
+ }
115
+ return cached.source;
116
+ });
109
117
  }
110
118
  }
111
119
  }
package/lib/Chunk.js CHANGED
@@ -690,7 +690,7 @@ class Chunk {
690
690
  for (const childGroup of group.childrenIterable) {
691
691
  for (const key of Object.keys(childGroup.options)) {
692
692
  if (key.endsWith("Order")) {
693
- const name = key.substr(0, key.length - "Order".length);
693
+ const name = key.slice(0, key.length - "Order".length);
694
694
  let list = lists.get(name);
695
695
  if (list === undefined) {
696
696
  list = [];
package/lib/ChunkGraph.js CHANGED
@@ -85,14 +85,17 @@ const getModuleRuntimes = chunks => {
85
85
  };
86
86
 
87
87
  /**
88
- * @param {SortableSet<Module>} set the set
89
- * @returns {Map<string, SortableSet<Module>>} modules by source type
88
+ * @param {WeakMap<Module, Set<string>> | undefined} sourceTypesByModule sourceTypesByModule
89
+ * @returns {function (SortableSet<Module>): Map<string, SortableSet<Module>>} modules by source type
90
90
  */
91
- const modulesBySourceType = set => {
91
+ const modulesBySourceType = sourceTypesByModule => set => {
92
92
  /** @type {Map<string, SortableSet<Module>>} */
93
93
  const map = new Map();
94
94
  for (const module of set) {
95
- for (const sourceType of module.getSourceTypes()) {
95
+ const sourceTypes =
96
+ (sourceTypesByModule && sourceTypesByModule.get(module)) ||
97
+ module.getSourceTypes();
98
+ for (const sourceType of sourceTypes) {
96
99
  let innerSet = map.get(sourceType);
97
100
  if (innerSet === undefined) {
98
101
  innerSet = new SortableSet();
@@ -110,6 +113,7 @@ const modulesBySourceType = set => {
110
113
  }
111
114
  return map;
112
115
  };
116
+ const defaultModulesBySourceType = modulesBySourceType(undefined);
113
117
 
114
118
  /** @type {WeakMap<Function, any>} */
115
119
  const createOrderedArrayFunctionMap = new WeakMap();
@@ -201,6 +205,8 @@ class ChunkGraphChunk {
201
205
  constructor() {
202
206
  /** @type {SortableSet<Module>} */
203
207
  this.modules = new SortableSet();
208
+ /** @type {WeakMap<Module, Set<string>> | undefined} */
209
+ this.sourceTypesByModule = undefined;
204
210
  /** @type {Map<Module, Entrypoint>} */
205
211
  this.entryModules = new Map();
206
212
  /** @type {SortableSet<RuntimeModule>} */
@@ -213,6 +219,8 @@ class ChunkGraphChunk {
213
219
  this.runtimeRequirements = undefined;
214
220
  /** @type {Set<string>} */
215
221
  this.runtimeRequirementsInTree = new Set();
222
+
223
+ this._modulesBySourceType = defaultModulesBySourceType;
216
224
  }
217
225
  }
218
226
 
@@ -315,6 +323,8 @@ class ChunkGraph {
315
323
  const cgm = this._getChunkGraphModule(module);
316
324
  const cgc = this._getChunkGraphChunk(chunk);
317
325
  cgc.modules.delete(module);
326
+ // No need to invalidate cgc._modulesBySourceType because we modified cgc.modules anyway
327
+ if (cgc.sourceTypesByModule) cgc.sourceTypesByModule.delete(module);
318
328
  cgm.chunks.delete(chunk);
319
329
  }
320
330
 
@@ -568,11 +578,84 @@ class ChunkGraph {
568
578
  getChunkModulesIterableBySourceType(chunk, sourceType) {
569
579
  const cgc = this._getChunkGraphChunk(chunk);
570
580
  const modulesWithSourceType = cgc.modules
571
- .getFromUnorderedCache(modulesBySourceType)
581
+ .getFromUnorderedCache(cgc._modulesBySourceType)
572
582
  .get(sourceType);
573
583
  return modulesWithSourceType;
574
584
  }
575
585
 
586
+ /**
587
+ * @param {Chunk} chunk chunk
588
+ * @param {Module} module chunk module
589
+ * @param {Set<string>} sourceTypes source types
590
+ */
591
+ setChunkModuleSourceTypes(chunk, module, sourceTypes) {
592
+ const cgc = this._getChunkGraphChunk(chunk);
593
+ if (cgc.sourceTypesByModule === undefined) {
594
+ cgc.sourceTypesByModule = new WeakMap();
595
+ }
596
+ cgc.sourceTypesByModule.set(module, sourceTypes);
597
+ // Update cgc._modulesBySourceType to invalidate the cache
598
+ cgc._modulesBySourceType = modulesBySourceType(cgc.sourceTypesByModule);
599
+ }
600
+
601
+ /**
602
+ * @param {Chunk} chunk chunk
603
+ * @param {Module} module chunk module
604
+ * @returns {Set<string>} source types
605
+ */
606
+ getChunkModuleSourceTypes(chunk, module) {
607
+ const cgc = this._getChunkGraphChunk(chunk);
608
+ if (cgc.sourceTypesByModule === undefined) {
609
+ return module.getSourceTypes();
610
+ }
611
+ return cgc.sourceTypesByModule.get(module) || module.getSourceTypes();
612
+ }
613
+
614
+ /**
615
+ * @param {Module} module module
616
+ * @returns {Set<string>} source types
617
+ */
618
+ getModuleSourceTypes(module) {
619
+ return (
620
+ this._getOverwrittenModuleSourceTypes(module) || module.getSourceTypes()
621
+ );
622
+ }
623
+
624
+ /**
625
+ * @param {Module} module module
626
+ * @returns {Set<string> | undefined} source types
627
+ */
628
+ _getOverwrittenModuleSourceTypes(module) {
629
+ let newSet = false;
630
+ let sourceTypes;
631
+ for (const chunk of this.getModuleChunksIterable(module)) {
632
+ const cgc = this._getChunkGraphChunk(chunk);
633
+ if (cgc.sourceTypesByModule === undefined) return;
634
+ const st = cgc.sourceTypesByModule.get(module);
635
+ if (st === undefined) return;
636
+ if (!sourceTypes) {
637
+ sourceTypes = st;
638
+ continue;
639
+ } else if (!newSet) {
640
+ for (const type of st) {
641
+ if (!newSet) {
642
+ if (!sourceTypes.has(type)) {
643
+ newSet = true;
644
+ sourceTypes = new Set(sourceTypes);
645
+ sourceTypes.add(type);
646
+ }
647
+ } else {
648
+ sourceTypes.add(type);
649
+ }
650
+ }
651
+ } else {
652
+ for (const type of st) sourceTypes.add(type);
653
+ }
654
+ }
655
+
656
+ return sourceTypes;
657
+ }
658
+
576
659
  /**
577
660
  * @param {Chunk} chunk the chunk
578
661
  * @param {function(Module, Module): -1|0|1} comparator comparator function
@@ -593,7 +676,7 @@ class ChunkGraph {
593
676
  getOrderedChunkModulesIterableBySourceType(chunk, sourceType, comparator) {
594
677
  const cgc = this._getChunkGraphChunk(chunk);
595
678
  const modulesWithSourceType = cgc.modules
596
- .getFromUnorderedCache(modulesBySourceType)
679
+ .getFromUnorderedCache(cgc._modulesBySourceType)
597
680
  .get(sourceType);
598
681
  if (modulesWithSourceType === undefined) return undefined;
599
682
  modulesWithSourceType.sortWith(comparator);
@@ -1473,6 +1556,10 @@ Caller might not support runtime-dependent code generation (opt-out via optimiza
1473
1556
  const graphHash = cgm.graphHashes.provide(runtime, () => {
1474
1557
  const hash = createHash(this._hashFunction);
1475
1558
  hash.update(`${cgm.id}${this.moduleGraph.isAsync(module)}`);
1559
+ const sourceTypes = this._getOverwrittenModuleSourceTypes(module);
1560
+ if (sourceTypes !== undefined) {
1561
+ for (const type of sourceTypes) hash.update(type);
1562
+ }
1476
1563
  this.moduleGraph.getExportsInfo(module).updateHash(hash, runtime);
1477
1564
  return BigInt(`0x${/** @type {string} */ (hash.digest("hex"))}`);
1478
1565
  });
package/lib/ChunkGroup.js CHANGED
@@ -486,7 +486,7 @@ class ChunkGroup {
486
486
  for (const childGroup of this._children) {
487
487
  for (const key of Object.keys(childGroup.options)) {
488
488
  if (key.endsWith("Order")) {
489
- const name = key.substr(0, key.length - "Order".length);
489
+ const name = key.slice(0, key.length - "Order".length);
490
490
  let list = lists.get(name);
491
491
  if (list === undefined) {
492
492
  lists.set(name, (list = []));
@@ -19,6 +19,7 @@ const processAsyncTree = require("./util/processAsyncTree");
19
19
  /** @typedef {import("./util/fs").StatsCallback} StatsCallback */
20
20
 
21
21
  /** @typedef {(function(string):boolean)|RegExp} IgnoreItem */
22
+ /** @typedef {Map<string, number>} Assets */
22
23
  /** @typedef {function(IgnoreItem): void} AddToIgnoreCallback */
23
24
 
24
25
  /**
@@ -40,18 +41,32 @@ const validate = createSchemaValidation(
40
41
  baseDataPath: "options"
41
42
  }
42
43
  );
44
+ const _10sec = 10 * 1000;
45
+
46
+ /**
47
+ * marge assets map 2 into map 1
48
+ * @param {Assets} as1 assets
49
+ * @param {Assets} as2 assets
50
+ * @returns {void}
51
+ */
52
+ const mergeAssets = (as1, as2) => {
53
+ for (const [key, value1] of as2) {
54
+ const value2 = as1.get(key);
55
+ if (!value2 || value1 > value2) as1.set(key, value1);
56
+ }
57
+ };
43
58
 
44
59
  /**
45
60
  * @param {OutputFileSystem} fs filesystem
46
61
  * @param {string} outputPath output path
47
- * @param {Set<string>} currentAssets filename of the current assets (must not start with .. or ., must only use / as path separator)
62
+ * @param {Map<string, number>} currentAssets filename of the current assets (must not start with .. or ., must only use / as path separator)
48
63
  * @param {function((Error | null)=, Set<string>=): void} callback returns the filenames of the assets that shouldn't be there
49
64
  * @returns {void}
50
65
  */
51
66
  const getDiffToFs = (fs, outputPath, currentAssets, callback) => {
52
67
  const directories = new Set();
53
68
  // get directories of assets
54
- for (const asset of currentAssets) {
69
+ for (const [asset] of currentAssets) {
55
70
  directories.add(asset.replace(/(^|\/)[^/]*$/, ""));
56
71
  }
57
72
  // and all parent directories
@@ -91,13 +106,15 @@ const getDiffToFs = (fs, outputPath, currentAssets, callback) => {
91
106
  };
92
107
 
93
108
  /**
94
- * @param {Set<string>} currentAssets assets list
95
- * @param {Set<string>} oldAssets old assets list
109
+ * @param {Assets} currentAssets assets list
110
+ * @param {Assets} oldAssets old assets list
96
111
  * @returns {Set<string>} diff
97
112
  */
98
113
  const getDiffToOldAssets = (currentAssets, oldAssets) => {
99
114
  const diff = new Set();
100
- for (const asset of oldAssets) {
115
+ const now = Date.now();
116
+ for (const [asset, ts] of oldAssets) {
117
+ if (ts >= now) continue;
101
118
  if (!currentAssets.has(asset)) diff.add(asset);
102
119
  }
103
120
  return diff;
@@ -124,7 +141,7 @@ const doStat = (fs, filename, callback) => {
124
141
  * @param {Logger} logger logger
125
142
  * @param {Set<string>} diff filenames of the assets that shouldn't be there
126
143
  * @param {function(string): boolean} isKept check if the entry is ignored
127
- * @param {function(Error=): void} callback callback
144
+ * @param {function(Error=, Assets=): void} callback callback
128
145
  * @returns {void}
129
146
  */
130
147
  const applyDiff = (fs, outputPath, dry, logger, diff, isKept, callback) => {
@@ -137,11 +154,13 @@ const applyDiff = (fs, outputPath, dry, logger, diff, isKept, callback) => {
137
154
  };
138
155
  /** @typedef {{ type: "check" | "unlink" | "rmdir", filename: string, parent: { remaining: number, job: Job } | undefined }} Job */
139
156
  /** @type {Job[]} */
140
- const jobs = Array.from(diff, filename => ({
157
+ const jobs = Array.from(diff.keys(), filename => ({
141
158
  type: "check",
142
159
  filename,
143
160
  parent: undefined
144
161
  }));
162
+ /** @type {Assets} */
163
+ const keptAssets = new Map();
145
164
  processAsyncTree(
146
165
  jobs,
147
166
  10,
@@ -161,6 +180,7 @@ const applyDiff = (fs, outputPath, dry, logger, diff, isKept, callback) => {
161
180
  switch (type) {
162
181
  case "check":
163
182
  if (isKept(filename)) {
183
+ keptAssets.set(filename, 0);
164
184
  // do not decrement parent entry as we don't want to delete the parent
165
185
  log(`${filename} will be kept`);
166
186
  return process.nextTick(callback);
@@ -247,7 +267,10 @@ const applyDiff = (fs, outputPath, dry, logger, diff, isKept, callback) => {
247
267
  break;
248
268
  }
249
269
  },
250
- callback
270
+ err => {
271
+ if (err) return callback(err);
272
+ callback(undefined, keptAssets);
273
+ }
251
274
  );
252
275
  };
253
276
 
@@ -302,6 +325,7 @@ class CleanPlugin {
302
325
  // We assume that no external modification happens while the compiler is active
303
326
  // So we can store the old assets and only diff to them to avoid fs access on
304
327
  // incremental builds
328
+ /** @type {undefined|Assets} */
305
329
  let oldAssets;
306
330
 
307
331
  compiler.hooks.emit.tapAsync(
@@ -322,7 +346,9 @@ class CleanPlugin {
322
346
  );
323
347
  }
324
348
 
325
- const currentAssets = new Set();
349
+ /** @type {Assets} */
350
+ const currentAssets = new Map();
351
+ const now = Date.now();
326
352
  for (const asset of Object.keys(compilation.assets)) {
327
353
  if (/^[A-Za-z]:\\|^\/|^\\\\/.test(asset)) continue;
328
354
  let normalizedAsset;
@@ -335,7 +361,12 @@ class CleanPlugin {
335
361
  );
336
362
  } while (newNormalizedAsset !== normalizedAsset);
337
363
  if (normalizedAsset.startsWith("../")) continue;
338
- currentAssets.add(normalizedAsset);
364
+ const assetInfo = compilation.assetsInfo.get(asset);
365
+ if (assetInfo && assetInfo.hotModuleReplacement) {
366
+ currentAssets.set(normalizedAsset, now + _10sec);
367
+ } else {
368
+ currentAssets.set(normalizedAsset, 0);
369
+ }
339
370
  }
340
371
 
341
372
  const outputPath = compilation.getPath(compiler.outputPath, {});
@@ -346,19 +377,34 @@ class CleanPlugin {
346
377
  return keepFn(path);
347
378
  };
348
379
 
380
+ /**
381
+ * @param {Error=} err err
382
+ * @param {Set<string>=} diff diff
383
+ */
349
384
  const diffCallback = (err, diff) => {
350
385
  if (err) {
351
386
  oldAssets = undefined;
352
- return callback(err);
387
+ callback(err);
388
+ return;
353
389
  }
354
- applyDiff(fs, outputPath, dry, logger, diff, isKept, err => {
355
- if (err) {
356
- oldAssets = undefined;
357
- } else {
358
- oldAssets = currentAssets;
390
+ applyDiff(
391
+ fs,
392
+ outputPath,
393
+ dry,
394
+ logger,
395
+ diff,
396
+ isKept,
397
+ (err, keptAssets) => {
398
+ if (err) {
399
+ oldAssets = undefined;
400
+ } else {
401
+ if (oldAssets) mergeAssets(currentAssets, oldAssets);
402
+ oldAssets = currentAssets;
403
+ if (keptAssets) mergeAssets(oldAssets, keptAssets);
404
+ }
405
+ callback(err);
359
406
  }
360
- callback(err);
361
- });
407
+ );
362
408
  };
363
409
 
364
410
  if (oldAssets) {
@@ -43,6 +43,7 @@ const Module = require("./Module");
43
43
  const ModuleDependencyError = require("./ModuleDependencyError");
44
44
  const ModuleDependencyWarning = require("./ModuleDependencyWarning");
45
45
  const ModuleGraph = require("./ModuleGraph");
46
+ const ModuleHashingError = require("./ModuleHashingError");
46
47
  const ModuleNotFoundError = require("./ModuleNotFoundError");
47
48
  const ModuleProfile = require("./ModuleProfile");
48
49
  const ModuleRestoreError = require("./ModuleRestoreError");
@@ -1435,7 +1436,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
1435
1436
  * @returns {void}
1436
1437
  */
1437
1438
  _processModuleDependencies(module, callback) {
1438
- /** @type {Array<{factory: ModuleFactory, dependencies: Dependency[], originModule: Module|null}>} */
1439
+ /** @type {Array<{factory: ModuleFactory, dependencies: Dependency[], context: string|undefined, originModule: Module|null}>} */
1439
1440
  const sortedDependencies = [];
1440
1441
 
1441
1442
  /** @type {DependenciesBlock} */
@@ -1667,6 +1668,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
1667
1668
  sortedDependencies.push({
1668
1669
  factory: factoryCacheKey2,
1669
1670
  dependencies: list,
1671
+ context: dep.getContext(),
1670
1672
  originModule: module
1671
1673
  });
1672
1674
  }
@@ -3327,7 +3329,8 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
3327
3329
  dependencyTemplates,
3328
3330
  runtimeTemplate,
3329
3331
  runtime,
3330
- codeGenerationResults: results
3332
+ codeGenerationResults: results,
3333
+ compilation: this
3331
3334
  });
3332
3335
  } catch (err) {
3333
3336
  errors.push(new CodeGenerationError(module, err));
@@ -3883,6 +3886,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
3883
3886
  let statModulesFromCache = 0;
3884
3887
  const { chunkGraph, runtimeTemplate, moduleMemCaches2 } = this;
3885
3888
  const { hashFunction, hashDigest, hashDigestLength } = this.outputOptions;
3889
+ const errors = [];
3886
3890
  for (const module of this.modules) {
3887
3891
  const memCache = moduleMemCaches2 && moduleMemCaches2.get(module);
3888
3892
  for (const runtime of chunkGraph.getModuleRuntimes(module)) {
@@ -3893,7 +3897,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
3893
3897
  module,
3894
3898
  runtime,
3895
3899
  digest,
3896
- digest.substr(0, hashDigestLength)
3900
+ digest.slice(0, hashDigestLength)
3897
3901
  );
3898
3902
  statModulesFromCache++;
3899
3903
  continue;
@@ -3907,13 +3911,20 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
3907
3911
  hashFunction,
3908
3912
  runtimeTemplate,
3909
3913
  hashDigest,
3910
- hashDigestLength
3914
+ hashDigestLength,
3915
+ errors
3911
3916
  );
3912
3917
  if (memCache) {
3913
3918
  memCache.set(`moduleHash-${getRuntimeKey(runtime)}`, digest);
3914
3919
  }
3915
3920
  }
3916
3921
  }
3922
+ if (errors.length > 0) {
3923
+ errors.sort(compareSelect(err => err.module, compareModulesByIdentifier));
3924
+ for (const error of errors) {
3925
+ this.errors.push(error);
3926
+ }
3927
+ }
3917
3928
  this.logger.log(
3918
3929
  `${statModulesHashed} modules hashed, ${statModulesFromCache} from cache (${
3919
3930
  Math.round(
@@ -3930,22 +3941,27 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
3930
3941
  hashFunction,
3931
3942
  runtimeTemplate,
3932
3943
  hashDigest,
3933
- hashDigestLength
3944
+ hashDigestLength,
3945
+ errors
3934
3946
  ) {
3935
- const moduleHash = createHash(hashFunction);
3936
- module.updateHash(moduleHash, {
3937
- chunkGraph,
3938
- runtime,
3939
- runtimeTemplate
3940
- });
3941
- const moduleHashDigest = /** @type {string} */ (
3942
- moduleHash.digest(hashDigest)
3943
- );
3947
+ let moduleHashDigest;
3948
+ try {
3949
+ const moduleHash = createHash(hashFunction);
3950
+ module.updateHash(moduleHash, {
3951
+ chunkGraph,
3952
+ runtime,
3953
+ runtimeTemplate
3954
+ });
3955
+ moduleHashDigest = /** @type {string} */ (moduleHash.digest(hashDigest));
3956
+ } catch (err) {
3957
+ errors.push(new ModuleHashingError(module, err));
3958
+ moduleHashDigest = "XXXXXX";
3959
+ }
3944
3960
  chunkGraph.setModuleHashes(
3945
3961
  module,
3946
3962
  runtime,
3947
3963
  moduleHashDigest,
3948
- moduleHashDigest.substr(0, hashDigestLength)
3964
+ moduleHashDigest.slice(0, hashDigestLength)
3949
3965
  );
3950
3966
  return moduleHashDigest;
3951
3967
  }
@@ -4091,6 +4107,7 @@ This prevents using hashes of each other and should be avoided.`);
4091
4107
  const codeGenerationJobs = [];
4092
4108
  /** @type {Map<string, Map<Module, {module: Module, hash: string, runtime: RuntimeSpec, runtimes: RuntimeSpec[]}>>} */
4093
4109
  const codeGenerationJobsMap = new Map();
4110
+ const errors = [];
4094
4111
 
4095
4112
  const processChunk = chunk => {
4096
4113
  // Last minute module hash generation for modules that depend on chunk hashes
@@ -4105,7 +4122,8 @@ This prevents using hashes of each other and should be avoided.`);
4105
4122
  hashFunction,
4106
4123
  runtimeTemplate,
4107
4124
  hashDigest,
4108
- hashDigestLength
4125
+ hashDigestLength,
4126
+ errors
4109
4127
  );
4110
4128
  let hashMap = codeGenerationJobsMap.get(hash);
4111
4129
  if (hashMap) {
@@ -4129,9 +4147,9 @@ This prevents using hashes of each other and should be avoided.`);
4129
4147
  }
4130
4148
  }
4131
4149
  this.logger.timeAggregate("hashing: hash runtime modules");
4132
- this.logger.time("hashing: hash chunks");
4133
- const chunkHash = createHash(hashFunction);
4134
4150
  try {
4151
+ this.logger.time("hashing: hash chunks");
4152
+ const chunkHash = createHash(hashFunction);
4135
4153
  if (outputOptions.hashSalt) {
4136
4154
  chunkHash.update(outputOptions.hashSalt);
4137
4155
  }
@@ -4147,7 +4165,7 @@ This prevents using hashes of each other and should be avoided.`);
4147
4165
  );
4148
4166
  hash.update(chunkHashDigest);
4149
4167
  chunk.hash = chunkHashDigest;
4150
- chunk.renderedHash = chunk.hash.substr(0, hashDigestLength);
4168
+ chunk.renderedHash = chunk.hash.slice(0, hashDigestLength);
4151
4169
  const fullHashModules =
4152
4170
  chunkGraph.getChunkFullHashModulesIterable(chunk);
4153
4171
  if (fullHashModules) {
@@ -4162,13 +4180,19 @@ This prevents using hashes of each other and should be avoided.`);
4162
4180
  };
4163
4181
  otherChunks.forEach(processChunk);
4164
4182
  for (const chunk of runtimeChunks) processChunk(chunk);
4183
+ if (errors.length > 0) {
4184
+ errors.sort(compareSelect(err => err.module, compareModulesByIdentifier));
4185
+ for (const error of errors) {
4186
+ this.errors.push(error);
4187
+ }
4188
+ }
4165
4189
 
4166
4190
  this.logger.timeAggregateEnd("hashing: hash runtime modules");
4167
4191
  this.logger.timeAggregateEnd("hashing: hash chunks");
4168
4192
  this.logger.time("hashing: hash digest");
4169
4193
  this.hooks.fullHash.call(hash);
4170
4194
  this.fullHash = /** @type {string} */ (hash.digest(hashDigest));
4171
- this.hash = this.fullHash.substr(0, hashDigestLength);
4195
+ this.hash = this.fullHash.slice(0, hashDigestLength);
4172
4196
  this.logger.timeEnd("hashing: hash digest");
4173
4197
 
4174
4198
  this.logger.time("hashing: process full hash modules");
@@ -4188,7 +4212,7 @@ This prevents using hashes of each other and should be avoided.`);
4188
4212
  module,
4189
4213
  chunk.runtime,
4190
4214
  moduleHashDigest,
4191
- moduleHashDigest.substr(0, hashDigestLength)
4215
+ moduleHashDigest.slice(0, hashDigestLength)
4192
4216
  );
4193
4217
  codeGenerationJobsMap.get(oldHash).get(module).hash = moduleHashDigest;
4194
4218
  }
@@ -4199,7 +4223,7 @@ This prevents using hashes of each other and should be avoided.`);
4199
4223
  chunkHash.digest(hashDigest)
4200
4224
  );
4201
4225
  chunk.hash = chunkHashDigest;
4202
- chunk.renderedHash = chunk.hash.substr(0, hashDigestLength);
4226
+ chunk.renderedHash = chunk.hash.slice(0, hashDigestLength);
4203
4227
  this.hooks.contentHash.call(chunk);
4204
4228
  }
4205
4229
  this.logger.timeEnd("hashing: process full hash modules");
@@ -4801,6 +4825,9 @@ This prevents using hashes of each other and should be avoided.`);
4801
4825
  chunkGraph.connectChunkAndModule(chunk, module);
4802
4826
  }
4803
4827
 
4828
+ /** @type {WebpackError[]} */
4829
+ const errors = [];
4830
+
4804
4831
  // Hash modules
4805
4832
  for (const module of modules) {
4806
4833
  this._createModuleHash(
@@ -4810,15 +4837,14 @@ This prevents using hashes of each other and should be avoided.`);
4810
4837
  hashFunction,
4811
4838
  runtimeTemplate,
4812
4839
  hashDigest,
4813
- hashDigestLength
4840
+ hashDigestLength,
4841
+ errors
4814
4842
  );
4815
4843
  }
4816
4844
 
4817
4845
  const codeGenerationResults = new CodeGenerationResults(
4818
4846
  this.outputOptions.hashFunction
4819
4847
  );
4820
- /** @type {WebpackError[]} */
4821
- const errors = [];
4822
4848
  /**
4823
4849
  * @param {Module} module the module
4824
4850
  * @param {Callback} callback callback
package/lib/Compiler.js CHANGED
@@ -545,8 +545,21 @@ class Compiler {
545
545
  */
546
546
  runAsChild(callback) {
547
547
  const startTime = Date.now();
548
+
549
+ const finalCallback = (err, entries, compilation) => {
550
+ try {
551
+ callback(err, entries, compilation);
552
+ } catch (e) {
553
+ const err = new WebpackError(
554
+ `compiler.runAsChild callback error: ${e}`
555
+ );
556
+ err.details = e.stack;
557
+ this.parentCompilation.errors.push(err);
558
+ }
559
+ };
560
+
548
561
  this.compile((err, compilation) => {
549
- if (err) return callback(err);
562
+ if (err) return finalCallback(err);
550
563
 
551
564
  this.parentCompilation.children.push(compilation);
552
565
  for (const { name, source, info } of compilation.getAssets()) {
@@ -561,7 +574,7 @@ class Compiler {
561
574
  compilation.startTime = startTime;
562
575
  compilation.endTime = Date.now();
563
576
 
564
- return callback(null, entries, compilation);
577
+ return finalCallback(null, entries, compilation);
565
578
  });
566
579
  }
567
580
 
@@ -596,7 +609,7 @@ class Compiler {
596
609
  let immutable = info.immutable;
597
610
  const queryStringIdx = targetFile.indexOf("?");
598
611
  if (queryStringIdx >= 0) {
599
- targetFile = targetFile.substr(0, queryStringIdx);
612
+ targetFile = targetFile.slice(0, queryStringIdx);
600
613
  // We may remove the hash, which is in the query string
601
614
  // So we recheck if the file is immutable
602
615
  // This doesn't cover all cases, but immutable is only a performance optimization anyway
@@ -324,7 +324,7 @@ class ConstPlugin {
324
324
  }
325
325
  } else if (expression.operator === "??") {
326
326
  const param = parser.evaluateExpression(expression.left);
327
- const keepRight = param && param.asNullish();
327
+ const keepRight = param.asNullish();
328
328
  if (typeof keepRight === "boolean") {
329
329
  // ------------------------------------------
330
330
  //
@@ -407,7 +407,7 @@ class ConstPlugin {
407
407
  const expression = optionalExpressionsStack.pop();
408
408
  const evaluated = parser.evaluateExpression(expression);
409
409
 
410
- if (evaluated && evaluated.asNullish()) {
410
+ if (evaluated.asNullish()) {
411
411
  // ------------------------------------------
412
412
  //
413
413
  // Given the following code: