webpack 5.106.1 → 5.107.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 (600) hide show
  1. package/README.md +2 -2
  2. package/lib/APIPlugin.js +4 -2
  3. package/lib/AsyncDependenciesBlock.js +3 -0
  4. package/lib/AutomaticPrefetchPlugin.js +6 -1
  5. package/lib/BannerPlugin.js +10 -1
  6. package/lib/Cache.js +27 -5
  7. package/lib/CacheFacade.js +26 -0
  8. package/lib/Chunk.js +46 -0
  9. package/lib/ChunkGraph.js +111 -0
  10. package/lib/ChunkGroup.js +57 -13
  11. package/lib/ChunkTemplate.js +9 -0
  12. package/lib/CleanPlugin.js +14 -1
  13. package/lib/CodeGenerationResults.js +19 -0
  14. package/lib/CompatibilityPlugin.js +23 -8
  15. package/lib/Compilation.js +161 -27
  16. package/lib/Compiler.js +41 -17
  17. package/lib/ConcatenationScope.js +24 -1
  18. package/lib/ConditionalInitFragment.js +6 -0
  19. package/lib/ConstPlugin.js +4 -1
  20. package/lib/ContextExclusionPlugin.js +2 -1
  21. package/lib/ContextModule.js +14 -2
  22. package/lib/ContextModuleFactory.js +10 -0
  23. package/lib/ContextReplacementPlugin.js +4 -1
  24. package/lib/DefinePlugin.js +22 -9
  25. package/lib/DependenciesBlock.js +6 -1
  26. package/lib/Dependency.js +48 -4
  27. package/lib/DependencyTemplate.js +7 -1
  28. package/lib/DependencyTemplates.js +4 -0
  29. package/lib/DotenvPlugin.js +3 -0
  30. package/lib/DynamicEntryPlugin.js +3 -1
  31. package/lib/EntryOptionPlugin.js +3 -0
  32. package/lib/EntryPlugin.js +2 -1
  33. package/lib/Entrypoint.js +4 -0
  34. package/lib/EnvironmentPlugin.js +3 -2
  35. package/lib/ErrorHelpers.js +7 -0
  36. package/lib/EvalDevToolModulePlugin.js +3 -1
  37. package/lib/EvalSourceMapDevToolPlugin.js +11 -10
  38. package/lib/ExportsInfo.js +56 -2
  39. package/lib/ExportsInfoApiPlugin.js +2 -1
  40. package/lib/ExternalModule.js +114 -15
  41. package/lib/ExternalModuleFactoryPlugin.js +15 -0
  42. package/lib/ExternalsPlugin.js +2 -1
  43. package/lib/FileSystemInfo.js +291 -71
  44. package/lib/FlagAllModulesAsUsedPlugin.js +2 -1
  45. package/lib/FlagDependencyExportsPlugin.js +4 -1
  46. package/lib/FlagDependencyUsagePlugin.js +5 -1
  47. package/lib/FlagEntryExportAsUsedPlugin.js +2 -1
  48. package/lib/Generator.js +16 -3
  49. package/lib/HotModuleReplacementPlugin.js +35 -9
  50. package/lib/IgnorePlugin.js +4 -2
  51. package/lib/IgnoreWarningsPlugin.js +2 -1
  52. package/lib/InitFragment.js +10 -0
  53. package/lib/JavascriptMetaInfoPlugin.js +2 -1
  54. package/lib/LibraryTemplatePlugin.js +2 -1
  55. package/lib/LoaderOptionsPlugin.js +3 -1
  56. package/lib/LoaderTargetPlugin.js +2 -1
  57. package/lib/MainTemplate.js +15 -0
  58. package/lib/ManifestPlugin.js +9 -2
  59. package/lib/Module.js +101 -19
  60. package/lib/ModuleFactory.js +6 -1
  61. package/lib/ModuleFilenameHelpers.js +3 -0
  62. package/lib/ModuleGraph.js +66 -0
  63. package/lib/ModuleGraphConnection.js +9 -0
  64. package/lib/ModuleInfoHeaderPlugin.js +5 -0
  65. package/lib/ModuleSourceTypeConstants.js +32 -1
  66. package/lib/ModuleTemplate.js +8 -0
  67. package/lib/ModuleTypeConstants.js +12 -3
  68. package/lib/MultiCompiler.js +30 -2
  69. package/lib/MultiStats.js +8 -0
  70. package/lib/MultiWatching.js +3 -0
  71. package/lib/NoEmitOnErrorsPlugin.js +1 -1
  72. package/lib/NodeStuffPlugin.js +11 -2
  73. package/lib/NormalModule.js +43 -33
  74. package/lib/NormalModuleFactory.js +35 -2
  75. package/lib/NormalModuleReplacementPlugin.js +1 -1
  76. package/lib/NullFactory.js +1 -0
  77. package/lib/OptionsApply.js +1 -0
  78. package/lib/Parser.js +3 -1
  79. package/lib/PlatformPlugin.js +2 -1
  80. package/lib/PrefetchPlugin.js +2 -1
  81. package/lib/ProgressPlugin.js +158 -68
  82. package/lib/ProvidePlugin.js +3 -1
  83. package/lib/RawModule.js +12 -0
  84. package/lib/RecordIdsPlugin.js +8 -0
  85. package/lib/RequestShortener.js +8 -0
  86. package/lib/ResolverFactory.js +5 -0
  87. package/lib/RuntimeGlobals.js +6 -5
  88. package/lib/RuntimeModule.js +22 -7
  89. package/lib/RuntimePlugin.js +13 -0
  90. package/lib/RuntimeTemplate.js +35 -1
  91. package/lib/SelfModuleFactory.js +2 -0
  92. package/lib/SourceMapDevToolModuleOptionsPlugin.js +2 -0
  93. package/lib/SourceMapDevToolPlugin.js +3 -1
  94. package/lib/Stats.js +5 -0
  95. package/lib/Template.js +20 -0
  96. package/lib/TemplatedPathPlugin.js +10 -3
  97. package/lib/UseStrictPlugin.js +2 -1
  98. package/lib/WarnCaseSensitiveModulesPlugin.js +71 -3
  99. package/lib/WarnDeprecatedOptionPlugin.js +2 -2
  100. package/lib/WarnNoModeSetPlugin.js +17 -2
  101. package/lib/WatchIgnorePlugin.js +4 -1
  102. package/lib/Watching.js +16 -3
  103. package/lib/WebpackError.js +3 -74
  104. package/lib/WebpackIsIncludedPlugin.js +3 -1
  105. package/lib/WebpackOptionsApply.js +14 -1
  106. package/lib/WebpackOptionsDefaulter.js +1 -0
  107. package/lib/asset/AssetBytesGenerator.js +12 -2
  108. package/lib/asset/AssetBytesParser.js +1 -0
  109. package/lib/asset/AssetGenerator.js +42 -10
  110. package/lib/asset/AssetModulesPlugin.js +7 -2
  111. package/lib/asset/AssetParser.js +2 -0
  112. package/lib/asset/AssetSourceGenerator.js +12 -2
  113. package/lib/asset/AssetSourceParser.js +1 -0
  114. package/lib/asset/RawDataUrlModule.js +11 -0
  115. package/lib/async-modules/AsyncModuleHelpers.js +1 -0
  116. package/lib/async-modules/AwaitDependenciesInitFragment.js +4 -0
  117. package/lib/async-modules/InferAsyncModulesPlugin.js +1 -1
  118. package/lib/buildChunkGraph.js +19 -6
  119. package/lib/cache/AddBuildDependenciesPlugin.js +2 -1
  120. package/lib/cache/AddManagedPathsPlugin.js +2 -1
  121. package/lib/cache/IdleFileCachePlugin.js +2 -1
  122. package/lib/cache/MemoryCachePlugin.js +1 -1
  123. package/lib/cache/MemoryWithGcCachePlugin.js +3 -1
  124. package/lib/cache/PackFileCacheStrategy.js +33 -4
  125. package/lib/cache/ResolverCachePlugin.js +10 -1
  126. package/lib/cache/getLazyHashedEtag.js +4 -0
  127. package/lib/cache/mergeEtags.js +2 -0
  128. package/lib/cli.js +33 -1
  129. package/lib/config/browserslistTargetHandler.js +2 -0
  130. package/lib/config/defaults.js +232 -12
  131. package/lib/config/normalization.js +15 -1
  132. package/lib/config/target.js +11 -0
  133. package/lib/container/ContainerEntryDependency.js +2 -0
  134. package/lib/container/ContainerEntryModule.js +12 -0
  135. package/lib/container/ContainerEntryModuleFactory.js +1 -0
  136. package/lib/container/ContainerExposedDependency.js +4 -0
  137. package/lib/container/ContainerPlugin.js +2 -1
  138. package/lib/container/ContainerReferencePlugin.js +2 -1
  139. package/lib/container/FallbackDependency.js +4 -0
  140. package/lib/container/FallbackItemDependency.js +1 -0
  141. package/lib/container/FallbackModule.js +12 -0
  142. package/lib/container/FallbackModuleFactory.js +1 -0
  143. package/lib/container/ModuleFederationPlugin.js +3 -1
  144. package/lib/container/RemoteModule.js +13 -0
  145. package/lib/container/RemoteRuntimeModule.js +1 -0
  146. package/lib/container/RemoteToExternalDependency.js +1 -0
  147. package/lib/container/options.js +7 -0
  148. package/lib/css/CssGenerator.js +336 -100
  149. package/lib/css/CssInjectStyleRuntimeModule.js +45 -42
  150. package/lib/css/CssLoadingRuntimeModule.js +23 -4
  151. package/lib/{CssModule.js → css/CssModule.js} +21 -15
  152. package/lib/css/CssModulesPlugin.js +235 -89
  153. package/lib/css/CssParser.js +616 -261
  154. package/lib/css/walkCssTokens.js +179 -2
  155. package/lib/debug/ProfilingPlugin.js +19 -1
  156. package/lib/dependencies/AMDDefineDependency.js +7 -0
  157. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +12 -0
  158. package/lib/dependencies/AMDPlugin.js +4 -1
  159. package/lib/dependencies/AMDRequireArrayDependency.js +6 -0
  160. package/lib/dependencies/AMDRequireContextDependency.js +3 -0
  161. package/lib/dependencies/AMDRequireDependenciesBlock.js +1 -0
  162. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +14 -1
  163. package/lib/dependencies/AMDRequireDependency.js +4 -0
  164. package/lib/dependencies/AMDRequireItemDependency.js +1 -0
  165. package/lib/dependencies/AMDRuntimeModules.js +3 -0
  166. package/lib/dependencies/CachedConstDependency.js +6 -1
  167. package/lib/dependencies/CommonJsDependencyHelpers.js +64 -0
  168. package/lib/dependencies/CommonJsExportRequireDependency.js +62 -10
  169. package/lib/dependencies/CommonJsExportsDependency.js +4 -0
  170. package/lib/dependencies/CommonJsExportsParserPlugin.js +9 -1
  171. package/lib/dependencies/CommonJsFullRequireDependency.js +36 -9
  172. package/lib/dependencies/CommonJsImportsParserPlugin.js +24 -3
  173. package/lib/dependencies/CommonJsPlugin.js +4 -1
  174. package/lib/dependencies/CommonJsRequireContextDependency.js +3 -0
  175. package/lib/dependencies/CommonJsRequireDependency.js +70 -4
  176. package/lib/dependencies/CommonJsSelfReferenceDependency.js +5 -0
  177. package/lib/dependencies/ConstDependency.js +6 -1
  178. package/lib/dependencies/ContextDependency.js +9 -2
  179. package/lib/dependencies/ContextDependencyHelpers.js +4 -1
  180. package/lib/dependencies/ContextDependencyTemplateAsId.js +1 -0
  181. package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +1 -0
  182. package/lib/dependencies/ContextElementDependency.js +4 -0
  183. package/lib/dependencies/CreateRequireParserPlugin.js +7 -1
  184. package/lib/dependencies/CreateScriptUrlDependency.js +4 -0
  185. package/lib/dependencies/CriticalDependencyWarning.js +2 -1
  186. package/lib/dependencies/CssIcssExportDependency.js +339 -66
  187. package/lib/dependencies/CssIcssImportDependency.js +53 -8
  188. package/lib/dependencies/CssIcssSymbolDependency.js +16 -4
  189. package/lib/dependencies/CssImportDependency.js +12 -0
  190. package/lib/dependencies/CssUrlDependency.js +32 -0
  191. package/lib/dependencies/DelegatedSourceDependency.js +1 -0
  192. package/lib/dependencies/DllEntryDependency.js +3 -0
  193. package/lib/dependencies/DynamicExports.js +5 -0
  194. package/lib/dependencies/EntryDependency.js +1 -0
  195. package/lib/dependencies/ExportsInfoDependency.js +6 -0
  196. package/lib/dependencies/ExternalModuleDependency.js +5 -0
  197. package/lib/dependencies/ExternalModuleInitFragment.js +3 -0
  198. package/lib/dependencies/ExternalModuleInitFragmentDependency.js +4 -0
  199. package/lib/dependencies/HarmonyAcceptDependency.js +6 -0
  200. package/lib/dependencies/HarmonyAcceptImportDependency.js +1 -0
  201. package/lib/dependencies/HarmonyCompatibilityDependency.js +1 -0
  202. package/lib/dependencies/HarmonyDetectionParserPlugin.js +4 -1
  203. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +4 -0
  204. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +10 -7
  205. package/lib/dependencies/HarmonyExportExpressionDependency.js +27 -14
  206. package/lib/dependencies/HarmonyExportHeaderDependency.js +4 -0
  207. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +143 -5
  208. package/lib/dependencies/HarmonyExportInitFragment.js +6 -0
  209. package/lib/dependencies/HarmonyExportSpecifierDependency.js +5 -0
  210. package/lib/dependencies/HarmonyExports.js +2 -0
  211. package/lib/dependencies/HarmonyImportDependency.js +21 -2
  212. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +31 -1
  213. package/lib/dependencies/HarmonyImportSideEffectDependency.js +4 -0
  214. package/lib/dependencies/HarmonyImportSpecifierDependency.js +18 -3
  215. package/lib/{HarmonyLinkingError.js → dependencies/HarmonyLinkingError.js} +5 -3
  216. package/lib/dependencies/HarmonyModulesPlugin.js +4 -1
  217. package/lib/dependencies/HarmonyTopLevelThisParserPlugin.js +1 -0
  218. package/lib/dependencies/HtmlInlineScriptDependency.js +133 -0
  219. package/lib/dependencies/HtmlInlineStyleDependency.js +101 -0
  220. package/lib/dependencies/HtmlScriptSrcDependency.js +318 -0
  221. package/lib/dependencies/HtmlSourceDependency.js +127 -0
  222. package/lib/dependencies/ImportContextDependency.js +4 -0
  223. package/lib/dependencies/ImportDependency.js +5 -0
  224. package/lib/dependencies/ImportEagerDependency.js +2 -0
  225. package/lib/dependencies/ImportMetaContextDependency.js +1 -0
  226. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +4 -1
  227. package/lib/dependencies/ImportMetaContextPlugin.js +2 -1
  228. package/lib/dependencies/ImportMetaHotAcceptDependency.js +1 -0
  229. package/lib/dependencies/ImportMetaHotDeclineDependency.js +1 -0
  230. package/lib/dependencies/ImportMetaPlugin.js +6 -0
  231. package/lib/dependencies/ImportParserPlugin.js +9 -2
  232. package/lib/dependencies/ImportPhase.js +7 -3
  233. package/lib/dependencies/ImportPlugin.js +2 -1
  234. package/lib/dependencies/ImportWeakDependency.js +2 -0
  235. package/lib/dependencies/JsonExportsDependency.js +6 -1
  236. package/lib/dependencies/LoaderDependency.js +2 -0
  237. package/lib/dependencies/LoaderImportDependency.js +2 -0
  238. package/lib/dependencies/LoaderPlugin.js +4 -1
  239. package/lib/dependencies/LocalModule.js +4 -0
  240. package/lib/dependencies/LocalModuleDependency.js +4 -0
  241. package/lib/dependencies/LocalModulesHelpers.js +3 -0
  242. package/lib/dependencies/ModuleDecoratorDependency.js +7 -1
  243. package/lib/dependencies/ModuleDependency.js +7 -0
  244. package/lib/dependencies/ModuleDependencyTemplateAsId.js +1 -0
  245. package/lib/dependencies/ModuleDependencyTemplateAsRequireId.js +1 -0
  246. package/lib/dependencies/ModuleHotAcceptDependency.js +1 -0
  247. package/lib/dependencies/ModuleHotDeclineDependency.js +1 -0
  248. package/lib/dependencies/ModuleInitFragmentDependency.js +4 -0
  249. package/lib/dependencies/NullDependency.js +2 -0
  250. package/lib/dependencies/PrefetchDependency.js +1 -0
  251. package/lib/dependencies/ProvidedDependency.js +6 -1
  252. package/lib/dependencies/PureExpressionDependency.js +7 -1
  253. package/lib/dependencies/RequireContextDependency.js +1 -0
  254. package/lib/dependencies/RequireContextDependencyParserPlugin.js +1 -0
  255. package/lib/dependencies/RequireContextPlugin.js +2 -1
  256. package/lib/dependencies/RequireEnsureDependenciesBlock.js +1 -0
  257. package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +1 -0
  258. package/lib/dependencies/RequireEnsureDependency.js +4 -0
  259. package/lib/dependencies/RequireEnsureItemDependency.js +1 -0
  260. package/lib/dependencies/RequireEnsurePlugin.js +2 -1
  261. package/lib/dependencies/RequireHeaderDependency.js +4 -0
  262. package/lib/dependencies/RequireIncludeDependency.js +2 -0
  263. package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +4 -1
  264. package/lib/dependencies/RequireIncludePlugin.js +2 -1
  265. package/lib/{RequireJsStuffPlugin.js → dependencies/RequireJsStuffPlugin.js} +9 -8
  266. package/lib/dependencies/RequireResolveContextDependency.js +3 -0
  267. package/lib/dependencies/RequireResolveDependency.js +1 -0
  268. package/lib/dependencies/RequireResolveHeaderDependency.js +5 -0
  269. package/lib/dependencies/RuntimeRequirementsDependency.js +5 -1
  270. package/lib/dependencies/StaticExportsDependency.js +3 -0
  271. package/lib/dependencies/SystemPlugin.js +5 -2
  272. package/lib/dependencies/SystemRuntimeModule.js +1 -0
  273. package/lib/dependencies/URLContextDependency.js +3 -0
  274. package/lib/dependencies/URLDependency.js +6 -0
  275. package/lib/dependencies/URLPlugin.js +2 -0
  276. package/lib/dependencies/UnsupportedDependency.js +4 -0
  277. package/lib/dependencies/WebAssemblyExportImportedDependency.js +4 -0
  278. package/lib/dependencies/WebAssemblyImportDependency.js +5 -2
  279. package/lib/dependencies/WebpackIsIncludedDependency.js +2 -0
  280. package/lib/dependencies/WorkerDependency.js +6 -1
  281. package/lib/dependencies/WorkerPlugin.js +11 -3
  282. package/lib/dependencies/getFunctionExpression.js +1 -0
  283. package/lib/dependencies/processExportInfo.js +1 -0
  284. package/lib/{DelegatedModule.js → dll/DelegatedModule.js} +44 -31
  285. package/lib/{DelegatedModuleFactoryPlugin.js → dll/DelegatedModuleFactoryPlugin.js} +7 -4
  286. package/lib/{DelegatedPlugin.js → dll/DelegatedPlugin.js} +4 -3
  287. package/lib/{DllEntryPlugin.js → dll/DllEntryPlugin.js} +6 -5
  288. package/lib/{DllModule.js → dll/DllModule.js} +35 -24
  289. package/lib/{DllModuleFactory.js → dll/DllModuleFactory.js} +5 -4
  290. package/lib/{DllPlugin.js → dll/DllPlugin.js} +8 -6
  291. package/lib/{DllReferencePlugin.js → dll/DllReferencePlugin.js} +23 -18
  292. package/lib/{LibManifestPlugin.js → dll/LibManifestPlugin.js} +13 -10
  293. package/lib/electron/ElectronTargetPlugin.js +2 -1
  294. package/lib/{AbstractMethodError.js → errors/AbstractMethodError.js} +10 -1
  295. package/lib/{AsyncDependencyToInitialChunkError.js → errors/AsyncDependencyToInitialChunkError.js} +8 -3
  296. package/lib/errors/BuildCycleError.js +1 -1
  297. package/lib/{ChunkRenderError.js → errors/ChunkRenderError.js} +1 -1
  298. package/lib/{CodeGenerationError.js → errors/CodeGenerationError.js} +1 -1
  299. package/lib/{CommentCompilationWarning.js → errors/CommentCompilationWarning.js} +9 -3
  300. package/lib/{ConcurrentCompilationError.js → errors/ConcurrentCompilationError.js} +4 -2
  301. package/lib/{EnvironmentNotSupportAsyncWarning.js → errors/EnvironmentNotSupportAsyncWarning.js} +4 -4
  302. package/lib/{HookWebpackError.js → errors/HookWebpackError.js} +11 -5
  303. package/lib/{IgnoreErrorModuleFactory.js → errors/IgnoreErrorModuleFactory.js} +6 -4
  304. package/lib/{InvalidDependenciesModuleWarning.js → errors/InvalidDependenciesModuleWarning.js} +4 -3
  305. package/lib/errors/JSONParseError.js +114 -0
  306. package/lib/{ModuleBuildError.js → errors/ModuleBuildError.js} +8 -5
  307. package/lib/{ModuleDependencyError.js → errors/ModuleDependencyError.js} +2 -2
  308. package/lib/{ModuleDependencyWarning.js → errors/ModuleDependencyWarning.js} +5 -4
  309. package/lib/{ModuleError.js → errors/ModuleError.js} +7 -5
  310. package/lib/{ModuleHashingError.js → errors/ModuleHashingError.js} +1 -1
  311. package/lib/{ModuleNotFoundError.js → errors/ModuleNotFoundError.js} +3 -2
  312. package/lib/{ModuleParseError.js → errors/ModuleParseError.js} +11 -6
  313. package/lib/{ModuleRestoreError.js → errors/ModuleRestoreError.js} +2 -1
  314. package/lib/{ModuleStoreError.js → errors/ModuleStoreError.js} +2 -1
  315. package/lib/{ModuleWarning.js → errors/ModuleWarning.js} +8 -5
  316. package/lib/{NodeStuffInWebError.js → errors/NodeStuffInWebError.js} +5 -4
  317. package/lib/errors/NonErrorEmittedError.js +28 -0
  318. package/lib/{UnhandledSchemeError.js → errors/UnhandledSchemeError.js} +8 -2
  319. package/lib/{UnsupportedFeatureWarning.js → errors/UnsupportedFeatureWarning.js} +4 -3
  320. package/lib/errors/WebpackError.js +84 -0
  321. package/lib/esm/ExportWebpackRequireRuntimeModule.js +2 -0
  322. package/lib/esm/ModuleChunkFormatPlugin.js +5 -1
  323. package/lib/esm/ModuleChunkLoadingPlugin.js +3 -1
  324. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +5 -0
  325. package/lib/hmr/HotModuleReplacementRuntimeModule.js +1 -0
  326. package/lib/hmr/JavascriptHotModuleReplacementHelper.js +1 -0
  327. package/lib/hmr/LazyCompilationPlugin.js +20 -1
  328. package/lib/hmr/lazyCompilationBackend.js +2 -0
  329. package/lib/html/HtmlGenerator.js +379 -0
  330. package/lib/html/HtmlModulesPlugin.js +433 -0
  331. package/lib/html/HtmlParser.js +1489 -0
  332. package/lib/html/walkHtmlTokens.js +2733 -0
  333. package/lib/ids/ChunkModuleIdRangePlugin.js +3 -1
  334. package/lib/ids/DeterministicChunkIdsPlugin.js +3 -1
  335. package/lib/ids/DeterministicModuleIdsPlugin.js +3 -1
  336. package/lib/ids/HashedModuleIdsPlugin.js +2 -1
  337. package/lib/ids/IdHelpers.js +22 -1
  338. package/lib/ids/NamedChunkIdsPlugin.js +3 -1
  339. package/lib/ids/NamedModuleIdsPlugin.js +3 -1
  340. package/lib/ids/NaturalChunkIdsPlugin.js +1 -1
  341. package/lib/ids/NaturalModuleIdsPlugin.js +1 -1
  342. package/lib/ids/OccurrenceChunkIdsPlugin.js +2 -1
  343. package/lib/ids/OccurrenceModuleIdsPlugin.js +4 -1
  344. package/lib/ids/SyncModuleIdsPlugin.js +3 -1
  345. package/lib/index.js +39 -15
  346. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +1 -1
  347. package/lib/javascript/BasicEvaluatedExpression.js +4 -2
  348. package/lib/javascript/ChunkFormatHelpers.js +2 -1
  349. package/lib/javascript/ChunkHelpers.js +1 -0
  350. package/lib/javascript/CommonJsChunkFormatPlugin.js +1 -1
  351. package/lib/javascript/EnableChunkLoadingPlugin.js +5 -1
  352. package/lib/javascript/JavascriptGenerator.js +10 -0
  353. package/lib/javascript/JavascriptModulesPlugin.js +112 -9
  354. package/lib/javascript/JavascriptParser.js +360 -16
  355. package/lib/javascript/JavascriptParserHelpers.js +7 -1
  356. package/lib/javascript/StartupHelpers.js +5 -0
  357. package/lib/json/JsonData.js +5 -0
  358. package/lib/json/JsonGenerator.js +21 -0
  359. package/lib/json/JsonModulesPlugin.js +1 -1
  360. package/lib/json/JsonParser.js +14 -25
  361. package/lib/library/AbstractLibraryPlugin.js +17 -2
  362. package/lib/library/AmdLibraryPlugin.js +8 -0
  363. package/lib/library/AssignLibraryPlugin.js +16 -0
  364. package/lib/library/EnableLibraryPlugin.js +8 -2
  365. package/lib/library/ExportPropertyLibraryPlugin.js +9 -0
  366. package/lib/{FalseIIFEUmdWarning.js → library/FalseIIFEUmdWarning.js} +1 -1
  367. package/lib/library/JsonpLibraryPlugin.js +8 -0
  368. package/lib/library/ModuleLibraryPlugin.js +86 -1
  369. package/lib/library/SystemLibraryPlugin.js +8 -0
  370. package/lib/library/UmdLibraryPlugin.js +16 -0
  371. package/lib/logging/Logger.js +17 -0
  372. package/lib/logging/createConsoleLogger.js +7 -0
  373. package/lib/logging/runtime.js +2 -0
  374. package/lib/logging/truncateArgs.js +2 -0
  375. package/lib/node/CommonJsChunkLoadingPlugin.js +5 -1
  376. package/lib/node/NodeEnvironmentPlugin.js +7 -3
  377. package/lib/node/NodeSourcePlugin.js +1 -1
  378. package/lib/node/NodeTargetPlugin.js +2 -1
  379. package/lib/node/NodeTemplatePlugin.js +3 -1
  380. package/lib/node/NodeWatchFileSystem.js +2 -0
  381. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +3 -0
  382. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +4 -1
  383. package/lib/node/ReadFileCompileWasmPlugin.js +4 -1
  384. package/lib/node/RequireChunkLoadingRuntimeModule.js +3 -0
  385. package/lib/node/nodeConsole.js +116 -64
  386. package/lib/optimize/AggressiveMergingPlugin.js +3 -1
  387. package/lib/optimize/AggressiveSplittingPlugin.js +6 -1
  388. package/lib/optimize/ConcatenatedModule.js +62 -6
  389. package/lib/optimize/EnsureChunkConditionsPlugin.js +2 -1
  390. package/lib/optimize/FlagIncludedChunksPlugin.js +2 -1
  391. package/lib/optimize/InnerGraph.js +16 -1
  392. package/lib/optimize/InnerGraphPlugin.js +14 -2
  393. package/lib/optimize/LimitChunkCountPlugin.js +9 -0
  394. package/lib/optimize/MangleExportsPlugin.js +5 -1
  395. package/lib/optimize/MergeDuplicateChunksPlugin.js +2 -0
  396. package/lib/optimize/MinChunkSizePlugin.js +2 -1
  397. package/lib/optimize/MinMaxSizeWarning.js +5 -4
  398. package/lib/optimize/ModuleConcatenationPlugin.js +36 -8
  399. package/lib/optimize/RealContentHashPlugin.js +104 -26
  400. package/lib/optimize/RemoveEmptyChunksPlugin.js +2 -1
  401. package/lib/optimize/RemoveParentModulesPlugin.js +3 -1
  402. package/lib/optimize/RuntimeChunkPlugin.js +2 -1
  403. package/lib/optimize/SideEffectsFlagPlugin.js +118 -4
  404. package/lib/optimize/SplitChunksPlugin.js +50 -2
  405. package/lib/performance/AssetsOverSizeLimitWarning.js +3 -2
  406. package/lib/performance/EntrypointsOverSizeLimitWarning.js +3 -2
  407. package/lib/performance/NoAsyncChunksWarning.js +5 -3
  408. package/lib/performance/SizeLimitsPlugin.js +8 -2
  409. package/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js +1 -0
  410. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +6 -0
  411. package/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js +1 -0
  412. package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +5 -1
  413. package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +1 -0
  414. package/lib/rules/BasicEffectRulePlugin.js +3 -0
  415. package/lib/rules/BasicMatcherRulePlugin.js +3 -0
  416. package/lib/rules/ObjectMatcherRulePlugin.js +3 -0
  417. package/lib/rules/RuleSetCompiler.js +18 -0
  418. package/lib/rules/UseEffectRulePlugin.js +10 -3
  419. package/lib/runtime/AsyncModuleRuntimeModule.js +1 -0
  420. package/lib/runtime/AutoPublicPathRuntimeModule.js +1 -0
  421. package/lib/runtime/BaseUriRuntimeModule.js +1 -0
  422. package/lib/runtime/ChunkNameRuntimeModule.js +1 -0
  423. package/lib/runtime/CompatGetDefaultExportRuntimeModule.js +1 -0
  424. package/lib/runtime/CompatRuntimeModule.js +2 -0
  425. package/lib/runtime/CreateFakeNamespaceObjectRuntimeModule.js +1 -0
  426. package/lib/runtime/CreateScriptRuntimeModule.js +1 -0
  427. package/lib/runtime/CreateScriptUrlRuntimeModule.js +1 -0
  428. package/lib/runtime/DefinePropertyGettersRuntimeModule.js +1 -0
  429. package/lib/runtime/EnsureChunkRuntimeModule.js +1 -0
  430. package/lib/runtime/GetChunkFilenameRuntimeModule.js +1 -0
  431. package/lib/runtime/GetFullHashRuntimeModule.js +1 -0
  432. package/lib/runtime/GetMainFilenameRuntimeModule.js +1 -0
  433. package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +1 -0
  434. package/lib/runtime/GlobalRuntimeModule.js +1 -0
  435. package/lib/runtime/HasOwnPropertyRuntimeModule.js +1 -0
  436. package/lib/runtime/HelperRuntimeModule.js +5 -0
  437. package/lib/runtime/LoadScriptRuntimeModule.js +1 -0
  438. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +121 -13
  439. package/lib/runtime/MakeNamespaceObjectRuntimeModule.js +1 -0
  440. package/lib/runtime/NonceRuntimeModule.js +1 -0
  441. package/lib/runtime/OnChunksLoadedRuntimeModule.js +1 -0
  442. package/lib/runtime/PublicPathRuntimeModule.js +1 -0
  443. package/lib/runtime/RelativeUrlRuntimeModule.js +1 -0
  444. package/lib/runtime/RuntimeIdRuntimeModule.js +1 -0
  445. package/lib/runtime/SetAnonymousDefaultNameRuntimeModule.js +35 -0
  446. package/lib/runtime/StartupChunkDependenciesPlugin.js +13 -1
  447. package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +1 -0
  448. package/lib/runtime/StartupEntrypointRuntimeModule.js +1 -0
  449. package/lib/runtime/SystemContextRuntimeModule.js +1 -0
  450. package/lib/runtime/ToBinaryRuntimeModule.js +1 -0
  451. package/lib/schemes/DataUriPlugin.js +14 -2
  452. package/lib/schemes/FileUriPlugin.js +1 -1
  453. package/lib/schemes/HttpUriPlugin.js +43 -1
  454. package/lib/schemes/VirtualUrlPlugin.js +7 -2
  455. package/lib/serialization/AggregateErrorSerializer.js +2 -0
  456. package/lib/serialization/ArraySerializer.js +2 -0
  457. package/lib/serialization/BinaryMiddleware.js +20 -1
  458. package/lib/serialization/DateObjectSerializer.js +2 -0
  459. package/lib/serialization/ErrorObjectSerializer.js +3 -0
  460. package/lib/serialization/FileMiddleware.js +21 -0
  461. package/lib/serialization/MapObjectSerializer.js +2 -0
  462. package/lib/serialization/NullPrototypeObjectSerializer.js +2 -0
  463. package/lib/serialization/ObjectMiddleware.js +23 -0
  464. package/lib/serialization/PlainObjectSerializer.js +7 -0
  465. package/lib/serialization/RegExpObjectSerializer.js +2 -0
  466. package/lib/serialization/Serializer.js +5 -0
  467. package/lib/serialization/SerializerMiddleware.js +14 -2
  468. package/lib/serialization/SetObjectSerializer.js +2 -0
  469. package/lib/serialization/SingleItemMiddleware.js +3 -0
  470. package/lib/sharing/ConsumeSharedFallbackDependency.js +1 -0
  471. package/lib/sharing/ConsumeSharedModule.js +15 -0
  472. package/lib/sharing/ConsumeSharedPlugin.js +8 -3
  473. package/lib/sharing/ConsumeSharedRuntimeModule.js +9 -4
  474. package/lib/sharing/ProvideForSharedDependency.js +1 -0
  475. package/lib/sharing/ProvideSharedDependency.js +4 -0
  476. package/lib/sharing/ProvideSharedModule.js +12 -1
  477. package/lib/sharing/ProvideSharedModuleFactory.js +1 -0
  478. package/lib/sharing/ProvideSharedPlugin.js +5 -2
  479. package/lib/sharing/SharePlugin.js +2 -1
  480. package/lib/sharing/ShareRuntimeModule.js +1 -0
  481. package/lib/sharing/resolveMatchedConfigs.js +4 -1
  482. package/lib/sharing/utils.js +8 -0
  483. package/lib/stats/DefaultStatsFactoryPlugin.js +58 -3
  484. package/lib/stats/DefaultStatsPresetPlugin.js +12 -2
  485. package/lib/stats/DefaultStatsPrinterPlugin.js +38 -2
  486. package/lib/stats/StatsFactory.js +13 -1
  487. package/lib/stats/StatsPrinter.js +7 -0
  488. package/lib/typescript/TypeScriptPlugin.js +210 -0
  489. package/lib/url/URLParserPlugin.js +8 -2
  490. package/lib/util/AppendOnlyStackedSet.js +15 -0
  491. package/lib/util/ArrayHelpers.js +1 -0
  492. package/lib/util/ArrayQueue.js +10 -5
  493. package/lib/util/AsyncQueue.js +22 -2
  494. package/lib/util/Hash.js +2 -2
  495. package/lib/util/IterableHelpers.js +3 -0
  496. package/lib/util/LazyBucketSortedSet.js +21 -0
  497. package/lib/util/LazySet.js +39 -0
  498. package/lib/util/LocConverter.js +53 -0
  499. package/lib/util/ParallelismFactorCalculator.js +1 -0
  500. package/lib/util/Queue.js +6 -3
  501. package/lib/util/Semaphore.js +14 -1
  502. package/lib/util/SetHelpers.js +3 -0
  503. package/lib/util/SortableSet.js +7 -1
  504. package/lib/util/StackedCacheMap.js +20 -3
  505. package/lib/util/StackedMap.js +45 -0
  506. package/lib/util/StringXor.js +1 -1
  507. package/lib/util/TupleQueue.js +7 -3
  508. package/lib/util/TupleSet.js +13 -0
  509. package/lib/util/URLAbsoluteSpecifier.js +1 -0
  510. package/lib/util/WeakTupleMap.js +33 -0
  511. package/lib/util/binarySearchBounds.js +1 -0
  512. package/lib/util/cleverMerge.js +19 -2
  513. package/lib/util/comparators.js +34 -3
  514. package/lib/util/compileBooleanMatcher.js +9 -0
  515. package/lib/util/concatenate.js +9 -3
  516. package/lib/util/conventions.js +46 -1
  517. package/lib/util/createMappings.js +118 -0
  518. package/lib/util/dataURL.js +1 -0
  519. package/lib/util/deprecation.js +19 -0
  520. package/lib/util/deterministicGrouping.js +20 -0
  521. package/lib/util/extractSourceMap.js +1 -0
  522. package/lib/util/extractUrlAndGlobal.js +1 -0
  523. package/lib/util/findGraphRoots.js +5 -0
  524. package/lib/{formatLocation.js → util/formatLocation.js} +4 -2
  525. package/lib/{SizeFormatHelpers.js → util/formatSize.js} +4 -1
  526. package/lib/util/fs.js +71 -8
  527. package/lib/util/generateDebugId.js +1 -0
  528. package/lib/util/hash/BatchedHash.js +1 -0
  529. package/lib/util/hash/BulkUpdateHash.js +1 -0
  530. package/lib/util/hash/hash-digest.js +8 -0
  531. package/lib/util/hash/md4.js +1 -1
  532. package/lib/util/hash/wasm-hash.js +5 -0
  533. package/lib/util/hash/xxhash64.js +1 -1
  534. package/lib/util/identifier.js +67 -0
  535. package/lib/util/internalSerializables.js +35 -19
  536. package/lib/util/magicComment.js +10 -6
  537. package/lib/util/makeSerializable.js +6 -0
  538. package/lib/util/memoize.js +2 -0
  539. package/lib/util/mimeTypes.js +176 -0
  540. package/lib/util/nonNumericOnlyHash.js +1 -0
  541. package/lib/util/parseJson.js +41 -0
  542. package/lib/util/processAsyncTree.js +8 -0
  543. package/lib/util/property.js +1 -0
  544. package/lib/util/registerExternalSerializer.js +20 -0
  545. package/lib/util/removeBOM.js +1 -0
  546. package/lib/util/runtime.js +32 -0
  547. package/lib/util/semver.js +15 -0
  548. package/lib/util/serialization.js +2 -0
  549. package/lib/util/smartGrouping.js +8 -0
  550. package/lib/util/source.js +23 -0
  551. package/lib/util/topologicalSort.js +69 -0
  552. package/lib/validateSchema.js +1 -0
  553. package/lib/wasm/EnableWasmLoadingPlugin.js +15 -1
  554. package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +1 -0
  555. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +1 -0
  556. package/lib/wasm-async/AsyncWebAssemblyGenerator.js +6 -0
  557. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +5 -0
  558. package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +12 -3
  559. package/lib/wasm-async/AsyncWebAssemblyParser.js +2 -1
  560. package/lib/wasm-async/UniversalCompileAsyncWasmPlugin.js +12 -1
  561. package/lib/wasm-sync/UnsupportedWebAssemblyFeatureError.js +6 -3
  562. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +1 -0
  563. package/lib/wasm-sync/WasmFinalizeExportsPlugin.js +2 -2
  564. package/lib/wasm-sync/WebAssemblyGenerator.js +26 -1
  565. package/lib/wasm-sync/WebAssemblyInInitialChunkError.js +7 -3
  566. package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +4 -0
  567. package/lib/wasm-sync/WebAssemblyModulesPlugin.js +10 -1
  568. package/lib/wasm-sync/WebAssemblyParser.js +2 -0
  569. package/lib/wasm-sync/WebAssemblyUtils.js +2 -0
  570. package/lib/web/FetchCompileAsyncWasmPlugin.js +10 -1
  571. package/lib/web/FetchCompileWasmPlugin.js +13 -1
  572. package/lib/web/JsonpChunkLoadingPlugin.js +11 -1
  573. package/lib/web/JsonpChunkLoadingRuntimeModule.js +1 -0
  574. package/lib/web/JsonpTemplatePlugin.js +2 -1
  575. package/lib/webpack.js +13 -1
  576. package/lib/webworker/ImportScriptsChunkLoadingPlugin.js +10 -1
  577. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +1 -0
  578. package/lib/webworker/WebWorkerTemplatePlugin.js +1 -1
  579. package/package.json +31 -31
  580. package/schemas/WebpackOptions.check.js +1 -1
  581. package/schemas/WebpackOptions.json +161 -57
  582. package/schemas/plugins/{DllPlugin.check.d.ts → HtmlGeneratorOptions.check.d.ts} +1 -1
  583. package/schemas/plugins/HtmlGeneratorOptions.check.js +6 -0
  584. package/schemas/plugins/HtmlGeneratorOptions.json +3 -0
  585. package/schemas/plugins/ProgressPlugin.check.js +1 -1
  586. package/schemas/plugins/ProgressPlugin.json +22 -0
  587. package/schemas/plugins/{DllReferencePlugin.check.d.ts → css/CssAutoOrModuleParserOptions.check.d.ts} +1 -1
  588. package/schemas/plugins/css/CssAutoOrModuleParserOptions.check.js +6 -0
  589. package/schemas/plugins/css/CssAutoOrModuleParserOptions.json +3 -0
  590. package/schemas/plugins/dll/DllPlugin.check.d.ts +7 -0
  591. package/schemas/plugins/dll/DllReferencePlugin.check.d.ts +7 -0
  592. package/types.d.ts +5325 -353
  593. package/lib/CaseSensitiveModulesWarning.js +0 -72
  594. package/lib/GraphHelpers.js +0 -46
  595. package/lib/NoModeWarning.js +0 -23
  596. package/lib/css/CssMergeStyleSheetsRuntimeModule.js +0 -56
  597. /package/schemas/plugins/{DllPlugin.check.js → dll/DllPlugin.check.js} +0 -0
  598. /package/schemas/plugins/{DllPlugin.json → dll/DllPlugin.json} +0 -0
  599. /package/schemas/plugins/{DllReferencePlugin.check.js → dll/DllReferencePlugin.check.js} +0 -0
  600. /package/schemas/plugins/{DllReferencePlugin.json → dll/DllReferencePlugin.json} +0 -0
@@ -5,13 +5,10 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ const path = require("path");
8
9
  const vm = require("vm");
9
- const CommentCompilationWarning = require("../CommentCompilationWarning");
10
- const ModuleDependencyWarning = require("../ModuleDependencyWarning");
11
10
  const { CSS_MODULE_TYPE_AUTO } = require("../ModuleTypeConstants");
12
11
  const Parser = require("../Parser");
13
- const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning");
14
- const WebpackError = require("../WebpackError");
15
12
  const ConstDependency = require("../dependencies/ConstDependency");
16
13
  const CssIcssExportDependency = require("../dependencies/CssIcssExportDependency");
17
14
  const CssIcssImportDependency = require("../dependencies/CssIcssImportDependency");
@@ -19,12 +16,18 @@ const CssIcssSymbolDependency = require("../dependencies/CssIcssSymbolDependency
19
16
  const CssImportDependency = require("../dependencies/CssImportDependency");
20
17
  const CssUrlDependency = require("../dependencies/CssUrlDependency");
21
18
  const StaticExportsDependency = require("../dependencies/StaticExportsDependency");
19
+ const CommentCompilationWarning = require("../errors/CommentCompilationWarning");
20
+ const ModuleDependencyWarning = require("../errors/ModuleDependencyWarning");
21
+ const UnsupportedFeatureWarning = require("../errors/UnsupportedFeatureWarning");
22
+ const WebpackError = require("../errors/WebpackError");
23
+ const LocConverter = require("../util/LocConverter");
22
24
  const binarySearchBounds = require("../util/binarySearchBounds");
23
25
  const { parseResource } = require("../util/identifier");
24
26
  const {
25
27
  createMagicCommentContext,
26
28
  webpackCommentRegExp
27
29
  } = require("../util/magicComment");
30
+ const topologicalSort = require("../util/topologicalSort");
28
31
  const walkCssTokens = require("./walkCssTokens");
29
32
 
30
33
  /** @typedef {import("../Module").BuildInfo} BuildInfo */
@@ -32,8 +35,9 @@ const walkCssTokens = require("./walkCssTokens");
32
35
  /** @typedef {import("../Parser").ParserState} ParserState */
33
36
  /** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
34
37
  /** @typedef {import("./walkCssTokens").CssTokenCallbacks} CssTokenCallbacks */
38
+ /** @typedef {import("../../declarations/WebpackOptions").CssAutoOrModuleParserOptions} CssAutoOrModuleParserOptions */
35
39
  /** @typedef {import("../../declarations/WebpackOptions").CssModuleParserOptions} CssModuleParserOptions */
36
- /** @typedef {import("../CssModule")} CssModule */
40
+ /** @typedef {import("./CssModule")} CssModule */
37
41
 
38
42
  /** @typedef {[number, number]} Range */
39
43
  /** @typedef {{ line: number, column: number }} Position */
@@ -52,6 +56,7 @@ const CC_TILDE = "~".charCodeAt(0);
52
56
  const CC_EQUAL = "=".charCodeAt(0);
53
57
  const CC_FULL_STOP = ".".charCodeAt(0);
54
58
  const CC_EXCLAMATION = "!".charCodeAt(0);
59
+ const CC_AMPERSAND = "&".charCodeAt(0);
55
60
 
56
61
  // https://www.w3.org/TR/css-syntax-3/#newline
57
62
  // We don't have `preprocessing` stage, so we need specify all of them
@@ -66,6 +71,7 @@ const IS_MODULES = /\.modules?\.[^.]+$/i;
66
71
  const CSS_COMMENT = /\/\*((?!\*\/)[\s\S]*?)\*\//g;
67
72
 
68
73
  /**
74
+ * Returns matches.
69
75
  * @param {RegExp} regexp a regexp
70
76
  * @param {string} str a string
71
77
  * @returns {RegExpExecArray[]} matches
@@ -87,6 +93,7 @@ const matchAll = (regexp, str) => {
87
93
  };
88
94
 
89
95
  /**
96
+ * Returns normalized url.
90
97
  * @param {string} str url string
91
98
  * @param {boolean} isString is url wrapped in quotes
92
99
  * @returns {string} normalized url
@@ -126,135 +133,7 @@ const normalizeUrl = (str, isString) => {
126
133
  return str;
127
134
  };
128
135
 
129
- const regexSingleEscape = /[ -,./:-@[\]^`{-~]/;
130
- const regexExcessiveSpaces =
131
- /(^|\\+)?(\\[A-F0-9]{1,6})\u0020(?![a-fA-F0-9\u0020])/g;
132
-
133
- /**
134
- * @param {string} str string
135
- * @returns {string} escaped identifier
136
- */
137
- const escapeIdentifier = (str) => {
138
- let output = "";
139
- let counter = 0;
140
-
141
- while (counter < str.length) {
142
- const character = str.charAt(counter++);
143
-
144
- /** @type {string} */
145
- let value;
146
-
147
- if (/[\t\n\f\r\v]/.test(character)) {
148
- const codePoint = character.charCodeAt(0);
149
-
150
- value = `\\${codePoint.toString(16).toUpperCase()} `;
151
- } else if (character === "\\" || regexSingleEscape.test(character)) {
152
- value = `\\${character}`;
153
- } else {
154
- value = character;
155
- }
156
-
157
- output += value;
158
- }
159
-
160
- const firstChar = str.charAt(0);
161
-
162
- if (/^-[-\d]/.test(output)) {
163
- output = `\\-${output.slice(1)}`;
164
- } else if (/\d/.test(firstChar)) {
165
- output = `\\3${firstChar} ${output.slice(1)}`;
166
- }
167
-
168
- // Remove spaces after `\HEX` escapes that are not followed by a hex digit,
169
- // since they’re redundant. Note that this is only possible if the escape
170
- // sequence isn’t preceded by an odd number of backslashes.
171
- output = output.replace(regexExcessiveSpaces, ($0, $1, $2) => {
172
- if ($1 && $1.length % 2) {
173
- // It’s not safe to remove the space, so don’t.
174
- return $0;
175
- }
176
-
177
- // Strip the space.
178
- return ($1 || "") + $2;
179
- });
180
-
181
- return output;
182
- };
183
-
184
- const CONTAINS_ESCAPE = /\\/;
185
-
186
- /**
187
- * @param {string} str string
188
- * @returns {[string, number] | undefined} hex
189
- */
190
- const gobbleHex = (str) => {
191
- const lower = str.toLowerCase();
192
- let hex = "";
193
- let spaceTerminated = false;
194
-
195
- for (let i = 0; i < 6 && lower[i] !== undefined; i++) {
196
- const code = lower.charCodeAt(i);
197
- // check to see if we are dealing with a valid hex char [a-f|0-9]
198
- const valid = (code >= 97 && code <= 102) || (code >= 48 && code <= 57);
199
- // https://drafts.csswg.org/css-syntax/#consume-escaped-code-point
200
- spaceTerminated = code === 32;
201
- if (!valid) break;
202
- hex += lower[i];
203
- }
204
-
205
- if (hex.length === 0) return undefined;
206
-
207
- const codePoint = Number.parseInt(hex, 16);
208
- const isSurrogate = codePoint >= 0xd800 && codePoint <= 0xdfff;
209
-
210
- // Add special case for
211
- // "If this number is zero, or is for a surrogate, or is greater than the maximum allowed code point"
212
- // https://drafts.csswg.org/css-syntax/#maximum-allowed-code-point
213
- if (isSurrogate || codePoint === 0x0000 || codePoint > 0x10ffff) {
214
- return ["\uFFFD", hex.length + (spaceTerminated ? 1 : 0)];
215
- }
216
-
217
- return [
218
- String.fromCodePoint(codePoint),
219
- hex.length + (spaceTerminated ? 1 : 0)
220
- ];
221
- };
222
-
223
- /**
224
- * @param {string} str string
225
- * @returns {string} unescaped string
226
- */
227
- const unescapeIdentifier = (str) => {
228
- const needToProcess = CONTAINS_ESCAPE.test(str);
229
- if (!needToProcess) return str;
230
- let ret = "";
231
- for (let i = 0; i < str.length; i++) {
232
- if (str[i] === "\\") {
233
- const gobbled = gobbleHex(str.slice(i + 1, i + 7));
234
- if (gobbled !== undefined) {
235
- ret += gobbled[0];
236
- i += gobbled[1];
237
- continue;
238
- }
239
- // Retain a pair of \\ if double escaped `\\\\`
240
- // https://github.com/postcss/postcss-selector-parser/commit/268c9a7656fb53f543dc620aa5b73a30ec3ff20e
241
- if (str[i + 1] === "\\") {
242
- ret += "\\";
243
- i += 1;
244
- continue;
245
- }
246
- // if \\ is at the end of the string retain it
247
- // https://github.com/postcss/postcss-selector-parser/commit/01a6b346e3612ce1ab20219acc26abdc259ccefb
248
- if (str.length === i + 1) {
249
- ret += str[i];
250
- }
251
- continue;
252
- }
253
- ret += str[i];
254
- }
255
-
256
- return ret;
257
- };
136
+ const { escapeIdentifier, unescapeIdentifier } = walkCssTokens;
258
137
 
259
138
  /**
260
139
  * A custom property is any property whose name starts with two dashes (U+002D HYPHEN-MINUS), like --foo.
@@ -406,6 +285,7 @@ const GRID = {
406
285
  };
407
286
 
408
287
  /**
288
+ * Gets known properties.
409
289
  * @param {{ animation?: boolean, container?: boolean, customIdents?: boolean, grid?: boolean }=} options options
410
290
  * @returns {Map<string, Record<string, number>>} list of known properties
411
291
  */
@@ -525,49 +405,6 @@ const getKnownProperties = (options = {}) => {
525
405
  return knownProperties;
526
406
  };
527
407
 
528
- class LocConverter {
529
- /**
530
- * @param {string} input input
531
- */
532
- constructor(input) {
533
- this._input = input;
534
- this.line = 1;
535
- this.column = 0;
536
- this.pos = 0;
537
- }
538
-
539
- /**
540
- * @param {number} pos position
541
- * @returns {LocConverter} location converter
542
- */
543
- get(pos) {
544
- if (this.pos !== pos) {
545
- if (this.pos < pos) {
546
- const str = this._input.slice(this.pos, pos);
547
- let i = str.lastIndexOf("\n");
548
- if (i === -1) {
549
- this.column += str.length;
550
- } else {
551
- this.column = str.length - i - 1;
552
- this.line++;
553
- while (i > 0 && (i = str.lastIndexOf("\n", i - 1)) !== -1) {
554
- this.line++;
555
- }
556
- }
557
- } else {
558
- let i = this._input.lastIndexOf("\n", this.pos);
559
- while (i >= pos) {
560
- this.line--;
561
- i = i > 0 ? this._input.lastIndexOf("\n", i - 1) : -1;
562
- }
563
- this.column = pos - i;
564
- }
565
- this.pos = pos;
566
- }
567
- return this;
568
- }
569
- }
570
-
571
408
  const EMPTY_COMMENT_OPTIONS = {
572
409
  options: null,
573
410
  errors: null
@@ -583,14 +420,16 @@ const eatUntilSemi = walkCssTokens.eatUntil(";");
583
420
  const eatUntilLeftCurly = walkCssTokens.eatUntil("{");
584
421
 
585
422
  /**
423
+ * Defines the css parser own options type used by this module.
586
424
  * @typedef {object} CssParserOwnOptions
587
425
  * @property {("pure" | "global" | "local" | "auto")=} defaultMode default mode
588
426
  */
589
427
 
590
- /** @typedef {CssModuleParserOptions & CssParserOwnOptions} CssParserOptions */
428
+ /** @typedef {CssAutoOrModuleParserOptions & CssParserOwnOptions} CssParserOptions */
591
429
 
592
430
  class CssParser extends Parser {
593
431
  /**
432
+ * Creates an instance of CssParser.
594
433
  * @param {CssParserOptions=} options options
595
434
  */
596
435
  constructor(options = {}) {
@@ -615,6 +454,7 @@ class CssParser extends Parser {
615
454
  }
616
455
 
617
456
  /**
457
+ * Processes the provided state.
618
458
  * @param {ParserState} state parser state
619
459
  * @param {string} message warning message
620
460
  * @param {LocConverter} locConverter location converter
@@ -634,6 +474,28 @@ class CssParser extends Parser {
634
474
  }
635
475
 
636
476
  /**
477
+ * Emits a build error for the provided range.
478
+ * @param {ParserState} state parser state
479
+ * @param {string} message error message
480
+ * @param {LocConverter} locConverter location converter
481
+ * @param {number} start start offset
482
+ * @param {number} end end offset
483
+ */
484
+ _emitError(state, message, locConverter, start, end) {
485
+ const { line: sl, column: sc } = locConverter.get(start);
486
+ const { line: el, column: ec } = locConverter.get(end);
487
+
488
+ const err = new WebpackError(message);
489
+ err.module = state.module;
490
+ err.loc = {
491
+ start: { line: sl, column: sc },
492
+ end: { line: el, column: ec }
493
+ };
494
+ state.module.addError(err);
495
+ }
496
+
497
+ /**
498
+ * Parses the provided source and updates the parser state.
637
499
  * @param {string | Buffer | PreparsedAst} source the source to parse
638
500
  * @param {ParserState} state the parser state
639
501
  * @returns {ParserState} the parser state
@@ -648,6 +510,10 @@ class CssParser extends Parser {
648
510
  source = source.slice(1);
649
511
  }
650
512
 
513
+ const unescapeIdentifierCached = unescapeIdentifier.bindCache(
514
+ state.compilation.compiler.root
515
+ );
516
+
651
517
  let mode = this.defaultMode;
652
518
 
653
519
  const module = state.module;
@@ -663,6 +529,40 @@ class CssParser extends Parser {
663
529
  }
664
530
 
665
531
  const isModules = mode === "global" || mode === "local";
532
+
533
+ const parsedModuleResource = parseResource(
534
+ /** @type {string} */ (module.getResource())
535
+ );
536
+
537
+ /**
538
+ * Check whether a request points back to the current module
539
+ * (e.g. `composes: foo from "./self.module.css"` inside `self.module.css`).
540
+ * Only relative requests are checked — aliases / package / absolute requests
541
+ * fall through to the normal import path. Requests with a `?query` or
542
+ * `#fragment` are only treated as self when the parent module's resource
543
+ * has the same query/fragment, since `NormalModuleFactory` keys modules
544
+ * on the full resource string.
545
+ * @param {string} request request string from `from "<request>"`
546
+ * @returns {boolean} true if request resolves to the current module
547
+ */
548
+ const isSelfReferenceRequest = (request) => {
549
+ if (!/^\.{1,2}\//.test(request)) return false;
550
+ if (!module.context) return false;
551
+ const parsedRequest = parseResource(request);
552
+ if (parsedRequest.query !== parsedModuleResource.query) return false;
553
+ if (parsedRequest.fragment !== parsedModuleResource.fragment) {
554
+ return false;
555
+ }
556
+ try {
557
+ return (
558
+ path.resolve(module.context, parsedRequest.path) ===
559
+ parsedModuleResource.path
560
+ );
561
+ } catch (_err) {
562
+ return false;
563
+ }
564
+ };
565
+
666
566
  const knownProperties = getKnownProperties({
667
567
  animation: this.options.animation,
668
568
  container: this.options.container,
@@ -671,7 +571,11 @@ class CssParser extends Parser {
671
571
  });
672
572
 
673
573
  /** @type {BuildMeta} */
674
- (module.buildMeta).isCSSModule = isModules;
574
+ (module.buildMeta).isCssModule = isModules;
575
+ if (/** @type {CssModule} */ (module).exportType === "style") {
576
+ /** @type {BuildMeta} */
577
+ (module.buildMeta).needIdInConcatenation = true;
578
+ }
675
579
 
676
580
  const locConverter = new LocConverter(source);
677
581
 
@@ -695,11 +599,123 @@ class CssParser extends Parser {
695
599
  /** @type {string[]} */
696
600
  let lastLocalIdentifiers = [];
697
601
 
698
- /** @typedef {{ value?: string, importName?: string, localName?: string }} IcssDefinition */
602
+ const pureMode = isModules && Boolean(this.options.pure);
603
+ /** @type {boolean} */
604
+ let currentSelectorHasLocal = false;
605
+ /** Whether any comma-separated selector in the current rule's prelude was impure. */
606
+ let currentRuleHasImpureSelector = false;
607
+ /** Offset just after the previous `}` (or 0) — used as the prelude start. */
608
+ let currentRulePreludeStart = 0;
609
+ /** Pure-mode flags (only meaningful when `pureMode` is true). */
610
+ let pureNoCheck = false;
611
+ let pureIgnorePending = false;
612
+ let nextBlockChildrenSkip = false;
613
+ let nextBlockTreatAsLeaf = false;
614
+ let seenTopLevelRule = false;
615
+ // True after an at-rule keyword and before the next `{` or `;`. Used so
616
+ // identifiers inside the at-rule prelude (e.g. `min-width` inside
617
+ // `@media (min-width: 768px)`) don't get counted as declarations.
618
+ let inAtRulePrelude = false;
619
+ /**
620
+ * One entry per open block. `skipOwn` skips this rule's own check (set
621
+ * when the parent passed down `skipChildren`, e.g. `from`/`to` inside
622
+ * `@keyframes`). `skipChildren` is propagated to descendants. `ignored`
623
+ * is per-rule only (PCSL semantics for `cssmodules-pure-ignore`).
624
+ * `ancestorHadLocal` lets nested rules inherit purity from a
625
+ * local-bearing ancestor.
626
+ * @type {{
627
+ * ignored: boolean,
628
+ * skipOwn: boolean,
629
+ * skipChildren: boolean,
630
+ * treatAsLeaf: boolean,
631
+ * ancestorHadLocal: boolean,
632
+ * impure: boolean,
633
+ * hasDirectDecl: boolean,
634
+ * hasNestedBlock: boolean,
635
+ * isRulePrelude: boolean,
636
+ * preludeStart: number,
637
+ * preludeEnd: number,
638
+ * }[]}
639
+ */
640
+ const pureBlockStack = [];
641
+
642
+ const PURE_IGNORE_RE = /^\s*cssmodules-pure-ignore(?:\s|$)/;
643
+ const PURE_NO_CHECK_RE = /^\s*cssmodules-pure-no-check(?:\s|$)/;
644
+
645
+ /**
646
+ * @returns {(typeof pureBlockStack)[number] | undefined} top of stack
647
+ */
648
+ const pureTop = () => pureBlockStack[pureBlockStack.length - 1];
649
+
650
+ /**
651
+ * Was the parent rule pure overall (its own selectors pure or any
652
+ * ancestor pure)? Used both for ancestor-inheritance and `&`-resolution.
653
+ * @returns {boolean} true if any ancestor (self inclusive) provided a local
654
+ */
655
+ const parentEffectivePure = () => {
656
+ const top = pureTop();
657
+ return top ? top.ancestorHadLocal : false;
658
+ };
659
+
660
+ /**
661
+ * Marks the just-finished comma-separated selector (or whole prelude
662
+ * at `{`) as impure if it lacks a local and no ancestor compensates.
663
+ */
664
+ const finalizeSelector = () => {
665
+ if (!currentSelectorHasLocal && !parentEffectivePure()) {
666
+ currentRuleHasImpureSelector = true;
667
+ }
668
+ currentSelectorHasLocal = false;
669
+ };
670
+
671
+ /**
672
+ * Reports a pure-mode violation covering the entire rule prelude.
673
+ * @param {number} start prelude start offset
674
+ * @param {number} end prelude end offset (`{` position)
675
+ */
676
+ const reportPureRule = (start, end) => {
677
+ const slice = source.slice(start, end);
678
+ const lead = /** @type {RegExpExecArray} */ (
679
+ /^(?:\s|\/\*[\s\S]*?\*\/)*/.exec(slice)
680
+ )[0].length;
681
+ const trail = /** @type {RegExpExecArray} */ (/\s*$/.exec(slice))[0]
682
+ .length;
683
+ const from = start + lead;
684
+ const to = end - trail;
685
+ if (to <= from) return;
686
+ this._emitError(
687
+ state,
688
+ `Selector "${source.slice(from, to)}" is not pure (pure selectors must contain at least one local class or id)`,
689
+ locConverter,
690
+ from,
691
+ to
692
+ );
693
+ };
694
+
695
+ /** @typedef {{ value?: string, importName?: string, localName?: string, request?: string }} IcssDefinition */
699
696
  /** @type {Map<string, IcssDefinition>} */
700
697
  const icssDefinitions = new Map();
701
698
 
699
+ // Tracks `composes: <name> from "<file>"` declarations to enforce a
700
+ // predictable file load order across rules (port of
701
+ // postcss-modules-extract-imports#138). Each rule's composes order
702
+ // is a partial ordering: if `.x` composes `b from "./b"` before
703
+ // `c from "./c"`, then `b.css` must load before `c.css` so `c` can
704
+ // override `b` in the cascade. Edges are added inline as the rule
705
+ // is parsed; at end-of-parse the first composes-import dep of each
706
+ // file is tagged with `sourceOrder` according to a topological
707
+ // sort (`NormalModule#build` reorders by `sourceOrder` for us).
708
+ /** @type {Map<string, Set<string>>} */
709
+ const composesGraph = new Map();
710
+ /** @type {Map<string, CssIcssImportDependency>} */
711
+ const composesFirstFileImport = new Map();
712
+ /** @type {string | undefined} */
713
+ let currentRulePrevComposesFile;
714
+ /** @type {Set<string>} */
715
+ const currentRuleComposesFiles = new Set();
716
+
702
717
  /**
718
+ * Checks whether this css parser is next nested syntax.
703
719
  * @param {string} input input
704
720
  * @param {number} pos position
705
721
  * @returns {boolean} true, when next is nested syntax
@@ -731,12 +747,14 @@ class CssParser extends Parser {
731
747
  return true;
732
748
  };
733
749
  /**
750
+ * Checks whether this css parser is local mode.
734
751
  * @returns {boolean} true, when in local scope
735
752
  */
736
753
  const isLocalMode = () =>
737
754
  modeData === LOCAL_MODE || (mode === "local" && modeData === undefined);
738
755
 
739
756
  /**
757
+ * Returns end.
740
758
  * @param {string} input input
741
759
  * @param {number} start start
742
760
  * @param {number} end end
@@ -747,9 +765,11 @@ class CssParser extends Parser {
747
765
  const { line: sl, column: sc } = locConverter.get(start);
748
766
  const { line: el, column: ec } = locConverter.get(end);
749
767
 
768
+ const value = input.slice(start + 2, end - 2);
769
+
750
770
  /** @type {Comment} */
751
771
  const comment = {
752
- value: input.slice(start + 2, end - 2),
772
+ value,
753
773
  range: [start, end],
754
774
  loc: {
755
775
  start: { line: sl, column: sc },
@@ -757,12 +777,26 @@ class CssParser extends Parser {
757
777
  }
758
778
  };
759
779
  this.comments.push(comment);
780
+
781
+ if (pureMode) {
782
+ if (PURE_IGNORE_RE.test(value)) {
783
+ pureIgnorePending = true;
784
+ } else if (
785
+ PURE_NO_CHECK_RE.test(value) &&
786
+ scope === CSS_MODE_TOP_LEVEL &&
787
+ !seenTopLevelRule
788
+ ) {
789
+ pureNoCheck = true;
790
+ }
791
+ }
792
+
760
793
  return end;
761
794
  };
762
795
 
763
796
  // Vanilla CSS stuff
764
797
 
765
798
  /**
799
+ * Processes the provided input.
766
800
  * @param {string} input input
767
801
  * @param {number} start name start position
768
802
  * @param {number} end name end position
@@ -774,7 +808,7 @@ class CssParser extends Parser {
774
808
  });
775
809
  if (!tokens[3]) return end;
776
810
  const semi = tokens[3][1];
777
- if (!tokens[0]) {
811
+ if (!tokens[0] || (tokens[0][4] && !isModules)) {
778
812
  this._emitWarning(
779
813
  state,
780
814
  `Expected URL in '${input.slice(start, semi)}'`,
@@ -786,7 +820,48 @@ class CssParser extends Parser {
786
820
  }
787
821
 
788
822
  const urlToken = tokens[0];
789
- const url = normalizeUrl(input.slice(urlToken[2], urlToken[3]), true);
823
+ /** @type {string} */
824
+ let url;
825
+ if (urlToken[4]) {
826
+ // URL given as identifier — resolve via CSS Modules @value.
827
+ const name = input.slice(urlToken[2], urlToken[3]);
828
+ const def = icssDefinitions.get(name);
829
+ if (!def) {
830
+ this._emitWarning(
831
+ state,
832
+ `Unknown '@value' identifier '${name}' in '${input.slice(start, semi)}'`,
833
+ locConverter,
834
+ start,
835
+ semi
836
+ );
837
+ // Consume the whole at-rule so the unresolved identifier
838
+ // doesn't get re-tokenized and accidentally substituted
839
+ // into a malformed `@import` in the output.
840
+ const dep = new ConstDependency("", [start, semi]);
841
+ module.addPresentationalDependency(dep);
842
+ return semi;
843
+ }
844
+ if (def.value === undefined) {
845
+ this._emitWarning(
846
+ state,
847
+ `'@value' identifier '${name}' was imported from another module and cannot be used as the URL of '@import' — only locally defined values are supported here`,
848
+ locConverter,
849
+ start,
850
+ semi
851
+ );
852
+ const dep = new ConstDependency("", [start, semi]);
853
+ module.addPresentationalDependency(dep);
854
+ return semi;
855
+ }
856
+ const raw = def.value.trim();
857
+ url =
858
+ (raw.startsWith('"') && raw.endsWith('"')) ||
859
+ (raw.startsWith("'") && raw.endsWith("'"))
860
+ ? normalizeUrl(raw.slice(1, -1), true)
861
+ : normalizeUrl(raw, false);
862
+ } else {
863
+ url = normalizeUrl(input.slice(urlToken[2], urlToken[3]), true);
864
+ }
790
865
  const newline = walkCssTokens.eatWhiteLine(input, semi);
791
866
  const { options, errors: commentErrors } = this.parseCommentOptions([
792
867
  end,
@@ -870,11 +945,23 @@ class CssParser extends Parser {
870
945
  );
871
946
  dep.setLoc(sl, sc, el, ec);
872
947
  module.addDependency(dep);
948
+ // `text` and `css-style-sheet` parents inline the imported
949
+ // module's rendered CSS at build time, which means we read the
950
+ // imported module's `codeGenerationResults` (and through it the
951
+ // results of any assets the import references). Registering this
952
+ // as a code-generation dependency tells the compilation scheduler
953
+ // to generate the imported subtree before us.
954
+ const exportType = /** @type {import("./CssModule")} */ (module)
955
+ .exportType;
956
+ if (exportType === "text" || exportType === "css-style-sheet") {
957
+ module.addCodeGenerationDependency(dep);
958
+ }
873
959
 
874
960
  return newline;
875
961
  };
876
962
 
877
963
  /**
964
+ * Process url function.
878
965
  * @param {string} input input
879
966
  * @param {number} end end position
880
967
  * @param {string} name the name of function
@@ -937,6 +1024,7 @@ class CssParser extends Parser {
937
1024
  };
938
1025
 
939
1026
  /**
1027
+ * Process old url function.
940
1028
  * @param {string} input input
941
1029
  * @param {number} start start position
942
1030
  * @param {number} end end position
@@ -986,9 +1074,32 @@ class CssParser extends Parser {
986
1074
  return end;
987
1075
  }
988
1076
  }
989
- const value = normalizeUrl(input.slice(contentStart, contentEnd), false);
1077
+ let value = normalizeUrl(input.slice(contentStart, contentEnd), false);
990
1078
  // Ignore `url()`, `url('')` and `url("")`, they are valid by spec
991
1079
  if (value.length === 0) return end;
1080
+ if (isModules) {
1081
+ const def = icssDefinitions.get(value);
1082
+ if (def) {
1083
+ if (def.value !== undefined) {
1084
+ const raw = def.value.trim();
1085
+ value =
1086
+ (raw.startsWith('"') && raw.endsWith('"')) ||
1087
+ (raw.startsWith("'") && raw.endsWith("'"))
1088
+ ? normalizeUrl(raw.slice(1, -1), true)
1089
+ : normalizeUrl(raw, false);
1090
+ if (value.length === 0) return end;
1091
+ } else {
1092
+ this._emitWarning(
1093
+ state,
1094
+ `'@value' identifier '${value}' was imported from another module and cannot be used inside 'url()' — only locally defined values are supported here`,
1095
+ locConverter,
1096
+ start,
1097
+ end
1098
+ );
1099
+ return end;
1100
+ }
1101
+ }
1102
+ }
992
1103
  const dep = new CssUrlDependency(value, [start, end], "url");
993
1104
  const { line: sl, column: sc } = locConverter.get(start);
994
1105
  const { line: el, column: ec } = locConverter.get(end);
@@ -999,6 +1110,7 @@ class CssParser extends Parser {
999
1110
  };
1000
1111
 
1001
1112
  /**
1113
+ * Process image set function.
1002
1114
  * @param {string} input input
1003
1115
  * @param {number} start start position
1004
1116
  * @param {number} end end position
@@ -1063,10 +1175,11 @@ class CssParser extends Parser {
1063
1175
  // CSS modules stuff
1064
1176
 
1065
1177
  /**
1178
+ * Returns resolved reexport (localName and importName).
1066
1179
  * @param {string} value value to resolve
1067
1180
  * @param {string=} localName override local name
1068
1181
  * @param {boolean=} isCustomProperty true when it is custom property, otherwise false
1069
- * @returns {string | [string, string]} resolved reexport (`localName` and `importName`)
1182
+ * @returns {string | [string, string] | [string, string, string]} resolved reexport (`localName`, `importName` and optional `request` of the active `@value` import)
1070
1183
  */
1071
1184
  const getReexport = (value, localName, isCustomProperty) => {
1072
1185
  const reexport = icssDefinitions.get(
@@ -1075,10 +1188,11 @@ class CssParser extends Parser {
1075
1188
 
1076
1189
  if (reexport) {
1077
1190
  if (reexport.importName) {
1078
- return [
1079
- reexport.localName || (isCustomProperty ? `--${value}` : value),
1080
- reexport.importName
1081
- ];
1191
+ const resolvedLocalName =
1192
+ reexport.localName || (isCustomProperty ? `--${value}` : value);
1193
+ return reexport.request
1194
+ ? [resolvedLocalName, reexport.importName, reexport.request]
1195
+ : [resolvedLocalName, reexport.importName];
1082
1196
  }
1083
1197
 
1084
1198
  if (isCustomProperty) {
@@ -1096,6 +1210,7 @@ class CssParser extends Parser {
1096
1210
  };
1097
1211
 
1098
1212
  /**
1213
+ * Process import or export.
1099
1214
  * @param {0 | 1} type import or export
1100
1215
  * @param {string} input input
1101
1216
  * @param {number} pos start position
@@ -1149,6 +1264,7 @@ class CssParser extends Parser {
1149
1264
  }
1150
1265
 
1151
1266
  /**
1267
+ * Creates a dep from the provided name.
1152
1268
  * @param {string} name name
1153
1269
  * @param {string} value value
1154
1270
  * @param {number} start start of position
@@ -1170,7 +1286,10 @@ class CssParser extends Parser {
1170
1286
  dep.setLoc(sl, sc, el, ec);
1171
1287
  module.addDependency(dep);
1172
1288
 
1173
- icssDefinitions.set(name, { importName: value });
1289
+ icssDefinitions.set(name, {
1290
+ importName: value,
1291
+ request: /** @type {string} */ (request)
1292
+ });
1174
1293
  } else if (type === 1) {
1175
1294
  const dep = new CssIcssExportDependency(name, getReexport(value));
1176
1295
  const { line: sl, column: sc } = locConverter.get(start);
@@ -1266,6 +1385,7 @@ class CssParser extends Parser {
1266
1385
  /** @typedef {{ from: string, items: ({ localName: string, importName: string })[] }} ValueAtRuleImport */
1267
1386
  /** @typedef {{ localName: string, value: string }} ValueAtRuleValue */
1268
1387
  /**
1388
+ * Parses value at rule params.
1269
1389
  * @param {string} str value at-rule params
1270
1390
  * @returns {ValueAtRuleImport | ValueAtRuleValue} parsed result
1271
1391
  */
@@ -1334,6 +1454,7 @@ class CssParser extends Parser {
1334
1454
  };
1335
1455
 
1336
1456
  /**
1457
+ * Processes the provided input.
1337
1458
  * @param {string} input input
1338
1459
  * @param {number} start name start position
1339
1460
  * @param {number} end name end position
@@ -1385,7 +1506,7 @@ class CssParser extends Parser {
1385
1506
  dep.setLoc(sl, sc, el, ec);
1386
1507
  module.addDependency(dep);
1387
1508
 
1388
- icssDefinitions.set(localName, { importName });
1509
+ icssDefinitions.set(localName, { importName, request: from });
1389
1510
  }
1390
1511
 
1391
1512
  {
@@ -1451,6 +1572,7 @@ class CssParser extends Parser {
1451
1572
  };
1452
1573
 
1453
1574
  /**
1575
+ * Process icss symbol.
1454
1576
  * @param {string} name ICSS symbol name
1455
1577
  * @param {number} start start position
1456
1578
  * @param {number} end end position
@@ -1466,7 +1588,8 @@ class CssParser extends Parser {
1466
1588
  def.localName || name,
1467
1589
  [start, end],
1468
1590
  def.value,
1469
- def.importName
1591
+ def.importName,
1592
+ def.request
1470
1593
  );
1471
1594
  dep.setLoc(sl, sc, el, ec);
1472
1595
  module.addDependency(dep);
@@ -1474,6 +1597,7 @@ class CssParser extends Parser {
1474
1597
  };
1475
1598
 
1476
1599
  /**
1600
+ * Process local or global function.
1477
1601
  * @param {string} input input
1478
1602
  * @param {1 | 2} type type of function
1479
1603
  * @param {number} start start position
@@ -1494,7 +1618,9 @@ class CssParser extends Parser {
1494
1618
  {
1495
1619
  identifier(input, start, end) {
1496
1620
  if (type === 1) {
1497
- let identifier = unescapeIdentifier(input.slice(start, end));
1621
+ let identifier = unescapeIdentifierCached(
1622
+ input.slice(start, end)
1623
+ );
1498
1624
  const { line: sl, column: sc } = locConverter.get(start);
1499
1625
  const { line: el, column: ec } = locConverter.get(end);
1500
1626
  const isDashedIdent = isDashedIdentifier(identifier);
@@ -1535,6 +1661,7 @@ class CssParser extends Parser {
1535
1661
  };
1536
1662
 
1537
1663
  /**
1664
+ * Process local at rule.
1538
1665
  * @param {string} input input
1539
1666
  * @param {number} end name end position
1540
1667
  * @param {{ string?: boolean, identifier?: boolean | RegExp }} options types which allowed to handle
@@ -1549,7 +1676,9 @@ class CssParser extends Parser {
1549
1676
  {
1550
1677
  string(_input, start, end) {
1551
1678
  if (!found && options.string) {
1552
- const value = unescapeIdentifier(input.slice(start + 1, end - 1));
1679
+ const value = unescapeIdentifierCached(
1680
+ input.slice(start + 1, end - 1)
1681
+ );
1553
1682
  const { line: sl, column: sc } = locConverter.get(start);
1554
1683
  const { line: el, column: ec } = locConverter.get(end);
1555
1684
  const dep = new CssIcssExportDependency(
@@ -1562,6 +1691,7 @@ class CssParser extends Parser {
1562
1691
  dep.setLoc(sl, sc, el, ec);
1563
1692
  module.addDependency(dep);
1564
1693
  found = true;
1694
+ if (pureMode) currentSelectorHasLocal = true;
1565
1695
  }
1566
1696
  return end;
1567
1697
  },
@@ -1570,7 +1700,7 @@ class CssParser extends Parser {
1570
1700
  const value = input.slice(start, end);
1571
1701
 
1572
1702
  if (options.identifier) {
1573
- const identifier = unescapeIdentifier(value);
1703
+ const identifier = unescapeIdentifierCached(value);
1574
1704
 
1575
1705
  if (
1576
1706
  options.identifier instanceof RegExp &&
@@ -1593,6 +1723,7 @@ class CssParser extends Parser {
1593
1723
  dep.setLoc(sl, sc, el, ec);
1594
1724
  module.addDependency(dep);
1595
1725
  found = true;
1726
+ if (pureMode) currentSelectorHasLocal = true;
1596
1727
  }
1597
1728
  }
1598
1729
  return end;
@@ -1611,6 +1742,7 @@ class CssParser extends Parser {
1611
1742
 
1612
1743
  if (!found && type) {
1613
1744
  found = true;
1745
+ if (type === 1 && pureMode) currentSelectorHasLocal = true;
1614
1746
  return processLocalOrGlobalFunction(input, type, start, end);
1615
1747
  }
1616
1748
 
@@ -1629,6 +1761,7 @@ class CssParser extends Parser {
1629
1761
  );
1630
1762
  };
1631
1763
  /**
1764
+ * Process dashed ident.
1632
1765
  * @param {string} input input
1633
1766
  * @param {number} start start position
1634
1767
  * @param {number} end end position
@@ -1637,7 +1770,7 @@ class CssParser extends Parser {
1637
1770
  const processDashedIdent = (input, start, end) => {
1638
1771
  const customIdent = walkCssTokens.eatIdentSequence(input, start);
1639
1772
  if (!customIdent) return end;
1640
- const identifier = unescapeIdentifier(
1773
+ const identifier = unescapeIdentifierCached(
1641
1774
  input.slice(customIdent[0] + 2, customIdent[1])
1642
1775
  );
1643
1776
  const afterCustomIdent = walkCssTokens.eatWhitespaceAndComments(
@@ -1728,6 +1861,7 @@ class CssParser extends Parser {
1728
1861
  return end;
1729
1862
  };
1730
1863
  /**
1864
+ * Process local declaration.
1731
1865
  * @param {string} input input
1732
1866
  * @param {number} pos name start position
1733
1867
  * @param {number} end name end position
@@ -1813,7 +1947,7 @@ class CssParser extends Parser {
1813
1947
  propertyName === "grid-template" ||
1814
1948
  propertyName === "grid-template-areas"
1815
1949
  ) {
1816
- const areas = unescapeIdentifier(
1950
+ const areas = unescapeIdentifierCached(
1817
1951
  input.slice(start + 1, end - 1)
1818
1952
  );
1819
1953
  const matches = matchAll(/\b\w+\b/g, areas);
@@ -1907,7 +2041,7 @@ class CssParser extends Parser {
1907
2041
  const { line: sl, column: sc } = locConverter.get(value[0]);
1908
2042
  const { line: el, column: ec } = locConverter.get(value[1]);
1909
2043
  const [start, end, isString] = value;
1910
- const name = unescapeIdentifier(
2044
+ const name = unescapeIdentifierCached(
1911
2045
  isString
1912
2046
  ? input.slice(start + 1, end - 1)
1913
2047
  : input.slice(start, end)
@@ -1947,7 +2081,7 @@ class CssParser extends Parser {
1947
2081
  const lastLocalIdentifier = lastLocalIdentifiers[0];
1948
2082
  let end = pos;
1949
2083
 
1950
- /** @type {Set<[number, number]>} */
2084
+ /** @type {Set<[number, number, boolean]>} */
1951
2085
  const classNames = new Set();
1952
2086
 
1953
2087
  while (true) {
@@ -1993,18 +2127,20 @@ class CssParser extends Parser {
1993
2127
 
1994
2128
  if (isComma || isSemicolon || isRightCurly) {
1995
2129
  if (className) {
1996
- classNames.add(className);
2130
+ classNames.add([className[0], className[1], isGlobalFunction]);
1997
2131
  }
1998
2132
 
1999
- for (const className of classNames) {
2000
- const [start, end] = className;
2001
- const identifier = unescapeIdentifier(input.slice(start, end));
2133
+ for (const entry of classNames) {
2134
+ const [start, end, isGlobal] = entry;
2135
+ const identifier = unescapeIdentifierCached(
2136
+ input.slice(start, end)
2137
+ );
2002
2138
  const dep = new CssIcssExportDependency(
2003
2139
  lastLocalIdentifier,
2004
2140
  getReexport(identifier),
2005
2141
  [start, end],
2006
- !isGlobalFunction,
2007
- isGlobalFunction
2142
+ !isGlobal,
2143
+ isGlobal
2008
2144
  ? CssIcssExportDependency.EXPORT_MODE.APPEND
2009
2145
  : CssIcssExportDependency.EXPORT_MODE.SELF_REFERENCE,
2010
2146
  CssIcssExportDependency.EXPORT_TYPE.COMPOSES
@@ -2034,12 +2170,53 @@ class CssParser extends Parser {
2034
2170
 
2035
2171
  if (from) {
2036
2172
  const request = input.slice(from[0] + 1, from[1] - 1);
2173
+ const selfReference = isSelfReferenceRequest(request);
2174
+
2175
+ if (!selfReference && !currentRuleComposesFiles.has(request)) {
2176
+ currentRuleComposesFiles.add(request);
2177
+ if (
2178
+ currentRulePrevComposesFile !== undefined &&
2179
+ currentRulePrevComposesFile !== request
2180
+ ) {
2181
+ let successors = composesGraph.get(
2182
+ currentRulePrevComposesFile
2183
+ );
2184
+ if (!successors) {
2185
+ successors = new Set();
2186
+ composesGraph.set(currentRulePrevComposesFile, successors);
2187
+ }
2188
+ successors.add(request);
2189
+ }
2190
+ currentRulePrevComposesFile = request;
2191
+ }
2037
2192
 
2038
- for (const className of classNames) {
2039
- const [start, end] = className;
2040
- const identifier = unescapeIdentifier(input.slice(start, end));
2193
+ for (const entry of classNames) {
2194
+ const [start, end] = entry;
2195
+ const identifier = unescapeIdentifierCached(
2196
+ input.slice(start, end)
2197
+ );
2041
2198
  const { line: sl, column: sc } = locConverter.get(start);
2042
2199
  const { line: el, column: ec } = locConverter.get(end);
2200
+
2201
+ if (selfReference) {
2202
+ // `composes: foo from "./self.module.css"` from inside
2203
+ // `self.module.css` — collapse to a self-reference, like
2204
+ // `composes: foo` without `from`. When the composed name
2205
+ // equals the local class name, it's a true no-op.
2206
+ if (identifier === lastLocalIdentifier) continue;
2207
+ const dep = new CssIcssExportDependency(
2208
+ lastLocalIdentifier,
2209
+ getReexport(identifier),
2210
+ [start, end],
2211
+ true,
2212
+ CssIcssExportDependency.EXPORT_MODE.SELF_REFERENCE,
2213
+ CssIcssExportDependency.EXPORT_TYPE.COMPOSES
2214
+ );
2215
+ dep.setLoc(sl, sc, el, ec);
2216
+ module.addDependency(dep);
2217
+ continue;
2218
+ }
2219
+
2043
2220
  const localName = `__ICSS_IMPORT_${counter++}__`;
2044
2221
 
2045
2222
  {
@@ -2053,6 +2230,9 @@ class CssParser extends Parser {
2053
2230
  );
2054
2231
  dep.setLoc(sl, sc, el, ec);
2055
2232
  module.addDependency(dep);
2233
+ if (!composesFirstFileImport.has(request)) {
2234
+ composesFirstFileImport.set(request, dep);
2235
+ }
2056
2236
  }
2057
2237
 
2058
2238
  {
@@ -2075,9 +2255,9 @@ class CssParser extends Parser {
2075
2255
  from = walkCssTokens.eatIdentSequence(input, pos);
2076
2256
 
2077
2257
  if (from && input.slice(from[0], from[1]) === "global") {
2078
- for (const className of classNames) {
2079
- const [start, end] = className;
2080
- const identifier = unescapeIdentifier(
2258
+ for (const entry of classNames) {
2259
+ const [start, end] = entry;
2260
+ const identifier = unescapeIdentifierCached(
2081
2261
  input.slice(start, end)
2082
2262
  );
2083
2263
  const dep = new CssIcssExportDependency(
@@ -2110,7 +2290,7 @@ class CssParser extends Parser {
2110
2290
  }
2111
2291
  }
2112
2292
  } else if (className) {
2113
- classNames.add(className);
2293
+ classNames.add([className[0], className[1], isGlobalFunction]);
2114
2294
  } else {
2115
2295
  const end = eatUntilSemi(input, pos);
2116
2296
  this._emitWarning(
@@ -2133,6 +2313,7 @@ class CssParser extends Parser {
2133
2313
  };
2134
2314
 
2135
2315
  /**
2316
+ * Process id selector.
2136
2317
  * @param {string} input input
2137
2318
  * @param {number} start start position
2138
2319
  * @param {number} end end position
@@ -2140,7 +2321,7 @@ class CssParser extends Parser {
2140
2321
  */
2141
2322
  const processIdSelector = (input, start, end) => {
2142
2323
  const valueStart = start + 1;
2143
- const name = unescapeIdentifier(input.slice(valueStart, end));
2324
+ const name = unescapeIdentifierCached(input.slice(valueStart, end));
2144
2325
  const dep = new CssIcssExportDependency(
2145
2326
  name,
2146
2327
  getReexport(name),
@@ -2152,10 +2333,12 @@ class CssParser extends Parser {
2152
2333
  const { line: el, column: ec } = locConverter.get(end);
2153
2334
  dep.setLoc(sl, sc, el, ec);
2154
2335
  module.addDependency(dep);
2336
+ if (pureMode) currentSelectorHasLocal = true;
2155
2337
  return end;
2156
2338
  };
2157
2339
 
2158
2340
  /**
2341
+ * Process class selector.
2159
2342
  * @param {string} input input
2160
2343
  * @param {number} start start position
2161
2344
  * @param {number} end end position
@@ -2164,7 +2347,7 @@ class CssParser extends Parser {
2164
2347
  const processClassSelector = (input, start, end) => {
2165
2348
  const ident = walkCssTokens.skipCommentsAndEatIdentSequence(input, end);
2166
2349
  if (!ident) return end;
2167
- const name = unescapeIdentifier(input.slice(ident[0], ident[1]));
2350
+ const name = unescapeIdentifierCached(input.slice(ident[0], ident[1]));
2168
2351
  lastLocalIdentifiers.push(name);
2169
2352
  const dep = new CssIcssExportDependency(
2170
2353
  name,
@@ -2177,10 +2360,12 @@ class CssParser extends Parser {
2177
2360
  const { line: el, column: ec } = locConverter.get(ident[1]);
2178
2361
  dep.setLoc(sl, sc, el, ec);
2179
2362
  module.addDependency(dep);
2363
+ if (pureMode) currentSelectorHasLocal = true;
2180
2364
  return ident[1];
2181
2365
  };
2182
2366
 
2183
2367
  /**
2368
+ * Process attribute selector.
2184
2369
  * @param {string} input input
2185
2370
  * @param {number} start start position
2186
2371
  * @param {number} end end position
@@ -2190,7 +2375,7 @@ class CssParser extends Parser {
2190
2375
  end = walkCssTokens.eatWhitespaceAndComments(input, end)[0];
2191
2376
  const identifier = walkCssTokens.eatIdentSequence(input, end);
2192
2377
  if (!identifier) return end;
2193
- const name = unescapeIdentifier(
2378
+ const name = unescapeIdentifierCached(
2194
2379
  input.slice(identifier[0], identifier[1])
2195
2380
  );
2196
2381
  if (name.toLowerCase() !== "class") {
@@ -2226,7 +2411,7 @@ class CssParser extends Parser {
2226
2411
 
2227
2412
  const classNameStart = value[2] ? value[0] : value[0] + 1;
2228
2413
  const classNameEnd = value[2] ? value[1] : value[1] - 1;
2229
- const className = unescapeIdentifier(
2414
+ const className = unescapeIdentifierCached(
2230
2415
  input.slice(classNameStart, classNameEnd)
2231
2416
  );
2232
2417
  const dep = new CssIcssExportDependency(
@@ -2246,44 +2431,97 @@ class CssParser extends Parser {
2246
2431
  walkCssTokens(source, 0, {
2247
2432
  comment,
2248
2433
  leftCurlyBracket: (input, start, end) => {
2249
- switch (scope) {
2250
- case CSS_MODE_TOP_LEVEL: {
2251
- allowImportAtRule = false;
2252
- scope = CSS_MODE_IN_BLOCK;
2253
-
2254
- if (isModules) {
2255
- blockNestingLevel = 1;
2256
- isNextRulePrelude = isNextNestedSyntax(input, end);
2257
- }
2258
-
2259
- break;
2260
- }
2261
- case CSS_MODE_IN_BLOCK: {
2262
- if (isModules) {
2263
- blockNestingLevel++;
2264
- isNextRulePrelude = isNextNestedSyntax(input, end);
2265
- }
2266
- break;
2267
- }
2434
+ const wasTopLevel = scope === CSS_MODE_TOP_LEVEL;
2435
+ if (wasTopLevel) {
2436
+ allowImportAtRule = false;
2437
+ scope = CSS_MODE_IN_BLOCK;
2438
+ } else if (scope !== CSS_MODE_IN_BLOCK) {
2439
+ return end;
2268
2440
  }
2441
+ if (!isModules) return end;
2442
+ if (pureMode) {
2443
+ inAtRulePrelude = false;
2444
+ if (wasTopLevel) seenTopLevelRule = true;
2445
+ const isRulePrelude = isNextRulePrelude;
2446
+ if (isRulePrelude) finalizeSelector();
2447
+ const top = pureTop();
2448
+ if (top) top.hasNestedBlock = true;
2449
+ const inheritedSkip = top ? top.skipChildren : false;
2450
+ pureBlockStack.push({
2451
+ ignored: pureIgnorePending,
2452
+ skipOwn: inheritedSkip,
2453
+ skipChildren: nextBlockChildrenSkip || inheritedSkip,
2454
+ treatAsLeaf: nextBlockTreatAsLeaf,
2455
+ // "this rule is fully pure" (no impure comma-segment) OR any
2456
+ // ancestor pure. Matches PCSL's `[isPureSelectorSymbol]`.
2457
+ ancestorHadLocal:
2458
+ parentEffectivePure() ||
2459
+ (isRulePrelude && !currentRuleHasImpureSelector),
2460
+ impure: isRulePrelude && currentRuleHasImpureSelector,
2461
+ hasDirectDecl: false,
2462
+ hasNestedBlock: false,
2463
+ isRulePrelude,
2464
+ preludeStart: currentRulePreludeStart,
2465
+ preludeEnd: start
2466
+ });
2467
+ pureIgnorePending = false;
2468
+ nextBlockChildrenSkip = false;
2469
+ nextBlockTreatAsLeaf = false;
2470
+ currentRuleHasImpureSelector = false;
2471
+ currentSelectorHasLocal = false;
2472
+ currentRulePreludeStart = end;
2473
+ }
2474
+ blockNestingLevel = wasTopLevel ? 1 : blockNestingLevel + 1;
2475
+ isNextRulePrelude = isNextNestedSyntax(input, end);
2269
2476
  return end;
2270
2477
  },
2271
2478
  rightCurlyBracket: (input, start, end) => {
2272
- switch (scope) {
2273
- case CSS_MODE_IN_BLOCK: {
2274
- if (--blockNestingLevel === 0) {
2275
- scope = CSS_MODE_TOP_LEVEL;
2276
-
2277
- if (isModules) {
2278
- isNextRulePrelude = true;
2279
- modeData = undefined;
2280
- lastLocalIdentifiers = [];
2281
- }
2282
- } else if (isModules) {
2283
- isNextRulePrelude = isNextNestedSyntax(input, end);
2479
+ if (scope !== CSS_MODE_IN_BLOCK) return end;
2480
+ const closing = blockNestingLevel === 1;
2481
+ if (closing) {
2482
+ scope = CSS_MODE_TOP_LEVEL;
2483
+ blockNestingLevel = 0;
2484
+ if (!isModules) return end;
2485
+ isNextRulePrelude = true;
2486
+ modeData = undefined;
2487
+ lastLocalIdentifiers = [];
2488
+ currentRulePrevComposesFile = undefined;
2489
+ currentRuleComposesFiles.clear();
2490
+ } else {
2491
+ blockNestingLevel--;
2492
+ if (!isModules) return end;
2493
+ isNextRulePrelude = isNextNestedSyntax(input, end);
2494
+ }
2495
+ if (pureMode) {
2496
+ const frame = pureBlockStack.pop();
2497
+ if (frame) {
2498
+ // PCSL throws on impure rules whose body has any non-rule
2499
+ // content (declaration, empty body). Rules whose body is
2500
+ // only nested rules are skipped — child rules carry the
2501
+ // check themselves.
2502
+ if (
2503
+ !pureNoCheck &&
2504
+ !frame.ignored &&
2505
+ !frame.skipOwn &&
2506
+ frame.isRulePrelude &&
2507
+ frame.impure &&
2508
+ (frame.hasDirectDecl ||
2509
+ !frame.hasNestedBlock ||
2510
+ frame.treatAsLeaf)
2511
+ ) {
2512
+ reportPureRule(frame.preludeStart, frame.preludeEnd);
2513
+ }
2514
+ // Propagate "has direct declaration" through at-rule frames
2515
+ // so a parent rule containing only e.g. `@media { decl }` is
2516
+ // still treated as "rule with declarations".
2517
+ if (!frame.isRulePrelude && frame.hasDirectDecl) {
2518
+ const parent = pureTop();
2519
+ if (parent) parent.hasDirectDecl = true;
2284
2520
  }
2285
- break;
2286
2521
  }
2522
+ currentRuleHasImpureSelector = false;
2523
+ currentSelectorHasLocal = false;
2524
+ currentRulePreludeStart = end;
2287
2525
  }
2288
2526
  return end;
2289
2527
  },
@@ -2302,7 +2540,16 @@ class CssParser extends Parser {
2302
2540
  },
2303
2541
  atKeyword: (input, start, end) => {
2304
2542
  const name = input.slice(start, end).toLowerCase();
2543
+ const wasTopLevel = scope === CSS_MODE_TOP_LEVEL;
2544
+ if (pureMode) {
2545
+ inAtRulePrelude = true;
2546
+ // Match PCSL's `isPureCheckDisabled`: any non-comment top-level
2547
+ // node (including `;`-terminated at-rules like `@import`) seals
2548
+ // the leading-comments window.
2549
+ if (wasTopLevel) seenTopLevelRule = true;
2550
+ }
2305
2551
 
2552
+ let pos = end;
2306
2553
  switch (name) {
2307
2554
  case "@namespace": {
2308
2555
  this._emitWarning(
@@ -2313,11 +2560,39 @@ class CssParser extends Parser {
2313
2560
  end
2314
2561
  );
2315
2562
 
2316
- return eatUntilSemi(input, start);
2563
+ pos = eatUntilSemi(input, start);
2564
+ break;
2565
+ }
2566
+ case "@charset": {
2567
+ const atRuleEnd = eatUntilSemi(input, start);
2568
+
2569
+ if (/** @type {CssModule} */ (module).exportType === "style") {
2570
+ pos = atRuleEnd;
2571
+ break;
2572
+ }
2573
+
2574
+ const dep = new ConstDependency("", [start, atRuleEnd + 1]);
2575
+ module.addPresentationalDependency(dep);
2576
+
2577
+ const value = walkCssTokens.eatString(input, end);
2578
+
2579
+ if (!value) {
2580
+ pos = atRuleEnd;
2581
+ break;
2582
+ }
2583
+
2584
+ /** @type {BuildInfo} */
2585
+ (module.buildInfo).charset = input
2586
+ .slice(value[0] + 1, value[1] - 1)
2587
+ .toUpperCase();
2588
+
2589
+ pos = atRuleEnd;
2590
+ break;
2317
2591
  }
2318
2592
  case "@import": {
2319
2593
  if (!this.options.import) {
2320
- return eatUntilSemi(input, end);
2594
+ pos = eatUntilSemi(input, end);
2595
+ break;
2321
2596
  }
2322
2597
 
2323
2598
  if (!allowImportAtRule) {
@@ -2328,43 +2603,57 @@ class CssParser extends Parser {
2328
2603
  start,
2329
2604
  end
2330
2605
  );
2331
- return end;
2606
+ pos = eatUntilSemi(input, end);
2607
+ break;
2332
2608
  }
2333
2609
 
2334
- return processAtImport(input, start, end);
2610
+ pos = processAtImport(input, start, end);
2611
+ break;
2335
2612
  }
2336
2613
  default: {
2337
2614
  if (isModules) {
2338
2615
  if (name === "@value") {
2339
- return processAtValue(input, start, end);
2616
+ pos = processAtValue(input, start, end);
2617
+ break;
2340
2618
  } else if (
2341
2619
  this.options.animation &&
2342
2620
  OPTIONALLY_VENDOR_PREFIXED_KEYFRAMES_AT_RULE.test(name) &&
2343
2621
  isLocalMode()
2344
2622
  ) {
2345
- return processLocalAtRule(input, end, {
2623
+ if (pureMode) {
2624
+ nextBlockChildrenSkip = true;
2625
+ nextBlockTreatAsLeaf = true;
2626
+ }
2627
+ pos = processLocalAtRule(input, end, {
2346
2628
  string: true,
2347
2629
  identifier: true
2348
2630
  });
2631
+ break;
2349
2632
  } else if (
2350
2633
  this.options.customIdents &&
2351
2634
  name === "@counter-style" &&
2352
2635
  isLocalMode()
2353
2636
  ) {
2354
- return processLocalAtRule(input, end, {
2637
+ if (pureMode) {
2638
+ nextBlockChildrenSkip = true;
2639
+ nextBlockTreatAsLeaf = true;
2640
+ }
2641
+ pos = processLocalAtRule(input, end, {
2355
2642
  identifier: true
2356
2643
  });
2644
+ break;
2357
2645
  } else if (
2358
2646
  this.options.container &&
2359
2647
  name === "@container" &&
2360
2648
  isLocalMode()
2361
2649
  ) {
2362
- return processLocalAtRule(input, end, {
2650
+ pos = processLocalAtRule(input, end, {
2363
2651
  identifier: /^(none|and|or|not)$/
2364
2652
  });
2653
+ break;
2365
2654
  } else if (name === "@scope") {
2366
2655
  isNextRulePrelude = true;
2367
- return end;
2656
+ break;
2368
2657
  }
2369
2658
 
2370
2659
  isNextRulePrelude = false;
@@ -2372,12 +2661,48 @@ class CssParser extends Parser {
2372
2661
  }
2373
2662
  }
2374
2663
 
2375
- return end;
2664
+ // If the at-rule consumed its own `;` (for `@import`/`@value`/
2665
+ // `@charset`/`@namespace`), advance the prelude pointer so a
2666
+ // later impure rule's reported selector doesn't include this
2667
+ // at-rule's text. Body-bearing at-rules return at `{` — let
2668
+ // `leftCurlyBracket` handle those.
2669
+ if (pureMode && wasTopLevel && pos > end) {
2670
+ let probe = pos - 1;
2671
+ while (
2672
+ probe > end &&
2673
+ walkCssTokens.isWhiteSpace(input.charCodeAt(probe))
2674
+ ) {
2675
+ probe--;
2676
+ }
2677
+ if (input.charCodeAt(probe) === CC_SEMICOLON) {
2678
+ currentRulePreludeStart = pos;
2679
+ }
2680
+ }
2681
+
2682
+ return pos;
2376
2683
  },
2377
2684
  semicolon: (input, start, end) => {
2378
2685
  if (isModules && scope === CSS_MODE_IN_BLOCK) {
2379
2686
  isNextRulePrelude = isNextNestedSyntax(input, end);
2380
2687
  }
2688
+ if (pureMode) {
2689
+ if (scope === CSS_MODE_IN_BLOCK) {
2690
+ if (
2691
+ balanced.length === 0 &&
2692
+ !isNextRulePrelude &&
2693
+ !inAtRulePrelude
2694
+ ) {
2695
+ const top = pureTop();
2696
+ if (top) top.hasDirectDecl = true;
2697
+ }
2698
+ } else if (scope === CSS_MODE_TOP_LEVEL && balanced.length === 0) {
2699
+ // Top-level `;` ends a statement (e.g. `@import "x";`).
2700
+ // Advance the prelude pointer so a later impure rule's
2701
+ // reported selector doesn't include the preceding text.
2702
+ currentRulePreludeStart = end;
2703
+ }
2704
+ inAtRulePrelude = false;
2705
+ }
2381
2706
  return end;
2382
2707
  },
2383
2708
  identifier: (input, start, end) => {
@@ -2399,6 +2724,10 @@ class CssParser extends Parser {
2399
2724
  switch (scope) {
2400
2725
  case CSS_MODE_IN_BLOCK: {
2401
2726
  if (isModules && !isNextRulePrelude) {
2727
+ if (balanced.length === 0 && !inAtRulePrelude) {
2728
+ const top = pureTop();
2729
+ if (top) top.hasDirectDecl = true;
2730
+ }
2402
2731
  // Handle only top level values and not inside functions
2403
2732
  return processLocalDeclaration(input, start, end);
2404
2733
  }
@@ -2410,12 +2739,17 @@ class CssParser extends Parser {
2410
2739
  return end;
2411
2740
  },
2412
2741
  delim: (input, start, end) => {
2742
+ const ch = input.charCodeAt(start);
2743
+ if (ch === CC_FULL_STOP && isNextRulePrelude && isLocalMode()) {
2744
+ return processClassSelector(input, start, end);
2745
+ }
2413
2746
  if (
2414
- input.charCodeAt(start) === CC_FULL_STOP &&
2747
+ ch === CC_AMPERSAND &&
2415
2748
  isNextRulePrelude &&
2416
- isLocalMode()
2749
+ parentEffectivePure() &&
2750
+ pureMode
2417
2751
  ) {
2418
- return processClassSelector(input, start, end);
2752
+ currentSelectorHasLocal = true;
2419
2753
  }
2420
2754
 
2421
2755
  return end;
@@ -2622,6 +2956,7 @@ class CssParser extends Parser {
2622
2956
  if (isModules && balanced.length === 0) {
2623
2957
  // Reset stack for `:global .class :local .class-other` selector after
2624
2958
  modeData = undefined;
2959
+ if (pureMode && isNextRulePrelude) finalizeSelector();
2625
2960
  }
2626
2961
 
2627
2962
  lastTokenEndForComments = start;
@@ -2633,6 +2968,23 @@ class CssParser extends Parser {
2633
2968
  /** @type {BuildInfo} */
2634
2969
  (module.buildInfo).strict = true;
2635
2970
 
2971
+ // Topologically sort the files referenced by `composes ... from`
2972
+ // declarations and tag each file's first import dep with the
2973
+ // resulting `sourceOrder`. `NormalModule#build` then reorders the
2974
+ // deps via `sortWithSourceOrder` so the bundle loads them in
2975
+ // cascade-correct order. Files stuck in a cycle are not visited
2976
+ // and keep their natural loc-based position.
2977
+ if (composesFirstFileImport.size > 1) {
2978
+ topologicalSort(
2979
+ composesGraph,
2980
+ [...composesFirstFileImport.keys()],
2981
+ (file, i) => {
2982
+ /** @type {CssIcssImportDependency} */
2983
+ (composesFirstFileImport.get(file)).sourceOrder = i;
2984
+ }
2985
+ );
2986
+ }
2987
+
2636
2988
  const buildMeta = /** @type {BuildMeta} */ (state.module.buildMeta);
2637
2989
 
2638
2990
  buildMeta.exportsType = this.options.namedExports ? "namespace" : "default";
@@ -2653,6 +3005,7 @@ class CssParser extends Parser {
2653
3005
  }
2654
3006
 
2655
3007
  /**
3008
+ * Returns comments in the range.
2656
3009
  * @param {Range} range range
2657
3010
  * @returns {Comment[]} comments in the range
2658
3011
  */
@@ -2660,6 +3013,7 @@ class CssParser extends Parser {
2660
3013
  if (!this.comments) return [];
2661
3014
  const [rangeStart, rangeEnd] = range;
2662
3015
  /**
3016
+ * Returns compared.
2663
3017
  * @param {Comment} comment comment
2664
3018
  * @param {number} needle needle
2665
3019
  * @returns {number} compared
@@ -2682,6 +3036,7 @@ class CssParser extends Parser {
2682
3036
  }
2683
3037
 
2684
3038
  /**
3039
+ * Parses comment options.
2685
3040
  * @param {Range} range range of the comment
2686
3041
  * @returns {{ options: Record<string, EXPECTED_ANY> | null, errors: (Error & { comment: Comment })[] | null }} result
2687
3042
  */