@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,1490 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ */
4
+
5
+ "use strict";
6
+
7
+ const { RawSource, ReplaceSource } = require("webpack-sources");
8
+ const ConcatenationScope = require("../ConcatenationScope");
9
+ const Generator = require("../Generator");
10
+ const {
11
+ HTML_TYPE,
12
+ JAVASCRIPT_TYPE,
13
+ JAVASCRIPT_TYPES
14
+ } = require("../ModuleSourceTypeConstants");
15
+ const RuntimeGlobals = require("../RuntimeGlobals");
16
+ const Template = require("../Template");
17
+ const WebpackError = require("../errors/WebpackError");
18
+ const { getUndoPath } = require("../util/identifier");
19
+ const memoize = require("../util/memoize");
20
+ const { PUBLIC_PATH_AUTO } = require("../util/publicPathPlaceholder");
21
+ const { NodeType, SourceProcessor, escapeAttribute } = require("./syntax");
22
+
23
+ // Lazy so loading the HTML generator doesn't pull in the whole CSS pipeline.
24
+ const getCssModulesPlugin = memoize(() => require("../css/CssModulesPlugin"));
25
+ // The CSS tokenizer, used to locate `url(...)` when rebasing inlined stylesheets.
26
+ const getCssSyntax = memoize(() => require("../css/syntax"));
27
+ // node's crypto — real SHA hashes for Content-Security-Policy source lists
28
+ // (the wasm hashes are xxhash, unusable for CSP), loaded only when CSP is on.
29
+ const getCreateNodeHash = memoize(() => require("crypto").createHash);
30
+
31
+ // HTML void elements — serialized without a closing tag when a tag descriptor
32
+ // (`output.html` `injectTags`) doesn't say otherwise.
33
+ const VOID_TAGS = new Set([
34
+ "area",
35
+ "base",
36
+ "br",
37
+ "col",
38
+ "embed",
39
+ "hr",
40
+ "img",
41
+ "input",
42
+ "link",
43
+ "meta",
44
+ "param",
45
+ "source",
46
+ "track",
47
+ "wbr"
48
+ ]);
49
+
50
+ /**
51
+ * Serializes an attribute map: `true` → bare attribute, `false`/`undefined`/
52
+ * `null` → omitted, else a quoted (escaped) value.
53
+ * @param {Record<string, string | boolean | undefined> | undefined} attrs attributes
54
+ * @returns {string} the leading-space-prefixed attribute string
55
+ */
56
+ const serializeAttrs = (attrs) => {
57
+ let out = "";
58
+ if (attrs) {
59
+ for (const name of Object.keys(attrs)) {
60
+ const value = attrs[name];
61
+ if (value === false || value === undefined || value === null) continue;
62
+ out +=
63
+ value === true
64
+ ? ` ${name}`
65
+ : ` ${name}="${escapeAttribute(`${value}`)}"`;
66
+ }
67
+ }
68
+ return out;
69
+ };
70
+
71
+ /**
72
+ * Serializes one tag descriptor. `attrs` values: `true` → bare attribute,
73
+ * `false`/`undefined` → omitted, else a quoted (escaped) value.
74
+ * @param {HtmlTagDescriptor} tag the descriptor
75
+ * @returns {string} the tag's HTML
76
+ */
77
+ const serializeTag = (tag) => {
78
+ const attrs = serializeAttrs(tag.attrs);
79
+ const isVoid =
80
+ tag.voidTag !== undefined
81
+ ? tag.voidTag
82
+ : VOID_TAGS.has(tag.tag.toLowerCase());
83
+ return isVoid
84
+ ? `<${tag.tag}${attrs}>`
85
+ : `<${tag.tag}${attrs}>${tag.children || ""}</${tag.tag}>`;
86
+ };
87
+
88
+ /**
89
+ * Canonical string of an attribute map (present keys, sorted) — used to detect
90
+ * whether an `transformTags` plugin changed a tag, so unchanged tags stay untouched.
91
+ * `false`/`undefined`/`null` count as absent.
92
+ * @param {Record<string, string | boolean | undefined>} attrs attributes
93
+ * @returns {string} a comparable snapshot
94
+ */
95
+ const snapshotAttrs = (attrs) =>
96
+ JSON.stringify(
97
+ Object.keys(attrs)
98
+ .filter((name) => {
99
+ const value = attrs[name];
100
+ return value !== false && value !== undefined && value !== null;
101
+ })
102
+ .sort()
103
+ .map((name) => [name, attrs[name]])
104
+ );
105
+
106
+ /**
107
+ * Whether an attribute renders (present and not `false`/`undefined`/`null`).
108
+ * @param {Record<string, string | boolean | undefined>} attrs attributes
109
+ * @param {string} name attribute name
110
+ * @returns {boolean} true if it renders
111
+ */
112
+ const attrPresent = (attrs, name) => {
113
+ const value = attrs[name];
114
+ return value !== undefined && value !== false && value !== null;
115
+ };
116
+
117
+ /**
118
+ * Whether a `<meta>`'s attributes declare a Content-Security-Policy (case-
119
+ * insensitive `http-equiv`), used to detect an author-declared CSP.
120
+ * @param {Record<string, string | boolean | undefined>} attrs attributes
121
+ * @returns {boolean} true if it is a CSP meta
122
+ */
123
+ const metaIsCsp = (attrs) => {
124
+ for (const name of Object.keys(attrs)) {
125
+ const value = attrs[name];
126
+ if (
127
+ name.toLowerCase() === "http-equiv" &&
128
+ typeof value === "string" &&
129
+ value.trim().toLowerCase() === "content-security-policy"
130
+ ) {
131
+ return true;
132
+ }
133
+ }
134
+ return false;
135
+ };
136
+
137
+ /** @typedef {import("webpack-sources").Source} Source */
138
+ /** @typedef {import("../../declarations/WebpackOptions").HtmlGeneratorOptions} HtmlGeneratorOptions */
139
+ /** @typedef {import("../../declarations/WebpackOptions").OutputHtmlOptions["csp"]} CspOption */
140
+ /** @typedef {import("./HtmlModulesPlugin").HtmlTagDescriptor} HtmlTagDescriptor */
141
+ /** @typedef {import("./HtmlModulesPlugin").HtmlMutableTag} HtmlMutableTag */
142
+ /** @typedef {"head" | "body"} HtmlTagLocation */
143
+ /**
144
+ * @typedef {object} HtmlTagSpan
145
+ * @property {number} start opening `<` offset
146
+ * @property {number} openEnd offset just after the opening `>`
147
+ * @property {number} end offset just after the whole element
148
+ * @property {HtmlTagLocation} location the `<head>`/`<body>` region it sits in
149
+ * @property {number} nameEnd offset after the tag name (nonce insertion point), `-1` for non-`<script>`/`<style>`
150
+ * @property {number} contentEnd raw-text body end for `<script>`/`<style>`, `-1` otherwise
151
+ * @property {boolean} selfClosing whether the element is self-closing
152
+ */
153
+ /** @typedef {{ headOpen: number, headEnd: number, bodyOpen: number, bodyEnd: number }} HtmlAnchors */
154
+ /** @typedef {{ tags: HtmlMutableTag[], spans: (HtmlTagSpan | null)[], originals: (string | null)[], descriptors: (HtmlTagDescriptor | null)[], anchors: HtmlAnchors }} HtmlModel */
155
+ /** @typedef {import("../Chunk")} Chunk */
156
+ /** @typedef {import("../Compilation")} Compilation */
157
+ /** @typedef {boolean | string[] | ((asset: { chunk: Chunk, filename: string }) => string[] | false)} HtmlIntegrity */
158
+ /** @typedef {import("../Compilation").DependencyConstructor} DependencyConstructor */
159
+ /** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
160
+ /** @typedef {import("../Dependency")} Dependency */
161
+ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
162
+ /** @typedef {import("../Generator").GenerateContext} GenerateContext */
163
+ /** @typedef {import("../Generator").UpdateHashContext} UpdateHashContext */
164
+ /** @typedef {import("../Module")} Module */
165
+ /** @typedef {import("../Module").SourceType} SourceType */
166
+ /** @typedef {import("../Module").SourceTypes} SourceTypes */
167
+ /** @typedef {import("../Module").ConcatenationBailoutReasonContext} ConcatenationBailoutReasonContext */
168
+ /** @typedef {import("../ModuleGraph")} ModuleGraph */
169
+ /** @typedef {import("../NormalModule")} NormalModule */
170
+ /** @typedef {import("./HtmlModule").HtmlModuleBuildInfo} HtmlModuleBuildInfo */
171
+ /** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
172
+ /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
173
+ /** @typedef {import("../util/Hash")} Hash */
174
+ /**
175
+ * @template T
176
+ * @typedef {import("../InitFragment")<T>} InitFragment
177
+ */
178
+
179
+ /**
180
+ * @type {ReadonlySet<"javascript" | "html">}
181
+ */
182
+ const JAVASCRIPT_AND_HTML_TYPES = new Set([JAVASCRIPT_TYPE, HTML_TYPE]);
183
+
184
+ /** @type {WeakMap<Compilation, Map<string, Chunk>>} */
185
+ const chunksByIdCache = new WeakMap();
186
+
187
+ /**
188
+ * `String(chunk.id)` → chunk lookup, memoized per compilation and shared by the
189
+ * URL and integrity sentinel resolvers.
190
+ * @param {Compilation} compilation compilation
191
+ * @returns {Map<string, Chunk>} chunks keyed by stringified id
192
+ */
193
+ const getChunksById = (compilation) => {
194
+ let chunksById = chunksByIdCache.get(compilation);
195
+ if (chunksById === undefined) {
196
+ chunksById = new Map();
197
+ for (const chunk of compilation.chunks) {
198
+ chunksById.set(String(chunk.id), chunk);
199
+ }
200
+ chunksByIdCache.set(compilation, chunksById);
201
+ }
202
+ return chunksById;
203
+ };
204
+
205
+ /** @type {WeakMap<Compilation, Map<string, Module>>} */
206
+ const modulesByIdentifierCache = new WeakMap();
207
+
208
+ /**
209
+ * `module.identifier()` → module lookup, memoized per compilation so the asset
210
+ * URL sentinel resolver doesn't re-scan the whole module graph per HTML module.
211
+ * @param {Compilation} compilation compilation
212
+ * @returns {Map<string, Module>} modules keyed by identifier
213
+ */
214
+ const getModulesByIdentifier = (compilation) => {
215
+ let modulesByIdentifier = modulesByIdentifierCache.get(compilation);
216
+ if (modulesByIdentifier === undefined) {
217
+ modulesByIdentifier = new Map();
218
+ for (const module of compilation.modules) {
219
+ modulesByIdentifier.set(module.identifier(), module);
220
+ }
221
+ modulesByIdentifierCache.set(compilation, modulesByIdentifier);
222
+ }
223
+ return modulesByIdentifier;
224
+ };
225
+
226
+ // Hoisted so `resolveChunkUrlSentinels` (per chunk × module) doesn't allocate a
227
+ // fresh `RegExp` each call. `String#replace` resets `lastIndex`, so sharing the
228
+ // global-flag instance is safe under these synchronous, non-reentrant calls.
229
+ const CHUNK_URL_SENTINEL_REGEXP =
230
+ /__WEBPACK_HTML_CHUNK_URL__([0-9a-f]+)__([a-z]+)__END__/g;
231
+
232
+ // Sentinel for a linked HTML page (a tag mapped to the `html` source type);
233
+ // resolved to the page's emitted filename once it has been built. Keyed by the
234
+ // linked module's id so it shares the `<iframe srcdoc>` nested-module mechanism.
235
+ const HTML_PAGE_URL_SENTINEL_REGEXP =
236
+ /__WEBPACK_HTML_PAGE_URL__([0-9a-f]+)__END__/g;
237
+
238
+ // Sentinel for a URL-referenced asset (font/image/…) emitted into a resource-hint
239
+ // `<link>` tag by `HtmlEntryDependency`; resolved to the asset's real emitted
240
+ // URL from its codegen data during `HtmlModulesPlugin` render. Deferred because
241
+ // HtmlEntry deps run *while* the HTML module is being codegen'd — the asset
242
+ // module's own codegen might not have completed yet. Keyed by the asset
243
+ // module's identifier, hex-encoded so any character in it is safe in a URL.
244
+ const ASSET_URL_SENTINEL_REGEXP =
245
+ /__WEBPACK_HTML_ASSET_URL__([0-9a-f]+)__END__/g;
246
+
247
+ // Matches the whole ` integrity="<sentinel>"` so the attribute can be dropped
248
+ // entirely when the per-asset `integrity` function returns `false`.
249
+ const INTEGRITY_SENTINEL_REGEXP =
250
+ / integrity="__WEBPACK_HTML_INTEGRITY__([0-9a-f]+)__([a-z]+)__END__"/g;
251
+
252
+ // Same attribute, but tolerant of the `\"` escaping the surrounding quotes get
253
+ // when the HTML lives inside a JS string literal — used only to strip it there.
254
+ const INTEGRITY_SENTINEL_STRIP_REGEXP =
255
+ / integrity=\\?"__WEBPACK_HTML_INTEGRITY__[0-9a-f]+__[a-z]+__END__\\?"/g;
256
+
257
+ // The trailing `(?:__<hash>)?` is the inlined chunk's content hash, embedded by
258
+ // `embedInlineChunkHashes` so the host HTML's bytes (and its `[contenthash]`,
259
+ // incl. RealContentHashPlugin's recompute) change with the inlined content; the
260
+ // resolver ignores it.
261
+ const INLINE_SENTINEL_REGEXP =
262
+ /__WEBPACK_HTML_INLINE__([0-9a-f]+)__([a-z]+)(?:__[0-9a-f]+)?__END__/g;
263
+
264
+ /**
265
+ * Rewrite relative `url(...)` references in a CSS chunk so they still resolve
266
+ * after the styles are inlined into the HTML document (which may sit in a
267
+ * different directory). webpack emits every url as `undoPath(cssFile) + <asset
268
+ * path from the output root>`, so swapping the CSS file's undo prefix for the
269
+ * HTML file's re-bases them — no path math. Uses the CSS tokenizer to find url
270
+ * tokens exactly (never a `url(` inside a comment or string); webpack emits
271
+ * unquoted url()s (special characters `\`-escaped), so only that shape occurs.
272
+ * @param {string} css the CSS content
273
+ * @param {string} fromFile the CSS file's output name
274
+ * @param {string} toFile the HTML file's output name
275
+ * @param {string} outputPath the compilation output path
276
+ * @returns {string} the CSS with rebased urls
277
+ */
278
+ const rebaseCssUrls = (css, fromFile, toFile, outputPath) => {
279
+ const fromUndo = getUndoPath(fromFile, outputPath, false);
280
+ const toUndo = getUndoPath(toFile, outputPath, false);
281
+ if (fromUndo === toUndo) return css;
282
+ const { readToken, TT_URL } = getCssSyntax();
283
+ const token = {
284
+ type: 0,
285
+ start: 0,
286
+ end: 0,
287
+ isId: false,
288
+ contentStart: 0,
289
+ contentEnd: 0,
290
+ unitStart: 0
291
+ };
292
+ let pos = 0;
293
+ let last = 0;
294
+ let out = "";
295
+ while (readToken(css, pos, token) !== undefined) {
296
+ pos = token.end;
297
+ if (token.type !== TT_URL) continue;
298
+ const url = css.slice(token.contentStart, token.contentEnd);
299
+ // Rebase only the undo-path-relative urls; a root-relative (`/`), fragment
300
+ // (`#`) or scheme (`data:`, …, a `:` before any `/`) url is absolute.
301
+ const colon = url.indexOf(":");
302
+ const slash = url.indexOf("/");
303
+ if (
304
+ !url.startsWith(fromUndo) ||
305
+ url[0] === "/" ||
306
+ url[0] === "#" ||
307
+ (colon !== -1 && (slash === -1 || colon < slash))
308
+ ) {
309
+ continue;
310
+ }
311
+ out += `${css.slice(last, token.contentStart)}${toUndo}${url.slice(
312
+ fromUndo.length
313
+ )}`;
314
+ last = token.contentEnd;
315
+ }
316
+ return last === 0 ? css : out + css.slice(last);
317
+ };
318
+
319
+ class HtmlGenerator extends Generator {
320
+ /**
321
+ * Emit a sentinel for a chunk URL that can't be resolved at code-gen time
322
+ * (chunk hashes aren't computed yet); `resolveChunkUrlSentinels` swaps it
323
+ * for `${PUBLIC_PATH_AUTO}<chunkFilename>` once they are.
324
+ * @param {Chunk} chunk chunk
325
+ * @param {"javascript" | "css"} contentHashType which chunk content hash slot the resolved URL should reference
326
+ * @returns {string} sentinel
327
+ */
328
+ static makeChunkUrlSentinel(chunk, contentHashType) {
329
+ const hexId = Buffer.from(String(chunk.id), "utf8").toString("hex");
330
+ return `__WEBPACK_HTML_CHUNK_URL__${hexId}__${contentHashType}__END__`;
331
+ }
332
+
333
+ /**
334
+ * Replace every `makeChunkUrlSentinel` sentinel in `content` with
335
+ * `${PUBLIC_PATH_AUTO}<chunkFilename>`. Must run after
336
+ * `Compilation#createHash()` so `[contenthash]` resolves.
337
+ * @param {string} content content
338
+ * @param {Compilation} compilation compilation
339
+ * @returns {string} resolved content
340
+ */
341
+ static resolveChunkUrlSentinels(content, compilation) {
342
+ if (!content.includes("__WEBPACK_HTML_CHUNK_URL__")) return content;
343
+ const outputOptions = compilation.outputOptions;
344
+ const chunksById = getChunksById(compilation);
345
+ return content.replace(
346
+ CHUNK_URL_SENTINEL_REGEXP,
347
+ (_, hexId, contentHashType) => {
348
+ const chunkId = Buffer.from(hexId, "hex").toString("utf8");
349
+ const chunk = chunksById.get(chunkId);
350
+ if (!chunk) return "data:,";
351
+ // Reuse each pipeline's own filename-template resolver so the URL
352
+ // matches exactly what that plugin emits (worker/hot-update chunk
353
+ // handling included), mirroring the CSS branch.
354
+ let filenameTemplate;
355
+ if (contentHashType === "css") {
356
+ filenameTemplate = getCssModulesPlugin().getChunkFilenameTemplate(
357
+ chunk,
358
+ outputOptions
359
+ );
360
+ } else {
361
+ const JavascriptModulesPlugin = require("../javascript/JavascriptModulesPlugin");
362
+
363
+ filenameTemplate = JavascriptModulesPlugin.getChunkFilenameTemplate(
364
+ chunk,
365
+ outputOptions
366
+ );
367
+ }
368
+ const filename = compilation.getPath(
369
+ /** @type {import("../TemplatedPathPlugin").TemplatePath} */
370
+ (filenameTemplate),
371
+ {
372
+ chunk,
373
+ contentHashType
374
+ }
375
+ );
376
+ return `${PUBLIC_PATH_AUTO}${filename}`;
377
+ }
378
+ );
379
+ }
380
+
381
+ /**
382
+ * Emit a sentinel for a linked HTML page's URL (a tag the user mapped to
383
+ * the `html` source `type`). The page's emitted filename isn't known at
384
+ * code-gen time; `resolveHtmlPageUrlSentinels` swaps it for
385
+ * `${PUBLIC_PATH_AUTO}<htmlFilename>` once the page has been built.
386
+ * @param {string | number} moduleId id of the linked HTML module
387
+ * @returns {string} sentinel
388
+ */
389
+ static makeHtmlPageUrlSentinel(moduleId) {
390
+ const hexId = Buffer.from(String(moduleId), "utf8").toString("hex");
391
+ return `__WEBPACK_HTML_PAGE_URL__${hexId}__END__`;
392
+ }
393
+
394
+ /**
395
+ * Replace every `makeHtmlPageUrlSentinel` sentinel in `content` with
396
+ * `${PUBLIC_PATH_AUTO}<htmlFilename>`, resolving each linked page's emitted
397
+ * filename through `getFilename`.
398
+ * @param {string} content content
399
+ * @param {(moduleId: string) => string} getFilename maps a linked module id to its emitted html filename
400
+ * @returns {string} resolved content
401
+ */
402
+ static resolveHtmlPageUrlSentinels(content, getFilename) {
403
+ if (!content.includes("__WEBPACK_HTML_PAGE_URL__")) return content;
404
+ return content.replace(
405
+ HTML_PAGE_URL_SENTINEL_REGEXP,
406
+ (_, hexId) =>
407
+ `${PUBLIC_PATH_AUTO}${getFilename(
408
+ Buffer.from(hexId, "hex").toString("utf8")
409
+ )}`
410
+ );
411
+ }
412
+
413
+ /**
414
+ * Emit a sentinel for a URL-referenced asset module. Resolved by
415
+ * `resolveAssetUrlSentinels` from the asset module's own codegen data
416
+ * (`data.get("url")`), which isn't populated when `HtmlEntryDependency`
417
+ * runs — the asset module's own codegen may still be pending.
418
+ * @param {string} moduleIdentifier the referenced asset module's `identifier()`
419
+ * @returns {string} sentinel
420
+ */
421
+ static makeAssetUrlSentinel(moduleIdentifier) {
422
+ const hex = Buffer.from(moduleIdentifier, "utf8").toString("hex");
423
+ return `__WEBPACK_HTML_ASSET_URL__${hex}__END__`;
424
+ }
425
+
426
+ /**
427
+ * Replace every `makeAssetUrlSentinel` in `content` with the asset module's
428
+ * emitted URL, read from its codegen data. Unresolved sentinels (module
429
+ * absent, no codegen result yet, or no URL channel — e.g. an inlined
430
+ * data-URI) map to `data:,` so the surrounding `<link>` degrades cleanly
431
+ * instead of shipping the raw placeholder.
432
+ * @param {string} content content
433
+ * @param {Compilation} compilation compilation
434
+ * @returns {string} resolved content
435
+ */
436
+ static resolveAssetUrlSentinels(content, compilation) {
437
+ if (!content.includes("__WEBPACK_HTML_ASSET_URL__")) return content;
438
+ const byIdentifier = getModulesByIdentifier(compilation);
439
+ const codeGenerationResults =
440
+ /** @type {import("../CodeGenerationResults")} */
441
+ (compilation.codeGenerationResults);
442
+ return content.replace(ASSET_URL_SENTINEL_REGEXP, (_, hex) => {
443
+ const id = Buffer.from(hex, "hex").toString("utf8");
444
+ const module = byIdentifier.get(id);
445
+ if (!module) return "data:,";
446
+ if (!codeGenerationResults.has(module, undefined)) return "data:,";
447
+ const codeGen = codeGenerationResults.get(module, undefined);
448
+ const data = codeGen.data;
449
+ if (!data) return "data:,";
450
+ const url =
451
+ /** @type {Record<string, string | undefined> | undefined} */
452
+ (data.get("url"));
453
+ // Prefer the `asset-url` channel — it's the actual URL string
454
+ // (publicPath + filename). Also handled: assets reached only from JS
455
+ // have no `asset-url` channel (their only URL is the JS expression
456
+ // `__webpack_require__.p + "…"`); for those we reconstruct the URL
457
+ // from the emitted `filename` + `PUBLIC_PATH_AUTO` so the same
458
+ // undo-path substitution runs at asset render.
459
+ if (url && url["asset-url"]) return url["asset-url"];
460
+ const filename = /** @type {string | undefined} */ (data.get("filename"));
461
+ if (filename) return `${PUBLIC_PATH_AUTO}${filename}`;
462
+ return "data:,";
463
+ });
464
+ }
465
+
466
+ /**
467
+ * Emit a sentinel for a chunk's SRI hash. Resolved late (after
468
+ * `RealContentHashPlugin`) by `resolveChunkIntegritySentinels`, since the
469
+ * hash must cover the chunk's final emitted bytes.
470
+ * @param {Chunk} chunk chunk
471
+ * @param {"javascript" | "css"} contentHashType which chunk asset to hash
472
+ * @returns {string} sentinel
473
+ */
474
+ static makeChunkIntegritySentinel(chunk, contentHashType) {
475
+ const hexId = Buffer.from(String(chunk.id), "utf8").toString("hex");
476
+ return `__WEBPACK_HTML_INTEGRITY__${hexId}__${contentHashType}__END__`;
477
+ }
478
+
479
+ /**
480
+ * Drop every ` integrity="<sentinel>"` from `content`. Used on the HTML
481
+ * string embedded in a JS chunk (e.g. `<iframe srcdoc>`), where a real SRI
482
+ * hash can't be produced — the chunk's own bytes aren't final at render time
483
+ * — and resolving it later would mutate the chunk after its content hash was
484
+ * computed. Only real HTML output assets keep the sentinel for late resolution.
485
+ * @param {string} content content
486
+ * @returns {string} content with integrity sentinels removed
487
+ */
488
+ static stripChunkIntegritySentinels(content) {
489
+ if (!content.includes("__WEBPACK_HTML_INTEGRITY__")) return content;
490
+ return content.replace(INTEGRITY_SENTINEL_STRIP_REGEXP, "");
491
+ }
492
+
493
+ /**
494
+ * Replace every ` integrity="<sentinel>"` with the chunk's real SRI hashes,
495
+ * or drop the attribute when `integrity` (a function) returns `false` for it.
496
+ * @param {string} content content
497
+ * @param {Compilation} compilation compilation
498
+ * @param {HtmlIntegrity} integrity the `output.html.integrity` option
499
+ * @returns {string} resolved content
500
+ */
501
+ static resolveChunkIntegritySentinels(content, compilation, integrity) {
502
+ if (!content.includes("__WEBPACK_HTML_INTEGRITY__")) return content;
503
+
504
+ const crypto = require("crypto");
505
+
506
+ // Report each bad hash algorithm once, not once per referencing tag.
507
+ const reportedBadAlgorithms = new Set();
508
+
509
+ const chunksById = getChunksById(compilation);
510
+ return content.replace(
511
+ INTEGRITY_SENTINEL_REGEXP,
512
+ (_, hexId, contentHashType) => {
513
+ const chunkId = Buffer.from(hexId, "hex").toString("utf8");
514
+ const chunk = chunksById.get(chunkId);
515
+ if (!chunk) return "";
516
+ // `chunk.files` holds the real emitted names (after
517
+ // `RealContentHashPlugin`), so hash those bytes — not a name
518
+ // re-derived from the template, which still has the pre-hash value.
519
+ let filename;
520
+ for (const file of chunk.files) {
521
+ if ((contentHashType === "css") === file.endsWith(".css")) {
522
+ filename = file;
523
+ break;
524
+ }
525
+ }
526
+ if (!filename) return "";
527
+ const asset = compilation.getAsset(filename);
528
+ if (!asset) return "";
529
+ const algorithms =
530
+ typeof integrity === "function"
531
+ ? integrity({ chunk, filename })
532
+ : integrity === true
533
+ ? ["sha384"]
534
+ : integrity;
535
+ if (!algorithms || algorithms.length === 0) return "";
536
+ const buffer = asset.source.buffer();
537
+ const parts = [];
538
+ for (const algorithm of algorithms) {
539
+ // `crypto.createHash` throws on an unknown algorithm name — turn
540
+ // that into a webpack error and skip the algorithm instead of
541
+ // crashing the whole compilation out of `processAssets`.
542
+ try {
543
+ parts.push(
544
+ `${algorithm}-${crypto
545
+ .createHash(algorithm)
546
+ .update(buffer)
547
+ .digest("base64")}`
548
+ );
549
+ } catch (_err) {
550
+ if (!reportedBadAlgorithms.has(algorithm)) {
551
+ reportedBadAlgorithms.add(algorithm);
552
+ compilation.errors.push(
553
+ new WebpackError(
554
+ `output.html.integrity: unsupported hash algorithm ${JSON.stringify(
555
+ algorithm
556
+ )}`
557
+ )
558
+ );
559
+ }
560
+ }
561
+ }
562
+ if (parts.length === 0) return "";
563
+ return ` integrity="${parts.join(" ")}"`;
564
+ }
565
+ );
566
+ }
567
+
568
+ /**
569
+ * @param {Chunk} chunk chunk
570
+ * @param {"javascript" | "css"} contentHashType which chunk asset to inline
571
+ * @returns {string} sentinel
572
+ */
573
+ static makeChunkInlineSentinel(chunk, contentHashType) {
574
+ const hexId = Buffer.from(String(chunk.id), "utf8").toString("hex");
575
+ return `__WEBPACK_HTML_INLINE__${hexId}__${contentHashType}__END__`;
576
+ }
577
+
578
+ /**
579
+ * Replace every inline sentinel with the chunk's actual source content.
580
+ * Must run after `RealContentHashPlugin` so the final emitted filenames are
581
+ * known (we look up the asset by filename from `chunk.files`).
582
+ * @param {string} content content
583
+ * @param {Compilation} compilation compilation
584
+ * @param {string} htmlFilename output name of the HTML file being resolved (to rebase CSS urls)
585
+ * @param {Set<string>=} inlinedFiles collects every chunk file inlined here, so the caller can drop now-unreferenced assets
586
+ * @returns {string} resolved content
587
+ */
588
+ static resolveChunkInlineSentinels(
589
+ content,
590
+ compilation,
591
+ htmlFilename,
592
+ inlinedFiles
593
+ ) {
594
+ if (!content.includes("__WEBPACK_HTML_INLINE__")) return content;
595
+ const chunksById = getChunksById(compilation);
596
+ const outputPath = /** @type {string} */ (compilation.outputOptions.path);
597
+ return content.replace(
598
+ INLINE_SENTINEL_REGEXP,
599
+ (_, hexId, contentHashType) => {
600
+ const chunkId = Buffer.from(hexId, "hex").toString("utf8");
601
+ const chunk = chunksById.get(chunkId);
602
+ if (!chunk) return "";
603
+ const isCss = contentHashType === "css";
604
+ let out = "";
605
+ for (const file of chunk.files) {
606
+ if (isCss !== file.endsWith(".css")) continue;
607
+ const asset = compilation.getAsset(file);
608
+ if (!asset) continue;
609
+ let raw = String(asset.source.source());
610
+ if (isCss) {
611
+ // Styles move into the document, so relative `url(...)` must be
612
+ // rebased; then escape `</style` so it can't close the block early.
613
+ raw = rebaseCssUrls(raw, file, htmlFilename, outputPath).replace(
614
+ /<\/(style)/gi,
615
+ "<\\/$1"
616
+ );
617
+ } else {
618
+ // Escape `</script` (early close) and `<!--` (enters the script-data
619
+ // escaped state, where a later `<script` hides the real close); both
620
+ // only occur inside a string/comment/regex, where `<\` is inert.
621
+ raw = raw
622
+ .replace(/<\/(script)/gi, "<\\/$1")
623
+ .replace(/<!--/g, "<\\!--");
624
+ }
625
+ out += raw;
626
+ if (inlinedFiles) inlinedFiles.add(file);
627
+ }
628
+ return out;
629
+ }
630
+ );
631
+ }
632
+
633
+ /**
634
+ * Parses the final HTML once and collects everything the `output.html`
635
+ * post-processing stages need: every `<script>`/`<link>`/`<style>`/`<meta>` as
636
+ * a mutable descriptor (for `transformTags`) paired with its source span, an
637
+ * attribute snapshot (to detect changes), and — for `<script>`/`<style>` — the
638
+ * raw-text body range and nonce insertion point (for CSP); plus the
639
+ * `<head>`/`<body>` open/content-end anchors (for `injectTags`). One parse feeds
640
+ * `injectTags` + `transformTags` + CSP, which `renderHtml` then applies in a
641
+ * single pass. Uses the pipeline's own parser (no regex).
642
+ * @param {string} content the final HTML (inline content already resolved)
643
+ * @returns {HtmlModel} the collected model
644
+ */
645
+ static collectHtml(content) {
646
+ /** @type {HtmlMutableTag[]} */
647
+ const tags = [];
648
+ /** @type {(HtmlTagSpan | null)[]} */
649
+ const spans = [];
650
+ /** @type {(string | null)[]} */
651
+ const originals = [];
652
+ /** @type {(HtmlTagDescriptor | null)[]} */
653
+ const descriptors = [];
654
+ let headOpen = -1;
655
+ let headEnd = -1;
656
+ let bodyOpen = -1;
657
+ let bodyEnd = -1;
658
+ let headDepth = 0;
659
+ let bodyDepth = 0;
660
+ // `skip.text` populates `contentEnd` (raw-text body end) without
661
+ // materializing text nodes; `</script` stays escaped, so CSP hashes match
662
+ // the exact bytes the browser sees.
663
+ new SourceProcessor()
664
+ .use({
665
+ [NodeType.Element]: {
666
+ enter: (path) => {
667
+ const name = path.tagName();
668
+ if (name === "head") {
669
+ if (headOpen < 0) headOpen = headEnd = path.tagEnd();
670
+ headDepth++;
671
+ return;
672
+ }
673
+ if (name === "body") {
674
+ if (bodyOpen < 0) bodyOpen = bodyEnd = path.tagEnd();
675
+ bodyDepth++;
676
+ return;
677
+ }
678
+ const end = path.end();
679
+ if (headDepth > 0 && end > headEnd) headEnd = end;
680
+ if (bodyDepth > 0 && end > bodyEnd) bodyEnd = end;
681
+ if (
682
+ name !== "script" &&
683
+ name !== "link" &&
684
+ name !== "style" &&
685
+ name !== "meta"
686
+ ) {
687
+ return;
688
+ }
689
+ /** @type {Record<string, string | boolean | undefined>} */
690
+ const attrs = {};
691
+ const count = path.attributeCount();
692
+ for (let i = 0; i < count; i++) {
693
+ const attr = path.attributeAt(i);
694
+ attrs[path.attributeName(attr)] =
695
+ path.attributeValueStart(attr) === -1
696
+ ? true
697
+ : path.attributeValue(attr);
698
+ }
699
+ const isRawText = name === "script" || name === "style";
700
+ tags.push({
701
+ tag: name,
702
+ attrs,
703
+ injectTo: bodyDepth > 0 ? "body" : "head"
704
+ });
705
+ spans.push({
706
+ start: path.start(),
707
+ openEnd: path.tagEnd(),
708
+ end,
709
+ location: bodyDepth > 0 ? "body" : "head",
710
+ nameEnd: isRawText ? path.nameEnd() : -1,
711
+ contentEnd: isRawText ? path.contentEnd() : -1,
712
+ selfClosing: path.selfClosing()
713
+ });
714
+ originals.push(snapshotAttrs(attrs));
715
+ descriptors.push(null);
716
+ },
717
+ exit: (path) => {
718
+ const name = path.tagName();
719
+ if (name === "head") {
720
+ if (headDepth > 0) headDepth--;
721
+ } else if (name === "body" && bodyDepth > 0) {
722
+ bodyDepth--;
723
+ }
724
+ }
725
+ }
726
+ })
727
+ .process(content, { skip: { text: true, doctype: true } });
728
+ return {
729
+ tags,
730
+ spans,
731
+ originals,
732
+ descriptors,
733
+ anchors: { headOpen, headEnd, bodyOpen, bodyEnd }
734
+ };
735
+ }
736
+
737
+ /**
738
+ * Appends `injectTags` descriptors to the model as spanless tags (pure inserts
739
+ * placed by `injectTo`), so `transformTags` sees them alongside the page's own
740
+ * tags and CSP hashes any injected inline `<script>`/`<style>`. `attrs` is
741
+ * copied so a `transformTags` mutation never corrupts the caller's descriptor.
742
+ * @param {HtmlModel} model the value from `collectHtml`
743
+ * @param {HtmlTagDescriptor[]} injected the `injectTags` descriptors
744
+ * @returns {void}
745
+ */
746
+ static addInjectedTags(model, injected) {
747
+ for (const descriptor of injected) {
748
+ model.tags.push({
749
+ tag: descriptor.tag,
750
+ attrs: descriptor.attrs ? { ...descriptor.attrs } : {},
751
+ injectTo: descriptor.injectTo || "head"
752
+ });
753
+ model.spans.push(null);
754
+ model.originals.push(null);
755
+ model.descriptors.push(descriptor);
756
+ }
757
+ }
758
+
759
+ /**
760
+ * Renders the collected (and hook-mutated) model back into HTML in a single
761
+ * pass: injected tags are placed by `injectTo`; an existing tag is left
762
+ * byte-for-byte unless it was removed, moved (`<head>`↔`<body>`, honoring
763
+ * `*-prepend`), or had its `attrs` changed; and — when `csp` is set and the
764
+ * page declares no CSP — a strict `<meta http-equiv="Content-Security-Policy">`
765
+ * is injected with a hash of every inline `<script>`/`<style>` (page's own and
766
+ * injected) plus an optional placeholder `nonce` on each. Edits run
767
+ * right-to-left; at a shared offset a delete/replace runs before an insert.
768
+ * @param {string} content the collected HTML (inline content already resolved)
769
+ * @param {HtmlModel} model the value from `collectHtml` after the hooks
770
+ * @param {CspOption} csp the `output.html.csp` option
771
+ * @returns {string} the rendered HTML
772
+ */
773
+ static renderHtml(content, model, csp) {
774
+ const { tags, spans, originals, descriptors, anchors } = model;
775
+ // CSP setup: an author-declared policy (page's own or injected) wins.
776
+ const options = csp ? (csp === true ? {} : csp) : undefined;
777
+ const nonce = options && options.nonce;
778
+ let hasCsp = false;
779
+ if (options) {
780
+ for (let i = 0; i < tags.length; i++) {
781
+ const tag = tags[i];
782
+ if (!tag.remove && tag.tag === "meta" && metaIsCsp(tag.attrs)) {
783
+ hasCsp = true;
784
+ break;
785
+ }
786
+ }
787
+ }
788
+ const addCsp = Boolean(options) && !hasCsp;
789
+ /** @type {Set<string>} */
790
+ const scriptSrc = new Set();
791
+ /** @type {Set<string>} */
792
+ const styleSrc = new Set();
793
+ let hashOf;
794
+ if (addCsp) {
795
+ const hashFunction =
796
+ /** @type {Exclude<CspOption, boolean | undefined>} */ (options)
797
+ .hashFunction || "sha256";
798
+ const createHash = getCreateNodeHash();
799
+ hashOf = (/** @type {string} */ body) =>
800
+ `'${hashFunction}-${createHash(hashFunction)
801
+ .update(body, "utf8")
802
+ .digest("base64")}'`;
803
+ }
804
+ // Insertions accumulated per offset (placement order preserved); range edits
805
+ // replace/delete an existing tag's span; region groups collect placements so
806
+ // `*-prepend` precedes the plain name at a shared (empty-region) anchor.
807
+ /** @type {Map<number, string>} */
808
+ const inserts = new Map();
809
+ /** @type {(pos: number, text: string) => void} */
810
+ const at = (pos, text) => {
811
+ if (text) inserts.set(pos, (inserts.get(pos) || "") + text);
812
+ };
813
+ // Placements accumulate per region so `*-prepend` always precedes the plain
814
+ // name at a shared offset (an empty `<head>`/`<body>`); emitted at the anchors
815
+ // after the loop.
816
+ /** @type {Record<string, string>} */
817
+ const groups = {
818
+ "head-prepend": "",
819
+ head: "",
820
+ "body-prepend": "",
821
+ body: ""
822
+ };
823
+ /** @type {(region: string | undefined, text: string) => void} */
824
+ const place = (region, text) => {
825
+ if (text) {
826
+ groups[region !== undefined && region in groups ? region : "head"] +=
827
+ text;
828
+ }
829
+ };
830
+ /** @type {{ start: number, end: number, text: string, insert: boolean }[]} */
831
+ const edits = [];
832
+ for (let i = 0; i < tags.length; i++) {
833
+ const tag = tags[i];
834
+ const span = spans[i];
835
+ const isRawText = tag.tag === "script" || tag.tag === "style";
836
+ const needsNonce =
837
+ addCsp &&
838
+ Boolean(nonce) &&
839
+ isRawText &&
840
+ !attrPresent(tag.attrs, "nonce");
841
+ // Hash an inline `<script>`/`<style>` (page's own or injected). External
842
+ // `<script src>` is covered by `'self'`; a self-closing tag has no body.
843
+ if (addCsp && isRawText && !tag.remove) {
844
+ const isScript = tag.tag === "script";
845
+ let body = "";
846
+ if (span) {
847
+ if (
848
+ !span.selfClosing &&
849
+ !(isScript && attrPresent(tag.attrs, "src"))
850
+ ) {
851
+ body = content.slice(span.openEnd, span.contentEnd);
852
+ }
853
+ } else if (!(isScript && attrPresent(tag.attrs, "src"))) {
854
+ body =
855
+ /** @type {HtmlTagDescriptor} */ (descriptors[i]).children || "";
856
+ }
857
+ if (body !== "") {
858
+ (isScript ? scriptSrc : styleSrc).add(
859
+ /** @type {(body: string) => string} */ (hashOf)(body)
860
+ );
861
+ }
862
+ }
863
+ if (!span) {
864
+ // Injected tag: serialize (with a nonce when CSP asks) and place it.
865
+ if (tag.remove) continue;
866
+ const descriptor = /** @type {HtmlTagDescriptor} */ (descriptors[i]);
867
+ const attrs = needsNonce
868
+ ? { nonce: /** @type {string} */ (nonce), ...tag.attrs }
869
+ : tag.attrs;
870
+ place(
871
+ tag.injectTo || "head",
872
+ serializeTag({
873
+ tag: tag.tag,
874
+ attrs,
875
+ children: descriptor.children,
876
+ voidTag: descriptor.voidTag
877
+ })
878
+ );
879
+ continue;
880
+ }
881
+ // Existing tag.
882
+ if (tag.remove) {
883
+ edits.push({
884
+ start: span.start,
885
+ end: span.end,
886
+ text: "",
887
+ insert: false
888
+ });
889
+ continue;
890
+ }
891
+ const attrsChanged = snapshotAttrs(tag.attrs) !== originals[i];
892
+ const moved =
893
+ tag.injectTo !== undefined && tag.injectTo !== span.location;
894
+ const nonceStr = needsNonce
895
+ ? ` nonce="${escapeAttribute(/** @type {string} */ (nonce))}"`
896
+ : "";
897
+ if (moved) {
898
+ const opening = `<${tag.tag}${nonceStr}${serializeAttrs(tag.attrs)}>`;
899
+ edits.push({
900
+ start: span.start,
901
+ end: span.end,
902
+ text: "",
903
+ insert: false
904
+ });
905
+ place(tag.injectTo, opening + content.slice(span.openEnd, span.end));
906
+ } else if (attrsChanged) {
907
+ // Rewrite the opening tag (a nonce, if any, lands first).
908
+ edits.push({
909
+ start: span.start,
910
+ end: span.openEnd,
911
+ text: `<${tag.tag}${nonceStr}${serializeAttrs(tag.attrs)}>`,
912
+ insert: false
913
+ });
914
+ } else if (nonceStr) {
915
+ // Nonce-only change: insert right after the tag name, rest verbatim.
916
+ edits.push({
917
+ start: span.nameEnd,
918
+ end: span.nameEnd,
919
+ text: nonceStr,
920
+ insert: true
921
+ });
922
+ }
923
+ }
924
+ if (addCsp) {
925
+ if (nonce) {
926
+ scriptSrc.add(`'nonce-${nonce}'`);
927
+ styleSrc.add(`'nonce-${nonce}'`);
928
+ }
929
+ // Strict baseline; a user `policy` directive replaces one, hashes/nonce append.
930
+ /** @type {Map<string, Set<string>>} */
931
+ const directives = new Map([
932
+ ["script-src", new Set(["'self'"])],
933
+ ["style-src", new Set(["'self'"])],
934
+ ["object-src", new Set(["'none'"])],
935
+ ["base-uri", new Set(["'self'"])]
936
+ ]);
937
+ const policyOption =
938
+ /** @type {Exclude<CspOption, boolean | undefined>} */ (options).policy;
939
+ if (policyOption) {
940
+ for (const [name, value] of Object.entries(policyOption)) {
941
+ directives.set(name, new Set(Array.isArray(value) ? value : [value]));
942
+ }
943
+ }
944
+ /** @type {(name: string, extra: Set<string>) => void} */
945
+ const append = (name, extra) => {
946
+ let set = directives.get(name);
947
+ if (!set) directives.set(name, (set = new Set()));
948
+ for (const value of extra) set.add(value);
949
+ };
950
+ append("script-src", scriptSrc);
951
+ append("style-src", styleSrc);
952
+ const policy = [...directives]
953
+ .filter(([, values]) => values.size > 0)
954
+ .map(([name, values]) => `${name} ${[...values].join(" ")}`)
955
+ .join("; ");
956
+ const meta = `<meta http-equiv="Content-Security-Policy" content="${escapeAttribute(
957
+ policy
958
+ )}">`;
959
+ // First at the head anchor, so it precedes any head-prepend tag.
960
+ at(anchors.headOpen, meta);
961
+ }
962
+ // Emit region placements at the `<head>`/`<body>` anchors (after any CSP
963
+ // meta, prepend before the plain name). The parser always synthesizes an
964
+ // implied `<head>`/`<body>`, so both anchors are always present.
965
+ at(anchors.headOpen, groups["head-prepend"]);
966
+ at(anchors.headEnd, groups.head);
967
+ at(anchors.bodyOpen, groups["body-prepend"]);
968
+ at(anchors.bodyEnd, groups.body);
969
+ for (const [pos, text] of inserts) {
970
+ edits.push({ start: pos, end: pos, text, insert: true });
971
+ }
972
+ if (edits.length === 0) return content;
973
+ edits.sort(
974
+ (a, b) => b.start - a.start || Number(a.insert) - Number(b.insert)
975
+ );
976
+ let result = content;
977
+ for (const edit of edits) {
978
+ result = result.slice(0, edit.start) + edit.text + result.slice(edit.end);
979
+ }
980
+ return result;
981
+ }
982
+
983
+ /**
984
+ * Embeds each inlined chunk's content hash into its inline sentinel
985
+ * (`…__<type>__END__` → `…__<type>__<hash>__END__`). The sentinel otherwise
986
+ * carries only the stable chunk id, so the host HTML's bytes wouldn't change
987
+ * when the inlined content changes — the resolved chunk URL that normally
988
+ * busts the page `[contenthash]` is gone once inlined. Embedding the hash
989
+ * makes the emitted bytes content-dependent, so both the initial hash and
990
+ * RealContentHashPlugin's recompute pick up inlined-content changes. The
991
+ * resolver (`resolveChunkInlineSentinels`) ignores this segment.
992
+ * @param {string} content content with chunk-url sentinels already resolved
993
+ * @param {Compilation} compilation compilation
994
+ * @returns {string} content with content-hash-tagged inline sentinels
995
+ */
996
+ static embedInlineChunkHashes(content, compilation) {
997
+ if (!content.includes("__WEBPACK_HTML_INLINE__")) return content;
998
+ const chunksById = getChunksById(compilation);
999
+ return content.replace(
1000
+ INLINE_SENTINEL_REGEXP,
1001
+ (match, hexId, contentHashType) => {
1002
+ const chunkId = Buffer.from(hexId, "hex").toString("utf8");
1003
+ const chunk = chunksById.get(chunkId);
1004
+ if (!chunk) return match;
1005
+ const hash =
1006
+ (chunk.contentHash && chunk.contentHash[contentHashType]) ||
1007
+ chunk.renderedHash ||
1008
+ chunk.hash;
1009
+ if (!hash) return match;
1010
+ return `__WEBPACK_HTML_INLINE__${hexId}__${contentHashType}__${hash}__END__`;
1011
+ }
1012
+ );
1013
+ }
1014
+
1015
+ /**
1016
+ * Creates an instance of HtmlGenerator.
1017
+ * @param {HtmlGeneratorOptions=} options generator options
1018
+ * @param {ModuleGraph=} moduleGraph the module graph; used to detect when an HTML module is reached as a compilation entry so `extract` can default to `true` for it
1019
+ */
1020
+ constructor(options, moduleGraph) {
1021
+ super();
1022
+ /** @type {HtmlGeneratorOptions} */
1023
+ this.options = options || {};
1024
+ /** @type {ModuleGraph | undefined} */
1025
+ this._moduleGraph = moduleGraph;
1026
+ // Raw dependency-template render (before `[webpack/auto]` resolution),
1027
+ // shared between the JS and HTML type passes of a single
1028
+ // `codeGeneration()` call. Keyed by that call's `runtimeRequirements`
1029
+ // Set — created once per call and passed to every type's `generate()`,
1030
+ // so it uniquely scopes the cache to one module's one code generation
1031
+ // and releases with it. The two passes differ only in `undoPath`.
1032
+ /** @type {WeakMap<RuntimeRequirements, string>} */
1033
+ this._rawRenderCache = new WeakMap();
1034
+ }
1035
+
1036
+ /**
1037
+ * Returns the reason this module cannot be concatenated, when one exists.
1038
+ * @param {NormalModule} module module for which the bailout reason should be determined
1039
+ * @param {ConcatenationBailoutReasonContext} context context
1040
+ * @returns {string | undefined} reason why this module can't be concatenated, undefined when it can be concatenated
1041
+ */
1042
+ getConcatenationBailoutReason(module, context) {
1043
+ // The HMR shim references the per-module `module.hot` object — when an
1044
+ // HTML module is concatenated, that scope is gone (the merged file
1045
+ // shares a single `module`), so the self-accept / DOM-patch wiring
1046
+ // would target the wrong module id. Bail out of concatenation so the
1047
+ // HMR-aware HTML module keeps its own module scope.
1048
+ if (module.hot) {
1049
+ return "HTML module needs its own module scope for HMR";
1050
+ }
1051
+ return undefined;
1052
+ }
1053
+
1054
+ /**
1055
+ * Whether this HTML module is reached as a compilation entry. Entry
1056
+ * modules have at least one incoming connection without an
1057
+ * `originModule` (the EntryDependency added by `compilation.addEntry`) —
1058
+ * this covers both HTML-as-entry-point and a linked `type: "html"` page
1059
+ * (added as its own entry by HtmlModulesPlugin).
1060
+ * @param {NormalModule} module module
1061
+ * @returns {boolean} true when the module is an entry
1062
+ */
1063
+ _isEntryModule(module) {
1064
+ if (!this._moduleGraph) return false;
1065
+ for (const connection of this._moduleGraph.getIncomingConnections(module)) {
1066
+ if (!connection.originModule) return true;
1067
+ }
1068
+ return false;
1069
+ }
1070
+
1071
+ /**
1072
+ * Whether to emit the extracted `.html` file for this module.
1073
+ * `options.extract === true` always extracts; `false` and `"inline"` never;
1074
+ * when the option is left unspecified, extraction defaults to on for HTML
1075
+ * modules used as compilation entries — that's the HTML-as-entry-point case
1076
+ * and a linked `type: "html"` page (which is added as its own entry).
1077
+ * @param {NormalModule} module module
1078
+ * @returns {boolean} true when the `.html` file should be emitted
1079
+ */
1080
+ _shouldExtract(module) {
1081
+ const { extract } = this.options;
1082
+ if (extract === true) return true;
1083
+ if (extract === false || extract === "inline") return false;
1084
+ return this._isEntryModule(module);
1085
+ }
1086
+
1087
+ /**
1088
+ * Whether this module exposes the `html` source type. Like `_shouldExtract`,
1089
+ * but `"inline"` also exposes it — the processed HTML is read back into the
1090
+ * host attribute (e.g. `<iframe srcdoc>`) instead of emitted as a file.
1091
+ * @param {NormalModule} module module
1092
+ * @returns {boolean} true when the `html` source type is available
1093
+ */
1094
+ _shouldExposeHtmlType(module) {
1095
+ if (this.options.extract === "inline") return true;
1096
+ return this._shouldExtract(module);
1097
+ }
1098
+
1099
+ /**
1100
+ * Returns the source types available for this module.
1101
+ * @param {NormalModule} module fresh module
1102
+ * @returns {SourceTypes} available types (do not mutate)
1103
+ */
1104
+ getTypes(module) {
1105
+ if (this._shouldExposeHtmlType(module)) {
1106
+ return JAVASCRIPT_AND_HTML_TYPES;
1107
+ }
1108
+ return JAVASCRIPT_TYPES;
1109
+ }
1110
+
1111
+ /**
1112
+ * @returns {boolean} whether getTypes() depends on the module's incoming connections
1113
+ */
1114
+ getTypesDependOnIncomingConnections() {
1115
+ // A fixed extract (`true` / `false` / `"inline"`) gives a stable type set;
1116
+ // only the unset default reads `_isEntryModule` (incoming connections).
1117
+ const { extract } = this.options;
1118
+ return extract !== true && extract !== false && extract !== "inline";
1119
+ }
1120
+
1121
+ /**
1122
+ * Returns the estimated size for the requested source type.
1123
+ * @param {NormalModule} module the module
1124
+ * @param {SourceType=} type source type
1125
+ * @returns {number} estimate size of the module
1126
+ */
1127
+ getSize(module, type) {
1128
+ const originalSource = module.originalSource();
1129
+ if (!originalSource) return 0;
1130
+ if (type === HTML_TYPE) return originalSource.size();
1131
+ return originalSource.size() + 10;
1132
+ }
1133
+
1134
+ /**
1135
+ * Processes the provided module.
1136
+ * @param {Dependency} dependency the dependency to generate
1137
+ * @param {ReplaceSource} source the current replace source which can be modified
1138
+ * @param {DependencyTemplateContext} templateContext the template context (shared across all dependencies of the module)
1139
+ * @returns {void}
1140
+ */
1141
+ sourceDependency(dependency, source, templateContext) {
1142
+ const constructor =
1143
+ /** @type {DependencyConstructor} */
1144
+ (dependency.constructor);
1145
+ const template = templateContext.dependencyTemplates.get(constructor);
1146
+ if (!template) {
1147
+ throw new Error(
1148
+ `No template for dependency: ${dependency.constructor.name}`
1149
+ );
1150
+ }
1151
+
1152
+ template.apply(dependency, source, templateContext);
1153
+ }
1154
+
1155
+ /**
1156
+ * Processes the provided dependencies block.
1157
+ * @param {import("../DependenciesBlock")} block the dependencies block which will be processed
1158
+ * @param {ReplaceSource} source the current replace source which can be modified
1159
+ * @param {DependencyTemplateContext} templateContext the template context
1160
+ * @returns {void}
1161
+ */
1162
+ sourceBlock(block, source, templateContext) {
1163
+ for (const dependency of block.dependencies) {
1164
+ this.sourceDependency(dependency, source, templateContext);
1165
+ }
1166
+
1167
+ for (const childBlock of block.blocks) {
1168
+ this.sourceBlock(childBlock, source, templateContext);
1169
+ }
1170
+ }
1171
+
1172
+ /**
1173
+ * Processes the provided module.
1174
+ * @param {NormalModule} module the module to generate
1175
+ * @param {InitFragment<GenerateContext>[]} initFragments mutable list of init fragments
1176
+ * @param {ReplaceSource} source the current replace source which can be modified
1177
+ * @param {GenerateContext} generateContext the generateContext
1178
+ * @returns {void}
1179
+ */
1180
+ sourceModule(module, initFragments, source, generateContext) {
1181
+ // Only `dependency` varies across `template.apply` calls, so one context
1182
+ // (and one lazy `chunkInitFragments` getter) serves the whole module.
1183
+ /** @type {InitFragment<GenerateContext>[] | undefined} */
1184
+ let chunkInitFragments;
1185
+ /** @type {DependencyTemplateContext} */
1186
+ const templateContext = {
1187
+ runtimeTemplate: generateContext.runtimeTemplate,
1188
+ dependencyTemplates: generateContext.dependencyTemplates,
1189
+ moduleGraph: generateContext.moduleGraph,
1190
+ chunkGraph: generateContext.chunkGraph,
1191
+ module,
1192
+ runtime: generateContext.runtime,
1193
+ runtimeRequirements: generateContext.runtimeRequirements,
1194
+ concatenationScope: generateContext.concatenationScope,
1195
+ codeGenerationResults:
1196
+ /** @type {CodeGenerationResults} */
1197
+ (generateContext.codeGenerationResults),
1198
+ initFragments,
1199
+ get chunkInitFragments() {
1200
+ if (!chunkInitFragments) {
1201
+ const data =
1202
+ /** @type {NonNullable<GenerateContext["getData"]>} */
1203
+ (generateContext.getData)();
1204
+ chunkInitFragments = data.get("chunkInitFragments");
1205
+ if (!chunkInitFragments) {
1206
+ chunkInitFragments = [];
1207
+ data.set("chunkInitFragments", chunkInitFragments);
1208
+ }
1209
+ }
1210
+
1211
+ return chunkInitFragments;
1212
+ }
1213
+ };
1214
+
1215
+ for (const dependency of module.dependencies) {
1216
+ this.sourceDependency(dependency, source, templateContext);
1217
+ }
1218
+
1219
+ if (module.presentationalDependencies !== undefined) {
1220
+ for (const dependency of module.presentationalDependencies) {
1221
+ this.sourceDependency(dependency, source, templateContext);
1222
+ }
1223
+ }
1224
+
1225
+ for (const childBlock of module.blocks) {
1226
+ this.sourceBlock(childBlock, source, templateContext);
1227
+ }
1228
+ }
1229
+
1230
+ /**
1231
+ * Run all HTML dependency templates against the original module source and
1232
+ * return the rewritten HTML. When `undoPath` is a string, `[webpack/auto]`
1233
+ * placeholders left in by asset/url dependencies are resolved to that
1234
+ * undo path (use `""` to make URLs root-relative). When `undoPath` is
1235
+ * `undefined`, the placeholders are preserved so the caller (typically
1236
+ * `HtmlModulesPlugin#renderManifest`, which only knows the final
1237
+ * `.html` filename after code generation) can resolve them itself.
1238
+ * @param {NormalModule} module the module to render
1239
+ * @param {GenerateContext} generateContext the generate context
1240
+ * @param {string=} undoPath value to substitute for `[webpack/auto]` placeholders
1241
+ * @returns {string} the rewritten HTML
1242
+ */
1243
+ _renderHtml(module, generateContext, undoPath) {
1244
+ // The dependency-template pass is identical for both type passes (no
1245
+ // template branches on `type` or writes `runtimeRequirements`), so
1246
+ // compute the raw render once per `codeGeneration()` and reuse it; the
1247
+ // passes diverge only in the `[webpack/auto]` substitution below.
1248
+ const cacheKey = generateContext.runtimeRequirements;
1249
+ let rawContent = this._rawRenderCache.get(cacheKey);
1250
+ if (rawContent === undefined) {
1251
+ const originalSource = /** @type {Source} */ (module.originalSource());
1252
+ const source = new ReplaceSource(originalSource);
1253
+ /** @type {InitFragment<GenerateContext>[]} */
1254
+ const initFragments = [];
1255
+
1256
+ this.sourceModule(module, initFragments, source, generateContext);
1257
+ rawContent = /** @type {string} */ (source.source());
1258
+ this._rawRenderCache.set(cacheKey, rawContent);
1259
+ }
1260
+
1261
+ if (undoPath === undefined) {
1262
+ // HTML output — leave sentinels and `[webpack/auto]` for renderManifest.
1263
+ return rawContent;
1264
+ }
1265
+
1266
+ // JS-export path — resolve `[webpack/auto]` inline; chunk-URL sentinels
1267
+ // stay for `HtmlModulesPlugin`'s `JavascriptModulesPlugin.render` tap.
1268
+ if (!rawContent.includes(PUBLIC_PATH_AUTO)) return rawContent;
1269
+ // A relative `<base href>` prepends `../`s so the base can't misdirect
1270
+ // the rewritten URLs (see `HtmlParser`).
1271
+ const basePrefix =
1272
+ /** @type {HtmlModuleBuildInfo} */ (module.buildInfo).baseUrlPrefix || "";
1273
+ return rawContent.split(PUBLIC_PATH_AUTO).join(basePrefix + undoPath);
1274
+ }
1275
+
1276
+ /**
1277
+ * Generates generated code for this runtime module.
1278
+ * @param {NormalModule} module module for which the code should be generated
1279
+ * @param {GenerateContext} generateContext context for generate
1280
+ * @returns {Source | null} generated code
1281
+ */
1282
+ generate(module, generateContext) {
1283
+ const originalSource = module.originalSource();
1284
+
1285
+ if (!originalSource) {
1286
+ return new RawSource("");
1287
+ }
1288
+
1289
+ if (generateContext.type === HTML_TYPE) {
1290
+ // Preserve `[webpack/auto]`; renderManifest resolves it once `.html` filename is known.
1291
+ return new RawSource(
1292
+ this._renderHtml(module, generateContext, undefined)
1293
+ );
1294
+ }
1295
+
1296
+ // JS export: resolve `[webpack/auto]` to root-relative URLs.
1297
+ const generated = this._renderHtml(module, generateContext, "");
1298
+
1299
+ /** @type {string} */
1300
+ let sourceContent;
1301
+ // `module.hot` is set by `HotModuleReplacementPlugin` on every module
1302
+ // when HMR is enabled. When set, we cannot use the concatenation path
1303
+ // (it merges into a parent's module scope, where `module.hot.accept`
1304
+ // would target the wrong id) — `getConcatenationBailoutReason` keeps
1305
+ // us out of concatenation in that case.
1306
+ if (generateContext.concatenationScope && !module.hot) {
1307
+ generateContext.concatenationScope.registerNamespaceExport(
1308
+ ConcatenationScope.NAMESPACE_OBJECT_EXPORT
1309
+ );
1310
+ sourceContent = `${generateContext.runtimeTemplate.renderConst()} ${
1311
+ ConcatenationScope.NAMESPACE_OBJECT_EXPORT
1312
+ } = ${JSON.stringify(generated)};`;
1313
+ } else {
1314
+ generateContext.runtimeRequirements.add(RuntimeGlobals.module);
1315
+ if (module.hot) {
1316
+ sourceContent = this._renderHmrShim(
1317
+ module,
1318
+ generated,
1319
+ this._shouldExtract(module),
1320
+ generateContext.runtimeTemplate
1321
+ );
1322
+ } else {
1323
+ sourceContent = `${module.moduleArgument}.exports = ${JSON.stringify(
1324
+ generated
1325
+ )};`;
1326
+ }
1327
+ }
1328
+
1329
+ return new RawSource(sourceContent);
1330
+ }
1331
+
1332
+ /**
1333
+ * Emits the JS shim with HMR self-acceptance. When `extracting` is true the
1334
+ * HTML module is also the document the browser is viewing, so the shim
1335
+ * additionally patches `document.body` and `document.title` on every hot
1336
+ * update so the rendered page reflects the new HTML without a full
1337
+ * reload. The patching guard `module.hot.data` ensures the body is only
1338
+ * replaced on a re-evaluation after a hot update — never on the initial
1339
+ * page load, where `document.body` already matches the extracted HTML.
1340
+ *
1341
+ * The runtime extracts the body / title / head-sans-title sections from
1342
+ * the HTML with regexes. HTML comments are *masked* first — their
1343
+ * characters replaced with spaces, preserving length — via a `<!--…-->`
1344
+ * regex, so a `<body>` (or `</body>` / `<title>` / etc.) that appears
1345
+ * inside a comment can't fool the tag regexes — that was the one
1346
+ * well-known sharp edge of HTML+regex. Because masking keeps offsets
1347
+ * stable, the body / title content is sliced back out of the *original*
1348
+ * HTML, so real comments inside `<body>` survive into the patched DOM
1349
+ * exactly as a full page reload would render them.
1350
+ *
1351
+ * `<head>` changes beyond `<title>` (a new `<meta>`, a swapped
1352
+ * `<link rel=icon>`, an inline `<style>` block, …) can't be safely
1353
+ * DOM-patched: webpack injects its own runtime scripts and stylesheet
1354
+ * links into the head on initial load, and blindly replacing
1355
+ * `document.head.innerHTML` would tear them down. So the shim falls
1356
+ * back to a full reload — fine in a dev-server context because the
1357
+ * regular (non-hot-update) `page.html` chunk is re-emitted on every
1358
+ * rebuild, so the reloaded page picks up the new head.
1359
+ * @param {NormalModule} module module
1360
+ * @param {string} html the rewritten HTML content (with placeholders resolved)
1361
+ * @param {boolean} extracting whether the HTML module is being extracted as a real `.html` file
1362
+ * @param {RuntimeTemplate} runtimeTemplate runtime template (drives `const`/arrow emission based on environment support)
1363
+ * @returns {string} JS shim source
1364
+ */
1365
+ _renderHmrShim(module, html, extracting, runtimeTemplate) {
1366
+ const declare = runtimeTemplate.renderConst();
1367
+ const acceptBlock = extracting
1368
+ ? [
1369
+ "module.hot.accept();",
1370
+ // Mask `<!-- … -->` comments — replace their characters
1371
+ // with spaces, preserving length — before any tag regex
1372
+ // runs. Masking (rather than deleting) keeps string offsets
1373
+ // stable, so the body/title content can be sliced back out
1374
+ // of the original HTML with comments intact, while a
1375
+ // `<body>`/`</body>`/`<title>` inside a comment can no
1376
+ // longer fool the tag regexes (the non-greedy `*?` would
1377
+ // otherwise stop at the FIRST `</body>` it sees, even one
1378
+ // inside a comment).
1379
+ `${declare} __webpack_mask_comments__ = ${runtimeTemplate.returningFunction(
1380
+ `h.replace(/<!--[\\s\\S]*?-->/g, ${runtimeTemplate.returningFunction(
1381
+ 'c.replace(/[^\\n]/g, " ")',
1382
+ "c"
1383
+ )})`,
1384
+ "h"
1385
+ )};`,
1386
+ // Mask comments once per evaluation; reused for every
1387
+ // tag-boundary search (head/body/title and the dispose-time
1388
+ // head diff) so a large page isn't re-scanned per section.
1389
+ `${declare} __webpack_masked_html__ = __webpack_mask_comments__(__webpack_html__);`,
1390
+ // Slice the inner content of `<tag>…</tag>` out of the original
1391
+ // HTML, using the pre-masked copy to locate the tag boundaries.
1392
+ `${declare} __webpack_extract__ = ${runtimeTemplate.basicFunction(
1393
+ "tag",
1394
+ [
1395
+ `${declare} open = new RegExp("<" + tag + "[^>]*>", "i").exec(__webpack_masked_html__);`,
1396
+ "if (!open) return null;",
1397
+ `${declare} start = open.index + open[0].length;`,
1398
+ `${declare} close = new RegExp("</" + tag + ">", "i").exec(__webpack_masked_html__.slice(start));`,
1399
+ "if (!close) return null;",
1400
+ "return __webpack_html__.slice(start, start + close.index);"
1401
+ ]
1402
+ )};`,
1403
+ `${declare} __webpack_extract_head__ = ${runtimeTemplate.basicFunction(
1404
+ "",
1405
+ [
1406
+ // Mask only the small extracted head so a comment-only head
1407
+ // edit doesn't force a full reload.
1408
+ `${declare} head = __webpack_extract__("head");`,
1409
+ 'return head === null ? "" : __webpack_mask_comments__(head).replace(/<title[^>]*>[\\s\\S]*?<\\/title>/i, "").trim();'
1410
+ ]
1411
+ )};`,
1412
+ "if (module.hot.data && typeof document !== 'undefined') {",
1413
+ Template.indent([
1414
+ `${declare} __webpack_new_head__ = __webpack_extract_head__();`,
1415
+ "if (module.hot.data.__webpack_head__ !== undefined && __webpack_new_head__ !== module.hot.data.__webpack_head__ && typeof window !== 'undefined' && window.location && typeof window.location.reload === 'function') {",
1416
+ Template.indent("window.location.reload();"),
1417
+ "} else {",
1418
+ Template.indent([
1419
+ `${declare} __webpack_body__ = __webpack_extract__("body");`,
1420
+ "if (__webpack_body__ !== null && document.body) document.body.innerHTML = __webpack_body__;",
1421
+ `${declare} __webpack_title__ = __webpack_extract__("title");`,
1422
+ "if (__webpack_title__ !== null) document.title = __webpack_title__;"
1423
+ ]),
1424
+ "}"
1425
+ ]),
1426
+ "}",
1427
+ // Capture this evaluation's head (sans title, comments
1428
+ // masked) on dispose so the next module instance can diff
1429
+ // against it.
1430
+ `module.hot.dispose(${runtimeTemplate.basicFunction(
1431
+ "data",
1432
+ "data.__webpack_head__ = __webpack_extract_head__();"
1433
+ )});`
1434
+ ]
1435
+ : ["module.hot.accept();"];
1436
+ return Template.asString([
1437
+ `${declare} __webpack_html__ = ${JSON.stringify(html)};`,
1438
+ `${module.moduleArgument}.exports = __webpack_html__;`,
1439
+ "if (module.hot) {",
1440
+ Template.indent(acceptBlock),
1441
+ "}"
1442
+ ]);
1443
+ }
1444
+
1445
+ /**
1446
+ * Generates fallback output for the provided error condition.
1447
+ * @param {Error} error the error
1448
+ * @param {NormalModule} module module for which the code should be generated
1449
+ * @param {GenerateContext} generateContext context for generate
1450
+ * @returns {Source | null} generated code
1451
+ */
1452
+ generateError(error, module, generateContext) {
1453
+ if (generateContext.type === HTML_TYPE) {
1454
+ // Strip `<`, `>`, `--` runs from `error.message` so it can't escape the comment.
1455
+ const safe = String(error.message)
1456
+ .replace(/[<>]/g, "")
1457
+ .replace(/-{2,}/g, (m) => `${"-".repeat(m.length - 1)} `);
1458
+ return new RawSource(`<!-- webpack error: ${safe} -->`);
1459
+ }
1460
+ return new RawSource(`throw new Error(${JSON.stringify(error.message)});`);
1461
+ }
1462
+
1463
+ /**
1464
+ * Updates the hash with the data contributed by this instance.
1465
+ * @param {Hash} hash hash that will be modified
1466
+ * @param {UpdateHashContext} updateHashContext context for updating hash
1467
+ */
1468
+ updateHash(hash, updateHashContext) {
1469
+ hash.update("html");
1470
+ // Source-type set changes when html-type exposure flips; the HMR shim's
1471
+ // `extracting` branch changes when the emit decision flips. They differ
1472
+ // only for `"inline"` (exposes html, but does not emit), so hash both.
1473
+ // One `_shouldExtract` walk covers both checks (expose = extract ∪ inline).
1474
+ const extract = this._shouldExtract(updateHashContext.module);
1475
+ if (extract || this.options.extract === "inline") {
1476
+ hash.update("html-type");
1477
+ }
1478
+ if (extract) {
1479
+ hash.update("extract");
1480
+ }
1481
+ // The HMR shim emits additional self-accept / DOM-patch code that
1482
+ // isn't emitted in non-HMR builds, so the cached codegen must
1483
+ // invalidate when `module.hot` toggles.
1484
+ if (updateHashContext.module.hot) {
1485
+ hash.update("hot");
1486
+ }
1487
+ }
1488
+ }
1489
+
1490
+ module.exports = HtmlGenerator;