webpack 5.106.2 → 5.107.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 (235) hide show
  1. package/README.md +2 -2
  2. package/lib/APIPlugin.js +1 -1
  3. package/lib/BannerPlugin.js +3 -4
  4. package/lib/Cache.js +3 -6
  5. package/lib/Chunk.js +21 -25
  6. package/lib/ChunkGroup.js +57 -15
  7. package/lib/CompatibilityPlugin.js +8 -7
  8. package/lib/Compilation.js +67 -37
  9. package/lib/Compiler.js +4 -13
  10. package/lib/ContextModule.js +2 -2
  11. package/lib/DefinePlugin.js +2 -2
  12. package/lib/Dependency.js +22 -1
  13. package/lib/DependencyTemplate.js +2 -1
  14. package/lib/EnvironmentPlugin.js +1 -1
  15. package/lib/EvalSourceMapDevToolPlugin.js +8 -10
  16. package/lib/ExportsInfo.js +30 -34
  17. package/lib/ExternalModule.js +91 -26
  18. package/lib/ExternalModuleFactoryPlugin.js +7 -1
  19. package/lib/FileSystemInfo.js +187 -72
  20. package/lib/Generator.js +3 -3
  21. package/lib/HotModuleReplacementPlugin.js +26 -8
  22. package/lib/IgnorePlugin.js +2 -1
  23. package/lib/Module.js +20 -19
  24. package/lib/ModuleFactory.js +1 -1
  25. package/lib/ModuleNotFoundError.js +3 -84
  26. package/lib/ModuleSourceTypeConstants.js +51 -19
  27. package/lib/ModuleTypeConstants.js +12 -3
  28. package/lib/MultiCompiler.js +2 -2
  29. package/lib/NodeStuffPlugin.js +1 -1
  30. package/lib/NormalModule.js +119 -77
  31. package/lib/NormalModuleFactory.js +47 -27
  32. package/lib/Parser.js +1 -1
  33. package/lib/ProgressPlugin.js +129 -56
  34. package/lib/RuntimeGlobals.js +5 -5
  35. package/lib/RuntimeModule.js +9 -7
  36. package/lib/RuntimePlugin.js +12 -1
  37. package/lib/SourceMapDevToolPlugin.js +250 -49
  38. package/lib/Template.js +1 -1
  39. package/lib/TemplatedPathPlugin.js +22 -4
  40. package/lib/WarnCaseSensitiveModulesPlugin.js +70 -2
  41. package/lib/WarnDeprecatedOptionPlugin.js +1 -1
  42. package/lib/WarnNoModeSetPlugin.js +16 -1
  43. package/lib/Watching.js +2 -3
  44. package/lib/WebpackError.js +3 -77
  45. package/lib/WebpackIsIncludedPlugin.js +1 -1
  46. package/lib/WebpackOptionsApply.js +13 -1
  47. package/lib/asset/AssetBytesGenerator.js +12 -8
  48. package/lib/asset/AssetGenerator.js +36 -22
  49. package/lib/asset/AssetModulesPlugin.js +6 -8
  50. package/lib/asset/AssetSourceGenerator.js +12 -8
  51. package/lib/buildChunkGraph.js +4 -6
  52. package/lib/cache/PackFileCacheStrategy.js +4 -4
  53. package/lib/cli.js +3 -1
  54. package/lib/config/defaults.js +197 -10
  55. package/lib/config/normalization.js +3 -1
  56. package/lib/css/CssGenerator.js +320 -105
  57. package/lib/css/CssInjectStyleRuntimeModule.js +44 -42
  58. package/lib/css/CssLoadingRuntimeModule.js +22 -4
  59. package/lib/{CssModule.js → css/CssModule.js} +15 -15
  60. package/lib/css/CssModulesPlugin.js +168 -88
  61. package/lib/css/CssParser.js +566 -269
  62. package/lib/css/walkCssTokens.js +148 -2
  63. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +1 -1
  64. package/lib/dependencies/CommonJsDependencyHelpers.js +63 -0
  65. package/lib/dependencies/CommonJsExportRequireDependency.js +54 -10
  66. package/lib/dependencies/CommonJsExportsParserPlugin.js +1 -1
  67. package/lib/dependencies/CommonJsFullRequireDependency.js +32 -9
  68. package/lib/dependencies/CommonJsImportsParserPlugin.js +112 -4
  69. package/lib/dependencies/CommonJsRequireDependency.js +67 -4
  70. package/lib/dependencies/ContextDependency.js +1 -1
  71. package/lib/dependencies/ContextDependencyHelpers.js +1 -1
  72. package/lib/dependencies/CreateRequireParserPlugin.js +1 -1
  73. package/lib/dependencies/CriticalDependencyWarning.js +1 -1
  74. package/lib/dependencies/CssIcssExportDependency.js +332 -67
  75. package/lib/dependencies/CssIcssImportDependency.js +49 -7
  76. package/lib/dependencies/CssIcssSymbolDependency.js +11 -3
  77. package/lib/dependencies/CssImportDependency.js +8 -0
  78. package/lib/dependencies/CssUrlDependency.js +28 -2
  79. package/lib/dependencies/HarmonyDetectionParserPlugin.js +22 -2
  80. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +8 -7
  81. package/lib/dependencies/HarmonyExportExpressionDependency.js +22 -14
  82. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +110 -3
  83. package/lib/dependencies/HarmonyImportDependency.js +10 -2
  84. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +22 -1
  85. package/lib/dependencies/HarmonyImportSpecifierDependency.js +1 -1
  86. package/lib/{HarmonyLinkingError.js → dependencies/HarmonyLinkingError.js} +5 -3
  87. package/lib/dependencies/HtmlInlineScriptDependency.js +133 -0
  88. package/lib/dependencies/HtmlInlineStyleDependency.js +101 -0
  89. package/lib/dependencies/HtmlScriptSrcDependency.js +557 -0
  90. package/lib/dependencies/HtmlSourceDependency.js +128 -0
  91. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +1 -1
  92. package/lib/dependencies/ImportParserPlugin.js +2 -2
  93. package/lib/dependencies/ImportPhase.js +1 -1
  94. package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +1 -1
  95. package/lib/{RequireJsStuffPlugin.js → dependencies/RequireJsStuffPlugin.js} +7 -7
  96. package/lib/dependencies/SystemPlugin.js +1 -1
  97. package/lib/dependencies/WebAssemblyImportDependency.js +1 -1
  98. package/lib/dependencies/WorkerPlugin.js +2 -2
  99. package/lib/{DelegatedModule.js → dll/DelegatedModule.js} +31 -31
  100. package/lib/{DelegatedModuleFactoryPlugin.js → dll/DelegatedModuleFactoryPlugin.js} +4 -4
  101. package/lib/{DelegatedPlugin.js → dll/DelegatedPlugin.js} +2 -2
  102. package/lib/{DllEntryPlugin.js → dll/DllEntryPlugin.js} +4 -4
  103. package/lib/{DllModule.js → dll/DllModule.js} +24 -24
  104. package/lib/{DllModuleFactory.js → dll/DllModuleFactory.js} +4 -4
  105. package/lib/{DllPlugin.js → dll/DllPlugin.js} +6 -5
  106. package/lib/{DllReferencePlugin.js → dll/DllReferencePlugin.js} +14 -14
  107. package/lib/{LibManifestPlugin.js → dll/LibManifestPlugin.js} +9 -9
  108. package/lib/{AsyncDependencyToInitialChunkError.js → errors/AsyncDependencyToInitialChunkError.js} +2 -2
  109. package/lib/errors/BuildCycleError.js +1 -1
  110. package/lib/{ChunkRenderError.js → errors/ChunkRenderError.js} +1 -1
  111. package/lib/{CodeGenerationError.js → errors/CodeGenerationError.js} +1 -1
  112. package/lib/{CommentCompilationWarning.js → errors/CommentCompilationWarning.js} +3 -3
  113. package/lib/{ConcurrentCompilationError.js → errors/ConcurrentCompilationError.js} +4 -2
  114. package/lib/{EnvironmentNotSupportAsyncWarning.js → errors/EnvironmentNotSupportAsyncWarning.js} +4 -4
  115. package/lib/{HookWebpackError.js → errors/HookWebpackError.js} +5 -5
  116. package/lib/{IgnoreErrorModuleFactory.js → errors/IgnoreErrorModuleFactory.js} +4 -4
  117. package/lib/{InvalidDependenciesModuleWarning.js → errors/InvalidDependenciesModuleWarning.js} +3 -3
  118. package/lib/errors/JSONParseError.js +114 -0
  119. package/lib/{ModuleBuildError.js → errors/ModuleBuildError.js} +5 -5
  120. package/lib/{ModuleDependencyError.js → errors/ModuleDependencyError.js} +2 -2
  121. package/lib/{ModuleDependencyWarning.js → errors/ModuleDependencyWarning.js} +4 -4
  122. package/lib/{ModuleError.js → errors/ModuleError.js} +5 -5
  123. package/lib/{ModuleHashingError.js → errors/ModuleHashingError.js} +1 -1
  124. package/lib/errors/ModuleNotFoundError.js +91 -0
  125. package/lib/{ModuleParseError.js → errors/ModuleParseError.js} +8 -6
  126. package/lib/{ModuleRestoreError.js → errors/ModuleRestoreError.js} +1 -1
  127. package/lib/{ModuleStoreError.js → errors/ModuleStoreError.js} +1 -1
  128. package/lib/{ModuleWarning.js → errors/ModuleWarning.js} +5 -5
  129. package/lib/{NodeStuffInWebError.js → errors/NodeStuffInWebError.js} +4 -4
  130. package/lib/errors/NonErrorEmittedError.js +28 -0
  131. package/lib/{UnhandledSchemeError.js → errors/UnhandledSchemeError.js} +2 -2
  132. package/lib/{UnsupportedFeatureWarning.js → errors/UnsupportedFeatureWarning.js} +3 -3
  133. package/lib/errors/WebpackError.js +84 -0
  134. package/lib/html/HtmlGenerator.js +379 -0
  135. package/lib/html/HtmlModulesPlugin.js +429 -0
  136. package/lib/html/HtmlParser.js +1489 -0
  137. package/lib/html/walkHtmlTokens.js +3249 -0
  138. package/lib/ids/IdHelpers.js +2 -1
  139. package/lib/index.js +36 -15
  140. package/lib/javascript/JavascriptModulesPlugin.js +91 -10
  141. package/lib/javascript/JavascriptParser.js +197 -16
  142. package/lib/javascript/JavascriptParserHelpers.js +1 -1
  143. package/lib/json/JsonParser.js +7 -16
  144. package/lib/library/AbstractLibraryPlugin.js +1 -1
  145. package/lib/library/EnableLibraryPlugin.js +1 -1
  146. package/lib/{FalseIIFEUmdWarning.js → library/FalseIIFEUmdWarning.js} +1 -1
  147. package/lib/library/ModuleLibraryPlugin.js +74 -0
  148. package/lib/node/NodeEnvironmentPlugin.js +4 -2
  149. package/lib/node/nodeConsole.js +113 -64
  150. package/lib/optimize/ConcatenatedModule.js +51 -6
  151. package/lib/optimize/InnerGraph.js +1 -1
  152. package/lib/optimize/InnerGraphPlugin.js +11 -1
  153. package/lib/optimize/MinMaxSizeWarning.js +4 -4
  154. package/lib/optimize/ModuleConcatenationPlugin.js +15 -7
  155. package/lib/optimize/RealContentHashPlugin.js +89 -26
  156. package/lib/optimize/SideEffectsFlagPlugin.js +112 -5
  157. package/lib/optimize/SplitChunksPlugin.js +5 -5
  158. package/lib/performance/AssetsOverSizeLimitWarning.js +2 -2
  159. package/lib/performance/EntrypointsOverSizeLimitWarning.js +2 -2
  160. package/lib/performance/NoAsyncChunksWarning.js +5 -3
  161. package/lib/performance/SizeLimitsPlugin.js +1 -1
  162. package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +4 -1
  163. package/lib/rules/UseEffectRulePlugin.js +4 -3
  164. package/lib/runtime/AutoPublicPathRuntimeModule.js +3 -3
  165. package/lib/runtime/GetChunkFilenameRuntimeModule.js +5 -5
  166. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +119 -13
  167. package/lib/runtime/SetAnonymousDefaultNameRuntimeModule.js +35 -0
  168. package/lib/schemes/DataUriPlugin.js +13 -1
  169. package/lib/schemes/VirtualUrlPlugin.js +1 -1
  170. package/lib/serialization/SerializerMiddleware.js +2 -2
  171. package/lib/sharing/ConsumeSharedPlugin.js +4 -10
  172. package/lib/sharing/ConsumeSharedRuntimeModule.js +8 -4
  173. package/lib/sharing/ProvideSharedModule.js +1 -1
  174. package/lib/sharing/ProvideSharedPlugin.js +5 -5
  175. package/lib/sharing/resolveMatchedConfigs.js +1 -1
  176. package/lib/stats/DefaultStatsFactoryPlugin.js +2 -2
  177. package/lib/stats/DefaultStatsPresetPlugin.js +1 -1
  178. package/lib/stats/DefaultStatsPrinterPlugin.js +1 -1
  179. package/lib/stats/StatsFactory.js +1 -1
  180. package/lib/typescript/TypeScriptPlugin.js +210 -0
  181. package/lib/url/URLParserPlugin.js +2 -2
  182. package/lib/util/AsyncQueue.js +2 -2
  183. package/lib/util/Hash.js +2 -2
  184. package/lib/util/LocConverter.js +53 -0
  185. package/lib/util/SortableSet.js +1 -1
  186. package/lib/util/cleverMerge.js +2 -2
  187. package/lib/util/comparators.js +3 -3
  188. package/lib/util/concatenate.js +3 -3
  189. package/lib/util/conventions.js +42 -1
  190. package/lib/util/createMappings.js +118 -0
  191. package/lib/{formatLocation.js → util/formatLocation.js} +2 -2
  192. package/lib/{SizeFormatHelpers.js → util/formatSize.js} +3 -1
  193. package/lib/util/fs.js +8 -8
  194. package/lib/util/hash/md4.js +1 -1
  195. package/lib/util/hash/xxhash64.js +1 -1
  196. package/lib/util/identifier.js +48 -0
  197. package/lib/util/internalSerializables.js +35 -19
  198. package/lib/util/magicComment.js +10 -7
  199. package/lib/util/parseJson.js +2 -73
  200. package/lib/util/source.js +21 -0
  201. package/lib/util/topologicalSort.js +69 -0
  202. package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +3 -4
  203. package/lib/wasm-async/AsyncWebAssemblyParser.js +1 -1
  204. package/lib/wasm-sync/UnsupportedWebAssemblyFeatureError.js +5 -3
  205. package/lib/wasm-sync/WasmFinalizeExportsPlugin.js +1 -1
  206. package/lib/wasm-sync/WebAssemblyInInitialChunkError.js +5 -3
  207. package/lib/webpack.js +3 -1
  208. package/package.json +24 -22
  209. package/schemas/WebpackOptions.check.js +1 -1
  210. package/schemas/WebpackOptions.json +129 -12
  211. package/schemas/plugins/{DllPlugin.check.d.ts → HtmlGeneratorOptions.check.d.ts} +1 -1
  212. package/schemas/plugins/HtmlGeneratorOptions.check.js +6 -0
  213. package/schemas/plugins/HtmlGeneratorOptions.json +3 -0
  214. package/schemas/plugins/ProgressPlugin.check.js +1 -1
  215. package/schemas/plugins/ProgressPlugin.json +22 -0
  216. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  217. package/schemas/plugins/container/ContainerReferencePlugin.json +1 -0
  218. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  219. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  220. package/schemas/plugins/container/ModuleFederationPlugin.json +1 -0
  221. package/schemas/plugins/{DllReferencePlugin.check.d.ts → css/CssAutoOrModuleParserOptions.check.d.ts} +1 -1
  222. package/schemas/plugins/css/CssAutoOrModuleParserOptions.check.js +6 -0
  223. package/schemas/plugins/css/CssAutoOrModuleParserOptions.json +3 -0
  224. package/schemas/plugins/dll/DllPlugin.check.d.ts +7 -0
  225. package/schemas/plugins/dll/DllReferencePlugin.check.d.ts +7 -0
  226. package/types.d.ts +1153 -233
  227. package/lib/CaseSensitiveModulesWarning.js +0 -80
  228. package/lib/GraphHelpers.js +0 -49
  229. package/lib/NoModeWarning.js +0 -23
  230. package/lib/css/CssMergeStyleSheetsRuntimeModule.js +0 -57
  231. /package/lib/{AbstractMethodError.js → errors/AbstractMethodError.js} +0 -0
  232. /package/schemas/plugins/{DllPlugin.check.js → dll/DllPlugin.check.js} +0 -0
  233. /package/schemas/plugins/{DllPlugin.json → dll/DllPlugin.json} +0 -0
  234. /package/schemas/plugins/{DllReferencePlugin.check.js → dll/DllReferencePlugin.check.js} +0 -0
  235. /package/schemas/plugins/{DllReferencePlugin.json → dll/DllReferencePlugin.json} +0 -0
@@ -7,13 +7,14 @@
7
7
 
8
8
  const { CSS_TYPE, JAVASCRIPT_TYPE } = require("../ModuleSourceTypeConstants");
9
9
  const { interpolate } = require("../TemplatedPathPlugin");
10
- const WebpackError = require("../WebpackError");
10
+ const WebpackError = require("../errors/WebpackError");
11
11
  const { cssExportConvention } = require("../util/conventions");
12
12
  const createHash = require("../util/createHash");
13
13
  const { makePathsRelative } = require("../util/identifier");
14
14
  const makeSerializable = require("../util/makeSerializable");
15
15
  const memoize = require("../util/memoize");
16
16
  const nonNumericOnlyHash = require("../util/nonNumericOnlyHash");
17
+ const { updateHashFromSource } = require("../util/source");
17
18
  const CssIcssImportDependency = require("./CssIcssImportDependency");
18
19
  const NullDependency = require("./NullDependency");
19
20
 
@@ -23,7 +24,8 @@ const getCssParser = memoize(() => require("../css/CssParser"));
23
24
  /** @typedef {import("../../declarations/WebpackOptions").HashFunction} HashFunction */
24
25
  /** @typedef {import("../../declarations/WebpackOptions").CssGeneratorExportsConvention} CssGeneratorExportsConvention */
25
26
  /** @typedef {import("../../declarations/WebpackOptions").CssGeneratorLocalIdentName} CssGeneratorLocalIdentName */
26
- /** @typedef {import("../CssModule")} CssModule */
27
+ /** @typedef {import("../css/CssModule")} CssModule */
28
+ /** @typedef {import("../Module").BuildInfo} BuildInfo */
27
29
  /** @typedef {import("../Dependency")} Dependency */
28
30
  /** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
29
31
  /** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
@@ -36,10 +38,11 @@ const getCssParser = memoize(() => require("../css/CssParser"));
36
38
  /** @typedef {import("../util/Hash")} Hash */
37
39
  /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
38
40
  /** @typedef {import("../ChunkGraph")} ChunkGraph */
41
+ /** @typedef {import("../Compilation").ModulePathData} ModulePathData */
39
42
  /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
40
43
  /** @typedef {import("../css/CssParser").Range} Range */
41
44
 
42
- /** @typedef {(name: string) => string} ExportsConventionFn */
45
+ /** @typedef {(name: string) => string | string[]} ExportsConventionFn */
43
46
 
44
47
  /**
45
48
  * Returns local ident.
@@ -104,7 +107,7 @@ const getLocalIdent = (local, module, chunkGraph, runtimeTemplate) => {
104
107
  const source = module.originalSource();
105
108
 
106
109
  if (source) {
107
- hash.update(source.buffer());
110
+ updateHashFromSource(hash, source);
108
111
  }
109
112
 
110
113
  if (module.error) {
@@ -157,13 +160,113 @@ const getLocalIdent = (local, module, chunkGraph, runtimeTemplate) => {
157
160
  return localIdent.replace(/^((-?\d)|--)/, "_$1");
158
161
  };
159
162
 
160
- /** @typedef {string | [string, string]} Value */
163
+ /** @typedef {string | [string, string] | [string, string, string]} Value */
161
164
 
162
165
  // 0 - replace, 1 - replace, 2 - append, 2 - once
163
166
  /** @typedef {0 | 1 | 2 | 3 | 4} ExportMode */
164
167
  // 0 - normal, 1 - custom css variable, 2 - grid custom ident, 3 - composes
165
168
  /** @typedef {0 | 1 | 2 | 3} ExportType */
166
169
 
170
+ /**
171
+ * Computes the interpolated identifier for `(module, value, exportType)`.
172
+ * Module-level reference so `moduleGraph.cached` can use it as a stable
173
+ * computer key — repeated lookups during a build skip
174
+ * `cssExportConvention`, `getLocalIdent` (with its content / path hashing)
175
+ * and `escapeIdentifier`.
176
+ * @param {ModuleGraph} _moduleGraph module graph (unused, kept for `cached` signature)
177
+ * @param {CssModule} module css module the value resolves in
178
+ * @param {string} value raw value to interpolate
179
+ * @param {ExportType} exportType export type discriminator
180
+ * @param {ChunkGraph} chunkGraph chunk graph
181
+ * @param {RuntimeTemplate} runtimeTemplate runtime template
182
+ * @returns {string} interpolated identifier
183
+ */
184
+ const computeInterpolatedIdentifier = (
185
+ _moduleGraph,
186
+ module,
187
+ value,
188
+ exportType,
189
+ chunkGraph,
190
+ runtimeTemplate
191
+ ) => {
192
+ const generator = /** @type {CssGenerator} */ (module.generator);
193
+ const local = cssExportConvention(
194
+ value,
195
+ /** @type {CssGeneratorExportsConvention} */
196
+ (generator.options.exportsConvention)
197
+ )[0];
198
+ const prefix =
199
+ exportType === CssIcssExportDependency.EXPORT_TYPE.CUSTOM_VARIABLE
200
+ ? "--"
201
+ : "";
202
+ return (
203
+ prefix +
204
+ getCssParser().escapeIdentifier(
205
+ getLocalIdent(local, module, chunkGraph, runtimeTemplate),
206
+ runtimeTemplate.compilation.compiler.root
207
+ )
208
+ );
209
+ };
210
+
211
+ /**
212
+ * Top-level computer for `resolve`. Allocates a fresh `seen` set; recursive
213
+ * calls go through the un-cached inner path so cycle detection still works.
214
+ * @param {ModuleGraph} moduleGraph module graph
215
+ * @param {CssModule} module module to search
216
+ * @param {string} localName local name
217
+ * @param {string} importName imported export name
218
+ * @param {string | undefined} request request of the active `@value` import
219
+ * @param {ChunkGraph} chunkGraph chunk graph
220
+ * @param {RuntimeTemplate} runtimeTemplate runtime template
221
+ * @returns {string | undefined} resolved value or undefined
222
+ */
223
+ const computeResolve = (
224
+ moduleGraph,
225
+ module,
226
+ localName,
227
+ importName,
228
+ request,
229
+ chunkGraph,
230
+ runtimeTemplate
231
+ ) =>
232
+ CssIcssExportDependency.Template._doResolve(
233
+ localName,
234
+ importName,
235
+ /** @type {DependencyTemplateContext} */
236
+ (
237
+ /** @type {unknown} */
238
+ ({ moduleGraph, module, chunkGraph, runtimeTemplate })
239
+ ),
240
+ request,
241
+ new Set()
242
+ );
243
+
244
+ /**
245
+ * Top-level computer for `resolveReferences`. See `computeResolve`.
246
+ * @param {ModuleGraph} moduleGraph module graph
247
+ * @param {CssIcssExportDependency} dep export dependency
248
+ * @param {CssModule} module module that hosts `dep`
249
+ * @param {ChunkGraph} chunkGraph chunk graph
250
+ * @param {RuntimeTemplate} runtimeTemplate runtime template
251
+ * @returns {string[]} final references, deduplicated
252
+ */
253
+ const computeResolveReferences = (
254
+ moduleGraph,
255
+ dep,
256
+ module,
257
+ chunkGraph,
258
+ runtimeTemplate
259
+ ) =>
260
+ CssIcssExportDependency.Template._doResolveReferences(
261
+ dep,
262
+ /** @type {DependencyTemplateContext} */
263
+ (
264
+ /** @type {unknown} */
265
+ ({ moduleGraph, module, chunkGraph, runtimeTemplate })
266
+ ),
267
+ new Set()
268
+ );
269
+
167
270
  class CssIcssExportDependency extends NullDependency {
168
271
  /**
169
272
  * Example of dependency:
@@ -193,6 +296,10 @@ class CssIcssExportDependency extends NullDependency {
193
296
  this.exportType = exportType;
194
297
  /** @type {undefined | string} */
195
298
  this._hashUpdate = undefined;
299
+ /** @type {undefined | string[]} */
300
+ this._conventionNames = undefined;
301
+ /** @type {undefined | string[]} */
302
+ this._valueConventionNames = undefined;
196
303
  }
197
304
 
198
305
  get type() {
@@ -213,6 +320,26 @@ class CssIcssExportDependency extends NullDependency {
213
320
  return this._conventionNames;
214
321
  }
215
322
 
323
+ /**
324
+ * Memoized `cssExportConvention(this.value, convention)`. Used by every
325
+ * code path that needs the convention-derived aliases of the composed /
326
+ * referenced class: `getReferencedExports`, `getWarnings`, and the template's
327
+ * `getIdentifier`. Caller guarantees `typeof this.value === "string"` —
328
+ * the array form (cross-module references) is resolved separately.
329
+ * @param {CssGeneratorExportsConvention} convention convention of the export name
330
+ * @returns {string[]} convention results
331
+ */
332
+ getValueConventionNames(convention) {
333
+ if (this._valueConventionNames) {
334
+ return this._valueConventionNames;
335
+ }
336
+ this._valueConventionNames = cssExportConvention(
337
+ /** @type {string} */ (this.value),
338
+ convention
339
+ );
340
+ return this._valueConventionNames;
341
+ }
342
+
216
343
  /**
217
344
  * Returns list of exports referenced by this dependency
218
345
  * @param {ModuleGraph} moduleGraph module graph
@@ -221,14 +348,26 @@ class CssIcssExportDependency extends NullDependency {
221
348
  */
222
349
  getReferencedExports(moduleGraph, runtime) {
223
350
  if (
224
- this.exportMode === CssIcssExportDependency.EXPORT_MODE.SELF_REFERENCE
351
+ this.exportMode === CssIcssExportDependency.EXPORT_MODE.SELF_REFERENCE &&
352
+ typeof this.value === "string"
225
353
  ) {
226
- return [
227
- {
228
- name: [this.name],
229
- canMangle: true
230
- }
231
- ];
354
+ // `composes: foo;` — the composed class (`this.value`) is the one
355
+ // referenced, not the class doing the composing (`this.name`). Apply
356
+ // the generator's `exportsConvention` so the export names produced
357
+ // by the convention are what the optimizer sees.
358
+ const module =
359
+ /** @type {CssModule | undefined} */
360
+ (moduleGraph.getParentModule(this));
361
+ if (!module) return super.getReferencedExports(moduleGraph, runtime);
362
+ const generator = /** @type {CssGenerator} */ (module.generator);
363
+ const names = this.getValueConventionNames(
364
+ /** @type {CssGeneratorExportsConvention} */
365
+ (generator.options.exportsConvention)
366
+ );
367
+ return names.map((name) => ({
368
+ name: [name],
369
+ canMangle: true
370
+ }));
232
371
  }
233
372
 
234
373
  return super.getReferencedExports(moduleGraph, runtime);
@@ -272,14 +411,30 @@ class CssIcssExportDependency extends NullDependency {
272
411
  getWarnings(moduleGraph) {
273
412
  if (
274
413
  this.exportMode === CssIcssExportDependency.EXPORT_MODE.SELF_REFERENCE &&
275
- !Array.isArray(this.value)
414
+ typeof this.value === "string"
276
415
  ) {
277
- const module = moduleGraph.getParentModule(this);
416
+ const module =
417
+ /** @type {CssModule | undefined} */
418
+ (moduleGraph.getParentModule(this));
419
+
420
+ if (!module) return null;
421
+
422
+ // `ExportsInfo` only stores names produced by `exportsConvention`,
423
+ // so a raw `isExportProvided(this.value)` check is a false-positive
424
+ // for `camel-case-only` / `dashes-only` (and any custom function
425
+ // that drops the original spelling). Treat the composed class as
426
+ // provided if *any* of its convention-produced aliases is provided.
427
+ const generator = /** @type {CssGenerator} */ (module.generator);
428
+ const exportsInfo = moduleGraph.getExportsInfo(module);
429
+ const names = this.getValueConventionNames(
430
+ /** @type {CssGeneratorExportsConvention} */
431
+ (generator.options.exportsConvention)
432
+ );
433
+ const isProvided = names.some((name) =>
434
+ exportsInfo.isExportProvided(name)
435
+ );
278
436
 
279
- if (
280
- module &&
281
- !moduleGraph.getExportsInfo(module).isExportProvided(this.value)
282
- ) {
437
+ if (!isProvided) {
283
438
  const error = new WebpackError(
284
439
  `Self-referencing name "${this.value}" not found`
285
440
  );
@@ -309,7 +464,11 @@ class CssIcssExportDependency extends NullDependency {
309
464
  /** @type {CssGeneratorExportsConvention} */
310
465
  (generator.options.exportsConvention)
311
466
  );
312
- this._hashUpdate = `exportsConvention|${JSON.stringify(names)}|localIdentName|${JSON.stringify(generator.options.localIdentName)}`;
467
+ // Include all instance state that affects the emitted output —
468
+ // `name`, `value`, `range`, `interpolate`, `exportMode`,
469
+ // `exportType` — so changes like switching `composes: foo` →
470
+ // `composes: bar` or `ONCE` → `APPEND` invalidate caches.
471
+ this._hashUpdate = `exportsConvention|${JSON.stringify(names)}|localIdentName|${JSON.stringify(generator.options.localIdentName)}|value|${JSON.stringify(this.value)}|range|${JSON.stringify(this.range)}|interpolate|${this.interpolate}|exportMode|${this.exportMode}|exportType|${this.exportType}`;
313
472
  }
314
473
  hash.update(this._hashUpdate);
315
474
  }
@@ -348,23 +507,60 @@ class CssIcssExportDependency extends NullDependency {
348
507
  CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends (
349
508
  NullDependency.Template
350
509
  ) {
351
- // TODO looking how to cache
352
510
  /**
353
- * Returns found reference.
511
+ * Returns found reference. The top-level call (no `seen` argument) is
512
+ * memoized via `moduleGraph.cached` keyed by `(module, localName,
513
+ * importName, request, chunkGraph, runtimeTemplate)`. Recursive callers
514
+ * pass `seen` and skip the cache so the cycle guard is preserved — only
515
+ * completed top-level resolutions land in the cache.
354
516
  * @param {string} localName local name
355
517
  * @param {string} importName import name
356
518
  * @param {DependencyTemplateContext} templateContext the context object
519
+ * @param {string | undefined} request user request of the `@value` import that was active when the reference was parsed — used to disambiguate when the same local name is imported from multiple modules
520
+ * @param {Set<CssIcssExportDependency>=} seen seen to prevent cyclical problems
521
+ * @returns {string | undefined} found reference
522
+ */
523
+ static resolve(localName, importName, templateContext, request, seen) {
524
+ if (seen !== undefined) {
525
+ return CssIcssExportDependencyTemplate._doResolve(
526
+ localName,
527
+ importName,
528
+ templateContext,
529
+ request,
530
+ seen
531
+ );
532
+ }
533
+ const { moduleGraph, module, chunkGraph, runtimeTemplate } =
534
+ templateContext;
535
+ return moduleGraph.cached(
536
+ computeResolve,
537
+ /** @type {CssModule} */ (module),
538
+ localName,
539
+ importName,
540
+ request,
541
+ chunkGraph,
542
+ runtimeTemplate
543
+ );
544
+ }
545
+
546
+ /**
547
+ * Inner recursive worker for `resolve`. Not memoized — see `resolve`.
548
+ * @param {string} localName local name
549
+ * @param {string} importName import name
550
+ * @param {DependencyTemplateContext} templateContext the context object
551
+ * @param {string | undefined} request user request
357
552
  * @param {Set<CssIcssExportDependency>} seen seen to prevent cyclical problems
358
553
  * @returns {string | undefined} found reference
359
554
  */
360
- static resolve(localName, importName, templateContext, seen = new Set()) {
555
+ static _doResolve(localName, importName, templateContext, request, seen) {
361
556
  const { moduleGraph } = templateContext;
362
557
  const importDep =
363
558
  /** @type {CssIcssImportDependency | undefined} */
364
559
  (
365
- templateContext.module.dependencies.find(
366
- (d) =>
367
- d instanceof CssIcssImportDependency && d.localName === localName
560
+ CssIcssExportDependencyTemplate.findImportDep(
561
+ templateContext.module.dependencies,
562
+ localName,
563
+ request
368
564
  )
369
565
  );
370
566
  if (!importDep) return undefined;
@@ -388,13 +584,14 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
388
584
  const { value, interpolate } = exportDep;
389
585
 
390
586
  if (Array.isArray(value)) {
391
- return this.resolve(
587
+ return CssIcssExportDependencyTemplate._doResolve(
392
588
  value[0],
393
589
  value[1],
394
590
  {
395
591
  ...templateContext,
396
592
  module
397
593
  },
594
+ value[2],
398
595
  seen
399
596
  );
400
597
  }
@@ -410,13 +607,65 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
410
607
  }
411
608
 
412
609
  /**
413
- * Resolves references.
610
+ * Finds the active `CssIcssImportDependency` for a given local name. When a
611
+ * `request` is provided the lookup also requires the import dependency's
612
+ * `request` to match — this lets references that appear between two
613
+ * `@value foo from "..."` declarations resolve through the import that was
614
+ * in scope at the reference site, rather than always picking the first.
615
+ * @param {Iterable<Dependency>} dependencies module dependencies to search
616
+ * @param {string} localName local name
617
+ * @param {string=} request user request of the `@value` import to match
618
+ * @returns {CssIcssImportDependency | undefined} matching import dep, if any
619
+ */
620
+ static findImportDep(dependencies, localName, request) {
621
+ /** @type {CssIcssImportDependency | undefined} */
622
+ let firstMatch;
623
+ for (const d of dependencies) {
624
+ if (d instanceof CssIcssImportDependency && d.localName === localName) {
625
+ if (request === undefined) return d;
626
+ if (d.request === request) return d;
627
+ if (firstMatch === undefined) firstMatch = d;
628
+ }
629
+ }
630
+ return firstMatch;
631
+ }
632
+
633
+ /**
634
+ * Resolves references. The top-level call (no `seen` argument) is
635
+ * memoized via `moduleGraph.cached`; recursive callers pass `seen` and
636
+ * bypass the cache to keep the cycle guard intact.
637
+ * @param {CssIcssExportDependency} dep value
638
+ * @param {DependencyTemplateContext} templateContext template context
639
+ * @param {Set<CssIcssExportDependency>=} seen to prevent cyclical problems
640
+ * @returns {string[]} final names
641
+ */
642
+ static resolveReferences(dep, templateContext, seen) {
643
+ if (seen !== undefined) {
644
+ return CssIcssExportDependencyTemplate._doResolveReferences(
645
+ dep,
646
+ templateContext,
647
+ seen
648
+ );
649
+ }
650
+ const { moduleGraph, module, chunkGraph, runtimeTemplate } =
651
+ templateContext;
652
+ return moduleGraph.cached(
653
+ computeResolveReferences,
654
+ dep,
655
+ /** @type {CssModule} */ (module),
656
+ chunkGraph,
657
+ runtimeTemplate
658
+ );
659
+ }
660
+
661
+ /**
662
+ * Inner recursive worker for `resolveReferences`. Not memoized.
414
663
  * @param {CssIcssExportDependency} dep value
415
664
  * @param {DependencyTemplateContext} templateContext template context
416
665
  * @param {Set<CssIcssExportDependency>} seen to prevent cyclical problems
417
666
  * @returns {string[]} final names
418
667
  */
419
- static resolveReferences(dep, templateContext, seen = new Set()) {
668
+ static _doResolveReferences(dep, templateContext, seen) {
420
669
  /** @type {string[]} */
421
670
  const references = [];
422
671
 
@@ -427,10 +676,10 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
427
676
  const importDep =
428
677
  /** @type {CssIcssImportDependency | undefined} */
429
678
  (
430
- templateContext.module.dependencies.find(
431
- (d) =>
432
- d instanceof CssIcssImportDependency &&
433
- d.localName === dep.value[0]
679
+ CssIcssExportDependencyTemplate.findImportDep(
680
+ templateContext.module.dependencies,
681
+ dep.value[0],
682
+ dep.value[2]
434
683
  )
435
684
  );
436
685
  if (!importDep) return references;
@@ -444,7 +693,7 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
444
693
  if (d instanceof CssIcssExportDependency && d.name === dep.value[1]) {
445
694
  if (Array.isArray(d.value)) {
446
695
  const deepReferences =
447
- CssIcssExportDependencyTemplate.resolveReferences(
696
+ CssIcssExportDependencyTemplate._doResolveReferences(
448
697
  d,
449
698
  {
450
699
  ...templateContext,
@@ -482,7 +731,7 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
482
731
  ) {
483
732
  if (Array.isArray(d.value)) {
484
733
  const deepReferences =
485
- CssIcssExportDependencyTemplate.resolveReferences(
734
+ CssIcssExportDependencyTemplate._doResolveReferences(
486
735
  d,
487
736
  templateContext,
488
737
  seen
@@ -506,7 +755,11 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
506
755
  }
507
756
 
508
757
  /**
509
- * Returns identifier.
758
+ * Returns identifier. When the dep opts into interpolation the full
759
+ * computation is memoized via `moduleGraph.cached` keyed by
760
+ * `(module, value, exportType, chunkGraph, runtimeTemplate)` so
761
+ * `cssExportConvention` / `getLocalIdent` / `escapeIdentifier` are not
762
+ * re-run for the same identifier during code generation.
510
763
  * @param {string} value value to identifier
511
764
  * @param {Dependency} dependency the dependency for which the template should be applied
512
765
  * @param {DependencyTemplateContext} templateContext the context object
@@ -514,36 +767,17 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
514
767
  */
515
768
  static getIdentifier(value, dependency, templateContext) {
516
769
  const dep = /** @type {CssIcssExportDependency} */ (dependency);
517
-
518
- if (dep.interpolate) {
519
- const { module: m } = templateContext;
520
- const module = /** @type {CssModule} */ (m);
521
- const generator = /** @type {CssGenerator} */ (module.generator);
522
- const local = cssExportConvention(
523
- value,
524
- /** @type {CssGeneratorExportsConvention} */
525
- (generator.options.exportsConvention)
526
- )[0];
527
- const prefix =
528
- dep.exportType === CssIcssExportDependency.EXPORT_TYPE.CUSTOM_VARIABLE
529
- ? "--"
530
- : "";
531
-
532
- return (
533
- prefix +
534
- getCssParser().escapeIdentifier(
535
- getLocalIdent(
536
- local,
537
- /** @type {CssModule} */
538
- (m),
539
- templateContext.chunkGraph,
540
- templateContext.runtimeTemplate
541
- )
542
- )
543
- );
544
- }
545
-
546
- return value;
770
+ if (!dep.interpolate) return value;
771
+ const { moduleGraph, module, chunkGraph, runtimeTemplate } =
772
+ templateContext;
773
+ return moduleGraph.cached(
774
+ computeInterpolatedIdentifier,
775
+ /** @type {CssModule} */ (module),
776
+ value,
777
+ dep.exportType,
778
+ chunkGraph,
779
+ runtimeTemplate
780
+ );
547
781
  }
548
782
 
549
783
  /**
@@ -577,7 +811,8 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
577
811
  const resolved = CssIcssExportDependencyTemplate.resolve(
578
812
  dep.value[0],
579
813
  dep.value[1],
580
- templateContext
814
+ templateContext,
815
+ dep.value[2]
581
816
  );
582
817
 
583
818
  // Fallback to the local name if not resolved
@@ -616,12 +851,29 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
616
851
  .filter(Boolean)
617
852
  );
618
853
  const allNames = new Set([...usedNames, ...names]);
619
- const unescaped = getCssParser().unescapeIdentifier(value);
854
+ const unescaped = getCssParser().unescapeIdentifier(
855
+ value,
856
+ templateContext.runtimeTemplate.compilation.compiler.root
857
+ );
620
858
 
859
+ const depLocStart =
860
+ dep.loc &&
861
+ /** @type {{ start?: { line: number, column: number } }} */ (dep.loc)
862
+ .start;
621
863
  for (const used of allNames) {
622
864
  if (dep.exportMode === CssIcssExportDependency.EXPORT_MODE.ONCE) {
623
865
  if (cssData.exports.has(used)) return;
624
866
  cssData.exports.set(used, unescaped);
867
+ if (
868
+ depLocStart &&
869
+ cssData.exportLocs &&
870
+ !cssData.exportLocs.has(used)
871
+ ) {
872
+ cssData.exportLocs.set(used, {
873
+ line: depLocStart.line,
874
+ column: depLocStart.column
875
+ });
876
+ }
625
877
  } else {
626
878
  const originalValue =
627
879
  dep.exportMode === CssIcssExportDependency.EXPORT_MODE.REPLACE
@@ -632,6 +884,19 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
632
884
  used,
633
885
  `${originalValue ? `${originalValue}${unescaped ? " " : ""}` : ""}${unescaped}`
634
886
  );
887
+ // Record the source location once per export (use the first
888
+ // occurrence — for APPEND/REPLACE this corresponds to the
889
+ // first selector seen, which is a reasonable anchor).
890
+ if (
891
+ depLocStart &&
892
+ cssData.exportLocs &&
893
+ !cssData.exportLocs.has(used)
894
+ ) {
895
+ cssData.exportLocs.set(used, {
896
+ line: depLocStart.line,
897
+ column: depLocStart.column
898
+ });
899
+ }
635
900
  }
636
901
  }
637
902
  } else if (
@@ -5,7 +5,8 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const WebpackError = require("../WebpackError");
8
+ const WebpackError = require("../errors/WebpackError");
9
+ const { cssExportConvention } = require("../util/conventions");
9
10
  const makeSerializable = require("../util/makeSerializable");
10
11
  const CssImportDependency = require("./CssImportDependency");
11
12
 
@@ -13,7 +14,8 @@ const CssImportDependency = require("./CssImportDependency");
13
14
  /** @typedef {import("../Dependency")} Dependency */
14
15
  /** @typedef {import("../DependencyTemplate").CssDependencyTemplateContext} DependencyTemplateContext */
15
16
  /** @typedef {import("../Module")} Module */
16
- /** @typedef {import("../CssModule")} CssModule */
17
+ /** @typedef {import("../css/CssGenerator")} CssGenerator */
18
+ /** @typedef {import("../css/CssModule")} CssModule */
17
19
  /** @typedef {import("../ModuleGraph")} ModuleGraph */
18
20
  /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
19
21
  /** @typedef {import("../javascript/JavascriptParser").Range} Range */
@@ -39,6 +41,26 @@ class CssIcssImportDependency extends CssImportDependency {
39
41
  super(request, range, mode);
40
42
  this.importName = importName;
41
43
  this.localName = localName;
44
+ /** @type {undefined | string[]} */
45
+ this._importNameConventionNames = undefined;
46
+ }
47
+
48
+ /**
49
+ * Memoized `cssExportConvention(this.importName, convention)`. The target
50
+ * module is fixed for a given dep, so its `exportsConvention` is fixed,
51
+ * so the convention-derived aliases of `importName` can be cached on the dep.
52
+ * @param {CssGeneratorExportsConvention} convention convention from the target module's generator
53
+ * @returns {string[]} convention results
54
+ */
55
+ getImportNameConventionNames(convention) {
56
+ if (this._importNameConventionNames) {
57
+ return this._importNameConventionNames;
58
+ }
59
+ this._importNameConventionNames = cssExportConvention(
60
+ this.importName,
61
+ convention
62
+ );
63
+ return this._importNameConventionNames;
42
64
  }
43
65
 
44
66
  get type() {
@@ -66,12 +88,32 @@ class CssIcssImportDependency extends CssImportDependency {
66
88
  * @returns {WebpackError[] | null | undefined} warnings
67
89
  */
68
90
  getWarnings(moduleGraph) {
69
- const module = moduleGraph.getModule(this);
91
+ const module = /** @type {CssModule | undefined} */ (
92
+ moduleGraph.getModule(this)
93
+ );
94
+
95
+ if (!module) return null;
96
+
97
+ // The target module stores exports under the names produced by its
98
+ // `exportsConvention`, so a raw `isExportProvided(this.importName)`
99
+ // would false-positive against `camel-case-only` / `dashes-only` (and
100
+ // any custom function that drops the original spelling). Expand
101
+ // `importName` through the *target* module's convention and accept
102
+ // if any alias is provided.
103
+ const generator =
104
+ /** @type {CssGenerator | undefined} */
105
+ (module.generator);
106
+ const convention =
107
+ generator &&
108
+ /** @type {CssGeneratorExportsConvention | undefined} */
109
+ (generator.options && generator.options.exportsConvention);
110
+ const exportsInfo = moduleGraph.getExportsInfo(module);
111
+ const names = convention
112
+ ? this.getImportNameConventionNames(convention)
113
+ : [this.importName];
114
+ const isProvided = names.some((name) => exportsInfo.isExportProvided(name));
70
115
 
71
- if (
72
- module &&
73
- !moduleGraph.getExportsInfo(module).isExportProvided(this.importName)
74
- ) {
116
+ if (!isProvided) {
75
117
  const error = new WebpackError(
76
118
  `Referenced name "${this.importName}" in "${this.userRequest}" not found`
77
119
  );