webpack 5.110.0 → 5.110.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1207,6 +1207,15 @@ const getManagedItem = (managedPath, path) => {
1207
1207
  return path.slice(0, i);
1208
1208
  };
1209
1209
 
1210
+ /**
1211
+ * The managed directory a `snapshot.managedPaths` RegExp matched. The schema
1212
+ * documents it as matching that directory, so a capture-less pattern is it.
1213
+ * @param {RegExpExecArray} match a match of a managed path RegExp
1214
+ * @returns {string} the managed directory
1215
+ */
1216
+ const getManagedPathFromMatch = (match) =>
1217
+ match[1] === undefined ? match[0] : match[1];
1218
+
1210
1219
  /**
1211
1220
  * Gets resolved timestamp.
1212
1221
  * @template {ContextFileSystemInfoEntry | ContextTimestampAndHash} T
@@ -2663,7 +2672,10 @@ class FileSystemInfo {
2663
2672
  for (const managedPath of this.managedPathsRegExps) {
2664
2673
  const match = managedPath.exec(path);
2665
2674
  if (match) {
2666
- const managedItem = getManagedItem(match[1], path);
2675
+ const managedItem = getManagedItem(
2676
+ getManagedPathFromMatch(match),
2677
+ path
2678
+ );
2667
2679
  if (managedItem) {
2668
2680
  classificationCache.set(path, managedItem);
2669
2681
  managedItems.add(managedItem);
@@ -3921,7 +3933,10 @@ class FileSystemInfo {
3921
3933
  for (const managedPath of this.managedPathsRegExps) {
3922
3934
  const match = managedPath.exec(path);
3923
3935
  if (match) {
3924
- const managedItem = getManagedItem(match[1], path);
3936
+ const managedItem = getManagedItem(
3937
+ getManagedPathFromMatch(match),
3938
+ path
3939
+ );
3925
3940
  if (managedItem) {
3926
3941
  // construct timestampHash from managed info
3927
3942
  return this.managedItemQueue.add(managedItem, (err, info) => {
package/lib/Generator.js CHANGED
@@ -6,6 +6,7 @@
6
6
  "use strict";
7
7
 
8
8
  const { JAVASCRIPT_TYPE } = require("./ModuleSourceTypeConstants");
9
+ const memoize = require("./util/memoize");
9
10
 
10
11
  /** @import { Source } from "webpack-sources" */
11
12
  /** @import ChunkGraph from "./ChunkGraph" */
@@ -60,6 +61,8 @@ const { JAVASCRIPT_TYPE } = require("./ModuleSourceTypeConstants");
60
61
  * @property {RuntimeTemplate=} runtimeTemplate
61
62
  */
62
63
 
64
+ const getModuleParseError = memoize(() => require("./errors/ModuleParseError"));
65
+
63
66
  class Generator {
64
67
  /**
65
68
  * Returns generator by type.
@@ -70,6 +73,20 @@ class Generator {
70
73
  return new ByTypeGenerator(map);
71
74
  }
72
75
 
76
+ /**
77
+ * Returns the statement a module that failed to build throws when executed.
78
+ * @param {Error} error the build error
79
+ * @param {string=} parseErrorConstructor constructor for a rejected source, defaults to `SyntaxError` (WebAssembly rejects with `WebAssembly.CompileError` instead)
80
+ * @returns {string} javascript statement
81
+ */
82
+ static throwBuildErrorCode(error, parseErrorConstructor = "SyntaxError") {
83
+ // A source the parser rejected throws what a native load of it would.
84
+ const name =
85
+ error instanceof getModuleParseError() ? parseErrorConstructor : "Error";
86
+
87
+ return `throw new ${name}(${JSON.stringify(error.message)});`;
88
+ }
89
+
73
90
  /* istanbul ignore next */
74
91
  /**
75
92
  * Returns the source types available for this module.
@@ -55,6 +55,8 @@ const parseJson = require("./util/parseJson");
55
55
 
56
56
  const getValidate = memoize(() => require("schema-utils").validate);
57
57
 
58
+ const getGenerator = memoize(() => require("./Generator"));
59
+
58
60
  const getExtractSourceMap = memoize(() => require("./util/extractSourceMap"));
59
61
 
60
62
  const getInvalidDependenciesModuleWarning = memoize(() =>
@@ -1913,9 +1915,7 @@ class NormalModule extends Module {
1913
1915
  getData,
1914
1916
  type
1915
1917
  })
1916
- : new RawSource(
1917
- `throw new Error(${JSON.stringify(this.error.message)});`
1918
- )
1918
+ : new RawSource(getGenerator().throwBuildErrorCode(this.error))
1919
1919
  : generator.generate(this, {
1920
1920
  dependencyTemplates,
1921
1921
  runtimeTemplate,
@@ -114,9 +114,7 @@ class AssetBytesGenerator extends Generator {
114
114
  generateError(error, module, generateContext) {
115
115
  switch (generateContext.type) {
116
116
  case JAVASCRIPT_TYPE: {
117
- return new RawSource(
118
- `throw new Error(${JSON.stringify(error.message)});`
119
- );
117
+ return new RawSource(Generator.throwBuildErrorCode(error));
120
118
  }
121
119
  default:
122
120
  return null;
@@ -777,9 +777,7 @@ class AssetGenerator extends Generator {
777
777
  return new RawSource(error.message);
778
778
  }
779
779
  case JAVASCRIPT_TYPE: {
780
- return new RawSource(
781
- `throw new Error(${JSON.stringify(error.message)});`
782
- );
780
+ return new RawSource(Generator.throwBuildErrorCode(error));
783
781
  }
784
782
  default:
785
783
  return null;
@@ -158,9 +158,7 @@ class AssetSourceGenerator extends Generator {
158
158
  generateError(error, module, generateContext) {
159
159
  switch (generateContext.type) {
160
160
  case JAVASCRIPT_TYPE: {
161
- return new RawSource(
162
- `throw new Error(${JSON.stringify(error.message)});`
163
- );
161
+ return new RawSource(Generator.throwBuildErrorCode(error));
164
162
  }
165
163
  default:
166
164
  return null;
@@ -2464,6 +2464,12 @@ const applyOptimizationDefaults = (
2464
2464
  D(optimization, "portableRecords", records);
2465
2465
  D(optimization, "realContentHash", production);
2466
2466
  F(optimization, "minimize", () => (production ? {} : false));
2467
+ // A plugin can assign the `true` shorthand in `apply()`, which runs after
2468
+ // `getNormalizedOptimizationMinimize` and so never gets normalized. The
2469
+ // normalized type does not allow it, hence the cast.
2470
+ if (/** @type {unknown} */ (optimization.minimize) === true) {
2471
+ optimization.minimize = {};
2472
+ }
2467
2473
  const { minimize } = optimization;
2468
2474
  if (minimize) {
2469
2475
  // Canonicalize the object form: the JS minimizer's defaults become
@@ -617,9 +617,7 @@ class CssGenerator extends Generator {
617
617
  generateError(error, module, generateContext) {
618
618
  switch (generateContext.type) {
619
619
  case JAVASCRIPT_TYPE: {
620
- return new RawSource(
621
- `throw new Error(${JSON.stringify(error.message)});`
622
- );
620
+ return new RawSource(Generator.throwBuildErrorCode(error));
623
621
  }
624
622
  case CSS_TYPE: {
625
623
  return new RawSource(`/**\n ${error.message} \n**/`);
@@ -1648,7 +1648,7 @@ class HtmlGenerator extends Generator {
1648
1648
  .replace(/-{2,}/g, (m) => `${"-".repeat(m.length - 1)} `);
1649
1649
  return new RawSource(`<!-- webpack error: ${safe} -->`);
1650
1650
  }
1651
- return new RawSource(`throw new Error(${JSON.stringify(error.message)});`);
1651
+ return new RawSource(Generator.throwBuildErrorCode(error));
1652
1652
  }
1653
1653
 
1654
1654
  /**
@@ -332,7 +332,7 @@ class JavascriptGenerator extends Generator {
332
332
  * @returns {Source | null} generated code
333
333
  */
334
334
  generateError(error, module, generateContext) {
335
- return new RawSource(`throw new Error(${JSON.stringify(error.message)});`);
335
+ return new RawSource(Generator.throwBuildErrorCode(error));
336
336
  }
337
337
  }
338
338
 
@@ -259,7 +259,7 @@ class JsonGenerator extends Generator {
259
259
  * @returns {Source | null} generated code
260
260
  */
261
261
  generateError(error, module, generateContext) {
262
- return new RawSource(`throw new Error(${JSON.stringify(error.message)});`);
262
+ return new RawSource(Generator.throwBuildErrorCode(error));
263
263
  }
264
264
 
265
265
  /**
@@ -461,7 +461,7 @@ class ObjectMiddleware extends SerializerMiddleware {
461
461
  return buf;
462
462
  };
463
463
  let currentPosTypeLookup = 0;
464
- /** @type {Map<ComplexSerializableType, number>} */
464
+ /** @type {Map<SerializerConfigWithSerializer, number>} */
465
465
  let objectTypeLookup = new Map();
466
466
  /** @type {Set<ComplexSerializableType>} */
467
467
  const cycleStack = new Set();
@@ -573,140 +573,160 @@ class ObjectMiddleware extends SerializerMiddleware {
573
573
  ...context
574
574
  };
575
575
  this.extendContext(ctx);
576
+ // Dispatched on `typeof` first: two thirds of the items are numbers,
577
+ // booleans and `undefined`, and only 3% are buffers.
576
578
  /**
577
579
  * Processes the provided item.
578
580
  * @param {ComplexSerializableType} item item to serialize
579
581
  */
580
582
  const process = (item) => {
581
- if (Buffer.isBuffer(item)) {
582
- // check if we can emit a reference
583
- const ref = referenceable.get(item);
584
- if (ref !== undefined) {
585
- result.push(ESCAPE, ref - currentPos);
583
+ switch (typeof item) {
584
+ case "number":
585
+ case "boolean":
586
+ result.push(item);
586
587
  return;
587
- }
588
- const alreadyUsedBuffer = dedupeBuffer(item);
589
- if (alreadyUsedBuffer !== item) {
590
- const ref = referenceable.get(alreadyUsedBuffer);
591
- if (ref !== undefined) {
592
- referenceable.set(item, ref);
593
- result.push(ESCAPE, ref - currentPos);
594
- return;
588
+ case "string": {
589
+ if (item.length > 1) {
590
+ // short strings are shorter when not emitting a reference (this saves 1 byte per empty string)
591
+ // check if we can emit a reference
592
+ const ref = referenceable.get(item);
593
+ if (ref !== undefined) {
594
+ const offset = ref - currentPos;
595
+ if (
596
+ // One far ref → 5 bytes (`null` + offset), one near ref -> 2/3 bytes
597
+ offset >= -32768 ||
598
+ // long enough that the ref wins, keep it
599
+ item.length >= 4 ||
600
+ // multibyte → inline would be even bigger, keep it
601
+ Buffer.byteLength(item) !== item.length
602
+ ) {
603
+ // A back-reference is `null` + the offset.
604
+ result.push(ESCAPE, offset);
605
+ return;
606
+ }
607
+ }
608
+ addReferenceable(item);
595
609
  }
596
- item = alreadyUsedBuffer;
597
- }
598
- addReferenceable(item);
599
610
 
600
- result.push(/** @type {Buffer} */ (item));
601
- } else if (item === ESCAPE) {
602
- result.push(ESCAPE, ESCAPE_ESCAPE_VALUE);
603
- } else if (
604
- typeof item === "object"
605
- // We don't have to check for null as ESCAPE is null and this has been checked before
606
- ) {
607
- // check if we can emit a reference
608
- const ref = referenceable.get(item);
609
- if (ref !== undefined) {
610
- result.push(ESCAPE, ref - currentPos);
611
+ if (item.length > 102400 && context.logger) {
612
+ context.logger.warn(
613
+ `Serializing big strings (${Math.round(
614
+ item.length / 1024
615
+ )}kiB) impacts deserialization performance (consider using Buffer instead and decode when needed)`
616
+ );
617
+ }
618
+
619
+ result.push(item);
611
620
  return;
612
621
  }
622
+ case "undefined":
623
+ result.push(ESCAPE, ESCAPE_UNDEFINED);
624
+ return;
625
+ case "object": {
626
+ // ESCAPE is null, so this covers null too
627
+ if (item === ESCAPE) {
628
+ result.push(ESCAPE, ESCAPE_ESCAPE_VALUE);
629
+ return;
630
+ }
613
631
 
614
- if (cycleStack.has(item)) {
615
- throw new Error(
616
- "This is a circular references. To serialize circular references use 'setCircularReference' somewhere in the circle during serialize and deserialize."
617
- );
618
- }
632
+ if (Buffer.isBuffer(item)) {
633
+ // check if we can emit a reference
634
+ const ref = referenceable.get(item);
635
+ if (ref !== undefined) {
636
+ result.push(ESCAPE, ref - currentPos);
637
+ return;
638
+ }
639
+ const alreadyUsedBuffer = dedupeBuffer(item);
640
+ if (alreadyUsedBuffer !== item) {
641
+ const ref = referenceable.get(alreadyUsedBuffer);
642
+ if (ref !== undefined) {
643
+ referenceable.set(item, ref);
644
+ result.push(ESCAPE, ref - currentPos);
645
+ return;
646
+ }
647
+ item = alreadyUsedBuffer;
648
+ }
649
+ addReferenceable(item);
619
650
 
620
- const { request, name, serializer } = ObjectMiddleware.getSerializerFor(
621
- /** @type {Constructor} */
622
- (item)
623
- );
624
- const key = `${request}/${name}`;
625
- const lastIndex = objectTypeLookup.get(key);
651
+ result.push(/** @type {Buffer} */ (item));
652
+ return;
653
+ }
626
654
 
627
- if (lastIndex === undefined) {
628
- objectTypeLookup.set(key, currentPosTypeLookup++);
655
+ // check if we can emit a reference
656
+ const ref = referenceable.get(item);
657
+ if (ref !== undefined) {
658
+ result.push(ESCAPE, ref - currentPos);
659
+ return;
660
+ }
629
661
 
630
- result.push(ESCAPE, request, name);
631
- } else {
632
- result.push(ESCAPE, currentPosTypeLookup - lastIndex);
633
- }
662
+ if (cycleStack.has(item)) {
663
+ throw new Error(
664
+ "This is a circular references. To serialize circular references use 'setCircularReference' somewhere in the circle during serialize and deserialize."
665
+ );
666
+ }
634
667
 
635
- cycleStack.add(item);
668
+ // Keyed by the registration itself: one per class, so it stands in for
669
+ // `${request}/${name}` without building that string per object.
670
+ const config = ObjectMiddleware.getSerializerFor(
671
+ /** @type {Constructor} */
672
+ (item)
673
+ );
674
+ const { request, name, serializer } = config;
675
+ const lastIndex = objectTypeLookup.get(config);
636
676
 
637
- try {
638
- serializer.serialize(item, ctx);
639
- } finally {
640
- cycleStack.delete(item);
641
- }
677
+ if (lastIndex === undefined) {
678
+ objectTypeLookup.set(config, currentPosTypeLookup++);
642
679
 
643
- result.push(ESCAPE, ESCAPE_END_OBJECT);
680
+ result.push(ESCAPE, request, name);
681
+ } else {
682
+ result.push(ESCAPE, currentPosTypeLookup - lastIndex);
683
+ }
644
684
 
645
- addReferenceable(item);
646
- } else if (typeof item === "string") {
647
- if (item.length > 1) {
648
- // short strings are shorter when not emitting a reference (this saves 1 byte per empty string)
649
- // check if we can emit a reference
650
- const ref = referenceable.get(item);
651
- if (ref !== undefined) {
652
- const offset = ref - currentPos;
653
- if (
654
- // One far ref → 5 bytes (`null` + offset), one near ref -> 2/3 bytes
655
- offset >= -32768 ||
656
- // long enough that the ref wins, keep it
657
- item.length >= 4 ||
658
- // multibyte → inline would be even bigger, keep it
659
- Buffer.byteLength(item) !== item.length
660
- ) {
661
- // A back-reference is `null` + the offset.
662
- result.push(ESCAPE, offset);
663
- return;
664
- }
685
+ cycleStack.add(item);
686
+
687
+ try {
688
+ serializer.serialize(item, ctx);
689
+ } finally {
690
+ cycleStack.delete(item);
665
691
  }
666
- addReferenceable(item);
667
- }
668
692
 
669
- if (item.length > 102400 && context.logger) {
670
- context.logger.warn(
671
- `Serializing big strings (${Math.round(
672
- item.length / 1024
673
- )}kiB) impacts deserialization performance (consider using Buffer instead and decode when needed)`
674
- );
675
- }
693
+ result.push(ESCAPE, ESCAPE_END_OBJECT);
676
694
 
677
- result.push(item);
678
- } else if (typeof item === "function") {
679
- if (!SerializerMiddleware.isLazy(item)) {
680
- throw new Error(`Unexpected function ${item}`);
695
+ addReferenceable(item);
696
+ return;
681
697
  }
698
+ case "function": {
699
+ if (!SerializerMiddleware.isLazy(item)) {
700
+ throw new Error(`Unexpected function ${item}`);
701
+ }
682
702
 
683
- /** @type {SerializedType | undefined} */
684
- const serializedData =
685
- SerializerMiddleware.getLazySerializedValue(item);
703
+ /** @type {SerializedType | undefined} */
704
+ const serializedData =
705
+ SerializerMiddleware.getLazySerializedValue(item);
686
706
 
687
- if (serializedData !== undefined) {
688
- if (typeof serializedData === "function") {
689
- result.push(serializedData);
690
- } else {
707
+ if (serializedData !== undefined) {
708
+ if (typeof serializedData === "function") {
709
+ result.push(serializedData);
710
+ } else {
711
+ throw new Error("Not implemented");
712
+ }
713
+ } else if (SerializerMiddleware.isLazy(item, this)) {
691
714
  throw new Error("Not implemented");
715
+ } else {
716
+ const data =
717
+ /** @type {() => PrimitiveSerializableType[] | Promise<PrimitiveSerializableType[]>} */
718
+ (
719
+ SerializerMiddleware.serializeLazy(item, (data) =>
720
+ this.serialize([data], context)
721
+ )
722
+ );
723
+ SerializerMiddleware.setLazySerializedValue(item, data);
724
+ result.push(data);
692
725
  }
693
- } else if (SerializerMiddleware.isLazy(item, this)) {
694
- throw new Error("Not implemented");
695
- } else {
696
- const data =
697
- /** @type {() => PrimitiveSerializableType[] | Promise<PrimitiveSerializableType[]>} */
698
- (
699
- SerializerMiddleware.serializeLazy(item, (data) =>
700
- this.serialize([data], context)
701
- )
702
- );
703
- SerializerMiddleware.setLazySerializedValue(item, data);
704
- result.push(data);
726
+ return;
705
727
  }
706
- } else if (item === undefined) {
707
- result.push(ESCAPE, ESCAPE_UNDEFINED);
708
- } else {
709
- result.push(item);
728
+ default:
729
+ result.push(item);
710
730
  }
711
731
  };
712
732
 
@@ -302,7 +302,9 @@ class AsyncWebAssemblyJavascriptGenerator extends Generator {
302
302
  * @returns {Source | null} generated code
303
303
  */
304
304
  generateError(error, module, generateContext) {
305
- return new RawSource(`throw new Error(${JSON.stringify(error.message)});`);
305
+ return new RawSource(
306
+ Generator.throwBuildErrorCode(error, "WebAssembly.CompileError")
307
+ );
306
308
  }
307
309
  }
308
310
 
@@ -231,7 +231,9 @@ class WebAssemblyJavascriptGenerator extends Generator {
231
231
  * @returns {Source | null} generated code
232
232
  */
233
233
  generateError(error, module, generateContext) {
234
- return new RawSource(`throw new Error(${JSON.stringify(error.message)});`);
234
+ return new RawSource(
235
+ Generator.throwBuildErrorCode(error, "WebAssembly.CompileError")
236
+ );
235
237
  }
236
238
  }
237
239
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webpack",
3
- "version": "5.110.0",
3
+ "version": "5.110.1",
4
4
  "description": "Packs ECMAScript/CommonJs/AMD modules for the browser. Allows you to split your codebase into multiple bundles, which can be loaded on demand. Supports loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.",
5
5
  "homepage": "https://github.com/webpack/webpack",
6
6
  "bugs": "https://github.com/webpack/webpack/issues",
package/types.d.ts CHANGED
@@ -9482,6 +9482,14 @@ declare class Generator {
9482
9482
  static byType(map: {
9483
9483
  [index: string]: undefined | Generator;
9484
9484
  }): ByTypeGenerator;
9485
+
9486
+ /**
9487
+ * Returns the statement a module that failed to build throws when executed.
9488
+ */
9489
+ static throwBuildErrorCode(
9490
+ error: Error,
9491
+ parseErrorConstructor?: string
9492
+ ): string;
9485
9493
  }
9486
9494
  declare interface GeneratorOptions {
9487
9495
  [index: string]: any;