webpack 5.81.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.
- package/bin/webpack.js +13 -2
- package/lib/Compilation.js +2 -0
- package/lib/CssModule.js +39 -7
- package/lib/WebpackOptionsApply.js +33 -40
- package/lib/cache/MemoryWithGcCachePlugin.js +2 -0
- package/lib/config/defaults.js +1 -0
- package/lib/css/CssGenerator.js +4 -0
- package/lib/css/CssLoadingRuntimeModule.js +9 -2
- package/lib/css/CssModulesPlugin.js +136 -33
- package/lib/css/CssParser.js +144 -80
- package/lib/css/walkCssTokens.js +96 -20
- package/lib/debug/ProfilingPlugin.js +2 -0
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +1 -0
- package/lib/javascript/BasicEvaluatedExpression.js +108 -1
- package/lib/javascript/JavascriptParser.js +132 -11
- package/lib/json/JsonData.js +25 -0
- package/lib/json/JsonGenerator.js +15 -3
- package/lib/json/JsonModulesPlugin.js +1 -0
- package/lib/json/JsonParser.js +2 -1
- package/lib/library/ModuleLibraryPlugin.js +2 -1
- package/lib/runtime/GetChunkFilenameRuntimeModule.js +4 -0
- package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +22 -3
- package/lib/schemes/DataUriPlugin.js +4 -0
- package/lib/schemes/HttpUriPlugin.js +38 -0
- package/lib/sharing/utils.js +293 -7
- package/lib/stats/DefaultStatsPrinterPlugin.js +25 -0
- package/lib/util/StackedCacheMap.js +6 -0
- package/lib/util/StringXor.js +51 -0
- package/lib/util/compileBooleanMatcher.js +31 -0
- package/lib/util/deprecation.js +8 -0
- package/lib/util/identifier.js +4 -0
- package/lib/util/numberHash.js +75 -21
- package/lib/util/propertyAccess.js +5 -0
- package/lib/wasm/EnableWasmLoadingPlugin.js +4 -0
- package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +1 -0
- package/lib/wasm-async/AsyncWebAssemblyParser.js +1 -1
- package/package.json +1 -1
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +25 -0
- package/types.d.ts +121 -26
@@ -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
|
-
|
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 =
|
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
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
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
|
-
|
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 =
|
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(
|
package/lib/json/JsonData.js
CHANGED
@@ -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 {
|
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 {
|
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
|
-
|
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"),
|
package/lib/json/JsonParser.js
CHANGED
@@ -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
|
-
|
92
|
+
/** @type {string} */
|
93
|
+
(exportInfo.getUsedName(exportInfo.name, chunk.runtime))
|
93
94
|
])};\n`
|
94
95
|
);
|
95
96
|
exports.push(`${varName} as ${exportInfo.name}`);
|
@@ -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
|
-
|
62
|
-
|
63
|
-
|
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
|
]
|