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.
- package/bin/webpack.js +13 -2
- package/lib/Compilation.js +4 -1
- package/lib/CssModule.js +39 -7
- package/lib/DependenciesBlock.js +8 -0
- package/lib/FileSystemInfo.js +1 -1
- package/lib/HotModuleReplacementPlugin.js +3 -2
- package/lib/Module.js +3 -2
- package/lib/ModuleTypeConstants.js +90 -0
- package/lib/NormalModule.js +2 -1
- package/lib/RuntimeModule.js +4 -3
- package/lib/Template.js +2 -1
- package/lib/WebpackOptionsApply.js +33 -40
- package/lib/asset/AssetGenerator.js +4 -3
- package/lib/asset/AssetModulesPlugin.js +21 -11
- package/lib/asset/RawDataUrlModule.js +2 -1
- package/lib/cache/MemoryWithGcCachePlugin.js +2 -0
- package/lib/config/defaults.js +4 -2
- package/lib/container/FallbackModule.js +2 -1
- package/lib/container/RemoteModule.js +2 -1
- package/lib/css/CssGenerator.js +4 -0
- package/lib/css/CssLoadingRuntimeModule.js +9 -2
- package/lib/css/CssModulesPlugin.js +149 -39
- package/lib/css/CssParser.js +443 -319
- package/lib/css/walkCssTokens.js +118 -27
- package/lib/debug/ProfilingPlugin.js +2 -0
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +1 -0
- package/lib/esm/ModuleChunkLoadingRuntimeModule.js +4 -2
- package/lib/hmr/LazyCompilationPlugin.js +13 -4
- package/lib/javascript/BasicEvaluatedExpression.js +108 -1
- package/lib/javascript/JavascriptModulesPlugin.js +3 -2
- 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/node/ReadFileChunkLoadingRuntimeModule.js +3 -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/ConsumeSharedModule.js +5 -2
- package/lib/sharing/ProvideSharedModule.js +2 -1
- package/lib/sharing/utils.js +293 -7
- package/lib/stats/DefaultStatsFactoryPlugin.js +7 -4
- 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/createHash.js +4 -3
- 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/lib/web/JsonpChunkLoadingRuntimeModule.js +8 -4
- package/package.json +3 -3
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +25 -0
- 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
|
-
|
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}`);
|
@@ -178,7 +178,9 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule {
|
|
178
178
|
"});",
|
179
179
|
"promises.push(installedChunkData[2] = promise);"
|
180
180
|
]),
|
181
|
-
|
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
|
-
|
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
|
]
|
@@ -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(
|
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
|
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(
|
43
|
+
super(WEBPACK_MODULE_TYPE_PROVIDE);
|
43
44
|
this._shareScope = shareScope;
|
44
45
|
this._name = name;
|
45
46
|
this._version = version;
|