webpack 5.80.0 → 5.82.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 (135) hide show
  1. package/bin/webpack.js +13 -2
  2. package/lib/AsyncDependenciesBlock.js +8 -0
  3. package/lib/CodeGenerationResults.js +2 -2
  4. package/lib/Compilation.js +4 -2
  5. package/lib/ContextModule.js +8 -0
  6. package/lib/CssModule.js +169 -0
  7. package/lib/DefinePlugin.js +81 -44
  8. package/lib/DelegatedModule.js +5 -0
  9. package/lib/DependenciesBlock.js +8 -0
  10. package/lib/Dependency.js +8 -0
  11. package/lib/DllModule.js +8 -0
  12. package/lib/ExportsInfo.js +3 -0
  13. package/lib/ExternalModule.js +8 -0
  14. package/lib/FileSystemInfo.js +8 -0
  15. package/lib/LoaderOptionsPlugin.js +12 -2
  16. package/lib/Module.js +8 -0
  17. package/lib/ModuleBuildError.js +9 -0
  18. package/lib/ModuleError.js +9 -0
  19. package/lib/ModuleFilenameHelpers.js +113 -4
  20. package/lib/ModuleParseError.js +9 -0
  21. package/lib/ModuleTypeConstants.js +21 -0
  22. package/lib/ModuleWarning.js +9 -0
  23. package/lib/NormalModule.js +8 -0
  24. package/lib/NormalModuleFactory.js +15 -3
  25. package/lib/RawModule.js +8 -0
  26. package/lib/WebpackError.js +8 -0
  27. package/lib/WebpackOptionsApply.js +33 -40
  28. package/lib/asset/RawDataUrlModule.js +8 -0
  29. package/lib/cache/MemoryWithGcCachePlugin.js +2 -0
  30. package/lib/cache/ResolverCachePlugin.js +3 -0
  31. package/lib/config/defaults.js +1 -0
  32. package/lib/config/normalization.js +1 -0
  33. package/lib/container/ContainerEntryModule.js +5 -0
  34. package/lib/container/ContainerExposedDependency.js +9 -0
  35. package/lib/container/FallbackDependency.js +6 -0
  36. package/lib/container/FallbackModule.js +5 -0
  37. package/lib/container/RemoteModule.js +5 -0
  38. package/lib/css/CssGenerator.js +4 -0
  39. package/lib/css/CssLoadingRuntimeModule.js +9 -2
  40. package/lib/css/CssModulesPlugin.js +201 -57
  41. package/lib/css/CssParser.js +270 -147
  42. package/lib/css/walkCssTokens.js +121 -65
  43. package/lib/debug/ProfilingPlugin.js +2 -0
  44. package/lib/dependencies/AMDDefineDependency.js +8 -0
  45. package/lib/dependencies/AMDRequireArrayDependency.js +8 -0
  46. package/lib/dependencies/AMDRequireContextDependency.js +9 -0
  47. package/lib/dependencies/AMDRequireDependency.js +8 -0
  48. package/lib/dependencies/CachedConstDependency.js +8 -0
  49. package/lib/dependencies/CommonJsDependencyHelpers.js +9 -0
  50. package/lib/dependencies/CommonJsExportRequireDependency.js +8 -0
  51. package/lib/dependencies/CommonJsExportsDependency.js +8 -0
  52. package/lib/dependencies/CommonJsExportsParserPlugin.js +65 -3
  53. package/lib/dependencies/CommonJsFullRequireDependency.js +8 -0
  54. package/lib/dependencies/CommonJsRequireContextDependency.js +9 -0
  55. package/lib/dependencies/CommonJsSelfReferenceDependency.js +8 -0
  56. package/lib/dependencies/ConstDependency.js +8 -0
  57. package/lib/dependencies/ContextDependency.js +8 -0
  58. package/lib/dependencies/ContextElementDependency.js +8 -0
  59. package/lib/dependencies/CreateScriptUrlDependency.js +8 -0
  60. package/lib/dependencies/CssExportDependency.js +8 -0
  61. package/lib/dependencies/CssImportDependency.js +52 -1
  62. package/lib/dependencies/CssLocalIdentifierDependency.js +8 -0
  63. package/lib/dependencies/CssSelfLocalIdentifierDependency.js +8 -0
  64. package/lib/dependencies/CssUrlDependency.js +8 -0
  65. package/lib/dependencies/DllEntryDependency.js +9 -0
  66. package/lib/dependencies/ExportsInfoDependency.js +5 -0
  67. package/lib/dependencies/HarmonyAcceptDependency.js +8 -0
  68. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +8 -0
  69. package/lib/dependencies/HarmonyExportExpressionDependency.js +8 -0
  70. package/lib/dependencies/HarmonyExportHeaderDependency.js +8 -0
  71. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +14 -0
  72. package/lib/dependencies/HarmonyExportSpecifierDependency.js +8 -0
  73. package/lib/dependencies/HarmonyImportDependency.js +8 -0
  74. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +1 -0
  75. package/lib/dependencies/HarmonyImportSpecifierDependency.js +8 -0
  76. package/lib/dependencies/ImportContextDependency.js +9 -0
  77. package/lib/dependencies/ImportDependency.js +8 -0
  78. package/lib/dependencies/JsonExportsDependency.js +8 -0
  79. package/lib/dependencies/LocalModuleDependency.js +8 -0
  80. package/lib/dependencies/ModuleDecoratorDependency.js +8 -0
  81. package/lib/dependencies/ModuleDependency.js +8 -0
  82. package/lib/dependencies/ProvidedDependency.js +8 -0
  83. package/lib/dependencies/PureExpressionDependency.js +8 -0
  84. package/lib/dependencies/RequireEnsureDependency.js +8 -0
  85. package/lib/dependencies/RequireHeaderDependency.js +5 -0
  86. package/lib/dependencies/RequireResolveContextDependency.js +9 -0
  87. package/lib/dependencies/RequireResolveHeaderDependency.js +5 -0
  88. package/lib/dependencies/RuntimeRequirementsDependency.js +8 -0
  89. package/lib/dependencies/StaticExportsDependency.js +8 -0
  90. package/lib/dependencies/URLDependency.js +8 -0
  91. package/lib/dependencies/UnsupportedDependency.js +8 -0
  92. package/lib/dependencies/WebAssemblyExportImportedDependency.js +8 -0
  93. package/lib/dependencies/WebAssemblyImportDependency.js +8 -0
  94. package/lib/dependencies/WorkerDependency.js +8 -0
  95. package/lib/index.js +1 -0
  96. package/lib/javascript/BasicEvaluatedExpression.js +108 -1
  97. package/lib/javascript/JavascriptParser.js +133 -12
  98. package/lib/json/JsonData.js +25 -0
  99. package/lib/json/JsonGenerator.js +15 -3
  100. package/lib/json/JsonModulesPlugin.js +1 -0
  101. package/lib/json/JsonParser.js +2 -1
  102. package/lib/library/ModuleLibraryPlugin.js +2 -1
  103. package/lib/optimize/RealContentHashPlugin.js +6 -0
  104. package/lib/runtime/AutoPublicPathRuntimeModule.js +6 -1
  105. package/lib/runtime/GetChunkFilenameRuntimeModule.js +4 -0
  106. package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +22 -3
  107. package/lib/schemes/DataUriPlugin.js +4 -0
  108. package/lib/schemes/HttpUriPlugin.js +38 -0
  109. package/lib/serialization/ObjectMiddleware.js +2 -0
  110. package/lib/sharing/ConsumeSharedModule.js +8 -0
  111. package/lib/sharing/ConsumeSharedRuntimeModule.js +9 -3
  112. package/lib/sharing/ProvideSharedDependency.js +6 -0
  113. package/lib/sharing/ProvideSharedModule.js +5 -0
  114. package/lib/sharing/ShareRuntimeModule.js +7 -4
  115. package/lib/sharing/utils.js +293 -7
  116. package/lib/stats/DefaultStatsPrinterPlugin.js +25 -0
  117. package/lib/util/LazySet.js +10 -2
  118. package/lib/util/MapHelpers.js +19 -5
  119. package/lib/util/StackedCacheMap.js +6 -0
  120. package/lib/util/StringXor.js +51 -0
  121. package/lib/util/binarySearchBounds.js +49 -0
  122. package/lib/util/compileBooleanMatcher.js +31 -0
  123. package/lib/util/deprecation.js +8 -0
  124. package/lib/util/identifier.js +4 -0
  125. package/lib/util/internalSerializables.js +1 -0
  126. package/lib/util/numberHash.js +75 -21
  127. package/lib/util/propertyAccess.js +5 -0
  128. package/lib/util/semver.js +1 -1
  129. package/lib/wasm/EnableWasmLoadingPlugin.js +4 -0
  130. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +1 -0
  131. package/lib/wasm-async/AsyncWebAssemblyParser.js +1 -1
  132. package/package.json +4 -5
  133. package/schemas/WebpackOptions.check.js +1 -1
  134. package/schemas/WebpackOptions.json +33 -0
  135. package/types.d.ts +176 -48
@@ -13,6 +13,8 @@ const ModuleDependency = require("./ModuleDependency");
13
13
  /** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */
14
14
  /** @typedef {import("../ModuleGraph")} ModuleGraph */
15
15
  /** @typedef {import("../WebpackError")} WebpackError */
16
+ /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
17
+ /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
16
18
  /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
17
19
 
18
20
  class WebAssemblyImportDependency extends ModuleDependency {
@@ -71,6 +73,9 @@ class WebAssemblyImportDependency extends ModuleDependency {
71
73
  }
72
74
  }
73
75
 
76
+ /**
77
+ * @param {ObjectSerializerContext} context context
78
+ */
74
79
  serialize(context) {
75
80
  const { write } = context;
76
81
 
@@ -81,6 +86,9 @@ class WebAssemblyImportDependency extends ModuleDependency {
81
86
  super.serialize(context);
82
87
  }
83
88
 
89
+ /**
90
+ * @param {ObjectDeserializerContext} context context
91
+ */
84
92
  deserialize(context) {
85
93
  const { read } = context;
86
94
 
@@ -18,6 +18,8 @@ const ModuleDependency = require("./ModuleDependency");
18
18
  /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
19
19
  /** @typedef {import("../Entrypoint")} Entrypoint */
20
20
  /** @typedef {import("../ModuleGraph")} ModuleGraph */
21
+ /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
22
+ /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
21
23
  /** @typedef {import("../util/Hash")} Hash */
22
24
  /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
23
25
 
@@ -68,12 +70,18 @@ class WorkerDependency extends ModuleDependency {
68
70
  hash.update(this._hashUpdate);
69
71
  }
70
72
 
73
+ /**
74
+ * @param {ObjectSerializerContext} context context
75
+ */
71
76
  serialize(context) {
72
77
  const { write } = context;
73
78
  write(this.options);
74
79
  super.serialize(context);
75
80
  }
76
81
 
82
+ /**
83
+ * @param {ObjectDeserializerContext} context context
84
+ */
77
85
  deserialize(context) {
78
86
  const { read } = context;
79
87
  this.options = read();
package/lib/index.js CHANGED
@@ -18,6 +18,7 @@ const memoize = require("./util/memoize");
18
18
  /** @typedef {import("../declarations/WebpackOptions").Externals} Externals */
19
19
  /** @typedef {import("../declarations/WebpackOptions").FileCacheOptions} FileCacheOptions */
20
20
  /** @typedef {import("../declarations/WebpackOptions").LibraryOptions} LibraryOptions */
21
+ /** @typedef {import("../declarations/WebpackOptions").MemoryCacheOptions} MemoryCacheOptions */
21
22
  /** @typedef {import("../declarations/WebpackOptions").ModuleOptions} ModuleOptions */
22
23
  /** @typedef {import("../declarations/WebpackOptions").ResolveOptions} ResolveOptions */
23
24
  /** @typedef {import("../declarations/WebpackOptions").RuleSetCondition} RuleSetCondition */
@@ -60,10 +60,11 @@ class BasicEvaluatedExpression {
60
60
  this.prefix = undefined;
61
61
  /** @type {BasicEvaluatedExpression | undefined} */
62
62
  this.postfix = undefined;
63
+ /** @type {BasicEvaluatedExpression[]} */
63
64
  this.wrappedInnerExpressions = undefined;
64
65
  /** @type {string | VariableInfoInterface | undefined} */
65
66
  this.identifier = undefined;
66
- /** @type {VariableInfoInterface} */
67
+ /** @type {string | VariableInfoInterface} */
67
68
  this.rootInfo = undefined;
68
69
  /** @type {() => string[]} */
69
70
  this.getMembers = undefined;
@@ -222,6 +223,10 @@ class BasicEvaluatedExpression {
222
223
  return this.sideEffects;
223
224
  }
224
225
 
226
+ /**
227
+ * Creates a boolean representation of this evaluated expression.
228
+ * @returns {boolean | undefined} true: truthy, false: falsy, undefined: unknown
229
+ */
225
230
  asBool() {
226
231
  if (this.truthy) return true;
227
232
  if (this.falsy || this.nullish) return false;
@@ -247,6 +252,10 @@ class BasicEvaluatedExpression {
247
252
  return undefined;
248
253
  }
249
254
 
255
+ /**
256
+ * Creates a nullish coalescing representation of this evaluated expression.
257
+ * @returns {boolean | undefined} true: nullish, false: not nullish, undefined: unknown
258
+ */
250
259
  asNullish() {
251
260
  const nullish = this.isNullish();
252
261
 
@@ -267,6 +276,10 @@ class BasicEvaluatedExpression {
267
276
  return undefined;
268
277
  }
269
278
 
279
+ /**
280
+ * Creates a string representation of this evaluated expression.
281
+ * @returns {string | undefined} the string representation or undefined if not possible
282
+ */
270
283
  asString() {
271
284
  if (this.isBoolean()) return `${this.bool}`;
272
285
  if (this.isNull()) return "null";
@@ -316,6 +329,11 @@ class BasicEvaluatedExpression {
316
329
  return this;
317
330
  }
318
331
 
332
+ /**
333
+ * Set's the value of this expression to a number
334
+ * @param {number} number number to set
335
+ * @returns {this} this
336
+ */
319
337
  setNumber(number) {
320
338
  this.type = TypeNumber;
321
339
  this.number = number;
@@ -323,6 +341,11 @@ class BasicEvaluatedExpression {
323
341
  return this;
324
342
  }
325
343
 
344
+ /**
345
+ * Set's the value of this expression to a BigInt
346
+ * @param {bigint} bigint bigint to set
347
+ * @returns {this} this
348
+ */
326
349
  setBigInt(bigint) {
327
350
  this.type = TypeBigInt;
328
351
  this.bigint = bigint;
@@ -330,6 +353,11 @@ class BasicEvaluatedExpression {
330
353
  return this;
331
354
  }
332
355
 
356
+ /**
357
+ * Set's the value of this expression to a boolean
358
+ * @param {boolean} bool boolean to set
359
+ * @returns {this} this
360
+ */
333
361
  setBoolean(bool) {
334
362
  this.type = TypeBoolean;
335
363
  this.bool = bool;
@@ -337,6 +365,11 @@ class BasicEvaluatedExpression {
337
365
  return this;
338
366
  }
339
367
 
368
+ /**
369
+ * Set's the value of this expression to a regular expression
370
+ * @param {RegExp} regExp regular expression to set
371
+ * @returns {this} this
372
+ */
340
373
  setRegExp(regExp) {
341
374
  this.type = TypeRegExp;
342
375
  this.regExp = regExp;
@@ -344,6 +377,15 @@ class BasicEvaluatedExpression {
344
377
  return this;
345
378
  }
346
379
 
380
+ /**
381
+ * Set's the value of this expression to a particular identifier and its members.
382
+ *
383
+ * @param {string | VariableInfoInterface} identifier identifier to set
384
+ * @param {string | VariableInfoInterface} rootInfo root info
385
+ * @param {() => string[]} getMembers members
386
+ * @param {() => boolean[]=} getMembersOptionals optional members
387
+ * @returns {this} this
388
+ */
347
389
  setIdentifier(identifier, rootInfo, getMembers, getMembersOptionals) {
348
390
  this.type = TypeIdentifier;
349
391
  this.identifier = identifier;
@@ -354,6 +396,14 @@ class BasicEvaluatedExpression {
354
396
  return this;
355
397
  }
356
398
 
399
+ /**
400
+ * Wraps an array of expressions with a prefix and postfix expression.
401
+ *
402
+ * @param {BasicEvaluatedExpression | null} prefix Expression to be added before the innerExpressions
403
+ * @param {BasicEvaluatedExpression} postfix Expression to be added after the innerExpressions
404
+ * @param {BasicEvaluatedExpression[]} innerExpressions Expressions to be wrapped
405
+ * @returns {this} this
406
+ */
357
407
  setWrapped(prefix, postfix, innerExpressions) {
358
408
  this.type = TypeWrapped;
359
409
  this.prefix = prefix;
@@ -363,6 +413,12 @@ class BasicEvaluatedExpression {
363
413
  return this;
364
414
  }
365
415
 
416
+ /**
417
+ * Stores the options of a conditional expression.
418
+ *
419
+ * @param {BasicEvaluatedExpression[]} options optional (consequent/alternate) expressions to be set
420
+ * @returns {this} this
421
+ */
366
422
  setOptions(options) {
367
423
  this.type = TypeConditional;
368
424
  this.options = options;
@@ -370,6 +426,12 @@ class BasicEvaluatedExpression {
370
426
  return this;
371
427
  }
372
428
 
429
+ /**
430
+ * Adds options to a conditional expression.
431
+ *
432
+ * @param {BasicEvaluatedExpression[]} options optional (consequent/alternate) expressions to be added
433
+ * @returns {this} this
434
+ */
373
435
  addOptions(options) {
374
436
  if (!this.options) {
375
437
  this.type = TypeConditional;
@@ -382,6 +444,12 @@ class BasicEvaluatedExpression {
382
444
  return this;
383
445
  }
384
446
 
447
+ /**
448
+ * Set's the value of this expression to an array of expressions.
449
+ *
450
+ * @param {BasicEvaluatedExpression[]} items expressions to set
451
+ * @returns {this} this
452
+ */
385
453
  setItems(items) {
386
454
  this.type = TypeArray;
387
455
  this.items = items;
@@ -389,6 +457,12 @@ class BasicEvaluatedExpression {
389
457
  return this;
390
458
  }
391
459
 
460
+ /**
461
+ * Set's the value of this expression to an array of strings.
462
+ *
463
+ * @param {string[]} array array to set
464
+ * @returns {this} this
465
+ */
392
466
  setArray(array) {
393
467
  this.type = TypeConstArray;
394
468
  this.array = array;
@@ -396,6 +470,15 @@ class BasicEvaluatedExpression {
396
470
  return this;
397
471
  }
398
472
 
473
+ /**
474
+ * Set's the value of this expression to a processed/unprocessed template string. Used
475
+ * for evaluating TemplateLiteral expressions in the JavaScript Parser.
476
+ *
477
+ * @param {BasicEvaluatedExpression[]} quasis template string quasis
478
+ * @param {BasicEvaluatedExpression[]} parts template string parts
479
+ * @param {"cooked" | "raw"} kind template string kind
480
+ * @returns {this} this
481
+ */
399
482
  setTemplateString(quasis, parts, kind) {
400
483
  this.type = TypeTemplateString;
401
484
  this.quasis = quasis;
@@ -418,6 +501,12 @@ class BasicEvaluatedExpression {
418
501
  return this;
419
502
  }
420
503
 
504
+ /**
505
+ * Set's the value of the expression to nullish.
506
+ *
507
+ * @param {boolean} value true, if the expression is nullish
508
+ * @returns {this} this
509
+ */
421
510
  setNullish(value) {
422
511
  this.nullish = value;
423
512
 
@@ -426,16 +515,34 @@ class BasicEvaluatedExpression {
426
515
  return this;
427
516
  }
428
517
 
518
+ /**
519
+ * Set's the range for the expression.
520
+ *
521
+ * @param {[number, number]} range range to set
522
+ * @returns {this} this
523
+ */
429
524
  setRange(range) {
430
525
  this.range = range;
431
526
  return this;
432
527
  }
433
528
 
529
+ /**
530
+ * Set whether or not the expression has side effects.
531
+ *
532
+ * @param {boolean} sideEffects true, if the expression has side effects
533
+ * @returns {this} this
534
+ */
434
535
  setSideEffects(sideEffects = true) {
435
536
  this.sideEffects = sideEffects;
436
537
  return this;
437
538
  }
438
539
 
540
+ /**
541
+ * Set the expression node for the expression.
542
+ *
543
+ * @param {EsTreeNode} expression expression
544
+ * @returns {this} this
545
+ */
439
546
  setExpression(expression) {
440
547
  this.expression = expression;
441
548
  return this;
@@ -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(
@@ -2482,7 +2603,7 @@ class JavascriptParser extends Parser {
2482
2603
  walkFunctionExpression(expression) {
2483
2604
  const wasTopLevel = this.scope.topLevelScope;
2484
2605
  this.scope.topLevelScope = false;
2485
- const scopeParams = expression.params;
2606
+ const scopeParams = [...expression.params];
2486
2607
 
2487
2608
  // Add function name in scope for recursive calls
2488
2609
  if (expression.id) {
@@ -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"),