webpack 5.31.2 → 5.33.2

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 (55) hide show
  1. package/lib/CaseSensitiveModulesWarning.js +3 -3
  2. package/lib/Compilation.js +488 -48
  3. package/lib/DefinePlugin.js +21 -5
  4. package/lib/EntryOptionPlugin.js +1 -0
  5. package/lib/FlagDependencyExportsPlugin.js +22 -0
  6. package/lib/Module.js +1 -1
  7. package/lib/ModuleGraph.js +24 -0
  8. package/lib/NormalModule.js +14 -3
  9. package/lib/NormalModuleFactory.js +15 -1
  10. package/lib/RuntimeModule.js +5 -1
  11. package/lib/RuntimePlugin.js +7 -2
  12. package/lib/WarnCaseSensitiveModulesPlugin.js +15 -9
  13. package/lib/WebpackOptionsApply.js +3 -1
  14. package/lib/asset/AssetModulesPlugin.js +13 -0
  15. package/lib/config/defaults.js +1 -3
  16. package/lib/config/normalization.js +1 -0
  17. package/lib/container/RemoteRuntimeModule.js +2 -1
  18. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +7 -3
  19. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +191 -39
  20. package/lib/dependencies/LoaderImportDependency.js +28 -0
  21. package/lib/dependencies/LoaderPlugin.js +134 -2
  22. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +2 -2
  23. package/lib/javascript/CommonJsChunkFormatPlugin.js +2 -2
  24. package/lib/javascript/JavascriptModulesPlugin.js +67 -2
  25. package/lib/library/AbstractLibraryPlugin.js +26 -8
  26. package/lib/node/CommonJsChunkLoadingPlugin.js +3 -1
  27. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +2 -2
  28. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +3 -1
  29. package/lib/node/ReadFileCompileWasmPlugin.js +3 -1
  30. package/lib/node/RequireChunkLoadingRuntimeModule.js +2 -2
  31. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +2 -4
  32. package/lib/runtime/CompatRuntimeModule.js +1 -2
  33. package/lib/runtime/GetChunkFilenameRuntimeModule.js +3 -2
  34. package/lib/runtime/PublicPathRuntimeModule.js +5 -5
  35. package/lib/runtime/RuntimeIdRuntimeModule.js +1 -2
  36. package/lib/runtime/StartupChunkDependenciesPlugin.js +5 -3
  37. package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +2 -2
  38. package/lib/serialization/ObjectMiddleware.js +13 -4
  39. package/lib/sharing/ConsumeSharedRuntimeModule.js +2 -5
  40. package/lib/sharing/ShareRuntimeModule.js +2 -2
  41. package/lib/stats/DefaultStatsFactoryPlugin.js +5 -0
  42. package/lib/stats/DefaultStatsPrinterPlugin.js +2 -0
  43. package/lib/util/AsyncQueue.js +45 -10
  44. package/lib/util/WeakTupleMap.js +168 -0
  45. package/lib/util/processAsyncTree.js +3 -2
  46. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +2 -2
  47. package/lib/web/FetchCompileAsyncWasmPlugin.js +3 -1
  48. package/lib/web/FetchCompileWasmPlugin.js +3 -1
  49. package/lib/web/JsonpChunkLoadingPlugin.js +3 -1
  50. package/lib/web/JsonpChunkLoadingRuntimeModule.js +1 -2
  51. package/lib/webworker/ImportScriptsChunkLoadingPlugin.js +3 -1
  52. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +1 -1
  53. package/package.json +3 -3
  54. package/schemas/WebpackOptions.json +10 -0
  55. package/types.d.ts +131 -14
@@ -6,6 +6,7 @@
6
6
  "use strict";
7
7
 
8
8
  const { SyncWaterfallHook, SyncHook, SyncBailHook } = require("tapable");
9
+ const vm = require("vm");
9
10
  const {
10
11
  ConcatSource,
11
12
  OriginalSource,
@@ -51,6 +52,17 @@ const chunkHasJs = (chunk, chunkGraph) => {
51
52
  : false;
52
53
  };
53
54
 
55
+ const printGeneratedCodeForStack = (module, code) => {
56
+ const lines = code.split("\n");
57
+ const n = `${lines.length}`.length;
58
+ return `\n\nGenerated code for ${module.identifier()}\n${lines
59
+ .map((line, i, lines) => {
60
+ const iStr = `${i + 1}`;
61
+ return `${" ".repeat(n - iStr.length)}${iStr} | ${line}`;
62
+ })
63
+ .join("\n")}`;
64
+ };
65
+
54
66
  /**
55
67
  * @typedef {Object} RenderContext
56
68
  * @property {Chunk} chunk the chunk
@@ -369,16 +381,69 @@ class JavascriptModulesPlugin {
369
381
  });
370
382
  compilation.hooks.additionalTreeRuntimeRequirements.tap(
371
383
  "JavascriptModulesPlugin",
372
- (chunk, set) => {
384
+ (chunk, set, { chunkGraph }) => {
373
385
  if (
374
386
  !set.has(RuntimeGlobals.startupNoDefault) &&
375
- compilation.chunkGraph.hasChunkEntryDependentChunks(chunk)
387
+ chunkGraph.hasChunkEntryDependentChunks(chunk)
376
388
  ) {
377
389
  set.add(RuntimeGlobals.onChunksLoaded);
378
390
  set.add(RuntimeGlobals.require);
379
391
  }
380
392
  }
381
393
  );
394
+ compilation.hooks.executeModule.tap(
395
+ "JavascriptModulesPlugin",
396
+ (options, context) => {
397
+ const source = options.codeGenerationResult.sources.get(
398
+ "javascript"
399
+ );
400
+ if (source === undefined) return;
401
+ const { module, moduleObject } = options;
402
+ const code = source.source();
403
+
404
+ const fn = vm.runInThisContext(
405
+ `(function(${module.moduleArgument}, ${module.exportsArgument}, __webpack_require__) {\n${code}\n/**/})`,
406
+ {
407
+ filename: module.identifier(),
408
+ lineOffset: -1
409
+ }
410
+ );
411
+ try {
412
+ fn.call(
413
+ moduleObject.exports,
414
+ moduleObject,
415
+ moduleObject.exports,
416
+ context.__webpack_require__
417
+ );
418
+ } catch (e) {
419
+ e.stack += printGeneratedCodeForStack(options.module, code);
420
+ throw e;
421
+ }
422
+ }
423
+ );
424
+ compilation.hooks.executeModule.tap(
425
+ "JavascriptModulesPlugin",
426
+ (options, context) => {
427
+ const source = options.codeGenerationResult.sources.get("runtime");
428
+ if (source === undefined) return;
429
+ let code = source.source();
430
+ if (typeof code !== "string") code = code.toString();
431
+
432
+ const fn = vm.runInThisContext(
433
+ `(function(__webpack_require__) {\n${code}\n/**/})`,
434
+ {
435
+ filename: options.module.identifier(),
436
+ lineOffset: -1
437
+ }
438
+ );
439
+ try {
440
+ fn.call(null, context.__webpack_require__);
441
+ } catch (e) {
442
+ e.stack += printGeneratedCodeForStack(options.module, code);
443
+ throw e;
444
+ }
445
+ }
446
+ );
382
447
  }
383
448
  );
384
449
  }
@@ -12,6 +12,7 @@ const JavascriptModulesPlugin = require("../javascript/JavascriptModulesPlugin")
12
12
  /** @typedef {import("../../declarations/WebpackOptions").LibraryOptions} LibraryOptions */
13
13
  /** @typedef {import("../../declarations/WebpackOptions").LibraryType} LibraryType */
14
14
  /** @typedef {import("../Chunk")} Chunk */
15
+ /** @typedef {import("../ChunkGraph")} ChunkGraph */
15
16
  /** @typedef {import("../Compilation")} Compilation */
16
17
  /** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */
17
18
  /** @typedef {import("../Compiler")} Compiler */
@@ -27,6 +28,7 @@ const COMMON_LIBRARY_NAME_MESSAGE =
27
28
  * @template T
28
29
  * @typedef {Object} LibraryContext
29
30
  * @property {Compilation} compilation
31
+ * @property {ChunkGraph} chunkGraph
30
32
  * @property {T} options
31
33
  */
32
34
 
@@ -75,7 +77,8 @@ class AbstractLibraryPlugin {
75
77
  if (module) {
76
78
  this.finishEntryModule(module, name, {
77
79
  options,
78
- compilation
80
+ compilation,
81
+ chunkGraph: compilation.chunkGraph
79
82
  });
80
83
  }
81
84
  }
@@ -101,10 +104,14 @@ class AbstractLibraryPlugin {
101
104
  ) {
102
105
  compilation.hooks.additionalChunkRuntimeRequirements.tap(
103
106
  _pluginName,
104
- (chunk, set) => {
107
+ (chunk, set, { chunkGraph }) => {
105
108
  const options = getOptionsForChunk(chunk);
106
109
  if (options !== false) {
107
- this.runtimeRequirements(chunk, set, { options, compilation });
110
+ this.runtimeRequirements(chunk, set, {
111
+ options,
112
+ compilation,
113
+ chunkGraph
114
+ });
108
115
  }
109
116
  }
110
117
  );
@@ -116,7 +123,11 @@ class AbstractLibraryPlugin {
116
123
  hooks.render.tap(_pluginName, (source, renderContext) => {
117
124
  const options = getOptionsForChunk(renderContext.chunk);
118
125
  if (options === false) return source;
119
- return this.render(source, renderContext, { options, compilation });
126
+ return this.render(source, renderContext, {
127
+ options,
128
+ compilation,
129
+ chunkGraph: compilation.chunkGraph
130
+ });
120
131
  });
121
132
  }
122
133
 
@@ -131,7 +142,8 @@ class AbstractLibraryPlugin {
131
142
  if (options === false) return;
132
143
  return this.embedInRuntimeBailout(module, renderContext, {
133
144
  options,
134
- compilation
145
+ compilation,
146
+ chunkGraph: compilation.chunkGraph
135
147
  });
136
148
  }
137
149
  );
@@ -146,7 +158,8 @@ class AbstractLibraryPlugin {
146
158
  if (options === false) return;
147
159
  return this.strictRuntimeBailout(renderContext, {
148
160
  options,
149
- compilation
161
+ compilation,
162
+ chunkGraph: compilation.chunkGraph
150
163
  });
151
164
  });
152
165
  }
@@ -161,7 +174,8 @@ class AbstractLibraryPlugin {
161
174
  if (options === false) return source;
162
175
  return this.renderStartup(source, module, renderContext, {
163
176
  options,
164
- compilation
177
+ compilation,
178
+ chunkGraph: compilation.chunkGraph
165
179
  });
166
180
  }
167
181
  );
@@ -170,7 +184,11 @@ class AbstractLibraryPlugin {
170
184
  hooks.chunkHash.tap(_pluginName, (chunk, hash, context) => {
171
185
  const options = getOptionsForChunk(chunk);
172
186
  if (options === false) return;
173
- this.chunkHash(chunk, hash, context, { options, compilation });
187
+ this.chunkHash(chunk, hash, context, {
188
+ options,
189
+ compilation,
190
+ chunkGraph: compilation.chunkGraph
191
+ });
174
192
  });
175
193
  });
176
194
  }
@@ -39,7 +39,9 @@ class CommonJsChunkLoadingPlugin {
39
39
  const isEnabledForChunk = chunk => {
40
40
  const options = chunk.getEntryOptions();
41
41
  const chunkLoading =
42
- (options && options.chunkLoading) || globalChunkLoading;
42
+ options && options.chunkLoading !== undefined
43
+ ? options.chunkLoading
44
+ : globalChunkLoading;
43
45
  return chunkLoading === chunkLoadingValue;
44
46
  };
45
47
  const onceForChunkSet = new WeakSet();
@@ -25,8 +25,8 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule {
25
25
  * @returns {string} runtime code
26
26
  */
27
27
  generate() {
28
- const { chunk } = this;
29
- const { chunkGraph, runtimeTemplate } = this.compilation;
28
+ const { chunkGraph, chunk } = this;
29
+ const { runtimeTemplate } = this.compilation;
30
30
  const fn = RuntimeGlobals.ensureChunkHandlers;
31
31
  const withBaseURI = this.runtimeRequirements.has(RuntimeGlobals.baseURI);
32
32
  const withExternalInstallChunk = this.runtimeRequirements.has(
@@ -25,7 +25,9 @@ class ReadFileCompileAsyncWasmPlugin {
25
25
  const isEnabledForChunk = chunk => {
26
26
  const options = chunk.getEntryOptions();
27
27
  const wasmLoading =
28
- (options && options.wasmLoading) || globalWasmLoading;
28
+ options && options.wasmLoading !== undefined
29
+ ? options.wasmLoading
30
+ : globalWasmLoading;
29
31
  return wasmLoading === "async-node";
30
32
  };
31
33
  const generateLoadBinaryCode = path =>
@@ -31,7 +31,9 @@ class ReadFileCompileWasmPlugin {
31
31
  const isEnabledForChunk = chunk => {
32
32
  const options = chunk.getEntryOptions();
33
33
  const wasmLoading =
34
- (options && options.wasmLoading) || globalWasmLoading;
34
+ options && options.wasmLoading !== undefined
35
+ ? options.wasmLoading
36
+ : globalWasmLoading;
35
37
  return wasmLoading === "async-node";
36
38
  };
37
39
  const generateLoadBinaryCode = path =>
@@ -25,8 +25,8 @@ class RequireChunkLoadingRuntimeModule extends RuntimeModule {
25
25
  * @returns {string} runtime code
26
26
  */
27
27
  generate() {
28
- const { chunk } = this;
29
- const { chunkGraph, runtimeTemplate } = this.compilation;
28
+ const { chunkGraph, chunk } = this;
29
+ const { runtimeTemplate } = this.compilation;
30
30
  const fn = RuntimeGlobals.ensureChunkHandlers;
31
31
  const withBaseURI = this.runtimeRequirements.has(RuntimeGlobals.baseURI);
32
32
  const withExternalInstallChunk = this.runtimeRequirements.has(
@@ -24,8 +24,7 @@ class ChunkPrefetchPreloadPlugin {
24
24
  compilation => {
25
25
  compilation.hooks.additionalChunkRuntimeRequirements.tap(
26
26
  "ChunkPrefetchPreloadPlugin",
27
- (chunk, set) => {
28
- const { chunkGraph } = compilation;
27
+ (chunk, set, { chunkGraph }) => {
29
28
  if (chunkGraph.getNumberOfEntryModules(chunk) === 0) return;
30
29
  const startupChildChunks = chunk.getChildrenOfTypeInOrder(
31
30
  chunkGraph,
@@ -43,8 +42,7 @@ class ChunkPrefetchPreloadPlugin {
43
42
  );
44
43
  compilation.hooks.additionalTreeRuntimeRequirements.tap(
45
44
  "ChunkPrefetchPreloadPlugin",
46
- (chunk, set) => {
47
- const { chunkGraph } = compilation;
45
+ (chunk, set, { chunkGraph }) => {
48
46
  const chunkMap = chunk.getChildIdsByOrdersMap(chunkGraph, false);
49
47
 
50
48
  if (chunkMap.prefetch) {
@@ -19,9 +19,8 @@ class CompatRuntimeModule extends RuntimeModule {
19
19
  * @returns {string} runtime code
20
20
  */
21
21
  generate() {
22
- const { chunk, compilation } = this;
22
+ const { chunkGraph, chunk, compilation } = this;
23
23
  const {
24
- chunkGraph,
25
24
  runtimeTemplate,
26
25
  mainTemplate,
27
26
  moduleTemplates,
@@ -39,6 +39,7 @@ class GetChunkFilenameRuntimeModule extends RuntimeModule {
39
39
  const {
40
40
  global,
41
41
  chunk,
42
+ chunkGraph,
42
43
  contentType,
43
44
  getFilenameForChunk,
44
45
  allChunks,
@@ -90,12 +91,12 @@ class GetChunkFilenameRuntimeModule extends RuntimeModule {
90
91
  for (const c of chunk.getAllAsyncChunks()) {
91
92
  addChunk(c);
92
93
  }
93
- const includeEntries = compilation.chunkGraph
94
+ const includeEntries = chunkGraph
94
95
  .getTreeRuntimeRequirements(chunk)
95
96
  .has(RuntimeGlobals.ensureChunkIncludeEntries);
96
97
  if (includeEntries) {
97
98
  includedChunksMessages.push("sibling chunks for the entrypoint");
98
- for (const c of compilation.chunkGraph.getChunkEntryDependentChunksIterable(
99
+ for (const c of chunkGraph.getChunkEntryDependentChunksIterable(
99
100
  chunk
100
101
  )) {
101
102
  addChunk(c);
@@ -8,20 +8,20 @@ const RuntimeGlobals = require("../RuntimeGlobals");
8
8
  const RuntimeModule = require("../RuntimeModule");
9
9
 
10
10
  class PublicPathRuntimeModule extends RuntimeModule {
11
- constructor() {
11
+ constructor(publicPath) {
12
12
  super("publicPath", RuntimeModule.STAGE_BASIC);
13
+ this.publicPath = publicPath;
13
14
  }
14
15
 
15
16
  /**
16
17
  * @returns {string} runtime code
17
18
  */
18
19
  generate() {
19
- const { compilation } = this;
20
- const { publicPath } = compilation.outputOptions;
20
+ const { compilation, publicPath } = this;
21
21
 
22
22
  return `${RuntimeGlobals.publicPath} = ${JSON.stringify(
23
- this.compilation.getPath(publicPath || "", {
24
- hash: this.compilation.hash || "XXXX"
23
+ compilation.getPath(publicPath || "", {
24
+ hash: compilation.hash || "XXXX"
25
25
  })
26
26
  )};`;
27
27
  }
@@ -16,8 +16,7 @@ class RuntimeIdRuntimeModule extends RuntimeModule {
16
16
  * @returns {string} runtime code
17
17
  */
18
18
  generate() {
19
- const { chunk, compilation } = this;
20
- const { chunkGraph } = compilation;
19
+ const { chunkGraph, chunk } = this;
21
20
  const runtime = chunk.runtime;
22
21
  if (typeof runtime !== "string")
23
22
  throw new Error("RuntimeIdRuntimeModule must be in a single runtime");
@@ -32,14 +32,16 @@ class StartupChunkDependenciesPlugin {
32
32
  const isEnabledForChunk = chunk => {
33
33
  const options = chunk.getEntryOptions();
34
34
  const chunkLoading =
35
- (options && options.chunkLoading) || globalChunkLoading;
35
+ options && options.chunkLoading !== undefined
36
+ ? options.chunkLoading
37
+ : globalChunkLoading;
36
38
  return chunkLoading === this.chunkLoading;
37
39
  };
38
40
  compilation.hooks.additionalTreeRuntimeRequirements.tap(
39
41
  "StartupChunkDependenciesPlugin",
40
- (chunk, set) => {
42
+ (chunk, set, { chunkGraph }) => {
41
43
  if (!isEnabledForChunk(chunk)) return;
42
- if (compilation.chunkGraph.hasChunkEntryDependentChunks(chunk)) {
44
+ if (chunkGraph.hasChunkEntryDependentChunks(chunk)) {
43
45
  set.add(RuntimeGlobals.startup);
44
46
  set.add(RuntimeGlobals.ensureChunk);
45
47
  set.add(RuntimeGlobals.ensureChunkIncludeEntries);
@@ -19,8 +19,8 @@ class StartupChunkDependenciesRuntimeModule extends RuntimeModule {
19
19
  * @returns {string} runtime code
20
20
  */
21
21
  generate() {
22
- const { chunk, compilation } = this;
23
- const { chunkGraph, runtimeTemplate } = compilation;
22
+ const { chunkGraph, chunk, compilation } = this;
23
+ const { runtimeTemplate } = compilation;
24
24
  const chunkIds = Array.from(
25
25
  chunkGraph.getChunkEntryDependentChunksIterable(chunk)
26
26
  ).map(chunk => {
@@ -386,6 +386,9 @@ class ObjectMiddleware extends SerializerMiddleware {
386
386
  throw e;
387
387
  }
388
388
  },
389
+ setCircularReference(ref) {
390
+ addReferenceable(ref);
391
+ },
389
392
  snapshot() {
390
393
  return {
391
394
  length: result.length,
@@ -442,7 +445,9 @@ class ObjectMiddleware extends SerializerMiddleware {
442
445
  }
443
446
 
444
447
  if (cycleStack.has(item)) {
445
- throw new Error(`Circular references can't be serialized`);
448
+ throw new Error(
449
+ `This is a circular references. To serialize circular references use 'setCircularReference' somewhere in the circle during serialize and deserialize.`
450
+ );
446
451
  }
447
452
 
448
453
  const { request, name, serializer } = ObjectMiddleware.getSerializerFor(
@@ -568,6 +573,9 @@ class ObjectMiddleware extends SerializerMiddleware {
568
573
  read() {
569
574
  return decodeValue();
570
575
  },
576
+ setCircularReference(ref) {
577
+ addReferenceable(ref);
578
+ },
571
579
  ...context
572
580
  };
573
581
  this.extendContext(ctx);
@@ -585,14 +593,15 @@ class ObjectMiddleware extends SerializerMiddleware {
585
593
  throw new Error(
586
594
  `Unexpected end of object at position ${currentDataPos - 1}`
587
595
  );
588
- } else if (typeof nextItem === "number" && nextItem < 0) {
589
- // relative reference
590
- return referenceable[currentPos + nextItem];
591
596
  } else {
592
597
  const request = nextItem;
593
598
  let serializer;
594
599
 
595
600
  if (typeof request === "number") {
601
+ if (request < 0) {
602
+ // relative reference
603
+ return referenceable[currentPos + request];
604
+ }
596
605
  serializer = objectTypeLookup[currentPosTypeLookup - request];
597
606
  } else {
598
607
  if (typeof request !== "string") {
@@ -30,11 +30,8 @@ class ConsumeSharedRuntimeModule extends RuntimeModule {
30
30
  * @returns {string} runtime code
31
31
  */
32
32
  generate() {
33
- const {
34
- runtimeTemplate,
35
- chunkGraph,
36
- codeGenerationResults
37
- } = this.compilation;
33
+ const { compilation, chunkGraph } = this;
34
+ const { runtimeTemplate, codeGenerationResults } = compilation;
38
35
  const chunkToModuleMapping = {};
39
36
  /** @type {Map<string | number, Source>} */
40
37
  const moduleIdToSourceMapping = new Map();
@@ -22,12 +22,12 @@ class ShareRuntimeModule extends RuntimeModule {
22
22
  * @returns {string} runtime code
23
23
  */
24
24
  generate() {
25
+ const { compilation, chunkGraph } = this;
25
26
  const {
26
27
  runtimeTemplate,
27
- chunkGraph,
28
28
  codeGenerationResults,
29
29
  outputOptions: { uniqueName }
30
- } = this.compilation;
30
+ } = compilation;
31
31
  /** @type {Map<string, Map<number, Set<string>>>} */
32
32
  const initCodePerScope = new Map();
33
33
  for (const chunk of this.chunk.getAllReferencedChunks()) {
@@ -148,6 +148,7 @@ const { makePathsRelative, parseResource } = require("../util/identifier");
148
148
  * @property {boolean=} cacheable
149
149
  * @property {boolean=} built
150
150
  * @property {boolean=} codeGenerated
151
+ * @property {boolean=} buildTimeExecuted
151
152
  * @property {boolean=} cached
152
153
  * @property {boolean=} optional
153
154
  * @property {boolean=} orphan
@@ -1077,6 +1078,9 @@ const SIMPLE_EXTRACTORS = {
1077
1078
  const { compilation, type } = context;
1078
1079
  const built = compilation.builtModules.has(module);
1079
1080
  const codeGenerated = compilation.codeGeneratedModules.has(module);
1081
+ const buildTimeExecuted = compilation.buildTimeExecutedModules.has(
1082
+ module
1083
+ );
1080
1084
  /** @type {{[x: string]: number}} */
1081
1085
  const sizes = {};
1082
1086
  for (const sourceType of module.getSourceTypes()) {
@@ -1091,6 +1095,7 @@ const SIMPLE_EXTRACTORS = {
1091
1095
  sizes,
1092
1096
  built,
1093
1097
  codeGenerated,
1098
+ buildTimeExecuted,
1094
1099
  cached: !built && !codeGenerated
1095
1100
  };
1096
1101
  Object.assign(object, statsModule);
@@ -306,6 +306,8 @@ const SIMPLE_PRINTERS = {
306
306
  built ? yellow(formatFlag("built")) : undefined,
307
307
  "module.codeGenerated": (codeGenerated, { formatFlag, yellow }) =>
308
308
  codeGenerated ? yellow(formatFlag("code generated")) : undefined,
309
+ "module.buildTimeExecuted": (buildTimeExecuted, { formatFlag, green }) =>
310
+ buildTimeExecuted ? green(formatFlag("build time executed")) : undefined,
309
311
  "module.cached": (cached, { formatFlag, green }) =>
310
312
  cached ? green(formatFlag("cached")) : undefined,
311
313
  "module.assets": (assets, { formatFlag, magenta }) =>
@@ -6,6 +6,8 @@
6
6
  "use strict";
7
7
 
8
8
  const { SyncHook, AsyncSeriesHook } = require("tapable");
9
+ const { makeWebpackError } = require("../HookWebpackError");
10
+ const WebpackError = require("../WebpackError");
9
11
  const ArrayQueue = require("./ArrayQueue");
10
12
 
11
13
  const QUEUED_STATE = 0;
@@ -17,7 +19,7 @@ let inHandleResult = 0;
17
19
  /**
18
20
  * @template T
19
21
  * @callback Callback
20
- * @param {Error=} err
22
+ * @param {WebpackError=} err
21
23
  * @param {T=} result
22
24
  */
23
25
 
@@ -39,6 +41,7 @@ class AsyncQueueEntry {
39
41
  /** @type {Callback<R>[] | undefined} */
40
42
  this.callbacks = undefined;
41
43
  this.result = undefined;
44
+ /** @type {WebpackError | undefined} */
42
45
  this.error = undefined;
43
46
  }
44
47
  }
@@ -99,15 +102,17 @@ class AsyncQueue {
99
102
  }
100
103
 
101
104
  /**
102
- * @param {T} item a item
105
+ * @param {T} item an item
103
106
  * @param {Callback<R>} callback callback function
104
107
  * @returns {void}
105
108
  */
106
109
  add(item, callback) {
107
- if (this._stopped) return callback(new Error("Queue was stopped"));
110
+ if (this._stopped) return callback(new WebpackError("Queue was stopped"));
108
111
  this.hooks.beforeAdd.callAsync(item, err => {
109
112
  if (err) {
110
- callback(err);
113
+ callback(
114
+ makeWebpackError(err, `AsyncQueue(${this._name}).hooks.beforeAdd`)
115
+ );
111
116
  return;
112
117
  }
113
118
  const key = this._getKey(item);
@@ -127,7 +132,7 @@ class AsyncQueue {
127
132
  this.hooks.added.call(item);
128
133
  this._root._activeTasks++;
129
134
  process.nextTick(() =>
130
- this._handleResult(newEntry, new Error("Queue was stopped"))
135
+ this._handleResult(newEntry, new WebpackError("Queue was stopped"))
131
136
  );
132
137
  } else {
133
138
  this._entries.set(key, newEntry);
@@ -144,7 +149,7 @@ class AsyncQueue {
144
149
  }
145
150
 
146
151
  /**
147
- * @param {T} item a item
152
+ * @param {T} item an item
148
153
  * @returns {void}
149
154
  */
150
155
  invalidate(item) {
@@ -156,6 +161,31 @@ class AsyncQueue {
156
161
  }
157
162
  }
158
163
 
164
+ /**
165
+ * Waits for an already started item
166
+ * @param {T} item an item
167
+ * @param {Callback<R>} callback callback function
168
+ * @returns {void}
169
+ */
170
+ waitFor(item, callback) {
171
+ const key = this._getKey(item);
172
+ const entry = this._entries.get(key);
173
+ if (entry === undefined) {
174
+ return callback(
175
+ new WebpackError(
176
+ "waitFor can only be called for an already started item"
177
+ )
178
+ );
179
+ }
180
+ if (entry.state === DONE_STATE) {
181
+ process.nextTick(() => callback(entry.error, entry.result));
182
+ } else if (entry.callbacks === undefined) {
183
+ entry.callbacks = [callback];
184
+ } else {
185
+ entry.callbacks.push(callback);
186
+ }
187
+ }
188
+
159
189
  /**
160
190
  * @returns {void}
161
191
  */
@@ -167,7 +197,7 @@ class AsyncQueue {
167
197
  for (const entry of queue) {
168
198
  this._entries.delete(this._getKey(entry.item));
169
199
  root._activeTasks++;
170
- this._handleResult(entry, new Error("Queue was stopped"));
200
+ this._handleResult(entry, new WebpackError("Queue was stopped"));
171
201
  }
172
202
  }
173
203
 
@@ -257,7 +287,10 @@ class AsyncQueue {
257
287
  _startProcessing(entry) {
258
288
  this.hooks.beforeStart.callAsync(entry.item, err => {
259
289
  if (err) {
260
- this._handleResult(entry, err);
290
+ this._handleResult(
291
+ entry,
292
+ makeWebpackError(err, `AsyncQueue(${this._name}).hooks.beforeStart`)
293
+ );
261
294
  return;
262
295
  }
263
296
  let inCallback = false;
@@ -276,13 +309,15 @@ class AsyncQueue {
276
309
 
277
310
  /**
278
311
  * @param {AsyncQueueEntry<T, K, R>} entry the entry
279
- * @param {Error=} err error, if any
312
+ * @param {WebpackError=} err error, if any
280
313
  * @param {R=} result result, if any
281
314
  * @returns {void}
282
315
  */
283
316
  _handleResult(entry, err, result) {
284
317
  this.hooks.result.callAsync(entry.item, err, result, hookError => {
285
- const error = hookError || err;
318
+ const error = hookError
319
+ ? makeWebpackError(hookError, `AsyncQueue(${this._name}).hooks.result`)
320
+ : err;
286
321
 
287
322
  const callback = entry.callback;
288
323
  const callbacks = entry.callbacks;