webpack 5.106.2 → 5.107.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (235) hide show
  1. package/README.md +2 -2
  2. package/lib/APIPlugin.js +1 -1
  3. package/lib/BannerPlugin.js +3 -4
  4. package/lib/Cache.js +3 -6
  5. package/lib/Chunk.js +21 -25
  6. package/lib/ChunkGroup.js +57 -15
  7. package/lib/CompatibilityPlugin.js +8 -7
  8. package/lib/Compilation.js +67 -37
  9. package/lib/Compiler.js +4 -13
  10. package/lib/ContextModule.js +2 -2
  11. package/lib/DefinePlugin.js +2 -2
  12. package/lib/Dependency.js +22 -1
  13. package/lib/DependencyTemplate.js +2 -1
  14. package/lib/EnvironmentPlugin.js +1 -1
  15. package/lib/EvalSourceMapDevToolPlugin.js +8 -10
  16. package/lib/ExportsInfo.js +30 -34
  17. package/lib/ExternalModule.js +91 -26
  18. package/lib/ExternalModuleFactoryPlugin.js +7 -1
  19. package/lib/FileSystemInfo.js +187 -72
  20. package/lib/Generator.js +3 -3
  21. package/lib/HotModuleReplacementPlugin.js +26 -8
  22. package/lib/IgnorePlugin.js +2 -1
  23. package/lib/Module.js +20 -19
  24. package/lib/ModuleFactory.js +1 -1
  25. package/lib/ModuleNotFoundError.js +3 -84
  26. package/lib/ModuleSourceTypeConstants.js +51 -19
  27. package/lib/ModuleTypeConstants.js +12 -3
  28. package/lib/MultiCompiler.js +2 -2
  29. package/lib/NodeStuffPlugin.js +1 -1
  30. package/lib/NormalModule.js +119 -77
  31. package/lib/NormalModuleFactory.js +47 -27
  32. package/lib/Parser.js +1 -1
  33. package/lib/ProgressPlugin.js +129 -56
  34. package/lib/RuntimeGlobals.js +5 -5
  35. package/lib/RuntimeModule.js +9 -7
  36. package/lib/RuntimePlugin.js +12 -1
  37. package/lib/SourceMapDevToolPlugin.js +250 -49
  38. package/lib/Template.js +1 -1
  39. package/lib/TemplatedPathPlugin.js +22 -4
  40. package/lib/WarnCaseSensitiveModulesPlugin.js +70 -2
  41. package/lib/WarnDeprecatedOptionPlugin.js +1 -1
  42. package/lib/WarnNoModeSetPlugin.js +16 -1
  43. package/lib/Watching.js +2 -3
  44. package/lib/WebpackError.js +3 -77
  45. package/lib/WebpackIsIncludedPlugin.js +1 -1
  46. package/lib/WebpackOptionsApply.js +13 -1
  47. package/lib/asset/AssetBytesGenerator.js +12 -8
  48. package/lib/asset/AssetGenerator.js +36 -22
  49. package/lib/asset/AssetModulesPlugin.js +6 -8
  50. package/lib/asset/AssetSourceGenerator.js +12 -8
  51. package/lib/buildChunkGraph.js +4 -6
  52. package/lib/cache/PackFileCacheStrategy.js +4 -4
  53. package/lib/cli.js +3 -1
  54. package/lib/config/defaults.js +197 -10
  55. package/lib/config/normalization.js +3 -1
  56. package/lib/css/CssGenerator.js +320 -105
  57. package/lib/css/CssInjectStyleRuntimeModule.js +44 -42
  58. package/lib/css/CssLoadingRuntimeModule.js +22 -4
  59. package/lib/{CssModule.js → css/CssModule.js} +15 -15
  60. package/lib/css/CssModulesPlugin.js +168 -88
  61. package/lib/css/CssParser.js +566 -269
  62. package/lib/css/walkCssTokens.js +148 -2
  63. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +1 -1
  64. package/lib/dependencies/CommonJsDependencyHelpers.js +63 -0
  65. package/lib/dependencies/CommonJsExportRequireDependency.js +54 -10
  66. package/lib/dependencies/CommonJsExportsParserPlugin.js +1 -1
  67. package/lib/dependencies/CommonJsFullRequireDependency.js +32 -9
  68. package/lib/dependencies/CommonJsImportsParserPlugin.js +112 -4
  69. package/lib/dependencies/CommonJsRequireDependency.js +67 -4
  70. package/lib/dependencies/ContextDependency.js +1 -1
  71. package/lib/dependencies/ContextDependencyHelpers.js +1 -1
  72. package/lib/dependencies/CreateRequireParserPlugin.js +1 -1
  73. package/lib/dependencies/CriticalDependencyWarning.js +1 -1
  74. package/lib/dependencies/CssIcssExportDependency.js +332 -67
  75. package/lib/dependencies/CssIcssImportDependency.js +49 -7
  76. package/lib/dependencies/CssIcssSymbolDependency.js +11 -3
  77. package/lib/dependencies/CssImportDependency.js +8 -0
  78. package/lib/dependencies/CssUrlDependency.js +28 -2
  79. package/lib/dependencies/HarmonyDetectionParserPlugin.js +22 -2
  80. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +8 -7
  81. package/lib/dependencies/HarmonyExportExpressionDependency.js +22 -14
  82. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +110 -3
  83. package/lib/dependencies/HarmonyImportDependency.js +10 -2
  84. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +22 -1
  85. package/lib/dependencies/HarmonyImportSpecifierDependency.js +1 -1
  86. package/lib/{HarmonyLinkingError.js → dependencies/HarmonyLinkingError.js} +5 -3
  87. package/lib/dependencies/HtmlInlineScriptDependency.js +133 -0
  88. package/lib/dependencies/HtmlInlineStyleDependency.js +101 -0
  89. package/lib/dependencies/HtmlScriptSrcDependency.js +557 -0
  90. package/lib/dependencies/HtmlSourceDependency.js +128 -0
  91. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +1 -1
  92. package/lib/dependencies/ImportParserPlugin.js +2 -2
  93. package/lib/dependencies/ImportPhase.js +1 -1
  94. package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +1 -1
  95. package/lib/{RequireJsStuffPlugin.js → dependencies/RequireJsStuffPlugin.js} +7 -7
  96. package/lib/dependencies/SystemPlugin.js +1 -1
  97. package/lib/dependencies/WebAssemblyImportDependency.js +1 -1
  98. package/lib/dependencies/WorkerPlugin.js +2 -2
  99. package/lib/{DelegatedModule.js → dll/DelegatedModule.js} +31 -31
  100. package/lib/{DelegatedModuleFactoryPlugin.js → dll/DelegatedModuleFactoryPlugin.js} +4 -4
  101. package/lib/{DelegatedPlugin.js → dll/DelegatedPlugin.js} +2 -2
  102. package/lib/{DllEntryPlugin.js → dll/DllEntryPlugin.js} +4 -4
  103. package/lib/{DllModule.js → dll/DllModule.js} +24 -24
  104. package/lib/{DllModuleFactory.js → dll/DllModuleFactory.js} +4 -4
  105. package/lib/{DllPlugin.js → dll/DllPlugin.js} +6 -5
  106. package/lib/{DllReferencePlugin.js → dll/DllReferencePlugin.js} +14 -14
  107. package/lib/{LibManifestPlugin.js → dll/LibManifestPlugin.js} +9 -9
  108. package/lib/{AsyncDependencyToInitialChunkError.js → errors/AsyncDependencyToInitialChunkError.js} +2 -2
  109. package/lib/errors/BuildCycleError.js +1 -1
  110. package/lib/{ChunkRenderError.js → errors/ChunkRenderError.js} +1 -1
  111. package/lib/{CodeGenerationError.js → errors/CodeGenerationError.js} +1 -1
  112. package/lib/{CommentCompilationWarning.js → errors/CommentCompilationWarning.js} +3 -3
  113. package/lib/{ConcurrentCompilationError.js → errors/ConcurrentCompilationError.js} +4 -2
  114. package/lib/{EnvironmentNotSupportAsyncWarning.js → errors/EnvironmentNotSupportAsyncWarning.js} +4 -4
  115. package/lib/{HookWebpackError.js → errors/HookWebpackError.js} +5 -5
  116. package/lib/{IgnoreErrorModuleFactory.js → errors/IgnoreErrorModuleFactory.js} +4 -4
  117. package/lib/{InvalidDependenciesModuleWarning.js → errors/InvalidDependenciesModuleWarning.js} +3 -3
  118. package/lib/errors/JSONParseError.js +114 -0
  119. package/lib/{ModuleBuildError.js → errors/ModuleBuildError.js} +5 -5
  120. package/lib/{ModuleDependencyError.js → errors/ModuleDependencyError.js} +2 -2
  121. package/lib/{ModuleDependencyWarning.js → errors/ModuleDependencyWarning.js} +4 -4
  122. package/lib/{ModuleError.js → errors/ModuleError.js} +5 -5
  123. package/lib/{ModuleHashingError.js → errors/ModuleHashingError.js} +1 -1
  124. package/lib/errors/ModuleNotFoundError.js +91 -0
  125. package/lib/{ModuleParseError.js → errors/ModuleParseError.js} +8 -6
  126. package/lib/{ModuleRestoreError.js → errors/ModuleRestoreError.js} +1 -1
  127. package/lib/{ModuleStoreError.js → errors/ModuleStoreError.js} +1 -1
  128. package/lib/{ModuleWarning.js → errors/ModuleWarning.js} +5 -5
  129. package/lib/{NodeStuffInWebError.js → errors/NodeStuffInWebError.js} +4 -4
  130. package/lib/errors/NonErrorEmittedError.js +28 -0
  131. package/lib/{UnhandledSchemeError.js → errors/UnhandledSchemeError.js} +2 -2
  132. package/lib/{UnsupportedFeatureWarning.js → errors/UnsupportedFeatureWarning.js} +3 -3
  133. package/lib/errors/WebpackError.js +84 -0
  134. package/lib/html/HtmlGenerator.js +379 -0
  135. package/lib/html/HtmlModulesPlugin.js +429 -0
  136. package/lib/html/HtmlParser.js +1489 -0
  137. package/lib/html/walkHtmlTokens.js +3249 -0
  138. package/lib/ids/IdHelpers.js +2 -1
  139. package/lib/index.js +36 -15
  140. package/lib/javascript/JavascriptModulesPlugin.js +91 -10
  141. package/lib/javascript/JavascriptParser.js +197 -16
  142. package/lib/javascript/JavascriptParserHelpers.js +1 -1
  143. package/lib/json/JsonParser.js +7 -16
  144. package/lib/library/AbstractLibraryPlugin.js +1 -1
  145. package/lib/library/EnableLibraryPlugin.js +1 -1
  146. package/lib/{FalseIIFEUmdWarning.js → library/FalseIIFEUmdWarning.js} +1 -1
  147. package/lib/library/ModuleLibraryPlugin.js +74 -0
  148. package/lib/node/NodeEnvironmentPlugin.js +4 -2
  149. package/lib/node/nodeConsole.js +113 -64
  150. package/lib/optimize/ConcatenatedModule.js +51 -6
  151. package/lib/optimize/InnerGraph.js +1 -1
  152. package/lib/optimize/InnerGraphPlugin.js +11 -1
  153. package/lib/optimize/MinMaxSizeWarning.js +4 -4
  154. package/lib/optimize/ModuleConcatenationPlugin.js +15 -7
  155. package/lib/optimize/RealContentHashPlugin.js +89 -26
  156. package/lib/optimize/SideEffectsFlagPlugin.js +112 -5
  157. package/lib/optimize/SplitChunksPlugin.js +5 -5
  158. package/lib/performance/AssetsOverSizeLimitWarning.js +2 -2
  159. package/lib/performance/EntrypointsOverSizeLimitWarning.js +2 -2
  160. package/lib/performance/NoAsyncChunksWarning.js +5 -3
  161. package/lib/performance/SizeLimitsPlugin.js +1 -1
  162. package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +4 -1
  163. package/lib/rules/UseEffectRulePlugin.js +4 -3
  164. package/lib/runtime/AutoPublicPathRuntimeModule.js +3 -3
  165. package/lib/runtime/GetChunkFilenameRuntimeModule.js +5 -5
  166. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +119 -13
  167. package/lib/runtime/SetAnonymousDefaultNameRuntimeModule.js +35 -0
  168. package/lib/schemes/DataUriPlugin.js +13 -1
  169. package/lib/schemes/VirtualUrlPlugin.js +1 -1
  170. package/lib/serialization/SerializerMiddleware.js +2 -2
  171. package/lib/sharing/ConsumeSharedPlugin.js +4 -10
  172. package/lib/sharing/ConsumeSharedRuntimeModule.js +8 -4
  173. package/lib/sharing/ProvideSharedModule.js +1 -1
  174. package/lib/sharing/ProvideSharedPlugin.js +5 -5
  175. package/lib/sharing/resolveMatchedConfigs.js +1 -1
  176. package/lib/stats/DefaultStatsFactoryPlugin.js +2 -2
  177. package/lib/stats/DefaultStatsPresetPlugin.js +1 -1
  178. package/lib/stats/DefaultStatsPrinterPlugin.js +1 -1
  179. package/lib/stats/StatsFactory.js +1 -1
  180. package/lib/typescript/TypeScriptPlugin.js +210 -0
  181. package/lib/url/URLParserPlugin.js +2 -2
  182. package/lib/util/AsyncQueue.js +2 -2
  183. package/lib/util/Hash.js +2 -2
  184. package/lib/util/LocConverter.js +53 -0
  185. package/lib/util/SortableSet.js +1 -1
  186. package/lib/util/cleverMerge.js +2 -2
  187. package/lib/util/comparators.js +3 -3
  188. package/lib/util/concatenate.js +3 -3
  189. package/lib/util/conventions.js +42 -1
  190. package/lib/util/createMappings.js +118 -0
  191. package/lib/{formatLocation.js → util/formatLocation.js} +2 -2
  192. package/lib/{SizeFormatHelpers.js → util/formatSize.js} +3 -1
  193. package/lib/util/fs.js +8 -8
  194. package/lib/util/hash/md4.js +1 -1
  195. package/lib/util/hash/xxhash64.js +1 -1
  196. package/lib/util/identifier.js +48 -0
  197. package/lib/util/internalSerializables.js +35 -19
  198. package/lib/util/magicComment.js +10 -7
  199. package/lib/util/parseJson.js +2 -73
  200. package/lib/util/source.js +21 -0
  201. package/lib/util/topologicalSort.js +69 -0
  202. package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +3 -4
  203. package/lib/wasm-async/AsyncWebAssemblyParser.js +1 -1
  204. package/lib/wasm-sync/UnsupportedWebAssemblyFeatureError.js +5 -3
  205. package/lib/wasm-sync/WasmFinalizeExportsPlugin.js +1 -1
  206. package/lib/wasm-sync/WebAssemblyInInitialChunkError.js +5 -3
  207. package/lib/webpack.js +3 -1
  208. package/package.json +24 -22
  209. package/schemas/WebpackOptions.check.js +1 -1
  210. package/schemas/WebpackOptions.json +129 -12
  211. package/schemas/plugins/{DllPlugin.check.d.ts → HtmlGeneratorOptions.check.d.ts} +1 -1
  212. package/schemas/plugins/HtmlGeneratorOptions.check.js +6 -0
  213. package/schemas/plugins/HtmlGeneratorOptions.json +3 -0
  214. package/schemas/plugins/ProgressPlugin.check.js +1 -1
  215. package/schemas/plugins/ProgressPlugin.json +22 -0
  216. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  217. package/schemas/plugins/container/ContainerReferencePlugin.json +1 -0
  218. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  219. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  220. package/schemas/plugins/container/ModuleFederationPlugin.json +1 -0
  221. package/schemas/plugins/{DllReferencePlugin.check.d.ts → css/CssAutoOrModuleParserOptions.check.d.ts} +1 -1
  222. package/schemas/plugins/css/CssAutoOrModuleParserOptions.check.js +6 -0
  223. package/schemas/plugins/css/CssAutoOrModuleParserOptions.json +3 -0
  224. package/schemas/plugins/dll/DllPlugin.check.d.ts +7 -0
  225. package/schemas/plugins/dll/DllReferencePlugin.check.d.ts +7 -0
  226. package/types.d.ts +1153 -233
  227. package/lib/CaseSensitiveModulesWarning.js +0 -80
  228. package/lib/GraphHelpers.js +0 -49
  229. package/lib/NoModeWarning.js +0 -23
  230. package/lib/css/CssMergeStyleSheetsRuntimeModule.js +0 -57
  231. /package/lib/{AbstractMethodError.js → errors/AbstractMethodError.js} +0 -0
  232. /package/schemas/plugins/{DllPlugin.check.js → dll/DllPlugin.check.js} +0 -0
  233. /package/schemas/plugins/{DllPlugin.json → dll/DllPlugin.json} +0 -0
  234. /package/schemas/plugins/{DllReferencePlugin.check.js → dll/DllReferencePlugin.check.js} +0 -0
  235. /package/schemas/plugins/{DllReferencePlugin.json → dll/DllReferencePlugin.json} +0 -0
@@ -0,0 +1,429 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ */
4
+
5
+ "use strict";
6
+
7
+ const { RawSource } = require("webpack-sources");
8
+ const EntryPlugin = require("../EntryPlugin");
9
+ const HotUpdateChunk = require("../HotUpdateChunk");
10
+ const { HTML_TYPE } = require("../ModuleSourceTypeConstants");
11
+ const { HTML_MODULE_TYPE } = require("../ModuleTypeConstants");
12
+ const NormalModule = require("../NormalModule");
13
+ const ConstDependency = require("../dependencies/ConstDependency");
14
+ const HtmlInlineScriptDependency = require("../dependencies/HtmlInlineScriptDependency");
15
+ const HtmlInlineStyleDependency = require("../dependencies/HtmlInlineStyleDependency");
16
+ const HtmlScriptSrcDependency = require("../dependencies/HtmlScriptSrcDependency");
17
+ const HtmlSourceDependency = require("../dependencies/HtmlSourceDependency");
18
+ const StaticExportsDependency = require("../dependencies/StaticExportsDependency");
19
+ const { compareModulesByFullName } = require("../util/comparators");
20
+ const removeBOM = require("../util/removeBOM");
21
+ const HtmlGenerator = require("./HtmlGenerator");
22
+ const HtmlParser = require("./HtmlParser");
23
+
24
+ /** @typedef {import("../Compiler")} Compiler */
25
+ /** @typedef {{ request: string, entryName: string, kind: "classic" | "esm-script" | "modulepreload" | "stylesheet" }} EntryScriptInfo */
26
+
27
+ const PLUGIN_NAME = "HtmlModulesPlugin";
28
+
29
+ /**
30
+ * @param {string} name definition name in `schemas/WebpackOptions.json`
31
+ * @returns {EXPECTED_OBJECT} a schema referencing `#/definitions/<name>`
32
+ */
33
+ const getSchema = (name) => {
34
+ const { definitions } = require("../../schemas/WebpackOptions.json");
35
+
36
+ return {
37
+ definitions,
38
+ oneOf: [{ $ref: `#/definitions/${name}` }]
39
+ };
40
+ };
41
+
42
+ const generatorValidationOptions = {
43
+ name: "Html Modules Plugin",
44
+ baseDataPath: "generator"
45
+ };
46
+
47
+ class HtmlModulesPlugin {
48
+ /**
49
+ * Applies the plugin by registering its hooks on the compiler.
50
+ * @param {Compiler} compiler the compiler instance
51
+ * @returns {void}
52
+ */
53
+ apply(compiler) {
54
+ // `<script src>` and `<link rel="modulepreload">` references collected
55
+ // by HtmlParser become real compilation entries here. The classic
56
+ // and esm-script groups are chained via a leader-only dependOn so
57
+ // they share a runtime — the first entry of the group owns it and
58
+ // every subsequent entry sets `dependOn: [leader]`. Modulepreload
59
+ // entries are emitted as independent entries (no dependOn) so they
60
+ // can never be imported as a runtime leader by a later script —
61
+ // that's what keeps the "preload but don't execute" contract of
62
+ // `<link rel="modulepreload">` intact.
63
+ /** @type {WeakMap<import("../Compilation"), Set<string>>} */
64
+ const stylesheetEntriesPerCompilation = new WeakMap();
65
+ compiler.hooks.finishMake.tapAsync(PLUGIN_NAME, (compilation, callback) => {
66
+ /** @type {Promise<void>[]} */
67
+ const promises = [];
68
+ /** @type {Set<string>} */
69
+ const stylesheetEntries = new Set();
70
+ stylesheetEntriesPerCompilation.set(compilation, stylesheetEntries);
71
+
72
+ for (const module of compilation.modules) {
73
+ if (module.type !== HTML_MODULE_TYPE) continue;
74
+ const buildInfo = module.buildInfo;
75
+ const htmlEntryScripts =
76
+ buildInfo &&
77
+ /** @type {Record<string, EntryScriptInfo[]> | undefined} */
78
+ (buildInfo.htmlEntryScripts);
79
+ if (!htmlEntryScripts) continue;
80
+
81
+ const context = /** @type {string} */ (module.context);
82
+
83
+ for (const [groupKind, group] of Object.entries(htmlEntryScripts)) {
84
+ // Only the script chains (`classic`, `esm-script`) need a
85
+ // shared runtime via leader-only `dependOn` — the others
86
+ // either preload without executing (`modulepreload`) or
87
+ // produce CSS chunks (`stylesheet`) which have no runtime
88
+ // to share. CSS entries must NOT chain into a JS leader
89
+ // either, because the resulting chunk would mix a CSS
90
+ // stylesheet with a JS runtime.
91
+ const isChainGroup =
92
+ groupKind !== "modulepreload" && groupKind !== "stylesheet";
93
+ /** @type {string | undefined} */
94
+ let leaderName;
95
+ for (const entry of group) {
96
+ const dependOn =
97
+ isChainGroup && leaderName !== undefined
98
+ ? [leaderName]
99
+ : undefined;
100
+ if (isChainGroup && leaderName === undefined) {
101
+ leaderName = entry.entryName;
102
+ }
103
+ if (groupKind === "stylesheet") {
104
+ stylesheetEntries.add(entry.entryName);
105
+ }
106
+ promises.push(
107
+ new Promise((resolve, reject) => {
108
+ compilation.addEntry(
109
+ context,
110
+ EntryPlugin.createDependency(entry.request, {
111
+ name: entry.entryName
112
+ }),
113
+ {
114
+ name: entry.entryName,
115
+ // Each script src / modulepreload entry gets its own
116
+ // filename derived from the synthetic entry name so it
117
+ // doesn't collide with the user's `output.filename`.
118
+ // For CSS entries the JS `filename` is irrelevant (no
119
+ // `.js` is emitted) — the CSS file's name is set on the
120
+ // chunk via `cssFilenameTemplate` in `afterChunks` below.
121
+ filename:
122
+ compilation.outputOptions.chunkFilename || "[name].js",
123
+ dependOn
124
+ },
125
+ (err) => {
126
+ if (err) reject(err);
127
+ else resolve();
128
+ }
129
+ );
130
+ })
131
+ );
132
+ }
133
+ }
134
+ }
135
+
136
+ Promise.all(promises).then(
137
+ () => callback(),
138
+ (err) => callback(err)
139
+ );
140
+ });
141
+
142
+ compiler.hooks.compilation.tap(
143
+ PLUGIN_NAME,
144
+ (compilation, { normalModuleFactory }) => {
145
+ // CSS entries created by `<link rel="stylesheet">` in HTML need
146
+ // their `.css` filename set via `chunk.cssFilenameTemplate`
147
+ // (the field `CssModulesPlugin.getChunkFilenameTemplate` reads).
148
+ // Compilation only flows `options.filename` to `chunk.filenameTemplate`,
149
+ // which controls JS emit — there's no entry-level `cssFilename`.
150
+ // Set it ourselves after chunks are created so each stylesheet
151
+ // entry emits to a distinct file derived from `output.cssFilename`
152
+ // (or `output.cssChunkFilename` for non-initial CSS chunks).
153
+ compilation.hooks.afterChunks.tap(PLUGIN_NAME, () => {
154
+ const stylesheetEntries =
155
+ stylesheetEntriesPerCompilation.get(compilation);
156
+ if (!stylesheetEntries || stylesheetEntries.size === 0) return;
157
+ for (const entryName of stylesheetEntries) {
158
+ const entrypoint = compilation.entrypoints.get(entryName);
159
+ if (!entrypoint) continue;
160
+ const chunk = entrypoint.getEntrypointChunk();
161
+ if (!chunk) continue;
162
+ // Each html-derived stylesheet entry uses the
163
+ // `cssChunkFilename` template — even though the entry
164
+ // chunk technically `canBeInitial()`, we deliberately
165
+ // avoid `cssFilename` here because that template often
166
+ // has no per-entry placeholder (it's derived from
167
+ // `output.filename`, which can be a literal like
168
+ // `bundle0.js`), and multiple `<link rel="stylesheet">`
169
+ // tags would then collide on the same emitted `.css`
170
+ // file. `cssChunkFilename` is derived from
171
+ // `output.chunkFilename` which webpack auto-extends
172
+ // with `[id].` when needed, guaranteeing uniqueness.
173
+ chunk.cssFilenameTemplate =
174
+ compilation.outputOptions.cssChunkFilename;
175
+ }
176
+ });
177
+ compilation.dependencyFactories.set(
178
+ HtmlSourceDependency,
179
+ normalModuleFactory
180
+ );
181
+ compilation.dependencyTemplates.set(
182
+ HtmlSourceDependency,
183
+ new HtmlSourceDependency.Template()
184
+ );
185
+ compilation.dependencyFactories.set(
186
+ HtmlScriptSrcDependency,
187
+ normalModuleFactory
188
+ );
189
+ compilation.dependencyTemplates.set(
190
+ HtmlScriptSrcDependency,
191
+ new HtmlScriptSrcDependency.Template()
192
+ );
193
+ // Inline `<script>` content is bundled as its own entry — the
194
+ // same pipeline that handles `<script src>` — via a
195
+ // `data:text/javascript,...` request. The dependency
196
+ // template rewrites the original tag to `<script src=…>`.
197
+ compilation.dependencyFactories.set(
198
+ HtmlInlineScriptDependency,
199
+ normalModuleFactory
200
+ );
201
+ compilation.dependencyTemplates.set(
202
+ HtmlInlineScriptDependency,
203
+ new HtmlInlineScriptDependency.Template()
204
+ );
205
+ // Inline `<style>` content is routed through the CSS pipeline
206
+ // as a `data:text/css` module. The dependency template reads
207
+ // the processed CSS text from the CSS module's code
208
+ // generation data (`css-text` channel set by CssGenerator
209
+ // when `exportType` is `"text"`).
210
+ compilation.dependencyFactories.set(
211
+ HtmlInlineStyleDependency,
212
+ normalModuleFactory
213
+ );
214
+ compilation.dependencyTemplates.set(
215
+ HtmlInlineStyleDependency,
216
+ new HtmlInlineStyleDependency.Template()
217
+ );
218
+ compilation.dependencyTemplates.set(
219
+ StaticExportsDependency,
220
+ new StaticExportsDependency.Template()
221
+ );
222
+ // `ConstDependency` is used by HtmlParser to insert
223
+ // ` type="module"` into the rewritten <script> tag when
224
+ // `output.module` is on. Register its template so the HTML
225
+ // generator runs the insertion.
226
+ compilation.dependencyTemplates.set(
227
+ ConstDependency,
228
+ new ConstDependency.Template()
229
+ );
230
+ const cssEnabled = Boolean(
231
+ compiler.options.experiments && compiler.options.experiments.css
232
+ );
233
+ normalModuleFactory.hooks.createParser
234
+ .for(HTML_MODULE_TYPE)
235
+ .tap(
236
+ PLUGIN_NAME,
237
+ () =>
238
+ new HtmlParser(
239
+ compilation.outputOptions.hashFunction,
240
+ compiler.context,
241
+ compilation.outputOptions.module,
242
+ cssEnabled
243
+ )
244
+ );
245
+
246
+ normalModuleFactory.hooks.createGenerator
247
+ .for(HTML_MODULE_TYPE)
248
+ .tap(PLUGIN_NAME, (generatorOptions) => {
249
+ compiler.validate(
250
+ () => getSchema("HtmlGeneratorOptions"),
251
+ generatorOptions,
252
+ generatorValidationOptions,
253
+ (options) =>
254
+ require("../../schemas/plugins/HtmlGeneratorOptions.check")(
255
+ options
256
+ )
257
+ );
258
+ return new HtmlGenerator(generatorOptions, compilation.moduleGraph);
259
+ });
260
+
261
+ NormalModule.getCompilationHooks(compilation).processResult.tap(
262
+ PLUGIN_NAME,
263
+ (result, module) => {
264
+ if (module.type === HTML_MODULE_TYPE) {
265
+ const [source, ...rest] = result;
266
+
267
+ return [removeBOM(source), ...rest];
268
+ }
269
+
270
+ return result;
271
+ }
272
+ );
273
+
274
+ // Emit extracted `.html` files for any HTML module that opted
275
+ // into extraction. The opt-in is computed by
276
+ // `HtmlGenerator#_shouldExtract`: `module.generator.html.extract:
277
+ // true` always extracts, `false` never extracts, and when
278
+ // `extract` is unset the generator extracts iff the HTML module
279
+ // is a compilation entry — the iteration below picks up only
280
+ // modules whose generator reported the `html` source type, so
281
+ // that decision is honored implicitly. The HTML content is read
282
+ // from the generator's secondary `"html"` source type (see
283
+ // HtmlGenerator#generate). The filename template comes from
284
+ // `output.htmlFilename` (initial chunks) or
285
+ // `output.htmlChunkFilename` (non-initial chunks), mirroring
286
+ // the CSS pipeline. Path data follows the asset-module pattern —
287
+ // `module` + a relative source `filename`, with `chunk`
288
+ // intentionally omitted so `[name]` resolves to the HTML
289
+ // source's basename (e.g. `page` for `./page.html`) rather
290
+ // than the importing chunk's name (e.g. `main`). A per-module
291
+ // content hash is computed from the rewritten HTML so the
292
+ // template's `[contenthash]` placeholder works; the
293
+ // compilation hash is also forwarded so `[fullhash]` /
294
+ // `[hash]` work in user-supplied templates.
295
+ const {
296
+ getUndoPath,
297
+ makePathsRelative
298
+ } = require("../util/identifier");
299
+ const createHash = require("../util/createHash");
300
+ const nonNumericOnlyHash = require("../util/nonNumericOnlyHash");
301
+ const CssUrlDependency = require("../dependencies/CssUrlDependency");
302
+
303
+ const autoPlaceholder = CssUrlDependency.PUBLIC_PATH_AUTO;
304
+
305
+ compilation.hooks.renderManifest.tap(
306
+ PLUGIN_NAME,
307
+ (result, { chunk, codeGenerationResults, hash: compilationHash }) => {
308
+ // HMR's `HotUpdateChunk`s flow through the same hook
309
+ // but aren't real output chunks — extracting `.html`
310
+ // for them would create stray hot-update HTML files.
311
+ // `CssModulesPlugin` early-returns for the same reason.
312
+ if (chunk instanceof HotUpdateChunk) return result;
313
+ const { chunkGraph } = compilation;
314
+ const modules =
315
+ chunkGraph.getOrderedChunkModulesIterableBySourceType(
316
+ chunk,
317
+ HTML_TYPE,
318
+ compareModulesByFullName(compilation.compiler)
319
+ );
320
+ if (!modules) return result;
321
+ const outputOptions = compilation.outputOptions;
322
+ for (const module of modules) {
323
+ const normalModule = /** @type {NormalModule} */ (module);
324
+ const codeGenResult = codeGenerationResults.get(
325
+ module,
326
+ chunk.runtime
327
+ );
328
+ const placeholderSource = codeGenResult.sources.get(HTML_TYPE);
329
+ if (!placeholderSource) continue;
330
+
331
+ const filenameTemplate = chunk.canBeInitial()
332
+ ? outputOptions.htmlFilename
333
+ : outputOptions.htmlChunkFilename;
334
+
335
+ const sourceFilename = makePathsRelative(
336
+ compiler.context,
337
+ /** @type {string} */
338
+ (normalModule.getResource() || normalModule.resource),
339
+ compiler.root
340
+ ).replace(/^\.\//, "");
341
+
342
+ const placeholderContent = /** @type {string} */ (
343
+ placeholderSource.source()
344
+ );
345
+ const hashInput = createHash(outputOptions.hashFunction);
346
+ if (outputOptions.hashSalt) {
347
+ hashInput.update(outputOptions.hashSalt);
348
+ }
349
+ hashInput.update(placeholderContent);
350
+ const fullContentHash = /** @type {string} */ (
351
+ hashInput.digest(outputOptions.hashDigest)
352
+ );
353
+ const contentHash = nonNumericOnlyHash(
354
+ fullContentHash,
355
+ outputOptions.hashDigestLength
356
+ );
357
+
358
+ const { path: filename, info } = compilation.getPathWithInfo(
359
+ /** @type {import("../TemplatedPathPlugin").TemplatePath} */
360
+ (filenameTemplate),
361
+ {
362
+ module,
363
+ runtime: chunk.runtime,
364
+ chunkGraph,
365
+ contentHash,
366
+ contentHashType: HTML_TYPE,
367
+ filename: sourceFilename,
368
+ hash: compilationHash
369
+ }
370
+ );
371
+
372
+ // Resolve any remaining `[webpack/auto]` placeholders to
373
+ // an undo path computed from the emitted HTML's location.
374
+ // Without this, an `output.htmlFilename` that emits into
375
+ // a subdirectory (e.g. `pages/[name].html`) would leave
376
+ // asset URLs like `image.png` and chunk URLs like
377
+ // `main.js` root-relative, so the browser would resolve
378
+ // them under the HTML's directory instead of the
379
+ // `output.path` root.
380
+ const undoPath = getUndoPath(
381
+ filename,
382
+ /** @type {string} */ (outputOptions.path),
383
+ false
384
+ );
385
+ const finalContent = placeholderContent
386
+ .split(autoPlaceholder)
387
+ .join(undoPath);
388
+ const finalSource = new RawSource(finalContent);
389
+ // The same HTML module can land in multiple chunks
390
+ // with different `output.htmlFilename` /
391
+ // `output.htmlChunkFilename` shapes, which means
392
+ // different `undoPath`s and therefore different
393
+ // final content for the same module id. Include
394
+ // the emitted filename in the asset cache key and
395
+ // the post-undo-path content in the hash, so the
396
+ // asset cache can't reuse one variant's bytes at
397
+ // another variant's URL.
398
+ const finalHash = createHash(outputOptions.hashFunction);
399
+ if (outputOptions.hashSalt) {
400
+ finalHash.update(outputOptions.hashSalt);
401
+ }
402
+ finalHash.update(finalContent);
403
+ const finalContentHash = nonNumericOnlyHash(
404
+ /** @type {string} */ (
405
+ finalHash.digest(outputOptions.hashDigest)
406
+ ),
407
+ outputOptions.hashDigestLength
408
+ );
409
+
410
+ result.push({
411
+ render: () => finalSource,
412
+ filename,
413
+ info,
414
+ auxiliary: true,
415
+ identifier: `htmlModule${chunkGraph.getModuleId(
416
+ module
417
+ )}|${filename}`,
418
+ hash: finalContentHash
419
+ });
420
+ }
421
+ return result;
422
+ }
423
+ );
424
+ }
425
+ );
426
+ }
427
+ }
428
+
429
+ module.exports = HtmlModulesPlugin;