webpack 5.97.1 → 5.104.1

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 (610) hide show
  1. package/README.md +368 -434
  2. package/bin/webpack.js +15 -9
  3. package/hot/dev-server.js +18 -3
  4. package/hot/emitter-event-target.js +7 -0
  5. package/hot/lazy-compilation-node.js +45 -29
  6. package/hot/lazy-compilation-universal.js +18 -0
  7. package/hot/lazy-compilation-web.js +15 -5
  8. package/hot/load-http.js +7 -0
  9. package/hot/log.js +15 -15
  10. package/hot/only-dev-server.js +19 -4
  11. package/hot/poll.js +1 -0
  12. package/lib/APIPlugin.js +48 -50
  13. package/lib/AbstractMethodError.js +1 -0
  14. package/lib/AsyncDependenciesBlock.js +4 -5
  15. package/lib/AutomaticPrefetchPlugin.js +22 -22
  16. package/lib/BannerPlugin.js +35 -40
  17. package/lib/Cache.js +12 -9
  18. package/lib/CacheFacade.js +13 -13
  19. package/lib/CaseSensitiveModulesWarning.js +6 -6
  20. package/lib/Chunk.js +68 -47
  21. package/lib/ChunkGraph.js +174 -95
  22. package/lib/ChunkGroup.js +32 -24
  23. package/lib/ChunkTemplate.js +8 -8
  24. package/lib/CleanPlugin.js +90 -42
  25. package/lib/CodeGenerationResults.js +12 -9
  26. package/lib/CompatibilityPlugin.js +70 -21
  27. package/lib/Compilation.js +827 -550
  28. package/lib/Compiler.js +137 -109
  29. package/lib/ConcatenationScope.js +45 -8
  30. package/lib/ConditionalInitFragment.js +1 -1
  31. package/lib/ConstPlugin.js +89 -59
  32. package/lib/ContextExclusionPlugin.js +5 -4
  33. package/lib/ContextModule.js +66 -51
  34. package/lib/ContextModuleFactory.js +51 -30
  35. package/lib/ContextReplacementPlugin.js +89 -34
  36. package/lib/CssModule.js +8 -4
  37. package/lib/DefinePlugin.js +209 -57
  38. package/lib/DelegatedModule.js +34 -23
  39. package/lib/DelegatedModuleFactoryPlugin.js +27 -24
  40. package/lib/DelegatedPlugin.js +4 -2
  41. package/lib/DependenciesBlock.js +0 -2
  42. package/lib/Dependency.js +37 -19
  43. package/lib/DependencyTemplate.js +2 -0
  44. package/lib/DependencyTemplates.js +5 -6
  45. package/lib/DllEntryPlugin.js +8 -4
  46. package/lib/DllModule.js +11 -12
  47. package/lib/DllModuleFactory.js +2 -2
  48. package/lib/DllPlugin.js +9 -6
  49. package/lib/DllReferencePlugin.js +60 -65
  50. package/lib/DotenvPlugin.js +462 -0
  51. package/lib/DynamicEntryPlugin.js +8 -8
  52. package/lib/EntryOptionPlugin.js +8 -6
  53. package/lib/EntryPlugin.js +5 -3
  54. package/lib/Entrypoint.js +19 -0
  55. package/lib/EnvironmentNotSupportAsyncWarning.js +0 -3
  56. package/lib/EnvironmentPlugin.js +26 -19
  57. package/lib/ErrorHelpers.js +6 -6
  58. package/lib/EvalDevToolModulePlugin.js +17 -14
  59. package/lib/EvalSourceMapDevToolPlugin.js +156 -142
  60. package/lib/ExportsInfo.js +180 -115
  61. package/lib/ExportsInfoApiPlugin.js +2 -2
  62. package/lib/ExternalModule.js +256 -102
  63. package/lib/ExternalModuleFactoryPlugin.js +66 -29
  64. package/lib/ExternalsPlugin.js +57 -2
  65. package/lib/FileSystemInfo.js +313 -247
  66. package/lib/FlagAllModulesAsUsedPlugin.js +2 -2
  67. package/lib/FlagDependencyExportsPlugin.js +29 -19
  68. package/lib/FlagDependencyUsagePlugin.js +9 -10
  69. package/lib/FlagEntryExportAsUsedPlugin.js +1 -1
  70. package/lib/Generator.js +43 -10
  71. package/lib/GraphHelpers.js +11 -3
  72. package/lib/HookWebpackError.js +35 -7
  73. package/lib/HotModuleReplacementPlugin.js +149 -108
  74. package/lib/HotUpdateChunk.js +0 -3
  75. package/lib/IgnoreErrorModuleFactory.js +2 -2
  76. package/lib/IgnorePlugin.js +16 -13
  77. package/lib/IgnoreWarningsPlugin.js +6 -4
  78. package/lib/InitFragment.js +41 -23
  79. package/lib/InvalidDependenciesModuleWarning.js +2 -3
  80. package/lib/JavascriptMetaInfoPlugin.js +2 -4
  81. package/lib/LibManifestPlugin.js +12 -13
  82. package/lib/LoaderOptionsPlugin.js +12 -14
  83. package/lib/LoaderTargetPlugin.js +5 -3
  84. package/lib/MainTemplate.js +18 -29
  85. package/lib/ManifestPlugin.js +235 -0
  86. package/lib/Module.js +138 -60
  87. package/lib/ModuleBuildError.js +4 -2
  88. package/lib/ModuleDependencyError.js +4 -3
  89. package/lib/ModuleDependencyWarning.js +4 -3
  90. package/lib/ModuleError.js +1 -1
  91. package/lib/ModuleFactory.js +10 -3
  92. package/lib/ModuleFilenameHelpers.js +63 -60
  93. package/lib/ModuleGraph.js +195 -70
  94. package/lib/ModuleGraphConnection.js +14 -20
  95. package/lib/ModuleInfoHeaderPlugin.js +15 -16
  96. package/lib/ModuleNotFoundError.js +1 -1
  97. package/lib/ModuleParseError.js +8 -4
  98. package/lib/ModuleSourceTypeConstants.js +189 -0
  99. package/lib/ModuleTemplate.js +7 -8
  100. package/lib/ModuleTypeConstants.js +37 -15
  101. package/lib/ModuleWarning.js +1 -1
  102. package/lib/MultiCompiler.js +64 -49
  103. package/lib/MultiStats.js +19 -14
  104. package/lib/MultiWatching.js +7 -11
  105. package/lib/NoEmitOnErrorsPlugin.js +5 -3
  106. package/lib/NodeStuffPlugin.js +438 -126
  107. package/lib/NormalModule.js +322 -201
  108. package/lib/NormalModuleFactory.js +230 -117
  109. package/lib/NormalModuleReplacementPlugin.js +37 -39
  110. package/lib/NullFactory.js +3 -2
  111. package/lib/OptimizationStages.js +1 -1
  112. package/lib/OptionsApply.js +1 -1
  113. package/lib/Parser.js +5 -3
  114. package/lib/PlatformPlugin.js +3 -1
  115. package/lib/PrefetchPlugin.js +6 -4
  116. package/lib/ProgressPlugin.js +48 -49
  117. package/lib/ProvidePlugin.js +7 -5
  118. package/lib/RawModule.js +26 -12
  119. package/lib/RecordIdsPlugin.js +88 -110
  120. package/lib/RequestShortener.js +3 -1
  121. package/lib/ResolverFactory.js +15 -14
  122. package/lib/RuntimeGlobals.js +216 -153
  123. package/lib/RuntimeModule.js +7 -6
  124. package/lib/RuntimePlugin.js +115 -62
  125. package/lib/RuntimeTemplate.js +248 -76
  126. package/lib/SelfModuleFactory.js +2 -2
  127. package/lib/SizeFormatHelpers.js +2 -2
  128. package/lib/SourceMapDevToolModuleOptionsPlugin.js +17 -27
  129. package/lib/SourceMapDevToolPlugin.js +72 -59
  130. package/lib/Stats.js +2 -3
  131. package/lib/Template.js +31 -24
  132. package/lib/TemplatedPathPlugin.js +24 -21
  133. package/lib/UseStrictPlugin.js +1 -1
  134. package/lib/WarnCaseSensitiveModulesPlugin.js +36 -37
  135. package/lib/WarnDeprecatedOptionPlugin.js +7 -8
  136. package/lib/WarnNoModeSetPlugin.js +3 -1
  137. package/lib/WatchIgnorePlugin.js +11 -9
  138. package/lib/Watching.js +27 -29
  139. package/lib/WebpackError.js +10 -3
  140. package/lib/WebpackIsIncludedPlugin.js +4 -5
  141. package/lib/WebpackOptionsApply.js +263 -135
  142. package/lib/asset/AssetBytesGenerator.js +171 -0
  143. package/lib/asset/AssetBytesParser.js +37 -0
  144. package/lib/asset/AssetGenerator.js +285 -223
  145. package/lib/asset/AssetModulesPlugin.js +103 -41
  146. package/lib/asset/AssetParser.js +7 -3
  147. package/lib/asset/AssetSourceGenerator.js +41 -17
  148. package/lib/asset/RawDataUrlModule.js +17 -9
  149. package/lib/async-modules/AsyncModuleHelpers.js +52 -0
  150. package/lib/async-modules/AwaitDependenciesInitFragment.js +39 -24
  151. package/lib/async-modules/InferAsyncModulesPlugin.js +25 -26
  152. package/lib/buildChunkGraph.js +36 -17
  153. package/lib/cache/AddBuildDependenciesPlugin.js +5 -6
  154. package/lib/cache/IdleFileCachePlugin.js +22 -20
  155. package/lib/cache/MemoryCachePlugin.js +3 -3
  156. package/lib/cache/MemoryWithGcCachePlugin.js +17 -11
  157. package/lib/cache/PackFileCacheStrategy.js +198 -170
  158. package/lib/cache/ResolverCachePlugin.js +58 -48
  159. package/lib/cache/getLazyHashedEtag.js +5 -4
  160. package/lib/cli.js +197 -39
  161. package/lib/config/browserslistTargetHandler.js +110 -85
  162. package/lib/config/defaults.js +514 -113
  163. package/lib/config/normalization.js +91 -64
  164. package/lib/config/target.js +30 -18
  165. package/lib/container/ContainerEntryDependency.js +0 -1
  166. package/lib/container/ContainerEntryModule.js +16 -15
  167. package/lib/container/ContainerEntryModuleFactory.js +2 -2
  168. package/lib/container/ContainerPlugin.js +5 -6
  169. package/lib/container/ContainerReferencePlugin.js +27 -30
  170. package/lib/container/FallbackDependency.js +2 -1
  171. package/lib/container/FallbackModule.js +19 -14
  172. package/lib/container/FallbackModuleFactory.js +2 -2
  173. package/lib/container/HoistContainerReferencesPlugin.js +7 -7
  174. package/lib/container/ModuleFederationPlugin.js +4 -4
  175. package/lib/container/RemoteModule.js +14 -14
  176. package/lib/container/RemoteRuntimeModule.js +2 -2
  177. package/lib/container/options.js +9 -9
  178. package/lib/css/CssGenerator.js +366 -74
  179. package/lib/css/CssLoadingRuntimeModule.js +26 -16
  180. package/lib/css/CssMergeStyleSheetsRuntimeModule.js +56 -0
  181. package/lib/css/CssModulesPlugin.js +191 -142
  182. package/lib/css/CssParser.js +1756 -740
  183. package/lib/css/walkCssTokens.js +180 -67
  184. package/lib/debug/ProfilingPlugin.js +135 -51
  185. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +29 -28
  186. package/lib/dependencies/AMDPlugin.js +18 -11
  187. package/lib/dependencies/AMDRequireArrayDependency.js +5 -4
  188. package/lib/dependencies/AMDRequireContextDependency.js +2 -1
  189. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +35 -26
  190. package/lib/dependencies/AMDRuntimeModules.js +3 -1
  191. package/lib/dependencies/CachedConstDependency.js +24 -18
  192. package/lib/dependencies/CommonJsExportRequireDependency.js +31 -24
  193. package/lib/dependencies/CommonJsExportsDependency.js +2 -1
  194. package/lib/dependencies/CommonJsExportsParserPlugin.js +50 -36
  195. package/lib/dependencies/CommonJsFullRequireDependency.js +7 -13
  196. package/lib/dependencies/CommonJsImportsParserPlugin.js +146 -127
  197. package/lib/dependencies/CommonJsPlugin.js +29 -18
  198. package/lib/dependencies/CommonJsRequireContextDependency.js +4 -3
  199. package/lib/dependencies/CommonJsSelfReferenceDependency.js +4 -4
  200. package/lib/dependencies/ConstDependency.js +2 -2
  201. package/lib/dependencies/ContextDependency.js +10 -5
  202. package/lib/dependencies/ContextDependencyHelpers.js +21 -13
  203. package/lib/dependencies/ContextDependencyTemplateAsId.js +10 -9
  204. package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +13 -10
  205. package/lib/dependencies/ContextElementDependency.js +23 -12
  206. package/lib/dependencies/CssIcssExportDependency.js +402 -22
  207. package/lib/dependencies/CssIcssImportDependency.js +116 -51
  208. package/lib/dependencies/CssIcssSymbolDependency.js +33 -35
  209. package/lib/dependencies/CssImportDependency.js +17 -14
  210. package/lib/dependencies/CssUrlDependency.js +8 -13
  211. package/lib/dependencies/DynamicExports.js +19 -19
  212. package/lib/dependencies/ExportsInfoDependency.js +13 -10
  213. package/lib/dependencies/ExternalModuleDependency.js +7 -7
  214. package/lib/dependencies/ExternalModuleInitFragment.js +3 -2
  215. package/lib/dependencies/ExternalModuleInitFragmentDependency.js +96 -0
  216. package/lib/dependencies/HarmonyAcceptDependency.js +96 -5
  217. package/lib/dependencies/HarmonyAcceptImportDependency.js +2 -5
  218. package/lib/dependencies/HarmonyCompatibilityDependency.js +0 -1
  219. package/lib/dependencies/HarmonyDetectionParserPlugin.js +10 -30
  220. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +19 -8
  221. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +136 -99
  222. package/lib/dependencies/HarmonyExportExpressionDependency.js +1 -1
  223. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +152 -61
  224. package/lib/dependencies/HarmonyExportInitFragment.js +2 -2
  225. package/lib/dependencies/HarmonyExportSpecifierDependency.js +2 -2
  226. package/lib/dependencies/HarmonyExports.js +5 -5
  227. package/lib/dependencies/HarmonyImportDependency.js +92 -45
  228. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +201 -163
  229. package/lib/dependencies/HarmonyImportSideEffectDependency.js +5 -6
  230. package/lib/dependencies/HarmonyImportSpecifierDependency.js +69 -42
  231. package/lib/dependencies/HarmonyModulesPlugin.js +16 -11
  232. package/lib/dependencies/HarmonyTopLevelThisParserPlugin.js +15 -15
  233. package/lib/dependencies/ImportContextDependency.js +15 -1
  234. package/lib/dependencies/ImportDependency.js +25 -7
  235. package/lib/dependencies/ImportEagerDependency.js +7 -5
  236. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +23 -13
  237. package/lib/dependencies/ImportMetaContextPlugin.js +2 -2
  238. package/lib/dependencies/ImportMetaPlugin.js +172 -20
  239. package/lib/dependencies/ImportParserPlugin.js +327 -49
  240. package/lib/dependencies/ImportPhase.js +121 -0
  241. package/lib/dependencies/ImportPlugin.js +3 -1
  242. package/lib/dependencies/ImportWeakDependency.js +7 -5
  243. package/lib/dependencies/JsonExportsDependency.js +54 -28
  244. package/lib/dependencies/LoaderDependency.js +0 -3
  245. package/lib/dependencies/LoaderImportDependency.js +0 -3
  246. package/lib/dependencies/LoaderPlugin.js +24 -25
  247. package/lib/dependencies/LocalModulesHelpers.js +4 -4
  248. package/lib/dependencies/ModuleDecoratorDependency.js +2 -4
  249. package/lib/dependencies/ModuleDependency.js +14 -13
  250. package/lib/dependencies/ModuleDependencyTemplateAsRequireId.js +1 -0
  251. package/lib/dependencies/ModuleHotAcceptDependency.js +1 -1
  252. package/lib/dependencies/NullDependency.js +2 -0
  253. package/lib/dependencies/ProvidedDependency.js +8 -10
  254. package/lib/dependencies/PureExpressionDependency.js +1 -2
  255. package/lib/dependencies/RequireContextDependency.js +2 -1
  256. package/lib/dependencies/RequireContextDependencyParserPlugin.js +47 -44
  257. package/lib/dependencies/RequireContextPlugin.js +5 -2
  258. package/lib/dependencies/RequireEnsureDependenciesBlock.js +3 -3
  259. package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +101 -99
  260. package/lib/dependencies/RequireEnsurePlugin.js +6 -6
  261. package/lib/dependencies/RequireIncludeDependency.js +2 -2
  262. package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +33 -34
  263. package/lib/dependencies/RequireIncludePlugin.js +1 -0
  264. package/lib/dependencies/RequireResolveContextDependency.js +1 -1
  265. package/lib/dependencies/RequireResolveDependency.js +3 -3
  266. package/lib/dependencies/RuntimeRequirementsDependency.js +3 -4
  267. package/lib/dependencies/StaticExportsDependency.js +3 -5
  268. package/lib/dependencies/SystemPlugin.js +4 -4
  269. package/lib/dependencies/URLContextDependency.js +65 -0
  270. package/lib/dependencies/URLDependency.js +3 -8
  271. package/lib/dependencies/URLPlugin.js +18 -159
  272. package/lib/dependencies/WebAssemblyExportImportedDependency.js +3 -3
  273. package/lib/dependencies/WebAssemblyImportDependency.js +2 -2
  274. package/lib/dependencies/WebpackIsIncludedDependency.js +2 -3
  275. package/lib/dependencies/WorkerDependency.js +8 -6
  276. package/lib/dependencies/WorkerPlugin.js +131 -67
  277. package/lib/dependencies/getFunctionExpression.js +2 -2
  278. package/lib/dependencies/processExportInfo.js +4 -4
  279. package/lib/esm/ExportWebpackRequireRuntimeModule.js +1 -1
  280. package/lib/esm/ModuleChunkFormatPlugin.js +232 -179
  281. package/lib/esm/ModuleChunkLoadingPlugin.js +112 -57
  282. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +102 -28
  283. package/lib/formatLocation.js +2 -2
  284. package/lib/hmr/HotModuleReplacement.runtime.js +41 -29
  285. package/lib/hmr/HotModuleReplacementRuntimeModule.js +1 -1
  286. package/lib/hmr/JavascriptHotModuleReplacement.runtime.js +43 -33
  287. package/lib/hmr/JavascriptHotModuleReplacementHelper.js +37 -0
  288. package/lib/hmr/LazyCompilationPlugin.js +67 -54
  289. package/lib/hmr/lazyCompilationBackend.js +23 -18
  290. package/lib/ids/ChunkModuleIdRangePlugin.js +14 -11
  291. package/lib/ids/DeterministicChunkIdsPlugin.js +32 -37
  292. package/lib/ids/DeterministicModuleIdsPlugin.js +52 -52
  293. package/lib/ids/HashedModuleIdsPlugin.js +15 -13
  294. package/lib/ids/IdHelpers.js +66 -49
  295. package/lib/ids/NamedChunkIdsPlugin.js +14 -17
  296. package/lib/ids/NamedModuleIdsPlugin.js +12 -14
  297. package/lib/ids/NaturalChunkIdsPlugin.js +6 -4
  298. package/lib/ids/NaturalModuleIdsPlugin.js +4 -3
  299. package/lib/ids/OccurrenceChunkIdsPlugin.js +7 -5
  300. package/lib/ids/OccurrenceModuleIdsPlugin.js +8 -7
  301. package/lib/ids/SyncModuleIdsPlugin.js +18 -13
  302. package/lib/index.js +54 -14
  303. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +116 -119
  304. package/lib/javascript/BasicEvaluatedExpression.js +26 -18
  305. package/lib/javascript/ChunkFormatHelpers.js +70 -0
  306. package/lib/javascript/ChunkHelpers.js +17 -5
  307. package/lib/javascript/CommonJsChunkFormatPlugin.js +114 -141
  308. package/lib/javascript/EnableChunkLoadingPlugin.js +7 -4
  309. package/lib/javascript/JavascriptGenerator.js +122 -100
  310. package/lib/javascript/JavascriptModulesPlugin.js +332 -152
  311. package/lib/javascript/JavascriptParser.js +1488 -1052
  312. package/lib/javascript/JavascriptParserHelpers.js +48 -47
  313. package/lib/javascript/StartupHelpers.js +23 -22
  314. package/lib/json/JsonData.js +4 -4
  315. package/lib/json/JsonGenerator.js +66 -32
  316. package/lib/json/JsonModulesPlugin.js +16 -6
  317. package/lib/json/JsonParser.js +23 -8
  318. package/lib/library/AbstractLibraryPlugin.js +45 -10
  319. package/lib/library/AmdLibraryPlugin.js +7 -5
  320. package/lib/library/AssignLibraryPlugin.js +71 -17
  321. package/lib/library/EnableLibraryPlugin.js +51 -25
  322. package/lib/library/ExportPropertyLibraryPlugin.js +12 -18
  323. package/lib/library/JsonpLibraryPlugin.js +5 -2
  324. package/lib/library/ModuleLibraryPlugin.js +230 -18
  325. package/lib/library/SystemLibraryPlugin.js +29 -11
  326. package/lib/library/UmdLibraryPlugin.js +35 -32
  327. package/lib/logging/Logger.js +18 -15
  328. package/lib/logging/createConsoleLogger.js +27 -27
  329. package/lib/logging/runtime.js +11 -11
  330. package/lib/logging/truncateArgs.js +5 -5
  331. package/lib/node/CommonJsChunkLoadingPlugin.js +72 -75
  332. package/lib/node/NodeEnvironmentPlugin.js +9 -3
  333. package/lib/node/NodeTargetPlugin.js +9 -1
  334. package/lib/node/NodeTemplatePlugin.js +2 -2
  335. package/lib/node/NodeWatchFileSystem.js +4 -4
  336. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +22 -38
  337. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +10 -11
  338. package/lib/node/ReadFileCompileWasmPlugin.js +11 -14
  339. package/lib/node/RequireChunkLoadingRuntimeModule.js +22 -30
  340. package/lib/node/nodeConsole.js +12 -7
  341. package/lib/optimize/AggressiveMergingPlugin.js +46 -47
  342. package/lib/optimize/AggressiveSplittingPlugin.js +233 -238
  343. package/lib/optimize/ConcatenatedModule.js +620 -251
  344. package/lib/optimize/EnsureChunkConditionsPlugin.js +58 -58
  345. package/lib/optimize/FlagIncludedChunksPlugin.js +93 -96
  346. package/lib/optimize/InnerGraph.js +139 -124
  347. package/lib/optimize/InnerGraphPlugin.js +29 -24
  348. package/lib/optimize/LimitChunkCountPlugin.js +32 -8
  349. package/lib/optimize/MangleExportsPlugin.js +22 -22
  350. package/lib/optimize/MergeDuplicateChunksPlugin.js +80 -81
  351. package/lib/optimize/MinChunkSizePlugin.js +12 -7
  352. package/lib/optimize/ModuleConcatenationPlugin.js +92 -71
  353. package/lib/optimize/RealContentHashPlugin.js +58 -44
  354. package/lib/optimize/RemoveEmptyChunksPlugin.js +8 -5
  355. package/lib/optimize/RemoveParentModulesPlugin.js +7 -4
  356. package/lib/optimize/RuntimeChunkPlugin.js +22 -25
  357. package/lib/optimize/SideEffectsFlagPlugin.js +44 -26
  358. package/lib/optimize/SplitChunksPlugin.js +209 -158
  359. package/lib/performance/AssetsOverSizeLimitWarning.js +1 -1
  360. package/lib/performance/EntrypointsOverSizeLimitWarning.js +2 -2
  361. package/lib/performance/SizeLimitsPlugin.js +8 -5
  362. package/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js +5 -7
  363. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +61 -64
  364. package/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js +3 -4
  365. package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +2 -2
  366. package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +2 -2
  367. package/lib/rules/BasicEffectRulePlugin.js +14 -5
  368. package/lib/rules/BasicMatcherRulePlugin.js +18 -7
  369. package/lib/rules/ObjectMatcherRulePlugin.js +17 -6
  370. package/lib/rules/RuleSetCompiler.js +73 -32
  371. package/lib/rules/UseEffectRulePlugin.js +61 -25
  372. package/lib/runtime/AsyncModuleRuntimeModule.js +74 -9
  373. package/lib/runtime/AutoPublicPathRuntimeModule.js +9 -4
  374. package/lib/runtime/BaseUriRuntimeModule.js +2 -2
  375. package/lib/runtime/CompatRuntimeModule.js +0 -1
  376. package/lib/runtime/CreateFakeNamespaceObjectRuntimeModule.js +1 -1
  377. package/lib/runtime/GetChunkFilenameRuntimeModule.js +34 -35
  378. package/lib/runtime/GetMainFilenameRuntimeModule.js +1 -1
  379. package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +1 -1
  380. package/lib/runtime/LoadScriptRuntimeModule.js +0 -2
  381. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +248 -0
  382. package/lib/runtime/PublicPathRuntimeModule.js +2 -2
  383. package/lib/runtime/RuntimeIdRuntimeModule.js +2 -1
  384. package/lib/runtime/StartupChunkDependenciesPlugin.js +39 -42
  385. package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +10 -9
  386. package/lib/runtime/StartupEntrypointRuntimeModule.js +0 -1
  387. package/lib/runtime/SystemContextRuntimeModule.js +0 -2
  388. package/lib/runtime/ToBinaryRuntimeModule.js +64 -0
  389. package/lib/schemes/DataUriPlugin.js +9 -31
  390. package/lib/schemes/FileUriPlugin.js +11 -6
  391. package/lib/schemes/HttpUriPlugin.js +381 -261
  392. package/lib/schemes/VirtualUrlPlugin.js +222 -0
  393. package/lib/serialization/AggregateErrorSerializer.js +41 -0
  394. package/lib/serialization/BinaryMiddleware.js +51 -33
  395. package/lib/serialization/ErrorObjectSerializer.js +7 -2
  396. package/lib/serialization/FileMiddleware.js +101 -71
  397. package/lib/serialization/NullPrototypeObjectSerializer.js +5 -3
  398. package/lib/serialization/ObjectMiddleware.js +130 -54
  399. package/lib/serialization/PlainObjectSerializer.js +1 -1
  400. package/lib/serialization/Serializer.js +38 -20
  401. package/lib/serialization/SerializerMiddleware.js +121 -49
  402. package/lib/serialization/SingleItemMiddleware.js +9 -7
  403. package/lib/serialization/types.js +1 -1
  404. package/lib/sharing/ConsumeSharedModule.js +9 -9
  405. package/lib/sharing/ConsumeSharedPlugin.js +14 -14
  406. package/lib/sharing/ConsumeSharedRuntimeModule.js +11 -8
  407. package/lib/sharing/ProvideSharedModule.js +9 -11
  408. package/lib/sharing/ProvideSharedModuleFactory.js +5 -3
  409. package/lib/sharing/ProvideSharedPlugin.js +15 -10
  410. package/lib/sharing/SharePlugin.js +3 -4
  411. package/lib/sharing/ShareRuntimeModule.js +7 -6
  412. package/lib/sharing/resolveMatchedConfigs.js +27 -13
  413. package/lib/sharing/utils.js +37 -43
  414. package/lib/stats/DefaultStatsFactoryPlugin.js +455 -286
  415. package/lib/stats/DefaultStatsPresetPlugin.js +77 -46
  416. package/lib/stats/DefaultStatsPrinterPlugin.js +583 -419
  417. package/lib/stats/StatsFactory.js +75 -32
  418. package/lib/stats/StatsPrinter.js +71 -51
  419. package/lib/url/URLParserPlugin.js +264 -0
  420. package/lib/util/ArrayHelpers.js +6 -8
  421. package/lib/util/ArrayQueue.js +1 -1
  422. package/lib/util/AsyncQueue.js +11 -10
  423. package/lib/util/Hash.js +37 -5
  424. package/lib/util/IterableHelpers.js +4 -4
  425. package/lib/util/LazyBucketSortedSet.js +46 -27
  426. package/lib/util/LazySet.js +16 -10
  427. package/lib/util/MapHelpers.js +1 -1
  428. package/lib/util/ParallelismFactorCalculator.js +2 -2
  429. package/lib/util/Semaphore.js +3 -3
  430. package/lib/util/SetHelpers.js +6 -6
  431. package/lib/util/SortableSet.js +11 -9
  432. package/lib/util/StackedCacheMap.js +2 -2
  433. package/lib/util/StackedMap.js +3 -3
  434. package/lib/util/StringXor.js +2 -1
  435. package/lib/util/TupleQueue.js +11 -8
  436. package/lib/util/TupleSet.js +44 -19
  437. package/lib/util/URLAbsoluteSpecifier.js +3 -4
  438. package/lib/util/WeakTupleMap.js +56 -42
  439. package/lib/util/binarySearchBounds.js +4 -3
  440. package/lib/util/chainedImports.js +3 -1
  441. package/lib/util/cleverMerge.js +171 -107
  442. package/lib/util/comparators.js +265 -162
  443. package/lib/util/compileBooleanMatcher.js +120 -41
  444. package/lib/util/concatenate.js +20 -16
  445. package/lib/util/conventions.js +73 -74
  446. package/lib/util/create-schema-validation.js +8 -8
  447. package/lib/util/createHash.js +32 -135
  448. package/lib/util/dataURL.js +39 -0
  449. package/lib/util/deprecation.js +119 -116
  450. package/lib/util/deterministicGrouping.js +56 -47
  451. package/lib/util/extractSourceMap.js +319 -0
  452. package/lib/util/extractUrlAndGlobal.js +1 -1
  453. package/lib/util/findGraphRoots.js +19 -9
  454. package/lib/util/fs.js +169 -141
  455. package/lib/util/hash/BatchedHash.js +50 -10
  456. package/lib/util/hash/BulkUpdateHash.js +138 -0
  457. package/lib/util/hash/DebugHash.js +75 -0
  458. package/lib/util/hash/hash-digest.js +216 -0
  459. package/lib/util/hash/md4.js +2 -2
  460. package/lib/util/hash/wasm-hash.js +59 -17
  461. package/lib/util/identifier.js +124 -61
  462. package/lib/util/internalSerializables.js +4 -6
  463. package/lib/util/magicComment.js +9 -5
  464. package/lib/util/makeSerializable.js +2 -2
  465. package/lib/util/memoize.js +5 -2
  466. package/lib/util/objectToMap.js +3 -2
  467. package/lib/util/processAsyncTree.js +5 -5
  468. package/lib/util/propertyAccess.js +1 -1
  469. package/lib/util/propertyName.js +2 -3
  470. package/lib/util/registerExternalSerializer.js +16 -20
  471. package/lib/util/removeBOM.js +25 -0
  472. package/lib/util/runtime.js +72 -56
  473. package/lib/util/semver.js +44 -33
  474. package/lib/util/serialization.js +56 -56
  475. package/lib/util/smartGrouping.js +42 -27
  476. package/lib/util/source.js +5 -4
  477. package/lib/util/traverseDestructuringAssignmentProperties.js +45 -0
  478. package/lib/validateSchema.js +7 -9
  479. package/lib/wasm/EnableWasmLoadingPlugin.js +22 -12
  480. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +9 -5
  481. package/lib/wasm-async/AsyncWebAssemblyGenerator.js +15 -3
  482. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +28 -22
  483. package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +47 -57
  484. package/lib/wasm-async/AsyncWebAssemblyParser.js +2 -10
  485. package/lib/wasm-async/UniversalCompileAsyncWasmPlugin.js +8 -4
  486. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +23 -17
  487. package/lib/wasm-sync/WasmFinalizeExportsPlugin.js +55 -57
  488. package/lib/wasm-sync/WebAssemblyGenerator.js +56 -41
  489. package/lib/wasm-sync/WebAssemblyInInitialChunkError.js +6 -3
  490. package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +25 -10
  491. package/lib/wasm-sync/WebAssemblyModulesPlugin.js +11 -12
  492. package/lib/wasm-sync/WebAssemblyParser.js +10 -17
  493. package/lib/wasm-sync/WebAssemblyUtils.js +1 -1
  494. package/lib/web/FetchCompileAsyncWasmPlugin.js +4 -4
  495. package/lib/web/FetchCompileWasmPlugin.js +6 -8
  496. package/lib/web/JsonpChunkLoadingPlugin.js +74 -74
  497. package/lib/web/JsonpChunkLoadingRuntimeModule.js +10 -26
  498. package/lib/web/JsonpTemplatePlugin.js +0 -1
  499. package/lib/webpack.js +107 -87
  500. package/lib/webworker/ImportScriptsChunkLoadingPlugin.js +79 -75
  501. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +38 -51
  502. package/lib/webworker/WebWorkerTemplatePlugin.js +1 -0
  503. package/module.d.ts +5 -0
  504. package/package.json +149 -129
  505. package/schemas/WebpackOptions.check.d.ts +1 -1
  506. package/schemas/WebpackOptions.check.js +2 -2
  507. package/schemas/WebpackOptions.json +543 -190
  508. package/schemas/plugins/BannerPlugin.check.d.ts +1 -1
  509. package/schemas/plugins/BannerPlugin.check.js +2 -2
  510. package/schemas/plugins/BannerPlugin.json +4 -0
  511. package/schemas/plugins/DllPlugin.check.d.ts +1 -1
  512. package/schemas/plugins/DllPlugin.check.js +1 -1
  513. package/schemas/plugins/DllReferencePlugin.check.d.ts +1 -1
  514. package/schemas/plugins/DllReferencePlugin.check.js +1 -1
  515. package/schemas/plugins/IgnorePlugin.check.d.ts +1 -1
  516. package/schemas/plugins/IgnorePlugin.check.js +1 -1
  517. package/schemas/plugins/IgnorePlugin.json +1 -1
  518. package/schemas/plugins/LoaderOptionsPlugin.check.d.ts +1 -1
  519. package/schemas/plugins/LoaderOptionsPlugin.check.js +1 -1
  520. package/schemas/plugins/{HashedModuleIdsPlugin.check.d.ts → ManifestPlugin.check.d.ts} +2 -2
  521. package/schemas/plugins/ManifestPlugin.check.js +6 -0
  522. package/schemas/plugins/ManifestPlugin.json +98 -0
  523. package/schemas/plugins/ProgressPlugin.check.d.ts +1 -1
  524. package/schemas/plugins/ProgressPlugin.check.js +1 -1
  525. package/schemas/plugins/ProgressPlugin.json +1 -1
  526. package/schemas/plugins/SourceMapDevToolPlugin.check.d.ts +1 -1
  527. package/schemas/plugins/SourceMapDevToolPlugin.check.js +2 -2
  528. package/schemas/plugins/SourceMapDevToolPlugin.json +23 -6
  529. package/schemas/plugins/WatchIgnorePlugin.check.d.ts +1 -1
  530. package/schemas/plugins/WatchIgnorePlugin.check.js +1 -1
  531. package/schemas/plugins/asset/AssetGeneratorOptions.check.d.ts +1 -1
  532. package/schemas/plugins/asset/AssetGeneratorOptions.check.js +1 -1
  533. package/schemas/plugins/asset/AssetInlineGeneratorOptions.check.d.ts +1 -1
  534. package/schemas/plugins/asset/AssetInlineGeneratorOptions.check.js +1 -1
  535. package/schemas/plugins/asset/AssetParserOptions.check.d.ts +1 -1
  536. package/schemas/plugins/asset/AssetParserOptions.check.js +1 -1
  537. package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.d.ts +1 -1
  538. package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js +1 -1
  539. package/schemas/plugins/container/ContainerPlugin.check.d.ts +1 -1
  540. package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
  541. package/schemas/plugins/container/ContainerReferencePlugin.check.d.ts +1 -1
  542. package/schemas/plugins/container/ContainerReferencePlugin.check.js +2 -2
  543. package/schemas/plugins/container/ContainerReferencePlugin.json +4 -1
  544. package/schemas/plugins/container/ExternalsType.check.d.ts +1 -1
  545. package/schemas/plugins/container/ExternalsType.check.js +2 -2
  546. package/schemas/plugins/container/ModuleFederationPlugin.check.d.ts +1 -1
  547. package/schemas/plugins/container/ModuleFederationPlugin.check.js +2 -2
  548. package/schemas/plugins/container/ModuleFederationPlugin.json +4 -1
  549. package/schemas/plugins/css/CssGeneratorOptions.check.d.ts +1 -1
  550. package/schemas/plugins/css/CssGeneratorOptions.check.js +1 -1
  551. package/schemas/plugins/css/CssModuleGeneratorOptions.check.d.ts +1 -1
  552. package/schemas/plugins/css/CssModuleGeneratorOptions.check.js +2 -2
  553. package/schemas/plugins/css/CssModuleParserOptions.check.d.ts +1 -1
  554. package/schemas/plugins/css/CssModuleParserOptions.check.js +2 -2
  555. package/schemas/plugins/css/CssParserOptions.check.d.ts +1 -1
  556. package/schemas/plugins/css/CssParserOptions.check.js +2 -2
  557. package/schemas/plugins/debug/ProfilingPlugin.check.d.ts +1 -1
  558. package/schemas/plugins/debug/ProfilingPlugin.check.js +1 -1
  559. package/schemas/plugins/ids/HashedModuleIdsPlugin.check.d.ts +7 -0
  560. package/schemas/plugins/ids/HashedModuleIdsPlugin.check.js +6 -0
  561. package/schemas/plugins/{HashedModuleIdsPlugin.json → ids/HashedModuleIdsPlugin.json} +15 -2
  562. package/schemas/plugins/ids/OccurrenceChunkIdsPlugin.check.d.ts +1 -1
  563. package/schemas/plugins/ids/OccurrenceChunkIdsPlugin.check.js +1 -1
  564. package/schemas/plugins/ids/OccurrenceModuleIdsPlugin.check.d.ts +1 -1
  565. package/schemas/plugins/ids/OccurrenceModuleIdsPlugin.check.js +1 -1
  566. package/schemas/plugins/{css/CssGlobalParserOptions.check.d.ts → json/JsonModulesPluginGenerator.check.d.ts} +1 -1
  567. package/schemas/plugins/json/JsonModulesPluginGenerator.check.js +6 -0
  568. package/schemas/plugins/json/JsonModulesPluginGenerator.json +3 -0
  569. package/schemas/plugins/{css/CssGlobalGeneratorOptions.check.d.ts → json/JsonModulesPluginParser.check.d.ts} +1 -1
  570. package/schemas/plugins/json/JsonModulesPluginParser.check.js +6 -0
  571. package/schemas/plugins/json/JsonModulesPluginParser.json +3 -0
  572. package/schemas/plugins/optimize/AggressiveSplittingPlugin.check.d.ts +1 -1
  573. package/schemas/plugins/optimize/AggressiveSplittingPlugin.check.js +1 -1
  574. package/schemas/plugins/optimize/LimitChunkCountPlugin.check.d.ts +1 -1
  575. package/schemas/plugins/optimize/LimitChunkCountPlugin.check.js +1 -1
  576. package/schemas/plugins/optimize/MergeDuplicateChunksPlugin.check.d.ts +1 -1
  577. package/schemas/plugins/optimize/MergeDuplicateChunksPlugin.check.js +1 -1
  578. package/schemas/plugins/optimize/MinChunkSizePlugin.check.d.ts +1 -1
  579. package/schemas/plugins/optimize/MinChunkSizePlugin.check.js +1 -1
  580. package/schemas/plugins/schemes/HttpUriPlugin.check.d.ts +1 -1
  581. package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
  582. package/schemas/plugins/schemes/VirtualUrlPlugin.check.d.ts +7 -0
  583. package/schemas/plugins/schemes/VirtualUrlPlugin.check.js +6 -0
  584. package/schemas/plugins/schemes/VirtualUrlPlugin.json +77 -0
  585. package/schemas/plugins/sharing/ConsumeSharedPlugin.check.d.ts +1 -1
  586. package/schemas/plugins/sharing/ConsumeSharedPlugin.check.js +1 -1
  587. package/schemas/plugins/sharing/ProvideSharedPlugin.check.d.ts +1 -1
  588. package/schemas/plugins/sharing/ProvideSharedPlugin.check.js +1 -1
  589. package/schemas/plugins/sharing/SharePlugin.check.d.ts +1 -1
  590. package/schemas/plugins/sharing/SharePlugin.check.js +1 -1
  591. package/types.d.ts +5115 -1863
  592. package/SECURITY.md +0 -9
  593. package/lib/ModuleSourceTypesConstants.js +0 -112
  594. package/lib/dependencies/CssLocalIdentifierDependency.js +0 -250
  595. package/lib/dependencies/CssSelfLocalIdentifierDependency.js +0 -111
  596. package/lib/library/ModernModuleLibraryPlugin.js +0 -144
  597. package/schemas/plugins/HashedModuleIdsPlugin.check.js +0 -6
  598. package/schemas/plugins/JsonModulesPluginParser.check.d.ts +0 -7
  599. package/schemas/plugins/JsonModulesPluginParser.check.js +0 -6
  600. package/schemas/plugins/JsonModulesPluginParser.json +0 -12
  601. package/schemas/plugins/css/CssAutoGeneratorOptions.check.d.ts +0 -7
  602. package/schemas/plugins/css/CssAutoGeneratorOptions.check.js +0 -6
  603. package/schemas/plugins/css/CssAutoGeneratorOptions.json +0 -3
  604. package/schemas/plugins/css/CssAutoParserOptions.check.d.ts +0 -7
  605. package/schemas/plugins/css/CssAutoParserOptions.check.js +0 -6
  606. package/schemas/plugins/css/CssAutoParserOptions.json +0 -3
  607. package/schemas/plugins/css/CssGlobalGeneratorOptions.check.js +0 -6
  608. package/schemas/plugins/css/CssGlobalGeneratorOptions.json +0 -3
  609. package/schemas/plugins/css/CssGlobalParserOptions.check.js +0 -6
  610. package/schemas/plugins/css/CssGlobalParserOptions.json +0 -3
@@ -7,6 +7,7 @@
7
7
 
8
8
  const vm = require("vm");
9
9
  const CommentCompilationWarning = require("../CommentCompilationWarning");
10
+ const CssModule = require("../CssModule");
10
11
  const ModuleDependencyWarning = require("../ModuleDependencyWarning");
11
12
  const { CSS_MODULE_TYPE_AUTO } = require("../ModuleTypeConstants");
12
13
  const Parser = require("../Parser");
@@ -17,15 +18,13 @@ const CssIcssExportDependency = require("../dependencies/CssIcssExportDependency
17
18
  const CssIcssImportDependency = require("../dependencies/CssIcssImportDependency");
18
19
  const CssIcssSymbolDependency = require("../dependencies/CssIcssSymbolDependency");
19
20
  const CssImportDependency = require("../dependencies/CssImportDependency");
20
- const CssLocalIdentifierDependency = require("../dependencies/CssLocalIdentifierDependency");
21
- const CssSelfLocalIdentifierDependency = require("../dependencies/CssSelfLocalIdentifierDependency");
22
21
  const CssUrlDependency = require("../dependencies/CssUrlDependency");
23
22
  const StaticExportsDependency = require("../dependencies/StaticExportsDependency");
24
23
  const binarySearchBounds = require("../util/binarySearchBounds");
25
24
  const { parseResource } = require("../util/identifier");
26
25
  const {
27
- webpackCommentRegExp,
28
- createMagicCommentContext
26
+ createMagicCommentContext,
27
+ webpackCommentRegExp
29
28
  } = require("../util/magicComment");
30
29
  const walkCssTokens = require("./walkCssTokens");
31
30
 
@@ -34,17 +33,23 @@ const walkCssTokens = require("./walkCssTokens");
34
33
  /** @typedef {import("../Parser").ParserState} ParserState */
35
34
  /** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
36
35
  /** @typedef {import("./walkCssTokens").CssTokenCallbacks} CssTokenCallbacks */
36
+ /** @typedef {import("../../declarations/WebpackOptions").CssModuleParserOptions} CssModuleParserOptions */
37
37
 
38
38
  /** @typedef {[number, number]} Range */
39
39
  /** @typedef {{ line: number, column: number }} Position */
40
40
  /** @typedef {{ value: string, range: Range, loc: { start: Position, end: Position } }} Comment */
41
41
 
42
42
  const CC_COLON = ":".charCodeAt(0);
43
- const CC_SLASH = "/".charCodeAt(0);
43
+ const CC_SEMICOLON = ";".charCodeAt(0);
44
+ const CC_COMMA = ",".charCodeAt(0);
44
45
  const CC_LEFT_PARENTHESIS = "(".charCodeAt(0);
45
46
  const CC_RIGHT_PARENTHESIS = ")".charCodeAt(0);
46
47
  const CC_LOWER_F = "f".charCodeAt(0);
47
48
  const CC_UPPER_F = "F".charCodeAt(0);
49
+ const CC_RIGHT_CURLY = "}".charCodeAt(0);
50
+ const CC_HYPHEN_MINUS = "-".charCodeAt(0);
51
+ const CC_TILDE = "~".charCodeAt(0);
52
+ const CC_EQUAL = "=".charCodeAt(0);
48
53
 
49
54
  // https://www.w3.org/TR/css-syntax-3/#newline
50
55
  // We don't have `preprocessing` stage, so we need specify all of them
@@ -54,11 +59,30 @@ const TRIM_WHITE_SPACES = /(^[ \t\n\r\f]*|[ \t\n\r\f]*$)/g;
54
59
  const UNESCAPE = /\\([0-9a-fA-F]{1,6}[ \t\n\r\f]?|[\s\S])/g;
55
60
  const IMAGE_SET_FUNCTION = /^(-\w+-)?image-set$/i;
56
61
  const OPTIONALLY_VENDOR_PREFIXED_KEYFRAMES_AT_RULE = /^@(-\w+-)?keyframes$/;
57
- const OPTIONALLY_VENDOR_PREFIXED_ANIMATION_PROPERTY =
58
- /^(-\w+-)?animation(-name)?$/i;
62
+ const COMPOSES_PROPERTY = /^(composes|compose-with)$/i;
59
63
  const IS_MODULES = /\.module(s)?\.[^.]+$/i;
60
64
  const CSS_COMMENT = /\/\*((?!\*\/).*?)\*\//g;
61
65
 
66
+ /**
67
+ * @param {RegExp} regexp a regexp
68
+ * @param {string} str a string
69
+ * @returns {RegExpExecArray[]} matches
70
+ */
71
+ const matchAll = (regexp, str) => {
72
+ /** @type {RegExpExecArray[]} */
73
+ const result = [];
74
+
75
+ let match;
76
+
77
+ // Use a while loop with exec() to find all matches
78
+ while ((match = regexp.exec(str)) !== null) {
79
+ result.push(match);
80
+ }
81
+ // Return an array to be easily iterable (note: a true spec-compliant polyfill
82
+ // returns an iterator object, but an array spread often suffices for basic use)
83
+ return result;
84
+ };
85
+
62
86
  /**
63
87
  * @param {string} str url string
64
88
  * @param {boolean} isString is url wrapped in quotes
@@ -76,7 +100,7 @@ const normalizeUrl = (str, isString) => {
76
100
  // Remove unnecessary spaces from `url(" img.png ")`
77
101
  .replace(TRIM_WHITE_SPACES, "")
78
102
  // Unescape
79
- .replace(UNESCAPE, match => {
103
+ .replace(UNESCAPE, (match) => {
80
104
  if (match.length > 2) {
81
105
  return String.fromCharCode(Number.parseInt(match.slice(1).trim(), 16));
82
106
  }
@@ -108,7 +132,7 @@ const regexExcessiveSpaces =
108
132
  * @param {string} str string
109
133
  * @returns {string} escaped identifier
110
134
  */
111
- const escapeIdentifier = str => {
135
+ const escapeIdentifier = (str) => {
112
136
  let output = "";
113
137
  let counter = 0;
114
138
 
@@ -117,6 +141,7 @@ const escapeIdentifier = str => {
117
141
 
118
142
  let value;
119
143
 
144
+ // eslint-disable-next-line no-control-regex
120
145
  if (/[\t\n\f\r\u000B]/.test(character)) {
121
146
  const codePoint = character.charCodeAt(0);
122
147
 
@@ -160,7 +185,7 @@ const CONTAINS_ESCAPE = /\\/;
160
185
  * @param {string} str string
161
186
  * @returns {[string, number] | undefined} hex
162
187
  */
163
- const gobbleHex = str => {
188
+ const gobbleHex = (str) => {
164
189
  const lower = str.toLowerCase();
165
190
  let hex = "";
166
191
  let spaceTerminated = false;
@@ -197,7 +222,7 @@ const gobbleHex = str => {
197
222
  * @param {string} str string
198
223
  * @returns {string} unescaped string
199
224
  */
200
- const unescapeIdentifier = str => {
225
+ const unescapeIdentifier = (str) => {
201
226
  const needToProcess = CONTAINS_ESCAPE.test(str);
202
227
  if (!needToProcess) return str;
203
228
  let ret = "";
@@ -229,6 +254,276 @@ const unescapeIdentifier = str => {
229
254
  return ret;
230
255
  };
231
256
 
257
+ /**
258
+ * A custom property is any property whose name starts with two dashes (U+002D HYPHEN-MINUS), like --foo.
259
+ * The <custom-property-name> production corresponds to this:
260
+ * it’s defined as any <dashed-ident> (a valid identifier that starts with two dashes),
261
+ * except -- itself, which is reserved for future use by CSS.
262
+ * @param {string} identifier identifier
263
+ * @returns {boolean} true when identifier is dashed, otherwise false
264
+ */
265
+ const isDashedIdentifier = (identifier) =>
266
+ identifier.startsWith("--") && identifier.length >= 3;
267
+
268
+ /** @type {Record<string, number>} */
269
+ const PREDEFINED_COUNTER_STYLES = {
270
+ decimal: 1,
271
+ "decimal-leading-zero": 1,
272
+ "arabic-indic": 1,
273
+ armenian: 1,
274
+ "upper-armenian": 1,
275
+ "lower-armenian": 1,
276
+ bengali: 1,
277
+ cambodian: 1,
278
+ khmer: 1,
279
+ "cjk-decimal": 1,
280
+ devanagari: 1,
281
+ georgian: 1,
282
+ gujarati: 1,
283
+ /* cspell:disable-next-line */
284
+ gurmukhi: 1,
285
+ hebrew: 1,
286
+ kannada: 1,
287
+ lao: 1,
288
+ malayalam: 1,
289
+ mongolian: 1,
290
+ myanmar: 1,
291
+ oriya: 1,
292
+ persian: 1,
293
+ "lower-roman": 1,
294
+ "upper-roman": 1,
295
+ tamil: 1,
296
+ telugu: 1,
297
+ thai: 1,
298
+ tibetan: 1,
299
+
300
+ "lower-alpha": 1,
301
+ "lower-latin": 1,
302
+ "upper-alpha": 1,
303
+ "upper-latin": 1,
304
+ "lower-greek": 1,
305
+ hiragana: 1,
306
+ /* cspell:disable-next-line */
307
+ "hiragana-iroha": 1,
308
+ katakana: 1,
309
+ /* cspell:disable-next-line */
310
+ "katakana-iroha": 1,
311
+
312
+ disc: 1,
313
+ circle: 1,
314
+ square: 1,
315
+ "disclosure-open": 1,
316
+ "disclosure-closed": 1,
317
+
318
+ "cjk-earthly-branch": 1,
319
+ "cjk-heavenly-stem": 1,
320
+
321
+ "japanese-informal": 1,
322
+ "japanese-formal": 1,
323
+
324
+ "korean-hangul-formal": 1,
325
+ /* cspell:disable-next-line */
326
+ "korean-hanja-informal": 1,
327
+ /* cspell:disable-next-line */
328
+ "korean-hanja-formal": 1,
329
+
330
+ "simp-chinese-informal": 1,
331
+ "simp-chinese-formal": 1,
332
+ "trad-chinese-informal": 1,
333
+ "trad-chinese-formal": 1,
334
+ "cjk-ideographic": 1,
335
+
336
+ "ethiopic-numeric": 1
337
+ };
338
+
339
+ /** @type {Record<string, number>} */
340
+ const GLOBAL_VALUES = {
341
+ // Global values
342
+ initial: Infinity,
343
+ inherit: Infinity,
344
+ unset: Infinity,
345
+ revert: Infinity,
346
+ "revert-layer": Infinity
347
+ };
348
+
349
+ /** @type {Record<string, number>} */
350
+ const GRID_AREA_OR_COLUMN_OR_ROW = {
351
+ auto: Infinity,
352
+ span: Infinity,
353
+ ...GLOBAL_VALUES
354
+ };
355
+
356
+ /** @type {Record<string, number>} */
357
+ const GRID_AUTO_COLUMNS_OR_ROW = {
358
+ "min-content": Infinity,
359
+ "max-content": Infinity,
360
+ auto: Infinity,
361
+ ...GLOBAL_VALUES
362
+ };
363
+
364
+ /** @type {Record<string, number>} */
365
+ const GRID_AUTO_FLOW = {
366
+ row: 1,
367
+ column: 1,
368
+ dense: 1,
369
+ ...GLOBAL_VALUES
370
+ };
371
+
372
+ /** @type {Record<string, number>} */
373
+ const GRID_TEMPLATE_ARES = {
374
+ // Special
375
+ none: 1,
376
+ ...GLOBAL_VALUES
377
+ };
378
+
379
+ /** @type {Record<string, number>} */
380
+ const GRID_TEMPLATE_COLUMNS_OR_ROWS = {
381
+ none: 1,
382
+ subgrid: 1,
383
+ masonry: 1,
384
+ "max-content": Infinity,
385
+ "min-content": Infinity,
386
+ auto: Infinity,
387
+ ...GLOBAL_VALUES
388
+ };
389
+
390
+ /** @type {Record<string, number>} */
391
+ const GRID_TEMPLATE = {
392
+ ...GRID_TEMPLATE_ARES,
393
+ ...GRID_TEMPLATE_COLUMNS_OR_ROWS
394
+ };
395
+
396
+ /** @type {Record<string, number>} */
397
+ const GRID = {
398
+ "auto-flow": 1,
399
+ dense: 1,
400
+ ...GRID_AUTO_COLUMNS_OR_ROW,
401
+ ...GRID_AUTO_FLOW,
402
+ ...GRID_TEMPLATE_ARES,
403
+ ...GRID_TEMPLATE_COLUMNS_OR_ROWS
404
+ };
405
+
406
+ /**
407
+ * @param {{ animation?: boolean, container?: boolean, customIdents?: boolean, grid?: boolean }=} options options
408
+ * @returns {Map<string, Record<string, number>>} list of known properties
409
+ */
410
+ const getKnownProperties = (options = {}) => {
411
+ /** @type {Map<string, Record<string, number>>} */
412
+ const knownProperties = new Map();
413
+
414
+ if (options.animation) {
415
+ knownProperties.set("animation", {
416
+ // animation-direction
417
+ normal: 1,
418
+ reverse: 1,
419
+ alternate: 1,
420
+ "alternate-reverse": 1,
421
+ // animation-fill-mode
422
+ forwards: 1,
423
+ backwards: 1,
424
+ both: 1,
425
+ // animation-iteration-count
426
+ infinite: 1,
427
+ // animation-play-state
428
+ paused: 1,
429
+ running: 1,
430
+ // animation-timing-function
431
+ ease: 1,
432
+ "ease-in": 1,
433
+ "ease-out": 1,
434
+ "ease-in-out": 1,
435
+ linear: 1,
436
+ "step-end": 1,
437
+ "step-start": 1,
438
+ // Special
439
+ none: Infinity, // No matter how many times you write none, it will never be an animation name
440
+ ...GLOBAL_VALUES
441
+ });
442
+ knownProperties.set("animation-name", {
443
+ // Special
444
+ none: Infinity, // No matter how many times you write none, it will never be an animation name
445
+ ...GLOBAL_VALUES
446
+ });
447
+ }
448
+
449
+ if (options.container) {
450
+ knownProperties.set("container", {
451
+ // container-type
452
+ normal: 1,
453
+ size: 1,
454
+ "inline-size": 1,
455
+ "scroll-state": 1,
456
+ // Special
457
+ none: Infinity,
458
+ ...GLOBAL_VALUES
459
+ });
460
+ knownProperties.set("container-name", {
461
+ // Special
462
+ none: Infinity,
463
+ ...GLOBAL_VALUES
464
+ });
465
+ }
466
+
467
+ if (options.customIdents) {
468
+ knownProperties.set("list-style", {
469
+ // list-style-position
470
+ inside: 1,
471
+ outside: 1,
472
+ // list-style-type
473
+ ...PREDEFINED_COUNTER_STYLES,
474
+ // Special
475
+ none: Infinity,
476
+ ...GLOBAL_VALUES
477
+ });
478
+ knownProperties.set("list-style-type", {
479
+ // list-style-type
480
+ ...PREDEFINED_COUNTER_STYLES,
481
+ // Special
482
+ none: Infinity,
483
+ ...GLOBAL_VALUES
484
+ });
485
+ knownProperties.set("system", {
486
+ cyclic: 1,
487
+ numeric: 1,
488
+ alphabetic: 1,
489
+ symbolic: 1,
490
+ additive: 1,
491
+ fixed: 1,
492
+ extends: 1,
493
+ ...PREDEFINED_COUNTER_STYLES
494
+ });
495
+ knownProperties.set("fallback", {
496
+ ...PREDEFINED_COUNTER_STYLES
497
+ });
498
+ knownProperties.set("speak-as", {
499
+ auto: 1,
500
+ bullets: 1,
501
+ numbers: 1,
502
+ words: 1,
503
+ "spell-out": 1,
504
+ ...PREDEFINED_COUNTER_STYLES
505
+ });
506
+ }
507
+
508
+ if (options.grid) {
509
+ knownProperties.set("grid", GRID);
510
+ knownProperties.set("grid-area", GRID_AREA_OR_COLUMN_OR_ROW);
511
+ knownProperties.set("grid-column", GRID_AREA_OR_COLUMN_OR_ROW);
512
+ knownProperties.set("grid-column-end", GRID_AREA_OR_COLUMN_OR_ROW);
513
+ knownProperties.set("grid-column-start", GRID_AREA_OR_COLUMN_OR_ROW);
514
+ knownProperties.set("grid-column-start", GRID_AREA_OR_COLUMN_OR_ROW);
515
+ knownProperties.set("grid-row", GRID_AREA_OR_COLUMN_OR_ROW);
516
+ knownProperties.set("grid-row-end", GRID_AREA_OR_COLUMN_OR_ROW);
517
+ knownProperties.set("grid-row-start", GRID_AREA_OR_COLUMN_OR_ROW);
518
+ knownProperties.set("grid-template", GRID_TEMPLATE);
519
+ knownProperties.set("grid-template-areas", GRID_TEMPLATE_ARES);
520
+ knownProperties.set("grid-template-columns", GRID_TEMPLATE_COLUMNS_OR_ROWS);
521
+ knownProperties.set("grid-template-rows", GRID_TEMPLATE_COLUMNS_OR_ROWS);
522
+ }
523
+
524
+ return knownProperties;
525
+ };
526
+
232
527
  class LocConverter {
233
528
  /**
234
529
  * @param {string} input input
@@ -254,8 +549,9 @@ class LocConverter {
254
549
  } else {
255
550
  this.column = str.length - i - 1;
256
551
  this.line++;
257
- while (i > 0 && (i = str.lastIndexOf("\n", i - 1)) !== -1)
552
+ while (i > 0 && (i = str.lastIndexOf("\n", i - 1)) !== -1) {
258
553
  this.line++;
554
+ }
259
555
  }
260
556
  } else {
261
557
  let i = this._input.lastIndexOf("\n", this.pos);
@@ -279,29 +575,39 @@ const EMPTY_COMMENT_OPTIONS = {
279
575
  const CSS_MODE_TOP_LEVEL = 0;
280
576
  const CSS_MODE_IN_BLOCK = 1;
281
577
 
578
+ const LOCAL_MODE = 0;
579
+ const GLOBAL_MODE = 1;
580
+
282
581
  const eatUntilSemi = walkCssTokens.eatUntil(";");
283
582
  const eatUntilLeftCurly = walkCssTokens.eatUntil("{");
284
- const eatSemi = walkCssTokens.eatUntil(";");
583
+
584
+ /**
585
+ * @typedef {object} CssParserOwnOptions
586
+ * @property {("pure" | "global" | "local" | "auto")=} defaultMode default mode
587
+ */
588
+
589
+ /** @typedef {CssModuleParserOptions & CssParserOwnOptions} CssParserOptions */
285
590
 
286
591
  class CssParser extends Parser {
287
592
  /**
288
- * @param {object} options options
289
- * @param {boolean=} options.importOption need handle `@import`
290
- * @param {boolean=} options.url need handle URLs
291
- * @param {("pure" | "global" | "local" | "auto")=} options.defaultMode default mode
292
- * @param {boolean=} options.namedExports is named exports
593
+ * @param {CssParserOptions=} options options
293
594
  */
294
- constructor({
295
- defaultMode = "pure",
296
- importOption = true,
297
- url = true,
298
- namedExports = true
299
- } = {}) {
595
+ constructor(options = {}) {
300
596
  super();
301
- this.defaultMode = defaultMode;
302
- this.import = importOption;
303
- this.url = url;
304
- this.namedExports = namedExports;
597
+ this.defaultMode =
598
+ typeof options.defaultMode !== "undefined" ? options.defaultMode : "pure";
599
+ this.options = {
600
+ url: true,
601
+ import: true,
602
+ namedExports: true,
603
+ animation: true,
604
+ container: true,
605
+ customIdents: true,
606
+ dashedIdents: true,
607
+ function: true,
608
+ grid: true,
609
+ ...options
610
+ };
305
611
  /** @type {Comment[] | undefined} */
306
612
  this.comments = undefined;
307
613
  this.magicCommentContext = createMagicCommentContext();
@@ -333,7 +639,7 @@ class CssParser extends Parser {
333
639
  */
334
640
  parse(source, state) {
335
641
  if (Buffer.isBuffer(source)) {
336
- source = source.toString("utf-8");
642
+ source = source.toString("utf8");
337
643
  } else if (typeof source === "object") {
338
644
  throw new Error("webpackAst is unexpected for the CssParser");
339
645
  }
@@ -349,13 +655,23 @@ class CssParser extends Parser {
349
655
  mode === "auto" &&
350
656
  module.type === CSS_MODULE_TYPE_AUTO &&
351
657
  IS_MODULES.test(
352
- parseResource(module.matchResource || module.resource).path
658
+ // TODO matchResource
659
+ parseResource(/** @type {string} */ (module.getResource())).path
353
660
  )
354
661
  ) {
355
662
  mode = "local";
356
663
  }
357
664
 
358
665
  const isModules = mode === "global" || mode === "local";
666
+ const knownProperties = getKnownProperties({
667
+ animation: this.options.animation,
668
+ container: this.options.container,
669
+ customIdents: this.options.customIdents,
670
+ grid: this.options.grid
671
+ });
672
+
673
+ /** @type {BuildMeta} */
674
+ (module.buildMeta).isCSSModule = isModules;
359
675
 
360
676
  const locConverter = new LocConverter(source);
361
677
 
@@ -363,7 +679,7 @@ class CssParser extends Parser {
363
679
  let scope = CSS_MODE_TOP_LEVEL;
364
680
  /** @type {boolean} */
365
681
  let allowImportAtRule = true;
366
- /** @type [string, number, number][] */
682
+ /** @type {[string, number, number, boolean?][]} */
367
683
  const balanced = [];
368
684
  let lastTokenEndForComments = 0;
369
685
 
@@ -371,15 +687,14 @@ class CssParser extends Parser {
371
687
  let isNextRulePrelude = isModules;
372
688
  /** @type {number} */
373
689
  let blockNestingLevel = 0;
374
- /** @type {"local" | "global" | undefined} */
690
+ /** @type {0 | 1 | undefined} */
375
691
  let modeData;
376
- /** @type {boolean} */
377
- let inAnimationProperty = false;
378
- /** @type {[number, number, boolean] | undefined} */
379
- let lastIdentifier;
380
- /** @type {Set<string>} */
381
- const declaredCssVariables = new Set();
382
- /** @type {Map<string, { path?: string, value: string }>} */
692
+
693
+ /** @type {string[]} */
694
+ let lastLocalIdentifiers = [];
695
+
696
+ /** @typedef {{ value: string, isReference?: boolean }} IcssDefinition */
697
+ /** @type {Map<string, IcssDefinition>} */
383
698
  const icssDefinitions = new Map();
384
699
 
385
700
  /**
@@ -388,55 +703,375 @@ class CssParser extends Parser {
388
703
  * @returns {boolean} true, when next is nested syntax
389
704
  */
390
705
  const isNextNestedSyntax = (input, pos) => {
391
- pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
706
+ pos = walkCssTokens.eatWhitespaceAndComments(input, pos)[0];
392
707
 
393
- if (input[pos] === "}") {
708
+ if (
709
+ input.charCodeAt(pos) === CC_RIGHT_CURLY ||
710
+ (input.charCodeAt(pos) === CC_HYPHEN_MINUS &&
711
+ input.charCodeAt(pos + 1) === CC_HYPHEN_MINUS)
712
+ ) {
394
713
  return false;
395
714
  }
396
715
 
397
- // According spec only identifier can be used as a property name
398
- const isIdentifier = walkCssTokens.isIdentStartCodePoint(
399
- input.charCodeAt(pos)
400
- );
716
+ const identifier = walkCssTokens.eatIdentSequence(input, pos);
717
+
718
+ if (!identifier) {
719
+ return true;
720
+ }
721
+
722
+ const leftCurly = eatUntilLeftCurly(input, pos);
723
+ const content = input.slice(identifier[0], leftCurly);
724
+
725
+ if (content.includes(";") || content.includes("}")) {
726
+ return false;
727
+ }
401
728
 
402
- return !isIdentifier;
729
+ return true;
403
730
  };
404
731
  /**
405
732
  * @returns {boolean} true, when in local scope
406
733
  */
407
734
  const isLocalMode = () =>
408
- modeData === "local" || (mode === "local" && modeData === undefined);
735
+ modeData === LOCAL_MODE || (mode === "local" && modeData === undefined);
409
736
 
410
737
  /**
411
738
  * @param {string} input input
412
- * @param {number} pos start position
413
- * @param {(input: string, pos: number) => number} eater eater
414
- * @returns {[number,string]} new position and text
739
+ * @param {number} start start
740
+ * @param {number} end end
741
+ * @returns {number} end
415
742
  */
416
- const eatText = (input, pos, eater) => {
417
- let text = "";
418
- for (;;) {
419
- if (input.charCodeAt(pos) === CC_SLASH) {
420
- const newPos = walkCssTokens.eatComments(input, pos);
421
- if (pos !== newPos) {
422
- pos = newPos;
423
- if (pos === input.length) break;
424
- } else {
425
- text += "/";
426
- pos++;
427
- if (pos === input.length) break;
743
+ const comment = (input, start, end) => {
744
+ if (!this.comments) this.comments = [];
745
+ const { line: sl, column: sc } = locConverter.get(start);
746
+ const { line: el, column: ec } = locConverter.get(end);
747
+
748
+ /** @type {Comment} */
749
+ const comment = {
750
+ value: input.slice(start + 2, end - 2),
751
+ range: [start, end],
752
+ loc: {
753
+ start: { line: sl, column: sc },
754
+ end: { line: el, column: ec }
755
+ }
756
+ };
757
+ this.comments.push(comment);
758
+ return end;
759
+ };
760
+
761
+ // Vanilla CSS stuff
762
+
763
+ /**
764
+ * @param {string} input input
765
+ * @param {number} start name start position
766
+ * @param {number} end name end position
767
+ * @returns {number} position after handling
768
+ */
769
+ const processAtImport = (input, start, end) => {
770
+ const tokens = walkCssTokens.eatImportTokens(input, end, {
771
+ comment
772
+ });
773
+ if (!tokens[3]) return end;
774
+ const semi = tokens[3][1];
775
+ if (!tokens[0]) {
776
+ this._emitWarning(
777
+ state,
778
+ `Expected URL in '${input.slice(start, semi)}'`,
779
+ locConverter,
780
+ start,
781
+ semi
782
+ );
783
+ return end;
784
+ }
785
+
786
+ const urlToken = tokens[0];
787
+ const url = normalizeUrl(input.slice(urlToken[2], urlToken[3]), true);
788
+ const newline = walkCssTokens.eatWhiteLine(input, semi);
789
+ const { options, errors: commentErrors } = this.parseCommentOptions([
790
+ end,
791
+ urlToken[1]
792
+ ]);
793
+ if (commentErrors) {
794
+ for (const e of commentErrors) {
795
+ const { comment } = e;
796
+ state.module.addWarning(
797
+ new CommentCompilationWarning(
798
+ `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
799
+ comment.loc
800
+ )
801
+ );
802
+ }
803
+ }
804
+ if (options && options.webpackIgnore !== undefined) {
805
+ if (typeof options.webpackIgnore !== "boolean") {
806
+ const { line: sl, column: sc } = locConverter.get(start);
807
+ const { line: el, column: ec } = locConverter.get(newline);
808
+
809
+ state.module.addWarning(
810
+ new UnsupportedFeatureWarning(
811
+ `\`webpackIgnore\` expected a boolean, but received: ${options.webpackIgnore}.`,
812
+ {
813
+ start: { line: sl, column: sc },
814
+ end: { line: el, column: ec }
815
+ }
816
+ )
817
+ );
818
+ } else if (options.webpackIgnore) {
819
+ return newline;
820
+ }
821
+ }
822
+ if (url.length === 0) {
823
+ const { line: sl, column: sc } = locConverter.get(start);
824
+ const { line: el, column: ec } = locConverter.get(newline);
825
+ const dep = new ConstDependency("", [start, newline]);
826
+ module.addPresentationalDependency(dep);
827
+ dep.setLoc(sl, sc, el, ec);
828
+
829
+ return newline;
830
+ }
831
+
832
+ let layer;
833
+
834
+ if (tokens[1]) {
835
+ layer = input.slice(tokens[1][0] + 6, tokens[1][1] - 1).trim();
836
+ }
837
+
838
+ let supports;
839
+
840
+ if (tokens[2]) {
841
+ supports = input.slice(tokens[2][0] + 9, tokens[2][1] - 1).trim();
842
+ }
843
+
844
+ const last = tokens[2] || tokens[1] || tokens[0];
845
+ const mediaStart = walkCssTokens.eatWhitespaceAndComments(
846
+ input,
847
+ last[1]
848
+ )[0];
849
+
850
+ let media;
851
+
852
+ if (mediaStart !== semi - 1) {
853
+ media = input.slice(mediaStart, semi - 1).trim();
854
+ }
855
+
856
+ const { line: sl, column: sc } = locConverter.get(start);
857
+ const { line: el, column: ec } = locConverter.get(newline);
858
+ const dep = new CssImportDependency(
859
+ url,
860
+ [start, newline],
861
+ mode === "local" || mode === "global" ? mode : undefined,
862
+ layer,
863
+ supports && supports.length > 0 ? supports : undefined,
864
+ media && media.length > 0 ? media : undefined
865
+ );
866
+ dep.setLoc(sl, sc, el, ec);
867
+ module.addDependency(dep);
868
+
869
+ return newline;
870
+ };
871
+
872
+ /**
873
+ * @param {string} input input
874
+ * @param {number} end end position
875
+ * @param {string} name the name of function
876
+ * @returns {number} position after handling
877
+ */
878
+ const processURLFunction = (input, end, name) => {
879
+ const string = walkCssTokens.eatString(input, end);
880
+ if (!string) return end;
881
+ const { options, errors: commentErrors } = this.parseCommentOptions([
882
+ lastTokenEndForComments,
883
+ end
884
+ ]);
885
+ if (commentErrors) {
886
+ for (const e of commentErrors) {
887
+ const { comment } = e;
888
+ state.module.addWarning(
889
+ new CommentCompilationWarning(
890
+ `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
891
+ comment.loc
892
+ )
893
+ );
894
+ }
895
+ }
896
+ if (options && options.webpackIgnore !== undefined) {
897
+ if (typeof options.webpackIgnore !== "boolean") {
898
+ const { line: sl, column: sc } = locConverter.get(string[0]);
899
+ const { line: el, column: ec } = locConverter.get(string[1]);
900
+
901
+ state.module.addWarning(
902
+ new UnsupportedFeatureWarning(
903
+ `\`webpackIgnore\` expected a boolean, but received: ${options.webpackIgnore}.`,
904
+ {
905
+ start: { line: sl, column: sc },
906
+ end: { line: el, column: ec }
907
+ }
908
+ )
909
+ );
910
+ } else if (options.webpackIgnore) {
911
+ return end;
912
+ }
913
+ }
914
+ const value = normalizeUrl(
915
+ input.slice(string[0] + 1, string[1] - 1),
916
+ true
917
+ );
918
+ // Ignore `url()`, `url('')` and `url("")`, they are valid by spec
919
+ if (value.length === 0) return end;
920
+ const isUrl = name === "url" || name === "src";
921
+ const dep = new CssUrlDependency(
922
+ value,
923
+ [string[0], string[1]],
924
+ isUrl ? "string" : "url"
925
+ );
926
+ const { line: sl, column: sc } = locConverter.get(string[0]);
927
+ const { line: el, column: ec } = locConverter.get(string[1]);
928
+ dep.setLoc(sl, sc, el, ec);
929
+ module.addDependency(dep);
930
+ module.addCodeGenerationDependency(dep);
931
+ return string[1];
932
+ };
933
+
934
+ /**
935
+ * @param {string} input input
936
+ * @param {number} start start position
937
+ * @param {number} end end position
938
+ * @param {number} contentStart start position
939
+ * @param {number} contentEnd end position
940
+ * @returns {number} position after handling
941
+ */
942
+ const processOldURLFunction = (
943
+ input,
944
+ start,
945
+ end,
946
+ contentStart,
947
+ contentEnd
948
+ ) => {
949
+ const { options, errors: commentErrors } = this.parseCommentOptions([
950
+ lastTokenEndForComments,
951
+ end
952
+ ]);
953
+ if (commentErrors) {
954
+ for (const e of commentErrors) {
955
+ const { comment } = e;
956
+ state.module.addWarning(
957
+ new CommentCompilationWarning(
958
+ `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
959
+ comment.loc
960
+ )
961
+ );
962
+ }
963
+ }
964
+ if (options && options.webpackIgnore !== undefined) {
965
+ if (typeof options.webpackIgnore !== "boolean") {
966
+ const { line: sl, column: sc } = locConverter.get(
967
+ lastTokenEndForComments
968
+ );
969
+ const { line: el, column: ec } = locConverter.get(end);
970
+
971
+ state.module.addWarning(
972
+ new UnsupportedFeatureWarning(
973
+ `\`webpackIgnore\` expected a boolean, but received: ${options.webpackIgnore}.`,
974
+ {
975
+ start: { line: sl, column: sc },
976
+ end: { line: el, column: ec }
977
+ }
978
+ )
979
+ );
980
+ } else if (options.webpackIgnore) {
981
+ return end;
982
+ }
983
+ }
984
+ const value = normalizeUrl(input.slice(contentStart, contentEnd), false);
985
+ // Ignore `url()`, `url('')` and `url("")`, they are valid by spec
986
+ if (value.length === 0) return end;
987
+ const dep = new CssUrlDependency(value, [start, end], "url");
988
+ const { line: sl, column: sc } = locConverter.get(start);
989
+ const { line: el, column: ec } = locConverter.get(end);
990
+ dep.setLoc(sl, sc, el, ec);
991
+ module.addDependency(dep);
992
+ module.addCodeGenerationDependency(dep);
993
+ return end;
994
+ };
995
+
996
+ /**
997
+ * @param {string} input input
998
+ * @param {number} start start position
999
+ * @param {number} end end position
1000
+ * @returns {number} position after handling
1001
+ */
1002
+ const processImageSetFunction = (input, start, end) => {
1003
+ lastTokenEndForComments = end;
1004
+ const values = walkCssTokens.eatImageSetStrings(input, end, {
1005
+ comment
1006
+ });
1007
+ if (values.length === 0) return end;
1008
+ for (const [index, string] of values.entries()) {
1009
+ const value = normalizeUrl(
1010
+ input.slice(string[0] + 1, string[1] - 1),
1011
+ true
1012
+ );
1013
+ if (value.length === 0) return end;
1014
+ const { options, errors: commentErrors } = this.parseCommentOptions([
1015
+ index === 0 ? start : values[index - 1][1],
1016
+ string[1]
1017
+ ]);
1018
+ if (commentErrors) {
1019
+ for (const e of commentErrors) {
1020
+ const { comment } = e;
1021
+ state.module.addWarning(
1022
+ new CommentCompilationWarning(
1023
+ `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
1024
+ comment.loc
1025
+ )
1026
+ );
428
1027
  }
429
1028
  }
430
- const newPos = eater(input, pos);
431
- if (pos !== newPos) {
432
- text += input.slice(pos, newPos);
433
- pos = newPos;
434
- } else {
435
- break;
1029
+ if (options && options.webpackIgnore !== undefined) {
1030
+ if (typeof options.webpackIgnore !== "boolean") {
1031
+ const { line: sl, column: sc } = locConverter.get(string[0]);
1032
+ const { line: el, column: ec } = locConverter.get(string[1]);
1033
+
1034
+ state.module.addWarning(
1035
+ new UnsupportedFeatureWarning(
1036
+ `\`webpackIgnore\` expected a boolean, but received: ${options.webpackIgnore}.`,
1037
+ {
1038
+ start: { line: sl, column: sc },
1039
+ end: { line: el, column: ec }
1040
+ }
1041
+ )
1042
+ );
1043
+ } else if (options.webpackIgnore) {
1044
+ continue;
1045
+ }
436
1046
  }
437
- if (pos === input.length) break;
1047
+ const dep = new CssUrlDependency(value, [string[0], string[1]], "url");
1048
+ const { line: sl, column: sc } = locConverter.get(string[0]);
1049
+ const { line: el, column: ec } = locConverter.get(string[1]);
1050
+ dep.setLoc(sl, sc, el, ec);
1051
+ module.addDependency(dep);
1052
+ module.addCodeGenerationDependency(dep);
1053
+ }
1054
+ // Can contain `url()` inside, so let's return end to allow parse them
1055
+ return end;
1056
+ };
1057
+
1058
+ // CSS modules stuff
1059
+
1060
+ /**
1061
+ * @param {string} value value to resolve
1062
+ * @returns {string | [string, string, boolean]} resolved reexport
1063
+ */
1064
+ const getReexport = (value) => {
1065
+ const reexport = icssDefinitions.get(value);
1066
+
1067
+ if (reexport) {
1068
+ if (reexport.isReference) {
1069
+ return [value, reexport.value, true];
1070
+ }
1071
+ return [value, reexport.value, false];
438
1072
  }
439
- return [pos, text.trimEnd()];
1073
+
1074
+ return value;
440
1075
  };
441
1076
 
442
1077
  /**
@@ -445,9 +1080,10 @@ class CssParser extends Parser {
445
1080
  * @param {number} pos start position
446
1081
  * @returns {number} position after parse
447
1082
  */
448
- const parseImportOrExport = (type, input, pos) => {
449
- pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
450
- let importPath;
1083
+ const processImportOrExport = (type, input, pos) => {
1084
+ pos = walkCssTokens.eatWhitespaceAndComments(input, pos)[0];
1085
+ /** @type {string | undefined} */
1086
+ let request;
451
1087
  if (type === 0) {
452
1088
  let cc = input.charCodeAt(pos);
453
1089
  if (cc !== CC_LEFT_PARENTHESIS) {
@@ -466,16 +1102,16 @@ class CssParser extends Parser {
466
1102
  if (!str) {
467
1103
  this._emitWarning(
468
1104
  state,
469
- `Unexpected '${input[pos]}' at ${pos} during parsing of ':import' (expected string)`,
1105
+ `Unexpected '${input[pos]}' at ${pos} during parsing of '${type ? ":import" : ":export"}' (expected string)`,
470
1106
  locConverter,
471
1107
  stringStart,
472
1108
  pos
473
1109
  );
474
1110
  return pos;
475
1111
  }
476
- importPath = input.slice(str[0] + 1, str[1] - 1);
1112
+ request = input.slice(str[0] + 1, str[1] - 1);
477
1113
  pos = str[1];
478
- pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
1114
+ pos = walkCssTokens.eatWhitespaceAndComments(input, pos)[0];
479
1115
  cc = input.charCodeAt(pos);
480
1116
  if (cc !== CC_RIGHT_PARENTHESIS) {
481
1117
  this._emitWarning(
@@ -488,7 +1124,7 @@ class CssParser extends Parser {
488
1124
  return pos;
489
1125
  }
490
1126
  pos++;
491
- pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
1127
+ pos = walkCssTokens.eatWhitespaceAndComments(input, pos)[0];
492
1128
  }
493
1129
 
494
1130
  /**
@@ -499,12 +1135,22 @@ class CssParser extends Parser {
499
1135
  */
500
1136
  const createDep = (name, value, start, end) => {
501
1137
  if (type === 0) {
502
- icssDefinitions.set(name, {
503
- path: /** @type {string} */ (importPath),
1138
+ const dep = new CssIcssImportDependency(
1139
+ /** @type {string} */
1140
+ (request),
1141
+ [0, 0],
1142
+ /** @type {"local" | "global"} */
1143
+ (mode),
504
1144
  value
505
- });
1145
+ );
1146
+ const { line: sl, column: sc } = locConverter.get(start);
1147
+ const { line: el, column: ec } = locConverter.get(end);
1148
+ dep.setLoc(sl, sc, el, ec);
1149
+ module.addDependency(dep);
1150
+
1151
+ icssDefinitions.set(name, { value, isReference: true });
506
1152
  } else if (type === 1) {
507
- const dep = new CssIcssExportDependency(name, value);
1153
+ const dep = new CssIcssExportDependency(name, getReexport(value));
508
1154
  const { line: sl, column: sc } = locConverter.get(start);
509
1155
  const { line: el, column: ec } = locConverter.get(end);
510
1156
  dep.setLoc(sl, sc, el, ec);
@@ -517,7 +1163,9 @@ class CssParser extends Parser {
517
1163
  /** @type {undefined | 0 | 1 | 2} */
518
1164
  let scope;
519
1165
 
520
- /** @type {[number, number] | undefined} */
1166
+ /** @typedef {[number, number]} Name */
1167
+
1168
+ /** @type {Name | undefined} */
521
1169
  let name;
522
1170
  /** @type {number | undefined} */
523
1171
  let value;
@@ -537,10 +1185,11 @@ class CssParser extends Parser {
537
1185
  balanced--;
538
1186
 
539
1187
  if (scope === 2) {
1188
+ const [nameStart, nameEnd] = /** @type {Name} */ (name);
540
1189
  createDep(
541
- input.slice(name[0], name[1]),
1190
+ input.slice(nameStart, nameEnd),
542
1191
  input.slice(value, end - 1).trim(),
543
- name[1],
1192
+ nameEnd,
544
1193
  end - 1
545
1194
  );
546
1195
  scope = 0;
@@ -571,10 +1220,11 @@ class CssParser extends Parser {
571
1220
  },
572
1221
  semicolon: (input, _start, end) => {
573
1222
  if (scope === 2) {
1223
+ const [nameStart, nameEnd] = /** @type {Name} */ (name);
574
1224
  createDep(
575
- input.slice(name[0], name[1]),
1225
+ input.slice(nameStart, nameEnd),
576
1226
  input.slice(value, end - 1),
577
- name[1],
1227
+ nameEnd,
578
1228
  end - 1
579
1229
  );
580
1230
  scope = 0;
@@ -590,90 +1240,877 @@ class CssParser extends Parser {
590
1240
 
591
1241
  return pos;
592
1242
  };
593
- const eatPropertyName = walkCssTokens.eatUntil(":{};");
1243
+
594
1244
  /**
595
1245
  * @param {string} input input
596
- * @param {number} pos name start position
1246
+ * @param {number} start name start position
597
1247
  * @param {number} end name end position
598
1248
  * @returns {number} position after handling
599
1249
  */
600
- const processLocalDeclaration = (input, pos, end) => {
601
- modeData = undefined;
602
- pos = walkCssTokens.eatWhitespaceAndComments(input, pos);
603
- const propertyNameStart = pos;
604
- const [propertyNameEnd, propertyName] = eatText(
605
- input,
606
- pos,
607
- eatPropertyName
608
- );
609
- if (input.charCodeAt(propertyNameEnd) !== CC_COLON) return end;
610
- pos = propertyNameEnd + 1;
611
- if (propertyName.startsWith("--") && propertyName.length >= 3) {
612
- // CSS Variable
613
- const { line: sl, column: sc } = locConverter.get(propertyNameStart);
614
- const { line: el, column: ec } = locConverter.get(propertyNameEnd);
615
- const name = unescapeIdentifier(propertyName.slice(2));
616
- const dep = new CssLocalIdentifierDependency(
617
- name,
618
- [propertyNameStart, propertyNameEnd],
619
- "--"
620
- );
621
- dep.setLoc(sl, sc, el, ec);
622
- module.addDependency(dep);
623
- declaredCssVariables.add(name);
624
- } else if (
625
- OPTIONALLY_VENDOR_PREFIXED_ANIMATION_PROPERTY.test(propertyName)
626
- ) {
627
- inAnimationProperty = true;
628
- }
629
- return pos;
630
- };
631
- /**
632
- * @param {string} input input
633
- */
634
- const processDeclarationValueDone = input => {
635
- if (inAnimationProperty && lastIdentifier) {
636
- const { line: sl, column: sc } = locConverter.get(lastIdentifier[0]);
637
- const { line: el, column: ec } = locConverter.get(lastIdentifier[1]);
638
- const name = unescapeIdentifier(
639
- lastIdentifier[2]
640
- ? input.slice(lastIdentifier[0], lastIdentifier[1])
641
- : input.slice(lastIdentifier[0] + 1, lastIdentifier[1] - 1)
642
- );
643
- const dep = new CssSelfLocalIdentifierDependency(name, [
644
- lastIdentifier[0],
645
- lastIdentifier[1]
646
- ]);
647
- dep.setLoc(sl, sc, el, ec);
648
- module.addDependency(dep);
649
- lastIdentifier = undefined;
650
- }
651
- };
1250
+ const processAtValue = (input, start, end) => {
1251
+ const semi = eatUntilSemi(input, end);
1252
+ const atRuleEnd = semi + 1;
1253
+ const params = input.slice(end, semi);
1254
+ let [alias, request] = params.split(/\s*from\s*/);
652
1255
 
653
- /**
654
- * @param {string} input input
655
- * @param {number} start start
656
- * @param {number} end end
657
- * @returns {number} end
658
- */
659
- const comment = (input, start, end) => {
660
- if (!this.comments) this.comments = [];
1256
+ if (request) {
1257
+ const aliases = alias
1258
+ .replace(CSS_COMMENT, " ")
1259
+ .trim()
1260
+ .replace(/^\(\s*|\s*\)$/g, "")
1261
+ .split(/\s*,\s*/);
1262
+
1263
+ request = request.replace(CSS_COMMENT, "").trim();
1264
+
1265
+ const isExplicitImport = request[0] === "'" || request[0] === '"';
1266
+
1267
+ if (isExplicitImport) {
1268
+ request = request.slice(1, -1);
1269
+ }
1270
+
1271
+ for (const alias of aliases) {
1272
+ const [name, aliasName] = alias.split(/\s+as\s+/);
1273
+
1274
+ {
1275
+ const reexport = icssDefinitions.get(request);
1276
+
1277
+ if (reexport) {
1278
+ request = reexport.value.slice(1, -1);
1279
+ }
1280
+
1281
+ const dep = new CssIcssImportDependency(
1282
+ request,
1283
+ [0, 0],
1284
+ /** @type {"local" | "global"} */
1285
+ (mode),
1286
+ name
1287
+ );
1288
+ const { line: sl, column: sc } = locConverter.get(start);
1289
+ const { line: el, column: ec } = locConverter.get(end);
1290
+ dep.setLoc(sl, sc, el, ec);
1291
+ module.addDependency(dep);
1292
+
1293
+ icssDefinitions.set(aliasName || name, {
1294
+ value: name,
1295
+ isReference: true
1296
+ });
1297
+ }
1298
+
1299
+ {
1300
+ const dep = new CssIcssExportDependency(
1301
+ aliasName || name,
1302
+ getReexport(aliasName || name),
1303
+ undefined,
1304
+ false,
1305
+ CssIcssExportDependency.EXPORT_MODE.REPLACE
1306
+ );
1307
+ const { line: sl, column: sc } = locConverter.get(start);
1308
+ const { line: el, column: ec } = locConverter.get(end);
1309
+ dep.setLoc(sl, sc, el, ec);
1310
+ module.addDependency(dep);
1311
+ }
1312
+ }
1313
+ } else {
1314
+ const ident = walkCssTokens.eatIdentSequence(alias, 0);
1315
+
1316
+ if (!ident) {
1317
+ this._emitWarning(
1318
+ state,
1319
+ `Broken '@value' at-rule: ${input.slice(start, atRuleEnd)}'`,
1320
+ locConverter,
1321
+ start,
1322
+ atRuleEnd
1323
+ );
1324
+
1325
+ const dep = new ConstDependency("", [start, atRuleEnd]);
1326
+ module.addPresentationalDependency(dep);
1327
+ return atRuleEnd;
1328
+ }
1329
+
1330
+ const pos = walkCssTokens.eatWhitespaceAndComments(alias, ident[1])[0];
1331
+
1332
+ const name = alias.slice(ident[0], ident[1]);
1333
+ let value =
1334
+ alias.charCodeAt(pos) === CC_COLON
1335
+ ? alias.slice(pos + 1)
1336
+ : alias.slice(ident[1]);
1337
+
1338
+ if (value && !/^\s+$/.test(value.replace(CSS_COMMENT, ""))) {
1339
+ value = value.trim();
1340
+ }
1341
+
1342
+ if (icssDefinitions.has(value)) {
1343
+ const def =
1344
+ /** @type {IcssDefinition} */
1345
+ (icssDefinitions.get(value));
1346
+
1347
+ value = def.value;
1348
+ }
1349
+
1350
+ icssDefinitions.set(name, { value });
1351
+
1352
+ const dep = new CssIcssExportDependency(name, value);
1353
+ const { line: sl, column: sc } = locConverter.get(start);
1354
+ const { line: el, column: ec } = locConverter.get(end);
1355
+ dep.setLoc(sl, sc, el, ec);
1356
+ module.addDependency(dep);
1357
+ }
1358
+
1359
+ const dep = new ConstDependency("", [start, atRuleEnd]);
1360
+ module.addPresentationalDependency(dep);
1361
+ return atRuleEnd;
1362
+ };
1363
+
1364
+ /**
1365
+ * @param {string} name ICSS symbol name
1366
+ * @param {number} start start position
1367
+ * @param {number} end end position
1368
+ * @returns {number} position after handling
1369
+ */
1370
+ const processICSSSymbol = (name, start, end) => {
1371
+ const { value, isReference } =
1372
+ /** @type {IcssDefinition} */
1373
+ (icssDefinitions.get(name));
661
1374
  const { line: sl, column: sc } = locConverter.get(start);
662
1375
  const { line: el, column: ec } = locConverter.get(end);
1376
+ const dep = new CssIcssSymbolDependency(
1377
+ name,
1378
+ value,
1379
+ [start, end],
1380
+ isReference
1381
+ );
1382
+ dep.setLoc(sl, sc, el, ec);
1383
+ module.addDependency(dep);
1384
+ return end;
1385
+ };
663
1386
 
664
- /** @type {Comment} */
665
- const comment = {
666
- value: input.slice(start + 2, end - 2),
667
- range: [start, end],
668
- loc: {
669
- start: { line: sl, column: sc },
670
- end: { line: el, column: ec }
1387
+ /**
1388
+ * @param {string} input input
1389
+ * @param {1 | 2} type type of function
1390
+ * @param {number} start start position
1391
+ * @param {number} end end position
1392
+ * @returns {number} position after handling
1393
+ */
1394
+ const processLocalOrGlobalFunction = (input, type, start, end) => {
1395
+ // Replace `local(`/` or `global(` (handle legacy `:local(` or `:global(` too)
1396
+ {
1397
+ const isColon = input.charCodeAt(start - 1) === CC_COLON;
1398
+ const dep = new ConstDependency("", [isColon ? start - 1 : start, end]);
1399
+ module.addPresentationalDependency(dep);
1400
+ }
1401
+
1402
+ end = walkCssTokens.consumeUntil(
1403
+ input,
1404
+ start,
1405
+ {
1406
+ identifier(input, start, end) {
1407
+ if (type === 1) {
1408
+ let identifier = unescapeIdentifier(input.slice(start, end));
1409
+ const { line: sl, column: sc } = locConverter.get(start);
1410
+ const { line: el, column: ec } = locConverter.get(end);
1411
+ const isDashedIdent = isDashedIdentifier(identifier);
1412
+
1413
+ if (isDashedIdent) {
1414
+ identifier = identifier.slice(2);
1415
+ }
1416
+
1417
+ const dep = new CssIcssExportDependency(
1418
+ identifier,
1419
+ getReexport(identifier),
1420
+ [start, end],
1421
+ true,
1422
+ CssIcssExportDependency.EXPORT_MODE.ONCE,
1423
+ isDashedIdent
1424
+ ? CssIcssExportDependency.EXPORT_TYPE.CUSTOM_VARIABLE
1425
+ : CssIcssExportDependency.EXPORT_TYPE.NORMAL
1426
+ );
1427
+
1428
+ dep.setLoc(sl, sc, el, ec);
1429
+ module.addDependency(dep);
1430
+ }
1431
+
1432
+ return end;
1433
+ }
1434
+ },
1435
+ {},
1436
+ { onlyTopLevel: true, functionValue: true }
1437
+ );
1438
+
1439
+ {
1440
+ // Replace the last `)`
1441
+ const dep = new ConstDependency("", [end, end + 1]);
1442
+ module.addPresentationalDependency(dep);
1443
+ }
1444
+
1445
+ return end;
1446
+ };
1447
+
1448
+ /**
1449
+ * @param {string} input input
1450
+ * @param {number} end name end position
1451
+ * @param {{ string?: boolean, identifier?: boolean | RegExp }} options types which allowed to handle
1452
+ * @returns {number} position after handling
1453
+ */
1454
+ const processLocalAtRule = (input, end, options) => {
1455
+ let found = false;
1456
+
1457
+ return walkCssTokens.consumeUntil(
1458
+ input,
1459
+ end,
1460
+ {
1461
+ string(_input, start, end) {
1462
+ if (!found && options.string) {
1463
+ const value = unescapeIdentifier(input.slice(start + 1, end - 1));
1464
+ const { line: sl, column: sc } = locConverter.get(start);
1465
+ const { line: el, column: ec } = locConverter.get(end);
1466
+ const dep = new CssIcssExportDependency(
1467
+ value,
1468
+ value,
1469
+ [start, end],
1470
+ true,
1471
+ CssIcssExportDependency.EXPORT_MODE.ONCE
1472
+ );
1473
+ dep.setLoc(sl, sc, el, ec);
1474
+ module.addDependency(dep);
1475
+ found = true;
1476
+ }
1477
+ return end;
1478
+ },
1479
+ identifier(input, start, end) {
1480
+ if (!found) {
1481
+ const value = input.slice(start, end);
1482
+
1483
+ if (options.identifier) {
1484
+ const identifier = unescapeIdentifier(value);
1485
+
1486
+ if (
1487
+ options.identifier instanceof RegExp &&
1488
+ options.identifier.test(identifier)
1489
+ ) {
1490
+ return end;
1491
+ }
1492
+
1493
+ const { line: sl, column: sc } = locConverter.get(start);
1494
+ const { line: el, column: ec } = locConverter.get(end);
1495
+
1496
+ const dep = new CssIcssExportDependency(
1497
+ identifier,
1498
+ getReexport(identifier),
1499
+ [start, end],
1500
+ true,
1501
+ CssIcssExportDependency.EXPORT_MODE.ONCE,
1502
+ CssIcssExportDependency.EXPORT_TYPE.NORMAL
1503
+ );
1504
+ dep.setLoc(sl, sc, el, ec);
1505
+ module.addDependency(dep);
1506
+ found = true;
1507
+ }
1508
+ }
1509
+ return end;
1510
+ }
1511
+ },
1512
+ {
1513
+ function: (input, start, end) => {
1514
+ // No need to handle `:` (COLON), because it's always a function
1515
+ const name = input
1516
+ .slice(start, end - 1)
1517
+ .replace(/\\/g, "")
1518
+ .toLowerCase();
1519
+
1520
+ const type =
1521
+ name === "local" ? 1 : name === "global" ? 2 : undefined;
1522
+
1523
+ if (!found && type) {
1524
+ found = true;
1525
+ return processLocalOrGlobalFunction(input, type, start, end);
1526
+ }
1527
+
1528
+ if (
1529
+ this.options.dashedIdents &&
1530
+ isLocalMode() &&
1531
+ (name === "var" || name === "style")
1532
+ ) {
1533
+ return processDashedIdent(input, end, end);
1534
+ }
1535
+
1536
+ return end;
1537
+ }
1538
+ },
1539
+ { onlyTopLevel: true, atRulePrelude: true }
1540
+ );
1541
+ };
1542
+ /**
1543
+ * @param {string} input input
1544
+ * @param {number} start start position
1545
+ * @param {number} end end position
1546
+ * @returns {number} position after handling
1547
+ */
1548
+ const processDashedIdent = (input, start, end) => {
1549
+ const customIdent = walkCssTokens.eatIdentSequence(input, start);
1550
+ if (!customIdent) return end;
1551
+ const identifier = unescapeIdentifier(
1552
+ input.slice(customIdent[0] + 2, customIdent[1])
1553
+ );
1554
+ const afterCustomIdent = walkCssTokens.eatWhitespaceAndComments(
1555
+ input,
1556
+ customIdent[1]
1557
+ )[0];
1558
+ if (
1559
+ input.charCodeAt(afterCustomIdent) === CC_LOWER_F ||
1560
+ input.charCodeAt(afterCustomIdent) === CC_UPPER_F
1561
+ ) {
1562
+ const fromWord = walkCssTokens.eatIdentSequence(
1563
+ input,
1564
+ afterCustomIdent
1565
+ );
1566
+ if (
1567
+ !fromWord ||
1568
+ input.slice(fromWord[0], fromWord[1]).toLowerCase() !== "from"
1569
+ ) {
1570
+ return end;
671
1571
  }
672
- };
673
- this.comments.push(comment);
1572
+ const from = walkCssTokens.eatIdentSequenceOrString(
1573
+ input,
1574
+ walkCssTokens.eatWhitespaceAndComments(input, fromWord[1])[0]
1575
+ );
1576
+ if (!from) {
1577
+ return end;
1578
+ }
1579
+ const path = input.slice(from[0], from[1]);
1580
+ if (from[2] === true && path === "global") {
1581
+ const dep = new ConstDependency("", [customIdent[1], from[1]]);
1582
+ module.addPresentationalDependency(dep);
1583
+ return end;
1584
+ } else if (from[2] === false) {
1585
+ const { line: sl, column: sc } = locConverter.get(customIdent[0]);
1586
+ const { line: el, column: ec } = locConverter.get(from[1] - 1);
1587
+ const dep = new CssIcssImportDependency(
1588
+ path.slice(1, -1),
1589
+ [customIdent[0], from[1] - 1],
1590
+ /** @type {"local" | "global"} */
1591
+ (mode),
1592
+ identifier,
1593
+ identifier,
1594
+ CssIcssExportDependency.EXPORT_MODE.NONE,
1595
+ CssIcssExportDependency.EXPORT_TYPE.CUSTOM_VARIABLE
1596
+ );
1597
+
1598
+ dep.setLoc(sl, sc, el, ec);
1599
+ module.addDependency(dep);
1600
+
1601
+ {
1602
+ const dep = new ConstDependency("", [fromWord[0], from[1]]);
1603
+ module.addPresentationalDependency(dep);
1604
+ return end;
1605
+ }
1606
+ }
1607
+ } else {
1608
+ const { line: sl, column: sc } = locConverter.get(customIdent[0]);
1609
+ const { line: el, column: ec } = locConverter.get(customIdent[1]);
1610
+ const dep = new CssIcssExportDependency(
1611
+ identifier,
1612
+ getReexport(identifier),
1613
+ [customIdent[0], customIdent[1]],
1614
+ true,
1615
+ CssIcssExportDependency.EXPORT_MODE.ONCE,
1616
+ CssIcssExportDependency.EXPORT_TYPE.CUSTOM_VARIABLE
1617
+ );
1618
+ dep.setLoc(sl, sc, el, ec);
1619
+ module.addDependency(dep);
1620
+ return end;
1621
+ }
1622
+
1623
+ return end;
1624
+ };
1625
+ /**
1626
+ * @param {string} input input
1627
+ * @param {number} pos name start position
1628
+ * @param {number} end name end position
1629
+ * @returns {number} position after handling
1630
+ */
1631
+ const processLocalDeclaration = (input, pos, end) => {
1632
+ pos = walkCssTokens.eatWhitespaceAndComments(input, pos)[0];
1633
+ const identifier = walkCssTokens.eatIdentSequence(input, pos);
1634
+
1635
+ if (!identifier) {
1636
+ return end;
1637
+ }
1638
+
1639
+ const propertyNameStart = identifier[0];
1640
+
1641
+ pos = walkCssTokens.eatWhitespaceAndComments(input, identifier[1])[0];
1642
+
1643
+ if (input.charCodeAt(pos) !== CC_COLON) {
1644
+ return end;
1645
+ }
1646
+
1647
+ pos += 1;
1648
+
1649
+ // Remove prefix and lowercase
1650
+ const propertyName = input
1651
+ .slice(identifier[0], identifier[1])
1652
+ .replace(/^(-\w+-)/, "")
1653
+ .toLowerCase();
1654
+
1655
+ if (isLocalMode() && knownProperties.has(propertyName)) {
1656
+ /** @type {[number, number, boolean?][]} */
1657
+ const values = [];
1658
+ /** @type {Record<string, number>} */
1659
+ let parsedKeywords = Object.create(null);
1660
+
1661
+ const isGridProperty = Boolean(propertyName.startsWith("grid"));
1662
+ const isGridTemplate = isGridProperty
1663
+ ? Boolean(
1664
+ propertyName === "grid" ||
1665
+ propertyName === "grid-template" ||
1666
+ propertyName === "grid-template-columns" ||
1667
+ propertyName === "grid-template-rows"
1668
+ )
1669
+ : false;
1670
+
1671
+ const end = walkCssTokens.consumeUntil(
1672
+ input,
1673
+ pos,
1674
+ {
1675
+ leftSquareBracket(input, start, end) {
1676
+ let i = end;
1677
+
1678
+ while (true) {
1679
+ i = walkCssTokens.eatWhitespaceAndComments(input, i)[0];
1680
+ const name = walkCssTokens.eatIdentSequence(input, i);
1681
+
1682
+ if (!name) {
1683
+ break;
1684
+ }
1685
+
1686
+ values.push(name);
1687
+ i = name[1];
1688
+ }
1689
+
1690
+ return end;
1691
+ },
1692
+ string(_input, start, end) {
1693
+ if (
1694
+ propertyName === "animation" ||
1695
+ propertyName === "animation-name"
1696
+ ) {
1697
+ values.push([start, end, true]);
1698
+ }
1699
+
1700
+ if (
1701
+ propertyName === "grid" ||
1702
+ propertyName === "grid-template" ||
1703
+ propertyName === "grid-template-areas"
1704
+ ) {
1705
+ const areas = unescapeIdentifier(
1706
+ input.slice(start + 1, end - 1)
1707
+ );
1708
+ const matches = matchAll(/\b\w+\b/g, areas);
1709
+
1710
+ for (const match of matches) {
1711
+ const areaStart = start + 1 + match.index;
1712
+ values.push([areaStart, areaStart + match[0].length, false]);
1713
+ }
1714
+ }
1715
+
1716
+ return end;
1717
+ },
1718
+ identifier(input, start, end) {
1719
+ if (isGridTemplate) {
1720
+ return end;
1721
+ }
1722
+
1723
+ const identifier = input.slice(start, end);
1724
+ const keyword = identifier.toLowerCase();
1725
+
1726
+ parsedKeywords[keyword] =
1727
+ typeof parsedKeywords[keyword] !== "undefined"
1728
+ ? parsedKeywords[keyword] + 1
1729
+ : 0;
1730
+ const keywords =
1731
+ /** @type {Record<string, number>} */
1732
+ (knownProperties.get(propertyName));
1733
+
1734
+ if (
1735
+ keywords[keyword] &&
1736
+ parsedKeywords[keyword] < keywords[keyword]
1737
+ ) {
1738
+ return end;
1739
+ }
1740
+
1741
+ values.push([start, end]);
1742
+ return end;
1743
+ },
1744
+ comma(_input, _start, end) {
1745
+ parsedKeywords = {};
1746
+
1747
+ return end;
1748
+ }
1749
+ },
1750
+ {
1751
+ function: (input, start, end) => {
1752
+ const name = input
1753
+ .slice(start, end - 1)
1754
+ .replace(/\\/g, "")
1755
+ .toLowerCase();
1756
+
1757
+ const type =
1758
+ name === "local" ? 1 : name === "global" ? 2 : undefined;
1759
+
1760
+ if (type) {
1761
+ return processLocalOrGlobalFunction(input, type, start, end);
1762
+ }
1763
+
1764
+ if (
1765
+ this.options.dashedIdents &&
1766
+ isLocalMode() &&
1767
+ name === "var"
1768
+ ) {
1769
+ return processDashedIdent(input, end, end);
1770
+ }
1771
+
1772
+ if (this.options.url) {
1773
+ if (name === "src" || name === "url") {
1774
+ return processURLFunction(input, end, name);
1775
+ } else if (IMAGE_SET_FUNCTION.test(name)) {
1776
+ return processImageSetFunction(input, start, end);
1777
+ }
1778
+ }
1779
+
1780
+ return end;
1781
+ }
1782
+ },
1783
+ {
1784
+ onlyTopLevel: !isGridTemplate,
1785
+ declarationValue: true
1786
+ }
1787
+ );
1788
+
1789
+ if (values.length > 0) {
1790
+ for (const value of values) {
1791
+ const { line: sl, column: sc } = locConverter.get(value[0]);
1792
+ const { line: el, column: ec } = locConverter.get(value[1]);
1793
+ const [start, end, isString] = value;
1794
+ const name = unescapeIdentifier(
1795
+ isString
1796
+ ? input.slice(start + 1, end - 1)
1797
+ : input.slice(start, end)
1798
+ );
1799
+ const dep = new CssIcssExportDependency(
1800
+ name,
1801
+ getReexport(name),
1802
+ [start, end],
1803
+ true,
1804
+ CssIcssExportDependency.EXPORT_MODE.ONCE,
1805
+ isGridProperty
1806
+ ? CssIcssExportDependency.EXPORT_TYPE.GRID_CUSTOM_IDENTIFIER
1807
+ : CssIcssExportDependency.EXPORT_TYPE.NORMAL
1808
+ );
1809
+ dep.setLoc(sl, sc, el, ec);
1810
+ module.addDependency(dep);
1811
+ }
1812
+ }
1813
+
1814
+ return end;
1815
+ } else if (COMPOSES_PROPERTY.test(propertyName)) {
1816
+ if (lastLocalIdentifiers.length > 1) {
1817
+ const end = eatUntilSemi(input, pos);
1818
+ this._emitWarning(
1819
+ state,
1820
+ `Composition is only allowed when selector is single local class name not in "${lastLocalIdentifiers.join('", "')}"`,
1821
+ locConverter,
1822
+ pos,
1823
+ end
1824
+ );
1825
+
1826
+ return end;
1827
+ }
1828
+
1829
+ if (lastLocalIdentifiers.length !== 1) return pos;
1830
+
1831
+ const lastLocalIdentifier = lastLocalIdentifiers[0];
1832
+ let end = pos;
1833
+
1834
+ /** @type {Set<[number, number]>} */
1835
+ const classNames = new Set();
1836
+
1837
+ while (true) {
1838
+ pos = walkCssTokens.eatWhitespaceAndComments(input, pos)[0];
1839
+
1840
+ let className = walkCssTokens.eatIdentSequence(input, pos);
1841
+
1842
+ const ifFunction =
1843
+ className && input.charCodeAt(className[1]) === CC_LEFT_PARENTHESIS;
1844
+ let isGlobalFunction = false;
1845
+
1846
+ if (className && ifFunction) {
1847
+ const name = input
1848
+ .slice(className[0], className[1])
1849
+ .replace(/\\/g, "")
1850
+ .toLowerCase();
1851
+
1852
+ isGlobalFunction = name === "global";
1853
+ pos = walkCssTokens.eatWhitespaceAndComments(
1854
+ input,
1855
+ className[1] + 1
1856
+ )[0];
1857
+ className = walkCssTokens.eatIdentSequence(input, pos);
1858
+ if (className) {
1859
+ pos = walkCssTokens.eatWhitespaceAndComments(
1860
+ input,
1861
+ className[1]
1862
+ )[0];
1863
+ pos += 1;
1864
+ }
1865
+ } else if (className) {
1866
+ pos = walkCssTokens.eatWhitespaceAndComments(
1867
+ input,
1868
+ className[1]
1869
+ )[0];
1870
+ pos = className[1];
1871
+ }
1872
+
1873
+ // True when we have multiple values
1874
+ const isComma = input.charCodeAt(pos) === CC_COMMA;
1875
+ const isSemicolon = input.charCodeAt(pos) === CC_SEMICOLON;
1876
+ const isRightCurly = input.charCodeAt(pos) === CC_RIGHT_CURLY;
1877
+
1878
+ if (isComma || isSemicolon || isRightCurly) {
1879
+ if (className) {
1880
+ classNames.add(className);
1881
+ }
1882
+
1883
+ for (const className of classNames) {
1884
+ const [start, end] = className;
1885
+ const identifier = unescapeIdentifier(input.slice(start, end));
1886
+ const resolvedClassName = getReexport(identifier);
1887
+ const dep = new CssIcssExportDependency(
1888
+ lastLocalIdentifier,
1889
+ resolvedClassName,
1890
+ [start, end],
1891
+ isGlobalFunction ? false : !Array.isArray(resolvedClassName),
1892
+ isGlobalFunction
1893
+ ? CssIcssExportDependency.EXPORT_MODE.APPEND
1894
+ : CssIcssExportDependency.EXPORT_MODE.SELF_REFERENCE
1895
+ );
1896
+ const { line: sl, column: sc } = locConverter.get(start);
1897
+ const { line: el, column: ec } = locConverter.get(end);
1898
+ dep.setLoc(sl, sc, el, ec);
1899
+ module.addDependency(dep);
1900
+ }
1901
+
1902
+ classNames.clear();
1903
+
1904
+ if (isSemicolon || isRightCurly) {
1905
+ end = isSemicolon
1906
+ ? walkCssTokens.eatWhitespace(input, pos + 1)
1907
+ : pos;
1908
+ break;
1909
+ }
1910
+
1911
+ pos += 1;
1912
+ } else if (
1913
+ classNames.size > 0 &&
1914
+ className &&
1915
+ input.slice(className[0], className[1]).toLowerCase() === "from"
1916
+ ) {
1917
+ let from = walkCssTokens.eatString(input, pos);
1918
+
1919
+ if (from) {
1920
+ const request = input.slice(from[0] + 1, from[1] - 1);
1921
+
1922
+ for (const className of classNames) {
1923
+ const [start, end] = className;
1924
+ const identifier = unescapeIdentifier(input.slice(start, end));
1925
+ const dep = new CssIcssImportDependency(
1926
+ request,
1927
+ [start, end],
1928
+ /** @type {"local" | "global"} */
1929
+ (mode),
1930
+ identifier,
1931
+ /** @type {string} */
1932
+ (lastLocalIdentifier),
1933
+ CssIcssExportDependency.EXPORT_MODE.APPEND
1934
+ );
1935
+ const { line: sl, column: sc } = locConverter.get(start);
1936
+ const { line: el, column: ec } = locConverter.get(end);
1937
+ dep.setLoc(sl, sc, el, ec);
1938
+ module.addDependency(dep);
1939
+ }
1940
+
1941
+ classNames.clear();
1942
+ pos = from[1];
1943
+ } else {
1944
+ from = walkCssTokens.eatIdentSequence(input, pos);
1945
+
1946
+ if (from && input.slice(from[0], from[1]) === "global") {
1947
+ for (const className of classNames) {
1948
+ const [start, end] = className;
1949
+ const identifier = unescapeIdentifier(
1950
+ input.slice(start, end)
1951
+ );
1952
+ const dep = new CssIcssExportDependency(
1953
+ /** @type {string} */
1954
+ (lastLocalIdentifier),
1955
+ getReexport(identifier),
1956
+ [start, end],
1957
+ false,
1958
+ CssIcssExportDependency.EXPORT_MODE.APPEND
1959
+ );
1960
+ const { line: sl, column: sc } = locConverter.get(start);
1961
+ const { line: el, column: ec } = locConverter.get(end);
1962
+ dep.setLoc(sl, sc, el, ec);
1963
+ module.addDependency(dep);
1964
+ }
1965
+
1966
+ classNames.clear();
1967
+ pos = from[1];
1968
+ } else {
1969
+ const end = eatUntilSemi(input, pos);
1970
+ this._emitWarning(
1971
+ state,
1972
+ "Incorrect composition, expected global keyword or string value",
1973
+ locConverter,
1974
+ pos,
1975
+ end
1976
+ );
1977
+ return end;
1978
+ }
1979
+ }
1980
+ } else if (className) {
1981
+ classNames.add(className);
1982
+ } else {
1983
+ const end = eatUntilSemi(input, pos);
1984
+ this._emitWarning(
1985
+ state,
1986
+ "Incorrect composition, expected class named",
1987
+ locConverter,
1988
+ pos,
1989
+ end
1990
+ );
1991
+ return end;
1992
+ }
1993
+ }
1994
+
1995
+ // Remove `composes` from source code
1996
+ const dep = new ConstDependency("", [propertyNameStart, end]);
1997
+ module.addPresentationalDependency(dep);
1998
+ }
1999
+
2000
+ return pos;
2001
+ };
2002
+
2003
+ /**
2004
+ * @param {string} input input
2005
+ * @param {number} start start position
2006
+ * @param {number} end end position
2007
+ * @returns {number} position after handling
2008
+ */
2009
+ const processIdSelector = (input, start, end) => {
2010
+ const valueStart = start + 1;
2011
+ const name = unescapeIdentifier(input.slice(valueStart, end));
2012
+ const dep = new CssIcssExportDependency(
2013
+ name,
2014
+ getReexport(name),
2015
+ [valueStart, end],
2016
+ true,
2017
+ CssIcssExportDependency.EXPORT_MODE.ONCE
2018
+ );
2019
+ const { line: sl, column: sc } = locConverter.get(start);
2020
+ const { line: el, column: ec } = locConverter.get(end);
2021
+ dep.setLoc(sl, sc, el, ec);
2022
+ module.addDependency(dep);
674
2023
  return end;
675
2024
  };
676
2025
 
2026
+ /**
2027
+ * @param {string} input input
2028
+ * @param {number} start start position
2029
+ * @param {number} end end position
2030
+ * @returns {number} position after handling
2031
+ */
2032
+ const processClassSelector = (input, start, end) => {
2033
+ const ident = walkCssTokens.skipCommentsAndEatIdentSequence(input, end);
2034
+ if (!ident) return end;
2035
+ const name = unescapeIdentifier(input.slice(ident[0], ident[1]));
2036
+ lastLocalIdentifiers.push(name);
2037
+ const dep = new CssIcssExportDependency(
2038
+ name,
2039
+ getReexport(name),
2040
+ [ident[0], ident[1]],
2041
+ true,
2042
+ CssIcssExportDependency.EXPORT_MODE.ONCE
2043
+ );
2044
+ const { line: sl, column: sc } = locConverter.get(ident[0]);
2045
+ const { line: el, column: ec } = locConverter.get(ident[1]);
2046
+ dep.setLoc(sl, sc, el, ec);
2047
+ module.addDependency(dep);
2048
+ return ident[1];
2049
+ };
2050
+
2051
+ /**
2052
+ * @param {string} input input
2053
+ * @param {number} start start position
2054
+ * @param {number} end end position
2055
+ * @returns {number} position after handling
2056
+ */
2057
+ const processAttributeSelector = (input, start, end) => {
2058
+ end = walkCssTokens.eatWhitespaceAndComments(input, end)[0];
2059
+ const identifier = walkCssTokens.eatIdentSequence(input, end);
2060
+ if (!identifier) return end;
2061
+ const name = unescapeIdentifier(
2062
+ input.slice(identifier[0], identifier[1])
2063
+ );
2064
+ if (name.toLowerCase() !== "class") {
2065
+ return end;
2066
+ }
2067
+ end = walkCssTokens.eatWhitespaceAndComments(input, identifier[1])[0];
2068
+
2069
+ const isTilde = input.charCodeAt(end) === CC_TILDE;
2070
+
2071
+ if (
2072
+ input.charCodeAt(end) !== CC_EQUAL &&
2073
+ input.charCodeAt(end) !== CC_TILDE
2074
+ ) {
2075
+ return end;
2076
+ }
2077
+
2078
+ end += 1;
2079
+
2080
+ if (isTilde) {
2081
+ if (input.charCodeAt(end) !== CC_EQUAL) {
2082
+ return end;
2083
+ }
2084
+
2085
+ end += 1;
2086
+ }
2087
+
2088
+ end = walkCssTokens.eatWhitespaceAndComments(input, end)[0];
2089
+ const value = walkCssTokens.eatIdentSequenceOrString(input, end);
2090
+
2091
+ if (!value) {
2092
+ return end;
2093
+ }
2094
+
2095
+ const classNameStart = value[2] ? value[0] : value[0] + 1;
2096
+ const classNameEnd = value[2] ? value[1] : value[1] - 1;
2097
+ const className = unescapeIdentifier(
2098
+ input.slice(classNameStart, classNameEnd)
2099
+ );
2100
+ const dep = new CssIcssExportDependency(
2101
+ className,
2102
+ getReexport(className),
2103
+ [classNameStart, classNameEnd],
2104
+ true,
2105
+ CssIcssExportDependency.EXPORT_MODE.NONE
2106
+ );
2107
+ const { line: sl, column: sc } = locConverter.get(classNameStart);
2108
+ const { line: el, column: ec } = locConverter.get(classNameEnd);
2109
+ dep.setLoc(sl, sc, el, ec);
2110
+ module.addDependency(dep);
2111
+ return value[2] ? classNameEnd : classNameEnd + 1;
2112
+ };
2113
+
677
2114
  walkCssTokens(source, 0, {
678
2115
  comment,
679
2116
  leftCurlyBracket: (input, start, end) => {
@@ -708,13 +2145,9 @@ class CssParser extends Parser {
708
2145
  if (isModules) {
709
2146
  isNextRulePrelude = true;
710
2147
  modeData = undefined;
2148
+ lastLocalIdentifiers = [];
711
2149
  }
712
2150
  } else if (isModules) {
713
- if (isLocalMode()) {
714
- processDeclarationValueDone(input);
715
- inAnimationProperty = false;
716
- }
717
-
718
2151
  isNextRulePrelude = isNextNestedSyntax(input, end);
719
2152
  }
720
2153
  break;
@@ -723,68 +2156,17 @@ class CssParser extends Parser {
723
2156
  return end;
724
2157
  },
725
2158
  url: (input, start, end, contentStart, contentEnd) => {
726
- if (!this.url) {
2159
+ if (!this.options.url) {
727
2160
  return end;
728
2161
  }
729
2162
 
730
- const { options, errors: commentErrors } = this.parseCommentOptions([
731
- lastTokenEndForComments,
732
- end
733
- ]);
734
- if (commentErrors) {
735
- for (const e of commentErrors) {
736
- const { comment } = e;
737
- state.module.addWarning(
738
- new CommentCompilationWarning(
739
- `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
740
- comment.loc
741
- )
742
- );
743
- }
744
- }
745
- if (options && options.webpackIgnore !== undefined) {
746
- if (typeof options.webpackIgnore !== "boolean") {
747
- const { line: sl, column: sc } = locConverter.get(
748
- lastTokenEndForComments
749
- );
750
- const { line: el, column: ec } = locConverter.get(end);
751
-
752
- state.module.addWarning(
753
- new UnsupportedFeatureWarning(
754
- `\`webpackIgnore\` expected a boolean, but received: ${options.webpackIgnore}.`,
755
- {
756
- start: { line: sl, column: sc },
757
- end: { line: el, column: ec }
758
- }
759
- )
760
- );
761
- } else if (options.webpackIgnore) {
762
- return end;
763
- }
764
- }
765
- const value = normalizeUrl(
766
- input.slice(contentStart, contentEnd),
767
- false
2163
+ return processOldURLFunction(
2164
+ input,
2165
+ start,
2166
+ end,
2167
+ contentStart,
2168
+ contentEnd
768
2169
  );
769
- // Ignore `url()`, `url('')` and `url("")`, they are valid by spec
770
- if (value.length === 0) return end;
771
- const dep = new CssUrlDependency(value, [start, end], "url");
772
- const { line: sl, column: sc } = locConverter.get(start);
773
- const { line: el, column: ec } = locConverter.get(end);
774
- dep.setLoc(sl, sc, el, ec);
775
- module.addDependency(dep);
776
- module.addCodeGenerationDependency(dep);
777
- return end;
778
- },
779
- string: (_input, start, end) => {
780
- switch (scope) {
781
- case CSS_MODE_IN_BLOCK: {
782
- if (inAnimationProperty && balanced.length === 0) {
783
- lastIdentifier = [start, end, false];
784
- }
785
- }
786
- }
787
- return end;
788
2170
  },
789
2171
  atKeyword: (input, start, end) => {
790
2172
  const name = input.slice(start, end).toLowerCase();
@@ -802,8 +2184,8 @@ class CssParser extends Parser {
802
2184
  return eatUntilSemi(input, start);
803
2185
  }
804
2186
  case "@import": {
805
- if (!this.import) {
806
- return eatSemi(input, end);
2187
+ if (!this.options.import) {
2188
+ return eatUntilSemi(input, end);
807
2189
  }
808
2190
 
809
2191
  if (!allowImportAtRule) {
@@ -817,232 +2199,37 @@ class CssParser extends Parser {
817
2199
  return end;
818
2200
  }
819
2201
 
820
- const tokens = walkCssTokens.eatImportTokens(input, end, {
821
- comment
822
- });
823
- if (!tokens[3]) return end;
824
- const semi = tokens[3][1];
825
- if (!tokens[0]) {
826
- this._emitWarning(
827
- state,
828
- `Expected URL in '${input.slice(start, semi)}'`,
829
- locConverter,
830
- start,
831
- semi
832
- );
833
- return end;
834
- }
835
-
836
- const urlToken = tokens[0];
837
- const url = normalizeUrl(
838
- input.slice(urlToken[2], urlToken[3]),
839
- true
840
- );
841
- const newline = walkCssTokens.eatWhiteLine(input, semi);
842
- const { options, errors: commentErrors } = this.parseCommentOptions(
843
- [end, urlToken[1]]
844
- );
845
- if (commentErrors) {
846
- for (const e of commentErrors) {
847
- const { comment } = e;
848
- state.module.addWarning(
849
- new CommentCompilationWarning(
850
- `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
851
- comment.loc
852
- )
853
- );
854
- }
855
- }
856
- if (options && options.webpackIgnore !== undefined) {
857
- if (typeof options.webpackIgnore !== "boolean") {
858
- const { line: sl, column: sc } = locConverter.get(start);
859
- const { line: el, column: ec } = locConverter.get(newline);
860
-
861
- state.module.addWarning(
862
- new UnsupportedFeatureWarning(
863
- `\`webpackIgnore\` expected a boolean, but received: ${options.webpackIgnore}.`,
864
- {
865
- start: { line: sl, column: sc },
866
- end: { line: el, column: ec }
867
- }
868
- )
869
- );
870
- } else if (options.webpackIgnore) {
871
- return newline;
872
- }
873
- }
874
- if (url.length === 0) {
875
- const { line: sl, column: sc } = locConverter.get(start);
876
- const { line: el, column: ec } = locConverter.get(newline);
877
- const dep = new ConstDependency("", [start, newline]);
878
- module.addPresentationalDependency(dep);
879
- dep.setLoc(sl, sc, el, ec);
880
-
881
- return newline;
882
- }
883
-
884
- let layer;
885
-
886
- if (tokens[1]) {
887
- layer = input.slice(tokens[1][0] + 6, tokens[1][1] - 1).trim();
888
- }
889
-
890
- let supports;
891
-
892
- if (tokens[2]) {
893
- supports = input.slice(tokens[2][0] + 9, tokens[2][1] - 1).trim();
894
- }
895
-
896
- const last = tokens[2] || tokens[1] || tokens[0];
897
- const mediaStart = walkCssTokens.eatWhitespaceAndComments(
898
- input,
899
- last[1]
900
- );
901
-
902
- let media;
903
-
904
- if (mediaStart !== semi - 1) {
905
- media = input.slice(mediaStart, semi - 1).trim();
906
- }
907
-
908
- const { line: sl, column: sc } = locConverter.get(start);
909
- const { line: el, column: ec } = locConverter.get(newline);
910
- const dep = new CssImportDependency(
911
- url,
912
- [start, newline],
913
- layer,
914
- supports && supports.length > 0 ? supports : undefined,
915
- media && media.length > 0 ? media : undefined
916
- );
917
- dep.setLoc(sl, sc, el, ec);
918
- module.addDependency(dep);
919
-
920
- return newline;
2202
+ return processAtImport(input, start, end);
921
2203
  }
922
2204
  default: {
923
2205
  if (isModules) {
924
2206
  if (name === "@value") {
925
- const semi = eatUntilSemi(input, end);
926
- const atRuleEnd = semi + 1;
927
- const params = input.slice(end, semi);
928
- let [alias, from] = params.split(/\s*from\s*/);
929
-
930
- if (from) {
931
- const aliases = alias
932
- .replace(CSS_COMMENT, " ")
933
- .trim()
934
- .replace(/^\(|\)$/g, "")
935
- .split(/\s*,\s*/);
936
-
937
- from = from.replace(CSS_COMMENT, "").trim();
938
-
939
- const isExplicitImport = from[0] === "'" || from[0] === '"';
940
-
941
- if (isExplicitImport) {
942
- from = from.slice(1, -1);
943
- }
944
-
945
- for (const alias of aliases) {
946
- const [name, aliasName] = alias.split(/\s*as\s*/);
947
-
948
- icssDefinitions.set(aliasName || name, {
949
- value: name,
950
- path: from
951
- });
952
- }
953
- } else {
954
- const ident = walkCssTokens.eatIdentSequence(alias, 0);
955
-
956
- if (!ident) {
957
- this._emitWarning(
958
- state,
959
- `Broken '@value' at-rule: ${input.slice(
960
- start,
961
- atRuleEnd
962
- )}'`,
963
- locConverter,
964
- start,
965
- atRuleEnd
966
- );
967
-
968
- const dep = new ConstDependency("", [start, atRuleEnd]);
969
- module.addPresentationalDependency(dep);
970
- return atRuleEnd;
971
- }
972
-
973
- const pos = walkCssTokens.eatWhitespaceAndComments(
974
- alias,
975
- ident[1]
976
- );
977
-
978
- const name = alias.slice(ident[0], ident[1]);
979
- let value =
980
- alias.charCodeAt(pos) === CC_COLON
981
- ? alias.slice(pos + 1)
982
- : alias.slice(ident[1]);
983
-
984
- if (value && !/^\s+$/.test(value)) {
985
- value = value.trim();
986
- }
987
-
988
- if (icssDefinitions.has(value)) {
989
- const def = icssDefinitions.get(value);
990
-
991
- value = def.value;
992
- }
993
-
994
- icssDefinitions.set(name, { value });
995
-
996
- const dep = new CssIcssExportDependency(name, value);
997
- const { line: sl, column: sc } = locConverter.get(start);
998
- const { line: el, column: ec } = locConverter.get(end);
999
- dep.setLoc(sl, sc, el, ec);
1000
- module.addDependency(dep);
1001
- }
1002
-
1003
- const dep = new ConstDependency("", [start, atRuleEnd]);
1004
- module.addPresentationalDependency(dep);
1005
- return atRuleEnd;
2207
+ return processAtValue(input, start, end);
1006
2208
  } else if (
2209
+ this.options.animation &&
1007
2210
  OPTIONALLY_VENDOR_PREFIXED_KEYFRAMES_AT_RULE.test(name) &&
1008
2211
  isLocalMode()
1009
2212
  ) {
1010
- const ident = walkCssTokens.eatIdentSequenceOrString(
1011
- input,
1012
- end
1013
- );
1014
- if (!ident) return end;
1015
- const name = unescapeIdentifier(
1016
- ident[2] === true
1017
- ? input.slice(ident[0], ident[1])
1018
- : input.slice(ident[0] + 1, ident[1] - 1)
1019
- );
1020
- const { line: sl, column: sc } = locConverter.get(ident[0]);
1021
- const { line: el, column: ec } = locConverter.get(ident[1]);
1022
- const dep = new CssLocalIdentifierDependency(name, [
1023
- ident[0],
1024
- ident[1]
1025
- ]);
1026
- dep.setLoc(sl, sc, el, ec);
1027
- module.addDependency(dep);
1028
- return ident[1];
1029
- } else if (name === "@property" && isLocalMode()) {
1030
- const ident = walkCssTokens.eatIdentSequence(input, end);
1031
- if (!ident) return end;
1032
- let name = input.slice(ident[0], ident[1]);
1033
- if (!name.startsWith("--") || name.length < 3) return end;
1034
- name = unescapeIdentifier(name.slice(2));
1035
- declaredCssVariables.add(name);
1036
- const { line: sl, column: sc } = locConverter.get(ident[0]);
1037
- const { line: el, column: ec } = locConverter.get(ident[1]);
1038
- const dep = new CssLocalIdentifierDependency(
1039
- name,
1040
- [ident[0], ident[1]],
1041
- "--"
1042
- );
1043
- dep.setLoc(sl, sc, el, ec);
1044
- module.addDependency(dep);
1045
- return ident[1];
2213
+ return processLocalAtRule(input, end, {
2214
+ string: true,
2215
+ identifier: true
2216
+ });
2217
+ } else if (
2218
+ this.options.customIdents &&
2219
+ name === "@counter-style" &&
2220
+ isLocalMode()
2221
+ ) {
2222
+ return processLocalAtRule(input, end, {
2223
+ identifier: true
2224
+ });
2225
+ } else if (
2226
+ this.options.container &&
2227
+ name === "@container" &&
2228
+ isLocalMode()
2229
+ ) {
2230
+ return processLocalAtRule(input, end, {
2231
+ identifier: /^(none|and|or|not)$/
2232
+ });
1046
2233
  } else if (name === "@scope") {
1047
2234
  isNextRulePrelude = true;
1048
2235
  return end;
@@ -1057,59 +2244,31 @@ class CssParser extends Parser {
1057
2244
  },
1058
2245
  semicolon: (input, start, end) => {
1059
2246
  if (isModules && scope === CSS_MODE_IN_BLOCK) {
1060
- if (isLocalMode()) {
1061
- processDeclarationValueDone(input);
1062
- inAnimationProperty = false;
1063
- }
1064
-
1065
2247
  isNextRulePrelude = isNextNestedSyntax(input, end);
1066
2248
  }
1067
2249
  return end;
1068
2250
  },
1069
2251
  identifier: (input, start, end) => {
1070
2252
  if (isModules) {
1071
- if (icssDefinitions.has(input.slice(start, end))) {
1072
- const name = input.slice(start, end);
1073
- let { path, value } = icssDefinitions.get(name);
1074
-
1075
- if (path) {
1076
- if (icssDefinitions.has(path)) {
1077
- const definition = icssDefinitions.get(path);
1078
-
1079
- path = definition.value.slice(1, -1);
1080
- }
2253
+ const identifier = input.slice(start, end);
1081
2254
 
1082
- const dep = new CssIcssImportDependency(path, value, [
1083
- start,
1084
- end - 1
1085
- ]);
1086
- const { line: sl, column: sc } = locConverter.get(start);
1087
- const { line: el, column: ec } = locConverter.get(end - 1);
1088
- dep.setLoc(sl, sc, el, ec);
1089
- module.addDependency(dep);
1090
- } else {
1091
- const { line: sl, column: sc } = locConverter.get(start);
1092
- const { line: el, column: ec } = locConverter.get(end);
1093
- const dep = new CssIcssSymbolDependency(name, value, [
1094
- start,
1095
- end
1096
- ]);
1097
- dep.setLoc(sl, sc, el, ec);
1098
- module.addDependency(dep);
1099
- }
2255
+ if (icssDefinitions.has(identifier)) {
2256
+ return processICSSSymbol(identifier, start, end);
2257
+ }
1100
2258
 
1101
- return end;
2259
+ if (
2260
+ this.options.dashedIdents &&
2261
+ isLocalMode() &&
2262
+ isDashedIdentifier(identifier)
2263
+ ) {
2264
+ return processDashedIdent(input, start, end);
1102
2265
  }
1103
2266
 
1104
2267
  switch (scope) {
1105
2268
  case CSS_MODE_IN_BLOCK: {
1106
- if (isLocalMode()) {
2269
+ if (isModules && !isNextRulePrelude) {
1107
2270
  // Handle only top level values and not inside functions
1108
- if (inAnimationProperty && balanced.length === 0) {
1109
- lastIdentifier = [start, end, true];
1110
- } else {
1111
- return processLocalDeclaration(input, start, end);
1112
- }
2271
+ return processLocalDeclaration(input, start, end);
1113
2272
  }
1114
2273
  break;
1115
2274
  }
@@ -1120,34 +2279,14 @@ class CssParser extends Parser {
1120
2279
  },
1121
2280
  delim: (input, start, end) => {
1122
2281
  if (isNextRulePrelude && isLocalMode()) {
1123
- const ident = walkCssTokens.skipCommentsAndEatIdentSequence(
1124
- input,
1125
- end
1126
- );
1127
- if (!ident) return end;
1128
- const name = unescapeIdentifier(input.slice(ident[0], ident[1]));
1129
- const dep = new CssLocalIdentifierDependency(name, [
1130
- ident[0],
1131
- ident[1]
1132
- ]);
1133
- const { line: sl, column: sc } = locConverter.get(ident[0]);
1134
- const { line: el, column: ec } = locConverter.get(ident[1]);
1135
- dep.setLoc(sl, sc, el, ec);
1136
- module.addDependency(dep);
1137
- return ident[1];
2282
+ return processClassSelector(input, start, end);
1138
2283
  }
1139
2284
 
1140
2285
  return end;
1141
2286
  },
1142
2287
  hash: (input, start, end, isID) => {
1143
2288
  if (isNextRulePrelude && isLocalMode() && isID) {
1144
- const valueStart = start + 1;
1145
- const name = unescapeIdentifier(input.slice(valueStart, end));
1146
- const dep = new CssLocalIdentifierDependency(name, [valueStart, end]);
1147
- const { line: sl, column: sc } = locConverter.get(start);
1148
- const { line: el, column: ec } = locConverter.get(end);
1149
- dep.setLoc(sl, sc, el, ec);
1150
- module.addDependency(dep);
2289
+ return processIdSelector(input, start, end);
1151
2290
  }
1152
2291
 
1153
2292
  return end;
@@ -1164,12 +2303,12 @@ class CssParser extends Parser {
1164
2303
  switch (scope) {
1165
2304
  case CSS_MODE_TOP_LEVEL: {
1166
2305
  if (name === "import") {
1167
- const pos = parseImportOrExport(0, input, ident[1]);
2306
+ const pos = processImportOrExport(0, input, ident[1]);
1168
2307
  const dep = new ConstDependency("", [start, pos]);
1169
2308
  module.addPresentationalDependency(dep);
1170
2309
  return pos;
1171
2310
  } else if (name === "export") {
1172
- const pos = parseImportOrExport(1, input, ident[1]);
2311
+ const pos = processImportOrExport(1, input, ident[1]);
1173
2312
  const dep = new ConstDependency("", [start, pos]);
1174
2313
  module.addPresentationalDependency(dep);
1175
2314
  return pos;
@@ -1181,18 +2320,24 @@ class CssParser extends Parser {
1181
2320
  const isFn = input.charCodeAt(ident[1]) === CC_LEFT_PARENTHESIS;
1182
2321
 
1183
2322
  if (isFn && name === "local") {
1184
- const end = ident[1] + 1;
1185
- modeData = "local";
2323
+ // Eat extra whitespace
2324
+ const end = walkCssTokens.eatWhitespaceAndComments(
2325
+ input,
2326
+ ident[1] + 1
2327
+ )[0];
2328
+ modeData = LOCAL_MODE;
1186
2329
  const dep = new ConstDependency("", [start, end]);
1187
2330
  module.addPresentationalDependency(dep);
1188
- balanced.push([":local", start, end]);
2331
+ balanced.push([":local", start, end, true]);
1189
2332
  return end;
1190
2333
  } else if (name === "local") {
1191
- modeData = "local";
1192
- // Eat extra whitespace
1193
- end = walkCssTokens.eatWhitespace(input, ident[1]);
2334
+ modeData = LOCAL_MODE;
2335
+ const found = walkCssTokens.eatWhitespaceAndComments(
2336
+ input,
2337
+ ident[1]
2338
+ );
1194
2339
 
1195
- if (ident[1] === end) {
2340
+ if (!found[1]) {
1196
2341
  this._emitWarning(
1197
2342
  state,
1198
2343
  `Missing whitespace after ':local' in '${input.slice(
@@ -1205,22 +2350,30 @@ class CssParser extends Parser {
1205
2350
  );
1206
2351
  }
1207
2352
 
2353
+ end = walkCssTokens.eatWhitespace(input, ident[1]);
1208
2354
  const dep = new ConstDependency("", [start, end]);
1209
2355
  module.addPresentationalDependency(dep);
1210
2356
  return end;
1211
2357
  } else if (isFn && name === "global") {
1212
- const end = ident[1] + 1;
1213
- modeData = "global";
2358
+ // Eat extra whitespace
2359
+ const end = walkCssTokens.eatWhitespaceAndComments(
2360
+ input,
2361
+ ident[1] + 1
2362
+ )[0];
2363
+ modeData = GLOBAL_MODE;
1214
2364
  const dep = new ConstDependency("", [start, end]);
1215
2365
  module.addPresentationalDependency(dep);
1216
- balanced.push([":global", start, end]);
2366
+ balanced.push([":global", start, end, true]);
1217
2367
  return end;
1218
2368
  } else if (name === "global") {
1219
- modeData = "global";
2369
+ modeData = GLOBAL_MODE;
1220
2370
  // Eat extra whitespace
1221
- end = walkCssTokens.eatWhitespace(input, ident[1]);
2371
+ const found = walkCssTokens.eatWhitespaceAndComments(
2372
+ input,
2373
+ ident[1]
2374
+ );
1222
2375
 
1223
- if (ident[1] === end) {
2376
+ if (!found[1]) {
1224
2377
  this._emitWarning(
1225
2378
  state,
1226
2379
  `Missing whitespace after ':global' in '${input.slice(
@@ -1233,6 +2386,7 @@ class CssParser extends Parser {
1233
2386
  );
1234
2387
  }
1235
2388
 
2389
+ end = walkCssTokens.eatWhitespace(input, ident[1]);
1236
2390
  const dep = new ConstDependency("", [start, end]);
1237
2391
  module.addPresentationalDependency(dep);
1238
2392
  return end;
@@ -1257,211 +2411,31 @@ class CssParser extends Parser {
1257
2411
  switch (name) {
1258
2412
  case "src":
1259
2413
  case "url": {
1260
- if (!this.url) {
2414
+ if (!this.options.url) {
1261
2415
  return end;
1262
2416
  }
1263
2417
 
1264
- const string = walkCssTokens.eatString(input, end);
1265
- if (!string) return end;
1266
- const { options, errors: commentErrors } = this.parseCommentOptions(
1267
- [lastTokenEndForComments, end]
1268
- );
1269
- if (commentErrors) {
1270
- for (const e of commentErrors) {
1271
- const { comment } = e;
1272
- state.module.addWarning(
1273
- new CommentCompilationWarning(
1274
- `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
1275
- comment.loc
1276
- )
1277
- );
1278
- }
1279
- }
1280
- if (options && options.webpackIgnore !== undefined) {
1281
- if (typeof options.webpackIgnore !== "boolean") {
1282
- const { line: sl, column: sc } = locConverter.get(string[0]);
1283
- const { line: el, column: ec } = locConverter.get(string[1]);
1284
-
1285
- state.module.addWarning(
1286
- new UnsupportedFeatureWarning(
1287
- `\`webpackIgnore\` expected a boolean, but received: ${options.webpackIgnore}.`,
1288
- {
1289
- start: { line: sl, column: sc },
1290
- end: { line: el, column: ec }
1291
- }
1292
- )
1293
- );
1294
- } else if (options.webpackIgnore) {
1295
- return end;
1296
- }
1297
- }
1298
- const value = normalizeUrl(
1299
- input.slice(string[0] + 1, string[1] - 1),
1300
- true
1301
- );
1302
- // Ignore `url()`, `url('')` and `url("")`, they are valid by spec
1303
- if (value.length === 0) return end;
1304
- const isUrl = name === "url" || name === "src";
1305
- const dep = new CssUrlDependency(
1306
- value,
1307
- [string[0], string[1]],
1308
- isUrl ? "string" : "url"
1309
- );
1310
- const { line: sl, column: sc } = locConverter.get(string[0]);
1311
- const { line: el, column: ec } = locConverter.get(string[1]);
1312
- dep.setLoc(sl, sc, el, ec);
1313
- module.addDependency(dep);
1314
- module.addCodeGenerationDependency(dep);
1315
- return string[1];
2418
+ return processURLFunction(input, end, name);
1316
2419
  }
1317
2420
  default: {
1318
- if (this.url && IMAGE_SET_FUNCTION.test(name)) {
1319
- lastTokenEndForComments = end;
1320
- const values = walkCssTokens.eatImageSetStrings(input, end, {
1321
- comment
1322
- });
1323
- if (values.length === 0) return end;
1324
- for (const [index, string] of values.entries()) {
1325
- const value = normalizeUrl(
1326
- input.slice(string[0] + 1, string[1] - 1),
1327
- true
1328
- );
1329
- if (value.length === 0) return end;
1330
- const { options, errors: commentErrors } =
1331
- this.parseCommentOptions([
1332
- index === 0 ? start : values[index - 1][1],
1333
- string[1]
1334
- ]);
1335
- if (commentErrors) {
1336
- for (const e of commentErrors) {
1337
- const { comment } = e;
1338
- state.module.addWarning(
1339
- new CommentCompilationWarning(
1340
- `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
1341
- comment.loc
1342
- )
1343
- );
1344
- }
1345
- }
1346
- if (options && options.webpackIgnore !== undefined) {
1347
- if (typeof options.webpackIgnore !== "boolean") {
1348
- const { line: sl, column: sc } = locConverter.get(
1349
- string[0]
1350
- );
1351
- const { line: el, column: ec } = locConverter.get(
1352
- string[1]
1353
- );
2421
+ if (this.options.url && IMAGE_SET_FUNCTION.test(name)) {
2422
+ return processImageSetFunction(input, start, end);
2423
+ }
1354
2424
 
1355
- state.module.addWarning(
1356
- new UnsupportedFeatureWarning(
1357
- `\`webpackIgnore\` expected a boolean, but received: ${options.webpackIgnore}.`,
1358
- {
1359
- start: { line: sl, column: sc },
1360
- end: { line: el, column: ec }
1361
- }
1362
- )
1363
- );
1364
- } else if (options.webpackIgnore) {
1365
- continue;
1366
- }
1367
- }
1368
- const dep = new CssUrlDependency(
1369
- value,
1370
- [string[0], string[1]],
1371
- "url"
1372
- );
1373
- const { line: sl, column: sc } = locConverter.get(string[0]);
1374
- const { line: el, column: ec } = locConverter.get(string[1]);
1375
- dep.setLoc(sl, sc, el, ec);
1376
- module.addDependency(dep);
1377
- module.addCodeGenerationDependency(dep);
1378
- }
1379
- // Can contain `url()` inside, so let's return end to allow parse them
1380
- return end;
1381
- } else if (isLocalMode()) {
1382
- // Don't rename animation name when we have `var()` function
1383
- if (inAnimationProperty && balanced.length === 1) {
1384
- lastIdentifier = undefined;
2425
+ if (isModules) {
2426
+ if (
2427
+ this.options.function &&
2428
+ isLocalMode() &&
2429
+ isDashedIdentifier(name)
2430
+ ) {
2431
+ return processDashedIdent(input, start, end);
1385
2432
  }
1386
2433
 
1387
- if (name === "var") {
1388
- const customIdent = walkCssTokens.eatIdentSequence(input, end);
1389
- if (!customIdent) return end;
1390
- let name = input.slice(customIdent[0], customIdent[1]);
1391
- // A custom property is any property whose name starts with two dashes (U+002D HYPHEN-MINUS), like --foo.
1392
- // The <custom-property-name> production corresponds to this:
1393
- // it’s defined as any <dashed-ident> (a valid identifier that starts with two dashes),
1394
- // except -- itself, which is reserved for future use by CSS.
1395
- if (!name.startsWith("--") || name.length < 3) return end;
1396
- name = unescapeIdentifier(
1397
- input.slice(customIdent[0] + 2, customIdent[1])
1398
- );
1399
- const afterCustomIdent = walkCssTokens.eatWhitespaceAndComments(
1400
- input,
1401
- customIdent[1]
1402
- );
1403
- if (
1404
- input.charCodeAt(afterCustomIdent) === CC_LOWER_F ||
1405
- input.charCodeAt(afterCustomIdent) === CC_UPPER_F
1406
- ) {
1407
- const fromWord = walkCssTokens.eatIdentSequence(
1408
- input,
1409
- afterCustomIdent
1410
- );
1411
- if (
1412
- !fromWord ||
1413
- input.slice(fromWord[0], fromWord[1]).toLowerCase() !==
1414
- "from"
1415
- ) {
1416
- return end;
1417
- }
1418
- const from = walkCssTokens.eatIdentSequenceOrString(
1419
- input,
1420
- walkCssTokens.eatWhitespaceAndComments(input, fromWord[1])
1421
- );
1422
- if (!from) {
1423
- return end;
1424
- }
1425
- const path = input.slice(from[0], from[1]);
1426
- if (from[2] === true && path === "global") {
1427
- const dep = new ConstDependency("", [
1428
- customIdent[1],
1429
- from[1]
1430
- ]);
1431
- module.addPresentationalDependency(dep);
1432
- return end;
1433
- } else if (from[2] === false) {
1434
- const dep = new CssIcssImportDependency(
1435
- path.slice(1, -1),
1436
- name,
1437
- [customIdent[0], from[1] - 1]
1438
- );
1439
- const { line: sl, column: sc } = locConverter.get(
1440
- customIdent[0]
1441
- );
1442
- const { line: el, column: ec } = locConverter.get(
1443
- from[1] - 1
1444
- );
1445
- dep.setLoc(sl, sc, el, ec);
1446
- module.addDependency(dep);
1447
- }
1448
- } else {
1449
- const { line: sl, column: sc } = locConverter.get(
1450
- customIdent[0]
1451
- );
1452
- const { line: el, column: ec } = locConverter.get(
1453
- customIdent[1]
1454
- );
1455
- const dep = new CssSelfLocalIdentifierDependency(
1456
- name,
1457
- [customIdent[0], customIdent[1]],
1458
- "--",
1459
- declaredCssVariables
1460
- );
1461
- dep.setLoc(sl, sc, el, ec);
1462
- module.addDependency(dep);
1463
- return end;
1464
- }
2434
+ const type =
2435
+ name === "local" ? 1 : name === "global" ? 2 : undefined;
2436
+
2437
+ if (type && !isNextRulePrelude) {
2438
+ return processLocalOrGlobalFunction(input, type, start, end);
1465
2439
  }
1466
2440
  }
1467
2441
  }
@@ -1469,6 +2443,12 @@ class CssParser extends Parser {
1469
2443
 
1470
2444
  return end;
1471
2445
  },
2446
+ leftSquareBracket: (input, start, end) => {
2447
+ if (isNextRulePrelude && isLocalMode()) {
2448
+ return processAttributeSelector(input, start, end);
2449
+ }
2450
+ return end;
2451
+ },
1472
2452
  leftParenthesis: (input, start, end) => {
1473
2453
  balanced.push(["(", start, end]);
1474
2454
 
@@ -1477,28 +2457,38 @@ class CssParser extends Parser {
1477
2457
  rightParenthesis: (input, start, end) => {
1478
2458
  const popped = balanced.pop();
1479
2459
 
1480
- if (
1481
- isModules &&
1482
- popped &&
1483
- (popped[0] === ":local" || popped[0] === ":global")
1484
- ) {
1485
- modeData = balanced[balanced.length - 1]
1486
- ? /** @type {"local" | "global"} */
1487
- (balanced[balanced.length - 1][0])
1488
- : undefined;
1489
- const dep = new ConstDependency("", [start, end]);
1490
- module.addPresentationalDependency(dep);
2460
+ if (isModules && popped) {
2461
+ const isLocal = popped[0] === ":local";
2462
+ const isGlobal = popped[0] === ":global";
2463
+ if (isLocal || isGlobal) {
2464
+ modeData = balanced[balanced.length - 1]
2465
+ ? balanced[balanced.length - 1][0] === ":local"
2466
+ ? LOCAL_MODE
2467
+ : balanced[balanced.length - 1][0] === ":global"
2468
+ ? GLOBAL_MODE
2469
+ : undefined
2470
+ : undefined;
2471
+ if (popped[3] && isLocal) {
2472
+ while (walkCssTokens.isWhiteSpace(input.charCodeAt(start - 1))) {
2473
+ start -= 1;
2474
+ }
2475
+ }
2476
+ const dep = new ConstDependency("", [start, end]);
2477
+ module.addPresentationalDependency(dep);
2478
+ } else if (isNextRulePrelude) {
2479
+ modeData = undefined;
2480
+ }
1491
2481
  }
1492
2482
 
1493
2483
  return end;
1494
2484
  },
1495
2485
  comma: (input, start, end) => {
1496
2486
  if (isModules) {
1497
- // Reset stack for `:global .class :local .class-other` selector after
1498
- modeData = undefined;
2487
+ const popped = balanced.pop();
1499
2488
 
1500
- if (scope === CSS_MODE_IN_BLOCK && isLocalMode()) {
1501
- processDeclarationValueDone(input);
2489
+ if (!popped) {
2490
+ // Reset stack for `:global .class :local .class-other` selector after
2491
+ modeData = undefined;
1502
2492
  }
1503
2493
  }
1504
2494
 
@@ -1510,17 +2500,43 @@ class CssParser extends Parser {
1510
2500
 
1511
2501
  /** @type {BuildInfo} */
1512
2502
  (module.buildInfo).strict = true;
1513
- /** @type {BuildMeta} */
1514
- (module.buildMeta).exportsType = this.namedExports
1515
- ? "namespace"
1516
- : "default";
1517
2503
 
1518
- if (!this.namedExports) {
1519
- /** @type {BuildMeta} */
1520
- (module.buildMeta).defaultObject = "redirect";
2504
+ const buildMeta = /** @type {BuildMeta} */ (state.module.buildMeta);
2505
+
2506
+ buildMeta.exportsType = this.options.namedExports ? "namespace" : "default";
2507
+ buildMeta.defaultObject = this.options.namedExports
2508
+ ? false
2509
+ : "redirect-warn";
2510
+ buildMeta.exportType = this.options.exportType;
2511
+
2512
+ if (!buildMeta.exportType) {
2513
+ // Inherit exportType from parent module to ensure consistency.
2514
+ // When a CSS file is imported with syntax like `import "./basic.css" with { type: "css" }`,
2515
+ // the parent module's exportType is set to "css-style-sheet".
2516
+ // Child modules imported via @import should inherit this exportType
2517
+ // instead of using the default "link", ensuring that the entire
2518
+ // import chain uses the same export format.
2519
+ const parent = state.compilation.moduleGraph.getIssuer(module);
2520
+ if (parent instanceof CssModule) {
2521
+ buildMeta.exportType = /** @type {BuildMeta} */ (
2522
+ parent.buildMeta
2523
+ ).exportType;
2524
+ }
2525
+ }
2526
+ if (!buildMeta.exportType) {
2527
+ buildMeta.exportType = "link";
2528
+ }
2529
+
2530
+ // TODO this.namedExports?
2531
+ if (
2532
+ buildMeta.exportType === "text" ||
2533
+ buildMeta.exportType === "css-style-sheet"
2534
+ ) {
2535
+ module.addDependency(new StaticExportsDependency(["default"], true));
2536
+ } else {
2537
+ module.addDependency(new StaticExportsDependency([], true));
1521
2538
  }
1522
2539
 
1523
- module.addDependency(new StaticExportsDependency([], true));
1524
2540
  return state;
1525
2541
  }
1526
2542
 
@@ -1555,14 +2571,14 @@ class CssParser extends Parser {
1555
2571
 
1556
2572
  /**
1557
2573
  * @param {Range} range range of the comment
1558
- * @returns {{ options: Record<string, any> | null, errors: (Error & { comment: Comment })[] | null }} result
2574
+ * @returns {{ options: Record<string, EXPECTED_ANY> | null, errors: (Error & { comment: Comment })[] | null }} result
1559
2575
  */
1560
2576
  parseCommentOptions(range) {
1561
2577
  const comments = this.getComments(range);
1562
2578
  if (comments.length === 0) {
1563
2579
  return EMPTY_COMMENT_OPTIONS;
1564
2580
  }
1565
- /** @type {Record<string, EXPECTED_ANY> } */
2581
+ /** @type {Record<string, EXPECTED_ANY>} */
1566
2582
  const options = {};
1567
2583
  /** @type {(Error & { comment: Comment })[]} */
1568
2584
  const errors = [];
@@ -1589,7 +2605,7 @@ class CssParser extends Parser {
1589
2605
  const newErr = new Error(String(/** @type {Error} */ (err).message));
1590
2606
  newErr.stack = String(/** @type {Error} */ (err).stack);
1591
2607
  Object.assign(newErr, { comment });
1592
- errors.push(/** @type (Error & { comment: Comment }) */ (newErr));
2608
+ errors.push(/** @type {(Error & { comment: Comment })} */ (newErr));
1593
2609
  }
1594
2610
  }
1595
2611
  }