webpack 5.81.0 → 5.82.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.

Potentially problematic release.


This version of webpack might be problematic. Click here for more details.

Files changed (62) hide show
  1. package/bin/webpack.js +13 -2
  2. package/lib/Compilation.js +4 -1
  3. package/lib/CssModule.js +39 -7
  4. package/lib/DependenciesBlock.js +8 -0
  5. package/lib/FileSystemInfo.js +1 -1
  6. package/lib/HotModuleReplacementPlugin.js +3 -2
  7. package/lib/Module.js +3 -2
  8. package/lib/ModuleTypeConstants.js +90 -0
  9. package/lib/NormalModule.js +2 -1
  10. package/lib/RuntimeModule.js +4 -3
  11. package/lib/Template.js +2 -1
  12. package/lib/WebpackOptionsApply.js +33 -40
  13. package/lib/asset/AssetGenerator.js +4 -3
  14. package/lib/asset/AssetModulesPlugin.js +21 -11
  15. package/lib/asset/RawDataUrlModule.js +2 -1
  16. package/lib/cache/MemoryWithGcCachePlugin.js +2 -0
  17. package/lib/config/defaults.js +4 -2
  18. package/lib/container/FallbackModule.js +2 -1
  19. package/lib/container/RemoteModule.js +2 -1
  20. package/lib/css/CssGenerator.js +4 -0
  21. package/lib/css/CssLoadingRuntimeModule.js +9 -2
  22. package/lib/css/CssModulesPlugin.js +149 -39
  23. package/lib/css/CssParser.js +443 -319
  24. package/lib/css/walkCssTokens.js +118 -27
  25. package/lib/debug/ProfilingPlugin.js +2 -0
  26. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +1 -0
  27. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +4 -2
  28. package/lib/hmr/LazyCompilationPlugin.js +13 -4
  29. package/lib/javascript/BasicEvaluatedExpression.js +108 -1
  30. package/lib/javascript/JavascriptModulesPlugin.js +3 -2
  31. package/lib/javascript/JavascriptParser.js +132 -11
  32. package/lib/json/JsonData.js +25 -0
  33. package/lib/json/JsonGenerator.js +15 -3
  34. package/lib/json/JsonModulesPlugin.js +1 -0
  35. package/lib/json/JsonParser.js +2 -1
  36. package/lib/library/ModuleLibraryPlugin.js +2 -1
  37. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +3 -1
  38. package/lib/runtime/GetChunkFilenameRuntimeModule.js +4 -0
  39. package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +22 -3
  40. package/lib/schemes/DataUriPlugin.js +4 -0
  41. package/lib/schemes/HttpUriPlugin.js +38 -0
  42. package/lib/sharing/ConsumeSharedModule.js +5 -2
  43. package/lib/sharing/ProvideSharedModule.js +2 -1
  44. package/lib/sharing/utils.js +293 -7
  45. package/lib/stats/DefaultStatsFactoryPlugin.js +7 -4
  46. package/lib/stats/DefaultStatsPrinterPlugin.js +25 -0
  47. package/lib/util/StackedCacheMap.js +6 -0
  48. package/lib/util/StringXor.js +51 -0
  49. package/lib/util/compileBooleanMatcher.js +31 -0
  50. package/lib/util/createHash.js +4 -3
  51. package/lib/util/deprecation.js +8 -0
  52. package/lib/util/identifier.js +4 -0
  53. package/lib/util/numberHash.js +75 -21
  54. package/lib/util/propertyAccess.js +5 -0
  55. package/lib/wasm/EnableWasmLoadingPlugin.js +4 -0
  56. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +1 -0
  57. package/lib/wasm-async/AsyncWebAssemblyParser.js +1 -1
  58. package/lib/web/JsonpChunkLoadingRuntimeModule.js +8 -4
  59. package/package.json +3 -3
  60. package/schemas/WebpackOptions.check.js +1 -1
  61. package/schemas/WebpackOptions.json +25 -0
  62. package/types.d.ts +181 -39
@@ -102,12 +102,46 @@ class VariableInfo {
102
102
  * @property {boolean} inTry
103
103
  */
104
104
 
105
+ /**
106
+ * Helper function for joining two ranges into a single range. This is useful
107
+ * when working with AST nodes, as it allows you to combine the ranges of child nodes
108
+ * to create the range of the _parent node_.
109
+ *
110
+ * @param {[number, number]} startRange start range to join
111
+ * @param {[number, number]} endRange end range to join
112
+ * @returns {[number, number]} joined range
113
+ *
114
+ * @example
115
+ * ```js
116
+ * const startRange = [0, 5];
117
+ * const endRange = [10, 15];
118
+ * const joinedRange = joinRanges(startRange, endRange);
119
+ * console.log(joinedRange); // [0, 15]
120
+ * ```
121
+ *
122
+ */
105
123
  const joinRanges = (startRange, endRange) => {
106
124
  if (!endRange) return startRange;
107
125
  if (!startRange) return endRange;
108
126
  return [startRange[0], endRange[1]];
109
127
  };
110
128
 
129
+ /**
130
+ * Helper function used to generate a string representation of a
131
+ * [member expression](https://github.com/estree/estree/blob/master/es5.md#memberexpression).
132
+ *
133
+ * @param {string} object object to name
134
+ * @param {string[]} membersReversed reversed list of members
135
+ * @returns {string} member expression as a string
136
+ * @example
137
+ * ```js
138
+ * const membersReversed = ["property1", "property2", "property3"]; // Members parsed from the AST
139
+ * const name = objectAndMembersToName("myObject", membersReversed);
140
+ *
141
+ * console.log(name); // "myObject.property1.property2.property3"
142
+ * ```
143
+ *
144
+ */
111
145
  const objectAndMembersToName = (object, membersReversed) => {
112
146
  let name = object;
113
147
  for (let i = membersReversed.length - 1; i >= 0; i--) {
@@ -116,6 +150,16 @@ const objectAndMembersToName = (object, membersReversed) => {
116
150
  return name;
117
151
  };
118
152
 
153
+ /**
154
+ * Grabs the name of a given expression and returns it as a string or undefined. Has particular
155
+ * handling for [Identifiers](https://github.com/estree/estree/blob/master/es5.md#identifier),
156
+ * [ThisExpressions](https://github.com/estree/estree/blob/master/es5.md#identifier), and
157
+ * [MetaProperties](https://github.com/estree/estree/blob/master/es2015.md#metaproperty) which is
158
+ * specifically for handling the `new.target` meta property.
159
+ *
160
+ * @param {ExpressionNode | SuperNode} expression expression
161
+ * @returns {string | "this" | undefined} name or variable info
162
+ */
119
163
  const getRootName = expression => {
120
164
  switch (expression.type) {
121
165
  case "Identifier":
@@ -469,6 +513,49 @@ class JavascriptParser extends Parser {
469
513
  }
470
514
  });
471
515
 
516
+ /**
517
+ * In simple logical cases, we can use valueAsExpression to assist us in evaluating the expression on
518
+ * either side of a [BinaryExpression](https://github.com/estree/estree/blob/master/es5.md#binaryexpression).
519
+ * This supports scenarios in webpack like conditionally `import()`'ing modules based on some simple evaluation:
520
+ *
521
+ * ```js
522
+ * if (1 === 3) {
523
+ * import("./moduleA"); // webpack will auto evaluate this and not import the modules
524
+ * }
525
+ * ```
526
+ *
527
+ * Additional scenarios include evaluation of strings inside of dynamic import statements:
528
+ *
529
+ * ```js
530
+ * const foo = "foo";
531
+ * const bar = "bar";
532
+ *
533
+ * import("./" + foo + bar); // webpack will auto evaluate this into import("./foobar")
534
+ * ```
535
+ * @param {boolean | number | BigInt | string} value the value to convert to an expression
536
+ * @param {BinaryExpressionNode | UnaryExpressionNode} expr the expression being evaluated
537
+ * @param {boolean} sideEffects whether the expression has side effects
538
+ * @returns {BasicEvaluatedExpression} the evaluated expression
539
+ * @example
540
+ *
541
+ * ```js
542
+ * const binaryExpr = new BinaryExpressionNode("+",
543
+ * { type: "Literal", value: 2 },
544
+ * { type: "Literal", value: 3 }
545
+ * );
546
+ *
547
+ * const leftValue = 2;
548
+ * const rightValue = 3;
549
+ *
550
+ * const leftExpr = valueAsExpression(leftValue, binaryExpr.left, false);
551
+ * const rightExpr = valueAsExpression(rightValue, binaryExpr.right, false);
552
+ * const result = new BasicEvaluatedExpression()
553
+ * .setNumber(leftExpr.number + rightExpr.number)
554
+ * .setRange(binaryExpr.range);
555
+ *
556
+ * console.log(result.number); // Output: 5
557
+ * ```
558
+ */
472
559
  const valueAsExpression = (value, expr, sideEffects) => {
473
560
  switch (typeof value) {
474
561
  case "boolean":
@@ -499,14 +586,21 @@ class JavascriptParser extends Parser {
499
586
  .tap("JavascriptParser", _expr => {
500
587
  const expr = /** @type {BinaryExpressionNode} */ (_expr);
501
588
 
502
- const handleConstOperation = fn => {
589
+ /**
590
+ * Evaluates a binary expression if and only if it is a const operation (e.g. 1 + 2, "a" + "b", etc.).
591
+ *
592
+ * @template T
593
+ * @param {(leftOperand: T, rightOperand: T) => boolean | number | BigInt | string} operandHandler the handler for the operation (e.g. (a, b) => a + b)
594
+ * @returns {BasicEvaluatedExpression | undefined} the evaluated expression
595
+ */
596
+ const handleConstOperation = operandHandler => {
503
597
  const left = this.evaluateExpression(expr.left);
504
598
  if (!left.isCompileTimeValue()) return;
505
599
 
506
600
  const right = this.evaluateExpression(expr.right);
507
601
  if (!right.isCompileTimeValue()) return;
508
602
 
509
- const result = fn(
603
+ const result = operandHandler(
510
604
  left.asCompileTimeValue(),
511
605
  right.asCompileTimeValue()
512
606
  );
@@ -517,6 +611,14 @@ class JavascriptParser extends Parser {
517
611
  );
518
612
  };
519
613
 
614
+ /**
615
+ * Helper function to determine if two booleans are always different. This is used in `handleStrictEqualityComparison`
616
+ * to determine if an expressions boolean or nullish conversion is equal or not.
617
+ *
618
+ * @param {boolean} a first boolean to compare
619
+ * @param {boolean} b second boolean to compare
620
+ * @returns {boolean} true if the two booleans are always different, false otherwise
621
+ */
520
622
  const isAlwaysDifferent = (a, b) =>
521
623
  (a === true && b === false) || (a === false && b === true);
522
624
 
@@ -545,11 +647,13 @@ class JavascriptParser extends Parser {
545
647
  const rightSuffix = getSuffix(right.parts);
546
648
  const lenPrefix = Math.min(leftPrefix.length, rightPrefix.length);
547
649
  const lenSuffix = Math.min(leftSuffix.length, rightSuffix.length);
548
- if (
549
- leftPrefix.slice(0, lenPrefix) !==
550
- rightPrefix.slice(0, lenPrefix) ||
551
- leftSuffix.slice(-lenSuffix) !== rightSuffix.slice(-lenSuffix)
552
- ) {
650
+ const prefixMismatch =
651
+ lenPrefix > 0 &&
652
+ leftPrefix.slice(0, lenPrefix) !== rightPrefix.slice(0, lenPrefix);
653
+ const suffixMismatch =
654
+ lenSuffix > 0 &&
655
+ leftSuffix.slice(-lenSuffix) !== rightSuffix.slice(-lenSuffix);
656
+ if (prefixMismatch || suffixMismatch) {
553
657
  return res
554
658
  .setBoolean(!eql)
555
659
  .setSideEffects(
@@ -558,6 +662,11 @@ class JavascriptParser extends Parser {
558
662
  }
559
663
  };
560
664
 
665
+ /**
666
+ * Helper function to handle BinaryExpressions using strict equality comparisons (e.g. "===" and "!==").
667
+ * @param {boolean} eql true for "===" and false for "!=="
668
+ * @returns {BasicEvaluatedExpression | undefined} the evaluated expression
669
+ */
561
670
  const handleStrictEqualityComparison = eql => {
562
671
  const left = this.evaluateExpression(expr.left);
563
672
  const right = this.evaluateExpression(expr.right);
@@ -611,6 +720,11 @@ class JavascriptParser extends Parser {
611
720
  }
612
721
  };
613
722
 
723
+ /**
724
+ * Helper function to handle BinaryExpressions using abstract equality comparisons (e.g. "==" and "!=").
725
+ * @param {boolean} eql true for "==" and false for "!="
726
+ * @returns {BasicEvaluatedExpression | undefined} the evaluated expression
727
+ */
614
728
  const handleAbstractEqualityComparison = eql => {
615
729
  const left = this.evaluateExpression(expr.left);
616
730
  const right = this.evaluateExpression(expr.right);
@@ -823,10 +937,17 @@ class JavascriptParser extends Parser {
823
937
  .tap("JavascriptParser", _expr => {
824
938
  const expr = /** @type {UnaryExpressionNode} */ (_expr);
825
939
 
826
- const handleConstOperation = fn => {
940
+ /**
941
+ * Evaluates a UnaryExpression if and only if it is a basic const operator (e.g. +a, -a, ~a).
942
+ *
943
+ * @template T
944
+ * @param {(operand: T) => boolean | number | BigInt | string} operandHandler handler for the operand
945
+ * @returns {BasicEvaluatedExpression | undefined} evaluated expression
946
+ */
947
+ const handleConstOperation = operandHandler => {
827
948
  const argument = this.evaluateExpression(expr.argument);
828
949
  if (!argument.isCompileTimeValue()) return;
829
- const result = fn(argument.asCompileTimeValue());
950
+ const result = operandHandler(argument.asCompileTimeValue());
830
951
  return valueAsExpression(
831
952
  result,
832
953
  expr,
@@ -1259,10 +1380,10 @@ class JavascriptParser extends Parser {
1259
1380
  : "" + argExpr.number;
1260
1381
 
1261
1382
  const newString = value + (stringSuffix ? stringSuffix.string : "");
1262
- const newRange = [
1383
+ const newRange = /** @type {[number, number]} */ ([
1263
1384
  argExpr.range[0],
1264
1385
  (stringSuffix || argExpr).range[1]
1265
- ];
1386
+ ]);
1266
1387
  stringSuffix = new BasicEvaluatedExpression()
1267
1388
  .setString(newString)
1268
1389
  .setSideEffects(
@@ -7,9 +7,19 @@
7
7
 
8
8
  const { register } = require("../util/serialization");
9
9
 
10
+ /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
11
+ /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
12
+ /** @typedef {import("../util/Hash")} Hash */
13
+ /** @typedef {import("./JsonModulesPlugin").RawJsonData} RawJsonData */
14
+
10
15
  class JsonData {
16
+ /**
17
+ * @param {Buffer | RawJsonData} data JSON data
18
+ */
11
19
  constructor(data) {
20
+ /** @type {Buffer | undefined} */
12
21
  this._buffer = undefined;
22
+ /** @type {RawJsonData | undefined} */
13
23
  this._data = undefined;
14
24
  if (Buffer.isBuffer(data)) {
15
25
  this._buffer = data;
@@ -18,6 +28,9 @@ class JsonData {
18
28
  }
19
29
  }
20
30
 
31
+ /**
32
+ * @returns {RawJsonData|undefined} Raw JSON data
33
+ */
21
34
  get() {
22
35
  if (this._data === undefined && this._buffer !== undefined) {
23
36
  this._data = JSON.parse(this._buffer.toString());
@@ -25,6 +38,10 @@ class JsonData {
25
38
  return this._data;
26
39
  }
27
40
 
41
+ /**
42
+ * @param {Hash} hash hash to be updated
43
+ * @returns {Hash} the updated hash
44
+ */
28
45
  updateHash(hash) {
29
46
  if (this._buffer === undefined && this._data !== undefined) {
30
47
  this._buffer = Buffer.from(JSON.stringify(this._data));
@@ -35,12 +52,20 @@ class JsonData {
35
52
  }
36
53
 
37
54
  register(JsonData, "webpack/lib/json/JsonData", null, {
55
+ /**
56
+ * @param {JsonData} obj JSONData object
57
+ * @param {ObjectSerializerContext} context context
58
+ */
38
59
  serialize(obj, { write }) {
39
60
  if (obj._buffer === undefined && obj._data !== undefined) {
40
61
  obj._buffer = Buffer.from(JSON.stringify(obj._data));
41
62
  }
42
63
  write(obj._buffer);
43
64
  },
65
+ /**
66
+ * @param {ObjectDeserializerContext} context context
67
+ * @returns {JsonData} deserialized JSON data
68
+ */
44
69
  deserialize({ read }) {
45
70
  return new JsonData(read());
46
71
  }
@@ -17,7 +17,13 @@ const RuntimeGlobals = require("../RuntimeGlobals");
17
17
  /** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
18
18
  /** @typedef {import("../NormalModule")} NormalModule */
19
19
  /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
20
+ /** @typedef {import("./JsonData")} JsonData */
21
+ /** @typedef {import("./JsonModulesPlugin").RawJsonData} RawJsonData */
20
22
 
23
+ /**
24
+ * @param {RawJsonData} data Raw JSON data
25
+ * @returns {undefined|string} stringified data
26
+ */
21
27
  const stringifySafe = data => {
22
28
  const stringified = JSON.stringify(data);
23
29
  if (!stringified) {
@@ -30,10 +36,10 @@ const stringifySafe = data => {
30
36
  };
31
37
 
32
38
  /**
33
- * @param {Object} data data (always an object or array)
39
+ * @param {RawJsonData} data Raw JSON data (always an object or array)
34
40
  * @param {ExportsInfo} exportsInfo exports info
35
41
  * @param {RuntimeSpec} runtime the runtime
36
- * @returns {Object} reduced data
42
+ * @returns {RawJsonData} reduced data
37
43
  */
38
44
  const createObjectForExportsInfo = (data, exportsInfo, runtime) => {
39
45
  if (exportsInfo.otherExportsInfo.getUsed(runtime) !== UsageState.Unused)
@@ -45,6 +51,7 @@ const createObjectForExportsInfo = (data, exportsInfo, runtime) => {
45
51
  const used = exportInfo.getUsed(runtime);
46
52
  if (used === UsageState.Unused) continue;
47
53
 
54
+ /** @type {any} */
48
55
  let value;
49
56
  if (used === UsageState.OnlyPropertiesUsed && exportInfo.exportsInfo) {
50
57
  value = createObjectForExportsInfo(
@@ -86,6 +93,7 @@ const createObjectForExportsInfo = (data, exportsInfo, runtime) => {
86
93
  : { length: arrayLengthWhenUsed },
87
94
  reducedData
88
95
  );
96
+ /** @type {number} */
89
97
  const generatedLength =
90
98
  arrayLengthWhenUsed !== undefined
91
99
  ? Math.max(arrayLengthWhenUsed, reducedData.length)
@@ -116,7 +124,8 @@ class JsonGenerator extends Generator {
116
124
  * @returns {number} estimate size of the module
117
125
  */
118
126
  getSize(module, type) {
119
- let data =
127
+ /** @type {RawJsonData | undefined} */
128
+ const data =
120
129
  module.buildInfo &&
121
130
  module.buildInfo.jsonData &&
122
131
  module.buildInfo.jsonData.get();
@@ -148,6 +157,7 @@ class JsonGenerator extends Generator {
148
157
  concatenationScope
149
158
  }
150
159
  ) {
160
+ /** @type {RawJsonData | undefined} */
151
161
  const data =
152
162
  module.buildInfo &&
153
163
  module.buildInfo.jsonData &&
@@ -160,6 +170,7 @@ class JsonGenerator extends Generator {
160
170
  );
161
171
  }
162
172
  const exportsInfo = moduleGraph.getExportsInfo(module);
173
+ /** @type {RawJsonData} */
163
174
  let finalJson =
164
175
  typeof data === "object" &&
165
176
  data &&
@@ -172,6 +183,7 @@ class JsonGenerator extends Generator {
172
183
  jsonStr.length > 20 && typeof finalJson === "object"
173
184
  ? `JSON.parse('${jsonStr.replace(/[\\']/g, "\\$&")}')`
174
185
  : jsonStr;
186
+ /** @type {string} */
175
187
  let content;
176
188
  if (concatenationScope) {
177
189
  content = `${runtimeTemplate.supportsConst() ? "const" : "var"} ${
@@ -11,6 +11,7 @@ const JsonGenerator = require("./JsonGenerator");
11
11
  const JsonParser = require("./JsonParser");
12
12
 
13
13
  /** @typedef {import("../Compiler")} Compiler */
14
+ /** @typedef {Record<string, any>} RawJsonData */
14
15
 
15
16
  const validate = createSchemaValidation(
16
17
  require("../../schemas/plugins/JsonModulesPluginParser.check.js"),
@@ -13,6 +13,7 @@ const JsonData = require("./JsonData");
13
13
  /** @typedef {import("../../declarations/plugins/JsonModulesPluginParser").JsonModulesPluginParserOptions} JsonModulesPluginParserOptions */
14
14
  /** @typedef {import("../Parser").ParserState} ParserState */
15
15
  /** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
16
+ /** @typedef {import("./JsonModulesPlugin").RawJsonData} RawJsonData */
16
17
 
17
18
  class JsonParser extends Parser {
18
19
  /**
@@ -36,7 +37,7 @@ class JsonParser extends Parser {
36
37
  /** @type {JsonModulesPluginParserOptions["parse"]} */
37
38
  const parseFn =
38
39
  typeof this.options.parse === "function" ? this.options.parse : parseJson;
39
-
40
+ /** @type {Buffer | RawJsonData} */
40
41
  const data =
41
42
  typeof source === "object"
42
43
  ? source
@@ -89,7 +89,8 @@ class ModuleLibraryPlugin extends AbstractLibraryPlugin {
89
89
  )}`;
90
90
  result.add(
91
91
  `var ${varName} = __webpack_exports__${propertyAccess([
92
- exportInfo.getUsedName(exportInfo.name, chunk.runtime)
92
+ /** @type {string} */
93
+ (exportInfo.getUsedName(exportInfo.name, chunk.runtime))
93
94
  ])};\n`
94
95
  );
95
96
  exports.push(`${varName} as ${exportInfo.name}`);
@@ -178,7 +178,9 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule {
178
178
  "});",
179
179
  "promises.push(installedChunkData[2] = promise);"
180
180
  ]),
181
- "} else installedChunks[chunkId] = 0;"
181
+ hasJsMatcher === true
182
+ ? "}"
183
+ : "} else installedChunks[chunkId] = 0;"
182
184
  ]),
183
185
  "}"
184
186
  ]),
@@ -132,6 +132,10 @@ class GetChunkFilenameRuntimeModule extends RuntimeModule {
132
132
  const s = JSON.stringify(str);
133
133
  return s.slice(1, s.length - 1);
134
134
  };
135
+ /**
136
+ * @param {string} value string
137
+ * @returns {function(number): string} string to put in quotes with length
138
+ */
135
139
  const unquotedStringifyWithLength = value => length =>
136
140
  unquotedStringify(`${value}`.slice(0, length));
137
141
  const chunkFilenameValue =
@@ -25,6 +25,9 @@ class GetTrustedTypesPolicyRuntimeModule extends HelperRuntimeModule {
25
25
  const { runtimeTemplate, outputOptions } = compilation;
26
26
  const { trustedTypes } = outputOptions;
27
27
  const fn = RuntimeGlobals.getTrustedTypesPolicy;
28
+ const wrapPolicyCreationInTryCatch = trustedTypes
29
+ ? trustedTypes.onPolicyCreationFailure === "continue"
30
+ : false;
28
31
 
29
32
  return Template.asString([
30
33
  "var policy;",
@@ -58,9 +61,25 @@ class GetTrustedTypesPolicyRuntimeModule extends HelperRuntimeModule {
58
61
  ? [
59
62
  'if (typeof trustedTypes !== "undefined" && trustedTypes.createPolicy) {',
60
63
  Template.indent([
61
- `policy = trustedTypes.createPolicy(${JSON.stringify(
62
- trustedTypes.policyName
63
- )}, policy);`
64
+ ...(wrapPolicyCreationInTryCatch ? ["try {"] : []),
65
+ ...[
66
+ `policy = trustedTypes.createPolicy(${JSON.stringify(
67
+ trustedTypes.policyName
68
+ )}, policy);`
69
+ ].map(line =>
70
+ wrapPolicyCreationInTryCatch ? Template.indent(line) : line
71
+ ),
72
+ ...(wrapPolicyCreationInTryCatch
73
+ ? [
74
+ "} catch (e) {",
75
+ Template.indent([
76
+ `console.warn('Could not create trusted-types policy ${JSON.stringify(
77
+ trustedTypes.policyName
78
+ )}');`
79
+ ]),
80
+ "}"
81
+ ]
82
+ : [])
64
83
  ]),
65
84
  "}"
66
85
  ]
@@ -13,6 +13,10 @@ const NormalModule = require("../NormalModule");
13
13
  // http://www.ietf.org/rfc/rfc2397.txt
14
14
  const URIRegEx = /^data:([^;,]+)?((?:;[^;,]+)*?)(?:;(base64))?,(.*)$/i;
15
15
 
16
+ /**
17
+ * @param {string} uri data URI
18
+ * @returns {Buffer|null} decoded data
19
+ */
16
20
  const decodeDataURI = uri => {
17
21
  const match = URIRegEx.exec(uri);
18
22
  if (!match) return null;
@@ -71,11 +71,19 @@ const validate = createSchemaValidation(
71
71
  }
72
72
  );
73
73
 
74
+ /**
75
+ * @param {string} str path
76
+ * @returns {string} safe path
77
+ */
74
78
  const toSafePath = str =>
75
79
  str
76
80
  .replace(/^[^a-zA-Z0-9]+|[^a-zA-Z0-9]+$/g, "")
77
81
  .replace(/[^a-zA-Z0-9._-]+/g, "_");
78
82
 
83
+ /**
84
+ * @param {Buffer} content content
85
+ * @returns {string} integrity
86
+ */
79
87
  const computeIntegrity = content => {
80
88
  const hash = createHash("sha512");
81
89
  hash.update(content);
@@ -83,6 +91,11 @@ const computeIntegrity = content => {
83
91
  return integrity;
84
92
  };
85
93
 
94
+ /**
95
+ * @param {Buffer} content content
96
+ * @param {string} integrity integrity
97
+ * @returns {boolean} true, if integrity matches
98
+ */
86
99
  const verifyIntegrity = (content, integrity) => {
87
100
  if (integrity === "ignore") return true;
88
101
  return computeIntegrity(content) === integrity;
@@ -110,6 +123,11 @@ const parseKeyValuePairs = str => {
110
123
  return result;
111
124
  };
112
125
 
126
+ /**
127
+ * @param {string | undefined} cacheControl Cache-Control header
128
+ * @param {number} requestTime timestamp of request
129
+ * @returns {{storeCache: boolean, storeLock: boolean, validUntil: number}} Logic for storing in cache and lockfile cache
130
+ */
113
131
  const parseCacheControl = (cacheControl, requestTime) => {
114
132
  // When false resource is not stored in cache
115
133
  let storeCache = true;
@@ -147,6 +165,10 @@ const areLockfileEntriesEqual = (a, b) => {
147
165
  );
148
166
  };
149
167
 
168
+ /**
169
+ * @param {LockfileEntry} entry lockfile entry
170
+ * @returns {`resolved: ${string}, integrity: ${string}, contentType: ${*}`} stringified entry
171
+ */
150
172
  const entryToString = entry => {
151
173
  return `resolved: ${entry.resolved}, integrity: ${entry.integrity}, contentType: ${entry.contentType}`;
152
174
  };
@@ -158,6 +180,10 @@ class Lockfile {
158
180
  this.entries = new Map();
159
181
  }
160
182
 
183
+ /**
184
+ * @param {string} content content of the lockfile
185
+ * @returns {Lockfile} lockfile
186
+ */
161
187
  static parse(content) {
162
188
  // TODO handle merge conflicts
163
189
  const data = JSON.parse(content);
@@ -180,6 +206,9 @@ class Lockfile {
180
206
  return lockfile;
181
207
  }
182
208
 
209
+ /**
210
+ * @returns {string} stringified lockfile
211
+ */
183
212
  toString() {
184
213
  let str = "{\n";
185
214
  const entries = Array.from(this.entries).sort(([a], [b]) =>
@@ -342,6 +371,7 @@ class HttpUriPlugin {
342
371
  const fs = compilation.inputFileSystem;
343
372
  const cache = compilation.getCache("webpack.HttpUriPlugin");
344
373
  const logger = compilation.getLogger("webpack.HttpUriPlugin");
374
+ /** @type {string} */
345
375
  const lockfileLocation =
346
376
  this._lockfileLocation ||
347
377
  join(
@@ -351,6 +381,7 @@ class HttpUriPlugin {
351
381
  ? `${toSafePath(compiler.name)}.webpack.lock`
352
382
  : "webpack.lock"
353
383
  );
384
+ /** @type {string | false} */
354
385
  const cacheLocation =
355
386
  this._cacheLocation !== undefined
356
387
  ? this._cacheLocation
@@ -364,6 +395,7 @@ class HttpUriPlugin {
364
395
 
365
396
  let warnedAboutEol = false;
366
397
 
398
+ /** @type {Map<string, string>} */
367
399
  const cacheKeyCache = new Map();
368
400
  /**
369
401
  * @param {string} url the url
@@ -447,6 +479,12 @@ class HttpUriPlugin {
447
479
 
448
480
  /** @type {Map<string, LockfileEntry | "ignore" | "no-cache"> | undefined} */
449
481
  let lockfileUpdates = undefined;
482
+
483
+ /**
484
+ * @param {Lockfile} lockfile lockfile instance
485
+ * @param {string} url url to store
486
+ * @param {LockfileEntry | "ignore" | "no-cache"} entry lockfile entry
487
+ */
450
488
  const storeLockEntry = (lockfile, url, entry) => {
451
489
  const oldEntry = lockfile.entries.get(url);
452
490
  if (lockfileUpdates === undefined) lockfileUpdates = new Map();
@@ -8,6 +8,9 @@
8
8
  const { RawSource } = require("webpack-sources");
9
9
  const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
10
10
  const Module = require("../Module");
11
+ const {
12
+ WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE
13
+ } = require("../ModuleTypeConstants");
11
14
  const RuntimeGlobals = require("../RuntimeGlobals");
12
15
  const makeSerializable = require("../util/makeSerializable");
13
16
  const { rangeToString, stringifyHoley } = require("../util/semver");
@@ -52,7 +55,7 @@ class ConsumeSharedModule extends Module {
52
55
  * @param {ConsumeOptions} options consume options
53
56
  */
54
57
  constructor(context, options) {
55
- super("consume-shared-module", context);
58
+ super(WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE, context);
56
59
  this.options = options;
57
60
  }
58
61
 
@@ -69,7 +72,7 @@ class ConsumeSharedModule extends Module {
69
72
  singleton,
70
73
  eager
71
74
  } = this.options;
72
- return `consume-shared-module|${shareScope}|${shareKey}|${
75
+ return `${WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE}|${shareScope}|${shareKey}|${
73
76
  requiredVersion && rangeToString(requiredVersion)
74
77
  }|${strictVersion}|${importResolved}|${singleton}|${eager}`;
75
78
  }
@@ -7,6 +7,7 @@
7
7
 
8
8
  const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
9
9
  const Module = require("../Module");
10
+ const { WEBPACK_MODULE_TYPE_PROVIDE } = require("../ModuleTypeConstants");
10
11
  const RuntimeGlobals = require("../RuntimeGlobals");
11
12
  const makeSerializable = require("../util/makeSerializable");
12
13
  const ProvideForSharedDependency = require("./ProvideForSharedDependency");
@@ -39,7 +40,7 @@ class ProvideSharedModule extends Module {
39
40
  * @param {boolean} eager include the module in sync way
40
41
  */
41
42
  constructor(shareScope, name, version, request, eager) {
42
- super("provide-module");
43
+ super(WEBPACK_MODULE_TYPE_PROVIDE);
43
44
  this._shareScope = shareScope;
44
45
  this._name = name;
45
46
  this._version = version;