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
@@ -5,7 +5,7 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const { CSS_TYPE, JAVASCRIPT_TYPE } = require("../ModuleSourceTypeConstants");
8
+ const { JAVASCRIPT_TYPE } = require("../ModuleSourceTypeConstants");
9
9
  const { interpolate } = require("../TemplatedPathPlugin");
10
10
  const WebpackError = require("../errors/WebpackError");
11
11
  const { cssExportConvention } = require("../util/conventions");
@@ -13,36 +13,82 @@ const createHash = require("../util/createHash");
13
13
  const { makePathsRelative } = require("../util/identifier");
14
14
  const makeSerializable = require("../util/makeSerializable");
15
15
  const memoize = require("../util/memoize");
16
- const nonNumericOnlyHash = require("../util/nonNumericOnlyHash");
16
+ const { digestNonNumericOnly } = require("../util/nonNumericOnlyHash");
17
17
  const { updateHashFromSource } = require("../util/source");
18
18
  const CssIcssImportDependency = require("./CssIcssImportDependency");
19
19
  const NullDependency = require("./NullDependency");
20
20
 
21
- const getCssParser = memoize(() => require("../css/CssParser"));
21
+ const getCssTokens = memoize(() => require("../css/syntax"));
22
22
 
23
23
  /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
24
- /** @typedef {import("../../declarations/WebpackOptions").HashFunction} HashFunction */
25
24
  /** @typedef {import("../../declarations/WebpackOptions").CssGeneratorExportsConvention} CssGeneratorExportsConvention */
26
25
  /** @typedef {import("../../declarations/WebpackOptions").CssGeneratorLocalIdentName} CssGeneratorLocalIdentName */
26
+ /** @typedef {import("../../declarations/WebpackOptions").HashFunction} HashFunction */
27
+ /** @typedef {import("../css/CssGenerator")} CssGenerator */
27
28
  /** @typedef {import("../css/CssModule")} CssModule */
28
- /** @typedef {import("../Module").BuildInfo} BuildInfo */
29
- /** @typedef {import("../Dependency")} Dependency */
30
- /** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
29
+ /** @typedef {import("../ChunkGraph")} ChunkGraph */
31
30
  /** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
31
+ /** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
32
32
  /** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
33
+ /** @typedef {import("../Dependency")} Dependency */
33
34
  /** @typedef {import("../DependencyTemplate").CssDependencyTemplateContext} DependencyTemplateContext */
34
35
  /** @typedef {import("../ModuleGraph")} ModuleGraph */
35
- /** @typedef {import("../css/CssGenerator")} CssGenerator */
36
- /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
37
- /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
38
- /** @typedef {import("../util/Hash")} Hash */
39
- /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
40
- /** @typedef {import("../ChunkGraph")} ChunkGraph */
41
- /** @typedef {import("../Compilation").ModulePathData} ModulePathData */
42
36
  /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
43
37
  /** @typedef {import("../css/CssParser").Range} Range */
38
+ /** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
39
+ /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext<(number | string | Value | Range | boolean | ExportMode | ExportType | DependencyLocation | undefined)[]>} ObjectDeserializerContext */
40
+ /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext<(number | string | Value | Range | boolean | ExportMode | ExportType | DependencyLocation | undefined)[]>} ObjectSerializerContext */
41
+ /** @typedef {import("../util/Hash")} Hash */
42
+ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
43
+ /** @typedef {import("../errors/WebpackError")} WebpackErrorType */
44
44
 
45
+ /** @typedef {string | [string, string] | [string, string, string]} Value */
45
46
  /** @typedef {(name: string) => string | string[]} ExportsConventionFn */
47
+ // 0 - none, 1 - replace, 2 - append, 3 - once, 4 - self-reference
48
+ /** @typedef {0 | 1 | 2 | 3 | 4} ExportMode */
49
+ // 0 - normal, 1 - custom css variable, 2 - grid custom ident, 3 - composes
50
+ /** @typedef {0 | 1 | 2 | 3} ExportType */
51
+
52
+ /** @type {Record<"NONE" | "REPLACE" | "APPEND" | "ONCE" | "SELF_REFERENCE", ExportMode>} */
53
+ const EXPORT_MODE = {
54
+ NONE: 0,
55
+ REPLACE: 1,
56
+ APPEND: 2,
57
+ ONCE: 3,
58
+ SELF_REFERENCE: 4
59
+ };
60
+
61
+ /** @type {Record<"NORMAL" | "CUSTOM_VARIABLE" | "GRID_CUSTOM_IDENTIFIER" | "COMPOSES", ExportType>} */
62
+ const EXPORT_TYPE = {
63
+ NORMAL: 0,
64
+ CUSTOM_VARIABLE: 1,
65
+ GRID_CUSTOM_IDENTIFIER: 2,
66
+ COMPOSES: 3
67
+ };
68
+
69
+ // Hoisted out of `getLocalIdent`'s `prepareId` so the patterns + the replacer
70
+ // aren't recompiled/reallocated per interpolated id.
71
+ const IDENT_LEADING_INVALID_REGEXP = /^([.-]|[^a-z0-9_-])+/i;
72
+ const IDENT_INVALID_CHARS_REGEXP = /[^a-z0-9@_-]+/gi;
73
+ const IDENT_LOCAL_PLACEHOLDER_REGEXP = /\[local\]/g;
74
+ const IDENT_LEADING_PROTECT_REGEXP = /^((-?\d)|--)/;
75
+
76
+ /**
77
+ * `interpolate` `prepareId` hook — sanitize an id segment into a valid CSS ident.
78
+ * Pure (captures nothing), so it's shared rather than allocated per call.
79
+ * @param {string | number} id id segment
80
+ * @returns {string | number} sanitized id segment
81
+ */
82
+ const prepareLocalIdentId = (id) => {
83
+ if (typeof id !== "string") return id;
84
+ return (
85
+ id
86
+ .replace(IDENT_LEADING_INVALID_REGEXP, "")
87
+ // We keep the `@` symbol because it can be used in the package name (e.g. `@company/package`), and if we replace it with `_`, a class conflict may occur.
88
+ // For example - `@import "@foo/package/style.module.css"` and `@import "foo/package/style.module.css"` (`foo` is a package, `package` is just a directory) will create a class conflict.
89
+ .replace(IDENT_INVALID_CHARS_REGEXP, "_")
90
+ );
91
+ };
46
92
 
47
93
  /**
48
94
  * Returns local ident.
@@ -67,11 +113,9 @@ const getLocalIdent = (local, module, chunkGraph, runtimeTemplate) => {
67
113
  const { uniqueName } = runtimeTemplate.outputOptions;
68
114
 
69
115
  let localIdentHash = "";
116
+ let localIdentHashFull = "";
70
117
 
71
- if (
72
- typeof localIdentName === "function" ||
73
- /\[(?:fullhash|hash)\]/.test(localIdentName)
74
- ) {
118
+ if (generator._localIdentNeedsHash) {
75
119
  const hashSalt = generator.options.localIdentHashSalt;
76
120
  const hashDigest =
77
121
  /** @type {string} */
@@ -94,15 +138,15 @@ const getLocalIdent = (local, module, chunkGraph, runtimeTemplate) => {
94
138
  hash.update(relativeResourcePath);
95
139
  hash.update(local);
96
140
 
97
- localIdentHash = hash.digest(hashDigest).slice(0, hashDigestLength);
141
+ // Keep the untruncated digest so an inline `[fullhash:<digest>]` re-encodes
142
+ // with full entropy (see the `fullHash`/`fullHashDigest` passed below).
143
+ localIdentHashFull = hash.digest(hashDigest);
144
+ localIdentHash = localIdentHashFull.slice(0, hashDigestLength);
98
145
  }
99
146
 
100
147
  let contentHash = "";
101
148
 
102
- if (
103
- typeof localIdentName === "function" ||
104
- /\[contenthash\]/.test(localIdentName)
105
- ) {
149
+ if (generator._localIdentNeedsContentHash) {
106
150
  const hash = createHash(runtimeTemplate.outputOptions.hashFunction);
107
151
  const source = module.originalSource();
108
152
 
@@ -114,65 +158,49 @@ const getLocalIdent = (local, module, chunkGraph, runtimeTemplate) => {
114
158
  hash.update(module.error.toString());
115
159
  }
116
160
 
117
- const fullContentHash = hash.digest(
118
- runtimeTemplate.outputOptions.hashDigest
119
- );
120
-
121
- contentHash = nonNumericOnlyHash(
122
- fullContentHash,
123
- runtimeTemplate.outputOptions.hashDigestLength
161
+ contentHash = digestNonNumericOnly(
162
+ hash,
163
+ /** @type {string} */ (runtimeTemplate.outputOptions.hashDigest),
164
+ /** @type {number} */ (runtimeTemplate.outputOptions.hashDigestLength)
124
165
  );
125
166
  }
126
167
 
127
168
  let localIdent = interpolate(localIdentName, {
128
- prepareId: (id) => {
129
- if (typeof id !== "string") return id;
130
-
131
- return (
132
- id
133
- .replace(/^([.-]|[^a-z0-9_-])+/i, "")
134
- // We keep the `@` symbol because it can be used in the package name (e.g. `@company/package`), and if we replace it with `_`, a class conflict may occur.
135
- // For example - `@import "@foo/package/style.module.css"` and `@import "foo/package/style.module.css"` (`foo` is a package, `package` is just a directory) will create a class conflict.
136
- .replace(/[^a-z0-9@_-]+/gi, "_")
137
- );
138
- },
169
+ prepareId: prepareLocalIdentId,
139
170
  filename: relativeResourcePath,
140
171
  hash: localIdentHash,
172
+ // css-loader semantics: `[hash]` is the local ident hash, not the module
173
+ // hash (use `[modulehash]` for that).
174
+ hashAsFullHash: true,
175
+ // `[hash]`/`[contenthash]` are encoded with the output digest, but the
176
+ // `[fullhash]` local ident hash uses `localIdentHashDigest`, so re-encode it
177
+ // from its own (full) digest.
178
+ hashDigest: runtimeTemplate.outputOptions.hashDigest,
179
+ fullHash: localIdentHashFull,
180
+ fullHashDigest:
181
+ /** @type {string} */
182
+ (generator.options.localIdentHashDigest),
141
183
  local,
184
+ uniqueName,
142
185
  contentHash,
143
186
  chunkGraph,
144
187
  module
145
188
  });
146
189
 
147
- // TODO move these things into interpolate
148
- if (/\[local\]/.test(localIdent)) {
149
- localIdent = localIdent.replace(/\[local\]/g, local);
150
- }
151
-
152
- if (/\[uniqueName\]/.test(localIdent)) {
153
- localIdent = localIdent.replace(
154
- /\[uniqueName\]/g,
155
- /** @type {string} */ (uniqueName)
156
- );
157
- }
190
+ // TODO move this into interpolate
191
+ // `replace` on a non-matching global regexp returns the string unchanged, so
192
+ // the `.test` guard is redundant — one scan instead of two.
193
+ localIdent = localIdent.replace(IDENT_LOCAL_PLACEHOLDER_REGEXP, local);
158
194
 
159
195
  // Protect the first character from unsupported values
160
- return localIdent.replace(/^((-?\d)|--)/, "_$1");
196
+ return localIdent.replace(IDENT_LEADING_PROTECT_REGEXP, "_$1");
161
197
  };
162
198
 
163
- /** @typedef {string | [string, string] | [string, string, string]} Value */
164
-
165
- // 0 - replace, 1 - replace, 2 - append, 2 - once
166
- /** @typedef {0 | 1 | 2 | 3 | 4} ExportMode */
167
- // 0 - normal, 1 - custom css variable, 2 - grid custom ident, 3 - composes
168
- /** @typedef {0 | 1 | 2 | 3} ExportType */
169
-
170
199
  /**
171
200
  * Computes the interpolated identifier for `(module, value, exportType)`.
172
201
  * Module-level reference so `moduleGraph.cached` can use it as a stable
173
- * computer key — repeated lookups during a build skip
174
- * `cssExportConvention`, `getLocalIdent` (with its content / path hashing)
175
- * and `escapeIdentifier`.
202
+ * computer key — repeated lookups during a build skip `cssExportConvention`,
203
+ * `getLocalIdent` (with its content / path hashing) and `escapeIdentifier`.
176
204
  * @param {ModuleGraph} _moduleGraph module graph (unused, kept for `cached` signature)
177
205
  * @param {CssModule} module css module the value resolves in
178
206
  * @param {string} value raw value to interpolate
@@ -195,13 +223,10 @@ const computeInterpolatedIdentifier = (
195
223
  /** @type {CssGeneratorExportsConvention} */
196
224
  (generator.options.exportsConvention)
197
225
  )[0];
198
- const prefix =
199
- exportType === CssIcssExportDependency.EXPORT_TYPE.CUSTOM_VARIABLE
200
- ? "--"
201
- : "";
226
+ const prefix = exportType === EXPORT_TYPE.CUSTOM_VARIABLE ? "--" : "";
202
227
  return (
203
228
  prefix +
204
- getCssParser().escapeIdentifier(
229
+ getCssTokens().escapeIdentifier(
205
230
  getLocalIdent(local, module, chunkGraph, runtimeTemplate),
206
231
  runtimeTemplate.compilation.compiler.root
207
232
  )
@@ -209,97 +234,61 @@ const computeInterpolatedIdentifier = (
209
234
  };
210
235
 
211
236
  /**
212
- * Top-level computer for `resolve`. Allocates a fresh `seen` set; recursive
213
- * calls go through the un-cached inner path so cycle detection still works.
214
- * @param {ModuleGraph} moduleGraph module graph
215
- * @param {CssModule} module module to search
216
- * @param {string} localName local name
217
- * @param {string} importName imported export name
218
- * @param {string | undefined} request request of the active `@value` import
219
- * @param {ChunkGraph} chunkGraph chunk graph
220
- * @param {RuntimeTemplate} runtimeTemplate runtime template
221
- * @returns {string | undefined} resolved value or undefined
237
+ * One `:export { name: value }` style entry — a plain object so a module holds
238
+ * a single `Dependency` plus a flat array instead of thousands of `Dependency`
239
+ * instances. `_conventionNames`/`_valueConventionNames` memoize the convention
240
+ * expansion per entry.
241
+ * @typedef {object} CssExportEntry
242
+ * @property {string} name export name
243
+ * @property {Value} value value or [localName, importName, request?]
244
+ * @property {Range=} range source range to replace, when present
245
+ * @property {boolean} interpolate whether the value needs interpolation
246
+ * @property {ExportMode} exportMode export mode
247
+ * @property {ExportType} exportType export type
248
+ * @property {DependencyLocation=} loc per-export source location (for export source maps)
249
+ * @property {string[]=} _conventionNames memoized convention names for `name`
250
+ * @property {string[]=} _valueConventionNames memoized convention names for `value`
222
251
  */
223
- const computeResolve = (
224
- moduleGraph,
225
- module,
226
- localName,
227
- importName,
228
- request,
229
- chunkGraph,
230
- runtimeTemplate
231
- ) =>
232
- CssIcssExportDependency.Template._doResolve(
233
- localName,
234
- importName,
235
- /** @type {DependencyTemplateContext} */
236
- (
237
- /** @type {unknown} */
238
- ({ moduleGraph, module, chunkGraph, runtimeTemplate })
239
- ),
240
- request,
241
- new Set()
242
- );
243
252
 
244
253
  /**
245
- * Top-level computer for `resolveReferences`. See `computeResolve`.
246
- * @param {ModuleGraph} moduleGraph module graph
247
- * @param {CssIcssExportDependency} dep export dependency
248
- * @param {CssModule} module module that hosts `dep`
249
- * @param {ChunkGraph} chunkGraph chunk graph
250
- * @param {RuntimeTemplate} runtimeTemplate runtime template
251
- * @returns {string[]} final references, deduplicated
254
+ * Memoized `cssExportConvention(entry.name, convention)`.
255
+ * @param {CssExportEntry} entry entry
256
+ * @param {CssGeneratorExportsConvention} convention convention
257
+ * @returns {string[]} convention names
252
258
  */
253
- const computeResolveReferences = (
254
- moduleGraph,
255
- dep,
256
- module,
257
- chunkGraph,
258
- runtimeTemplate
259
- ) =>
260
- CssIcssExportDependency.Template._doResolveReferences(
261
- dep,
262
- /** @type {DependencyTemplateContext} */
263
- (
264
- /** @type {unknown} */
265
- ({ moduleGraph, module, chunkGraph, runtimeTemplate })
266
- ),
267
- new Set()
259
+ const entryConventionNames = (entry, convention) => {
260
+ if (entry._conventionNames) return entry._conventionNames;
261
+ entry._conventionNames = cssExportConvention(entry.name, convention);
262
+ return entry._conventionNames;
263
+ };
264
+
265
+ /**
266
+ * Memoized `cssExportConvention(entry.value, convention)`. Caller guarantees
267
+ * `typeof entry.value === "string"`.
268
+ * @param {CssExportEntry} entry entry
269
+ * @param {CssGeneratorExportsConvention} convention convention
270
+ * @returns {string[]} convention names
271
+ */
272
+ const entryValueConventionNames = (entry, convention) => {
273
+ if (entry._valueConventionNames) return entry._valueConventionNames;
274
+ entry._valueConventionNames = cssExportConvention(
275
+ /** @type {string} */ (entry.value),
276
+ convention
268
277
  );
278
+ return entry._valueConventionNames;
279
+ };
269
280
 
270
281
  class CssIcssExportDependency extends NullDependency {
271
282
  /**
272
- * Example of dependency:
273
- *
274
- * :export { LOCAL_NAME: EXPORT_NAME }
275
- * @param {string} name export name
276
- * @param {Value} value value or local name and import name
277
- * @param {Range=} range range
278
- * @param {boolean=} interpolate true when value need to be interpolated, otherwise false
279
- * @param {ExportMode=} exportMode export mode
280
- * @param {ExportType=} exportType export type
283
+ * One consolidated `:export` dependency for a whole CSS module.
284
+ * @param {CssExportEntry[]} entries export entries in source order
281
285
  */
282
- constructor(
283
- name,
284
- value,
285
- range,
286
- interpolate = false,
287
- exportMode = CssIcssExportDependency.EXPORT_MODE.REPLACE,
288
- exportType = CssIcssExportDependency.EXPORT_TYPE.NORMAL
289
- ) {
286
+ constructor(entries) {
290
287
  super();
291
- this.name = name;
292
- this.value = value;
293
- this.range = range;
294
- this.interpolate = interpolate;
295
- this.exportMode = exportMode;
296
- this.exportType = exportType;
288
+ /** @type {CssExportEntry[]} */
289
+ this.entries = entries;
297
290
  /** @type {undefined | string} */
298
291
  this._hashUpdate = undefined;
299
- /** @type {undefined | string[]} */
300
- this._conventionNames = undefined;
301
- /** @type {undefined | string[]} */
302
- this._valueConventionNames = undefined;
303
292
  }
304
293
 
305
294
  get type() {
@@ -307,37 +296,33 @@ class CssIcssExportDependency extends NullDependency {
307
296
  }
308
297
 
309
298
  /**
310
- * Gets exports convention names.
311
- * @param {string} name export name
312
- * @param {CssGeneratorExportsConvention} convention convention of the export name
313
- * @returns {string[]} convention results
299
+ * Returns the exported names
300
+ * @param {ModuleGraph} moduleGraph module graph
301
+ * @returns {ExportsSpec | undefined} export names
314
302
  */
315
- getExportsConventionNames(name, convention) {
316
- if (this._conventionNames) {
317
- return this._conventionNames;
303
+ getExports(moduleGraph) {
304
+ const module = /** @type {CssModule} */ (moduleGraph.getParentModule(this));
305
+ const generator = /** @type {CssGenerator} */ (module.generator);
306
+ const convention =
307
+ /** @type {CssGeneratorExportsConvention} */
308
+ (generator.options.exportsConvention);
309
+
310
+ /** @type {{ name: string, canMangle: boolean }[]} */
311
+ const exports = [];
312
+ for (const entry of this.entries) {
313
+ if (
314
+ entry.exportMode === EXPORT_MODE.NONE ||
315
+ entry.exportMode === EXPORT_MODE.SELF_REFERENCE
316
+ ) {
317
+ continue;
318
+ }
319
+ for (const name of entryConventionNames(entry, convention)) {
320
+ exports.push({ name, canMangle: true });
321
+ }
318
322
  }
319
- this._conventionNames = cssExportConvention(name, convention);
320
- return this._conventionNames;
321
- }
322
323
 
323
- /**
324
- * Memoized `cssExportConvention(this.value, convention)`. Used by every
325
- * code path that needs the convention-derived aliases of the composed /
326
- * referenced class: `getReferencedExports`, `getWarnings`, and the template's
327
- * `getIdentifier`. Caller guarantees `typeof this.value === "string"` —
328
- * the array form (cross-module references) is resolved separately.
329
- * @param {CssGeneratorExportsConvention} convention convention of the export name
330
- * @returns {string[]} convention results
331
- */
332
- getValueConventionNames(convention) {
333
- if (this._valueConventionNames) {
334
- return this._valueConventionNames;
335
- }
336
- this._valueConventionNames = cssExportConvention(
337
- /** @type {string} */ (this.value),
338
- convention
339
- );
340
- return this._valueConventionNames;
324
+ if (exports.length === 0) return undefined;
325
+ return { exports, dependencies: undefined };
341
326
  }
342
327
 
343
328
  /**
@@ -347,60 +332,43 @@ class CssIcssExportDependency extends NullDependency {
347
332
  * @returns {ReferencedExports} referenced exports
348
333
  */
349
334
  getReferencedExports(moduleGraph, runtime) {
350
- if (
351
- this.exportMode === CssIcssExportDependency.EXPORT_MODE.SELF_REFERENCE &&
352
- typeof this.value === "string"
353
- ) {
354
- // `composes: foo;` — the composed class (`this.value`) is the one
355
- // referenced, not the class doing the composing (`this.name`). Apply
356
- // the generator's `exportsConvention` so the export names produced
357
- // by the convention are what the optimizer sees.
358
- const module =
359
- /** @type {CssModule | undefined} */
360
- (moduleGraph.getParentModule(this));
361
- if (!module) return super.getReferencedExports(moduleGraph, runtime);
362
- const generator = /** @type {CssGenerator} */ (module.generator);
363
- const names = this.getValueConventionNames(
364
- /** @type {CssGeneratorExportsConvention} */
365
- (generator.options.exportsConvention)
366
- );
367
- return names.map((name) => ({
368
- name: [name],
369
- canMangle: true
370
- }));
335
+ // `composes: foo;` (SELF_REFERENCE) references the composed class
336
+ // (`entry.value`), not the composing class. Every other entry mode
337
+ // keeps the whole exports object referenced (legacy behaviour), so the
338
+ // presence of any such entry subsumes the self-reference names.
339
+ let hasNonSelfReference = false;
340
+ /** @type {ReferencedExports} */
341
+ const referenced = [];
342
+ let generator;
343
+ for (const entry of this.entries) {
344
+ if (
345
+ entry.exportMode === EXPORT_MODE.SELF_REFERENCE &&
346
+ typeof entry.value === "string"
347
+ ) {
348
+ const module =
349
+ /** @type {CssModule} */
350
+ (moduleGraph.getParentModule(this));
351
+ generator = generator || /** @type {CssGenerator} */ (module.generator);
352
+ const names = entryValueConventionNames(
353
+ entry,
354
+ /** @type {CssGeneratorExportsConvention} */
355
+ (generator.options.exportsConvention)
356
+ );
357
+ for (const name of names) {
358
+ referenced.push({ name: [name], canMangle: true });
359
+ }
360
+ } else {
361
+ hasNonSelfReference = true;
362
+ }
371
363
  }
372
364
 
373
- return super.getReferencedExports(moduleGraph, runtime);
374
- }
375
-
376
- /**
377
- * Returns the exported names
378
- * @param {ModuleGraph} moduleGraph module graph
379
- * @returns {ExportsSpec | undefined} export names
380
- */
381
- getExports(moduleGraph) {
382
- if (
383
- this.exportMode === CssIcssExportDependency.EXPORT_MODE.NONE ||
384
- this.exportMode === CssIcssExportDependency.EXPORT_MODE.SELF_REFERENCE
385
- ) {
386
- return;
365
+ if (hasNonSelfReference) {
366
+ return super.getReferencedExports(moduleGraph, runtime);
387
367
  }
388
-
389
- const module = /** @type {CssModule} */ (moduleGraph.getParentModule(this));
390
- const generator = /** @type {CssGenerator} */ (module.generator);
391
- const names = this.getExportsConventionNames(
392
- this.name,
393
- /** @type {CssGeneratorExportsConvention} */
394
- (generator.options.exportsConvention)
395
- );
396
-
397
- return {
398
- exports: [...names].map((name) => ({
399
- name,
400
- canMangle: true
401
- })),
402
- dependencies: undefined
403
- };
368
+ if (referenced.length === 0) {
369
+ return super.getReferencedExports(moduleGraph, runtime);
370
+ }
371
+ return referenced;
404
372
  }
405
373
 
406
374
  /**
@@ -409,42 +377,48 @@ class CssIcssExportDependency extends NullDependency {
409
377
  * @returns {WebpackError[] | null | undefined} warnings
410
378
  */
411
379
  getWarnings(moduleGraph) {
412
- if (
413
- this.exportMode === CssIcssExportDependency.EXPORT_MODE.SELF_REFERENCE &&
414
- typeof this.value === "string"
415
- ) {
416
- const module =
417
- /** @type {CssModule | undefined} */
418
- (moduleGraph.getParentModule(this));
419
-
420
- if (!module) return null;
421
-
422
- // `ExportsInfo` only stores names produced by `exportsConvention`,
423
- // so a raw `isExportProvided(this.value)` check is a false-positive
424
- // for `camel-case-only` / `dashes-only` (and any custom function
425
- // that drops the original spelling). Treat the composed class as
426
- // provided if *any* of its convention-produced aliases is provided.
427
- const generator = /** @type {CssGenerator} */ (module.generator);
428
- const exportsInfo = moduleGraph.getExportsInfo(module);
429
- const names = this.getValueConventionNames(
430
- /** @type {CssGeneratorExportsConvention} */
431
- (generator.options.exportsConvention)
432
- );
433
- const isProvided = names.some((name) =>
434
- exportsInfo.isExportProvided(name)
380
+ /** @type {WebpackErrorType[] | null} */
381
+ let warnings = null;
382
+ let module;
383
+ let exportsInfo;
384
+ let convention;
385
+ for (const entry of this.entries) {
386
+ if (
387
+ entry.exportMode !== EXPORT_MODE.SELF_REFERENCE ||
388
+ typeof entry.value !== "string"
389
+ ) {
390
+ continue;
391
+ }
392
+ if (module === undefined) {
393
+ module =
394
+ /** @type {CssModule | undefined} */
395
+ (moduleGraph.getParentModule(this));
396
+ if (!module) return warnings;
397
+ const generator = /** @type {CssGenerator} */ (module.generator);
398
+ convention =
399
+ /** @type {CssGeneratorExportsConvention} */
400
+ (generator.options.exportsConvention);
401
+ exportsInfo = moduleGraph.getExportsInfo(module);
402
+ }
403
+ const names = entryValueConventionNames(
404
+ entry,
405
+ /** @type {CssGeneratorExportsConvention} */ (convention)
435
406
  );
436
-
407
+ const ei = /** @type {NonNullable<typeof exportsInfo>} */ (exportsInfo);
408
+ const isProvided = names.some((name) => ei.isExportProvided(name));
437
409
  if (!isProvided) {
438
410
  const error = new WebpackError(
439
- `Self-referencing name "${this.value}" not found`
411
+ `Self-referencing name "${entry.value}" not found`
440
412
  );
441
413
  error.module = module;
442
-
443
- return [error];
414
+ // Per-entry loc so Compilation attributes the warning precisely
415
+ // (it can't use the consolidated dependency's single loc).
416
+ if (entry.loc) error.loc = entry.loc;
417
+ if (warnings === null) warnings = [];
418
+ warnings.push(error);
444
419
  }
445
420
  }
446
-
447
- return null;
421
+ return warnings;
448
422
  }
449
423
 
450
424
  /**
@@ -459,16 +433,19 @@ class CssIcssExportDependency extends NullDependency {
459
433
  /** @type {CssModule} */
460
434
  (chunkGraph.moduleGraph.getParentModule(this));
461
435
  const generator = /** @type {CssGenerator} */ (module.generator);
462
- const names = this.getExportsConventionNames(
463
- this.name,
436
+ const convention =
464
437
  /** @type {CssGeneratorExportsConvention} */
465
- (generator.options.exportsConvention)
466
- );
467
- // Include all instance state that affects the emitted output
468
- // `name`, `value`, `range`, `interpolate`, `exportMode`,
469
- // `exportType` so changes like switching `composes: foo` →
470
- // `composes: bar` or `ONCE` → `APPEND` invalidate caches.
471
- this._hashUpdate = `exportsConvention|${JSON.stringify(names)}|localIdentName|${JSON.stringify(generator.options.localIdentName)}|value|${JSON.stringify(this.value)}|range|${JSON.stringify(this.range)}|interpolate|${this.interpolate}|exportMode|${this.exportMode}|exportType|${this.exportType}`;
438
+ (generator.options.exportsConvention);
439
+ const localIdentName = JSON.stringify(generator.options.localIdentName);
440
+ // Concatenate each entry's contribution with no separator so the byte
441
+ // stream matches the legacy per-export `updateHash` sequence exactly
442
+ // (keeps module hashes stable for import-free modules).
443
+ let update = "";
444
+ for (const entry of this.entries) {
445
+ const names = entryConventionNames(entry, convention);
446
+ update += `exportsConvention|${JSON.stringify(names)}|localIdentName|${localIdentName}|value|${JSON.stringify(entry.value)}|range|${JSON.stringify(entry.range)}|interpolate|${entry.interpolate}|exportMode|${entry.exportMode}|exportType|${entry.exportType}`;
447
+ }
448
+ this._hashUpdate = update;
472
449
  }
473
450
  hash.update(this._hashUpdate);
474
451
  }
@@ -479,12 +456,16 @@ class CssIcssExportDependency extends NullDependency {
479
456
  */
480
457
  serialize(context) {
481
458
  const { write } = context;
482
- write(this.name);
483
- write(this.value);
484
- write(this.range);
485
- write(this.interpolate);
486
- write(this.exportMode);
487
- write(this.exportType);
459
+ write(this.entries.length);
460
+ for (const entry of this.entries) {
461
+ write(entry.name);
462
+ write(entry.value);
463
+ write(entry.range);
464
+ write(entry.interpolate);
465
+ write(entry.exportMode);
466
+ write(entry.exportType);
467
+ write(entry.loc);
468
+ }
488
469
  super.serialize(context);
489
470
  }
490
471
 
@@ -494,110 +475,134 @@ class CssIcssExportDependency extends NullDependency {
494
475
  */
495
476
  deserialize(context) {
496
477
  const { read } = context;
497
- this.name = read();
498
- this.value = read();
499
- this.range = read();
500
- this.interpolate = read();
501
- this.exportMode = read();
502
- this.exportType = read();
478
+ const length = /** @type {number} */ (read());
479
+ /** @type {CssExportEntry[]} */
480
+ const entries = [];
481
+ for (let i = 0; i < length; i++) {
482
+ entries.push({
483
+ name: /** @type {string} */ (read()),
484
+ value: /** @type {Value} */ (read()),
485
+ range: /** @type {Range=} */ (read()),
486
+ interpolate: /** @type {boolean} */ (read()),
487
+ exportMode: /** @type {ExportMode} */ (read()),
488
+ exportType: /** @type {ExportType} */ (read()),
489
+ loc: /** @type {DependencyLocation=} */ (read())
490
+ });
491
+ }
492
+ this.entries = entries;
493
+ this._hashUpdate = undefined;
503
494
  super.deserialize(context);
504
495
  }
505
496
  }
506
497
 
498
+ /**
499
+ * Get (or lazily build into `indexCache`) a name -> entries index for `dep`,
500
+ * so composes resolution does a Map lookup instead of scanning all entries per
501
+ * reference. The cache is owned by one `apply` call and GC'd with it.
502
+ * @param {Map<CssIcssExportDependency, Map<string, CssExportEntry[]>>} indexCache transient cache
503
+ * @param {CssIcssExportDependency} dep export dependency
504
+ * @returns {Map<string, CssExportEntry[]>} entries grouped by name
505
+ */
506
+ const indexEntries = (indexCache, dep) => {
507
+ let map = indexCache.get(dep);
508
+ if (map === undefined) {
509
+ map = new Map();
510
+ for (const e of dep.entries) {
511
+ const list = map.get(e.name);
512
+ if (list) list.push(e);
513
+ else map.set(e.name, [e]);
514
+ }
515
+ indexCache.set(dep, map);
516
+ }
517
+ return map;
518
+ };
519
+
520
+ /**
521
+ * Finds the active `CssIcssImportDependency` for a given local name. When a
522
+ * `request` is provided the lookup also requires the import dependency's
523
+ * `request` to match, so references between two `@value foo from "..."`
524
+ * declarations resolve through the import in scope at the reference site.
525
+ * @param {Iterable<Dependency>} dependencies module dependencies to search
526
+ * @param {string} localName local name
527
+ * @param {string=} request user request of the `@value` import to match
528
+ * @returns {CssIcssImportDependency | undefined} matching import dep, if any
529
+ */
530
+ const findImportDep = (dependencies, localName, request) => {
531
+ /** @type {CssIcssImportDependency | undefined} */
532
+ let firstMatch;
533
+ for (const d of dependencies) {
534
+ if (d instanceof CssIcssImportDependency && d.localName === localName) {
535
+ if (request === undefined) return d;
536
+ if (d.request === request) return d;
537
+ if (firstMatch === undefined) firstMatch = d;
538
+ }
539
+ }
540
+ return firstMatch;
541
+ };
542
+
507
543
  CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends (
508
544
  NullDependency.Template
509
545
  ) {
510
546
  /**
511
- * Returns found reference. The top-level call (no `seen` argument) is
512
- * memoized via `moduleGraph.cached` keyed by `(module, localName,
513
- * importName, request, chunkGraph, runtimeTemplate)`. Recursive callers
514
- * pass `seen` and skip the cache so the cycle guard is preserved — only
515
- * completed top-level resolutions land in the cache.
547
+ * Resolves a `[localName, importName, request]` reference to its final
548
+ * value by following `@value` imports into other modules' consolidated
549
+ * export dependencies.
516
550
  * @param {string} localName local name
517
551
  * @param {string} importName import name
518
552
  * @param {DependencyTemplateContext} templateContext the context object
519
- * @param {string | undefined} request user request of the `@value` import that was active when the reference was parsed — used to disambiguate when the same local name is imported from multiple modules
520
- * @param {Set<CssIcssExportDependency>=} seen seen to prevent cyclical problems
553
+ * @param {string | undefined} request user request of the `@value` import
554
+ * @param {Set<CssExportEntry>=} seen cycle guard
555
+ * @param {Map<CssIcssExportDependency, Map<string, CssExportEntry[]>>=} indexCache transient per-codegen name index (shared with `resolveReferences` within one `apply`)
521
556
  * @returns {string | undefined} found reference
522
557
  */
523
- static resolve(localName, importName, templateContext, request, seen) {
524
- if (seen !== undefined) {
525
- return CssIcssExportDependencyTemplate._doResolve(
526
- localName,
527
- importName,
528
- templateContext,
529
- request,
530
- seen
531
- );
532
- }
533
- const { moduleGraph, module, chunkGraph, runtimeTemplate } =
534
- templateContext;
535
- return moduleGraph.cached(
536
- computeResolve,
537
- /** @type {CssModule} */ (module),
558
+ static resolve(
559
+ localName,
560
+ importName,
561
+ templateContext,
562
+ request,
563
+ seen = new Set(),
564
+ indexCache = new Map()
565
+ ) {
566
+ const { moduleGraph } = templateContext;
567
+ const importDep = findImportDep(
568
+ templateContext.module.dependencies,
538
569
  localName,
539
- importName,
540
- request,
541
- chunkGraph,
542
- runtimeTemplate
570
+ request
543
571
  );
544
- }
545
-
546
- /**
547
- * Inner recursive worker for `resolve`. Not memoized — see `resolve`.
548
- * @param {string} localName local name
549
- * @param {string} importName import name
550
- * @param {DependencyTemplateContext} templateContext the context object
551
- * @param {string | undefined} request user request
552
- * @param {Set<CssIcssExportDependency>} seen seen to prevent cyclical problems
553
- * @returns {string | undefined} found reference
554
- */
555
- static _doResolve(localName, importName, templateContext, request, seen) {
556
- const { moduleGraph } = templateContext;
557
- const importDep =
558
- /** @type {CssIcssImportDependency | undefined} */
559
- (
560
- CssIcssExportDependencyTemplate.findImportDep(
561
- templateContext.module.dependencies,
562
- localName,
563
- request
564
- )
565
- );
566
572
  if (!importDep) return undefined;
567
573
 
568
574
  const module = /** @type {CssModule} */ (moduleGraph.getModule(importDep));
569
575
  if (!module) return undefined;
570
576
 
571
- const exportDep =
572
- /** @type {CssIcssExportDependency} */
573
- (
574
- module.dependencies.find(
575
- (d) => d instanceof CssIcssExportDependency && d.name === importName
576
- )
577
- );
578
-
579
- if (!exportDep) return undefined;
580
-
581
- if (seen.has(exportDep)) return undefined;
582
- seen.add(exportDep);
577
+ /** @type {CssExportEntry | undefined} */
578
+ let exportEntry;
579
+ for (const dep of module.dependencies) {
580
+ if (!(dep instanceof CssIcssExportDependency)) continue;
581
+ const matches = indexEntries(indexCache, dep).get(importName);
582
+ if (matches) {
583
+ exportEntry = matches[0];
584
+ break;
585
+ }
586
+ }
587
+ if (!exportEntry) return undefined;
588
+ if (seen.has(exportEntry)) return undefined;
589
+ seen.add(exportEntry);
583
590
 
584
- const { value, interpolate } = exportDep;
591
+ const { value, interpolate } = exportEntry;
585
592
 
586
593
  if (Array.isArray(value)) {
587
- return CssIcssExportDependencyTemplate._doResolve(
594
+ return CssIcssExportDependencyTemplate.resolve(
588
595
  value[0],
589
596
  value[1],
590
- {
591
- ...templateContext,
592
- module
593
- },
597
+ { ...templateContext, module },
594
598
  value[2],
595
- seen
599
+ seen,
600
+ indexCache
596
601
  );
597
602
  }
598
603
 
599
604
  if (interpolate) {
600
- return CssIcssExportDependency.Template.getIdentifier(value, exportDep, {
605
+ return CssIcssExportDependencyTemplate.getIdentifier(value, exportEntry, {
601
606
  ...templateContext,
602
607
  module
603
608
  });
@@ -607,81 +612,26 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
607
612
  }
608
613
 
609
614
  /**
610
- * Finds the active `CssIcssImportDependency` for a given local name. When a
611
- * `request` is provided the lookup also requires the import dependency's
612
- * `request` to match — this lets references that appear between two
613
- * `@value foo from "..."` declarations resolve through the import that was
614
- * in scope at the reference site, rather than always picking the first.
615
- * @param {Iterable<Dependency>} dependencies module dependencies to search
616
- * @param {string} localName local name
617
- * @param {string=} request user request of the `@value` import to match
618
- * @returns {CssIcssImportDependency | undefined} matching import dep, if any
619
- */
620
- static findImportDep(dependencies, localName, request) {
621
- /** @type {CssIcssImportDependency | undefined} */
622
- let firstMatch;
623
- for (const d of dependencies) {
624
- if (d instanceof CssIcssImportDependency && d.localName === localName) {
625
- if (request === undefined) return d;
626
- if (d.request === request) return d;
627
- if (firstMatch === undefined) firstMatch = d;
628
- }
629
- }
630
- return firstMatch;
631
- }
632
-
633
- /**
634
- * Resolves references. The top-level call (no `seen` argument) is
635
- * memoized via `moduleGraph.cached`; recursive callers pass `seen` and
636
- * bypass the cache to keep the cycle guard intact.
637
- * @param {CssIcssExportDependency} dep value
638
- * @param {DependencyTemplateContext} templateContext template context
639
- * @param {Set<CssIcssExportDependency>=} seen to prevent cyclical problems
640
- * @returns {string[]} final names
641
- */
642
- static resolveReferences(dep, templateContext, seen) {
643
- if (seen !== undefined) {
644
- return CssIcssExportDependencyTemplate._doResolveReferences(
645
- dep,
646
- templateContext,
647
- seen
648
- );
649
- }
650
- const { moduleGraph, module, chunkGraph, runtimeTemplate } =
651
- templateContext;
652
- return moduleGraph.cached(
653
- computeResolveReferences,
654
- dep,
655
- /** @type {CssModule} */ (module),
656
- chunkGraph,
657
- runtimeTemplate
658
- );
659
- }
660
-
661
- /**
662
- * Inner recursive worker for `resolveReferences`. Not memoized.
663
- * @param {CssIcssExportDependency} dep value
615
+ * Resolves all references of a `composes` entry, deduplicated.
616
+ * @param {CssExportEntry} entry composes entry
664
617
  * @param {DependencyTemplateContext} templateContext template context
665
- * @param {Set<CssIcssExportDependency>} seen to prevent cyclical problems
618
+ * @param {Set<CssExportEntry>} seen cycle guard
619
+ * @param {Map<CssIcssExportDependency, Map<string, CssExportEntry[]>>} indexCache transient per-codegen name index, discarded after the module's `apply` (so it isn't retained on the dependency)
666
620
  * @returns {string[]} final names
667
621
  */
668
- static _doResolveReferences(dep, templateContext, seen) {
622
+ static resolveReferences(entry, templateContext, seen, indexCache) {
669
623
  /** @type {string[]} */
670
624
  const references = [];
671
625
 
672
- if (seen.has(dep)) return references;
673
- seen.add(dep);
674
-
675
- if (Array.isArray(dep.value)) {
676
- const importDep =
677
- /** @type {CssIcssImportDependency | undefined} */
678
- (
679
- CssIcssExportDependencyTemplate.findImportDep(
680
- templateContext.module.dependencies,
681
- dep.value[0],
682
- dep.value[2]
683
- )
684
- );
626
+ if (seen.has(entry)) return references;
627
+ seen.add(entry);
628
+
629
+ if (Array.isArray(entry.value)) {
630
+ const importDep = findImportDep(
631
+ templateContext.module.dependencies,
632
+ entry.value[0],
633
+ entry.value[2]
634
+ );
685
635
  if (!importDep) return references;
686
636
 
687
637
  const module =
@@ -689,55 +639,60 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
689
639
  (templateContext.moduleGraph.getModule(importDep));
690
640
  if (!module) return references;
691
641
 
692
- for (const d of module.dependencies) {
693
- if (d instanceof CssIcssExportDependency && d.name === dep.value[1]) {
642
+ // Same overridden context and target name for every matched entry — build once, not per entry.
643
+ const subContext = { ...templateContext, module };
644
+ const name = /** @type {string[]} */ (entry.value)[1];
645
+ for (const dep of module.dependencies) {
646
+ if (!(dep instanceof CssIcssExportDependency)) continue;
647
+ const matches = indexEntries(indexCache, dep).get(name);
648
+ if (!matches) continue;
649
+ for (const d of matches) {
694
650
  if (Array.isArray(d.value)) {
695
- const deepReferences =
696
- CssIcssExportDependencyTemplate._doResolveReferences(
651
+ references.push(
652
+ ...CssIcssExportDependencyTemplate.resolveReferences(
697
653
  d,
698
- {
699
- ...templateContext,
700
- module
701
- },
702
- seen
703
- );
704
-
705
- references.push(...deepReferences);
654
+ subContext,
655
+ seen,
656
+ indexCache
657
+ )
658
+ );
706
659
  } else {
707
660
  references.push(
708
- CssIcssExportDependencyTemplate.getIdentifier(d.value, d, {
709
- ...templateContext,
710
- module
711
- })
661
+ CssIcssExportDependencyTemplate.getIdentifier(
662
+ d.value,
663
+ d,
664
+ subContext
665
+ )
712
666
  );
713
667
  }
714
668
  }
715
669
  }
716
670
  } else {
717
- // Adding basic class
718
671
  references.push(
719
672
  CssIcssExportDependencyTemplate.getIdentifier(
720
- dep.value,
721
- dep,
673
+ /** @type {string} */ (entry.value),
674
+ entry,
722
675
  templateContext
723
676
  )
724
677
  );
725
678
 
726
- for (const d of templateContext.module.dependencies) {
727
- if (
728
- d instanceof CssIcssExportDependency &&
729
- d.exportType === CssIcssExportDependency.EXPORT_TYPE.COMPOSES &&
730
- d.name === dep.value
731
- ) {
679
+ for (const dep of templateContext.module.dependencies) {
680
+ if (!(dep instanceof CssIcssExportDependency)) continue;
681
+ const matches = indexEntries(indexCache, dep).get(
682
+ /** @type {string} */ (entry.value)
683
+ );
684
+ if (!matches) continue;
685
+ for (const d of matches) {
686
+ if (d.exportType !== EXPORT_TYPE.COMPOSES) continue;
732
687
  if (Array.isArray(d.value)) {
733
- const deepReferences =
734
- CssIcssExportDependencyTemplate._doResolveReferences(
688
+ references.push(
689
+ ...CssIcssExportDependencyTemplate.resolveReferences(
735
690
  d,
736
691
  templateContext,
737
- seen
738
- );
739
-
740
- references.push(...deepReferences);
692
+ seen,
693
+ indexCache
694
+ )
695
+ );
741
696
  } else {
742
697
  references.push(
743
698
  CssIcssExportDependencyTemplate.getIdentifier(
@@ -751,30 +706,25 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
751
706
  }
752
707
  }
753
708
 
754
- return [...new Set(references)];
709
+ return references.length > 1 ? [...new Set(references)] : references;
755
710
  }
756
711
 
757
712
  /**
758
- * Returns identifier. When the dep opts into interpolation the full
759
- * computation is memoized via `moduleGraph.cached` keyed by
760
- * `(module, value, exportType, chunkGraph, runtimeTemplate)` so
761
- * `cssExportConvention` / `getLocalIdent` / `escapeIdentifier` are not
762
- * re-run for the same identifier during code generation.
713
+ * Returns the interpolated identifier for an entry value.
763
714
  * @param {string} value value to identifier
764
- * @param {Dependency} dependency the dependency for which the template should be applied
715
+ * @param {CssExportEntry} entry the entry
765
716
  * @param {DependencyTemplateContext} templateContext the context object
766
717
  * @returns {string} identifier
767
718
  */
768
- static getIdentifier(value, dependency, templateContext) {
769
- const dep = /** @type {CssIcssExportDependency} */ (dependency);
770
- if (!dep.interpolate) return value;
719
+ static getIdentifier(value, entry, templateContext) {
720
+ if (!entry.interpolate) return value;
771
721
  const { moduleGraph, module, chunkGraph, runtimeTemplate } =
772
722
  templateContext;
773
723
  return moduleGraph.cached(
774
724
  computeInterpolatedIdentifier,
775
725
  /** @type {CssModule} */ (module),
776
726
  value,
777
- dep.exportType,
727
+ entry.exportType,
778
728
  chunkGraph,
779
729
  runtimeTemplate
780
730
  );
@@ -789,143 +739,131 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
789
739
  */
790
740
  apply(dependency, source, templateContext) {
791
741
  const dep = /** @type {CssIcssExportDependency} */ (dependency);
792
- if (!dep.range && templateContext.type !== JAVASCRIPT_TYPE) return;
793
742
  const { module: m, moduleGraph, runtime, cssData } = templateContext;
794
743
  const module = /** @type {CssModule} */ (m);
795
744
  const generator = /** @type {CssGenerator} */ (module.generator);
796
- const isReference = Array.isArray(dep.value);
797
-
798
- /** @type {string} */
799
- let value;
800
-
801
- // The `composes` has more complex logic for collecting all the classes
802
- if (
803
- dep.exportType === CssIcssExportDependency.EXPORT_TYPE.COMPOSES &&
804
- templateContext.type === JAVASCRIPT_TYPE
805
- ) {
806
- value = CssIcssExportDependencyTemplate.resolveReferences(
807
- dep,
808
- templateContext
809
- ).join(" ");
810
- } else if (isReference) {
811
- const resolved = CssIcssExportDependencyTemplate.resolve(
812
- dep.value[0],
813
- dep.value[1],
814
- templateContext,
815
- dep.value[2]
816
- );
745
+ const isJs = templateContext.type === JAVASCRIPT_TYPE;
746
+ // All entries belong to this one module, so resolve its ExportsInfo once
747
+ // instead of re-resolving `module -> exportsInfo` per export name.
748
+ const exportsInfo = isJs ? moduleGraph.getExportsInfo(module) : undefined;
749
+ // Transient name index for composes resolution within this module's codegen; GC'd when apply returns (never retained on the dependency).
750
+ /** @type {Map<CssIcssExportDependency, Map<string, CssExportEntry[]>>} */
751
+ const indexCache = new Map();
752
+
753
+ for (const entry of dep.entries) {
754
+ if (!entry.range && !isJs) continue;
755
+ const isReference = Array.isArray(entry.value);
817
756
 
818
- // Fallback to the local name if not resolved
819
- value = resolved || dep.value[0];
820
- } else {
821
- value = CssIcssExportDependencyTemplate.getIdentifier(
822
- /** @type {string} */ (dep.value),
823
- dep,
824
- templateContext
825
- );
826
- }
757
+ /** @type {string} */
758
+ let value;
759
+ if (entry.exportType === EXPORT_TYPE.COMPOSES && isJs) {
760
+ value = CssIcssExportDependencyTemplate.resolveReferences(
761
+ entry,
762
+ templateContext,
763
+ new Set(),
764
+ indexCache
765
+ ).join(" ");
766
+ } else if (isReference) {
767
+ const resolved = CssIcssExportDependencyTemplate.resolve(
768
+ /** @type {string[]} */ (entry.value)[0],
769
+ /** @type {string[]} */ (entry.value)[1],
770
+ templateContext,
771
+ /** @type {string[]} */ (entry.value)[2],
772
+ new Set(),
773
+ indexCache
774
+ );
775
+ value = resolved || /** @type {string[]} */ (entry.value)[0];
776
+ } else {
777
+ value = CssIcssExportDependencyTemplate.getIdentifier(
778
+ /** @type {string} */ (entry.value),
779
+ entry,
780
+ templateContext
781
+ );
782
+ }
827
783
 
828
- if (
829
- dep.exportType ===
830
- CssIcssExportDependency.EXPORT_TYPE.GRID_CUSTOM_IDENTIFIER
831
- ) {
832
- value += `-${dep.name}`;
833
- }
784
+ if (entry.exportType === EXPORT_TYPE.GRID_CUSTOM_IDENTIFIER) {
785
+ value += `-${entry.name}`;
786
+ }
834
787
 
835
- if (
836
- templateContext.type === JAVASCRIPT_TYPE &&
837
- dep.exportMode !== CssIcssExportDependency.EXPORT_MODE.NONE
838
- ) {
839
- const names = dep.getExportsConventionNames(
840
- dep.name,
841
- /** @type {CssGeneratorExportsConvention} */
842
- (generator.options.exportsConvention)
843
- );
844
- const usedNames =
845
- /** @type {string[]} */
846
- (
847
- names
848
- .map((name) =>
849
- moduleGraph.getExportInfo(module, name).getUsedName(name, runtime)
850
- )
851
- .filter(Boolean)
788
+ if (isJs && entry.exportMode !== EXPORT_MODE.NONE) {
789
+ const names = entryConventionNames(
790
+ entry,
791
+ /** @type {CssGeneratorExportsConvention} */
792
+ (generator.options.exportsConvention)
793
+ );
794
+ /** @type {Set<string>} */
795
+ const allNames = new Set();
796
+ for (const name of names) {
797
+ const usedName = /** @type {NonNullable<typeof exportsInfo>} */ (
798
+ exportsInfo
799
+ )
800
+ .getExportInfo(name)
801
+ .getUsedName(name, runtime);
802
+ if (usedName) allNames.add(/** @type {string} */ (usedName));
803
+ }
804
+ for (const name of names) allNames.add(name);
805
+ const unescaped = getCssTokens().unescapeIdentifier(
806
+ value,
807
+ templateContext.runtimeTemplate.compilation.compiler.root
852
808
  );
853
- const allNames = new Set([...usedNames, ...names]);
854
- const unescaped = getCssParser().unescapeIdentifier(
855
- value,
856
- templateContext.runtimeTemplate.compilation.compiler.root
857
- );
858
809
 
859
- const depLocStart =
860
- dep.loc &&
861
- /** @type {{ start?: { line: number, column: number } }} */ (dep.loc)
862
- .start;
863
- for (const used of allNames) {
864
- if (dep.exportMode === CssIcssExportDependency.EXPORT_MODE.ONCE) {
865
- if (cssData.exports.has(used)) return;
866
- cssData.exports.set(used, unescaped);
867
- if (
868
- depLocStart &&
869
- cssData.exportLocs &&
870
- !cssData.exportLocs.has(used)
871
- ) {
872
- cssData.exportLocs.set(used, {
873
- line: depLocStart.line,
874
- column: depLocStart.column
875
- });
876
- }
877
- } else {
878
- const originalValue =
879
- dep.exportMode === CssIcssExportDependency.EXPORT_MODE.REPLACE
880
- ? undefined
881
- : cssData.exports.get(used);
882
-
883
- cssData.exports.set(
884
- used,
885
- `${originalValue ? `${originalValue}${unescaped ? " " : ""}` : ""}${unescaped}`
886
- );
887
- // Record the source location once per export (use the first
888
- // occurrence — for APPEND/REPLACE this corresponds to the
889
- // first selector seen, which is a reasonable anchor).
890
- if (
891
- depLocStart &&
892
- cssData.exportLocs &&
893
- !cssData.exportLocs.has(used)
894
- ) {
895
- cssData.exportLocs.set(used, {
896
- line: depLocStart.line,
897
- column: depLocStart.column
898
- });
810
+ const depLocStart =
811
+ entry.loc &&
812
+ /** @type {{ start?: { line: number, column: number } }} */ (
813
+ entry.loc
814
+ ).start;
815
+ for (const used of allNames) {
816
+ if (entry.exportMode === EXPORT_MODE.ONCE) {
817
+ if (cssData.exports.has(used)) continue;
818
+ cssData.exports.set(used, unescaped);
819
+ if (
820
+ depLocStart &&
821
+ cssData.exportLocs &&
822
+ !cssData.exportLocs.has(used)
823
+ ) {
824
+ cssData.exportLocs.set(used, {
825
+ line: depLocStart.line,
826
+ column: depLocStart.column
827
+ });
828
+ }
829
+ } else {
830
+ const originalValue =
831
+ entry.exportMode === EXPORT_MODE.REPLACE
832
+ ? undefined
833
+ : cssData.exports.get(used);
834
+ cssData.exports.set(
835
+ used,
836
+ `${originalValue ? `${originalValue}${unescaped ? " " : ""}` : ""}${unescaped}`
837
+ );
838
+ if (
839
+ depLocStart &&
840
+ cssData.exportLocs &&
841
+ !cssData.exportLocs.has(used)
842
+ ) {
843
+ cssData.exportLocs.set(used, {
844
+ line: depLocStart.line,
845
+ column: depLocStart.column
846
+ });
847
+ }
899
848
  }
900
849
  }
850
+ } else if (
851
+ entry.range &&
852
+ templateContext.type !== JAVASCRIPT_TYPE &&
853
+ entry.exportMode !== EXPORT_MODE.APPEND &&
854
+ entry.exportMode !== EXPORT_MODE.SELF_REFERENCE
855
+ ) {
856
+ source.replace(entry.range[0], entry.range[1] - 1, value);
901
857
  }
902
- } else if (
903
- dep.range &&
904
- templateContext.type === CSS_TYPE &&
905
- dep.exportMode !== CssIcssExportDependency.EXPORT_MODE.APPEND &&
906
- dep.exportMode !== CssIcssExportDependency.EXPORT_MODE.SELF_REFERENCE
907
- ) {
908
- source.replace(dep.range[0], dep.range[1] - 1, value);
909
858
  }
910
859
  }
911
860
  };
912
861
 
913
862
  /** @type {Record<"NONE" | "REPLACE" | "APPEND" | "ONCE" | "SELF_REFERENCE", ExportMode>} */
914
- CssIcssExportDependency.EXPORT_MODE = {
915
- NONE: 0,
916
- REPLACE: 1,
917
- APPEND: 2,
918
- ONCE: 3,
919
- SELF_REFERENCE: 4
920
- };
863
+ CssIcssExportDependency.EXPORT_MODE = EXPORT_MODE;
921
864
 
922
865
  /** @type {Record<"NORMAL" | "CUSTOM_VARIABLE" | "GRID_CUSTOM_IDENTIFIER" | "COMPOSES", ExportType>} */
923
- CssIcssExportDependency.EXPORT_TYPE = {
924
- NORMAL: 0,
925
- CUSTOM_VARIABLE: 1,
926
- GRID_CUSTOM_IDENTIFIER: 2,
927
- COMPOSES: 3
928
- };
866
+ CssIcssExportDependency.EXPORT_TYPE = EXPORT_TYPE;
929
867
 
930
868
  makeSerializable(
931
869
  CssIcssExportDependency,