webpack 5.107.2 → 5.108.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 (357) hide show
  1. package/hot/dev-server.js +2 -0
  2. package/lib/APIPlugin.js +8 -4
  3. package/lib/CacheFacade.js +7 -0
  4. package/lib/Chunk.js +4 -0
  5. package/lib/ChunkGraph.js +30 -9
  6. package/lib/CircularModulesPlugin.js +190 -0
  7. package/lib/CleanPlugin.js +2 -1
  8. package/lib/Compilation.js +396 -65
  9. package/lib/Compiler.js +25 -11
  10. package/lib/ConcatenationScope.js +10 -3
  11. package/lib/ContextExclusionPlugin.js +1 -0
  12. package/lib/ContextModule.js +92 -47
  13. package/lib/ContextReplacementPlugin.js +4 -0
  14. package/lib/DefinePlugin.js +89 -15
  15. package/lib/Dependency.js +111 -7
  16. package/lib/EntryOptionPlugin.js +39 -2
  17. package/lib/EntryPlugin.js +2 -0
  18. package/lib/ExportsInfo.js +314 -73
  19. package/lib/ExternalModule.js +82 -34
  20. package/lib/ExternalModuleFactoryPlugin.js +1 -0
  21. package/lib/ExternalsPlugin.js +1 -0
  22. package/lib/FileSystemInfo.js +173 -23
  23. package/lib/FlagAllModulesAsUsedPlugin.js +1 -5
  24. package/lib/FlagDependencyExportsPlugin.js +23 -0
  25. package/lib/FlagDependencyUsagePlugin.js +87 -5
  26. package/lib/FlagEntryExportAsUsedPlugin.js +2 -0
  27. package/lib/Generator.js +8 -0
  28. package/lib/HotModuleReplacementPlugin.js +65 -28
  29. package/lib/IgnorePlugin.js +1 -0
  30. package/lib/InitFragment.js +5 -0
  31. package/lib/JavascriptMetaInfoPlugin.js +7 -5
  32. package/lib/LazyBarrel.js +361 -0
  33. package/lib/LoaderTargetPlugin.js +1 -0
  34. package/lib/Module.js +21 -42
  35. package/lib/ModuleGraph.js +3 -2
  36. package/lib/ModuleProfile.js +27 -1
  37. package/lib/ModuleTemplate.js +2 -0
  38. package/lib/MultiCompiler.js +2 -0
  39. package/lib/MultiStats.js +1 -0
  40. package/lib/MultiWatching.js +2 -0
  41. package/lib/NodeStuffPlugin.js +22 -17
  42. package/lib/NormalModule.js +142 -80
  43. package/lib/NormalModuleReplacementPlugin.js +2 -0
  44. package/lib/PrefetchPlugin.js +2 -0
  45. package/lib/ProgressPlugin.js +8 -0
  46. package/lib/ProvidePlugin.js +1 -0
  47. package/lib/RawModule.js +20 -16
  48. package/lib/RecordIdsPlugin.js +1 -0
  49. package/lib/RuntimeGlobals.js +5 -0
  50. package/lib/RuntimePlugin.js +58 -26
  51. package/lib/RuntimeTemplate.js +278 -21
  52. package/lib/SelfModuleFactory.js +1 -0
  53. package/lib/SourceMapDevToolPlugin.js +3 -5
  54. package/lib/Stats.js +1 -0
  55. package/lib/Template.js +8 -2
  56. package/lib/TemplatedPathPlugin.js +473 -131
  57. package/lib/WarnCaseSensitiveModulesPlugin.js +1 -0
  58. package/lib/WarnDeprecatedOptionPlugin.js +4 -0
  59. package/lib/WarnNoModeSetPlugin.js +1 -0
  60. package/lib/WatchIgnorePlugin.js +1 -0
  61. package/lib/Watching.js +9 -0
  62. package/lib/WebpackOptionsApply.js +50 -5
  63. package/lib/asset/AssetBytesGenerator.js +11 -3
  64. package/lib/asset/AssetGenerator.js +47 -22
  65. package/lib/asset/AssetModule.js +47 -0
  66. package/lib/asset/AssetModulesPlugin.js +14 -14
  67. package/lib/asset/AssetParser.js +2 -2
  68. package/lib/asset/AssetSourceGenerator.js +8 -0
  69. package/lib/asset/RawDataUrlModule.js +12 -13
  70. package/lib/buildChunkGraph.js +64 -7
  71. package/lib/bun/BunTargetPlugin.js +48 -0
  72. package/lib/cache/AddBuildDependenciesPlugin.js +1 -0
  73. package/lib/cache/AddManagedPathsPlugin.js +3 -0
  74. package/lib/cache/IdleFileCachePlugin.js +4 -0
  75. package/lib/cache/MemoryWithGcCachePlugin.js +1 -0
  76. package/lib/cache/PackFileCacheStrategy.js +1 -0
  77. package/lib/cache/ResolverCachePlugin.js +2 -0
  78. package/lib/cache/mergeEtags.js +2 -0
  79. package/lib/cli.js +109 -19
  80. package/lib/config/browserslistTargetHandler.js +99 -0
  81. package/lib/config/defaults.js +147 -7
  82. package/lib/config/defineConfig.js +31 -0
  83. package/lib/config/normalization.js +5 -0
  84. package/lib/config/target.js +181 -2
  85. package/lib/container/ContainerEntryModule.js +15 -14
  86. package/lib/container/ContainerExposedDependency.js +2 -2
  87. package/lib/container/ContainerReferencePlugin.js +1 -1
  88. package/lib/container/FallbackDependency.js +5 -7
  89. package/lib/container/FallbackModule.js +10 -9
  90. package/lib/container/RemoteModule.js +20 -10
  91. package/lib/container/RemoteRuntimeModule.js +14 -12
  92. package/lib/css/CssGenerator.js +353 -327
  93. package/lib/css/CssInjectStyleRuntimeModule.js +36 -8
  94. package/lib/css/CssLoadingRuntimeModule.js +118 -47
  95. package/lib/css/CssModule.js +52 -23
  96. package/lib/css/CssModulesPlugin.js +107 -124
  97. package/lib/css/CssParser.js +2759 -2205
  98. package/lib/css/syntax.js +2859 -0
  99. package/lib/debug/ProfilingPlugin.js +2 -0
  100. package/lib/deno/DenoTargetPlugin.js +47 -0
  101. package/lib/dependencies/AMDDefineDependency.js +22 -17
  102. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +1 -0
  103. package/lib/dependencies/AMDRequireArrayDependency.js +7 -11
  104. package/lib/dependencies/AMDRequireContextDependency.js +7 -11
  105. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +1 -0
  106. package/lib/dependencies/AMDRequireDependency.js +24 -20
  107. package/lib/dependencies/CachedConstDependency.js +3 -0
  108. package/lib/dependencies/CommonJsDependencyHelpers.js +1 -0
  109. package/lib/dependencies/CommonJsExportRequireDependency.js +79 -31
  110. package/lib/dependencies/CommonJsExportsDependency.js +21 -16
  111. package/lib/dependencies/CommonJsExportsParserPlugin.js +230 -7
  112. package/lib/dependencies/CommonJsFullRequireDependency.js +27 -19
  113. package/lib/dependencies/CommonJsImportsParserPlugin.js +51 -16
  114. package/lib/dependencies/CommonJsPlugin.js +1 -1
  115. package/lib/dependencies/CommonJsRequireContextDependency.js +10 -13
  116. package/lib/dependencies/CommonJsRequireDependency.js +42 -11
  117. package/lib/dependencies/CommonJsSelfReferenceDependency.js +22 -14
  118. package/lib/dependencies/ConstDependency.js +16 -11
  119. package/lib/dependencies/ContextDependency.js +4 -0
  120. package/lib/dependencies/ContextDependencyTemplateAsId.js +1 -1
  121. package/lib/dependencies/ContextElementDependency.js +23 -14
  122. package/lib/dependencies/CreateRequireParserPlugin.js +1 -0
  123. package/lib/dependencies/CreateScriptUrlDependency.js +5 -7
  124. package/lib/dependencies/CriticalDependencyWarning.js +1 -0
  125. package/lib/dependencies/CssIcssExportDependency.js +512 -574
  126. package/lib/dependencies/CssIcssImportDependency.js +9 -9
  127. package/lib/dependencies/CssIcssSymbolDependency.js +22 -15
  128. package/lib/dependencies/CssImportDependency.js +25 -1
  129. package/lib/dependencies/CssUrlDependency.js +23 -14
  130. package/lib/dependencies/DllEntryDependency.js +9 -13
  131. package/lib/dependencies/ExportBindingInitFragment.js +164 -0
  132. package/lib/dependencies/ExportsInfoDependency.js +12 -12
  133. package/lib/dependencies/ExternalModuleDependency.js +8 -5
  134. package/lib/dependencies/ExternalModuleInitFragment.js +7 -5
  135. package/lib/dependencies/ExternalModuleInitFragmentDependency.js +13 -10
  136. package/lib/dependencies/HarmonyAcceptDependency.js +11 -11
  137. package/lib/dependencies/HarmonyAcceptImportDependency.js +1 -0
  138. package/lib/dependencies/HarmonyDetectionParserPlugin.js +47 -22
  139. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +28 -2
  140. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +46 -22
  141. package/lib/dependencies/HarmonyExportExpressionDependency.js +107 -30
  142. package/lib/dependencies/HarmonyExportHeaderDependency.js +7 -9
  143. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +109 -31
  144. package/lib/dependencies/HarmonyExportInitFragment.js +18 -15
  145. package/lib/dependencies/HarmonyExportSpecifierDependency.js +83 -18
  146. package/lib/dependencies/HarmonyExports.js +4 -1
  147. package/lib/dependencies/HarmonyImportDependency.js +24 -0
  148. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +110 -74
  149. package/lib/dependencies/HarmonyImportGuard.js +254 -0
  150. package/lib/dependencies/HarmonyImportSideEffectDependency.js +18 -1
  151. package/lib/dependencies/HarmonyImportSpecifierDependency.js +118 -14
  152. package/lib/dependencies/HarmonyLinkingError.js +1 -0
  153. package/lib/dependencies/HarmonyModulesPlugin.js +1 -0
  154. package/lib/dependencies/{HtmlScriptSrcDependency.js → HtmlEntryDependency.js} +261 -109
  155. package/lib/dependencies/HtmlInlineHtmlDependency.js +107 -0
  156. package/lib/dependencies/HtmlInlineScriptDependency.js +17 -13
  157. package/lib/dependencies/HtmlInlineStyleDependency.js +45 -11
  158. package/lib/dependencies/ImportContextDependency.js +5 -9
  159. package/lib/dependencies/ImportDependency.js +44 -2
  160. package/lib/dependencies/ImportMetaHotAcceptDependency.js +1 -0
  161. package/lib/dependencies/ImportMetaHotDeclineDependency.js +1 -0
  162. package/lib/dependencies/ImportMetaPlugin.js +74 -30
  163. package/lib/dependencies/ImportParserPlugin.js +19 -0
  164. package/lib/dependencies/ImportWeakDependency.js +1 -0
  165. package/lib/dependencies/JsonExportsDependency.js +9 -9
  166. package/lib/dependencies/LoaderImportDependency.js +1 -0
  167. package/lib/dependencies/LocalModule.js +11 -12
  168. package/lib/dependencies/LocalModuleDependency.js +11 -13
  169. package/lib/dependencies/ModuleDecoratorDependency.js +9 -9
  170. package/lib/dependencies/ModuleDependency.js +7 -0
  171. package/lib/dependencies/ModuleHotAcceptDependency.js +1 -0
  172. package/lib/dependencies/ModuleHotDeclineDependency.js +1 -0
  173. package/lib/dependencies/ModuleInitFragmentDependency.js +15 -11
  174. package/lib/dependencies/ProvidedDependency.js +31 -27
  175. package/lib/dependencies/PureExpressionDependency.js +7 -9
  176. package/lib/dependencies/RequireEnsureDependency.js +12 -13
  177. package/lib/dependencies/RequireHeaderDependency.js +3 -4
  178. package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +3 -0
  179. package/lib/dependencies/RequireResolveContextDependency.js +7 -11
  180. package/lib/dependencies/RequireResolveDependency.js +1 -0
  181. package/lib/dependencies/RequireResolveHeaderDependency.js +3 -5
  182. package/lib/dependencies/RuntimeRequirementsDependency.js +6 -7
  183. package/lib/dependencies/StaticExportsDependency.js +10 -10
  184. package/lib/dependencies/SystemPlugin.js +2 -0
  185. package/lib/dependencies/URLContextDependency.js +5 -7
  186. package/lib/dependencies/URLDependency.js +14 -16
  187. package/lib/dependencies/UnsupportedDependency.js +8 -13
  188. package/lib/dependencies/WebAssemblyExportImportedDependency.js +11 -16
  189. package/lib/dependencies/WebAssemblyImportDependency.js +14 -16
  190. package/lib/dependencies/WebpackIsIncludedDependency.js +1 -0
  191. package/lib/dependencies/WorkerDependency.js +19 -8
  192. package/lib/dependencies/WorkerPlugin.js +22 -6
  193. package/lib/dependencies/processExportInfo.js +13 -11
  194. package/lib/dll/DelegatedModule.js +29 -15
  195. package/lib/dll/DelegatedModuleFactoryPlugin.js +1 -0
  196. package/lib/dll/DelegatedPlugin.js +1 -0
  197. package/lib/dll/DllEntryPlugin.js +3 -0
  198. package/lib/dll/DllModule.js +3 -2
  199. package/lib/dll/DllPlugin.js +16 -0
  200. package/lib/dll/DllReferencePlugin.js +3 -0
  201. package/lib/dll/LibManifestPlugin.js +1 -0
  202. package/lib/electron/ElectronTargetPlugin.js +22 -4
  203. package/lib/errors/ConcurrentCompilationError.js +1 -0
  204. package/lib/errors/HookWebpackError.js +11 -13
  205. package/lib/errors/IgnoreErrorModuleFactory.js +1 -0
  206. package/lib/errors/InvalidDependenciesModuleWarning.js +2 -0
  207. package/lib/errors/JSONParseError.js +9 -8
  208. package/lib/errors/ModuleBuildError.js +16 -13
  209. package/lib/errors/ModuleDependencyError.js +8 -1
  210. package/lib/errors/ModuleDependencyWarning.js +8 -1
  211. package/lib/errors/ModuleError.js +5 -11
  212. package/lib/errors/ModuleHashingError.js +4 -0
  213. package/lib/errors/ModuleNotFoundError.js +3 -0
  214. package/lib/errors/ModuleParseError.js +5 -11
  215. package/lib/errors/ModuleRestoreError.js +2 -0
  216. package/lib/errors/ModuleStoreError.js +3 -0
  217. package/lib/errors/ModuleWarning.js +7 -11
  218. package/lib/errors/NodeStuffInWebError.js +1 -0
  219. package/lib/errors/NonErrorEmittedError.js +2 -0
  220. package/lib/errors/UnhandledSchemeError.js +1 -0
  221. package/lib/esm/ModuleChunkLoadingPlugin.js +0 -1
  222. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +28 -23
  223. package/lib/hmr/HotModuleReplacement.runtime.js +175 -30
  224. package/lib/hmr/HotModuleReplacementRuntimeModule.js +7 -0
  225. package/lib/hmr/JavascriptHotModuleReplacement.runtime.js +173 -26
  226. package/lib/hmr/LazyCompilationPlugin.js +30 -6
  227. package/lib/html/HtmlGenerator.js +217 -23
  228. package/lib/html/HtmlModule.js +40 -0
  229. package/lib/html/HtmlModulesPlugin.js +219 -55
  230. package/lib/html/HtmlParser.js +1108 -1099
  231. package/lib/html/{walkHtmlTokens.js → syntax.js} +4701 -212
  232. package/lib/ids/IdHelpers.js +4 -2
  233. package/lib/index.js +19 -0
  234. package/lib/javascript/BasicEvaluatedExpression.js +1 -0
  235. package/lib/javascript/EnableChunkLoadingPlugin.js +1 -0
  236. package/lib/javascript/JavascriptGenerator.js +6 -2
  237. package/lib/javascript/JavascriptModule.js +54 -0
  238. package/lib/javascript/JavascriptModulesPlugin.js +257 -102
  239. package/lib/javascript/JavascriptParser.js +285 -158
  240. package/lib/json/JsonModule.js +40 -0
  241. package/lib/json/JsonModulesPlugin.js +7 -0
  242. package/lib/json/JsonParser.js +4 -2
  243. package/lib/library/AssignLibraryPlugin.js +5 -3
  244. package/lib/library/ExportPropertyLibraryPlugin.js +1 -0
  245. package/lib/library/FalseIIFEUmdWarning.js +1 -0
  246. package/lib/library/ModuleLibraryPlugin.js +24 -5
  247. package/lib/library/SystemLibraryPlugin.js +3 -3
  248. package/lib/node/NodeTargetPlugin.js +1 -0
  249. package/lib/node/NodeWatchFileSystem.js +1 -0
  250. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +10 -9
  251. package/lib/node/RequireChunkLoadingRuntimeModule.js +18 -16
  252. package/lib/optimize/ConcatenatedModule.js +395 -77
  253. package/lib/optimize/ConstExportsPlugin.js +211 -0
  254. package/lib/optimize/InlineExports.js +178 -0
  255. package/lib/optimize/InnerGraph.js +372 -275
  256. package/lib/optimize/InnerGraphPlugin.js +196 -99
  257. package/lib/optimize/ModuleConcatenationPlugin.js +56 -25
  258. package/lib/optimize/RealContentHashPlugin.js +14 -1
  259. package/lib/optimize/SideEffectsFlagPlugin.js +234 -64
  260. package/lib/runtime/AsyncModuleRuntimeModule.js +32 -30
  261. package/lib/runtime/AutoPublicPathRuntimeModule.js +11 -5
  262. package/lib/runtime/CompatGetDefaultExportRuntimeModule.js +1 -1
  263. package/lib/runtime/CreateFakeNamespaceObjectRuntimeModule.js +6 -4
  264. package/lib/runtime/DefinePropertyGettersRuntimeModule.js +33 -4
  265. package/lib/runtime/GetChunkFilenameRuntimeModule.js +82 -3
  266. package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +1 -1
  267. package/lib/runtime/HasOwnPropertyRuntimeModule.js +1 -1
  268. package/lib/runtime/LoadScriptRuntimeModule.js +18 -13
  269. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +39 -26
  270. package/lib/runtime/MakeNamespaceObjectRuntimeModule.js +1 -1
  271. package/lib/runtime/OnChunksLoadedRuntimeModule.js +4 -4
  272. package/lib/runtime/RelativeUrlRuntimeModule.js +3 -2
  273. package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +1 -1
  274. package/lib/runtime/StartupEntrypointRuntimeModule.js +4 -3
  275. package/lib/runtime/WorkerRuntimeModule.js +33 -0
  276. package/lib/schemes/HttpUriPlugin.js +3 -2
  277. package/lib/serialization/AggregateErrorSerializer.js +7 -6
  278. package/lib/serialization/ArraySerializer.js +4 -8
  279. package/lib/serialization/BinaryMiddleware.js +538 -468
  280. package/lib/serialization/DateObjectSerializer.js +2 -2
  281. package/lib/serialization/ErrorObjectSerializer.js +7 -6
  282. package/lib/serialization/MapObjectSerializer.js +5 -9
  283. package/lib/serialization/NullPrototypeObjectSerializer.js +7 -9
  284. package/lib/serialization/ObjectMiddleware.js +50 -13
  285. package/lib/serialization/PlainObjectSerializer.js +9 -8
  286. package/lib/serialization/RegExpObjectSerializer.js +2 -2
  287. package/lib/serialization/Serializer.js +1 -0
  288. package/lib/serialization/SetObjectSerializer.js +4 -8
  289. package/lib/sharing/ConsumeSharedModule.js +6 -7
  290. package/lib/sharing/ConsumeSharedPlugin.js +1 -0
  291. package/lib/sharing/ConsumeSharedRuntimeModule.js +46 -41
  292. package/lib/sharing/ProvideSharedDependency.js +30 -15
  293. package/lib/sharing/ProvideSharedModule.js +30 -11
  294. package/lib/sharing/ProvideSharedPlugin.js +4 -2
  295. package/lib/sharing/SharePlugin.js +3 -0
  296. package/lib/sharing/ShareRuntimeModule.js +18 -16
  297. package/lib/sharing/resolveMatchedConfigs.js +2 -1
  298. package/lib/sharing/utils.js +1 -1
  299. package/lib/stats/DefaultStatsFactoryPlugin.js +4 -6
  300. package/lib/stats/DefaultStatsPrinterPlugin.js +14 -14
  301. package/lib/stats/StatsFactory.js +11 -9
  302. package/lib/stats/StatsPrinter.js +9 -2
  303. package/lib/url/URLParserPlugin.js +5 -2
  304. package/lib/util/AsyncQueue.js +10 -0
  305. package/lib/util/LazyBucketSortedSet.js +5 -0
  306. package/lib/util/LazySet.js +6 -4
  307. package/lib/util/LocConverter.js +11 -1
  308. package/lib/util/Semaphore.js +1 -0
  309. package/lib/util/SourceProcessor.js +106 -0
  310. package/lib/util/TupleSet.js +1 -0
  311. package/lib/util/WeakTupleMap.js +27 -1
  312. package/lib/util/chainedImports.js +3 -3
  313. package/lib/util/comparators.js +2 -2
  314. package/lib/util/concatenate.js +31 -7
  315. package/lib/util/createHash.js +0 -1
  316. package/lib/util/deterministicGrouping.js +19 -12
  317. package/lib/util/extractSourceMap.js +1 -1
  318. package/lib/util/findGraphRoots.js +2 -0
  319. package/lib/util/fs.js +10 -5
  320. package/lib/util/hash/DebugHash.js +1 -0
  321. package/lib/util/hash/hash-digest.js +24 -15
  322. package/lib/util/identifier.js +7 -0
  323. package/lib/util/internalSerializables.js +11 -2
  324. package/lib/util/magicComment.js +42 -0
  325. package/lib/util/makeSerializable.js +1 -0
  326. package/lib/util/nonNumericOnlyHash.js +30 -1
  327. package/lib/util/property.js +7 -1
  328. package/lib/util/publicPathPlaceholder.js +64 -0
  329. package/lib/util/registerExternalSerializer.js +4 -4
  330. package/lib/wasm-async/AsyncWasmModule.js +77 -0
  331. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +1 -1
  332. package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +1 -96
  333. package/lib/wasm-async/AsyncWebAssemblyParser.js +1 -1
  334. package/lib/wasm-async/UniversalCompileAsyncWasmPlugin.js +1 -1
  335. package/lib/wasm-sync/SyncWasmModule.js +39 -0
  336. package/lib/wasm-sync/UnsupportedWebAssemblyFeatureError.js +1 -0
  337. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +6 -3
  338. package/lib/wasm-sync/WasmFinalizeExportsPlugin.js +2 -1
  339. package/lib/wasm-sync/WebAssemblyGenerator.js +1 -0
  340. package/lib/wasm-sync/WebAssemblyInInitialChunkError.js +2 -0
  341. package/lib/wasm-sync/WebAssemblyModulesPlugin.js +10 -0
  342. package/lib/wasm-sync/WebAssemblyParser.js +7 -3
  343. package/lib/web/JsonpChunkLoadingRuntimeModule.js +45 -39
  344. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +11 -10
  345. package/package.json +35 -27
  346. package/schemas/WebpackOptions.check.js +1 -1
  347. package/schemas/WebpackOptions.json +212 -3
  348. package/schemas/plugins/HtmlGeneratorOptions.check.js +1 -1
  349. package/schemas/plugins/HtmlParserOptions.check.d.ts +7 -0
  350. package/schemas/plugins/HtmlParserOptions.check.js +6 -0
  351. package/schemas/plugins/HtmlParserOptions.json +3 -0
  352. package/schemas/plugins/css/CssAutoOrModuleParserOptions.check.js +1 -1
  353. package/schemas/plugins/css/CssModuleParserOptions.check.js +1 -1
  354. package/schemas/plugins/css/CssParserOptions.check.js +1 -1
  355. package/types.d.ts +1456 -290
  356. package/lib/css/walkCssTokens.js +0 -2020
  357. package/lib/util/AppendOnlyStackedSet.js +0 -93
@@ -20,21 +20,28 @@ const ModuleDependency = require("./ModuleDependency");
20
20
  /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
21
21
  /** @typedef {import("../Entrypoint")} Entrypoint */
22
22
  /** @typedef {import("../javascript/JavascriptParser").Range} Range */
23
- /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
24
- /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
23
+ /** @typedef {"script" | "script-module" | "modulepreload" | "stylesheet"} HtmlEntryElementKind */
25
24
 
26
- /** @typedef {"script-classic" | "script-module" | "modulepreload" | "stylesheet"} HtmlScriptElementKind */
25
+ /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext<[string, string, HtmlEntryElementKind, number, number, boolean, string, number, boolean, number, (Range | null), (Range | null)]>} ObjectDeserializerContext */
26
+ /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext<[string, string, HtmlEntryElementKind, number, number, boolean, string, number, boolean, number, (Range | null), (Range | null)]>} ObjectSerializerContext */
27
27
 
28
- class HtmlScriptSrcDependency extends ModuleDependency {
28
+ class HtmlEntryDependency extends ModuleDependency {
29
29
  /**
30
- * Creates an instance of HtmlScriptSrcDependency.
30
+ * Creates an instance of HtmlEntryDependency.
31
31
  * @param {string} request request
32
32
  * @param {Range} range range of the attribute value in the source
33
33
  * @param {string} entryName name of the entry this script src is bundled into
34
34
  * @param {string=} category dependency category used for resolving and grouping
35
- * @param {HtmlScriptElementKind=} elementKind shape of the originating HTML element; used when expanding sibling tags for split/runtime chunks
35
+ * @param {HtmlEntryElementKind=} elementKind shape of the originating HTML element; used when expanding sibling tags for split/runtime chunks
36
36
  * @param {number=} tagStart position of the opening `<` of the originating tag in the source; sibling tags emitted for additional entry chunks are inserted right before this
37
37
  * @param {number=} tagOpenEnd position of the character immediately after the opening tag's `>` in the source; combined with `tagStart` this lets the template clone the original opening tag verbatim (preserving attributes like `nonce`, `crossorigin`, `referrerpolicy`, `defer`, `async`) when generating sibling tags
38
+ * @param {boolean=} tagIsNative whether the originating element is the native tag for `elementKind` (`<script>` / `<link>`); decided at parse time from the tag name so the template needn't re-parse the source text. A custom element mapped to a `script`/`stylesheet` source `type` is non-native and gets a freshly synthesized sibling tag instead of a verbatim clone
39
+ * @param {string=} copyableAttrsText the originating tag's `nonce`/`crossorigin`/`referrerpolicy` attribute source spans (leading-space-prefixed, in that fixed order), captured at parse time so synthesized sibling `<link>`/`<script>` tags carry the same CSP/fetch policy without the template re-parsing the tag text; empty when none are present
40
+ * @param {number=} tagNameEnd position right after the originating tag's name (e.g. after `<script`), captured at parse time so the template can insert a `crossorigin` attribute without re-scanning the tag text for the name boundary
41
+ * @param {boolean=} hasOwnCrossOrigin whether the originating tag already carries a `crossorigin` attribute; when true the author's value wins and `output.crossOriginLoading` is not applied
42
+ * @param {number=} cssAnchor source offset of the first `<script>` tag; a later entry's injected stylesheet `<link>`s are inserted here so CSS loads before any script. -1 when the document has no script
43
+ * @param {Range | null=} integrityRange source span of the originating tag's `integrity` attribute (offsets relative to `tagStart`, leading whitespace and quotes included), captured at parse time so cloned sibling tags can drop it without re-parsing; null when absent
44
+ * @param {Range | null=} typeValueRange source span of the originating tag's `type` attribute value (offsets relative to `tagStart`), captured at parse time so `script-module` sibling clones can force `type="module"` in place; null when there is no value to rewrite (a `type="module"` is then inserted instead)
38
45
  */
39
46
  constructor(
40
47
  request,
@@ -43,23 +50,45 @@ class HtmlScriptSrcDependency extends ModuleDependency {
43
50
  category,
44
51
  elementKind,
45
52
  tagStart,
46
- tagOpenEnd
53
+ tagOpenEnd,
54
+ tagIsNative,
55
+ copyableAttrsText,
56
+ tagNameEnd,
57
+ hasOwnCrossOrigin,
58
+ cssAnchor,
59
+ integrityRange,
60
+ typeValueRange
47
61
  ) {
48
62
  super(request);
49
63
  this.range = range;
64
+ /** @type {string} */
50
65
  this.entryName = entryName;
51
66
  /** @type {string} */
52
67
  this._category = category || "commonjs";
53
- /** @type {HtmlScriptElementKind} */
54
- this.elementKind = elementKind || "script-classic";
68
+ /** @type {HtmlEntryElementKind} */
69
+ this.elementKind = elementKind || "script";
55
70
  /** @type {number} */
56
71
  this.tagStart = tagStart === undefined ? -1 : tagStart;
57
72
  /** @type {number} */
58
73
  this.tagOpenEnd = tagOpenEnd === undefined ? -1 : tagOpenEnd;
74
+ /** @type {boolean} */
75
+ this.tagIsNative = tagIsNative !== false;
76
+ /** @type {string} */
77
+ this.copyableAttrsText = copyableAttrsText || "";
78
+ /** @type {number} */
79
+ this.tagNameEnd = tagNameEnd === undefined ? -1 : tagNameEnd;
80
+ /** @type {boolean} */
81
+ this.hasOwnCrossOrigin = hasOwnCrossOrigin === true;
82
+ /** @type {number} */
83
+ this.cssAnchor = cssAnchor === undefined ? -1 : cssAnchor;
84
+ /** @type {Range | null} */
85
+ this.integrityRange = integrityRange || null;
86
+ /** @type {Range | null} */
87
+ this.typeValueRange = typeValueRange || null;
59
88
  }
60
89
 
61
90
  get type() {
62
- return "html script src";
91
+ return "html entry";
63
92
  }
64
93
 
65
94
  get category() {
@@ -71,12 +100,19 @@ class HtmlScriptSrcDependency extends ModuleDependency {
71
100
  * @param {ObjectSerializerContext} context context
72
101
  */
73
102
  serialize(context) {
74
- const { write } = context;
75
- write(this.entryName);
76
- write(this._category);
77
- write(this.elementKind);
78
- write(this.tagStart);
79
- write(this.tagOpenEnd);
103
+ context
104
+ .write(this.entryName)
105
+ .write(this._category)
106
+ .write(this.elementKind)
107
+ .write(this.tagStart)
108
+ .write(this.tagOpenEnd)
109
+ .write(this.tagIsNative)
110
+ .write(this.copyableAttrsText)
111
+ .write(this.tagNameEnd)
112
+ .write(this.hasOwnCrossOrigin)
113
+ .write(this.cssAnchor)
114
+ .write(this.integrityRange)
115
+ .write(this.typeValueRange);
80
116
  super.serialize(context);
81
117
  }
82
118
 
@@ -85,13 +121,30 @@ class HtmlScriptSrcDependency extends ModuleDependency {
85
121
  * @param {ObjectDeserializerContext} context context
86
122
  */
87
123
  deserialize(context) {
88
- const { read } = context;
89
- this.entryName = read();
90
- this._category = read();
91
- this.elementKind = read();
92
- this.tagStart = read();
93
- this.tagOpenEnd = read();
94
- super.deserialize(context);
124
+ this.entryName = context.read();
125
+ const c1 = context.rest;
126
+ this._category = c1.read();
127
+ const c2 = c1.rest;
128
+ this.elementKind = c2.read();
129
+ const c3 = c2.rest;
130
+ this.tagStart = c3.read();
131
+ const c4 = c3.rest;
132
+ this.tagOpenEnd = c4.read();
133
+ const c5 = c4.rest;
134
+ this.tagIsNative = c5.read();
135
+ const c6 = c5.rest;
136
+ this.copyableAttrsText = c6.read();
137
+ const c7 = c6.rest;
138
+ this.tagNameEnd = c7.read();
139
+ const c8 = c7.rest;
140
+ this.hasOwnCrossOrigin = c8.read();
141
+ const c9 = c8.rest;
142
+ this.cssAnchor = c9.read();
143
+ const c10 = c9.rest;
144
+ this.integrityRange = c10.read();
145
+ const c11 = c10.rest;
146
+ this.typeValueRange = c11.read();
147
+ super.deserialize(c11.rest);
95
148
  }
96
149
  }
97
150
 
@@ -207,27 +260,25 @@ const chunkHasCss = (chunk, chunkGraph) =>
207
260
  );
208
261
 
209
262
  /**
210
- * Compare two chunks for a deterministic tie-break in CSS link ordering.
211
- * `chunk.name` and `chunk.id` are both stable strings (when present);
212
- * one of them is set for every chunk webpack emits. We can't rely on
213
- * `Array.prototype.sort` being stable — webpack still supports Node
214
- * 10.13 where V8's sort is not guaranteed stable for arrays larger
215
- * than ten elements so any time `firstCssModulePostOrderIndex`
216
- * returns the same value for two chunks (most commonly when several
217
- * chunks have no reachable CSS module in the entrypoint's dependency
218
- * walk and all map to `Infinity`) this comparator picks the canonical
219
- * order.
220
- * @param {Chunk} a first chunk
221
- * @param {Chunk} b second chunk
222
- * @returns {-1 | 0 | 1} ordering
263
+ * Deterministic tie-break key for CSS link ordering. `chunk.name` and
264
+ * `chunk.id` are both stable strings (when present); one of them is set for
265
+ * every chunk webpack emits. We can't rely on `Array.prototype.sort` being
266
+ * stable — webpack still supports Node 10.13 where V8's sort is not guaranteed
267
+ * stable for arrays larger than ten elements so any time
268
+ * `firstCssModulePostOrderIndex` returns the same value for two chunks (most
269
+ * commonly when several chunks have no reachable CSS module in the entrypoint's
270
+ * dependency walk and all map to `Infinity`) this key picks the canonical order.
271
+ * Computed once per chunk when building the sort array rather than per
272
+ * comparison.
273
+ * @param {Chunk} chunk chunk
274
+ * @returns {string} the tie-break key
223
275
  */
224
- const compareChunksForCssTieBreak = (a, b) => {
225
- const an = `${a.name || ""} ${a.id === null || a.id === undefined ? "" : a.id}`;
226
- const bn = `${b.name || ""} ${b.id === null || b.id === undefined ? "" : b.id}`;
227
- if (an < bn) return -1;
228
- if (an > bn) return 1;
229
- return 0;
230
- };
276
+ const cssChunkSortKey = (chunk) =>
277
+ `${chunk.name || ""} ${
278
+ chunk.id === null || chunk.id === undefined ? "" : chunk.id
279
+ }`;
280
+
281
+ const CSS_SOURCE_TYPES = [CSS_TYPE, CSS_IMPORT_TYPE];
231
282
 
232
283
  /**
233
284
  * Smallest post-order index among the CSS modules of a chunk, taken
@@ -252,7 +303,7 @@ const compareChunksForCssTieBreak = (a, b) => {
252
303
  */
253
304
  const firstCssModulePostOrderIndex = (chunk, entrypoint, chunkGraph) => {
254
305
  let min = Number.POSITIVE_INFINITY;
255
- for (const sourceType of [CSS_TYPE, CSS_IMPORT_TYPE]) {
306
+ for (const sourceType of CSS_SOURCE_TYPES) {
256
307
  const modules = chunkGraph.getChunkModulesIterableBySourceType(
257
308
  chunk,
258
309
  sourceType
@@ -266,33 +317,44 @@ const firstCssModulePostOrderIndex = (chunk, entrypoint, chunkGraph) => {
266
317
  return min;
267
318
  };
268
319
 
269
- const COPYABLE_LINK_ATTRS = ["nonce", "crossorigin", "referrerpolicy"];
270
-
271
320
  /**
272
321
  * Build a fresh `<link rel="stylesheet" href="…">` for a CSS chunk that
273
322
  * was pulled in by a `<script src>` entry — the originating tag was a
274
323
  * `<script>`, but the chunk is CSS so cloning the script tag verbatim
275
- * would produce nonsense (`<script src="…\.css">`). Copy
276
- * `nonce`/`crossorigin`/`referrerpolicy` from the original element so
277
- * the same CSP and fetch policy applies; `defer`/`async`/`type` have no
278
- * meaning on `<link>` and are dropped.
279
- * @param {string} originalTag the originating `<script>`/`<link>` tag's source text
324
+ * would produce nonsense (`<script src="…\.css">`). `extra` carries the
325
+ * `nonce`/`crossorigin`/`referrerpolicy` source spans captured from the
326
+ * original element at parse time so the same CSP and fetch policy applies;
327
+ * `defer`/`async`/`type` have no meaning on `<link>` and are dropped.
328
+ * @param {string} extra the copyable CSP/fetch attribute source text (leading-space-prefixed, or empty)
280
329
  * @param {string} href URL for the stylesheet
330
+ * @param {string} crossOrigin ` crossorigin="…"` to append from `output.crossOriginLoading`, or `""`
281
331
  * @returns {string} the sibling `<link>` tag's HTML
282
332
  */
283
- const buildStylesheetLink = (originalTag, href) => {
284
- let extra = "";
285
- for (const attr of COPYABLE_LINK_ATTRS) {
286
- // Match ` <attr>`, ` <attr>=value`, ` <attr>="value"`, ` <attr>='value'`.
287
- const re = new RegExp(
288
- `\\s${attr}(?:\\s*=\\s*(?:"[^"]*"|'[^']*'|[^\\s>]+))?(?=[\\s/>])`,
289
- "i"
290
- );
291
- const m = originalTag.match(re);
292
- if (m) extra += m[0];
293
- }
333
+ const buildStylesheetLink = (extra, href, crossOrigin) => {
294
334
  const safeHref = href.replace(/"/g, "&quot;");
295
- return `<link rel="stylesheet" href="${safeHref}"${extra}>`;
335
+ return `<link rel="stylesheet" href="${safeHref}"${extra}${crossOrigin}>`;
336
+ };
337
+
338
+ /**
339
+ * Build a fresh `<script src="…">` for a JS chunk pulled in by a custom
340
+ * (non-`<script>`) element that the user mapped to `type: "script"` /
341
+ * `"script-module"`. Cloning the custom element verbatim and appending
342
+ * `</script>` (as `cloneTagWithUrl` does for a real `<script>`) would emit
343
+ * mismatched, non-executing markup such as `<my-script src="…"></script>`,
344
+ * so synthesize a real script element instead — copying only the CSP/fetch
345
+ * attributes (`extra`, captured at parse time), since the custom element's
346
+ * other attributes have no defined meaning on a `<script>`.
347
+ * @param {string} extra the copyable CSP/fetch attribute source text (leading-space-prefixed, or empty)
348
+ * @param {string} src URL for the script
349
+ * @param {boolean} isModule whether to emit `type="module"`
350
+ * @param {string} crossOrigin ` crossorigin="…"` to append from `output.crossOriginLoading`, or `""`
351
+ * @returns {string} the sibling `<script>` tag's HTML
352
+ */
353
+ const buildScriptTag = (extra, src, isModule, crossOrigin) => {
354
+ const safeSrc = src.replace(/"/g, "&quot;");
355
+ return `<script${
356
+ isModule ? ' type="module"' : ""
357
+ } src="${safeSrc}"${extra}${crossOrigin}></script>`;
296
358
  };
297
359
 
298
360
  /**
@@ -304,12 +366,18 @@ const buildStylesheetLink = (originalTag, href) => {
304
366
  * content-specific. When the original tag was upgraded to a module script
305
367
  * (either by the author or by the `output.module` auto-upgrade in
306
368
  * `HtmlParser`), the sibling is forced to `type="module"` regardless of what
307
- * the source originally said.
369
+ * the source originally said. The `integrity`/`type` spans come from the
370
+ * parser (`HtmlParser` captured them off the AST); edits are applied
371
+ * right-to-left so earlier offsets stay valid — no re-parsing of the tag.
308
372
  * @param {string} originalTag the opening tag's source text including `>`
309
373
  * @param {number} srcStartInTag offset of the src/href value start within `originalTag`
310
374
  * @param {number} srcEndInTag offset of the src/href value end within `originalTag`
311
375
  * @param {string} newUrl URL to put into the cloned tag's src/href slot
312
- * @param {HtmlScriptElementKind} elementKind shape of the originating tag
376
+ * @param {HtmlEntryElementKind} elementKind shape of the originating tag
377
+ * @param {string} crossOrigin ` crossorigin="…"` to insert from `output.crossOriginLoading`, or `""`
378
+ * @param {number} tagNameEndInTag offset right after the tag name within `originalTag`, where `crossOrigin` is inserted
379
+ * @param {Range | null} integrityRange `integrity` attribute span within `originalTag` to drop, or null
380
+ * @param {Range | null} typeValueRange `type` value span within `originalTag` to overwrite with `module`, or null to insert `type="module"`
313
381
  * @returns {string} the sibling tag's HTML (including a closing `</script>` for script tags)
314
382
  */
315
383
  const cloneTagWithUrl = (
@@ -317,39 +385,60 @@ const cloneTagWithUrl = (
317
385
  srcStartInTag,
318
386
  srcEndInTag,
319
387
  newUrl,
320
- elementKind
388
+ elementKind,
389
+ crossOrigin,
390
+ tagNameEndInTag,
391
+ integrityRange,
392
+ typeValueRange
321
393
  ) => {
322
- let body =
323
- originalTag.slice(0, srcStartInTag) +
324
- newUrl +
325
- originalTag.slice(srcEndInTag);
326
-
327
- // Strip dangerous-to-copy attributes from the cloned tag — currently
328
- // just `integrity`. The match handles all three quoting styles
329
- // (`"…"`, `'…'`, unquoted) and the bare-attribute form.
330
- body = body.replace(
331
- /\s+integrity(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+))?(?=[\s/>])/gi,
332
- ""
333
- );
394
+ const isLink =
395
+ elementKind === "modulepreload" || elementKind === "stylesheet";
334
396
 
397
+ /** @type {{ start: number, end: number, text: string }[]} */
398
+ const edits = [{ start: srcStartInTag, end: srcEndInTag, text: newUrl }];
399
+
400
+ // `integrity` is content-specific — drop it from the clone.
401
+ // TODO: emit a correct per-chunk `integrity` once a core SRI output
402
+ // option exists, instead of dropping it.
403
+ if (integrityRange) {
404
+ edits.push({ start: integrityRange[0], end: integrityRange[1], text: "" });
405
+ }
406
+
407
+ // Inserted right after the tag name: `crossorigin` from
408
+ // `output.crossOriginLoading`, then a forced `type="module"` when the tag
409
+ // has no `type` value to rewrite in place.
410
+ let afterName = crossOrigin;
335
411
  if (elementKind === "script-module") {
336
- if (/\stype\s*=/i.test(body)) {
337
- body = body.replace(
338
- /(\stype\s*=\s*)(?:"[^"]*"|'[^']*'|[^\s>]+)/i,
339
- '$1"module"'
340
- );
412
+ if (typeValueRange) {
413
+ edits.push({
414
+ start: typeValueRange[0],
415
+ end: typeValueRange[1],
416
+ text: "module"
417
+ });
341
418
  } else {
342
- body = body.replace(/^<script\b/i, '<script type="module"');
419
+ afterName += ' type="module"';
343
420
  }
344
421
  }
345
422
 
423
+ if (afterName) {
424
+ edits.push({
425
+ start: tagNameEndInTag,
426
+ end: tagNameEndInTag,
427
+ text: afterName
428
+ });
429
+ }
430
+
431
+ edits.sort((a, b) => b.start - a.start);
432
+ let body = originalTag;
433
+ for (const edit of edits) {
434
+ body = body.slice(0, edit.start) + edit.text + body.slice(edit.end);
435
+ }
436
+
346
437
  // `<link>` is a void element — no closing tag. `<script>` needs `</script>`.
347
- return elementKind === "modulepreload" || elementKind === "stylesheet"
348
- ? body
349
- : `${body}</script>`;
438
+ return isLink ? body : `${body}</script>`;
350
439
  };
351
440
 
352
- HtmlScriptSrcDependency.Template = class HtmlScriptSrcDependencyTemplate extends (
441
+ HtmlEntryDependency.Template = class HtmlEntryDependencyTemplate extends (
353
442
  ModuleDependency.Template
354
443
  ) {
355
444
  /**
@@ -361,9 +450,10 @@ HtmlScriptSrcDependency.Template = class HtmlScriptSrcDependencyTemplate extends
361
450
  */
362
451
  apply(dependency, source, templateContext) {
363
452
  const { runtimeTemplate } = templateContext;
364
- const dep = /** @type {HtmlScriptSrcDependency} */ (dependency);
453
+ const dep = /** @type {HtmlEntryDependency} */ (dependency);
365
454
  const compilation = runtimeTemplate.compilation;
366
455
  const { chunkGraph } = compilation;
456
+ const { crossOriginLoading } = compilation.outputOptions;
367
457
  const entrypoint = /** @type {Entrypoint | undefined} */ (
368
458
  compilation.entrypoints.get(dep.entryName)
369
459
  );
@@ -404,6 +494,30 @@ HtmlScriptSrcDependency.Template = class HtmlScriptSrcDependencyTemplate extends
404
494
  const originalTag = originalContent.slice(dep.tagStart, dep.tagOpenEnd);
405
495
  const srcStartInTag = dep.range[0] - dep.tagStart;
406
496
  const srcEndInTag = dep.range[1] - dep.tagStart;
497
+ // Non-native originating elements (a custom element mapped to a
498
+ // `script`/`stylesheet` source `type`) can't be cloned verbatim — the
499
+ // clone would be invalid markup (e.g. `<my-script …></script>`), so a
500
+ // real native tag is synthesized instead. Decided at parse time from the
501
+ // tag name (`dep.tagIsNative`) rather than re-parsing the source text.
502
+ const tagIsNative = dep.tagIsNative;
503
+
504
+ // `crossorigin` to mirror `output.crossOriginLoading` onto every injected
505
+ // tag. Empty when the option is off or the originating tag already set
506
+ // `crossorigin` (author value wins, flagged at parse time). Mirrors
507
+ // webpack's runtime, which sets `crossOrigin` on chunk-loading scripts,
508
+ // and matches Vite, which emits it on every injected script/stylesheet.
509
+ const crossOrigin =
510
+ crossOriginLoading && !dep.hasOwnCrossOrigin
511
+ ? ` crossorigin="${crossOriginLoading}"`
512
+ : "";
513
+ const tagNameEndInTag = dep.tagNameEnd - dep.tagStart;
514
+
515
+ // Mirror it onto the entry tag too (siblings get it via the builders
516
+ // below), inserted right after the tag name — its parse-time offset — so
517
+ // it sits alongside any `type="module"` the parser injected.
518
+ if (tagIsNative && crossOrigin && dep.tagNameEnd >= 0) {
519
+ source.insert(dep.tagNameEnd, crossOrigin);
520
+ }
407
521
 
408
522
  /**
409
523
  * @param {Chunk} chunk chunk to emit a sibling tag for
@@ -412,18 +526,48 @@ HtmlScriptSrcDependency.Template = class HtmlScriptSrcDependencyTemplate extends
412
526
  */
413
527
  const buildSibling = (chunk, kind) => {
414
528
  const url = HtmlGenerator.makeChunkUrlSentinel(chunk, kind);
415
- if (kind === "css" && !isStylesheet) {
416
- // Originating tag is `<script>` (or `<link rel=modulepreload>`)
417
- // but this chunk is CSS emit a fresh `<link>` rather than
418
- // cloning the script.
419
- return buildStylesheetLink(originalTag, url);
529
+ if (kind === "css") {
530
+ // A CSS chunk is always loaded via `<link rel="stylesheet">`.
531
+ // Clone only when the entry tag is itself a native `<link
532
+ // rel="stylesheet">` (so attributes like `media` carry over);
533
+ // a `<script>` entry that imported CSS, or a custom element,
534
+ // gets a freshly synthesized `<link>`.
535
+ if (isStylesheet && tagIsNative) {
536
+ return cloneTagWithUrl(
537
+ originalTag,
538
+ srcStartInTag,
539
+ srcEndInTag,
540
+ url,
541
+ dep.elementKind,
542
+ crossOrigin,
543
+ tagNameEndInTag,
544
+ dep.integrityRange,
545
+ dep.typeValueRange
546
+ );
547
+ }
548
+ return buildStylesheetLink(dep.copyableAttrsText, url, crossOrigin);
420
549
  }
421
- return cloneTagWithUrl(
422
- originalTag,
423
- srcStartInTag,
424
- srcEndInTag,
550
+ // A JS chunk is loaded via `<script>`. Clone a native `<script>`
551
+ // verbatim; synthesize a real `<script>` for custom elements that
552
+ // were mapped to `type: script`/`script-module`.
553
+ if (tagIsNative) {
554
+ return cloneTagWithUrl(
555
+ originalTag,
556
+ srcStartInTag,
557
+ srcEndInTag,
558
+ url,
559
+ dep.elementKind,
560
+ crossOrigin,
561
+ tagNameEndInTag,
562
+ dep.integrityRange,
563
+ dep.typeValueRange
564
+ );
565
+ }
566
+ return buildScriptTag(
567
+ dep.copyableAttrsText,
425
568
  url,
426
- dep.elementKind
569
+ dep.elementKind === "script-module",
570
+ crossOrigin
427
571
  );
428
572
  };
429
573
 
@@ -448,7 +592,7 @@ HtmlScriptSrcDependency.Template = class HtmlScriptSrcDependencyTemplate extends
448
592
  // re-derive the order from the entrypoint's module post-order
449
593
  // index, which mirrors the dependency walk and so reflects the
450
594
  // import order.
451
- /** @type {{ chunk: Chunk, index: number }[]} */
595
+ /** @type {{ chunk: Chunk, index: number, key: string }[]} */
452
596
  const cssChunkOrder = [];
453
597
  /** @type {Chunk[]} */
454
598
  const jsChunks = [];
@@ -459,7 +603,8 @@ HtmlScriptSrcDependency.Template = class HtmlScriptSrcDependencyTemplate extends
459
603
  if (hasCss) {
460
604
  cssChunkOrder.push({
461
605
  chunk,
462
- index: firstCssModulePostOrderIndex(chunk, entrypoint, chunkGraph)
606
+ index: firstCssModulePostOrderIndex(chunk, entrypoint, chunkGraph),
607
+ key: cssChunkSortKey(chunk)
463
608
  });
464
609
  }
465
610
  // Anything that isn't CSS-only stays on the JS lane, in the
@@ -481,7 +626,8 @@ HtmlScriptSrcDependency.Template = class HtmlScriptSrcDependencyTemplate extends
481
626
  entryChunk,
482
627
  entrypoint,
483
628
  chunkGraph
484
- )
629
+ ),
630
+ key: cssChunkSortKey(entryChunk)
485
631
  });
486
632
  }
487
633
  cssChunkOrder.sort((a, b) => {
@@ -494,11 +640,17 @@ HtmlScriptSrcDependency.Template = class HtmlScriptSrcDependencyTemplate extends
494
640
  // including the `Infinity === Infinity` case.
495
641
  if (a.index < b.index) return -1;
496
642
  if (a.index > b.index) return 1;
497
- return compareChunksForCssTieBreak(a.chunk, b.chunk);
643
+ if (a.key < b.key) return -1;
644
+ if (a.key > b.key) return 1;
645
+ return 0;
498
646
  });
499
- for (const { chunk } of cssChunkOrder) {
500
- siblings.push(buildSibling(chunk, "css"));
501
- }
647
+ // Insert CSS before the first script (not just before this tag) so a
648
+ // later entry's stylesheet still loads ahead of every script.
649
+ const cssAt = dep.cssAnchor === -1 ? dep.tagStart : dep.cssAnchor;
650
+ const cssLinks = cssChunkOrder.map(({ chunk }) =>
651
+ buildSibling(chunk, "css")
652
+ );
653
+ if (cssLinks.length > 0) source.insert(cssAt, cssLinks.join(""));
502
654
  for (const chunk of jsChunks) {
503
655
  siblings.push(buildSibling(chunk, "javascript"));
504
656
  }
@@ -511,8 +663,8 @@ HtmlScriptSrcDependency.Template = class HtmlScriptSrcDependencyTemplate extends
511
663
  };
512
664
 
513
665
  makeSerializable(
514
- HtmlScriptSrcDependency,
515
- "webpack/lib/dependencies/HtmlScriptSrcDependency"
666
+ HtmlEntryDependency,
667
+ "webpack/lib/dependencies/HtmlEntryDependency"
516
668
  );
517
669
 
518
- module.exports = HtmlScriptSrcDependency;
670
+ module.exports = HtmlEntryDependency;
@@ -0,0 +1,107 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ */
4
+
5
+ "use strict";
6
+
7
+ const { HTML_TYPE } = require("../ModuleSourceTypeConstants");
8
+ const makeSerializable = require("../util/makeSerializable");
9
+ const ModuleDependency = require("./ModuleDependency");
10
+
11
+ /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
12
+ /** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
13
+ /** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
14
+ /** @typedef {import("../Dependency")} Dependency */
15
+ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
16
+ /** @typedef {import("../Module")} Module */
17
+ /** @typedef {import("../javascript/JavascriptParser").Range} Range */
18
+ /** @typedef {import("../util/Hash")} Hash */
19
+
20
+ // One pass over the source: each char is replaced once and replacements aren't
21
+ // re-scanned, so this matches the `&`-first sequential escape chain exactly.
22
+ const ATTR_ESCAPE_REGEXP = /[&"']/g;
23
+ /** @type {Record<string, string>} */
24
+ const ATTR_ESCAPES = { "&": "&amp;", '"': "&quot;", "'": "&#39;" };
25
+ /**
26
+ * @param {string} c matched character
27
+ * @returns {string} the HTML-attribute-escaped entity
28
+ */
29
+ const escapeAttrChar = (c) => ATTR_ESCAPES[c];
30
+
31
+ /**
32
+ * Represents an `<iframe srcdoc="...">` attribute — an entity-encoded HTML
33
+ * document. The decoded document is fed back through webpack's HTML pipeline as
34
+ * a virtual `data:text/html` module so its asset URLs resolve relative to the
35
+ * host HTML file. At render time the attribute value is replaced with the
36
+ * processed HTML read from the nested module's `html` code-generation data,
37
+ * re-escaped so the surrounding attribute stays valid.
38
+ */
39
+ class HtmlInlineHtmlDependency extends ModuleDependency {
40
+ /**
41
+ * @param {string} request virtual request resolving to the inline HTML (data URI)
42
+ * @param {Range} range range of the `srcdoc` attribute value
43
+ */
44
+ constructor(request, range) {
45
+ super(request);
46
+ this.range = range;
47
+ }
48
+
49
+ get type() {
50
+ return "html inline html";
51
+ }
52
+
53
+ get category() {
54
+ return "html-srcdoc";
55
+ }
56
+
57
+ /**
58
+ * Updates the hash with the data contributed by this instance.
59
+ * @param {Hash} hash hash to be updated
60
+ * @param {UpdateHashContext} context context
61
+ * @returns {void}
62
+ */
63
+ updateHash(hash, context) {
64
+ // Recurse so the inline HTML's transitive deps (assets) propagate up.
65
+ // The module is guaranteed — it is registered as a code-generation dependency.
66
+ const module = /** @type {Module} */ (
67
+ context.chunkGraph.moduleGraph.getModule(this)
68
+ );
69
+ module.updateHash(hash, context);
70
+ }
71
+ }
72
+
73
+ HtmlInlineHtmlDependency.Template = class HtmlInlineHtmlDependencyTemplate extends (
74
+ ModuleDependency.Template
75
+ ) {
76
+ /**
77
+ * Applies the plugin by registering its hooks on the compiler.
78
+ * @param {Dependency} dependency the dependency for which the template should be applied
79
+ * @param {ReplaceSource} source the current replace source which can be modified
80
+ * @param {DependencyTemplateContext} templateContext the context object
81
+ * @returns {void}
82
+ */
83
+ apply(dependency, source, { moduleGraph, runtime, codeGenerationResults }) {
84
+ const dep = /** @type {HtmlInlineHtmlDependency} */ (dependency);
85
+ // The module is guaranteed — it is registered as a code-generation dependency.
86
+ const module = /** @type {Module} */ (moduleGraph.getModule(dep));
87
+ const codeGen =
88
+ /** @type {CodeGenerationResults} */
89
+ (codeGenerationResults).get(module, runtime);
90
+ const htmlSource = codeGen.sources.get(HTML_TYPE);
91
+
92
+ // The attribute value was entity-decoded before parsing, so re-escape the
93
+ // processed HTML to keep the surrounding `srcdoc="..."` attribute valid.
94
+ const htmlText = (
95
+ htmlSource ? /** @type {string} */ (htmlSource.source()) : ""
96
+ ).replace(ATTR_ESCAPE_REGEXP, escapeAttrChar);
97
+
98
+ source.replace(dep.range[0], dep.range[1] - 1, htmlText);
99
+ }
100
+ };
101
+
102
+ makeSerializable(
103
+ HtmlInlineHtmlDependency,
104
+ "webpack/lib/dependencies/HtmlInlineHtmlDependency"
105
+ );
106
+
107
+ module.exports = HtmlInlineHtmlDependency;