webpack 5.110.3 → 5.111.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.
- package/README.md +5 -0
- package/lib/APIPlugin.js +23 -7
- package/lib/AutomaticPrefetchPlugin.js +1 -1
- package/lib/Cache.js +8 -3
- package/lib/CacheFacade.js +1 -1
- package/lib/CircularModulesPlugin.js +157 -55
- package/lib/CleanPlugin.js +2 -2
- package/lib/Compilation.js +320 -302
- package/lib/Compiler.js +209 -46
- package/lib/ContextModule.js +17 -81
- package/lib/ContextModuleFactory.js +1 -1
- package/lib/CopyPlugin.js +1054 -0
- package/lib/DefinePlugin.js +24 -8
- package/lib/ExternalModule.js +41 -14
- package/lib/FileSystemInfo.js +17 -14
- package/lib/FlagDependencyExportsPlugin.js +45 -21
- package/lib/HotModuleReplacementPlugin.js +53 -7
- package/lib/JavascriptMetaInfoPlugin.js +5 -3
- package/lib/MainTemplate.js +5 -1
- package/lib/Module.js +16 -7
- package/lib/MultiCompiler.js +1 -1
- package/lib/MultiWatching.js +1 -1
- package/lib/NormalModule.js +45 -12
- package/lib/NormalModuleFactory.js +1 -1
- package/lib/RuntimeGlobals.js +21 -7
- package/lib/RuntimeModule.js +28 -12
- package/lib/RuntimePlugin.js +30 -3
- package/lib/RuntimeTemplate.js +780 -475
- package/lib/SourceMapDevToolPlugin.js +1 -1
- package/lib/Watching.js +9 -0
- package/lib/WebpackOptionsApply.js +84 -91
- package/lib/asset/AssetGenerator.js +25 -8
- package/lib/asset/AssetModule.js +3 -0
- package/lib/asset/WebManifestParser.js +7 -5
- package/lib/cache/AddBuildDependenciesPlugin.js +33 -4
- package/lib/cache/IdleFileCachePlugin.js +2 -2
- package/lib/cache/PackFileCacheStrategy.js +14 -1
- package/lib/config/browserslistTargetHandler.js +19 -0
- package/lib/config/defaults.js +86 -50
- package/lib/config/normalization.js +82 -12
- package/lib/config/target.js +10 -0
- package/lib/container/ContainerReferencePlugin.js +6 -0
- package/lib/container/RemoteRuntimeModule.js +9 -0
- package/lib/container/declaredRemotes.js +39 -0
- package/lib/css/CssGenerator.js +8 -0
- package/lib/css/CssInjectStyleRuntimeModule.js +9 -0
- package/lib/css/CssLoadingRuntimeModule.js +94 -36
- package/lib/css/CssModule.js +1 -1
- package/lib/css/CssModulesPlugin.js +7 -6
- package/lib/css/CssParser.js +144 -11
- package/lib/css/CssServerStylesRuntimeModule.js +9 -0
- package/lib/css/cssMinify.js +11 -3
- package/lib/css/data.js +2814 -678
- package/lib/css/syntax.js +4082 -248
- package/lib/debug/ProfilingPlugin.js +4 -0
- package/lib/dependencies/AMDDefineDependencyParserPlugin.js +6 -3
- package/lib/dependencies/AMDRuntimeModules.js +18 -0
- package/lib/dependencies/CommonJsExportRequireDependency.js +3 -1
- package/lib/dependencies/CommonJsExportsParserPlugin.js +12 -13
- package/lib/dependencies/CommonJsImportsParserPlugin.js +1 -0
- package/lib/dependencies/CommonJsPlugin.js +19 -3
- package/lib/dependencies/CommonJsRequireDependency.js +14 -5
- package/lib/dependencies/CssIcssExportDependency.js +7 -1
- package/lib/dependencies/HarmonyCompatibilityDependency.js +58 -4
- package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +8 -3
- package/lib/dependencies/HarmonyExportExpressionDependency.js +44 -29
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +71 -13
- package/lib/dependencies/HarmonyExportInitFragment.js +99 -19
- package/lib/dependencies/HarmonyExportSpecifierDependency.js +18 -30
- package/lib/dependencies/HarmonyImportBareSideEffectDependency.js +59 -0
- package/lib/dependencies/HarmonyImportDependency.js +6 -1
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +8 -1
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +24 -1
- package/lib/dependencies/HarmonyModulesPlugin.js +20 -0
- package/lib/dependencies/HtmlEntryDependency.js +50 -0
- package/lib/dependencies/ImportMetaMainDependency.js +104 -0
- package/lib/dependencies/ImportMetaPlugin.js +59 -15
- package/lib/dependencies/SystemRuntimeModule.js +9 -0
- package/lib/dependencies/WorkerDependency.js +1 -2
- package/lib/dependencies/WorkletDependency.js +1 -2
- package/lib/dll/DelegatedModule.js +18 -1
- package/lib/dll/DllReferencePlugin.js +11 -8
- package/lib/dll/LibManifestPlugin.js +1 -1
- package/lib/errors/AnalyzableBailoutsWarning.js +41 -0
- package/lib/errors/DuplicateModulesWarning.js +12 -7
- package/lib/errors/EmptyCopyPatternWarning.js +26 -0
- package/lib/errors/ExternalStarReexportError.js +44 -0
- package/lib/errors/MissingSourceMapsWarning.js +36 -0
- package/lib/errors/ModuleParseError.js +2 -1
- package/lib/errors/UnusedAssetsWarning.js +36 -0
- package/lib/errors/UnusedFederationWarning.js +35 -0
- package/lib/errors/UnusedModulesWarning.js +38 -0
- package/lib/esm/ExportWebpackRequireRuntimeModule.js +9 -0
- package/lib/esm/ModuleChunkFormatPlugin.js +28 -3
- package/lib/esm/ModuleChunkLoadingPlugin.js +30 -11
- package/lib/esm/ModuleChunkLoadingRuntimeModule.js +92 -60
- package/lib/hmr/HotModuleReplacement.runtime.js +8 -2
- package/lib/hmr/HotModuleReplacementRuntimeModule.js +9 -0
- package/lib/html/HtmlGenerator.js +11 -5
- package/lib/html/HtmlModulesPlugin.js +331 -62
- package/lib/html/HtmlParser.js +13 -6
- package/lib/html/builtinEmbeddedRenderer.js +107 -0
- package/lib/html/data.js +121 -7
- package/lib/html/htmlMinify.js +84 -113
- package/lib/html/syntax.js +763 -426
- package/lib/ids/HashedModuleIdsPlugin.js +2 -1
- package/lib/index.js +3 -0
- package/lib/javascript/JavascriptModule.js +1 -0
- package/lib/javascript/JavascriptModulesPlugin.js +52 -24
- package/lib/javascript/JavascriptParser.js +1255 -728
- package/lib/javascript/StartupHelpers.js +27 -3
- package/lib/javascript/data.js +172 -0
- package/lib/javascript/grammar.js +5546 -0
- package/lib/javascript/parser.js +1494 -0
- package/lib/javascript/regexp.js +1762 -0
- package/lib/javascript/regexpData.js +51 -0
- package/lib/javascript/syntax.js +8696 -5225
- package/lib/library/ModuleLibraryPlugin.js +116 -5
- package/lib/node/ReadFileChunkLoadingRuntimeModule.js +22 -0
- package/lib/node/RequireChunkLoadingRuntimeModule.js +22 -0
- package/lib/optimize/ConcatenatedModule.js +97 -20
- package/lib/optimize/ConstExportsPlugin.js +50 -39
- package/lib/optimize/InlineExports.js +20 -123
- package/lib/optimize/MangleExportsPlugin.js +10 -0
- package/lib/optimize/ModuleConcatenationPlugin.js +24 -1
- package/lib/optimize/RealContentHashPlugin.js +68 -9
- package/lib/optimize/SideEffectsFlagPlugin.js +17 -9
- package/lib/performance/AnalyzableBailoutsPlugin.js +115 -0
- package/lib/performance/CacheEffectivenessPlugin.js +4 -3
- package/lib/performance/DuplicateModulesPlugin.js +57 -13
- package/lib/performance/EvalUsagePlugin.js +5 -2
- package/lib/performance/MissingSourceMapsPlugin.js +115 -0
- package/lib/performance/PureAnnotationsPlugin.js +6 -3
- package/lib/performance/TopLevelThisPlugin.js +5 -4
- package/lib/performance/UnusedAssetsPlugin.js +109 -0
- package/lib/performance/UnusedFederationPlugin.js +147 -0
- package/lib/performance/UnusedModulesPlugin.js +141 -0
- package/lib/performance/UnusedReexportsPlugin.js +1 -55
- package/lib/performance/isOnlyReexported.js +65 -0
- package/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js +25 -5
- package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +2 -0
- package/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js +9 -0
- package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +9 -0
- package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +9 -0
- package/lib/prefetch/ResourceHintPlugin.js +1 -2
- package/lib/prefetch/ResourceHintRuntimeModule.js +9 -0
- package/lib/prefetch/StartupAssetHintRuntimeModule.js +9 -0
- package/lib/rules/RuleSetCompiler.js +211 -4
- package/lib/runtime/AsyncModuleRuntimeModule.js +100 -66
- package/lib/runtime/AutoPublicPathRuntimeModule.js +9 -0
- package/lib/runtime/BaseUriRuntimeModule.js +9 -0
- package/lib/runtime/ChunkNameRuntimeModule.js +9 -0
- package/lib/runtime/EnsureChunkRuntimeModule.js +35 -16
- package/lib/runtime/GetChunkFilenameRuntimeModule.js +9 -0
- package/lib/runtime/GetFullHashRuntimeModule.js +9 -0
- package/lib/runtime/GetMainFilenameRuntimeModule.js +9 -0
- package/lib/runtime/GetWorkletBootstrapRuntimeModule.js +9 -0
- package/lib/runtime/GlobalRuntimeModule.js +9 -0
- package/lib/runtime/HasOwnPropertyRuntimeModule.js +9 -0
- package/lib/runtime/HelperRuntimeModule.js +10 -0
- package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +330 -219
- package/lib/runtime/NonceRuntimeModule.js +9 -0
- package/lib/runtime/OnChunksLoadedRuntimeModule.js +67 -20
- package/lib/runtime/PublicPathRuntimeModule.js +9 -0
- package/lib/runtime/RuntimeIdRuntimeModule.js +9 -0
- package/lib/runtime/SpecNamespaceObjectRuntimeModule.js +90 -0
- package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +9 -0
- package/lib/runtime/StartupEntrypointRuntimeModule.js +9 -0
- package/lib/runtime/SystemContextRuntimeModule.js +9 -0
- package/lib/runtime/ToBinaryRuntimeModule.js +9 -0
- package/lib/serialization/ObjectMiddleware.js +138 -106
- package/lib/sharing/ConsumeSharedPlugin.js +12 -0
- package/lib/sharing/ConsumeSharedRuntimeModule.js +11 -0
- package/lib/sharing/ShareRuntimeModule.js +9 -0
- package/lib/sharing/declaredShared.js +47 -0
- package/lib/stats/DefaultStatsFactoryPlugin.js +3 -1
- package/lib/stats/DefaultStatsPrinterPlugin.js +3 -0
- package/lib/util/SourceProcessor.js +76 -69
- package/lib/util/async.js +292 -0
- package/lib/util/buildDiagnostics.js +69 -0
- package/lib/util/fs.js +27 -1
- package/lib/util/handlerKeys.js +40 -0
- package/lib/util/identifier.js +20 -0
- package/lib/util/internalSerializables.js +4 -0
- package/lib/util/registerExternalSerializer.js +6 -45
- package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +9 -0
- package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +9 -0
- package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +9 -0
- package/lib/web/JsonpChunkLoadingRuntimeModule.js +36 -0
- package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +19 -0
- package/package.json +22 -16
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +379 -66
- package/schemas/plugins/LoaderOptionsPlugin.check.js +1 -1
- package/schemas/plugins/ManifestPlugin.check.js +1 -1
- package/schemas/plugins/SourceMapDevToolPlugin.check.js +1 -1
- package/schemas/plugins/asset/AssetGeneratorOptions.check.js +1 -1
- package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js +1 -1
- package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
- package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
- package/schemas/plugins/debug/ProfilingPlugin.check.js +1 -1
- package/schemas/plugins/dll/DllReferencePlugin.check.js +1 -1
- package/schemas/plugins/ids/HashedModuleIdsPlugin.check.js +1 -1
- package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
- package/types.d.ts +1414 -314
- package/lib/dependencies/ExportBindingInitFragment.js +0 -191
- package/lib/errors/EntrypointOverlapWarning.js +0 -45
- package/lib/performance/EntrypointOverlapPlugin.js +0 -122
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
"use strict";
|
|
6
6
|
|
|
7
|
+
const { basename, extname } = require("path");
|
|
7
8
|
const { pathToFileURL } = require("url");
|
|
8
9
|
const { AsyncSeriesHook, AsyncSeriesWaterfallHook } = require("tapable");
|
|
9
10
|
const { RawSource } = require("webpack-sources");
|
|
@@ -19,10 +20,18 @@ const ConstDependency = require("../dependencies/ConstDependency");
|
|
|
19
20
|
const StaticExportsDependency = require("../dependencies/StaticExportsDependency");
|
|
20
21
|
const WebpackError = require("../errors/WebpackError");
|
|
21
22
|
const JavascriptModulesPlugin = require("../javascript/JavascriptModulesPlugin");
|
|
22
|
-
const
|
|
23
|
+
const ConcatenatedModule = require("../optimize/ConcatenatedModule");
|
|
24
|
+
const {
|
|
25
|
+
compareModulesByFullName,
|
|
26
|
+
compareModulesByIdentifier
|
|
27
|
+
} = require("../util/comparators");
|
|
23
28
|
const createHash = require("../util/createHash");
|
|
24
29
|
const createHooksRegistry = require("../util/createHooksRegistry");
|
|
25
|
-
const {
|
|
30
|
+
const {
|
|
31
|
+
getUndoPath,
|
|
32
|
+
makePathsRelative,
|
|
33
|
+
parseResource
|
|
34
|
+
} = require("../util/identifier");
|
|
26
35
|
const implicitTypeLoaderFallback = require("../util/implicitTypeLoaderFallback");
|
|
27
36
|
const lazyModule = require("../util/lazyModule");
|
|
28
37
|
const memoize = require("../util/memoize");
|
|
@@ -45,20 +54,41 @@ const getHtmlParser = lazyModule(() => require("./HtmlParser"));
|
|
|
45
54
|
// html generation only happens once a build actually has an html module
|
|
46
55
|
const getHtmlGenerator = memoize(() => require("./HtmlGenerator"));
|
|
47
56
|
|
|
57
|
+
// only reached once a page names a CSS chunk of its own
|
|
58
|
+
const getCssModulesPlugin = memoize(() => require("../css/CssModulesPlugin"));
|
|
59
|
+
|
|
48
60
|
/**
|
|
49
61
|
* @import {
|
|
50
62
|
* EntryDescriptionNormalized,
|
|
63
|
+
* FilenameTemplate,
|
|
51
64
|
* OutputHtmlOptions,
|
|
52
65
|
* HtmlFaviconIcon
|
|
53
66
|
* } from "../../declarations/WebpackOptions"
|
|
54
67
|
*/
|
|
68
|
+
/**
|
|
69
|
+
* @import {
|
|
70
|
+
* OutputNormalizedWithDefaults as OutputOptions
|
|
71
|
+
* } from "../config/defaults"
|
|
72
|
+
*/
|
|
55
73
|
/** @typedef {import("../../declarations/WebpackOptions").OutputHtmlOptions["favicon"]} FaviconOption */
|
|
56
74
|
/** @typedef {import("../../declarations/WebpackOptions").OutputHtmlOptions["manifest"]} ManifestOption */
|
|
57
75
|
/** @typedef {Exclude<HtmlFaviconIcon, string>} FaviconIcon */
|
|
76
|
+
/** @import Chunk, { ChunkFilenameTemplate } from "../Chunk" */
|
|
77
|
+
/** @import ChunkGraph from "../ChunkGraph" */
|
|
58
78
|
/** @import Compiler from "../Compiler" */
|
|
79
|
+
/** @import Module from "../Module" */
|
|
80
|
+
/** @typedef {import("../Compilation").EntryData} EntryData */
|
|
59
81
|
/** @import { HtmlModuleBuildInfo } from "./HtmlModule" */
|
|
60
82
|
/** @import HtmlParser from "./HtmlParser" */
|
|
61
|
-
/** @typedef {{ request: string, entryName: string, type: "script" | "script-module" | "modulepreload" | "stylesheet" | "html" | "preload" | "prefetch", css?: boolean }} HtmlEntryInfo */
|
|
83
|
+
/** @typedef {{ request: string, entryName: string, index: number, type: "script" | "script-module" | "modulepreload" | "stylesheet" | "html" | "preload" | "prefetch", css?: boolean }} HtmlEntryInfo */
|
|
84
|
+
/**
|
|
85
|
+
* What one extracted entry needs to be named. Recorded in page order once
|
|
86
|
+
* every page is built, and resolved to filenames once chunks exist.
|
|
87
|
+
* @typedef {object} PendingName
|
|
88
|
+
* @property {string} base name the tag's url (or its page) asks for, before numbering
|
|
89
|
+
* @property {FilenameTemplate} jsTemplate `output.filename` for this entry, as configured
|
|
90
|
+
* @property {string=} freeName name of a page-only entry, which emits nothing and leaves it free
|
|
91
|
+
*/
|
|
62
92
|
|
|
63
93
|
/** @typedef {{ outputName: string }} HtmlTransformHtmlContext */
|
|
64
94
|
/** @typedef {{ outputName: string }} HtmlEmittedContext */
|
|
@@ -222,9 +252,130 @@ const isIntegrityEnabled = (integrity) =>
|
|
|
222
252
|
// `\.html`/`\.css` request matchers for the synthetic `output.html` wrapper.
|
|
223
253
|
const HTML_REQUEST_RE = /\.html(\?|$)/i;
|
|
224
254
|
const CSS_REQUEST_RE = /\.css(\?|$)/i;
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
255
|
+
/**
|
|
256
|
+
* The entry a page is the whole of: nothing imports the module and the entry
|
|
257
|
+
* asks for nothing else, so the entry's JavaScript would be the page itself.
|
|
258
|
+
* @param {Compilation} compilation compilation
|
|
259
|
+
* @param {Module} module html module
|
|
260
|
+
* @returns {{ name: string, data: EntryData } | undefined} the page's own entry, when it has one
|
|
261
|
+
*/
|
|
262
|
+
const getPageEntry = (compilation, module) => {
|
|
263
|
+
const { moduleGraph } = compilation;
|
|
264
|
+
for (const connection of moduleGraph.getIncomingConnections(module)) {
|
|
265
|
+
if (connection.originModule) return undefined;
|
|
266
|
+
}
|
|
267
|
+
for (const [name, data] of compilation.entries) {
|
|
268
|
+
if (data.dependencies.length !== 1) continue;
|
|
269
|
+
if (data.includeDependencies.length !== 0) continue;
|
|
270
|
+
if (moduleGraph.getModule(data.dependencies[0]) === module) {
|
|
271
|
+
return { name, data };
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return undefined;
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* The entry of a page that emits nothing but its markup, so its chunk carries
|
|
279
|
+
* no JavaScript. An `output.library` asks for the page's exports, and keeps it.
|
|
280
|
+
* @param {Compilation} compilation compilation
|
|
281
|
+
* @param {Module} module html module
|
|
282
|
+
* @returns {{ name: string, data: EntryData } | undefined} the entry, when the page is all it emits
|
|
283
|
+
*/
|
|
284
|
+
const getPageOnlyEntry = (compilation, module) => {
|
|
285
|
+
const entry = getPageEntry(compilation, module);
|
|
286
|
+
if (entry === undefined) return undefined;
|
|
287
|
+
const { library } = entry.data.options;
|
|
288
|
+
const configured =
|
|
289
|
+
library === undefined ? compilation.outputOptions.library : library;
|
|
290
|
+
return configured === undefined ? entry : undefined;
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* The basename a tag's url lends to the entry it becomes, so
|
|
295
|
+
* `src="./my-script.js"` emits `my-script.js`. Undefined for an inline body.
|
|
296
|
+
* @param {string} request the tag's request
|
|
297
|
+
* @returns {string | undefined} the basename, when the url carries one
|
|
298
|
+
*/
|
|
299
|
+
const getRequestBaseName = (request) => {
|
|
300
|
+
// An inline `<script>` body is a `data:` request webpack writes itself.
|
|
301
|
+
if (request.startsWith("data:")) return undefined;
|
|
302
|
+
const { path: file } = parseResource(request);
|
|
303
|
+
return basename(file, extname(file)) || undefined;
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Claims `base`, numbering it while something else already emits under that
|
|
308
|
+
* name, so two tags sharing a basename stay distinct.
|
|
309
|
+
* @param {string} base preferred name
|
|
310
|
+
* @param {Set<string>} taken names this kind of output already emits under
|
|
311
|
+
* @returns {string} the claimed name
|
|
312
|
+
*/
|
|
313
|
+
const claimName = (base, taken) => {
|
|
314
|
+
let name = base;
|
|
315
|
+
for (let index = 1; taken.has(name); index++) name = `${base}${index}`;
|
|
316
|
+
taken.add(name);
|
|
317
|
+
return name;
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
// Placeholders that tell chunks apart on their own, so a template carrying
|
|
321
|
+
// one needs no `[name]`. Not `[id]`: an extracted entry's id is synthetic.
|
|
322
|
+
const CONTENT_PLACEHOLDER_REGEXP =
|
|
323
|
+
/\[(?:chunkhash|contenthash|fullhash|hash)[\]:]/;
|
|
324
|
+
|
|
325
|
+
// Basename stem of a filename template — what `[name]` stands in for, keeping
|
|
326
|
+
// the directory, extension and query the template asked for.
|
|
327
|
+
const TEMPLATE_STEM_REGEXP = /(^|\/)[^/?]*?((?:\.[^./?]+)*)(\?.*)?$/;
|
|
328
|
+
|
|
329
|
+
const NAME_PLACEHOLDER_REGEXP = /\[name\]/g;
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* A filename template usable for a page's extracted entries: it must tell one
|
|
333
|
+
* entry from another, or every entry of the page would be emitted to the same
|
|
334
|
+
* file. A template naming neither the chunk nor its content lends its directory
|
|
335
|
+
* and extension to a `[name]` instead.
|
|
336
|
+
* @param {string} template configured template
|
|
337
|
+
* @param {string} extension extension to fall back to when the template names none
|
|
338
|
+
* @returns {string} a template that tells the page's entries apart
|
|
339
|
+
*/
|
|
340
|
+
const getNamedTemplate = (template, extension) => {
|
|
341
|
+
if (
|
|
342
|
+
template.includes("[name]") ||
|
|
343
|
+
CONTENT_PLACEHOLDER_REGEXP.test(template)
|
|
344
|
+
) {
|
|
345
|
+
return template;
|
|
346
|
+
}
|
|
347
|
+
return template.replace(
|
|
348
|
+
TEMPLATE_STEM_REGEXP,
|
|
349
|
+
(_, dir, ext, query) => `${dir}[name]${ext || extension}${query || ""}`
|
|
350
|
+
);
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* The filename one extracted entry emits under, with `name` filling the
|
|
355
|
+
* `[name]` its template carries or the stem it leaves behind.
|
|
356
|
+
* @param {string} template configured template
|
|
357
|
+
* @param {string} extension extension to fall back to when the template names none
|
|
358
|
+
* @param {string} name the name this entry claimed
|
|
359
|
+
* @returns {string} the entry's filename template
|
|
360
|
+
*/
|
|
361
|
+
const fillNamedTemplate = (template, extension, name) =>
|
|
362
|
+
getNamedTemplate(template, extension).replace(NAME_PLACEHOLDER_REGEXP, name);
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* The same, for a template `output.filename` states as a function: it is called
|
|
366
|
+
* at emit, and the path it returns read for a stem the same way.
|
|
367
|
+
* @param {FilenameTemplate} template configured template
|
|
368
|
+
* @param {string} extension extension to fall back to when the template names none
|
|
369
|
+
* @param {string} name the name this entry claimed
|
|
370
|
+
* @returns {ChunkFilenameTemplate} the entry's filename template
|
|
371
|
+
*/
|
|
372
|
+
const getEntryTemplate = (template, extension, name) => {
|
|
373
|
+
if (typeof template === "function") {
|
|
374
|
+
return (pathData, assetInfo) =>
|
|
375
|
+
fillNamedTemplate(template(pathData, assetInfo), extension, name);
|
|
376
|
+
}
|
|
377
|
+
return fillNamedTemplate(template, extension, name);
|
|
378
|
+
};
|
|
228
379
|
|
|
229
380
|
/**
|
|
230
381
|
* Requests an `output.html` page must load for an entry: its `dependOn`
|
|
@@ -294,7 +445,7 @@ class HtmlModulesPlugin {
|
|
|
294
445
|
* digest of `content`, with `nonNumericOnlyHash` applied — webpack's
|
|
295
446
|
* standard `[contenthash]` recipe.
|
|
296
447
|
* @param {string | Buffer} content content to hash
|
|
297
|
-
* @param {
|
|
448
|
+
* @param {OutputOptions} outputOptions output options
|
|
298
449
|
* @returns {string} content hash
|
|
299
450
|
*/
|
|
300
451
|
static computeContentHash(content, outputOptions) {
|
|
@@ -316,7 +467,7 @@ class HtmlModulesPlugin {
|
|
|
316
467
|
* initial chunks, `output.htmlChunkFilename` otherwise — the HTML counterpart
|
|
317
468
|
* of `CssModulesPlugin.getChunkFilenameTemplate`.
|
|
318
469
|
* @param {import("../Chunk")} chunk chunk
|
|
319
|
-
* @param {
|
|
470
|
+
* @param {OutputOptions} outputOptions output options
|
|
320
471
|
* @returns {import("../Chunk").ChunkFilenameTemplate} used filename template
|
|
321
472
|
*/
|
|
322
473
|
static getChunkFilenameTemplate(chunk, outputOptions) {
|
|
@@ -485,11 +636,11 @@ class HtmlModulesPlugin {
|
|
|
485
636
|
// `finishMake` creates their entries without scanning the whole module
|
|
486
637
|
// graph), the stylesheet entry names (read in `afterChunks`) and the html
|
|
487
638
|
// options of every emitted page, keyed by its asset name.
|
|
488
|
-
/** @type {WeakMap<import("../Compilation"), { htmlModules: Set<
|
|
639
|
+
/** @type {WeakMap<import("../Compilation"), { htmlModules: Set<Module>, stylesheetEntries: Set<string>, pendingNames: Map<string, PendingName>, htmlAssetOptions: Map<string, OutputHtmlOptions> }>} */
|
|
489
640
|
const compilationState = new WeakMap();
|
|
490
641
|
/**
|
|
491
642
|
* @param {import("../Compilation")} compilation compilation
|
|
492
|
-
* @returns {{ htmlModules: Set<
|
|
643
|
+
* @returns {{ htmlModules: Set<Module>, stylesheetEntries: Set<string>, pendingNames: Map<string, PendingName>, htmlAssetOptions: Map<string, OutputHtmlOptions> }} per-compilation state
|
|
493
644
|
*/
|
|
494
645
|
const getState = (compilation) => {
|
|
495
646
|
let state = compilationState.get(compilation);
|
|
@@ -497,6 +648,7 @@ class HtmlModulesPlugin {
|
|
|
497
648
|
state = {
|
|
498
649
|
htmlModules: new Set(),
|
|
499
650
|
stylesheetEntries: new Set(),
|
|
651
|
+
pendingNames: new Map(),
|
|
500
652
|
htmlAssetOptions: new Map()
|
|
501
653
|
};
|
|
502
654
|
compilationState.set(compilation, state);
|
|
@@ -504,14 +656,21 @@ class HtmlModulesPlugin {
|
|
|
504
656
|
return state;
|
|
505
657
|
};
|
|
506
658
|
compiler.hooks.finishMake.tapAsync(PLUGIN_NAME, (compilation, callback) => {
|
|
507
|
-
const { htmlModules, stylesheetEntries } =
|
|
659
|
+
const { htmlModules, stylesheetEntries, pendingNames } =
|
|
660
|
+
getState(compilation);
|
|
661
|
+
/** @type {Set<string>} */
|
|
662
|
+
const extractedNames = new Set();
|
|
663
|
+
// The page each `type: "html"` link built, so the naming walk below can
|
|
664
|
+
// follow the links in document order instead of in build order.
|
|
665
|
+
/** @type {Map<string, Module>} */
|
|
666
|
+
const linkedPages = new Map();
|
|
508
667
|
|
|
509
668
|
// Collect the entries an HTML module asks for. Only the script chains
|
|
510
669
|
// (`script`, `script-module`) share a runtime via a leader-only
|
|
511
670
|
// `dependOn`; `modulepreload`, `stylesheet` and `html` links are all
|
|
512
671
|
// independent entries (a CSS or page entry must not chain into a JS
|
|
513
672
|
// leader, or the chunk would mix unrelated outputs).
|
|
514
|
-
/** @type {(module:
|
|
673
|
+
/** @type {(module: Module) => { context: string, request: string, name: string, dependOn: string[] | undefined }[]} */
|
|
515
674
|
const collectEntrySpecs = (module) => {
|
|
516
675
|
const { htmlEntries } = /** @type {HtmlModuleBuildInfo} */ (
|
|
517
676
|
module.buildInfo
|
|
@@ -533,10 +692,11 @@ class HtmlModulesPlugin {
|
|
|
533
692
|
leaderName = entry.entryName;
|
|
534
693
|
}
|
|
535
694
|
// Stylesheet entries and `as="style"` preload/prefetch entries emit
|
|
536
|
-
// a CSS chunk, so they
|
|
537
|
-
if (groupKind === "stylesheet" || entry.css) {
|
|
695
|
+
// a CSS chunk, so they are named from `output.cssFilename` alone.
|
|
696
|
+
if (groupKind === "stylesheet" || Boolean(entry.css)) {
|
|
538
697
|
stylesheetEntries.add(entry.entryName);
|
|
539
698
|
}
|
|
699
|
+
extractedNames.add(entry.entryName);
|
|
540
700
|
specs.push({
|
|
541
701
|
context,
|
|
542
702
|
request: entry.request,
|
|
@@ -548,9 +708,70 @@ class HtmlModulesPlugin {
|
|
|
548
708
|
return specs;
|
|
549
709
|
};
|
|
550
710
|
|
|
711
|
+
// Records what a page's entries ask to be named, then walks its links —
|
|
712
|
+
// once every page is built, so the order is the documents', not the builds'.
|
|
713
|
+
/** @type {(module: Module, seen: Set<Module>) => void} */
|
|
714
|
+
const recordNames = (module, seen) => {
|
|
715
|
+
if (seen.has(module)) return;
|
|
716
|
+
seen.add(module);
|
|
717
|
+
const { htmlEntries } = /** @type {HtmlModuleBuildInfo} */ (
|
|
718
|
+
module.buildInfo
|
|
719
|
+
);
|
|
720
|
+
if (!htmlEntries) return;
|
|
721
|
+
const pageEntry = getPageOnlyEntry(compilation, module);
|
|
722
|
+
const namedEntry =
|
|
723
|
+
pageEntry !== undefined && !extractedNames.has(pageEntry.name)
|
|
724
|
+
? pageEntry
|
|
725
|
+
: undefined;
|
|
726
|
+
const { resource } = /** @type {NormalModule} */ (module);
|
|
727
|
+
// An `output.html` page is a wrapper webpack writes around an entry, so
|
|
728
|
+
// what it loads is that entry's own output and takes its name.
|
|
729
|
+
const wrapsEntry =
|
|
730
|
+
namedEntry !== undefined &&
|
|
731
|
+
typeof resource === "string" &&
|
|
732
|
+
resource.startsWith("data:text/html");
|
|
733
|
+
const { filename } = compilation.outputOptions;
|
|
734
|
+
// Kept as configured, a function included, and read for a name once the
|
|
735
|
+
// chunks exist.
|
|
736
|
+
const jsTemplate =
|
|
737
|
+
namedEntry && namedEntry.data.options.filename !== undefined
|
|
738
|
+
? namedEntry.data.options.filename
|
|
739
|
+
: filename;
|
|
740
|
+
// In document order, so of two tags sharing a basename the first a
|
|
741
|
+
// reader sees keeps it. A linked page is named on emit instead.
|
|
742
|
+
/** @type {HtmlEntryInfo[]} */
|
|
743
|
+
const ordered = [];
|
|
744
|
+
/** @type {HtmlEntryInfo[]} */
|
|
745
|
+
const links = [];
|
|
746
|
+
for (const [groupKind, group] of Object.entries(htmlEntries)) {
|
|
747
|
+
for (const entry of group) {
|
|
748
|
+
(groupKind === "html" ? links : ordered).push(entry);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
ordered.sort((a, b) => a.index - b.index);
|
|
752
|
+
for (const entry of ordered) {
|
|
753
|
+
// An inline `<script>` body has no url to be named after, so it
|
|
754
|
+
// keeps the name of its own entry, page hash and tag index.
|
|
755
|
+
const base =
|
|
756
|
+
wrapsEntry && namedEntry
|
|
757
|
+
? namedEntry.name
|
|
758
|
+
: getRequestBaseName(entry.request) || entry.entryName;
|
|
759
|
+
pendingNames.set(entry.entryName, {
|
|
760
|
+
base,
|
|
761
|
+
jsTemplate,
|
|
762
|
+
freeName: namedEntry && namedEntry.name
|
|
763
|
+
});
|
|
764
|
+
}
|
|
765
|
+
links.sort((a, b) => a.index - b.index);
|
|
766
|
+
for (const link of links) {
|
|
767
|
+
const page = linkedPages.get(link.entryName);
|
|
768
|
+
if (page) recordNames(page, seen);
|
|
769
|
+
}
|
|
770
|
+
};
|
|
771
|
+
|
|
551
772
|
// Push one collected reference as a compilation entry; resolves with
|
|
552
773
|
// the built entry module.
|
|
553
|
-
/** @type {(spec: { context: string, request: string, name: string, dependOn: string[] | undefined }) => Promise<
|
|
774
|
+
/** @type {(spec: { context: string, request: string, name: string, dependOn: string[] | undefined }) => Promise<Module | null>} */
|
|
554
775
|
const addEntry = (spec) =>
|
|
555
776
|
new Promise((resolve, reject) => {
|
|
556
777
|
compilation.addEntry(
|
|
@@ -558,10 +779,8 @@ class HtmlModulesPlugin {
|
|
|
558
779
|
EntryPlugin.createDependency(spec.request, { name: spec.name }),
|
|
559
780
|
{
|
|
560
781
|
name: spec.name,
|
|
561
|
-
//
|
|
562
|
-
//
|
|
563
|
-
// `.css` name via `cssFilenameTemplate` below; `html` page entries
|
|
564
|
-
// emit their file via `renderManifest`.
|
|
782
|
+
// A placeholder `afterChunks` overwrites for every entry it
|
|
783
|
+
// names; only a linked page keeps it, and it emits no JavaScript.
|
|
565
784
|
filename: compilation.outputOptions.chunkFilename || "[name].js",
|
|
566
785
|
dependOn: spec.dependOn
|
|
567
786
|
},
|
|
@@ -575,7 +794,7 @@ class HtmlModulesPlugin {
|
|
|
575
794
|
// every HTML entry already gets. `processed` guards diamonds and cycles.
|
|
576
795
|
/** @type {WeakSet<import("../Module")>} */
|
|
577
796
|
const processed = new WeakSet();
|
|
578
|
-
/** @type {(module:
|
|
797
|
+
/** @type {(module: Module) => Promise<void>} */
|
|
579
798
|
const processEntry = async (module) => {
|
|
580
799
|
if (processed.has(module)) return;
|
|
581
800
|
processed.add(module);
|
|
@@ -583,6 +802,7 @@ class HtmlModulesPlugin {
|
|
|
583
802
|
collectEntrySpecs(module).map(async (spec) => {
|
|
584
803
|
const entryModule = await addEntry(spec);
|
|
585
804
|
if (entryModule && entryModule.type === HTML_MODULE_TYPE) {
|
|
805
|
+
linkedPages.set(spec.name, entryModule);
|
|
586
806
|
await processEntry(entryModule);
|
|
587
807
|
}
|
|
588
808
|
})
|
|
@@ -590,11 +810,15 @@ class HtmlModulesPlugin {
|
|
|
590
810
|
};
|
|
591
811
|
// Seed with the HTML modules seen during make (config entries /
|
|
592
812
|
// imports, fresh or cache-restored); linked pages are reached by
|
|
593
|
-
// recursion above.
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
813
|
+
// recursion above. Sorted because they are tracked in build-completion
|
|
814
|
+
// order, which the names must not depend on.
|
|
815
|
+
const seeds = [...htmlModules].sort(compareModulesByIdentifier);
|
|
816
|
+
Promise.all(seeds.map(processEntry)).then(() => {
|
|
817
|
+
/** @type {Set<Module>} */
|
|
818
|
+
const named = new Set();
|
|
819
|
+
for (const seed of seeds) recordNames(seed, named);
|
|
820
|
+
callback();
|
|
821
|
+
}, callback);
|
|
598
822
|
});
|
|
599
823
|
|
|
600
824
|
// `csp` injects a `<meta http-equiv="Content-Security-Policy">` and
|
|
@@ -725,26 +949,6 @@ class HtmlModulesPlugin {
|
|
|
725
949
|
// a content-hashed filename makes a substring hit a real reference.
|
|
726
950
|
/** @type {Set<string>} */
|
|
727
951
|
const deletionCandidates = new Set(inlinedFiles);
|
|
728
|
-
// A wrapper entry's chunk only rebuilds the page's own markup; the
|
|
729
|
-
// page loads the `<script src>` entries the parser split out of it.
|
|
730
|
-
for (const entrypoint of compilation.entrypoints.values()) {
|
|
731
|
-
const chunk = entrypoint.getEntrypointChunk();
|
|
732
|
-
if (!chunk) continue;
|
|
733
|
-
let wrapperOnly = false;
|
|
734
|
-
for (const entryModule of compilation.chunkGraph.getChunkEntryModulesIterable(
|
|
735
|
-
chunk
|
|
736
|
-
)) {
|
|
737
|
-
const { resource } = /** @type {import("../NormalModule")} */ (
|
|
738
|
-
entryModule
|
|
739
|
-
);
|
|
740
|
-
wrapperOnly =
|
|
741
|
-
typeof resource === "string" &&
|
|
742
|
-
HTML_DATA_URL_RE.test(resource);
|
|
743
|
-
if (!wrapperOnly) break;
|
|
744
|
-
}
|
|
745
|
-
if (!wrapperOnly) continue;
|
|
746
|
-
for (const file of chunk.files) deletionCandidates.add(file);
|
|
747
|
-
}
|
|
748
952
|
// Materialize each other asset's source once (it can be expensive to
|
|
749
953
|
// render) and test all candidates against it, rather than
|
|
750
954
|
// re-materializing every asset per candidate.
|
|
@@ -796,26 +1000,57 @@ class HtmlModulesPlugin {
|
|
|
796
1000
|
// entry emits to a distinct file derived from `output.cssFilename`
|
|
797
1001
|
// (or `output.cssChunkFilename` for non-initial CSS chunks).
|
|
798
1002
|
compilation.hooks.afterChunks.tap(PLUGIN_NAME, () => {
|
|
799
|
-
const { stylesheetEntries } = getState(compilation);
|
|
800
|
-
if (
|
|
801
|
-
|
|
1003
|
+
const { stylesheetEntries, pendingNames } = getState(compilation);
|
|
1004
|
+
if (pendingNames.size === 0) return;
|
|
1005
|
+
const { chunkGraph, outputOptions } = compilation;
|
|
1006
|
+
const jsExtension = outputOptions.module ? ".mjs" : ".js";
|
|
1007
|
+
// Claimed in the order the pages recorded them, which is the
|
|
1008
|
+
// documents' order rather than their builds'.
|
|
1009
|
+
const takenJsNames = new Set(compilation.entries.keys());
|
|
1010
|
+
const takenCssNames = new Set(takenJsNames);
|
|
1011
|
+
// An extracted entry emits nothing under its own synthetic name, so
|
|
1012
|
+
// that name never stands in the way of the one its tag asks for.
|
|
1013
|
+
for (const entryName of pendingNames.keys()) {
|
|
1014
|
+
takenJsNames.delete(entryName);
|
|
1015
|
+
takenCssNames.delete(entryName);
|
|
1016
|
+
}
|
|
1017
|
+
for (const { freeName } of pendingNames.values()) {
|
|
1018
|
+
if (freeName === undefined) continue;
|
|
1019
|
+
// A page-only entry emits nothing of its own, so its name is free for
|
|
1020
|
+
// the entries extracted from it — `app.html` keeps `app.js`.
|
|
1021
|
+
takenJsNames.delete(freeName);
|
|
1022
|
+
takenCssNames.delete(freeName);
|
|
1023
|
+
}
|
|
1024
|
+
for (const [entryName, { base, jsTemplate }] of pendingNames) {
|
|
802
1025
|
const entrypoint = compilation.entrypoints.get(entryName);
|
|
803
1026
|
if (!entrypoint) continue;
|
|
804
1027
|
const chunk = entrypoint.getEntrypointChunk();
|
|
805
1028
|
if (!chunk) continue;
|
|
806
|
-
//
|
|
807
|
-
//
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
1029
|
+
// A stylesheet entry emits no JavaScript, so it claims no JS name and
|
|
1030
|
+
// leaves that one to a `<script src>` of the same basename.
|
|
1031
|
+
const emitsCss = stylesheetEntries.has(entryName);
|
|
1032
|
+
if (!emitsCss) {
|
|
1033
|
+
// `output.filename` named after the tag's url, the way an entry
|
|
1034
|
+
// point is named. `Compilation` set it from the placeholder above.
|
|
1035
|
+
chunk.filenameTemplate = getEntryTemplate(
|
|
1036
|
+
jsTemplate,
|
|
1037
|
+
jsExtension,
|
|
1038
|
+
claimName(base, takenJsNames)
|
|
1039
|
+
);
|
|
1040
|
+
}
|
|
1041
|
+
// A `<script src>` whose chunk carries no CSS claims no CSS name, so
|
|
1042
|
+
// a `<link>` of the same basename still gets the plain one.
|
|
1043
|
+
if (
|
|
1044
|
+
!emitsCss &&
|
|
1045
|
+
!getCssModulesPlugin().chunkHasCss(chunk, chunkGraph)
|
|
1046
|
+
) {
|
|
1047
|
+
continue;
|
|
1048
|
+
}
|
|
1049
|
+
chunk.cssFilenameTemplate = getEntryTemplate(
|
|
1050
|
+
outputOptions.cssFilename,
|
|
1051
|
+
".css",
|
|
1052
|
+
claimName(base, takenCssNames)
|
|
1053
|
+
);
|
|
819
1054
|
}
|
|
820
1055
|
});
|
|
821
1056
|
compilation.dependencyTemplates.set(
|
|
@@ -933,7 +1168,8 @@ class HtmlModulesPlugin {
|
|
|
933
1168
|
);
|
|
934
1169
|
return new (getHtmlGenerator())(
|
|
935
1170
|
generatorOptions,
|
|
936
|
-
compilation.moduleGraph
|
|
1171
|
+
compilation.moduleGraph,
|
|
1172
|
+
(module) => getPageOnlyEntry(compilation, module) !== undefined
|
|
937
1173
|
);
|
|
938
1174
|
});
|
|
939
1175
|
|
|
@@ -1211,6 +1447,16 @@ class HtmlModulesPlugin {
|
|
|
1211
1447
|
jsHooks.render.tap(PLUGIN_NAME, (source, renderContext) => {
|
|
1212
1448
|
// No HTML modules ⇒ no sentinels; skip materializing the JS source.
|
|
1213
1449
|
if (htmlModules.size === 0) return source;
|
|
1450
|
+
// Chunks without HTML modules can't carry HTML sentinels — avoid
|
|
1451
|
+
// ConcatSource.source() on the common pure-JS chunk path.
|
|
1452
|
+
if (
|
|
1453
|
+
!HtmlModulesPlugin.chunkHasHtml(
|
|
1454
|
+
renderContext.chunk,
|
|
1455
|
+
compilation.chunkGraph
|
|
1456
|
+
)
|
|
1457
|
+
) {
|
|
1458
|
+
return source;
|
|
1459
|
+
}
|
|
1214
1460
|
const raw = source.source();
|
|
1215
1461
|
if (typeof raw !== "string") return source;
|
|
1216
1462
|
// Every sentinel shares this prefix — one scan answers the common
|
|
@@ -1281,6 +1527,29 @@ class HtmlModulesPlugin {
|
|
|
1281
1527
|
}
|
|
1282
1528
|
);
|
|
1283
1529
|
}
|
|
1530
|
+
|
|
1531
|
+
/**
|
|
1532
|
+
* Returns true, when the chunk has html.
|
|
1533
|
+
* @param {Chunk} chunk chunk
|
|
1534
|
+
* @param {ChunkGraph} chunkGraph chunk graph
|
|
1535
|
+
* @returns {boolean} true, when the chunk has html
|
|
1536
|
+
*/
|
|
1537
|
+
static chunkHasHtml(chunk, chunkGraph) {
|
|
1538
|
+
if (chunkGraph.getChunkModulesIterableBySourceType(chunk, HTML_TYPE)) {
|
|
1539
|
+
return true;
|
|
1540
|
+
}
|
|
1541
|
+
// Scope-hoisted HTML loses HTML_TYPE on the ConcatenatedModule, but its
|
|
1542
|
+
// JS export can still carry unresolved sentinels that need this path.
|
|
1543
|
+
for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
|
|
1544
|
+
if (module instanceof HtmlModule) return true;
|
|
1545
|
+
if (module instanceof ConcatenatedModule) {
|
|
1546
|
+
for (const inner of module.modules) {
|
|
1547
|
+
if (inner instanceof HtmlModule) return true;
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
return false;
|
|
1552
|
+
}
|
|
1284
1553
|
}
|
|
1285
1554
|
|
|
1286
1555
|
/**
|
package/lib/html/HtmlParser.js
CHANGED
|
@@ -868,6 +868,7 @@ class HtmlParser extends Parser {
|
|
|
868
868
|
* @typedef {object} HtmlEntryInfo
|
|
869
869
|
* @property {string} request
|
|
870
870
|
* @property {string} entryName
|
|
871
|
+
* @property {number} index position in the document, across all groups — the order the emitted files are named in
|
|
871
872
|
* @property {"script" | "script-module" | "modulepreload" | "stylesheet" | "html" | "preload" | "prefetch"} type
|
|
872
873
|
* @property {boolean=} css entry emits a CSS chunk (`<link rel="preload" as="style">`), so it needs the CSS filename template
|
|
873
874
|
*/
|
|
@@ -1478,7 +1479,8 @@ class HtmlParser extends Parser {
|
|
|
1478
1479
|
const scriptType =
|
|
1479
1480
|
/** @type {"script" | "script-module"} */ (type);
|
|
1480
1481
|
const request = dataUri("text/javascript", value);
|
|
1481
|
-
const
|
|
1482
|
+
const index = nextEntryIndex++;
|
|
1483
|
+
const entryName = `__html_${moduleHash}_${index}`;
|
|
1482
1484
|
const dep = new HtmlInlineScriptDependency(
|
|
1483
1485
|
request,
|
|
1484
1486
|
nameEnd,
|
|
@@ -1501,6 +1503,7 @@ class HtmlParser extends Parser {
|
|
|
1501
1503
|
).push({
|
|
1502
1504
|
request,
|
|
1503
1505
|
entryName,
|
|
1506
|
+
index,
|
|
1504
1507
|
type: scriptType
|
|
1505
1508
|
});
|
|
1506
1509
|
break;
|
|
@@ -1581,7 +1584,8 @@ class HtmlParser extends Parser {
|
|
|
1581
1584
|
// kind rewrites to the page's filename and emits no sibling tags.
|
|
1582
1585
|
// Recorded as an independent entry (no `dependOn`), like an entry point.
|
|
1583
1586
|
if (type === "html") {
|
|
1584
|
-
const
|
|
1587
|
+
const index = nextEntryIndex++;
|
|
1588
|
+
const entryName = `__html_${moduleHash}_${index}`;
|
|
1585
1589
|
const dep = new HtmlEntryDependency(
|
|
1586
1590
|
request,
|
|
1587
1591
|
[s, e],
|
|
@@ -1591,7 +1595,7 @@ class HtmlParser extends Parser {
|
|
|
1591
1595
|
);
|
|
1592
1596
|
setLoc(dep, s, e);
|
|
1593
1597
|
module.addPresentationalDependency(dep);
|
|
1594
|
-
htmlLinkEntries.push({ request, entryName, type });
|
|
1598
|
+
htmlLinkEntries.push({ request, entryName, index, type });
|
|
1595
1599
|
continue;
|
|
1596
1600
|
}
|
|
1597
1601
|
// `rel="preload"/"prefetch"` of a bundled resource: an
|
|
@@ -1603,7 +1607,8 @@ class HtmlParser extends Parser {
|
|
|
1603
1607
|
const asStyle = as
|
|
1604
1608
|
? as.trim().toLowerCase() === "style"
|
|
1605
1609
|
: false;
|
|
1606
|
-
const
|
|
1610
|
+
const index = nextEntryIndex++;
|
|
1611
|
+
const entryName = `__html_${moduleHash}_${index}`;
|
|
1607
1612
|
// Tag metadata so the template can mirror `crossorigin`/
|
|
1608
1613
|
// `integrity` onto a native `preload` `<link>` (integrity-
|
|
1609
1614
|
// eligible per the SRI spec). `prefetch` gets none — the spec
|
|
@@ -1635,6 +1640,7 @@ class HtmlParser extends Parser {
|
|
|
1635
1640
|
).push({
|
|
1636
1641
|
request,
|
|
1637
1642
|
entryName,
|
|
1643
|
+
index,
|
|
1638
1644
|
type,
|
|
1639
1645
|
css: asStyle
|
|
1640
1646
|
});
|
|
@@ -1649,7 +1655,8 @@ class HtmlParser extends Parser {
|
|
|
1649
1655
|
type === "modulepreload" ||
|
|
1650
1656
|
type === "stylesheet"
|
|
1651
1657
|
) {
|
|
1652
|
-
const
|
|
1658
|
+
const index = nextEntryIndex++;
|
|
1659
|
+
const entryName = `__html_${moduleHash}_${index}`;
|
|
1653
1660
|
const willBeModuleScript =
|
|
1654
1661
|
type === "script-module" ||
|
|
1655
1662
|
(outputModule && type === "script");
|
|
@@ -1777,7 +1784,7 @@ class HtmlParser extends Parser {
|
|
|
1777
1784
|
: type === "stylesheet"
|
|
1778
1785
|
? stylesheetEntries
|
|
1779
1786
|
: modulePreloadEntries
|
|
1780
|
-
).push({ request, entryName, type });
|
|
1787
|
+
).push({ request, entryName, index, type });
|
|
1781
1788
|
} else {
|
|
1782
1789
|
const dep = new HtmlSourceDependency(request, [s, e]);
|
|
1783
1790
|
ResourceHintPlugin.applyDefaults(
|