webpack 5.107.0 → 5.107.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/lib/BannerPlugin.js +3 -4
- package/lib/Chunk.js +21 -25
- package/lib/ChunkGroup.js +57 -15
- package/lib/Compilation.js +33 -11
- package/lib/Compiler.js +27 -3
- package/lib/ContextModuleFactory.js +45 -38
- package/lib/EvalSourceMapDevToolPlugin.js +0 -1
- package/lib/ExportsInfo.js +30 -34
- package/lib/ExternalModule.js +15 -11
- package/lib/ExternalModuleFactoryPlugin.js +2 -1
- package/lib/Module.js +1 -1
- package/lib/ModuleNotFoundError.js +10 -0
- package/lib/ModuleSourceTypeConstants.js +24 -22
- package/lib/MultiCompiler.js +14 -0
- package/lib/NormalModule.js +531 -53
- package/lib/NormalModuleFactory.js +38 -26
- package/lib/ProgressPlugin.js +1 -1
- package/lib/RuntimePlugin.js +1 -1
- package/lib/SourceMapDevToolPlugin.js +335 -57
- package/lib/Template.js +1 -1
- package/lib/TemplatedPathPlugin.js +22 -4
- package/lib/asset/AssetBytesGenerator.js +6 -6
- package/lib/asset/AssetGenerator.js +14 -14
- package/lib/asset/AssetModulesPlugin.js +3 -7
- package/lib/asset/AssetSourceGenerator.js +6 -6
- package/lib/buildChunkGraph.js +24 -2
- package/lib/cache/getLazyHashedEtag.js +9 -2
- package/lib/css/CssModulesPlugin.js +2 -2
- package/lib/dependencies/CommonJsImportsParserPlugin.js +108 -1
- package/lib/dependencies/CssUrlDependency.js +3 -2
- package/lib/dependencies/HarmonyDetectionParserPlugin.js +21 -1
- package/lib/dependencies/HarmonyExportInitFragment.js +8 -9
- package/lib/dependencies/HtmlInlineScriptDependency.js +3 -14
- package/lib/dependencies/HtmlInlineStyleDependency.js +17 -0
- package/lib/dependencies/HtmlScriptSrcDependency.js +265 -65
- package/lib/dependencies/HtmlSourceDependency.js +21 -2
- package/lib/dependencies/WorkerPlugin.js +18 -4
- package/lib/hmr/LazyCompilationPlugin.js +104 -0
- package/lib/html/HtmlGenerator.js +81 -33
- package/lib/html/HtmlModulesPlugin.js +87 -28
- package/lib/html/walkHtmlTokens.js +641 -125
- package/lib/index.js +2 -0
- package/lib/javascript/JavascriptModulesPlugin.js +2 -2
- package/lib/javascript/JavascriptParser.js +1 -1
- package/lib/library/ModuleLibraryPlugin.js +30 -24
- package/lib/node/NodeWatchFileSystem.js +37 -22
- package/lib/optimize/ConcatenatedModule.js +3 -2
- package/lib/optimize/SideEffectsFlagPlugin.js +1 -2
- package/lib/optimize/SplitChunksPlugin.js +4 -4
- package/lib/runtime/AutoPublicPathRuntimeModule.js +3 -3
- package/lib/runtime/GetChunkFilenameRuntimeModule.js +5 -5
- package/lib/sharing/ConsumeSharedPlugin.js +2 -8
- package/lib/sharing/ProvideSharedPlugin.js +4 -4
- package/lib/util/fs.js +6 -1
- package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +1 -2
- package/package.json +5 -5
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +11 -9
- package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
- package/schemas/plugins/container/ContainerReferencePlugin.json +1 -0
- package/schemas/plugins/container/ExternalsType.check.js +1 -1
- package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
- package/schemas/plugins/container/ModuleFederationPlugin.json +1 -0
- package/types.d.ts +472 -149
|
@@ -17,6 +17,8 @@ const CssUrlDependency = require("../dependencies/CssUrlDependency");
|
|
|
17
17
|
|
|
18
18
|
/** @typedef {import("webpack-sources").Source} Source */
|
|
19
19
|
/** @typedef {import("../../declarations/WebpackOptions").HtmlGeneratorOptions} HtmlGeneratorOptions */
|
|
20
|
+
/** @typedef {import("../Chunk")} Chunk */
|
|
21
|
+
/** @typedef {import("../Compilation")} Compilation */
|
|
20
22
|
/** @typedef {import("../Compilation").DependencyConstructor} DependencyConstructor */
|
|
21
23
|
/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
|
|
22
24
|
/** @typedef {import("../Dependency")} Dependency */
|
|
@@ -39,7 +41,76 @@ const CssUrlDependency = require("../dependencies/CssUrlDependency");
|
|
|
39
41
|
*/
|
|
40
42
|
const JAVASCRIPT_AND_HTML_TYPES = new Set([JAVASCRIPT_TYPE, HTML_TYPE]);
|
|
41
43
|
|
|
44
|
+
/** @type {WeakMap<Compilation, Map<string, Chunk>>} */
|
|
45
|
+
const chunksByIdCache = new WeakMap();
|
|
46
|
+
|
|
42
47
|
class HtmlGenerator extends Generator {
|
|
48
|
+
/**
|
|
49
|
+
* Emit a sentinel for a chunk URL that can't be resolved at code-gen time
|
|
50
|
+
* (chunk hashes aren't computed yet); `resolveChunkUrlSentinels` swaps it
|
|
51
|
+
* for `${PUBLIC_PATH_AUTO}<chunkFilename>` once they are.
|
|
52
|
+
* @param {Chunk} chunk chunk
|
|
53
|
+
* @param {"javascript" | "css"} contentHashType which chunk content hash slot the resolved URL should reference
|
|
54
|
+
* @returns {string} sentinel
|
|
55
|
+
*/
|
|
56
|
+
static makeChunkUrlSentinel(chunk, contentHashType) {
|
|
57
|
+
const hexId = Buffer.from(String(chunk.id), "utf8").toString("hex");
|
|
58
|
+
return `__WEBPACK_HTML_CHUNK_URL__${hexId}__${contentHashType}__END__`;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Replace every `makeChunkUrlSentinel` sentinel in `content` with
|
|
63
|
+
* `${PUBLIC_PATH_AUTO}<chunkFilename>`. Must run after
|
|
64
|
+
* `Compilation#createHash()` so `[contenthash]` resolves.
|
|
65
|
+
* @param {string} content content
|
|
66
|
+
* @param {Compilation} compilation compilation
|
|
67
|
+
* @returns {string} resolved content
|
|
68
|
+
*/
|
|
69
|
+
static resolveChunkUrlSentinels(content, compilation) {
|
|
70
|
+
if (!content.includes("__WEBPACK_HTML_CHUNK_URL__")) return content;
|
|
71
|
+
const outputOptions = compilation.outputOptions;
|
|
72
|
+
let chunksById = chunksByIdCache.get(compilation);
|
|
73
|
+
if (chunksById === undefined) {
|
|
74
|
+
chunksById = new Map();
|
|
75
|
+
for (const chunk of compilation.chunks) {
|
|
76
|
+
chunksById.set(String(chunk.id), chunk);
|
|
77
|
+
}
|
|
78
|
+
chunksByIdCache.set(compilation, chunksById);
|
|
79
|
+
}
|
|
80
|
+
return content.replace(
|
|
81
|
+
/__WEBPACK_HTML_CHUNK_URL__([0-9a-f]+)__([a-z]+)__END__/g,
|
|
82
|
+
(_, hexId, contentHashType) => {
|
|
83
|
+
const chunkId = Buffer.from(hexId, "hex").toString("utf8");
|
|
84
|
+
const chunk = chunksById.get(chunkId);
|
|
85
|
+
if (!chunk) return "data:,";
|
|
86
|
+
let filenameTemplate;
|
|
87
|
+
if (contentHashType === "css") {
|
|
88
|
+
const CssModulesPlugin = require("../css/CssModulesPlugin");
|
|
89
|
+
|
|
90
|
+
filenameTemplate = CssModulesPlugin.getChunkFilenameTemplate(
|
|
91
|
+
chunk,
|
|
92
|
+
outputOptions
|
|
93
|
+
);
|
|
94
|
+
} else {
|
|
95
|
+
filenameTemplate =
|
|
96
|
+
chunk.filenameTemplate ||
|
|
97
|
+
(chunk.canBeInitial()
|
|
98
|
+
? outputOptions.filename
|
|
99
|
+
: outputOptions.chunkFilename);
|
|
100
|
+
}
|
|
101
|
+
const filename = compilation.getPath(
|
|
102
|
+
/** @type {import("../TemplatedPathPlugin").TemplatePath} */
|
|
103
|
+
(filenameTemplate),
|
|
104
|
+
{
|
|
105
|
+
chunk,
|
|
106
|
+
contentHashType
|
|
107
|
+
}
|
|
108
|
+
);
|
|
109
|
+
return `${CssUrlDependency.PUBLIC_PATH_AUTO}${filename}`;
|
|
110
|
+
}
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
43
114
|
/**
|
|
44
115
|
* Creates an instance of HtmlGenerator.
|
|
45
116
|
* @param {HtmlGeneratorOptions=} options generator options
|
|
@@ -268,28 +339,15 @@ class HtmlGenerator extends Generator {
|
|
|
268
339
|
this.sourceModule(module, initFragments, source, generateContext);
|
|
269
340
|
|
|
270
341
|
if (undoPath === undefined) {
|
|
342
|
+
// HTML output — leave sentinels and `[webpack/auto]` for renderManifest.
|
|
271
343
|
return /** @type {string} */ (source.source());
|
|
272
344
|
}
|
|
273
345
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
for (
|
|
280
|
-
let idx = moduleSourceContent.indexOf(autoPlaceholder);
|
|
281
|
-
idx !== -1;
|
|
282
|
-
idx = moduleSourceContent.indexOf(
|
|
283
|
-
autoPlaceholder,
|
|
284
|
-
idx + autoPlaceholderLen
|
|
285
|
-
)
|
|
286
|
-
) {
|
|
287
|
-
generatedSource.replace(idx, idx + autoPlaceholderLen - 1, undoPath);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
// TODO handle `[fullhash]`
|
|
291
|
-
|
|
292
|
-
return /** @type {string} */ (generatedSource.source());
|
|
346
|
+
// JS-export path — resolve `[webpack/auto]` inline; chunk-URL sentinels
|
|
347
|
+
// stay for `HtmlModulesPlugin`'s `JavascriptModulesPlugin.render` tap.
|
|
348
|
+
let content = /** @type {string} */ (source.source());
|
|
349
|
+
content = content.split(CssUrlDependency.PUBLIC_PATH_AUTO).join(undoPath);
|
|
350
|
+
return content;
|
|
293
351
|
}
|
|
294
352
|
|
|
295
353
|
/**
|
|
@@ -306,16 +364,13 @@ class HtmlGenerator extends Generator {
|
|
|
306
364
|
}
|
|
307
365
|
|
|
308
366
|
if (generateContext.type === HTML_TYPE) {
|
|
309
|
-
// Preserve `[webpack/auto]
|
|
310
|
-
// `renderManifest` hook knows the final `.html` filename and
|
|
311
|
-
// resolves them to an undo path relative to that location.
|
|
367
|
+
// Preserve `[webpack/auto]`; renderManifest resolves it once `.html` filename is known.
|
|
312
368
|
return new RawSource(
|
|
313
369
|
this._renderHtml(module, generateContext, undefined)
|
|
314
370
|
);
|
|
315
371
|
}
|
|
316
372
|
|
|
317
|
-
// JS export:
|
|
318
|
-
// runtime, so resolve placeholders to root-relative URLs.
|
|
373
|
+
// JS export: resolve `[webpack/auto]` to root-relative URLs.
|
|
319
374
|
const generated = this._renderHtml(module, generateContext, "");
|
|
320
375
|
|
|
321
376
|
/** @type {string} */
|
|
@@ -346,10 +401,7 @@ class HtmlGenerator extends Generator {
|
|
|
346
401
|
*/
|
|
347
402
|
generateError(error, module, generateContext) {
|
|
348
403
|
if (generateContext.type === HTML_TYPE) {
|
|
349
|
-
//
|
|
350
|
-
// input, dep request strings). Strip `<`, `>`, and `--` runs so a
|
|
351
|
-
// crafted message can't close the comment with `-->` (or open a
|
|
352
|
-
// fake nested comment) and inject HTML into the extracted page.
|
|
404
|
+
// Strip `<`, `>`, `--` runs from `error.message` so it can't escape the comment.
|
|
353
405
|
const safe = String(error.message)
|
|
354
406
|
.replace(/[<>]/g, "")
|
|
355
407
|
.replace(/-{2,}/g, (m) => `${"-".repeat(m.length - 1)} `);
|
|
@@ -365,11 +417,7 @@ class HtmlGenerator extends Generator {
|
|
|
365
417
|
*/
|
|
366
418
|
updateHash(hash, updateHashContext) {
|
|
367
419
|
hash.update("html");
|
|
368
|
-
// Hash
|
|
369
|
-
// so the module hash flips when a module becomes (or stops being)
|
|
370
|
-
// a compilation entry under the `extract: undefined` default — the
|
|
371
|
-
// generator's source-type set changes with it, so any cached
|
|
372
|
-
// HTML-type codegen result must be invalidated.
|
|
420
|
+
// Hash effective extraction state — source-type set changes when this flips.
|
|
373
421
|
if (this._shouldExtract(updateHashContext.module)) {
|
|
374
422
|
hash.update("extract");
|
|
375
423
|
}
|
|
@@ -45,12 +45,43 @@ const generatorValidationOptions = {
|
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
class HtmlModulesPlugin {
|
|
48
|
+
/**
|
|
49
|
+
* `output.hashFunction`/`hashSalt`/`hashDigest`/`hashDigestLength`
|
|
50
|
+
* digest of `content`, with `nonNumericOnlyHash` applied — webpack's
|
|
51
|
+
* standard `[contenthash]` recipe.
|
|
52
|
+
* @param {string | Buffer} content content to hash
|
|
53
|
+
* @param {import("../../declarations/WebpackOptions").Output} outputOptions output options
|
|
54
|
+
* @returns {string} content hash
|
|
55
|
+
*/
|
|
56
|
+
static computeContentHash(content, outputOptions) {
|
|
57
|
+
const createHash = require("../util/createHash");
|
|
58
|
+
const nonNumericOnlyHash = require("../util/nonNumericOnlyHash");
|
|
59
|
+
|
|
60
|
+
const hash = createHash(
|
|
61
|
+
/** @type {import("../../declarations/WebpackOptions").HashFunction} */
|
|
62
|
+
(outputOptions.hashFunction)
|
|
63
|
+
);
|
|
64
|
+
if (outputOptions.hashSalt) hash.update(outputOptions.hashSalt);
|
|
65
|
+
hash.update(content);
|
|
66
|
+
return nonNumericOnlyHash(
|
|
67
|
+
/** @type {string} */ (
|
|
68
|
+
hash.digest(/** @type {string} */ (outputOptions.hashDigest))
|
|
69
|
+
),
|
|
70
|
+
/** @type {number} */ (outputOptions.hashDigestLength)
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
48
74
|
/**
|
|
49
75
|
* Applies the plugin by registering its hooks on the compiler.
|
|
50
76
|
* @param {Compiler} compiler the compiler instance
|
|
51
77
|
* @returns {void}
|
|
52
78
|
*/
|
|
53
79
|
apply(compiler) {
|
|
80
|
+
// Per-chunk `RawSource` reused across builds when bytes are unchanged:
|
|
81
|
+
// keeping identity stable avoids invalidating `RealContentHashPlugin|analyse`.
|
|
82
|
+
/** @type {Map<string, { content: string, source: import("webpack-sources").RawSource }>} */
|
|
83
|
+
const sentinelResolvedSourceCache = new Map();
|
|
84
|
+
|
|
54
85
|
// `<script src>` and `<link rel="modulepreload">` references collected
|
|
55
86
|
// by HtmlParser become real compilation entries here. The classic
|
|
56
87
|
// and esm-script groups are chained via a leader-only dependOn so
|
|
@@ -255,11 +286,7 @@ class HtmlModulesPlugin {
|
|
|
255
286
|
options
|
|
256
287
|
)
|
|
257
288
|
);
|
|
258
|
-
return new HtmlGenerator(
|
|
259
|
-
/** @type {import("../../declarations/WebpackOptions").HtmlGeneratorOptions} */
|
|
260
|
-
(generatorOptions),
|
|
261
|
-
compilation.moduleGraph
|
|
262
|
-
);
|
|
289
|
+
return new HtmlGenerator(generatorOptions, compilation.moduleGraph);
|
|
263
290
|
});
|
|
264
291
|
|
|
265
292
|
NormalModule.getCompilationHooks(compilation).processResult.tap(
|
|
@@ -300,8 +327,6 @@ class HtmlModulesPlugin {
|
|
|
300
327
|
getUndoPath,
|
|
301
328
|
makePathsRelative
|
|
302
329
|
} = require("../util/identifier");
|
|
303
|
-
const createHash = require("../util/createHash");
|
|
304
|
-
const nonNumericOnlyHash = require("../util/nonNumericOnlyHash");
|
|
305
330
|
const CssUrlDependency = require("../dependencies/CssUrlDependency");
|
|
306
331
|
|
|
307
332
|
const autoPlaceholder = CssUrlDependency.PUBLIC_PATH_AUTO;
|
|
@@ -346,17 +371,15 @@ class HtmlModulesPlugin {
|
|
|
346
371
|
const placeholderContent = /** @type {string} */ (
|
|
347
372
|
placeholderSource.source()
|
|
348
373
|
);
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
const fullContentHash = /** @type {string} */ (
|
|
355
|
-
hashInput.digest(outputOptions.hashDigest)
|
|
374
|
+
// Resolve sentinels *before* hashing so the HTML's `[contenthash]`
|
|
375
|
+
// invalidates with the referenced chunks' filenames.
|
|
376
|
+
const resolvedContent = HtmlGenerator.resolveChunkUrlSentinels(
|
|
377
|
+
placeholderContent,
|
|
378
|
+
compilation
|
|
356
379
|
);
|
|
357
|
-
const contentHash =
|
|
358
|
-
|
|
359
|
-
outputOptions
|
|
380
|
+
const contentHash = HtmlModulesPlugin.computeContentHash(
|
|
381
|
+
resolvedContent,
|
|
382
|
+
outputOptions
|
|
360
383
|
);
|
|
361
384
|
|
|
362
385
|
const { path: filename, info } = compilation.getPathWithInfo(
|
|
@@ -386,7 +409,7 @@ class HtmlModulesPlugin {
|
|
|
386
409
|
/** @type {string} */ (outputOptions.path),
|
|
387
410
|
false
|
|
388
411
|
);
|
|
389
|
-
const finalContent =
|
|
412
|
+
const finalContent = resolvedContent
|
|
390
413
|
.split(autoPlaceholder)
|
|
391
414
|
.join(undoPath);
|
|
392
415
|
const finalSource = new RawSource(finalContent);
|
|
@@ -399,16 +422,9 @@ class HtmlModulesPlugin {
|
|
|
399
422
|
// the post-undo-path content in the hash, so the
|
|
400
423
|
// asset cache can't reuse one variant's bytes at
|
|
401
424
|
// another variant's URL.
|
|
402
|
-
const
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
}
|
|
406
|
-
finalHash.update(finalContent);
|
|
407
|
-
const finalContentHash = nonNumericOnlyHash(
|
|
408
|
-
/** @type {string} */ (
|
|
409
|
-
finalHash.digest(outputOptions.hashDigest)
|
|
410
|
-
),
|
|
411
|
-
outputOptions.hashDigestLength
|
|
425
|
+
const finalContentHash = HtmlModulesPlugin.computeContentHash(
|
|
426
|
+
finalContent,
|
|
427
|
+
outputOptions
|
|
412
428
|
);
|
|
413
429
|
|
|
414
430
|
result.push({
|
|
@@ -425,6 +441,49 @@ class HtmlModulesPlugin {
|
|
|
425
441
|
return result;
|
|
426
442
|
}
|
|
427
443
|
);
|
|
444
|
+
|
|
445
|
+
// Resolve sentinels at JS chunk render time so later passes
|
|
446
|
+
// (SourceMapDevToolPlugin, size optimizers, RealContentHash) see resolved bytes.
|
|
447
|
+
const JavascriptModulesPlugin = require("../javascript/JavascriptModulesPlugin");
|
|
448
|
+
|
|
449
|
+
const jsHooks =
|
|
450
|
+
JavascriptModulesPlugin.getCompilationHooks(compilation);
|
|
451
|
+
jsHooks.render.tap(PLUGIN_NAME, (source, renderContext) => {
|
|
452
|
+
const raw = source.source();
|
|
453
|
+
if (typeof raw !== "string") return source;
|
|
454
|
+
if (!raw.includes("__WEBPACK_HTML_CHUNK_URL__")) return source;
|
|
455
|
+
const resolved = HtmlGenerator.resolveChunkUrlSentinels(
|
|
456
|
+
raw,
|
|
457
|
+
compilation
|
|
458
|
+
)
|
|
459
|
+
.split(autoPlaceholder)
|
|
460
|
+
.join("");
|
|
461
|
+
if (resolved === raw) return source;
|
|
462
|
+
const chunkId = String(renderContext.chunk.id);
|
|
463
|
+
const prior = sentinelResolvedSourceCache.get(chunkId);
|
|
464
|
+
if (prior !== undefined && prior.content === resolved) {
|
|
465
|
+
return prior.source;
|
|
466
|
+
}
|
|
467
|
+
const newSource = new RawSource(resolved);
|
|
468
|
+
sentinelResolvedSourceCache.set(chunkId, {
|
|
469
|
+
content: resolved,
|
|
470
|
+
source: newSource
|
|
471
|
+
});
|
|
472
|
+
return newSource;
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
// Prune cache entries for chunks no longer in the graph so a
|
|
476
|
+
// long watch session can't accumulate stale entries.
|
|
477
|
+
compilation.hooks.afterSeal.tap(PLUGIN_NAME, () => {
|
|
478
|
+
if (sentinelResolvedSourceCache.size === 0) return;
|
|
479
|
+
const live = new Set();
|
|
480
|
+
for (const chunk of compilation.chunks) {
|
|
481
|
+
live.add(String(chunk.id));
|
|
482
|
+
}
|
|
483
|
+
for (const id of sentinelResolvedSourceCache.keys()) {
|
|
484
|
+
if (!live.has(id)) sentinelResolvedSourceCache.delete(id);
|
|
485
|
+
}
|
|
486
|
+
});
|
|
428
487
|
}
|
|
429
488
|
);
|
|
430
489
|
}
|