webpack 5.5.1 → 5.9.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 +10 -3
- package/lib/Compilation.js +132 -17
- package/lib/Compiler.js +2 -2
- package/lib/ExportsInfo.js +1 -1
- package/lib/FlagDependencyUsagePlugin.js +4 -2
- package/lib/HotModuleReplacementPlugin.js +170 -36
- package/lib/NormalModule.js +13 -1
- package/lib/RuntimeTemplate.js +0 -3
- package/lib/SourceMapDevToolPlugin.js +2 -1
- package/lib/Template.js +0 -1
- package/lib/TemplatedPathPlugin.js +8 -0
- package/lib/Watching.js +0 -1
- package/lib/cache/ResolverCachePlugin.js +0 -1
- package/lib/config/defaults.js +1 -1
- package/lib/dependencies/AMDDefineDependency.js +3 -1
- package/lib/dependencies/AMDRequireArrayDependency.js +3 -1
- package/lib/dependencies/AMDRequireDependency.js +3 -1
- package/lib/dependencies/CachedConstDependency.js +3 -1
- package/lib/dependencies/CommonJsExportRequireDependency.js +3 -2
- package/lib/dependencies/CommonJsExportsDependency.js +3 -1
- package/lib/dependencies/CommonJsFullRequireDependency.js +3 -1
- package/lib/dependencies/CommonJsSelfReferenceDependency.js +3 -1
- package/lib/dependencies/ConstDependency.js +3 -1
- package/lib/dependencies/ExportsInfoDependency.js +3 -1
- package/lib/dependencies/HarmonyAcceptDependency.js +3 -1
- package/lib/dependencies/HarmonyAcceptImportDependency.js +3 -1
- package/lib/dependencies/HarmonyCompatibilityDependency.js +3 -1
- package/lib/dependencies/HarmonyExportExpressionDependency.js +3 -1
- package/lib/dependencies/HarmonyExportHeaderDependency.js +3 -1
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +11 -2
- package/lib/dependencies/HarmonyExportSpecifierDependency.js +3 -1
- package/lib/dependencies/HarmonyImportDependency.js +50 -46
- package/lib/dependencies/HarmonyImportSideEffectDependency.js +3 -1
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +11 -1
- package/lib/dependencies/ImportDependency.js +3 -2
- package/lib/dependencies/ImportEagerDependency.js +3 -1
- package/lib/dependencies/ImportWeakDependency.js +3 -1
- package/lib/dependencies/LocalModuleDependency.js +3 -1
- package/lib/dependencies/ModuleDecoratorDependency.js +3 -2
- package/lib/dependencies/NullDependency.js +3 -2
- package/lib/dependencies/PureExpressionDependency.js +3 -1
- package/lib/dependencies/RequireEnsureDependency.js +3 -1
- package/lib/dependencies/RequireHeaderDependency.js +3 -1
- package/lib/dependencies/RequireIncludeDependency.js +3 -2
- package/lib/dependencies/RequireResolveHeaderDependency.js +3 -1
- package/lib/dependencies/RuntimeRequirementsDependency.js +3 -1
- package/lib/dependencies/URLDependency.js +3 -1
- package/lib/dependencies/UnsupportedDependency.js +3 -1
- package/lib/dependencies/WorkerDependency.js +3 -2
- package/lib/hmr/HotModuleReplacement.runtime.js +1 -0
- package/lib/index.js +3 -0
- package/lib/javascript/JavascriptParser.js +29 -11
- package/lib/optimize/RealContentHashPlugin.js +127 -32
- package/lib/optimize/SideEffectsFlagPlugin.js +224 -204
- package/lib/optimize/SplitChunksPlugin.js +0 -1
- package/lib/runtime/GetMainFilenameRuntimeModule.js +4 -2
- package/lib/runtime/LoadScriptRuntimeModule.js +0 -1
- package/lib/serialization/FileMiddleware.js +4 -2
- package/lib/util/runtime.js +4 -0
- package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +0 -1
- package/lib/webpack.js +0 -2
- package/package.json +14 -14
- package/types.d.ts +179 -149
package/lib/index.js
CHANGED
@@ -355,6 +355,9 @@ module.exports = mergeExports(fn, {
|
|
355
355
|
get ModuleConcatenationPlugin() {
|
356
356
|
return require("./optimize/ModuleConcatenationPlugin");
|
357
357
|
},
|
358
|
+
get RealContentHashPlugin() {
|
359
|
+
return require("./optimize/RealContentHashPlugin");
|
360
|
+
},
|
358
361
|
get RuntimeChunkPlugin() {
|
359
362
|
return require("./optimize/RuntimeChunkPlugin");
|
360
363
|
},
|
@@ -1551,6 +1551,18 @@ class JavascriptParser extends Parser {
|
|
1551
1551
|
this.prevStatement = this.statementPath.pop();
|
1552
1552
|
}
|
1553
1553
|
|
1554
|
+
/**
|
1555
|
+
* Walks a statements that is nested within a parent statement
|
1556
|
+
* and can potentially be a non-block statement.
|
1557
|
+
* This enforces the nested statement to never be in ASI position.
|
1558
|
+
* @param {StatementNode} statement the nested statement
|
1559
|
+
* @returns {void}
|
1560
|
+
*/
|
1561
|
+
walkNestedStatement(statement) {
|
1562
|
+
this.prevStatement = undefined;
|
1563
|
+
this.walkStatement(statement);
|
1564
|
+
}
|
1565
|
+
|
1554
1566
|
// Real Statements
|
1555
1567
|
preWalkBlockStatement(statement) {
|
1556
1568
|
this.preWalkStatements(statement.body);
|
@@ -1581,15 +1593,15 @@ class JavascriptParser extends Parser {
|
|
1581
1593
|
const result = this.hooks.statementIf.call(statement);
|
1582
1594
|
if (result === undefined) {
|
1583
1595
|
this.walkExpression(statement.test);
|
1584
|
-
this.
|
1596
|
+
this.walkNestedStatement(statement.consequent);
|
1585
1597
|
if (statement.alternate) {
|
1586
|
-
this.
|
1598
|
+
this.walkNestedStatement(statement.alternate);
|
1587
1599
|
}
|
1588
1600
|
} else {
|
1589
1601
|
if (result) {
|
1590
|
-
this.
|
1602
|
+
this.walkNestedStatement(statement.consequent);
|
1591
1603
|
} else if (statement.alternate) {
|
1592
|
-
this.
|
1604
|
+
this.walkNestedStatement(statement.alternate);
|
1593
1605
|
}
|
1594
1606
|
}
|
1595
1607
|
}
|
@@ -1604,7 +1616,7 @@ class JavascriptParser extends Parser {
|
|
1604
1616
|
const result = hook.call(statement);
|
1605
1617
|
if (result === true) return;
|
1606
1618
|
}
|
1607
|
-
this.
|
1619
|
+
this.walkNestedStatement(statement.body);
|
1608
1620
|
}
|
1609
1621
|
|
1610
1622
|
preWalkWithStatement(statement) {
|
@@ -1613,7 +1625,7 @@ class JavascriptParser extends Parser {
|
|
1613
1625
|
|
1614
1626
|
walkWithStatement(statement) {
|
1615
1627
|
this.walkExpression(statement.object);
|
1616
|
-
this.
|
1628
|
+
this.walkNestedStatement(statement.body);
|
1617
1629
|
}
|
1618
1630
|
|
1619
1631
|
preWalkSwitchStatement(statement) {
|
@@ -1661,7 +1673,7 @@ class JavascriptParser extends Parser {
|
|
1661
1673
|
|
1662
1674
|
walkWhileStatement(statement) {
|
1663
1675
|
this.walkExpression(statement.test);
|
1664
|
-
this.
|
1676
|
+
this.walkNestedStatement(statement.body);
|
1665
1677
|
}
|
1666
1678
|
|
1667
1679
|
preWalkDoWhileStatement(statement) {
|
@@ -1669,7 +1681,7 @@ class JavascriptParser extends Parser {
|
|
1669
1681
|
}
|
1670
1682
|
|
1671
1683
|
walkDoWhileStatement(statement) {
|
1672
|
-
this.
|
1684
|
+
this.walkNestedStatement(statement.body);
|
1673
1685
|
this.walkExpression(statement.test);
|
1674
1686
|
}
|
1675
1687
|
|
@@ -1687,6 +1699,7 @@ class JavascriptParser extends Parser {
|
|
1687
1699
|
if (statement.init) {
|
1688
1700
|
if (statement.init.type === "VariableDeclaration") {
|
1689
1701
|
this.blockPreWalkVariableDeclaration(statement.init);
|
1702
|
+
this.prevStatement = undefined;
|
1690
1703
|
this.walkStatement(statement.init);
|
1691
1704
|
} else {
|
1692
1705
|
this.walkExpression(statement.init);
|
@@ -1706,7 +1719,7 @@ class JavascriptParser extends Parser {
|
|
1706
1719
|
this.prevStatement = prev;
|
1707
1720
|
this.walkStatements(body.body);
|
1708
1721
|
} else {
|
1709
|
-
this.
|
1722
|
+
this.walkNestedStatement(body);
|
1710
1723
|
}
|
1711
1724
|
});
|
1712
1725
|
}
|
@@ -1735,7 +1748,7 @@ class JavascriptParser extends Parser {
|
|
1735
1748
|
this.prevStatement = prev;
|
1736
1749
|
this.walkStatements(body.body);
|
1737
1750
|
} else {
|
1738
|
-
this.
|
1751
|
+
this.walkNestedStatement(body);
|
1739
1752
|
}
|
1740
1753
|
});
|
1741
1754
|
}
|
@@ -1767,7 +1780,7 @@ class JavascriptParser extends Parser {
|
|
1767
1780
|
this.prevStatement = prev;
|
1768
1781
|
this.walkStatements(body.body);
|
1769
1782
|
} else {
|
1770
|
-
this.
|
1783
|
+
this.walkNestedStatement(body);
|
1771
1784
|
}
|
1772
1785
|
});
|
1773
1786
|
}
|
@@ -3376,9 +3389,14 @@ class JavascriptParser extends Parser {
|
|
3376
3389
|
const currentStatement = this.statementPath[this.statementPath.length - 1];
|
3377
3390
|
if (currentStatement === undefined) throw new Error("Not in statement");
|
3378
3391
|
return (
|
3392
|
+
// Either asking directly for the end position of the current statement
|
3379
3393
|
(currentStatement.range[1] === pos && this.semicolons.has(pos)) ||
|
3394
|
+
// Or asking for the start position of the current statement,
|
3395
|
+
// here we have to check multiple things
|
3380
3396
|
(currentStatement.range[0] === pos &&
|
3397
|
+
// is there a previous statement which might be relevant?
|
3381
3398
|
this.prevStatement !== undefined &&
|
3399
|
+
// is the end position of the previous statement an ASI position?
|
3382
3400
|
this.semicolons.has(this.prevStatement.range[1]))
|
3383
3401
|
);
|
3384
3402
|
}
|
@@ -5,12 +5,15 @@
|
|
5
5
|
|
6
6
|
"use strict";
|
7
7
|
|
8
|
+
const { SyncBailHook } = require("tapable");
|
8
9
|
const { RawSource, CachedSource, CompatSource } = require("webpack-sources");
|
9
10
|
const Compilation = require("../Compilation");
|
10
11
|
const WebpackError = require("../WebpackError");
|
11
12
|
const { compareSelect, compareStrings } = require("../util/comparators");
|
12
13
|
const createHash = require("../util/createHash");
|
13
14
|
|
15
|
+
/** @typedef {import("webpack-sources").Source} Source */
|
16
|
+
/** @typedef {import("../Compilation").AssetInfo} AssetInfo */
|
14
17
|
/** @typedef {import("../Compiler")} Compiler */
|
15
18
|
|
16
19
|
const EMPTY_SET = new Set();
|
@@ -47,7 +50,50 @@ const toCachedSource = source => {
|
|
47
50
|
return newSource;
|
48
51
|
};
|
49
52
|
|
53
|
+
/**
|
54
|
+
* @typedef {Object} AssetInfoForRealContentHash
|
55
|
+
* @property {string} name
|
56
|
+
* @property {AssetInfo} info
|
57
|
+
* @property {Source} source
|
58
|
+
* @property {RawSource | undefined} newSource
|
59
|
+
* @property {RawSource | undefined} newSourceWithoutOwn
|
60
|
+
* @property {string} content
|
61
|
+
* @property {Set<string>} ownHashes
|
62
|
+
* @property {Promise} contentComputePromise
|
63
|
+
* @property {Promise} contentComputeWithoutOwnPromise
|
64
|
+
* @property {Set<string>} referencedHashes
|
65
|
+
* @property {Set<string>} hashes
|
66
|
+
*/
|
67
|
+
|
68
|
+
/**
|
69
|
+
* @typedef {Object} CompilationHooks
|
70
|
+
* @property {SyncBailHook<[Buffer[], string], string>} updateHash
|
71
|
+
*/
|
72
|
+
|
73
|
+
/** @type {WeakMap<Compilation, CompilationHooks>} */
|
74
|
+
const compilationHooksMap = new WeakMap();
|
75
|
+
|
50
76
|
class RealContentHashPlugin {
|
77
|
+
/**
|
78
|
+
* @param {Compilation} compilation the compilation
|
79
|
+
* @returns {CompilationHooks} the attached hooks
|
80
|
+
*/
|
81
|
+
static getCompilationHooks(compilation) {
|
82
|
+
if (!(compilation instanceof Compilation)) {
|
83
|
+
throw new TypeError(
|
84
|
+
"The 'compilation' argument must be an instance of Compilation"
|
85
|
+
);
|
86
|
+
}
|
87
|
+
let hooks = compilationHooksMap.get(compilation);
|
88
|
+
if (hooks === undefined) {
|
89
|
+
hooks = {
|
90
|
+
updateHash: new SyncBailHook(["content", "oldHash"])
|
91
|
+
};
|
92
|
+
compilationHooksMap.set(compilation, hooks);
|
93
|
+
}
|
94
|
+
return hooks;
|
95
|
+
}
|
96
|
+
|
51
97
|
constructor({ hashFunction, hashDigest }) {
|
52
98
|
this._hashFunction = hashFunction;
|
53
99
|
this._hashDigest = hashDigest;
|
@@ -66,6 +112,7 @@ class RealContentHashPlugin {
|
|
66
112
|
const cacheGenerate = compilation.getCache(
|
67
113
|
"RealContentHashPlugin|generate"
|
68
114
|
);
|
115
|
+
const hooks = RealContentHashPlugin.getCompilationHooks(compilation);
|
69
116
|
compilation.hooks.processAssets.tapPromise(
|
70
117
|
{
|
71
118
|
name: "RealContentHashPlugin",
|
@@ -73,6 +120,7 @@ class RealContentHashPlugin {
|
|
73
120
|
},
|
74
121
|
async () => {
|
75
122
|
const assets = compilation.getAssets();
|
123
|
+
/** @type {AssetInfoForRealContentHash[]} */
|
76
124
|
const assetsWithInfo = [];
|
77
125
|
const hashToAssets = new Map();
|
78
126
|
for (const { source, info, name } of assets) {
|
@@ -87,9 +135,13 @@ class RealContentHashPlugin {
|
|
87
135
|
source: cachedSource,
|
88
136
|
/** @type {RawSource | undefined} */
|
89
137
|
newSource: undefined,
|
138
|
+
/** @type {RawSource | undefined} */
|
139
|
+
newSourceWithoutOwn: undefined,
|
90
140
|
content,
|
91
|
-
|
92
|
-
|
141
|
+
/** @type {Set<string>} */
|
142
|
+
ownHashes: undefined,
|
143
|
+
contentComputePromise: undefined,
|
144
|
+
contentComputeWithoutOwnPromise: undefined,
|
93
145
|
/** @type {Set<string>} */
|
94
146
|
referencedHashes: undefined,
|
95
147
|
hashes
|
@@ -114,6 +166,7 @@ class RealContentHashPlugin {
|
|
114
166
|
const { name, source, content, hashes } = asset;
|
115
167
|
if (Buffer.isBuffer(content)) {
|
116
168
|
asset.referencedHashes = EMPTY_SET;
|
169
|
+
asset.ownHashes = EMPTY_SET;
|
117
170
|
return;
|
118
171
|
}
|
119
172
|
const etag = cacheAnalyse.mergeEtags(
|
@@ -122,21 +175,21 @@ class RealContentHashPlugin {
|
|
122
175
|
);
|
123
176
|
[
|
124
177
|
asset.referencedHashes,
|
125
|
-
asset.
|
178
|
+
asset.ownHashes
|
126
179
|
] = await cacheAnalyse.providePromise(name, etag, () => {
|
127
180
|
const referencedHashes = new Set();
|
128
|
-
let
|
181
|
+
let ownHashes = new Set();
|
129
182
|
const inContent = content.match(hashRegExp);
|
130
183
|
if (inContent) {
|
131
184
|
for (const hash of inContent) {
|
132
185
|
if (hashes.has(hash)) {
|
133
|
-
|
186
|
+
ownHashes.add(hash);
|
134
187
|
continue;
|
135
188
|
}
|
136
189
|
referencedHashes.add(hash);
|
137
190
|
}
|
138
191
|
}
|
139
|
-
return [referencedHashes,
|
192
|
+
return [referencedHashes, ownHashes];
|
140
193
|
});
|
141
194
|
})
|
142
195
|
);
|
@@ -163,7 +216,12 @@ ${referencingAssets
|
|
163
216
|
return undefined;
|
164
217
|
}
|
165
218
|
const hashes = new Set();
|
166
|
-
for (const { referencedHashes } of assets) {
|
219
|
+
for (const { referencedHashes, ownHashes } of assets) {
|
220
|
+
if (!ownHashes.has(hash)) {
|
221
|
+
for (const hash of ownHashes) {
|
222
|
+
hashes.add(hash);
|
223
|
+
}
|
224
|
+
}
|
167
225
|
for (const hash of referencedHashes) {
|
168
226
|
hashes.add(hash);
|
169
227
|
}
|
@@ -199,32 +257,57 @@ ${referencingAssets
|
|
199
257
|
add(hash, new Set());
|
200
258
|
}
|
201
259
|
const hashToNewHash = new Map();
|
202
|
-
const
|
260
|
+
const getEtag = asset =>
|
261
|
+
cacheGenerate.mergeEtags(
|
262
|
+
cacheGenerate.getLazyHashedEtag(asset.source),
|
263
|
+
Array.from(asset.referencedHashes, hash =>
|
264
|
+
hashToNewHash.get(hash)
|
265
|
+
).join("|")
|
266
|
+
);
|
267
|
+
const computeNewContent = asset => {
|
203
268
|
if (asset.contentComputePromise) return asset.contentComputePromise;
|
204
269
|
return (asset.contentComputePromise = (async () => {
|
205
270
|
if (
|
206
|
-
asset.
|
271
|
+
asset.ownHashes.size > 0 ||
|
207
272
|
Array.from(asset.referencedHashes).some(
|
208
273
|
hash => hashToNewHash.get(hash) !== hash
|
209
274
|
)
|
210
275
|
) {
|
211
|
-
const identifier =
|
212
|
-
|
213
|
-
(includeOwn && asset.hasOwnHash ? "|with-own" : "");
|
214
|
-
const etag = cacheGenerate.mergeEtags(
|
215
|
-
cacheGenerate.getLazyHashedEtag(asset.source),
|
216
|
-
Array.from(asset.referencedHashes, hash =>
|
217
|
-
hashToNewHash.get(hash)
|
218
|
-
).join("|")
|
219
|
-
);
|
276
|
+
const identifier = asset.name;
|
277
|
+
const etag = getEtag(asset);
|
220
278
|
asset.newSource = await cacheGenerate.providePromise(
|
279
|
+
identifier,
|
280
|
+
etag,
|
281
|
+
() => {
|
282
|
+
const newContent = asset.content.replace(hashRegExp, hash =>
|
283
|
+
hashToNewHash.get(hash)
|
284
|
+
);
|
285
|
+
return new RawSource(newContent);
|
286
|
+
}
|
287
|
+
);
|
288
|
+
}
|
289
|
+
})());
|
290
|
+
};
|
291
|
+
const computeNewContentWithoutOwn = asset => {
|
292
|
+
if (asset.contentComputeWithoutOwnPromise)
|
293
|
+
return asset.contentComputeWithoutOwnPromise;
|
294
|
+
return (asset.contentComputeWithoutOwnPromise = (async () => {
|
295
|
+
if (
|
296
|
+
asset.ownHashes.size > 0 ||
|
297
|
+
Array.from(asset.referencedHashes).some(
|
298
|
+
hash => hashToNewHash.get(hash) !== hash
|
299
|
+
)
|
300
|
+
) {
|
301
|
+
const identifier = asset.name + "|without-own";
|
302
|
+
const etag = getEtag(asset);
|
303
|
+
asset.newSourceWithoutOwn = await cacheGenerate.providePromise(
|
221
304
|
identifier,
|
222
305
|
etag,
|
223
306
|
() => {
|
224
307
|
const newContent = asset.content.replace(
|
225
308
|
hashRegExp,
|
226
309
|
hash => {
|
227
|
-
if (
|
310
|
+
if (asset.ownHashes.has(hash)) {
|
228
311
|
return "";
|
229
312
|
}
|
230
313
|
return hashToNewHash.get(hash);
|
@@ -241,25 +324,37 @@ ${referencingAssets
|
|
241
324
|
const assets = hashToAssets.get(oldHash);
|
242
325
|
assets.sort(comparator);
|
243
326
|
const hash = createHash(this._hashFunction);
|
244
|
-
await Promise.all(
|
245
|
-
|
246
|
-
|
247
|
-
|
327
|
+
await Promise.all(
|
328
|
+
assets.map(asset =>
|
329
|
+
asset.ownHashes.has(oldHash)
|
330
|
+
? computeNewContentWithoutOwn(asset)
|
331
|
+
: computeNewContent(asset)
|
332
|
+
)
|
333
|
+
);
|
334
|
+
const assetsContent = assets.map(asset => {
|
335
|
+
if (asset.ownHashes.has(oldHash)) {
|
336
|
+
return asset.newSourceWithoutOwn
|
337
|
+
? asset.newSourceWithoutOwn.buffer()
|
338
|
+
: asset.source.buffer();
|
339
|
+
} else {
|
340
|
+
return asset.newSource
|
248
341
|
? asset.newSource.buffer()
|
249
|
-
: asset.source.buffer()
|
250
|
-
|
342
|
+
: asset.source.buffer();
|
343
|
+
}
|
344
|
+
});
|
345
|
+
let newHash = hooks.updateHash.call(assetsContent, oldHash);
|
346
|
+
if (!newHash) {
|
347
|
+
for (const content of assetsContent) {
|
348
|
+
hash.update(content);
|
349
|
+
}
|
350
|
+
const digest = hash.digest(this._hashDigest);
|
351
|
+
newHash = /** @type {string} */ (digest.slice(0, oldHash.length));
|
251
352
|
}
|
252
|
-
const digest = hash.digest(this._hashDigest);
|
253
|
-
const newHash = digest.slice(0, oldHash.length);
|
254
353
|
hashToNewHash.set(oldHash, newHash);
|
255
354
|
}
|
256
355
|
await Promise.all(
|
257
356
|
assetsWithInfo.map(async asset => {
|
258
|
-
|
259
|
-
if (asset.hasOwnHash) {
|
260
|
-
asset.contentComputePromise = undefined;
|
261
|
-
}
|
262
|
-
await computeNewContent(asset, true);
|
357
|
+
await computeNewContent(asset);
|
263
358
|
const newName = asset.name.replace(hashRegExp, hash =>
|
264
359
|
hashToNewHash.get(hash)
|
265
360
|
);
|