webpack 5.110.1 → 5.110.2
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.
- package/README.md +10 -17
- package/lib/ExportsInfo.js +10 -0
- package/lib/RuntimeTemplate.js +423 -430
- package/lib/css/CssLoadingRuntimeModule.js +32 -13
- package/lib/css/CssModulesPlugin.js +9 -17
- package/lib/css/data.js +13 -3
- package/lib/css/syntax.js +78 -10
- package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +10 -4
- package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +2 -0
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +48 -3
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +83 -14
- package/lib/dependencies/HarmonyImportSideEffectDependency.js +114 -0
- package/lib/dependencies/WorkerAndWorkletPlugin.js +1 -0
- package/lib/dependencies/WorkerDependency.js +6 -12
- package/lib/dependencies/WorkletDependency.js +7 -11
- package/lib/esm/ModuleChunkLoadingPlugin.js +6 -9
- package/lib/esm/ModuleChunkLoadingRuntimeModule.js +7 -1
- package/lib/html/HtmlModulesPlugin.js +55 -16
- package/lib/html/syntax.js +113 -26
- package/lib/javascript/JavascriptModulesPlugin.js +3 -10
- package/lib/loaders/LoaderRunner.js +33 -5
- package/lib/node/ReadFileCompileAsyncWasmPlugin.js +8 -15
- package/lib/optimize/ConcatenatedModule.js +8 -0
- package/lib/optimize/ConstExportsPlugin.js +5 -0
- package/lib/optimize/InlineExports.js +121 -0
- package/lib/optimize/RealContentHashPlugin.js +111 -35
- package/lib/prefetch/ResourceHintPlugin.js +6 -12
- package/lib/typescript/TypeScriptPlugin.js +8 -10
- package/lib/util/SourceProcessor.js +24 -8
- package/lib/util/createMappings.js +25 -3
- package/lib/util/removeBOM.js +82 -1
- package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +5 -3
- package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +5 -3
- package/lib/wasm-async/UniversalCompileAsyncWasmPlugin.js +7 -12
- package/lib/web/FetchCompileAsyncWasmPlugin.js +10 -6
- package/lib/web/FetchCompileWasmPlugin.js +4 -2
- package/package.json +1 -1
- package/types.d.ts +69 -10
|
@@ -345,47 +345,68 @@ ${referencingAssets
|
|
|
345
345
|
}
|
|
346
346
|
return hashes;
|
|
347
347
|
};
|
|
348
|
+
// Tarjan: hashes naming each other come out as one group where a chain
|
|
349
|
+
// walk would never end, and groups arrive dependencies-first as needed.
|
|
350
|
+
/** @type {string[][]} */
|
|
351
|
+
const groupsInOrder = [];
|
|
352
|
+
/** @type {Map<string, number>} */
|
|
353
|
+
const indexOf = new Map();
|
|
354
|
+
/** @type {Map<string, number>} */
|
|
355
|
+
const lowOf = new Map();
|
|
356
|
+
/** @type {Set<string>} */
|
|
357
|
+
const onStack = new Set();
|
|
358
|
+
/** @type {string[]} */
|
|
359
|
+
const stack = [];
|
|
348
360
|
/**
|
|
349
|
-
*
|
|
361
|
+
* Visits one hash and everything its assets reference.
|
|
350
362
|
* @param {string} hash the hash
|
|
351
|
-
* @returns {
|
|
363
|
+
* @returns {void}
|
|
352
364
|
*/
|
|
353
|
-
const
|
|
354
|
-
const
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
)
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
for (const hash of hashToAssets.keys()) {
|
|
363
|
-
/**
|
|
364
|
-
* Processes the provided hash.
|
|
365
|
-
* @param {string} hash the hash
|
|
366
|
-
* @param {Set<string>} stack stack of hashes
|
|
367
|
-
*/
|
|
368
|
-
const add = (hash, stack) => {
|
|
369
|
-
const deps = getDependencies(hash);
|
|
370
|
-
if (!deps) return;
|
|
371
|
-
stack.add(hash);
|
|
365
|
+
const strongConnect = (hash) => {
|
|
366
|
+
const index = indexOf.size;
|
|
367
|
+
indexOf.set(hash, index);
|
|
368
|
+
lowOf.set(hash, index);
|
|
369
|
+
stack.push(hash);
|
|
370
|
+
onStack.add(hash);
|
|
371
|
+
// An unowned reference reports the caching problem and stays a leaf.
|
|
372
|
+
const deps = getDependencies(hash);
|
|
373
|
+
if (deps) {
|
|
372
374
|
for (const dep of deps) {
|
|
373
|
-
if (
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
375
|
+
if (!indexOf.has(dep)) {
|
|
376
|
+
strongConnect(dep);
|
|
377
|
+
lowOf.set(
|
|
378
|
+
hash,
|
|
379
|
+
Math.min(
|
|
380
|
+
/** @type {number} */ (lowOf.get(hash)),
|
|
381
|
+
/** @type {number} */ (lowOf.get(dep))
|
|
382
|
+
)
|
|
383
|
+
);
|
|
384
|
+
} else if (onStack.has(dep)) {
|
|
385
|
+
lowOf.set(
|
|
386
|
+
hash,
|
|
387
|
+
Math.min(
|
|
388
|
+
/** @type {number} */ (lowOf.get(hash)),
|
|
389
|
+
/** @type {number} */ (indexOf.get(dep))
|
|
390
|
+
)
|
|
380
391
|
);
|
|
381
392
|
}
|
|
382
|
-
add(dep, stack);
|
|
383
393
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
394
|
+
}
|
|
395
|
+
if (lowOf.get(hash) === indexOf.get(hash)) {
|
|
396
|
+
/** @type {string[]} */
|
|
397
|
+
const group = [];
|
|
398
|
+
/** @type {string} */
|
|
399
|
+
let member;
|
|
400
|
+
do {
|
|
401
|
+
member = /** @type {string} */ (stack.pop());
|
|
402
|
+
onStack.delete(member);
|
|
403
|
+
if (hashToAssets.has(member)) group.push(member);
|
|
404
|
+
} while (member !== hash);
|
|
405
|
+
if (group.length > 0) groupsInOrder.push(group);
|
|
406
|
+
}
|
|
407
|
+
};
|
|
408
|
+
for (const hash of hashToAssets.keys()) {
|
|
409
|
+
if (!indexOf.has(hash)) strongConnect(hash);
|
|
389
410
|
}
|
|
390
411
|
/** @type {Map<string, string>} */
|
|
391
412
|
const hashToNewHash = new Map();
|
|
@@ -474,7 +495,62 @@ ${referencingAssets
|
|
|
474
495
|
};
|
|
475
496
|
/** @type {Comparator<AssetInfoForRealContentHash>} */
|
|
476
497
|
const comparator = compareSelect((a) => a.name, compareStrings);
|
|
477
|
-
for (const
|
|
498
|
+
for (const group of groupsInOrder) {
|
|
499
|
+
// A cycle is assigned as one group: members are told apart by stable
|
|
500
|
+
// markers, so the group hashes to a fixed point instead of chasing one.
|
|
501
|
+
if (group.length > 1) {
|
|
502
|
+
const members = group.sort();
|
|
503
|
+
/** @type {Map<string, string>} */
|
|
504
|
+
const markerOf = new Map(
|
|
505
|
+
members.map((hash, i) => [hash, `|webpack/scc/${i}|`])
|
|
506
|
+
);
|
|
507
|
+
for (let i = 0; i < members.length; i++) {
|
|
508
|
+
const oldHash = members[i];
|
|
509
|
+
const memberAssets =
|
|
510
|
+
/** @type {AssetInfoForRealContentHash[]} */
|
|
511
|
+
(hashToAssets.get(oldHash));
|
|
512
|
+
memberAssets.sort(comparator);
|
|
513
|
+
const hash = createHash(this._hashFunction);
|
|
514
|
+
if (compilation.outputOptions.hashSalt) {
|
|
515
|
+
hash.update(compilation.outputOptions.hashSalt);
|
|
516
|
+
}
|
|
517
|
+
// Two members can normalize to the same text; the position keeps
|
|
518
|
+
// their hashes apart, and sorting keeps the position stable.
|
|
519
|
+
hash.update(`${i}`);
|
|
520
|
+
for (const asset of memberAssets) {
|
|
521
|
+
if (Buffer.isBuffer(asset.content)) {
|
|
522
|
+
hash.update(asset.content);
|
|
523
|
+
continue;
|
|
524
|
+
}
|
|
525
|
+
const withoutOwn =
|
|
526
|
+
/** @type {Hashes} */
|
|
527
|
+
(asset.ownHashes).has(oldHash);
|
|
528
|
+
hash.update(
|
|
529
|
+
asset.content.replace(hashRegExp, (matched) => {
|
|
530
|
+
// Its own occurrences vanish, exactly as a lone hash's do.
|
|
531
|
+
if (
|
|
532
|
+
withoutOwn &&
|
|
533
|
+
/** @type {Hashes} */ (asset.ownHashes).has(matched)
|
|
534
|
+
) {
|
|
535
|
+
return "";
|
|
536
|
+
}
|
|
537
|
+
const marker = markerOf.get(matched);
|
|
538
|
+
if (marker !== undefined) return marker;
|
|
539
|
+
const mapped = hashToNewHash.get(matched);
|
|
540
|
+
return mapped === undefined ? matched : mapped;
|
|
541
|
+
})
|
|
542
|
+
);
|
|
543
|
+
}
|
|
544
|
+
const digest = hash.digest(
|
|
545
|
+
/** @type {HashDigest} */ (
|
|
546
|
+
hashToDigest.get(oldHash) || this._hashDigest
|
|
547
|
+
)
|
|
548
|
+
);
|
|
549
|
+
hashToNewHash.set(oldHash, digest.slice(0, oldHash.length));
|
|
550
|
+
}
|
|
551
|
+
continue;
|
|
552
|
+
}
|
|
553
|
+
const oldHash = group[0];
|
|
478
554
|
const assets =
|
|
479
555
|
/** @type {AssetInfoForRealContentHash[]} */
|
|
480
556
|
(hashToAssets.get(oldHash));
|
|
@@ -481,19 +481,13 @@ const collectStartupAssetHintLines = (
|
|
|
481
481
|
seenWorkerChunks.add(workerChunk.id);
|
|
482
482
|
// The same specifier the `new Worker(...)` call site bakes, asked of the
|
|
483
483
|
// same module, so the two agree on whether a literal is spellable.
|
|
484
|
-
const specifier = runtimeTemplate.
|
|
485
|
-
|
|
484
|
+
const specifier = runtimeTemplate.getAnalyzableWorkerUrl(
|
|
485
|
+
dep.options.publicPath,
|
|
486
|
+
workerChunk,
|
|
487
|
+
module,
|
|
486
488
|
chunkGraph,
|
|
487
|
-
|
|
488
|
-
)
|
|
489
|
-
? runtimeTemplate._getAnalyzableChunkSpecifier(
|
|
490
|
-
dep.options.publicPath,
|
|
491
|
-
workerChunk,
|
|
492
|
-
module,
|
|
493
|
-
chunkGraph,
|
|
494
|
-
set
|
|
495
|
-
)
|
|
496
|
-
: null;
|
|
489
|
+
set
|
|
490
|
+
);
|
|
497
491
|
// Without one the call site keeps the runtime form, where it wraps its own
|
|
498
492
|
// href — firing the `<link>` here too would emit the call twice.
|
|
499
493
|
if (specifier === null) continue;
|
|
@@ -14,7 +14,7 @@ const {
|
|
|
14
14
|
} = require("../ModuleTypeConstants");
|
|
15
15
|
const NormalModule = require("../NormalModule");
|
|
16
16
|
const memoize = require("../util/memoize");
|
|
17
|
-
const
|
|
17
|
+
const { removeBOMFromResult } = require("../util/removeBOM");
|
|
18
18
|
|
|
19
19
|
const getModuleBuildError = memoize(() =>
|
|
20
20
|
require("../errors/ModuleBuildError")
|
|
@@ -133,15 +133,11 @@ const stripTypes = (input) => {
|
|
|
133
133
|
};
|
|
134
134
|
|
|
135
135
|
/**
|
|
136
|
-
* Coerce a Buffer-or-string source to a UTF-8 string, dropping any BOM.
|
|
137
136
|
* @param {string | Buffer} source raw source from the loader pipeline
|
|
138
|
-
* @returns {string} UTF-8 string
|
|
137
|
+
* @returns {string} UTF-8 string
|
|
139
138
|
*/
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
const stripped = removeBOM(text);
|
|
143
|
-
return typeof stripped === "string" ? stripped : stripped.toString("utf8");
|
|
144
|
-
};
|
|
139
|
+
const asString = (source) =>
|
|
140
|
+
Buffer.isBuffer(source) ? source.toString("utf8") : source;
|
|
145
141
|
|
|
146
142
|
class TypeScriptPlugin {
|
|
147
143
|
/**
|
|
@@ -181,8 +177,10 @@ class TypeScriptPlugin {
|
|
|
181
177
|
throw new (getModuleBuildError())(new Error(NODE_API_MISSING));
|
|
182
178
|
}
|
|
183
179
|
|
|
184
|
-
|
|
185
|
-
|
|
180
|
+
// A BOM must be off the source before it is stripped of types, and its
|
|
181
|
+
// map moved with it.
|
|
182
|
+
const [rawSource, loaderSourceMap, ...rest] = removeBOMFromResult(result);
|
|
183
|
+
const preStripSource = asString(rawSource);
|
|
186
184
|
const strippedSource = stripTypes(preStripSource);
|
|
187
185
|
|
|
188
186
|
const needSourceMap = module.useSourceMap || module.useSimpleSourceMap;
|
|
@@ -99,6 +99,23 @@ const expandDeferredWrites = (text, resolve, infix) => {
|
|
|
99
99
|
return out + text.slice(from);
|
|
100
100
|
};
|
|
101
101
|
|
|
102
|
+
/**
|
|
103
|
+
* The text this print spells with every deferred write declined: each marker
|
|
104
|
+
* replaced by what would stand there had no renderer answered. What a print
|
|
105
|
+
* verifying itself by re-parsing has to read, since a marker otherwise parses
|
|
106
|
+
* as text where its node stood. `build` rather than `source` so a write inside
|
|
107
|
+
* an attribute comes back escaped for where it sits.
|
|
108
|
+
* @param {string} text the printed output, holding this print's markers
|
|
109
|
+
* @param {DeferredWrite[]} writes what the print deferred, indexed by id
|
|
110
|
+
* @returns {string} the text with every marker put back
|
|
111
|
+
*/
|
|
112
|
+
const declineDeferredWrites = (text, writes) =>
|
|
113
|
+
expandDeferredWrites(
|
|
114
|
+
text,
|
|
115
|
+
(id) => (id < writes.length ? writes[id].build(undefined) : undefined),
|
|
116
|
+
deferredInfix
|
|
117
|
+
);
|
|
118
|
+
|
|
102
119
|
/**
|
|
103
120
|
* Babel-style visitor map keyed by a numeric node-type discriminator; a bucket
|
|
104
121
|
* is a function (enter-only) or `{ enter?, exit? }`.
|
|
@@ -389,16 +406,14 @@ class PrintContext {
|
|
|
389
406
|
_growStore(need) {
|
|
390
407
|
// From empty: a context that prints one inline `style=""` must not pay for
|
|
391
408
|
// a stylesheet's worth of columns.
|
|
392
|
-
const
|
|
393
|
-
|
|
394
|
-
//
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
for (let i =
|
|
398
|
-
for (let i = held.length; i < size; i++) text.push("");
|
|
409
|
+
const text = this._storeText;
|
|
410
|
+
const size = Math.max(need, text.length * 2, 16);
|
|
411
|
+
// Appended in place: `push` keeps the column packed for the read every
|
|
412
|
+
// composed child makes, and what it already holds never moves — where
|
|
413
|
+
// filling a second array would copy every slot again at each growth.
|
|
414
|
+
for (let i = text.length; i < size; i++) text.push("");
|
|
399
415
|
const gen = new Int32Array(size);
|
|
400
416
|
gen.set(this._storeGen);
|
|
401
|
-
this._storeText = text;
|
|
402
417
|
this._storeGen = gen;
|
|
403
418
|
}
|
|
404
419
|
|
|
@@ -1142,4 +1157,5 @@ class SourceProcessor {
|
|
|
1142
1157
|
SourceProcessor.PrintContext = PrintContext;
|
|
1143
1158
|
|
|
1144
1159
|
module.exports = SourceProcessor;
|
|
1160
|
+
module.exports.declineDeferredWrites = declineDeferredWrites;
|
|
1145
1161
|
module.exports.deferredWrite = deferredWrite;
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
* while richer call sites can pass arrays of segments.
|
|
14
14
|
*
|
|
15
15
|
* TODO move this encoder into `webpack-sources` and replace the body of this
|
|
16
|
-
* file with re-exports. The public shape (`encodeVLQ`, `
|
|
17
|
-
* `MappingSegment`, `LineMappings`) is intended to
|
|
18
|
-
* upstream so call sites don't have to change.
|
|
16
|
+
* file with re-exports. The public shape (`encodeVLQ`, `decodeVLQ`,
|
|
17
|
+
* `encodeMappings(lines)`, `MappingSegment`, `LineMappings`) is intended to
|
|
18
|
+
* match what would land upstream so call sites don't have to change.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
const VLQ_BASE64 =
|
|
@@ -38,6 +38,27 @@ const encodeVLQ = (value) => {
|
|
|
38
38
|
return result;
|
|
39
39
|
};
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Decode one base64 VLQ value per the source-map V3 spec.
|
|
43
|
+
* @param {string} mappings a VLQ encoded `mappings` string
|
|
44
|
+
* @param {number} start index of the value's first character
|
|
45
|
+
* @returns {{ value: number, end: number }} the decoded value and the index just past it; `end` equals `start` when there is no valid value at `start`
|
|
46
|
+
*/
|
|
47
|
+
const decodeVLQ = (mappings, start) => {
|
|
48
|
+
let value = 0;
|
|
49
|
+
let shift = 0;
|
|
50
|
+
let index = start;
|
|
51
|
+
let digit;
|
|
52
|
+
do {
|
|
53
|
+
digit = index < mappings.length ? VLQ_BASE64.indexOf(mappings[index]) : -1;
|
|
54
|
+
if (digit < 0) return { value: 0, end: start };
|
|
55
|
+
value += (digit & 0x1f) << shift;
|
|
56
|
+
shift += 5;
|
|
57
|
+
index++;
|
|
58
|
+
} while (digit & 0x20);
|
|
59
|
+
return { value: value & 1 ? -(value >>> 1) : value >>> 1, end: index };
|
|
60
|
+
};
|
|
61
|
+
|
|
41
62
|
/**
|
|
42
63
|
* @typedef {object} MappingSegment
|
|
43
64
|
* @property {number=} generatedColumn 0-based generated column (defaults to 0)
|
|
@@ -114,5 +135,6 @@ const encodeMappings = (lines) => {
|
|
|
114
135
|
return encodedLines.join(";");
|
|
115
136
|
};
|
|
116
137
|
|
|
138
|
+
module.exports.decodeVLQ = decodeVLQ;
|
|
117
139
|
module.exports.encodeMappings = encodeMappings;
|
|
118
140
|
module.exports.encodeVLQ = encodeVLQ;
|
package/lib/util/removeBOM.js
CHANGED
|
@@ -5,12 +5,17 @@
|
|
|
5
5
|
|
|
6
6
|
"use strict";
|
|
7
7
|
|
|
8
|
+
const { decodeVLQ, encodeVLQ } = require("./createMappings");
|
|
9
|
+
|
|
10
|
+
/** @import { RawSourceMap } from "webpack-sources" */
|
|
11
|
+
/** @import { Result } from "../NormalModule" */
|
|
12
|
+
|
|
8
13
|
/**
|
|
9
14
|
* Returns result without BOM.
|
|
10
15
|
* @param {string | Buffer} strOrBuffer string or buffer
|
|
11
16
|
* @returns {string | Buffer} result without BOM
|
|
12
17
|
*/
|
|
13
|
-
|
|
18
|
+
const removeBOM = (strOrBuffer) => {
|
|
14
19
|
if (typeof strOrBuffer === "string" && strOrBuffer.charCodeAt(0) === 0xfeff) {
|
|
15
20
|
return strOrBuffer.slice(1);
|
|
16
21
|
} else if (
|
|
@@ -24,3 +29,79 @@ module.exports = (strOrBuffer) => {
|
|
|
24
29
|
|
|
25
30
|
return strOrBuffer;
|
|
26
31
|
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* A BOM occupies generated column 0 of the first line, so a map describing
|
|
35
|
+
* BOM-prefixed content starts that line at column 1 or later. Removing the BOM
|
|
36
|
+
* moves the line one column left; the segments after the first are encoded
|
|
37
|
+
* relative to it, so only the first is rewritten. A map already starting at
|
|
38
|
+
* column 0 describes the content without its BOM and is left alone.
|
|
39
|
+
* @param {string} mappings VLQ encoded `mappings` of a map for BOM-prefixed content
|
|
40
|
+
* @returns {string} `mappings` for the same content without its BOM
|
|
41
|
+
*/
|
|
42
|
+
const shiftMappings = (mappings) => {
|
|
43
|
+
const { value, end } = decodeVLQ(mappings, 0);
|
|
44
|
+
if (end === 0 || value <= 0) return mappings;
|
|
45
|
+
return encodeVLQ(value - 1) + mappings.slice(end);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Adjust a source map that accompanied BOM-prefixed content for the removal of
|
|
50
|
+
* that BOM. Anything without VLQ `mappings` is passed through untouched, as is
|
|
51
|
+
* a map declaring a version other than 3 — earlier versions spell `mappings`
|
|
52
|
+
* differently. A map that declares no version at all is taken as version 3.
|
|
53
|
+
* @param {(string | RawSourceMap)=} sourceMap the map, as an object or as JSON
|
|
54
|
+
* @returns {(string | RawSourceMap)=} the adjusted map
|
|
55
|
+
*/
|
|
56
|
+
const adjustSourceMapForRemovedBOM = (sourceMap) => {
|
|
57
|
+
if (!sourceMap) return sourceMap;
|
|
58
|
+
|
|
59
|
+
if (typeof sourceMap === "string") {
|
|
60
|
+
/** @type {RawSourceMap} */
|
|
61
|
+
let parsed;
|
|
62
|
+
try {
|
|
63
|
+
parsed = JSON.parse(sourceMap);
|
|
64
|
+
} catch (_err) {
|
|
65
|
+
return sourceMap;
|
|
66
|
+
}
|
|
67
|
+
const adjusted = adjustSourceMapForRemovedBOM(parsed);
|
|
68
|
+
return adjusted === parsed ? sourceMap : JSON.stringify(adjusted);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (sourceMap.version !== undefined && sourceMap.version !== 3) {
|
|
72
|
+
return sourceMap;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (typeof sourceMap.mappings !== "string") return sourceMap;
|
|
76
|
+
|
|
77
|
+
const mappings = shiftMappings(sourceMap.mappings);
|
|
78
|
+
|
|
79
|
+
return mappings === sourceMap.mappings
|
|
80
|
+
? sourceMap
|
|
81
|
+
: { ...sourceMap, mappings };
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @param {Result} result a loader result: content, an optional source map, extra info
|
|
86
|
+
* @returns {Result} the result with a leading BOM removed from its content and its source map kept in sync
|
|
87
|
+
*/
|
|
88
|
+
const removeBOMFromResult = (result) => {
|
|
89
|
+
const content = result[0];
|
|
90
|
+
const withoutBOM = removeBOM(content);
|
|
91
|
+
|
|
92
|
+
if (withoutBOM === content) return result;
|
|
93
|
+
|
|
94
|
+
// Copied rather than rebuilt, so a result carrying no source map keeps its
|
|
95
|
+
// arity.
|
|
96
|
+
const adjusted = /** @type {Result} */ ([...result]);
|
|
97
|
+
|
|
98
|
+
adjusted[0] = withoutBOM;
|
|
99
|
+
|
|
100
|
+
if (adjusted[1]) adjusted[1] = adjustSourceMapForRemovedBOM(adjusted[1]);
|
|
101
|
+
|
|
102
|
+
return adjusted;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
module.exports.adjustSourceMapForRemovedBOM = adjustSourceMapForRemovedBOM;
|
|
106
|
+
module.exports.removeBOM = removeBOM;
|
|
107
|
+
module.exports.removeBOMFromResult = removeBOMFromResult;
|
|
@@ -11,11 +11,12 @@ const Template = require("../Template");
|
|
|
11
11
|
const { fullHashPathData } = require("../wasm/wasmModuleFilename");
|
|
12
12
|
|
|
13
13
|
/** @import Chunk from "../Chunk" */
|
|
14
|
+
/** @import ChunkGraph from "../ChunkGraph" */
|
|
14
15
|
/** @import Compilation from "../Compilation" */
|
|
15
16
|
/** @import { RuntimeSpec } from "../util/runtime" */
|
|
16
17
|
|
|
17
18
|
/** @typedef {(wasmModuleSrcPath: string) => string} GenerateBeforeLoadBinaryCode */
|
|
18
|
-
/** @typedef {(wasmModuleSrcPath: string, runtime: RuntimeSpec) => string} GenerateLoadBinaryCode */
|
|
19
|
+
/** @typedef {(wasmModuleSrcPath: string, runtime: RuntimeSpec, analyzable: boolean) => string} GenerateLoadBinaryCode */
|
|
19
20
|
/** @typedef {() => string} GenerateBeforeCompileStreaming */
|
|
20
21
|
|
|
21
22
|
/**
|
|
@@ -69,7 +70,7 @@ class AsyncWasmCompileRuntimeModule extends RuntimeModule {
|
|
|
69
70
|
// Analyzable output bakes the binary's URL into the call site instead.
|
|
70
71
|
const analyzable = runtimeTemplate.supportsAnalyzable(
|
|
71
72
|
"wasm",
|
|
72
|
-
|
|
73
|
+
/** @type {ChunkGraph} */ (this.chunkGraph),
|
|
73
74
|
undefined,
|
|
74
75
|
chunk.runtime
|
|
75
76
|
);
|
|
@@ -92,7 +93,8 @@ class AsyncWasmCompileRuntimeModule extends RuntimeModule {
|
|
|
92
93
|
|
|
93
94
|
const loader = this.generateLoadBinaryCode(
|
|
94
95
|
wasmModuleSrcPath,
|
|
95
|
-
chunk.runtime
|
|
96
|
+
chunk.runtime,
|
|
97
|
+
analyzable
|
|
96
98
|
);
|
|
97
99
|
|
|
98
100
|
// Fallback path: fetch -> arrayBuffer -> WebAssembly.compile
|
|
@@ -11,11 +11,12 @@ const Template = require("../Template");
|
|
|
11
11
|
const { fullHashPathData } = require("../wasm/wasmModuleFilename");
|
|
12
12
|
|
|
13
13
|
/** @import Chunk from "../Chunk" */
|
|
14
|
+
/** @import ChunkGraph from "../ChunkGraph" */
|
|
14
15
|
/** @import Compilation from "../Compilation" */
|
|
15
16
|
/** @import { RuntimeSpec } from "../util/runtime" */
|
|
16
17
|
|
|
17
18
|
/** @typedef {(wasmModuleSrcPath: string) => string} GenerateBeforeLoadBinaryCode */
|
|
18
|
-
/** @typedef {(wasmModuleSrcPath: string, runtime: RuntimeSpec) => string} GenerateLoadBinaryCode */
|
|
19
|
+
/** @typedef {(wasmModuleSrcPath: string, runtime: RuntimeSpec, analyzable: boolean) => string} GenerateLoadBinaryCode */
|
|
19
20
|
/** @typedef {() => string} GenerateBeforeInstantiateStreaming */
|
|
20
21
|
|
|
21
22
|
/**
|
|
@@ -70,7 +71,7 @@ class AsyncWasmLoadingRuntimeModule extends RuntimeModule {
|
|
|
70
71
|
// Analyzable output bakes the binary's URL into the call site instead.
|
|
71
72
|
const analyzable = runtimeTemplate.supportsAnalyzable(
|
|
72
73
|
"wasm",
|
|
73
|
-
|
|
74
|
+
/** @type {ChunkGraph} */ (this.chunkGraph),
|
|
74
75
|
undefined,
|
|
75
76
|
chunk.runtime
|
|
76
77
|
);
|
|
@@ -93,7 +94,8 @@ class AsyncWasmLoadingRuntimeModule extends RuntimeModule {
|
|
|
93
94
|
|
|
94
95
|
const loader = this.generateLoadBinaryCode(
|
|
95
96
|
wasmModuleSrcPath,
|
|
96
|
-
chunk.runtime
|
|
97
|
+
chunk.runtime,
|
|
98
|
+
analyzable
|
|
97
99
|
);
|
|
98
100
|
const fallback = [
|
|
99
101
|
`.then(${runtimeTemplate.returningFunction("x.arrayBuffer()", "x")})`,
|
|
@@ -67,31 +67,26 @@ class UniversalCompileAsyncWasmPlugin {
|
|
|
67
67
|
// per call: it depends on parse results, so it is not settled while the plugin
|
|
68
68
|
// is being applied.
|
|
69
69
|
/**
|
|
70
|
-
* @param {
|
|
70
|
+
* @param {boolean} analyzable whether the call site bakes a complete URL
|
|
71
71
|
* @returns {string} the argument to hand the reader
|
|
72
72
|
*/
|
|
73
|
-
const wasmUrlArg = (
|
|
74
|
-
|
|
75
|
-
"wasm",
|
|
76
|
-
undefined,
|
|
77
|
-
undefined,
|
|
78
|
-
runtime
|
|
79
|
-
)
|
|
73
|
+
const wasmUrlArg = (analyzable) =>
|
|
74
|
+
analyzable
|
|
80
75
|
? "wasmUrl"
|
|
81
76
|
: compilation.runtimeTemplate.importMetaUrl("wasmUrl");
|
|
82
77
|
/**
|
|
83
78
|
* Generates the runtime expression that fetches the binary in browsers
|
|
84
79
|
* or reads it from the filesystem in Node.js.
|
|
85
|
-
* @type {(path: string, runtime: RuntimeSpec) => string}
|
|
80
|
+
* @type {(path: string, runtime: RuntimeSpec, analyzable: boolean) => string}
|
|
86
81
|
*/
|
|
87
|
-
const generateLoadBinaryCode = (path, runtime) =>
|
|
82
|
+
const generateLoadBinaryCode = (path, runtime, analyzable) =>
|
|
88
83
|
Template.asString([
|
|
89
84
|
"(useFetch",
|
|
90
|
-
Template.indent([`? fetch(${wasmUrlArg(
|
|
85
|
+
Template.indent([`? fetch(${wasmUrlArg(analyzable)})`]),
|
|
91
86
|
Template.indent([
|
|
92
87
|
": Promise.all([import('fs'), import('url')]).then(([{ readFile }, { URL }]) => new Promise((resolve, reject) => {",
|
|
93
88
|
Template.indent([
|
|
94
|
-
`readFile(${wasmUrlArg(
|
|
89
|
+
`readFile(${wasmUrlArg(analyzable)}, (err, buffer) => {`,
|
|
95
90
|
Template.indent([
|
|
96
91
|
"if (err) return reject(err);",
|
|
97
92
|
"",
|
|
@@ -91,12 +91,14 @@ class FetchCompileAsyncWasmPlugin {
|
|
|
91
91
|
}
|
|
92
92
|
const baked = compilation.runtimeTemplate.supportsAnalyzable(
|
|
93
93
|
"wasm",
|
|
94
|
-
|
|
94
|
+
chunkGraph,
|
|
95
95
|
undefined,
|
|
96
96
|
chunk.runtime
|
|
97
97
|
);
|
|
98
|
-
const analyzable =
|
|
99
|
-
|
|
98
|
+
const analyzable = compilation.runtimeTemplate.supportsAnalyzable(
|
|
99
|
+
"wasm-relative",
|
|
100
|
+
chunkGraph
|
|
101
|
+
);
|
|
100
102
|
// A baked URL carries the public path already, and a settled one is written
|
|
101
103
|
// out below; only a path nothing but the global knows asks for it.
|
|
102
104
|
const constant =
|
|
@@ -151,12 +153,14 @@ class FetchCompileAsyncWasmPlugin {
|
|
|
151
153
|
}
|
|
152
154
|
const baked = compilation.runtimeTemplate.supportsAnalyzable(
|
|
153
155
|
"wasm",
|
|
154
|
-
|
|
156
|
+
chunkGraph,
|
|
155
157
|
undefined,
|
|
156
158
|
chunk.runtime
|
|
157
159
|
);
|
|
158
|
-
const analyzable =
|
|
159
|
-
|
|
160
|
+
const analyzable = compilation.runtimeTemplate.supportsAnalyzable(
|
|
161
|
+
"wasm-relative",
|
|
162
|
+
chunkGraph
|
|
163
|
+
);
|
|
160
164
|
// A baked URL carries the public path already, and a settled one is written
|
|
161
165
|
// out below; only a path nothing but the global knows asks for it.
|
|
162
166
|
const constant =
|
|
@@ -99,8 +99,10 @@ class FetchCompileWasmPlugin {
|
|
|
99
99
|
return;
|
|
100
100
|
}
|
|
101
101
|
set.add(RuntimeGlobals.moduleCache);
|
|
102
|
-
const analyzable =
|
|
103
|
-
|
|
102
|
+
const analyzable = compilation.runtimeTemplate.supportsAnalyzable(
|
|
103
|
+
"wasm-relative",
|
|
104
|
+
chunkGraph
|
|
105
|
+
);
|
|
104
106
|
const constant = analyzable
|
|
105
107
|
? undefined
|
|
106
108
|
: compilation.runtimeTemplate.constantPublicPath();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "webpack",
|
|
3
|
-
"version": "5.110.
|
|
3
|
+
"version": "5.110.2",
|
|
4
4
|
"description": "Packs ECMAScript/CommonJs/AMD modules for the browser. Allows you to split your codebase into multiple bundles, which can be loaded on demand. Supports loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.",
|
|
5
5
|
"homepage": "https://github.com/webpack/webpack",
|
|
6
6
|
"bugs": "https://github.com/webpack/webpack/issues",
|