@depup/webpack 5.106.1-depup.0 → 5.109.2-depup.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.
Files changed (669) hide show
  1. package/README.md +9 -11
  2. package/bin/webpack.js +12 -0
  3. package/changes.json +16 -24
  4. package/hot/dev-server.js +2 -0
  5. package/lib/APIPlugin.js +60 -35
  6. package/lib/AsyncDependenciesBlock.js +3 -0
  7. package/lib/AutomaticPrefetchPlugin.js +6 -1
  8. package/lib/BannerPlugin.js +13 -5
  9. package/lib/Cache.js +27 -5
  10. package/lib/CacheFacade.js +41 -0
  11. package/lib/Chunk.js +71 -25
  12. package/lib/ChunkGraph.js +153 -19
  13. package/lib/ChunkGroup.js +115 -28
  14. package/lib/ChunkTemplate.js +9 -0
  15. package/lib/CircularModulesPlugin.js +190 -0
  16. package/lib/CleanPlugin.js +27 -28
  17. package/lib/CodeGenerationResults.js +19 -0
  18. package/lib/CompatibilityPlugin.js +85 -37
  19. package/lib/Compilation.js +656 -112
  20. package/lib/Compiler.js +109 -35
  21. package/lib/ConcatenationScope.js +34 -4
  22. package/lib/ConditionalInitFragment.js +6 -0
  23. package/lib/ConstPlugin.js +15 -12
  24. package/lib/ContextExclusionPlugin.js +3 -1
  25. package/lib/ContextModule.js +345 -55
  26. package/lib/ContextModuleFactory.js +193 -51
  27. package/lib/ContextReplacementPlugin.js +8 -1
  28. package/lib/DefinePlugin.js +537 -139
  29. package/lib/DependenciesBlock.js +6 -1
  30. package/lib/Dependency.js +159 -11
  31. package/lib/DependencyTemplate.js +7 -1
  32. package/lib/DependencyTemplates.js +4 -0
  33. package/lib/DotenvPlugin.js +3 -0
  34. package/lib/DynamicEntryPlugin.js +3 -1
  35. package/lib/EntryOptionPlugin.js +42 -2
  36. package/lib/EntryPlugin.js +4 -1
  37. package/lib/Entrypoint.js +5 -1
  38. package/lib/EnvironmentPlugin.js +3 -2
  39. package/lib/ErrorHelpers.js +7 -0
  40. package/lib/EvalDevToolModulePlugin.js +3 -1
  41. package/lib/EvalSourceMapDevToolPlugin.js +11 -11
  42. package/lib/ExportsInfo.js +421 -113
  43. package/lib/ExportsInfoApiPlugin.js +4 -3
  44. package/lib/ExternalModule.js +381 -80
  45. package/lib/ExternalModuleFactoryPlugin.js +75 -3
  46. package/lib/ExternalsPlugin.js +3 -1
  47. package/lib/FileSystemInfo.js +701 -175
  48. package/lib/FlagAllModulesAsUsedPlugin.js +3 -6
  49. package/lib/FlagDependencyExportsPlugin.js +82 -9
  50. package/lib/FlagDependencyUsagePlugin.js +115 -8
  51. package/lib/FlagEntryExportAsUsedPlugin.js +4 -1
  52. package/lib/Generator.js +24 -3
  53. package/lib/HotModuleReplacementPlugin.js +110 -44
  54. package/lib/IgnorePlugin.js +5 -2
  55. package/lib/IgnoreWarningsPlugin.js +2 -1
  56. package/lib/InitFragment.js +33 -30
  57. package/lib/JavascriptMetaInfoPlugin.js +9 -6
  58. package/lib/LazyBarrel.js +389 -0
  59. package/lib/LibraryTemplatePlugin.js +2 -1
  60. package/lib/LoaderOptionsPlugin.js +3 -1
  61. package/lib/LoaderTargetPlugin.js +3 -1
  62. package/lib/MainTemplate.js +15 -0
  63. package/lib/ManifestPlugin.js +9 -2
  64. package/lib/Module.js +121 -57
  65. package/lib/ModuleFactory.js +6 -1
  66. package/lib/ModuleFilenameHelpers.js +18 -4
  67. package/lib/ModuleGraph.js +69 -2
  68. package/lib/ModuleGraphConnection.js +9 -0
  69. package/lib/ModuleInfoHeaderPlugin.js +5 -0
  70. package/lib/ModuleNotFoundError.js +3 -83
  71. package/lib/ModuleProfile.js +27 -1
  72. package/lib/ModuleSourceTypeConstants.js +52 -19
  73. package/lib/ModuleTemplate.js +10 -0
  74. package/lib/ModuleTypeConstants.js +20 -4
  75. package/lib/MultiCompiler.js +59 -4
  76. package/lib/MultiStats.js +9 -0
  77. package/lib/MultiWatching.js +6 -0
  78. package/lib/NoEmitOnErrorsPlugin.js +1 -1
  79. package/lib/NodeStuffPlugin.js +78 -46
  80. package/lib/NormalModule.js +519 -206
  81. package/lib/NormalModuleFactory.js +156 -31
  82. package/lib/NormalModuleReplacementPlugin.js +3 -1
  83. package/lib/NullFactory.js +1 -0
  84. package/lib/OptionsApply.js +1 -0
  85. package/lib/Parser.js +3 -1
  86. package/lib/PlatformPlugin.js +2 -1
  87. package/lib/PrefetchPlugin.js +4 -1
  88. package/lib/ProgressPlugin.js +351 -161
  89. package/lib/ProvidePlugin.js +6 -3
  90. package/lib/RawModule.js +32 -16
  91. package/lib/RecordIdsPlugin.js +9 -0
  92. package/lib/RequestShortener.js +8 -0
  93. package/lib/ResolverFactory.js +5 -0
  94. package/lib/RuntimeGlobals.js +58 -5
  95. package/lib/RuntimeModule.js +22 -7
  96. package/lib/RuntimePlugin.js +123 -118
  97. package/lib/RuntimeTemplate.js +616 -37
  98. package/lib/SelfModuleFactory.js +3 -0
  99. package/lib/SourceMapDevToolModuleOptionsPlugin.js +2 -0
  100. package/lib/SourceMapDevToolPlugin.js +341 -63
  101. package/lib/Stats.js +6 -0
  102. package/lib/Template.js +52 -6
  103. package/lib/TemplatedPathPlugin.js +505 -138
  104. package/lib/UseStrictPlugin.js +3 -2
  105. package/lib/WarnCaseSensitiveModulesPlugin.js +72 -3
  106. package/lib/WarnDeprecatedOptionPlugin.js +6 -2
  107. package/lib/WarnNoModeSetPlugin.js +18 -2
  108. package/lib/WatchIgnorePlugin.js +5 -1
  109. package/lib/Watching.js +25 -3
  110. package/lib/WebpackError.js +3 -74
  111. package/lib/WebpackIsIncludedPlugin.js +4 -2
  112. package/lib/WebpackOptionsApply.js +88 -25
  113. package/lib/WebpackOptionsDefaulter.js +1 -0
  114. package/lib/asset/AssetBytesGenerator.js +28 -10
  115. package/lib/asset/AssetBytesParser.js +1 -0
  116. package/lib/asset/AssetGenerator.js +199 -60
  117. package/lib/asset/AssetModule.js +47 -0
  118. package/lib/asset/AssetModulesPlugin.js +115 -24
  119. package/lib/asset/AssetParser.js +4 -2
  120. package/lib/asset/AssetSourceGenerator.js +26 -8
  121. package/lib/asset/AssetSourceParser.js +1 -0
  122. package/lib/asset/RawDataUrlModule.js +23 -13
  123. package/lib/asset/WebManifestGenerator.js +164 -0
  124. package/lib/asset/WebManifestParser.js +130 -0
  125. package/lib/async-modules/AsyncModuleHelpers.js +1 -0
  126. package/lib/async-modules/AwaitDependenciesInitFragment.js +18 -4
  127. package/lib/async-modules/InferAsyncModulesPlugin.js +1 -1
  128. package/lib/async-modules/isGeneratorLowered.js +26 -0
  129. package/lib/buildChunkGraph.js +107 -15
  130. package/lib/bun/BunTargetPlugin.js +42 -0
  131. package/lib/cache/AddBuildDependenciesPlugin.js +3 -1
  132. package/lib/cache/AddManagedPathsPlugin.js +5 -1
  133. package/lib/cache/IdleFileCachePlugin.js +6 -1
  134. package/lib/cache/MemoryCachePlugin.js +1 -1
  135. package/lib/cache/MemoryWithGcCachePlugin.js +4 -1
  136. package/lib/cache/PackFileCacheStrategy.js +302 -12
  137. package/lib/cache/ResolverCachePlugin.js +12 -1
  138. package/lib/cache/getLazyHashedEtag.js +13 -2
  139. package/lib/cache/mergeEtags.js +4 -0
  140. package/lib/cli.js +142 -20
  141. package/lib/config/browserslistTargetHandler.js +141 -0
  142. package/lib/config/defaults.js +612 -43
  143. package/lib/config/defineConfig.js +31 -0
  144. package/lib/config/normalization.js +46 -1
  145. package/lib/config/target.js +200 -2
  146. package/lib/container/ContainerEntryDependency.js +2 -0
  147. package/lib/container/ContainerEntryModule.js +27 -14
  148. package/lib/container/ContainerEntryModuleFactory.js +1 -0
  149. package/lib/container/ContainerExposedDependency.js +6 -2
  150. package/lib/container/ContainerPlugin.js +2 -1
  151. package/lib/container/ContainerReferencePlugin.js +3 -2
  152. package/lib/container/FallbackDependency.js +9 -7
  153. package/lib/container/FallbackItemDependency.js +1 -0
  154. package/lib/container/FallbackModule.js +22 -9
  155. package/lib/container/FallbackModuleFactory.js +1 -0
  156. package/lib/container/HoistContainerReferencesPlugin.js +47 -55
  157. package/lib/container/ModuleFederationPlugin.js +21 -29
  158. package/lib/container/RemoteModule.js +33 -10
  159. package/lib/container/RemoteRuntimeModule.js +15 -12
  160. package/lib/container/RemoteToExternalDependency.js +1 -0
  161. package/lib/container/options.js +7 -0
  162. package/lib/css/CssGenerator.js +540 -272
  163. package/lib/css/CssInjectStyleRuntimeModule.js +86 -70
  164. package/lib/css/CssLoadingRuntimeModule.js +173 -81
  165. package/lib/{CssModule.js → css/CssModule.js} +72 -37
  166. package/lib/css/CssModulesPlugin.js +371 -208
  167. package/lib/css/CssParser.js +3538 -1963
  168. package/lib/css/syntax.js +4155 -0
  169. package/lib/debug/ProfilingPlugin.js +33 -2
  170. package/lib/deno/DenoTargetPlugin.js +41 -0
  171. package/lib/dependencies/AMDDefineDependency.js +29 -17
  172. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +19 -6
  173. package/lib/dependencies/AMDPlugin.js +6 -3
  174. package/lib/dependencies/AMDRequireArrayDependency.js +13 -11
  175. package/lib/dependencies/AMDRequireContextDependency.js +10 -11
  176. package/lib/dependencies/AMDRequireDependenciesBlock.js +1 -0
  177. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +28 -14
  178. package/lib/dependencies/AMDRequireDependency.js +28 -20
  179. package/lib/dependencies/AMDRequireItemDependency.js +1 -0
  180. package/lib/dependencies/AMDRuntimeModules.js +3 -0
  181. package/lib/dependencies/CachedConstDependency.js +9 -1
  182. package/lib/dependencies/CommonJsDependencyHelpers.js +104 -0
  183. package/lib/dependencies/CommonJsExportRequireDependency.js +157 -38
  184. package/lib/dependencies/CommonJsExportsDependency.js +74 -20
  185. package/lib/dependencies/CommonJsExportsParserPlugin.js +246 -15
  186. package/lib/dependencies/CommonJsFullRequireDependency.js +91 -27
  187. package/lib/dependencies/CommonJsImportsParserPlugin.js +189 -24
  188. package/lib/dependencies/CommonJsPlugin.js +7 -4
  189. package/lib/dependencies/CommonJsRequireContextDependency.js +13 -13
  190. package/lib/dependencies/CommonJsRequireDependency.js +135 -13
  191. package/lib/dependencies/CommonJsSelfReferenceDependency.js +60 -16
  192. package/lib/dependencies/ConstDependency.js +22 -12
  193. package/lib/dependencies/ContextDependency.js +13 -2
  194. package/lib/dependencies/ContextDependencyHelpers.js +7 -4
  195. package/lib/dependencies/ContextDependencyTemplateAsId.js +2 -1
  196. package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +1 -0
  197. package/lib/dependencies/ContextElementDependency.js +27 -14
  198. package/lib/dependencies/CreateRequireParserPlugin.js +14 -7
  199. package/lib/dependencies/CreateScriptUrlDependency.js +9 -7
  200. package/lib/dependencies/CriticalDependencyWarning.js +3 -1
  201. package/lib/dependencies/CssIcssExportDependency.js +681 -367
  202. package/lib/dependencies/CssIcssImportDependency.js +62 -17
  203. package/lib/dependencies/CssIcssSymbolDependency.js +36 -17
  204. package/lib/dependencies/CssImportDependency.js +37 -1
  205. package/lib/dependencies/CssUrlDependency.js +87 -14
  206. package/lib/dependencies/DelegatedSourceDependency.js +1 -0
  207. package/lib/dependencies/DllEntryDependency.js +12 -13
  208. package/lib/dependencies/DynamicExports.js +5 -0
  209. package/lib/dependencies/EntryDependency.js +1 -0
  210. package/lib/dependencies/ExportBindingInitFragment.js +164 -0
  211. package/lib/dependencies/ExportsInfoDependency.js +18 -12
  212. package/lib/dependencies/ExternalModuleDependency.js +13 -5
  213. package/lib/dependencies/ExternalModuleInitFragment.js +10 -5
  214. package/lib/dependencies/ExternalModuleInitFragmentDependency.js +19 -12
  215. package/lib/dependencies/HarmonyAcceptDependency.js +24 -26
  216. package/lib/dependencies/HarmonyAcceptImportDependency.js +2 -0
  217. package/lib/dependencies/HarmonyCompatibilityDependency.js +33 -14
  218. package/lib/dependencies/HarmonyDetectionParserPlugin.js +108 -30
  219. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +34 -3
  220. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +70 -33
  221. package/lib/dependencies/HarmonyExportExpressionDependency.js +133 -43
  222. package/lib/dependencies/HarmonyExportHeaderDependency.js +11 -9
  223. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +268 -44
  224. package/lib/dependencies/HarmonyExportInitFragment.js +28 -20
  225. package/lib/dependencies/HarmonyExportSpecifierDependency.js +88 -18
  226. package/lib/dependencies/HarmonyExports.js +6 -1
  227. package/lib/dependencies/HarmonyImportDependency.js +60 -4
  228. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +139 -146
  229. package/lib/dependencies/HarmonyImportGuard.js +427 -0
  230. package/lib/dependencies/HarmonyImportSideEffectDependency.js +22 -1
  231. package/lib/dependencies/HarmonyImportSpecifierDependency.js +146 -24
  232. package/lib/{HarmonyLinkingError.js → dependencies/HarmonyLinkingError.js} +6 -3
  233. package/lib/dependencies/HarmonyModulesPlugin.js +11 -1
  234. package/lib/dependencies/HarmonyTopLevelThisParserPlugin.js +2 -1
  235. package/lib/dependencies/HtmlEntryDependency.js +1295 -0
  236. package/lib/dependencies/HtmlInlineHtmlDependency.js +107 -0
  237. package/lib/dependencies/HtmlInlineScriptDependency.js +126 -0
  238. package/lib/dependencies/HtmlInlineStyleDependency.js +152 -0
  239. package/lib/dependencies/HtmlSourceDependency.js +172 -0
  240. package/lib/dependencies/ImportContextDependency.js +9 -9
  241. package/lib/dependencies/ImportDependency.js +92 -3
  242. package/lib/dependencies/ImportEagerDependency.js +2 -0
  243. package/lib/dependencies/ImportMetaContextDependency.js +1 -0
  244. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +35 -19
  245. package/lib/dependencies/ImportMetaContextPlugin.js +40 -8
  246. package/lib/dependencies/ImportMetaGlobDependency.js +81 -0
  247. package/lib/dependencies/ImportMetaGlobDependencyParserPlugin.js +78 -0
  248. package/lib/dependencies/ImportMetaGlobHelpers.js +660 -0
  249. package/lib/dependencies/ImportMetaHotAcceptDependency.js +2 -0
  250. package/lib/dependencies/ImportMetaHotDeclineDependency.js +2 -0
  251. package/lib/dependencies/ImportMetaPlugin.js +595 -209
  252. package/lib/dependencies/ImportMetaResolveDependency.js +90 -0
  253. package/lib/dependencies/ImportParserPlugin.js +114 -27
  254. package/lib/dependencies/ImportPhase.js +17 -11
  255. package/lib/dependencies/ImportPlugin.js +2 -1
  256. package/lib/dependencies/ImportWeakDependency.js +3 -0
  257. package/lib/dependencies/JsonExportsDependency.js +15 -10
  258. package/lib/dependencies/LoaderDependency.js +2 -0
  259. package/lib/dependencies/LoaderImportDependency.js +3 -0
  260. package/lib/dependencies/LoaderPlugin.js +9 -2
  261. package/lib/dependencies/LocalModule.js +15 -12
  262. package/lib/dependencies/LocalModuleDependency.js +15 -13
  263. package/lib/dependencies/LocalModulesHelpers.js +3 -0
  264. package/lib/dependencies/ModuleDecoratorDependency.js +16 -10
  265. package/lib/dependencies/ModuleDependency.js +14 -0
  266. package/lib/dependencies/ModuleDependencyTemplateAsId.js +1 -0
  267. package/lib/dependencies/ModuleDependencyTemplateAsRequireId.js +1 -0
  268. package/lib/dependencies/ModuleHotAcceptDependency.js +2 -0
  269. package/lib/dependencies/ModuleHotDeclineDependency.js +2 -0
  270. package/lib/dependencies/ModuleInitFragmentDependency.js +19 -11
  271. package/lib/dependencies/NullDependency.js +2 -0
  272. package/lib/dependencies/PrefetchDependency.js +1 -0
  273. package/lib/dependencies/ProvidedDependency.js +36 -27
  274. package/lib/dependencies/PureExpressionDependency.js +14 -10
  275. package/lib/dependencies/RequireContextDependency.js +1 -0
  276. package/lib/dependencies/RequireContextDependencyParserPlugin.js +2 -1
  277. package/lib/dependencies/RequireContextPlugin.js +2 -1
  278. package/lib/dependencies/RequireEnsureDependenciesBlock.js +1 -0
  279. package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +4 -6
  280. package/lib/dependencies/RequireEnsureDependency.js +16 -13
  281. package/lib/dependencies/RequireEnsureItemDependency.js +1 -0
  282. package/lib/dependencies/RequireEnsurePlugin.js +2 -1
  283. package/lib/dependencies/RequireHeaderDependency.js +7 -4
  284. package/lib/dependencies/RequireIncludeDependency.js +2 -0
  285. package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +11 -12
  286. package/lib/dependencies/RequireIncludePlugin.js +2 -1
  287. package/lib/{RequireJsStuffPlugin.js → dependencies/RequireJsStuffPlugin.js} +9 -8
  288. package/lib/dependencies/RequireResolveContextDependency.js +10 -11
  289. package/lib/dependencies/RequireResolveDependency.js +2 -0
  290. package/lib/dependencies/RequireResolveHeaderDependency.js +8 -5
  291. package/lib/dependencies/RuntimeRequirementsDependency.js +11 -8
  292. package/lib/dependencies/StaticExportsDependency.js +13 -10
  293. package/lib/dependencies/SystemPlugin.js +9 -6
  294. package/lib/dependencies/SystemRuntimeModule.js +1 -0
  295. package/lib/dependencies/TopLevelAwaitDependency.js +93 -0
  296. package/lib/dependencies/URLContextDependency.js +8 -7
  297. package/lib/dependencies/URLDependency.js +157 -33
  298. package/lib/dependencies/URLPlugin.js +2 -0
  299. package/lib/dependencies/UnsupportedDependency.js +12 -13
  300. package/lib/dependencies/WebAssemblyExportImportedDependency.js +15 -16
  301. package/lib/dependencies/WebAssemblyImportDependency.js +19 -18
  302. package/lib/dependencies/WebpackIsIncludedDependency.js +3 -0
  303. package/lib/dependencies/{WorkerPlugin.js → WorkerAndWorkletPlugin.js} +364 -114
  304. package/lib/dependencies/WorkerDependency.js +111 -27
  305. package/lib/dependencies/WorkletDependency.js +278 -0
  306. package/lib/dependencies/getFunctionExpression.js +1 -0
  307. package/lib/dependencies/processExportInfo.js +14 -11
  308. package/lib/{DelegatedModule.js → dll/DelegatedModule.js} +71 -44
  309. package/lib/{DelegatedModuleFactoryPlugin.js → dll/DelegatedModuleFactoryPlugin.js} +27 -4
  310. package/lib/{DelegatedPlugin.js → dll/DelegatedPlugin.js} +5 -3
  311. package/lib/{DllEntryPlugin.js → dll/DllEntryPlugin.js} +9 -5
  312. package/lib/{DllModule.js → dll/DllModule.js} +36 -24
  313. package/lib/{DllModuleFactory.js → dll/DllModuleFactory.js} +5 -4
  314. package/lib/{DllPlugin.js → dll/DllPlugin.js} +24 -6
  315. package/lib/{DllReferencePlugin.js → dll/DllReferencePlugin.js} +26 -18
  316. package/lib/{LibManifestPlugin.js → dll/LibManifestPlugin.js} +14 -10
  317. package/lib/electron/ElectronTargetPlugin.js +24 -5
  318. package/lib/{AbstractMethodError.js → errors/AbstractMethodError.js} +10 -1
  319. package/lib/{AsyncDependencyToInitialChunkError.js → errors/AsyncDependencyToInitialChunkError.js} +8 -3
  320. package/lib/errors/BuildCycleError.js +1 -1
  321. package/lib/{ChunkRenderError.js → errors/ChunkRenderError.js} +1 -1
  322. package/lib/{CodeGenerationError.js → errors/CodeGenerationError.js} +1 -1
  323. package/lib/{CommentCompilationWarning.js → errors/CommentCompilationWarning.js} +9 -3
  324. package/lib/{ConcurrentCompilationError.js → errors/ConcurrentCompilationError.js} +5 -2
  325. package/lib/{EnvironmentNotSupportAsyncWarning.js → errors/EnvironmentNotSupportAsyncWarning.js} +5 -5
  326. package/lib/{HookWebpackError.js → errors/HookWebpackError.js} +20 -16
  327. package/lib/{IgnoreErrorModuleFactory.js → errors/IgnoreErrorModuleFactory.js} +7 -4
  328. package/lib/{InvalidDependenciesModuleWarning.js → errors/InvalidDependenciesModuleWarning.js} +6 -3
  329. package/lib/errors/JSONParseError.js +115 -0
  330. package/lib/errors/LoaderLoadingError.js +20 -0
  331. package/lib/{ModuleBuildError.js → errors/ModuleBuildError.js} +22 -16
  332. package/lib/{ModuleDependencyError.js → errors/ModuleDependencyError.js} +10 -3
  333. package/lib/{ModuleDependencyWarning.js → errors/ModuleDependencyWarning.js} +13 -5
  334. package/lib/{ModuleError.js → errors/ModuleError.js} +10 -14
  335. package/lib/{ModuleHashingError.js → errors/ModuleHashingError.js} +5 -1
  336. package/lib/errors/ModuleNotFoundError.js +94 -0
  337. package/lib/errors/ModuleParseError.js +141 -0
  338. package/lib/{ModuleRestoreError.js → errors/ModuleRestoreError.js} +4 -1
  339. package/lib/{ModuleStoreError.js → errors/ModuleStoreError.js} +5 -1
  340. package/lib/{ModuleWarning.js → errors/ModuleWarning.js} +13 -14
  341. package/lib/{NodeStuffInWebError.js → errors/NodeStuffInWebError.js} +7 -5
  342. package/lib/errors/NonErrorEmittedError.js +30 -0
  343. package/lib/{UnhandledSchemeError.js → errors/UnhandledSchemeError.js} +9 -2
  344. package/lib/{UnsupportedFeatureWarning.js → errors/UnsupportedFeatureWarning.js} +4 -3
  345. package/lib/errors/WebpackError.js +84 -0
  346. package/lib/esm/ExportWebpackRequireRuntimeModule.js +2 -0
  347. package/lib/esm/ModuleChunkFormatPlugin.js +52 -15
  348. package/lib/esm/ModuleChunkLoadingPlugin.js +11 -3
  349. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +80 -52
  350. package/lib/hmr/HotModuleReplacement.runtime.js +175 -30
  351. package/lib/hmr/HotModuleReplacementRuntimeModule.js +8 -0
  352. package/lib/hmr/JavascriptHotModuleReplacement.runtime.js +173 -26
  353. package/lib/hmr/JavascriptHotModuleReplacementHelper.js +1 -0
  354. package/lib/hmr/LazyCompilationPlugin.js +154 -7
  355. package/lib/hmr/lazyCompilationBackend.js +53 -12
  356. package/lib/html/HtmlGenerator.js +1490 -0
  357. package/lib/html/HtmlModule.js +41 -0
  358. package/lib/html/HtmlModulesPlugin.js +1129 -0
  359. package/lib/html/HtmlParser.js +1970 -0
  360. package/lib/html/favicon.svg +1 -0
  361. package/lib/html/syntax.js +9106 -0
  362. package/lib/ids/ChunkModuleIdRangePlugin.js +3 -1
  363. package/lib/ids/DeterministicChunkIdsPlugin.js +3 -1
  364. package/lib/ids/DeterministicModuleIdsPlugin.js +3 -1
  365. package/lib/ids/HashedModuleIdsPlugin.js +2 -1
  366. package/lib/ids/IdHelpers.js +49 -12
  367. package/lib/ids/NamedChunkIdsPlugin.js +3 -1
  368. package/lib/ids/NamedModuleIdsPlugin.js +3 -1
  369. package/lib/ids/NaturalChunkIdsPlugin.js +1 -1
  370. package/lib/ids/NaturalModuleIdsPlugin.js +1 -1
  371. package/lib/ids/OccurrenceChunkIdsPlugin.js +2 -1
  372. package/lib/ids/OccurrenceModuleIdsPlugin.js +4 -1
  373. package/lib/ids/SyncModuleIdsPlugin.js +3 -1
  374. package/lib/index.js +66 -15
  375. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +5 -6
  376. package/lib/javascript/BasicEvaluatedExpression.js +370 -49
  377. package/lib/javascript/ChunkFormatHelpers.js +2 -1
  378. package/lib/javascript/ChunkHelpers.js +1 -0
  379. package/lib/javascript/CommonJsChunkFormatPlugin.js +1 -1
  380. package/lib/javascript/EnableChunkLoadingPlugin.js +6 -1
  381. package/lib/javascript/JavascriptGenerator.js +213 -51
  382. package/lib/javascript/JavascriptModule.js +54 -0
  383. package/lib/javascript/JavascriptModulesPlugin.js +628 -198
  384. package/lib/javascript/JavascriptParser.js +1334 -471
  385. package/lib/javascript/JavascriptParserHelpers.js +10 -7
  386. package/lib/javascript/StartupHelpers.js +5 -0
  387. package/lib/javascript/syntax.js +5037 -0
  388. package/lib/json/JsonData.js +5 -0
  389. package/lib/json/JsonGenerator.js +21 -0
  390. package/lib/json/JsonModule.js +40 -0
  391. package/lib/json/JsonModulesPlugin.js +8 -1
  392. package/lib/json/JsonParser.js +18 -27
  393. package/lib/library/AbstractLibraryPlugin.js +17 -2
  394. package/lib/library/AmdLibraryPlugin.js +8 -0
  395. package/lib/library/AssignLibraryPlugin.js +21 -3
  396. package/lib/library/EnableLibraryPlugin.js +8 -2
  397. package/lib/library/ExportPropertyLibraryPlugin.js +10 -0
  398. package/lib/{FalseIIFEUmdWarning.js → library/FalseIIFEUmdWarning.js} +2 -1
  399. package/lib/library/JsonpLibraryPlugin.js +8 -0
  400. package/lib/library/ModuleLibraryPlugin.js +154 -7
  401. package/lib/library/SystemLibraryPlugin.js +11 -3
  402. package/lib/library/UmdLibraryPlugin.js +16 -0
  403. package/lib/loaders/LoaderRunner.js +714 -0
  404. package/lib/loaders/loadLoader.js +100 -0
  405. package/lib/logging/Logger.js +17 -0
  406. package/lib/logging/createConsoleLogger.js +7 -0
  407. package/lib/logging/runtime.js +2 -0
  408. package/lib/logging/truncateArgs.js +2 -0
  409. package/lib/node/CommonJsChunkLoadingPlugin.js +5 -1
  410. package/lib/node/NodeEnvironmentPlugin.js +7 -3
  411. package/lib/node/NodeSourcePlugin.js +1 -1
  412. package/lib/node/NodeTargetPlugin.js +4 -63
  413. package/lib/node/NodeTemplatePlugin.js +3 -1
  414. package/lib/node/NodeWatchFileSystem.js +40 -22
  415. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +13 -9
  416. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +33 -3
  417. package/lib/node/ReadFileCompileWasmPlugin.js +28 -3
  418. package/lib/node/RequireChunkLoadingRuntimeModule.js +21 -16
  419. package/lib/node/nodeBuiltins.js +80 -0
  420. package/lib/node/nodeConsole.js +116 -64
  421. package/lib/optimize/AggressiveMergingPlugin.js +22 -16
  422. package/lib/optimize/AggressiveSplittingPlugin.js +6 -1
  423. package/lib/optimize/ConcatenatedModule.js +603 -130
  424. package/lib/optimize/ConstExportsPlugin.js +211 -0
  425. package/lib/optimize/EnsureChunkConditionsPlugin.js +2 -1
  426. package/lib/optimize/FlagIncludedChunksPlugin.js +15 -4
  427. package/lib/optimize/InlineExports.js +178 -0
  428. package/lib/optimize/InnerGraph.js +374 -262
  429. package/lib/optimize/InnerGraphPlugin.js +246 -117
  430. package/lib/optimize/LimitChunkCountPlugin.js +9 -0
  431. package/lib/optimize/MangleExportsPlugin.js +5 -1
  432. package/lib/optimize/MergeDuplicateChunksPlugin.js +2 -0
  433. package/lib/optimize/MinChunkSizePlugin.js +2 -1
  434. package/lib/optimize/MinMaxSizeWarning.js +5 -4
  435. package/lib/optimize/ModuleConcatenationPlugin.js +229 -55
  436. package/lib/optimize/RealContentHashPlugin.js +130 -52
  437. package/lib/optimize/RemoveEmptyChunksPlugin.js +2 -1
  438. package/lib/optimize/RemoveParentModulesPlugin.js +3 -1
  439. package/lib/optimize/RuntimeChunkPlugin.js +2 -1
  440. package/lib/optimize/SideEffectsFlagPlugin.js +381 -55
  441. package/lib/optimize/SplitChunksPlugin.js +200 -50
  442. package/lib/performance/AssetsOverSizeLimitWarning.js +3 -2
  443. package/lib/performance/EntrypointsOverSizeLimitWarning.js +3 -2
  444. package/lib/performance/NoAsyncChunksWarning.js +5 -3
  445. package/lib/performance/SizeLimitsPlugin.js +8 -2
  446. package/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js +1 -0
  447. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +21 -0
  448. package/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js +1 -0
  449. package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +5 -1
  450. package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +25 -13
  451. package/lib/prefetch/ResourceHintPlugin.js +687 -0
  452. package/lib/prefetch/ResourceHintRuntimeModule.js +149 -0
  453. package/lib/prefetch/StartupAssetHintRuntimeModule.js +210 -0
  454. package/lib/prefetch/parseResourceHintOptions.js +103 -0
  455. package/lib/rules/BasicEffectRulePlugin.js +3 -0
  456. package/lib/rules/BasicMatcherRulePlugin.js +3 -0
  457. package/lib/rules/ObjectMatcherRulePlugin.js +3 -0
  458. package/lib/rules/RuleSetCompiler.js +132 -0
  459. package/lib/rules/UseEffectRulePlugin.js +10 -3
  460. package/lib/runtime/AsyncModuleGeneratorRuntimeModule.js +56 -0
  461. package/lib/runtime/AsyncModuleRuntimeModule.js +52 -33
  462. package/lib/runtime/AutoPublicPathRuntimeModule.js +22 -9
  463. package/lib/runtime/BaseUriRuntimeModule.js +1 -0
  464. package/lib/runtime/ChunkNameRuntimeModule.js +1 -0
  465. package/lib/runtime/CommonJsWrapRuntimeModule.js +37 -0
  466. package/lib/runtime/CompatGetDefaultExportRuntimeModule.js +2 -1
  467. package/lib/runtime/CompatRuntimeModule.js +2 -0
  468. package/lib/runtime/CreateFakeNamespaceObjectRuntimeModule.js +7 -4
  469. package/lib/runtime/CreateScriptRuntimeModule.js +1 -0
  470. package/lib/runtime/CreateScriptUrlRuntimeModule.js +1 -0
  471. package/lib/runtime/DefinePropertyGettersRuntimeModule.js +34 -4
  472. package/lib/runtime/EnsureChunkRuntimeModule.js +1 -0
  473. package/lib/runtime/GetChunkFilenameRuntimeModule.js +88 -8
  474. package/lib/runtime/GetFullHashRuntimeModule.js +1 -0
  475. package/lib/runtime/GetMainFilenameRuntimeModule.js +1 -0
  476. package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +2 -1
  477. package/lib/runtime/GetWorkletBootstrapRuntimeModule.js +59 -0
  478. package/lib/runtime/GlobalRuntimeModule.js +1 -0
  479. package/lib/runtime/HasOwnPropertyRuntimeModule.js +2 -1
  480. package/lib/runtime/HelperRuntimeModule.js +5 -0
  481. package/lib/runtime/LoadScriptRuntimeModule.js +28 -37
  482. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +354 -37
  483. package/lib/runtime/MakeNamespaceObjectRuntimeModule.js +2 -1
  484. package/lib/runtime/NonceRuntimeModule.js +1 -0
  485. package/lib/runtime/OnChunksLoadedRuntimeModule.js +5 -4
  486. package/lib/runtime/PublicPathRuntimeModule.js +1 -0
  487. package/lib/runtime/RelativeUrlRuntimeModule.js +4 -2
  488. package/lib/runtime/RuntimeIdRuntimeModule.js +1 -0
  489. package/lib/runtime/SetAnonymousDefaultNameRuntimeModule.js +38 -0
  490. package/lib/runtime/StartupChunkDependenciesPlugin.js +13 -1
  491. package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +2 -1
  492. package/lib/runtime/StartupEntrypointRuntimeModule.js +5 -3
  493. package/lib/runtime/SystemContextRuntimeModule.js +1 -0
  494. package/lib/runtime/ToBinaryRuntimeModule.js +1 -0
  495. package/lib/runtime/WorkerRuntimeModule.js +33 -0
  496. package/lib/schemes/DataUriPlugin.js +14 -2
  497. package/lib/schemes/FileUriPlugin.js +1 -1
  498. package/lib/schemes/HttpUriPlugin.js +86 -4
  499. package/lib/schemes/VirtualUrlPlugin.js +8 -4
  500. package/lib/serialization/AggregateErrorSerializer.js +9 -6
  501. package/lib/serialization/ArraySerializer.js +6 -8
  502. package/lib/serialization/BinaryMiddleware.js +427 -1006
  503. package/lib/serialization/DateObjectSerializer.js +4 -2
  504. package/lib/serialization/ErrorObjectSerializer.js +10 -6
  505. package/lib/serialization/FileMiddleware.js +345 -59
  506. package/lib/serialization/MapObjectSerializer.js +7 -9
  507. package/lib/serialization/NullPrototypeObjectSerializer.js +9 -9
  508. package/lib/serialization/ObjectMiddleware.js +73 -13
  509. package/lib/serialization/PlainObjectSerializer.js +16 -8
  510. package/lib/serialization/RegExpObjectSerializer.js +4 -2
  511. package/lib/serialization/Serializer.js +6 -0
  512. package/lib/serialization/SerializerMiddleware.js +14 -2
  513. package/lib/serialization/SetObjectSerializer.js +6 -8
  514. package/lib/serialization/SingleItemMiddleware.js +3 -0
  515. package/lib/sharing/ConsumeSharedFallbackDependency.js +1 -0
  516. package/lib/sharing/ConsumeSharedModule.js +21 -7
  517. package/lib/sharing/ConsumeSharedPlugin.js +11 -11
  518. package/lib/sharing/ConsumeSharedRuntimeModule.js +55 -45
  519. package/lib/sharing/ProvideForSharedDependency.js +1 -0
  520. package/lib/sharing/ProvideSharedDependency.js +34 -15
  521. package/lib/sharing/ProvideSharedModule.js +42 -12
  522. package/lib/sharing/ProvideSharedModuleFactory.js +1 -0
  523. package/lib/sharing/ProvideSharedPlugin.js +13 -8
  524. package/lib/sharing/SharePlugin.js +5 -1
  525. package/lib/sharing/ShareRuntimeModule.js +19 -16
  526. package/lib/sharing/resolveMatchedConfigs.js +6 -2
  527. package/lib/sharing/utils.js +9 -1
  528. package/lib/stats/DefaultStatsFactoryPlugin.js +289 -201
  529. package/lib/stats/DefaultStatsPresetPlugin.js +14 -2
  530. package/lib/stats/DefaultStatsPrinterPlugin.js +74 -170
  531. package/lib/stats/StatsFactory.js +70 -27
  532. package/lib/stats/StatsPrinter.js +16 -2
  533. package/lib/typescript/TypeScriptPlugin.js +210 -0
  534. package/lib/url/URLParserPlugin.js +111 -23
  535. package/lib/util/ArrayHelpers.js +1 -0
  536. package/lib/util/ArrayQueue.js +10 -5
  537. package/lib/util/AsyncQueue.js +154 -74
  538. package/lib/util/Hash.js +2 -2
  539. package/lib/util/IterableHelpers.js +3 -0
  540. package/lib/util/LazyBucketSortedSet.js +26 -0
  541. package/lib/util/LazySet.js +45 -4
  542. package/lib/util/LocConverter.js +64 -0
  543. package/lib/util/ParallelismFactorCalculator.js +1 -0
  544. package/lib/util/Queue.js +6 -3
  545. package/lib/util/Semaphore.js +15 -1
  546. package/lib/util/SetHelpers.js +4 -1
  547. package/lib/util/SortableSet.js +7 -1
  548. package/lib/util/SourceProcessor.js +119 -0
  549. package/lib/util/StackedCacheMap.js +20 -3
  550. package/lib/util/StackedMap.js +162 -43
  551. package/lib/util/StringXor.js +1 -1
  552. package/lib/util/TupleQueue.js +7 -3
  553. package/lib/util/TupleSet.js +14 -0
  554. package/lib/util/URLAbsoluteSpecifier.js +1 -0
  555. package/lib/util/WeakTupleMap.js +60 -1
  556. package/lib/util/binarySearchBounds.js +3 -2
  557. package/lib/util/chainedImports.js +3 -3
  558. package/lib/util/cleverMerge.js +19 -2
  559. package/lib/util/comparators.js +35 -4
  560. package/lib/util/compileBooleanMatcher.js +9 -0
  561. package/lib/util/concatenate.js +80 -24
  562. package/lib/util/conventions.js +46 -1
  563. package/lib/util/createHash.js +0 -1
  564. package/lib/util/createHooksRegistry.js +43 -0
  565. package/lib/util/createMappings.js +118 -0
  566. package/lib/util/dataURL.js +3 -2
  567. package/lib/util/deprecation.js +19 -0
  568. package/lib/util/deterministicGrouping.js +46 -17
  569. package/lib/util/extractSourceMap.js +2 -1
  570. package/lib/util/extractUrlAndGlobal.js +1 -0
  571. package/lib/util/findGraphRoots.js +7 -0
  572. package/lib/{formatLocation.js → util/formatLocation.js} +4 -2
  573. package/lib/{SizeFormatHelpers.js → util/formatSize.js} +10 -3
  574. package/lib/util/fs.js +87 -14
  575. package/lib/util/generateDebugId.js +1 -0
  576. package/lib/util/globUtils.js +710 -0
  577. package/lib/util/hash/BatchedHash.js +1 -0
  578. package/lib/util/hash/BulkUpdateHash.js +1 -0
  579. package/lib/util/hash/DebugHash.js +1 -0
  580. package/lib/util/hash/hash-digest.js +32 -15
  581. package/lib/util/hash/md4.js +1 -1
  582. package/lib/util/hash/wasm-hash.js +5 -0
  583. package/lib/util/hash/xxhash64.js +1 -1
  584. package/lib/util/identifier.js +118 -7
  585. package/lib/util/implicitTypeLoaderFallback.js +62 -0
  586. package/lib/util/internalSerializables.js +102 -60
  587. package/lib/util/magicComment.js +149 -7
  588. package/lib/util/makeSerializable.js +7 -0
  589. package/lib/util/memoize.js +2 -0
  590. package/lib/util/mimeTypes.js +176 -0
  591. package/lib/util/nonNumericOnlyHash.js +31 -1
  592. package/lib/util/numberHash.js +2 -2
  593. package/lib/util/parseJson.js +41 -0
  594. package/lib/util/processAsyncTree.js +8 -0
  595. package/lib/util/property.js +9 -2
  596. package/lib/util/publicPathPlaceholder.js +64 -0
  597. package/lib/util/registerExternalSerializer.js +24 -4
  598. package/lib/util/removeBOM.js +1 -0
  599. package/lib/util/runtime.js +32 -0
  600. package/lib/util/semver.js +15 -0
  601. package/lib/util/serialization.js +2 -0
  602. package/lib/util/smartGrouping.js +8 -0
  603. package/lib/util/source.js +23 -0
  604. package/lib/util/topologicalSort.js +69 -0
  605. package/lib/validateSchema.js +1 -0
  606. package/lib/wasm/EnableWasmLoadingPlugin.js +15 -1
  607. package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +25 -18
  608. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +34 -22
  609. package/lib/wasm-async/AsyncWasmModule.js +77 -0
  610. package/lib/wasm-async/AsyncWebAssemblyGenerator.js +6 -0
  611. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +6 -1
  612. package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +22 -126
  613. package/lib/wasm-async/AsyncWebAssemblyParser.js +3 -2
  614. package/lib/wasm-async/UniversalCompileAsyncWasmPlugin.js +13 -2
  615. package/lib/wasm-sync/SyncWasmModule.js +39 -0
  616. package/lib/wasm-sync/UnsupportedWebAssemblyFeatureError.js +7 -3
  617. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +86 -19
  618. package/lib/wasm-sync/WasmFinalizeExportsPlugin.js +4 -3
  619. package/lib/wasm-sync/WebAssemblyGenerator.js +27 -1
  620. package/lib/wasm-sync/WebAssemblyInInitialChunkError.js +9 -3
  621. package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +4 -0
  622. package/lib/wasm-sync/WebAssemblyModulesPlugin.js +20 -1
  623. package/lib/wasm-sync/WebAssemblyParser.js +9 -3
  624. package/lib/wasm-sync/WebAssemblyUtils.js +2 -0
  625. package/lib/web/FetchCompileAsyncWasmPlugin.js +29 -1
  626. package/lib/web/FetchCompileWasmPlugin.js +27 -1
  627. package/lib/web/JsonpChunkLoadingPlugin.js +11 -1
  628. package/lib/web/JsonpChunkLoadingRuntimeModule.js +58 -64
  629. package/lib/web/JsonpTemplatePlugin.js +2 -1
  630. package/lib/webpack.js +78 -1
  631. package/lib/webworker/ImportScriptsChunkLoadingPlugin.js +10 -1
  632. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +15 -10
  633. package/lib/webworker/WebWorkerTemplatePlugin.js +1 -1
  634. package/module.d.ts +21 -0
  635. package/package.json +79 -77
  636. package/schemas/WebpackOptions.check.js +1 -1
  637. package/schemas/WebpackOptions.json +1173 -80
  638. package/schemas/plugins/{DllPlugin.check.d.ts → HtmlGeneratorOptions.check.d.ts} +1 -1
  639. package/schemas/plugins/HtmlGeneratorOptions.check.js +6 -0
  640. package/schemas/plugins/HtmlGeneratorOptions.json +3 -0
  641. package/schemas/plugins/{DllReferencePlugin.check.d.ts → HtmlParserOptions.check.d.ts} +1 -1
  642. package/schemas/plugins/HtmlParserOptions.check.js +6 -0
  643. package/schemas/plugins/HtmlParserOptions.json +3 -0
  644. package/schemas/plugins/ProgressPlugin.check.js +1 -1
  645. package/schemas/plugins/ProgressPlugin.json +38 -0
  646. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  647. package/schemas/plugins/container/ContainerReferencePlugin.json +2 -0
  648. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  649. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  650. package/schemas/plugins/container/ModuleFederationPlugin.json +2 -0
  651. package/schemas/plugins/css/CssAutoOrModuleParserOptions.check.d.ts +7 -0
  652. package/schemas/plugins/css/CssAutoOrModuleParserOptions.check.js +6 -0
  653. package/schemas/plugins/css/CssAutoOrModuleParserOptions.json +3 -0
  654. package/schemas/plugins/css/CssModuleParserOptions.check.js +1 -1
  655. package/schemas/plugins/css/CssParserOptions.check.js +1 -1
  656. package/schemas/plugins/dll/DllPlugin.check.d.ts +7 -0
  657. package/schemas/plugins/dll/DllReferencePlugin.check.d.ts +7 -0
  658. package/types.d.ts +11053 -3019
  659. package/lib/CaseSensitiveModulesWarning.js +0 -72
  660. package/lib/GraphHelpers.js +0 -46
  661. package/lib/ModuleParseError.js +0 -125
  662. package/lib/NoModeWarning.js +0 -23
  663. package/lib/css/CssMergeStyleSheetsRuntimeModule.js +0 -56
  664. package/lib/css/walkCssTokens.js +0 -1843
  665. package/lib/util/AppendOnlyStackedSet.js +0 -78
  666. /package/schemas/plugins/{DllPlugin.check.js → dll/DllPlugin.check.js} +0 -0
  667. /package/schemas/plugins/{DllPlugin.json → dll/DllPlugin.json} +0 -0
  668. /package/schemas/plugins/{DllReferencePlugin.check.js → dll/DllReferencePlugin.check.js} +0 -0
  669. /package/schemas/plugins/{DllReferencePlugin.json → dll/DllReferencePlugin.json} +0 -0
@@ -0,0 +1,1129 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ */
4
+
5
+ "use strict";
6
+
7
+ const { pathToFileURL } = require("url");
8
+ const { AsyncSeriesHook, AsyncSeriesWaterfallHook } = require("tapable");
9
+ const { RawSource } = require("webpack-sources");
10
+ const Compilation = require("../Compilation");
11
+ const EntryOptionPlugin = require("../EntryOptionPlugin");
12
+ const EntryPlugin = require("../EntryPlugin");
13
+ const HotUpdateChunk = require("../HotUpdateChunk");
14
+ const { HTML_TYPE } = require("../ModuleSourceTypeConstants");
15
+ const { HTML_MODULE_TYPE } = require("../ModuleTypeConstants");
16
+ const NormalModule = require("../NormalModule");
17
+ const ConstDependency = require("../dependencies/ConstDependency");
18
+ const HtmlEntryDependency = require("../dependencies/HtmlEntryDependency");
19
+ const HtmlInlineHtmlDependency = require("../dependencies/HtmlInlineHtmlDependency");
20
+ const HtmlInlineScriptDependency = require("../dependencies/HtmlInlineScriptDependency");
21
+ const HtmlInlineStyleDependency = require("../dependencies/HtmlInlineStyleDependency");
22
+ const HtmlSourceDependency = require("../dependencies/HtmlSourceDependency");
23
+ const StaticExportsDependency = require("../dependencies/StaticExportsDependency");
24
+ const WebpackError = require("../errors/WebpackError");
25
+ const JavascriptModulesPlugin = require("../javascript/JavascriptModulesPlugin");
26
+ const { compareModulesByFullName } = require("../util/comparators");
27
+ const createHash = require("../util/createHash");
28
+ const createHooksRegistry = require("../util/createHooksRegistry");
29
+ const { getUndoPath, makePathsRelative } = require("../util/identifier");
30
+ const implicitTypeLoaderFallback = require("../util/implicitTypeLoaderFallback");
31
+ const memoize = require("../util/memoize");
32
+ const { digestNonNumericOnly } = require("../util/nonNumericOnlyHash");
33
+ const {
34
+ PUBLIC_PATH_AUTO: autoPlaceholder
35
+ } = require("../util/publicPathPlaceholder");
36
+ const removeBOM = require("../util/removeBOM");
37
+ const HtmlGenerator = require("./HtmlGenerator");
38
+ const HtmlModule = require("./HtmlModule");
39
+ const HtmlParser = require("./HtmlParser");
40
+ const { escapeAttribute } = require("./syntax");
41
+
42
+ /** @typedef {import("../../declarations/WebpackOptions").EntryDescriptionNormalized} EntryDescriptionNormalized */
43
+ /** @typedef {import("../../declarations/WebpackOptions").OutputHtmlOptions["favicon"]} FaviconOption */
44
+ /** @typedef {import("../../declarations/WebpackOptions").OutputHtmlOptions["manifest"]} ManifestOption */
45
+ /** @typedef {import("../../declarations/WebpackOptions").HtmlFaviconIcon} HtmlFaviconIcon */
46
+ /** @typedef {Exclude<HtmlFaviconIcon, string>} FaviconIcon */
47
+ /** @typedef {import("../Compiler")} Compiler */
48
+ /** @typedef {import("./HtmlModule").HtmlModuleBuildInfo} HtmlModuleBuildInfo */
49
+ /** @typedef {{ request: string, entryName: string, type: "script" | "script-module" | "modulepreload" | "stylesheet" | "html" | "preload" | "prefetch", css?: boolean }} HtmlEntryInfo */
50
+
51
+ /** @typedef {{ outputName: string }} HtmlTransformHtmlContext */
52
+ /** @typedef {{ outputName: string }} HtmlEmittedContext */
53
+ /**
54
+ * A tag to inject into an emitted page as a structured descriptor. Injected
55
+ * verbatim (not re-bundled) at the `injectTo` position.
56
+ * @typedef {object} HtmlTagDescriptor
57
+ * @property {string} tag tag name, e.g. `"script"` / `"link"` / `"meta"`
58
+ * @property {Record<string, string | boolean | undefined>=} attrs attributes; `true` renders a bare boolean attribute, `false`/`undefined` is omitted
59
+ * @property {string=} children inner content (ignored for void elements like `<link>`/`<meta>`)
60
+ * @property {("head" | "body" | "head-prepend" | "body-prepend")=} injectTo placement; defaults to `"head"`
61
+ * @property {boolean=} voidTag force a void element (no closing tag); inferred from the tag name when omitted
62
+ */
63
+ /** @typedef {{ outputName: string, html: string }} HtmlInjectTagsContext */
64
+ /**
65
+ * A `<script>`/`<link>`/`<style>`/`<meta>` tag already present in an emitted
66
+ * page, exposed for in-place mutation by `transformTags`. Mutate `attrs`, set
67
+ * `remove`, or change `injectTo` to move it; don't reorder the array itself.
68
+ * @typedef {object} HtmlMutableTag
69
+ * @property {string} tag the (lowercased) tag name
70
+ * @property {Record<string, string | boolean | undefined>} attrs mutable attributes; a string value renders `name="value"`, `true` a bare attribute, `false`/`undefined`/deleting the key drops it
71
+ * @property {("head" | "body" | "head-prepend" | "body-prepend")=} injectTo the tag's current region (`"head"`/`"body"`); set a different value to move it there (`*-prepend` to the region's start)
72
+ * @property {boolean=} remove set true to delete the whole element
73
+ */
74
+ /** @typedef {{ outputName: string, html: string }} HtmlTransformTagsContext */
75
+
76
+ const createCompilationHooks = () => ({
77
+ /**
78
+ * Called with the list of extra tags to inject into each page (initially empty) plus the current HTML; push `HtmlTagDescriptor`s and return the list — webpack serializes and places them by `injectTo`. A structured alternative to the string-level `transformHtml` for adding tags; runs before CSP so injected inline tags are hashed.
79
+ * @type {AsyncSeriesWaterfallHook<[HtmlTagDescriptor[], HtmlInjectTagsContext]>}
80
+ * @since 5.109.0
81
+ */
82
+ injectTags: new AsyncSeriesWaterfallHook(["tags", "context"]),
83
+ /**
84
+ * Called with the page's `<script>`/`<link>`/`<style>`/`<meta>` tags (webpack's own and any injected) as mutable descriptors; mutate `attrs` (add a `nonce`/`data-*`, switch `defer`↔`async`, …), set `remove: true`, or change `injectTo` to move a tag between `<head>` and `<body>`, and webpack rewrites the changed tags. Add new tags with `injectTags` instead.
85
+ * @type {AsyncSeriesHook<[HtmlMutableTag[], HtmlTransformTagsContext]>}
86
+ * @since 5.109.0
87
+ */
88
+ transformTags: new AsyncSeriesHook(["tags", "context"]),
89
+ /**
90
+ * Called with each emitted page's final HTML (all sentinels resolved) just before it is written; return the (possibly transformed) HTML — e.g. to minify, inject a CSP meta, or rewrite tags.
91
+ * @type {AsyncSeriesWaterfallHook<[string, HtmlTransformHtmlContext]>}
92
+ * @since 5.109.0
93
+ */
94
+ transformHtml: new AsyncSeriesWaterfallHook(["html", "context"]),
95
+ /**
96
+ * Called once each page's HTML asset has been finalized — a post-emit notification (nothing to return).
97
+ * @type {AsyncSeriesHook<[HtmlEmittedContext]>}
98
+ * @since 5.109.0
99
+ */
100
+ htmlEmitted: new AsyncSeriesHook(["context"])
101
+ });
102
+
103
+ /**
104
+ * @typedef {ReturnType<typeof createCompilationHooks>} HtmlCompilationHooks
105
+ */
106
+
107
+ const PLUGIN_NAME = "HtmlModulesPlugin";
108
+
109
+ // Built-in default favicon (the webpack logo). Referenced as a `file:` request
110
+ // so `<link rel="icon">` in the synthetic wrapper flows through the normal
111
+ // asset pipeline — emitted hashed, with the correct publicPath, no direct IO.
112
+ // Resolved from `__filename` (a sibling of this module) — no `path` needed.
113
+ const DEFAULT_FAVICON = new URL("./favicon.svg", pathToFileURL(__filename))
114
+ .href;
115
+
116
+ // mime-db is heavy — only load it when a favicon actually needs a `type`.
117
+ const getMimeTypes = memoize(() => require("../util/mimeTypes"));
118
+
119
+ /**
120
+ * Resolves `output.html.favicon` for one page to `[rel, icon]` pairs.
121
+ * `false`/absent → none; `true` → the webpack logo; a string → one `icon`
122
+ * link; an object maps each `rel` to an icon (a path string, an attributes
123
+ * object, or an array of those for several icons under one `rel`); a function
124
+ * receives the page name and returns any of those. Each icon is normalized to
125
+ * an object so `faviconLinkTag` reads one shape.
126
+ * @param {FaviconOption} favicon favicon option
127
+ * @param {string} name page/entry name
128
+ * @returns {[string, FaviconIcon][]} rel/icon pairs, in order
129
+ */
130
+ const resolveFaviconLinks = (favicon, name) => {
131
+ const value = typeof favicon === "function" ? favicon(name) : favicon;
132
+ if (value === true) return [["icon", { href: DEFAULT_FAVICON }]];
133
+ if (typeof value === "string") return [["icon", { href: value }]];
134
+ if (value && typeof value === "object") {
135
+ /** @type {[string, FaviconIcon][]} */
136
+ const pairs = [];
137
+ for (const [rel, icon] of Object.entries(value)) {
138
+ for (const one of Array.isArray(icon) ? icon : [icon]) {
139
+ pairs.push([rel, typeof one === "string" ? { href: one } : one]);
140
+ }
141
+ }
142
+ return pairs;
143
+ }
144
+ return [];
145
+ };
146
+
147
+ /**
148
+ * @param {string} rel link relation
149
+ * @param {FaviconIcon} icon icon `href` plus optional link attributes
150
+ * @returns {string} a `<link rel=… [attrs…] href=…>` tag; `type` defaults to the file format
151
+ */
152
+ const faviconLinkTag = (rel, icon) => {
153
+ const type = icon.type || getMimeTypes().lookup(icon.href) || "";
154
+ const attrs = [
155
+ `rel="${escapeAttribute(rel)}"`,
156
+ icon.sizes && `sizes="${escapeAttribute(icon.sizes)}"`,
157
+ type && `type="${escapeAttribute(type)}"`,
158
+ icon.media && `media="${escapeAttribute(icon.media)}"`,
159
+ icon.color && `color="${escapeAttribute(icon.color)}"`,
160
+ icon.crossorigin && `crossorigin="${escapeAttribute(icon.crossorigin)}"`,
161
+ `href="${escapeAttribute(icon.href)}"`
162
+ ];
163
+ return `<link ${attrs.filter(Boolean).join(" ")}>`;
164
+ };
165
+
166
+ /**
167
+ * Resolves `output.html.manifest` for one page to a `<link rel="manifest">`
168
+ * tag, or `""` when unset. A string is a path to an existing `.webmanifest`
169
+ * file; an object is serialized to a base64 `data:application/manifest+json`
170
+ * URL (routed to `asset/webmanifest` by a default rule, so its relative icon
171
+ * `src`s are hashed like any request); a function receives the page name.
172
+ * Base64 (not percent-encoding) is required because this tag is embedded in
173
+ * the outer `data:text/html` wrapper, which is itself percent-decoded — a
174
+ * percent-encoded inner URL would be corrupted by that decode.
175
+ * @param {ManifestOption} manifest manifest option
176
+ * @param {string} name page/entry name
177
+ * @returns {string} the `<link>` tag, or ""
178
+ */
179
+ const manifestLinkTag = (manifest, name) => {
180
+ const value = typeof manifest === "function" ? manifest(name) : manifest;
181
+ if (!value) return "";
182
+ const href =
183
+ typeof value === "string"
184
+ ? value
185
+ : `data:application/manifest+json;base64,${Buffer.from(
186
+ JSON.stringify(value),
187
+ "utf8"
188
+ ).toString("base64")}`;
189
+ return `<link rel="manifest" href="${escapeAttribute(href)}">`;
190
+ };
191
+
192
+ // `\.html`/`\.css` request matchers for the synthetic `output.html` wrapper.
193
+ const HTML_REQUEST_RE = /\.html(\?|$)/i;
194
+ const CSS_REQUEST_RE = /\.css(\?|$)/i;
195
+
196
+ /**
197
+ * Requests an `output.html` page must load for an entry: its `dependOn`
198
+ * ancestors first (transitive, deduped — so a diamond loads each once), then
199
+ * the entry's own imports. `.html` imports are dropped (own HTML entries).
200
+ * @param {string} name entry name
201
+ * @param {Record<string, EntryDescriptionNormalized>} entries normalized static entries
202
+ * @returns {string[]} deduped requests in load order
203
+ */
204
+ const collectHtmlEntryRequests = (name, entries) => {
205
+ /** @type {string[]} */
206
+ const requests = [];
207
+ /** @type {Set<string>} */
208
+ const seenRequests = new Set();
209
+ /** @type {Set<string>} */
210
+ const visited = new Set();
211
+ const walk = (/** @type {string} */ entryName) => {
212
+ if (visited.has(entryName)) return;
213
+ visited.add(entryName);
214
+ const desc = entries[entryName];
215
+ if (!desc) return;
216
+ if (desc.dependOn) {
217
+ for (const dep of desc.dependOn) walk(dep);
218
+ }
219
+ if (!desc.import) return;
220
+ for (const request of desc.import) {
221
+ if (HTML_REQUEST_RE.test(request) || seenRequests.has(request)) continue;
222
+ seenRequests.add(request);
223
+ requests.push(request);
224
+ }
225
+ };
226
+ walk(name);
227
+ return requests;
228
+ };
229
+
230
+ /**
231
+ * @param {string} name definition name in `schemas/WebpackOptions.json`
232
+ * @returns {EXPECTED_OBJECT} a schema referencing `#/definitions/<name>`
233
+ */
234
+ const getSchema = (name) => {
235
+ const { definitions } = require("../../schemas/WebpackOptions.json");
236
+
237
+ return {
238
+ definitions,
239
+ oneOf: [{ $ref: `#/definitions/${name}` }]
240
+ };
241
+ };
242
+
243
+ const generatorValidationOptions = {
244
+ name: "Html Modules Plugin",
245
+ baseDataPath: "generator"
246
+ };
247
+
248
+ const parserValidationOptions = {
249
+ name: "Html Modules Plugin",
250
+ baseDataPath: "parser"
251
+ };
252
+
253
+ class HtmlModulesPlugin {
254
+ /**
255
+ * `output.hashFunction`/`hashSalt`/`hashDigest`/`hashDigestLength`
256
+ * digest of `content`, with `nonNumericOnlyHash` applied — webpack's
257
+ * standard `[contenthash]` recipe.
258
+ * @param {string | Buffer} content content to hash
259
+ * @param {import("../../declarations/WebpackOptions").Output} outputOptions output options
260
+ * @returns {string} content hash
261
+ */
262
+ static computeContentHash(content, outputOptions) {
263
+ const hash = createHash(
264
+ /** @type {import("../../declarations/WebpackOptions").HashFunction} */
265
+ (outputOptions.hashFunction)
266
+ );
267
+ if (outputOptions.hashSalt) hash.update(outputOptions.hashSalt);
268
+ hash.update(content);
269
+ return digestNonNumericOnly(
270
+ hash,
271
+ /** @type {string} */ (outputOptions.hashDigest),
272
+ /** @type {number} */ (outputOptions.hashDigestLength)
273
+ );
274
+ }
275
+
276
+ /**
277
+ * Filename template for an extracted HTML page: `output.htmlFilename` for
278
+ * initial chunks, `output.htmlChunkFilename` otherwise — the HTML counterpart
279
+ * of `CssModulesPlugin.getChunkFilenameTemplate`.
280
+ * @param {import("../Chunk")} chunk chunk
281
+ * @param {import("../../declarations/WebpackOptions").Output} outputOptions output options
282
+ * @returns {import("../Chunk").ChunkFilenameTemplate} used filename template
283
+ */
284
+ static getChunkFilenameTemplate(chunk, outputOptions) {
285
+ return chunk.canBeInitial()
286
+ ? /** @type {import("../Chunk").ChunkFilenameTemplate} */ (
287
+ outputOptions.htmlFilename
288
+ )
289
+ : /** @type {import("../Chunk").ChunkFilenameTemplate} */ (
290
+ outputOptions.htmlChunkFilename
291
+ );
292
+ }
293
+
294
+ /**
295
+ * Applies the plugin by registering its hooks on the compiler.
296
+ * @param {Compiler} compiler the compiler instance
297
+ * @returns {void}
298
+ */
299
+ apply(compiler) {
300
+ const { output } = compiler.options;
301
+ const htmlOption = output.html;
302
+ const scriptLoading =
303
+ (typeof htmlOption === "object" && htmlOption.scriptLoading) || "auto";
304
+ // ESM output emits `type="module"` (already deferred), so scriptLoading
305
+ // is ignored under output.module — warn on an explicit defer/blocking.
306
+ let scriptAttr = " defer";
307
+ if (output.module) {
308
+ scriptAttr = "";
309
+ if (scriptLoading === "defer" || scriptLoading === "blocking") {
310
+ compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
311
+ compilation.warnings.push(
312
+ new WebpackError(
313
+ `output.html.scriptLoading: "${scriptLoading}" is ignored with output.module — ES module scripts are always deferred.`
314
+ )
315
+ );
316
+ });
317
+ }
318
+ } else if (scriptLoading === "blocking") {
319
+ scriptAttr = "";
320
+ }
321
+
322
+ // `output.html` (or an entry's `html`) wraps a non-HTML entry in a
323
+ // synthetic HTML module so the existing pipeline injects its JS/CSS
324
+ // chunks and applies the `template` option. `dependOn` ancestors are
325
+ // injected first so the page loads the shared/runtime chunks before
326
+ // the entry's own (see `collectHtmlEntryRequests`). `crossOriginLoading`
327
+ // and SRI are applied to the injected tags centrally in
328
+ // HtmlEntryDependency.
329
+ EntryOptionPlugin.getHooks(compiler).entry.tap(
330
+ PLUGIN_NAME,
331
+ (context, name, desc) => {
332
+ const html = desc.html !== undefined ? desc.html : htmlOption;
333
+ const imports = desc.import;
334
+ if (
335
+ !html ||
336
+ !imports ||
337
+ imports.every((r) => HTML_REQUEST_RE.test(r))
338
+ ) {
339
+ return;
340
+ }
341
+ const entries = compiler.options.entry;
342
+ const requests =
343
+ typeof entries === "object" && entries[name]
344
+ ? collectHtmlEntryRequests(name, entries)
345
+ : imports.filter((r) => !HTML_REQUEST_RE.test(r));
346
+ const links = [];
347
+ const scripts = [];
348
+ for (const r of requests) {
349
+ if (CSS_REQUEST_RE.test(r)) {
350
+ links.push(`<link rel="stylesheet" href="${r}">`);
351
+ } else {
352
+ scripts.push(`<script${scriptAttr} src="${r}"></script>`);
353
+ }
354
+ }
355
+ const htmlObj =
356
+ typeof html === "object"
357
+ ? html
358
+ : typeof htmlOption === "object"
359
+ ? htmlOption
360
+ : {};
361
+ const headTags = HtmlParser.buildHeadTags(htmlObj);
362
+ // Injected into webpack-generated pages only; each icon's href is a
363
+ // normal request the parser turns into a hashed asset.
364
+ const favicon =
365
+ typeof html === "object" && html.favicon !== undefined
366
+ ? html.favicon
367
+ : false;
368
+ const faviconTag = resolveFaviconLinks(favicon, name)
369
+ .map(([rel, icon]) => faviconLinkTag(rel, icon))
370
+ .join("");
371
+ const manifest =
372
+ typeof html === "object" && html.manifest !== undefined
373
+ ? html.manifest
374
+ : false;
375
+ const manifestTag = manifestLinkTag(manifest, name);
376
+ const inject = htmlObj.inject;
377
+ const scriptsInHead =
378
+ inject === "head" || (inject !== "body" && output.module);
379
+ const scriptsFirst = output.module || scriptAttr === " defer";
380
+ const headScripts = scriptsInHead ? scripts.join("") : "";
381
+ return `data:text/html,<!doctype html><html><head>${faviconTag}${manifestTag}${headTags}${
382
+ scriptsFirst
383
+ ? headScripts + links.join("")
384
+ : links.join("") + headScripts
385
+ }</head><body>${scriptsInHead ? "" : scripts.join("")}</body></html>`;
386
+ }
387
+ );
388
+
389
+ // Per-chunk `RawSource` reused across builds when bytes are unchanged:
390
+ // keeping identity stable avoids invalidating `RealContentHashPlugin|analyse`.
391
+ /** @type {Map<string, { content: string, source: import("webpack-sources").RawSource }>} */
392
+ const sentinelResolvedSourceCache = new Map();
393
+
394
+ // `<script src>` and `<link rel="modulepreload">` references collected
395
+ // by HtmlParser become real compilation entries here. The `script`
396
+ // and `script-module` groups are chained via a leader-only dependOn so
397
+ // they share a runtime — the first entry of the group owns it and
398
+ // every subsequent entry sets `dependOn: [leader]`. Modulepreload
399
+ // entries are emitted as independent entries (no dependOn) so they
400
+ // can never be imported as a runtime leader by a later script —
401
+ // that's what keeps the "preload but don't execute" contract of
402
+ // `<link rel="modulepreload">` intact.
403
+ // Per-compilation state: the HTML modules seen during make (so
404
+ // `finishMake` creates their entries without scanning the whole module
405
+ // graph) and the stylesheet entry names (read in `afterChunks`).
406
+ /** @type {WeakMap<import("../Compilation"), { htmlModules: Set<import("../Module")>, stylesheetEntries: Set<string>, htmlAssetNames: Set<string> }>} */
407
+ const compilationState = new WeakMap();
408
+ /**
409
+ * @param {import("../Compilation")} compilation compilation
410
+ * @returns {{ htmlModules: Set<import("../Module")>, stylesheetEntries: Set<string>, htmlAssetNames: Set<string> }} per-compilation state
411
+ */
412
+ const getState = (compilation) => {
413
+ let state = compilationState.get(compilation);
414
+ if (state === undefined) {
415
+ state = {
416
+ htmlModules: new Set(),
417
+ stylesheetEntries: new Set(),
418
+ htmlAssetNames: new Set()
419
+ };
420
+ compilationState.set(compilation, state);
421
+ }
422
+ return state;
423
+ };
424
+ compiler.hooks.finishMake.tapAsync(PLUGIN_NAME, (compilation, callback) => {
425
+ const { htmlModules, stylesheetEntries } = getState(compilation);
426
+
427
+ // Collect the entries an HTML module asks for. Only the script chains
428
+ // (`script`, `script-module`) share a runtime via a leader-only
429
+ // `dependOn`; `modulepreload`, `stylesheet` and `html` links are all
430
+ // independent entries (a CSS or page entry must not chain into a JS
431
+ // leader, or the chunk would mix unrelated outputs).
432
+ /** @type {(module: import("../Module")) => { context: string, request: string, name: string, dependOn: string[] | undefined }[]} */
433
+ const collectEntrySpecs = (module) => {
434
+ const { htmlEntries } = /** @type {HtmlModuleBuildInfo} */ (
435
+ module.buildInfo
436
+ );
437
+ if (!htmlEntries) return [];
438
+ const context = /** @type {string} */ (module.context);
439
+ const specs = [];
440
+ for (const [groupKind, group] of Object.entries(htmlEntries)) {
441
+ const isChainGroup =
442
+ groupKind === "script" || groupKind === "script-module";
443
+ /** @type {string | undefined} */
444
+ let leaderName;
445
+ for (const entry of group) {
446
+ const dependOn =
447
+ isChainGroup && leaderName !== undefined
448
+ ? [leaderName]
449
+ : undefined;
450
+ if (isChainGroup && leaderName === undefined) {
451
+ leaderName = entry.entryName;
452
+ }
453
+ // Stylesheet entries and `as="style"` preload/prefetch entries emit
454
+ // a CSS chunk, so they need the CSS filename template below.
455
+ if (groupKind === "stylesheet" || entry.css) {
456
+ stylesheetEntries.add(entry.entryName);
457
+ }
458
+ specs.push({
459
+ context,
460
+ request: entry.request,
461
+ name: entry.entryName,
462
+ dependOn
463
+ });
464
+ }
465
+ }
466
+ return specs;
467
+ };
468
+
469
+ // Push one collected reference as a compilation entry; resolves with
470
+ // the built entry module.
471
+ /** @type {(spec: { context: string, request: string, name: string, dependOn: string[] | undefined }) => Promise<import("../Module") | null>} */
472
+ const addEntry = (spec) =>
473
+ new Promise((resolve, reject) => {
474
+ compilation.addEntry(
475
+ spec.context,
476
+ EntryPlugin.createDependency(spec.request, { name: spec.name }),
477
+ {
478
+ name: spec.name,
479
+ // Each entry gets its own filename from the synthetic entry name so
480
+ // it doesn't collide with `output.filename`. CSS entries set their
481
+ // `.css` name via `cssFilenameTemplate` below; `html` page entries
482
+ // emit their file via `renderManifest`.
483
+ filename: compilation.outputOptions.chunkFilename || "[name].js",
484
+ dependOn: spec.dependOn
485
+ },
486
+ (err, entryModule) =>
487
+ err ? reject(err) : resolve(entryModule || null)
488
+ );
489
+ });
490
+
491
+ // Create one HTML module's entries. A `type: "html"` link is itself an
492
+ // HTML entry, so after it builds we recurse into it — the same handling
493
+ // every HTML entry already gets. `processed` guards diamonds and cycles.
494
+ /** @type {WeakSet<import("../Module")>} */
495
+ const processed = new WeakSet();
496
+ /** @type {(module: import("../Module")) => Promise<void>} */
497
+ const processEntry = async (module) => {
498
+ if (processed.has(module)) return;
499
+ processed.add(module);
500
+ await Promise.all(
501
+ collectEntrySpecs(module).map(async (spec) => {
502
+ const entryModule = await addEntry(spec);
503
+ if (entryModule && entryModule.type === HTML_MODULE_TYPE) {
504
+ await processEntry(entryModule);
505
+ }
506
+ })
507
+ );
508
+ };
509
+ // Seed with the HTML modules seen during make (config entries /
510
+ // imports, fresh or cache-restored); linked pages are reached by
511
+ // recursion above.
512
+ Promise.all([...htmlModules].map(processEntry)).then(
513
+ () => callback(),
514
+ callback
515
+ );
516
+ });
517
+
518
+ const integrity =
519
+ typeof htmlOption === "object" ? htmlOption.integrity : undefined;
520
+ const integrityOn =
521
+ integrity === true ||
522
+ typeof integrity === "function" ||
523
+ (Array.isArray(integrity) && integrity.length > 0);
524
+ // `output.html.csp` injects a `<meta http-equiv="Content-Security-Policy">`
525
+ // once the page's inline content is final (in `processAssets` below).
526
+ const csp = typeof htmlOption === "object" ? htmlOption.csp : undefined;
527
+ // `"auto"` marks implicit enablement (no user rule for HTML files) — see
528
+ // `applyExperimentsDefaults`. Only then loaders win over the built-in type
529
+ // (e.g. html-webpack-plugin's template loader in its child compiler).
530
+ // TODO webpack 6: html defaults to `true`, drop this implicit-only fallback.
531
+ const implicitlyEnabled = compiler.options.experiments.html === "auto";
532
+ compiler.hooks.compilation.tap(
533
+ PLUGIN_NAME,
534
+ (compilation, { normalModuleFactory }) => {
535
+ if (implicitlyEnabled) {
536
+ implicitTypeLoaderFallback(
537
+ normalModuleFactory,
538
+ PLUGIN_NAME,
539
+ /\.html$/i,
540
+ HTML_MODULE_TYPE
541
+ );
542
+ }
543
+ const { htmlModules } = getState(compilation);
544
+ // Record HTML modules as they appear — freshly built
545
+ // (`succeedModule`) or restored from cache (`stillValidModule`) —
546
+ // so `finishMake` creates their entries without scanning every
547
+ // module in the graph. Tracking only records; entries are still
548
+ // added (and awaited) in `finishMake`.
549
+ const trackHtmlModule = (/** @type {import("../Module")} */ module) => {
550
+ if (module.type === HTML_MODULE_TYPE) htmlModules.add(module);
551
+ };
552
+ compilation.hooks.succeedModule.tap(PLUGIN_NAME, trackHtmlModule);
553
+ compilation.hooks.stillValidModule.tap(PLUGIN_NAME, trackHtmlModule);
554
+
555
+ // Resolve integrity and inline sentinels after `RealContentHashPlugin`
556
+ // so final bytes are in place. Only HTML pages carry these sentinels —
557
+ // never JS chunks that embed an HTML string.
558
+ // SRI only takes effect on a cross-origin subresource fetched
559
+ // with CORS; without `output.crossOriginLoading` the browser
560
+ // silently ignores `integrity` on cross-origin loads. Warn once
561
+ // so a CDN deployment doesn't ship no-op integrity attributes.
562
+ if (integrityOn && !compilation.outputOptions.crossOriginLoading) {
563
+ compilation.warnings.push(
564
+ new WebpackError(
565
+ 'output.html.integrity is set but output.crossOriginLoading is not. Browsers ignore Subresource Integrity on cross-origin requests made without CORS; set output.crossOriginLoading (e.g. "anonymous") if any asset is served from a different origin.'
566
+ )
567
+ );
568
+ }
569
+ compilation.hooks.processAssets.tapPromise(
570
+ {
571
+ name: PLUGIN_NAME,
572
+ stage: Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_HASH + 1
573
+ },
574
+ async (assets) => {
575
+ const { htmlAssetNames } = getState(compilation);
576
+ const hooks = HtmlModulesPlugin.getCompilationHooks(compilation);
577
+ /** @type {Set<string>} */
578
+ const inlinedFiles = new Set();
579
+ for (const name of Object.keys(assets)) {
580
+ if (!htmlAssetNames.has(name)) continue;
581
+ const content = assets[name].source();
582
+ if (typeof content !== "string") continue;
583
+ let resolved = content;
584
+ if (
585
+ integrityOn &&
586
+ resolved.includes("__WEBPACK_HTML_INTEGRITY__")
587
+ ) {
588
+ resolved = HtmlGenerator.resolveChunkIntegritySentinels(
589
+ resolved,
590
+ compilation,
591
+ /** @type {import("./HtmlGenerator").HtmlIntegrity} */ (
592
+ integrity
593
+ )
594
+ );
595
+ }
596
+ if (resolved.includes("__WEBPACK_HTML_INLINE__")) {
597
+ resolved = HtmlGenerator.resolveChunkInlineSentinels(
598
+ resolved,
599
+ compilation,
600
+ name,
601
+ inlinedFiles
602
+ );
603
+ }
604
+ // `injectTags` (add tags), `transformTags` (mutate/move/remove the
605
+ // page's own and injected tags), and CSP all run over a single
606
+ // parse: collect the tags/anchors once, let the hooks act, then
607
+ // render every edit — placement, attribute rewrites, moves,
608
+ // removals, CSP hashes/nonce/meta — in one pass. Injected inline
609
+ // `<script>`/`<style>` are hashed like the page's own.
610
+ const injected = await hooks.injectTags.promise([], {
611
+ outputName: name,
612
+ html: resolved
613
+ });
614
+ const transformTags = hooks.transformTags.taps.length > 0;
615
+ if (injected.length > 0 || transformTags || csp) {
616
+ const model = HtmlGenerator.collectHtml(resolved);
617
+ HtmlGenerator.addInjectedTags(model, injected);
618
+ if (transformTags) {
619
+ await hooks.transformTags.promise(model.tags, {
620
+ outputName: name,
621
+ html: resolved
622
+ });
623
+ }
624
+ resolved = HtmlGenerator.renderHtml(resolved, model, csp);
625
+ }
626
+ // Final, fully-resolved HTML — let plugins transform it (minify,
627
+ // inject a CSP meta, rewrite tags) before it is written.
628
+ resolved = await hooks.transformHtml.promise(resolved, {
629
+ outputName: name
630
+ });
631
+ if (resolved !== content) {
632
+ compilation.updateAsset(name, new RawSource(resolved));
633
+ }
634
+ await hooks.htmlEmitted.promise({ outputName: name });
635
+ }
636
+ // An inlined chunk file is dead weight once nothing else references
637
+ // it by URL (another page's tag, or the runtime's async chunk map);
638
+ // a content-hashed filename makes a substring hit a real reference.
639
+ // Materialize each other asset's source once (it can be expensive to
640
+ // render) and test all inlined files against it, rather than
641
+ // re-materializing every asset per inlined file.
642
+ if (inlinedFiles.size > 0) {
643
+ /** @type {Set<string>} */
644
+ const stillReferenced = new Set();
645
+ for (const name of Object.keys(compilation.assets)) {
646
+ if (
647
+ inlinedFiles.has(name) ||
648
+ stillReferenced.size === inlinedFiles.size
649
+ ) {
650
+ continue;
651
+ }
652
+ const source = compilation.assets[name].source();
653
+ if (typeof source !== "string") continue;
654
+ for (const file of inlinedFiles) {
655
+ if (!stillReferenced.has(file) && source.includes(file)) {
656
+ stillReferenced.add(file);
657
+ }
658
+ }
659
+ }
660
+ for (const file of inlinedFiles) {
661
+ if (!stillReferenced.has(file)) compilation.deleteAsset(file);
662
+ }
663
+ }
664
+ }
665
+ );
666
+
667
+ // CSS entries created by `<link rel="stylesheet">` in HTML need
668
+ // their `.css` filename set via `chunk.cssFilenameTemplate`
669
+ // (the field `CssModulesPlugin.getChunkFilenameTemplate` reads).
670
+ // Compilation only flows `options.filename` to `chunk.filenameTemplate`,
671
+ // which controls JS emit — there's no entry-level `cssFilename`.
672
+ // Set it ourselves after chunks are created so each stylesheet
673
+ // entry emits to a distinct file derived from `output.cssFilename`
674
+ // (or `output.cssChunkFilename` for non-initial CSS chunks).
675
+ compilation.hooks.afterChunks.tap(PLUGIN_NAME, () => {
676
+ const { stylesheetEntries } = getState(compilation);
677
+ if (stylesheetEntries.size === 0) return;
678
+ for (const entryName of stylesheetEntries) {
679
+ const entrypoint = compilation.entrypoints.get(entryName);
680
+ if (!entrypoint) continue;
681
+ const chunk = entrypoint.getEntrypointChunk();
682
+ if (!chunk) continue;
683
+ // Each html-derived stylesheet entry uses the
684
+ // `cssChunkFilename` template — even though the entry
685
+ // chunk technically `canBeInitial()`, we deliberately
686
+ // avoid `cssFilename` here because that template often
687
+ // has no per-entry placeholder (it's derived from
688
+ // `output.filename`, which can be a literal like
689
+ // `bundle0.js`), and multiple `<link rel="stylesheet">`
690
+ // tags would then collide on the same emitted `.css`
691
+ // file. `cssChunkFilename` is derived from
692
+ // `output.chunkFilename` which webpack auto-extends
693
+ // with `[id].` when needed, guaranteeing uniqueness.
694
+ chunk.cssFilenameTemplate =
695
+ compilation.outputOptions.cssChunkFilename;
696
+ }
697
+ });
698
+ compilation.dependencyFactories.set(
699
+ HtmlSourceDependency,
700
+ normalModuleFactory
701
+ );
702
+ compilation.dependencyTemplates.set(
703
+ HtmlSourceDependency,
704
+ new HtmlSourceDependency.Template()
705
+ );
706
+ compilation.dependencyFactories.set(
707
+ HtmlEntryDependency,
708
+ normalModuleFactory
709
+ );
710
+ compilation.dependencyTemplates.set(
711
+ HtmlEntryDependency,
712
+ new HtmlEntryDependency.Template()
713
+ );
714
+ // Inline `<script>` content is bundled as its own entry — the
715
+ // same pipeline that handles `<script src>` — via a
716
+ // `data:text/javascript,...` request. The dependency
717
+ // template rewrites the original tag to `<script src=…>`.
718
+ compilation.dependencyFactories.set(
719
+ HtmlInlineScriptDependency,
720
+ normalModuleFactory
721
+ );
722
+ compilation.dependencyTemplates.set(
723
+ HtmlInlineScriptDependency,
724
+ new HtmlInlineScriptDependency.Template()
725
+ );
726
+ // Inline `<style>` content is routed through the CSS pipeline
727
+ // as a `data:text/css` module. The dependency template reads
728
+ // the processed CSS text from the CSS module's code
729
+ // generation data (`css-text` channel set by CssGenerator
730
+ // when `exportType` is `"text"`).
731
+ compilation.dependencyFactories.set(
732
+ HtmlInlineStyleDependency,
733
+ normalModuleFactory
734
+ );
735
+ compilation.dependencyTemplates.set(
736
+ HtmlInlineStyleDependency,
737
+ new HtmlInlineStyleDependency.Template()
738
+ );
739
+ // `<iframe srcdoc>` content is routed back through the HTML
740
+ // pipeline as a `data:text/html` module; the template reads the
741
+ // processed HTML from the nested module's `html` channel.
742
+ compilation.dependencyFactories.set(
743
+ HtmlInlineHtmlDependency,
744
+ normalModuleFactory
745
+ );
746
+ compilation.dependencyTemplates.set(
747
+ HtmlInlineHtmlDependency,
748
+ new HtmlInlineHtmlDependency.Template()
749
+ );
750
+ compilation.dependencyTemplates.set(
751
+ StaticExportsDependency,
752
+ new StaticExportsDependency.Template()
753
+ );
754
+ // `ConstDependency` is used by HtmlParser to insert
755
+ // ` type="module"` into the rewritten <script> tag when
756
+ // `output.module` is on. Register its template so the HTML
757
+ // generator runs the insertion.
758
+ compilation.dependencyTemplates.set(
759
+ ConstDependency,
760
+ new ConstDependency.Template()
761
+ );
762
+ normalModuleFactory.hooks.createModuleClass
763
+ .for(HTML_MODULE_TYPE)
764
+ .tap(
765
+ PLUGIN_NAME,
766
+ (createData, _resolveData) => new HtmlModule(createData)
767
+ );
768
+ normalModuleFactory.hooks.createParser
769
+ .for(HTML_MODULE_TYPE)
770
+ .tap(PLUGIN_NAME, (parserOptions) => {
771
+ compiler.validate(
772
+ () => getSchema("HtmlParserOptions"),
773
+ parserOptions,
774
+ parserValidationOptions,
775
+ (options) =>
776
+ require("../../schemas/plugins/HtmlParserOptions.check")(
777
+ options
778
+ )
779
+ );
780
+ return new HtmlParser(parserOptions);
781
+ });
782
+
783
+ normalModuleFactory.hooks.createGenerator
784
+ .for(HTML_MODULE_TYPE)
785
+ .tap(PLUGIN_NAME, (generatorOptions) => {
786
+ compiler.validate(
787
+ () => getSchema("HtmlGeneratorOptions"),
788
+ generatorOptions,
789
+ generatorValidationOptions,
790
+ (options) =>
791
+ require("../../schemas/plugins/HtmlGeneratorOptions.check")(
792
+ options
793
+ )
794
+ );
795
+ return new HtmlGenerator(generatorOptions, compilation.moduleGraph);
796
+ });
797
+
798
+ NormalModule.getCompilationHooks(compilation).processResult.tap(
799
+ PLUGIN_NAME,
800
+ (result, module) => {
801
+ if (module.type === HTML_MODULE_TYPE) {
802
+ const [source, ...rest] = result;
803
+ // `applyTemplate` is a no-op unless `module.parser.html.template`
804
+ // is set. Running it here (where the returned source becomes the
805
+ // module's stored source) keeps the parser's dependency offsets
806
+ // and the generator's render base in sync.
807
+ const parser = /** @type {HtmlParser} */ (module.parser);
808
+
809
+ return [parser.applyTemplate(removeBOM(source), module), ...rest];
810
+ }
811
+
812
+ return result;
813
+ }
814
+ );
815
+
816
+ // Emit extracted `.html` files for any HTML module that opted
817
+ // into extraction. The opt-in is computed by
818
+ // `HtmlGenerator#_shouldExtract`: `module.generator.html.extract:
819
+ // true` always extracts, `false` never extracts, and when
820
+ // `extract` is unset the generator extracts iff the HTML module
821
+ // is a compilation entry — the iteration below picks up only
822
+ // modules whose generator reported the `html` source type, so
823
+ // that decision is honored implicitly. The HTML content is read
824
+ // from the generator's secondary `"html"` source type (see
825
+ // HtmlGenerator#generate). The filename template comes from
826
+ // `output.htmlFilename` (initial chunks) or
827
+ // `output.htmlChunkFilename` (non-initial chunks), mirroring
828
+ // the CSS pipeline. Path data follows the asset-module pattern —
829
+ // `module` + a relative source `filename`, with `chunk`
830
+ // intentionally omitted so `[name]` resolves to the HTML
831
+ // source's basename (e.g. `page` for `./page.html`) rather
832
+ // than the importing chunk's name (e.g. `main`). A per-module
833
+ // content hash is computed from the rewritten HTML so the
834
+ // template's `[contenthash]` placeholder works; the
835
+ // compilation hash is also forwarded so `[fullhash]` /
836
+ // `[hash]` work in user-supplied templates.
837
+
838
+ // Sentinel-resolved content and its content hash depend only on
839
+ // the HTML-type module source — not on the chunk or output
840
+ // filename — yet `renderManifest` runs per `(chunk, module)`.
841
+ // Memoize so a module landing in multiple chunks resolves and
842
+ // hashes its sentinels once. Scoped to this compilation because
843
+ // sentinel resolution embeds chunk filenames, which change
844
+ // across rebuilds; weakly keyed by source so entries release.
845
+ /** @type {WeakMap<import("webpack-sources").Source, { resolvedContent: string, contentHash: string }>} */
846
+ const resolvedSentinelHashCache = new WeakMap();
847
+
848
+ // Compute a linked/entry HTML page's emitted filename + chunk-URL-resolved
849
+ // content + content hash for one (module, chunk). Shared by the emit loop
850
+ // below and the page-link resolver. The content hash covers only the
851
+ // chunk-URL-resolved source — links to *other* pages stay sentinels here,
852
+ // so a page's filename doesn't depend on the filenames of pages it links to.
853
+ const computePageEmit = (
854
+ /** @type {NormalModule} */ module,
855
+ /** @type {import("../Chunk")} */ chunk
856
+ ) => {
857
+ const { chunkGraph, outputOptions } = compilation;
858
+ const codeGenResult =
859
+ /** @type {import("../CodeGenerationResults")} */ (
860
+ compilation.codeGenerationResults
861
+ ).get(module, chunk.runtime);
862
+ const placeholderSource = codeGenResult.sources.get(HTML_TYPE);
863
+ if (!placeholderSource) return undefined;
864
+ let cached = resolvedSentinelHashCache.get(placeholderSource);
865
+ if (cached === undefined) {
866
+ // Resolve chunk-URL sentinels *before* hashing so the HTML's
867
+ // `[contenthash]` invalidates with the referenced chunks'
868
+ // filenames. Inlined chunks have no URL, so tag their inline
869
+ // sentinels with the chunk content hash — that keeps the emitted
870
+ // bytes (and RealContentHashPlugin's later recompute)
871
+ // content-dependent, so the page hash tracks inlined content too.
872
+ // Asset URL sentinels (from `HtmlEntryDependency` resource-hint
873
+ // tags) resolve here too — deferred from template.apply so it
874
+ // doesn't race with asset-module codegen.
875
+ const resolvedContent = HtmlGenerator.resolveAssetUrlSentinels(
876
+ HtmlGenerator.embedInlineChunkHashes(
877
+ HtmlGenerator.resolveChunkUrlSentinels(
878
+ /** @type {string} */ (placeholderSource.source()),
879
+ compilation
880
+ ),
881
+ compilation
882
+ ),
883
+ compilation
884
+ );
885
+ cached = {
886
+ resolvedContent,
887
+ contentHash: HtmlModulesPlugin.computeContentHash(
888
+ resolvedContent,
889
+ outputOptions
890
+ )
891
+ };
892
+ resolvedSentinelHashCache.set(placeholderSource, cached);
893
+ }
894
+ const resource = module.getResource() || module.resource;
895
+ // Synthetic `output.html` entries are `data:text/html` modules with no
896
+ // real basename — name the file after the entry instead.
897
+ const sourceFilename =
898
+ resource.startsWith("data:text/html") && chunk.name
899
+ ? chunk.name
900
+ : makePathsRelative(
901
+ compiler.context,
902
+ /** @type {string} */ (resource),
903
+ compiler.root
904
+ ).replace(/^\.\//, "");
905
+ const filenameTemplate = HtmlModulesPlugin.getChunkFilenameTemplate(
906
+ chunk,
907
+ outputOptions
908
+ );
909
+ const { path: filename, info } = compilation.getPathWithInfo(
910
+ /** @type {import("../TemplatedPathPlugin").TemplatePath} */
911
+ (filenameTemplate),
912
+ {
913
+ module,
914
+ runtime: chunk.runtime,
915
+ chunkGraph,
916
+ contentHash: cached.contentHash,
917
+ contentHashType: HTML_TYPE,
918
+ filename: sourceFilename,
919
+ hash: compilation.hash
920
+ }
921
+ );
922
+ return {
923
+ resolvedContent: cached.resolvedContent,
924
+ contentHash: cached.contentHash,
925
+ filename,
926
+ info
927
+ };
928
+ };
929
+
930
+ // Emitted filename of a linked `type: "html"` page, keyed by its entry
931
+ // name. Looked up from the page's own entry chunk so it's independent of
932
+ // chunk render order; cached for the compilation.
933
+ /** @type {Map<string, string>} */
934
+ const htmlPageFilenameCache = new Map();
935
+ const computePageFilenameByEntry = (
936
+ /** @type {string} */ entryName
937
+ ) => {
938
+ const cached = htmlPageFilenameCache.get(entryName);
939
+ if (cached !== undefined) return cached;
940
+ let filename = "data:,";
941
+ const entrypoint = compilation.entrypoints.get(entryName);
942
+ const chunk = entrypoint && entrypoint.getEntrypointChunk();
943
+ if (chunk) {
944
+ const modules =
945
+ compilation.chunkGraph.getOrderedChunkModulesIterableBySourceType(
946
+ chunk,
947
+ HTML_TYPE,
948
+ compareModulesByFullName(compilation.compiler)
949
+ );
950
+ const module = modules && modules[Symbol.iterator]().next().value;
951
+ if (module) {
952
+ const emit = computePageEmit(
953
+ /** @type {NormalModule} */ (module),
954
+ chunk
955
+ );
956
+ if (emit) filename = emit.filename;
957
+ }
958
+ }
959
+ htmlPageFilenameCache.set(entryName, filename);
960
+ return filename;
961
+ };
962
+
963
+ compilation.hooks.renderManifest.tap(
964
+ PLUGIN_NAME,
965
+ (result, { chunk }) => {
966
+ // HMR's `HotUpdateChunk`s flow through the same hook
967
+ // but aren't real output chunks — extracting `.html`
968
+ // for them would create stray hot-update HTML files.
969
+ // `CssModulesPlugin` early-returns for the same reason.
970
+ if (chunk instanceof HotUpdateChunk) return result;
971
+ const { chunkGraph } = compilation;
972
+ const modules =
973
+ chunkGraph.getOrderedChunkModulesIterableBySourceType(
974
+ chunk,
975
+ HTML_TYPE,
976
+ compareModulesByFullName(compilation.compiler)
977
+ );
978
+ if (!modules) return result;
979
+ const outputOptions = compilation.outputOptions;
980
+ for (const module of modules) {
981
+ const normalModule = /** @type {NormalModule} */ (module);
982
+ // `<iframe srcdoc>` modules expose `html` only so HtmlInlineHtmlDependency
983
+ // can write the processed markup back into the host attribute — they are
984
+ // never standalone pages. `generator.extract: "inline"` marks them so no
985
+ // `.html` file is emitted; without this they'd collide on the
986
+ // `data:text/html` → chunk-name path (every srcdoc module in a chunk would
987
+ // emit `<chunk>.html`). An O(1) flag check, not a scan.
988
+ const generatorOptions = normalModule.generatorOptions;
989
+ if (generatorOptions && generatorOptions.extract === "inline") {
990
+ continue;
991
+ }
992
+
993
+ const emit = computePageEmit(normalModule, chunk);
994
+ if (!emit) continue;
995
+ const { resolvedContent, contentHash, filename, info } = emit;
996
+
997
+ // Resolve any remaining `[webpack/auto]` placeholders to an undo
998
+ // path computed from the emitted HTML's location, so asset/chunk
999
+ // URLs stay relative to `output.path` even when the page emits into
1000
+ // a subdirectory. A relative `<base href>` prepends `../`s so the
1001
+ // base can't misdirect the rewritten URLs (see `HtmlParser`).
1002
+ const basePrefix =
1003
+ /** @type {HtmlModuleBuildInfo} */ (normalModule.buildInfo)
1004
+ .baseUrlPrefix || "";
1005
+ const undoPath =
1006
+ basePrefix +
1007
+ getUndoPath(
1008
+ filename,
1009
+ /** @type {string} */ (outputOptions.path),
1010
+ false
1011
+ );
1012
+ // Resolve linked-page (`type: "html"`) sentinels to each page's
1013
+ // emitted filename before the undo path, so the href is relative to
1014
+ // this page.
1015
+ const finalContent = HtmlGenerator.resolveHtmlPageUrlSentinels(
1016
+ resolvedContent,
1017
+ computePageFilenameByEntry
1018
+ )
1019
+ .split(autoPlaceholder)
1020
+ .join(undoPath);
1021
+ const finalSource = new RawSource(finalContent);
1022
+ // The same HTML module can land in multiple chunks with different
1023
+ // `htmlFilename`/`htmlChunkFilename` shapes → different `undoPath`s and
1024
+ // final content for the same module id. Include the emitted filename in
1025
+ // the asset cache key and the post-undo-path content in the hash so the
1026
+ // asset cache can't reuse one variant's bytes at another variant's URL.
1027
+ // Unchanged content reuses the memoized hash instead of re-digesting.
1028
+ const finalContentHash =
1029
+ finalContent === resolvedContent
1030
+ ? contentHash
1031
+ : HtmlModulesPlugin.computeContentHash(
1032
+ finalContent,
1033
+ outputOptions
1034
+ );
1035
+
1036
+ // Track HTML pages for the integrity sentinel pass (never JS chunks).
1037
+ getState(compilation).htmlAssetNames.add(filename);
1038
+
1039
+ result.push({
1040
+ render: () => finalSource,
1041
+ filename,
1042
+ info,
1043
+ auxiliary: true,
1044
+ identifier: `htmlModule${chunkGraph.getModuleId(
1045
+ module
1046
+ )}|${filename}`,
1047
+ hash: finalContentHash
1048
+ });
1049
+ }
1050
+ return result;
1051
+ }
1052
+ );
1053
+
1054
+ // Resolve sentinels at JS chunk render time so later passes
1055
+ // (SourceMapDevToolPlugin, size optimizers, RealContentHash) see resolved bytes.
1056
+ const jsHooks =
1057
+ JavascriptModulesPlugin.getCompilationHooks(compilation);
1058
+ jsHooks.render.tap(PLUGIN_NAME, (source, renderContext) => {
1059
+ // No HTML modules ⇒ no sentinels; skip materializing the JS source.
1060
+ if (htmlModules.size === 0) return source;
1061
+ const raw = source.source();
1062
+ if (typeof raw !== "string") return source;
1063
+ if (
1064
+ !raw.includes("__WEBPACK_HTML_CHUNK_URL__") &&
1065
+ !raw.includes("__WEBPACK_HTML_PAGE_URL__") &&
1066
+ !raw.includes("__WEBPACK_HTML_INTEGRITY__") &&
1067
+ !raw.includes("__WEBPACK_HTML_INLINE__") &&
1068
+ !raw.includes("__WEBPACK_HTML_ASSET_URL__")
1069
+ ) {
1070
+ return source;
1071
+ }
1072
+ // Strip integrity and inline sentinels (not resolve): a JS chunk
1073
+ // can't hold real SRI hashes for its own not-yet-final bytes, and
1074
+ // inline content belongs only in the final .html, never in JS bundles.
1075
+ const resolved = HtmlGenerator.stripChunkIntegritySentinels(
1076
+ HtmlGenerator.resolveAssetUrlSentinels(
1077
+ HtmlGenerator.resolveHtmlPageUrlSentinels(
1078
+ HtmlGenerator.resolveChunkUrlSentinels(raw, compilation),
1079
+ computePageFilenameByEntry
1080
+ ),
1081
+ compilation
1082
+ )
1083
+ .split(autoPlaceholder)
1084
+ .join("")
1085
+ ).replace(
1086
+ /__WEBPACK_HTML_INLINE__[0-9a-f]+__[a-z]+(?:__[0-9a-f]+)?__END__/g,
1087
+ ""
1088
+ );
1089
+ if (resolved === raw) return source;
1090
+ const chunkId = String(renderContext.chunk.id);
1091
+ const prior = sentinelResolvedSourceCache.get(chunkId);
1092
+ if (prior !== undefined && prior.content === resolved) {
1093
+ return prior.source;
1094
+ }
1095
+ const newSource = new RawSource(resolved);
1096
+ sentinelResolvedSourceCache.set(chunkId, {
1097
+ content: resolved,
1098
+ source: newSource
1099
+ });
1100
+ return newSource;
1101
+ });
1102
+
1103
+ // Prune cache entries for chunks no longer in the graph so a
1104
+ // long watch session can't accumulate stale entries.
1105
+ compilation.hooks.afterSeal.tap(PLUGIN_NAME, () => {
1106
+ if (sentinelResolvedSourceCache.size === 0) return;
1107
+ const live = new Set();
1108
+ for (const chunk of compilation.chunks) {
1109
+ live.add(String(chunk.id));
1110
+ }
1111
+ for (const id of sentinelResolvedSourceCache.keys()) {
1112
+ if (!live.has(id)) sentinelResolvedSourceCache.delete(id);
1113
+ }
1114
+ });
1115
+ }
1116
+ );
1117
+ }
1118
+ }
1119
+
1120
+ /**
1121
+ * Per-compilation hooks for the experimental HTML support.
1122
+ * @param {Compilation} compilation the compilation
1123
+ * @returns {HtmlCompilationHooks} the hooks
1124
+ */
1125
+ HtmlModulesPlugin.getCompilationHooks = createHooksRegistry(
1126
+ createCompilationHooks
1127
+ );
1128
+
1129
+ module.exports = HtmlModulesPlugin;