webpack 5.105.3 → 5.106.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/README.md +3 -6
  2. package/lib/BannerPlugin.js +13 -13
  3. package/lib/Chunk.js +25 -0
  4. package/lib/ChunkGraph.js +8 -4
  5. package/lib/CleanPlugin.js +23 -20
  6. package/lib/CompatibilityPlugin.js +1 -1
  7. package/lib/Compilation.js +36 -13
  8. package/lib/Compiler.js +59 -1
  9. package/lib/CssModule.js +17 -2
  10. package/lib/Dependency.js +1 -1
  11. package/lib/DllPlugin.js +17 -17
  12. package/lib/DllReferencePlugin.js +20 -18
  13. package/lib/DotenvPlugin.js +29 -27
  14. package/lib/ExternalModule.js +39 -6
  15. package/lib/FileSystemInfo.js +3 -1
  16. package/lib/IgnorePlugin.js +12 -11
  17. package/lib/LoaderOptionsPlugin.js +17 -15
  18. package/lib/ManifestPlugin.js +27 -25
  19. package/lib/Module.js +84 -4
  20. package/lib/ModuleGraph.js +3 -0
  21. package/lib/ModuleParseError.js +1 -1
  22. package/lib/ModuleTypeConstants.js +1 -1
  23. package/lib/MultiStats.js +5 -5
  24. package/lib/NormalModule.js +7 -3
  25. package/lib/NormalModuleFactory.js +20 -1
  26. package/lib/ProgressPlugin.js +39 -29
  27. package/lib/RuntimeGlobals.js +6 -0
  28. package/lib/RuntimeModule.js +18 -1
  29. package/lib/RuntimeTemplate.js +1 -1
  30. package/lib/SourceMapDevToolPlugin.js +13 -11
  31. package/lib/Stats.js +3 -2
  32. package/lib/TemplatedPathPlugin.js +4 -3
  33. package/lib/WatchIgnorePlugin.js +15 -13
  34. package/lib/WebpackOptionsApply.js +4 -4
  35. package/lib/asset/AssetModulesPlugin.js +50 -29
  36. package/lib/cli.js +3 -1
  37. package/lib/config/defaults.js +27 -13
  38. package/lib/config/normalization.js +3 -2
  39. package/lib/container/ContainerPlugin.js +46 -42
  40. package/lib/container/ContainerReferencePlugin.js +42 -26
  41. package/lib/container/FallbackModule.js +1 -1
  42. package/lib/container/ModuleFederationPlugin.js +17 -13
  43. package/lib/container/RemoteModule.js +18 -1
  44. package/lib/css/CssGenerator.js +315 -191
  45. package/lib/css/CssInjectStyleRuntimeModule.js +179 -0
  46. package/lib/css/CssLoadingRuntimeModule.js +1 -4
  47. package/lib/css/CssModulesPlugin.js +197 -98
  48. package/lib/css/CssParser.js +231 -134
  49. package/lib/css/walkCssTokens.js +115 -12
  50. package/lib/debug/ProfilingPlugin.js +16 -13
  51. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +20 -15
  52. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +4 -3
  53. package/lib/dependencies/CommonJsExportRequireDependency.js +4 -2
  54. package/lib/dependencies/CommonJsExportsDependency.js +1 -1
  55. package/lib/dependencies/CommonJsExportsParserPlugin.js +1 -1
  56. package/lib/dependencies/CommonJsFullRequireDependency.js +1 -1
  57. package/lib/dependencies/CommonJsImportsParserPlugin.js +63 -2
  58. package/lib/dependencies/CommonJsRequireContextDependency.js +21 -0
  59. package/lib/dependencies/CommonJsRequireDependency.js +42 -1
  60. package/lib/dependencies/CommonJsSelfReferenceDependency.js +1 -1
  61. package/lib/dependencies/ContextElementDependency.js +1 -1
  62. package/lib/dependencies/CreateRequireParserPlugin.js +11 -0
  63. package/lib/dependencies/CssIcssExportDependency.js +210 -87
  64. package/lib/dependencies/CssIcssImportDependency.js +13 -70
  65. package/lib/dependencies/CssIcssSymbolDependency.js +19 -30
  66. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +13 -2
  67. package/lib/dependencies/HarmonyExportExpressionDependency.js +28 -2
  68. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +13 -3
  69. package/lib/dependencies/HarmonyExportInitFragment.js +1 -1
  70. package/lib/dependencies/HarmonyImportDependency.js +21 -8
  71. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +124 -205
  72. package/lib/dependencies/HarmonyImportSideEffectDependency.js +12 -6
  73. package/lib/dependencies/HarmonyImportSpecifierDependency.js +13 -2
  74. package/lib/dependencies/ImportContextDependency.js +1 -1
  75. package/lib/dependencies/ImportDependency.js +16 -2
  76. package/lib/dependencies/ImportMetaPlugin.js +39 -29
  77. package/lib/dependencies/ImportParserPlugin.js +4 -5
  78. package/lib/dependencies/ImportPhase.js +65 -22
  79. package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +1 -1
  80. package/lib/esm/ModuleChunkFormatPlugin.js +1 -4
  81. package/lib/ids/HashedModuleIdsPlugin.js +21 -23
  82. package/lib/ids/OccurrenceChunkIdsPlugin.js +15 -11
  83. package/lib/ids/OccurrenceModuleIdsPlugin.js +15 -11
  84. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +1 -4
  85. package/lib/javascript/CommonJsChunkFormatPlugin.js +1 -4
  86. package/lib/javascript/EnableChunkLoadingPlugin.js +1 -2
  87. package/lib/javascript/JavascriptModulesPlugin.js +38 -12
  88. package/lib/javascript/JavascriptParser.js +5 -3
  89. package/lib/json/JsonModulesPlugin.js +28 -21
  90. package/lib/library/AssignLibraryPlugin.js +1 -1
  91. package/lib/library/ExportPropertyLibraryPlugin.js +1 -1
  92. package/lib/library/ModuleLibraryPlugin.js +35 -13
  93. package/lib/library/SystemLibraryPlugin.js +1 -1
  94. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +22 -0
  95. package/lib/optimize/AggressiveSplittingPlugin.js +18 -31
  96. package/lib/optimize/ConcatenatedModule.js +6 -2
  97. package/lib/optimize/InnerGraphPlugin.js +11 -5
  98. package/lib/optimize/LimitChunkCountPlugin.js +22 -18
  99. package/lib/optimize/MergeDuplicateChunksPlugin.js +15 -12
  100. package/lib/optimize/MinChunkSizePlugin.js +20 -16
  101. package/lib/optimize/ModuleConcatenationPlugin.js +4 -1
  102. package/lib/optimize/RemoveEmptyChunksPlugin.js +0 -1
  103. package/lib/rules/RuleSetCompiler.js +1 -0
  104. package/lib/schemes/HttpUriPlugin.js +20 -11
  105. package/lib/schemes/VirtualUrlPlugin.js +77 -30
  106. package/lib/serialization/FileMiddleware.js +7 -7
  107. package/lib/sharing/ConsumeSharedModule.js +18 -1
  108. package/lib/sharing/ConsumeSharedPlugin.js +32 -25
  109. package/lib/sharing/ProvideSharedPlugin.js +29 -25
  110. package/lib/util/AppendOnlyStackedSet.js +22 -1
  111. package/lib/util/{propertyName.js → property.js} +26 -1
  112. package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +148 -0
  113. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +54 -0
  114. package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +105 -0
  115. package/lib/wasm-async/AsyncWebAssemblyParser.js +30 -6
  116. package/lib/wasm-async/UniversalCompileAsyncWasmPlugin.js +26 -2
  117. package/lib/web/FetchCompileAsyncWasmPlugin.js +23 -0
  118. package/lib/web/JsonpTemplatePlugin.js +1 -0
  119. package/lib/webpack.js +34 -4
  120. package/package.json +20 -18
  121. package/schemas/WebpackOptions.check.js +1 -1
  122. package/schemas/WebpackOptions.json +82 -22
  123. package/schemas/plugins/css/CssModuleGeneratorOptions.check.js +1 -1
  124. package/schemas/plugins/css/CssModuleParserOptions.check.js +1 -1
  125. package/schemas/plugins/css/CssParserOptions.check.js +1 -1
  126. package/schemas/plugins/optimize/LimitChunkCountPlugin.json +1 -1
  127. package/schemas/plugins/schemes/VirtualUrlPlugin.check.js +1 -1
  128. package/schemas/plugins/schemes/VirtualUrlPlugin.json +8 -0
  129. package/types.d.ts +606 -150
  130. package/lib/util/create-schema-validation.js +0 -41
  131. package/lib/util/propertyAccess.js +0 -30
@@ -5,6 +5,7 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ const Dependency = require("../Dependency");
8
9
  const makeSerializable = require("../util/makeSerializable");
9
10
  const ContextDependency = require("./ContextDependency");
10
11
  const ContextDependencyTemplateAsRequireCall = require("./ContextDependencyTemplateAsRequireCall");
@@ -13,6 +14,10 @@ const ContextDependencyTemplateAsRequireCall = require("./ContextDependencyTempl
13
14
  /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
14
15
  /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
15
16
  /** @typedef {import("./ContextDependency").ContextDependencyOptions} ContextDependencyOptions */
17
+ /** @typedef {import("../Dependency").RawReferencedExports} RawReferencedExports */
18
+ /** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
19
+ /** @typedef {import("../ModuleGraph")} ModuleGraph */
20
+ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
16
21
 
17
22
  class CommonJsRequireContextDependency extends ContextDependency {
18
23
  /**
@@ -35,6 +40,22 @@ class CommonJsRequireContextDependency extends ContextDependency {
35
40
  return "cjs require context";
36
41
  }
37
42
 
43
+ /**
44
+ * Returns list of exports referenced by this dependency
45
+ * @param {ModuleGraph} moduleGraph module graph
46
+ * @param {RuntimeSpec} runtime the runtime for which the module is analysed
47
+ * @returns {ReferencedExports} referenced exports
48
+ */
49
+ getReferencedExports(moduleGraph, runtime) {
50
+ if (!this.options.referencedExports) {
51
+ return Dependency.EXPORTS_OBJECT_REFERENCED;
52
+ }
53
+ return this.options.referencedExports.map((name) => ({
54
+ name,
55
+ canMangle: false
56
+ }));
57
+ }
58
+
38
59
  /**
39
60
  * @param {ObjectSerializerContext} context context
40
61
  */
@@ -5,22 +5,31 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ const Dependency = require("../Dependency");
8
9
  const makeSerializable = require("../util/makeSerializable");
9
10
  const ModuleDependency = require("./ModuleDependency");
10
11
  const ModuleDependencyTemplateAsId = require("./ModuleDependencyTemplateAsId");
11
12
 
13
+ /** @typedef {import("../Dependency").RawReferencedExports} RawReferencedExports */
14
+ /** @typedef {import("../Dependency").ReferencedExports} ReferencedExports */
15
+ /** @typedef {import("../ModuleGraph")} ModuleGraph */
12
16
  /** @typedef {import("../javascript/JavascriptParser").Range} Range */
17
+ /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
18
+ /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
19
+ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
13
20
 
14
21
  class CommonJsRequireDependency extends ModuleDependency {
15
22
  /**
16
23
  * @param {string} request request
17
24
  * @param {Range=} range location in source code
18
25
  * @param {string=} context request context
26
+ * @param {RawReferencedExports | null=} referencedExports list of referenced exports
19
27
  */
20
- constructor(request, range, context) {
28
+ constructor(request, range, context, referencedExports = null) {
21
29
  super(request);
22
30
  this.range = range;
23
31
  this._context = context;
32
+ this.referencedExports = referencedExports;
24
33
  }
25
34
 
26
35
  get type() {
@@ -30,6 +39,38 @@ class CommonJsRequireDependency extends ModuleDependency {
30
39
  get category() {
31
40
  return "commonjs";
32
41
  }
42
+
43
+ /**
44
+ * Returns list of exports referenced by this dependency
45
+ * @param {ModuleGraph} moduleGraph module graph
46
+ * @param {RuntimeSpec} runtime the runtime for which the module is analysed
47
+ * @returns {ReferencedExports} referenced exports
48
+ */
49
+ getReferencedExports(moduleGraph, runtime) {
50
+ if (!this.referencedExports) return Dependency.EXPORTS_OBJECT_REFERENCED;
51
+ return this.referencedExports.map((name) => ({
52
+ name,
53
+ canMangle: false
54
+ }));
55
+ }
56
+
57
+ /**
58
+ * @param {ObjectSerializerContext} context context
59
+ */
60
+ serialize(context) {
61
+ const { write } = context;
62
+ write(this.referencedExports);
63
+ super.serialize(context);
64
+ }
65
+
66
+ /**
67
+ * @param {ObjectDeserializerContext} context context
68
+ */
69
+ deserialize(context) {
70
+ const { read } = context;
71
+ this.referencedExports = read();
72
+ super.deserialize(context);
73
+ }
33
74
  }
34
75
 
35
76
  CommonJsRequireDependency.Template = ModuleDependencyTemplateAsId;
@@ -8,7 +8,7 @@
8
8
  const RuntimeGlobals = require("../RuntimeGlobals");
9
9
  const { equals } = require("../util/ArrayHelpers");
10
10
  const makeSerializable = require("../util/makeSerializable");
11
- const propertyAccess = require("../util/propertyAccess");
11
+ const { propertyAccess } = require("../util/property");
12
12
  const NullDependency = require("./NullDependency");
13
13
 
14
14
  /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
@@ -69,7 +69,7 @@ class ContextElementDependency extends ModuleDependency {
69
69
  getResourceIdentifier() {
70
70
  let str = super.getResourceIdentifier();
71
71
  if (this.attributes) {
72
- str += `|importAttributes${JSON.stringify(this.attributes)}`;
72
+ str += `|attributes${JSON.stringify(this.attributes)}`;
73
73
  }
74
74
  return str;
75
75
  }
@@ -328,6 +328,17 @@ class CreateRequireParserPlugin {
328
328
  return processResolve(expr, false);
329
329
  }
330
330
  });
331
+ parser.hooks.expression
332
+ .for(createRequireSpecifierTag)
333
+ .tap(PLUGIN_NAME, (expr) => {
334
+ const clearDep = new ConstDependency(
335
+ "/* createRequire */ undefined",
336
+ /** @type {Range} */ (expr.range)
337
+ );
338
+ clearDep.loc = /** @type {DependencyLocation} */ (expr.loc);
339
+ parser.state.module.addPresentationalDependency(clearDep);
340
+ return true;
341
+ });
331
342
  parser.hooks.call
332
343
  .for(createRequireSpecifierTag)
333
344
  .tap(PLUGIN_NAME, (expr) => {
@@ -6,6 +6,7 @@
6
6
  "use strict";
7
7
 
8
8
  const { CSS_TYPE, JAVASCRIPT_TYPE } = require("../ModuleSourceTypeConstants");
9
+ const { interpolate } = require("../TemplatedPathPlugin");
9
10
  const WebpackError = require("../WebpackError");
10
11
  const { cssExportConvention } = require("../util/conventions");
11
12
  const createHash = require("../util/createHash");
@@ -19,6 +20,7 @@ const NullDependency = require("./NullDependency");
19
20
  const getCssParser = memoize(() => require("../css/CssParser"));
20
21
 
21
22
  /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
23
+ /** @typedef {import("../../declarations/WebpackOptions").HashFunction} HashFunction */
22
24
  /** @typedef {import("../../declarations/WebpackOptions").CssGeneratorExportsConvention} CssGeneratorExportsConvention */
23
25
  /** @typedef {import("../../declarations/WebpackOptions").CssGeneratorLocalIdentName} CssGeneratorLocalIdentName */
24
26
  /** @typedef {import("../CssModule")} CssModule */
@@ -62,13 +64,18 @@ const getLocalIdent = (local, module, chunkGraph, runtimeTemplate) => {
62
64
 
63
65
  let localIdentHash = "";
64
66
 
65
- if (/\[(?:fullhash|hash)\]/.test(localIdentName)) {
67
+ if (
68
+ typeof localIdentName === "function" ||
69
+ /\[(?:fullhash|hash)\]/.test(localIdentName)
70
+ ) {
66
71
  const hashSalt = generator.options.localIdentHashSalt;
67
72
  const hashDigest =
68
73
  /** @type {string} */
69
74
  (generator.options.localIdentHashDigest);
70
75
  const hashDigestLength = generator.options.localIdentHashDigestLength;
71
- const { hashFunction } = runtimeTemplate.outputOptions;
76
+ const hashFunction =
77
+ /** @type {HashFunction} */
78
+ (generator.options.localIdentHashFunction);
72
79
 
73
80
  const hash = createHash(hashFunction);
74
81
 
@@ -88,7 +95,10 @@ const getLocalIdent = (local, module, chunkGraph, runtimeTemplate) => {
88
95
 
89
96
  let contentHash = "";
90
97
 
91
- if (/\[contenthash\]/.test(localIdentName)) {
98
+ if (
99
+ typeof localIdentName === "function" ||
100
+ /\[contenthash\]/.test(localIdentName)
101
+ ) {
92
102
  const hash = createHash(runtimeTemplate.outputOptions.hashFunction);
93
103
  const source = module.originalSource();
94
104
 
@@ -110,26 +120,32 @@ const getLocalIdent = (local, module, chunkGraph, runtimeTemplate) => {
110
120
  );
111
121
  }
112
122
 
113
- let localIdent = runtimeTemplate.compilation.getPath(localIdentName, {
123
+ let localIdent = interpolate(localIdentName, {
114
124
  prepareId: (id) => {
115
125
  if (typeof id !== "string") return id;
116
126
 
117
- return id
118
- .replace(/^([.-]|[^a-z0-9_-])+/i, "")
119
- .replace(/[^a-z0-9_-]+/gi, "_");
127
+ return (
128
+ id
129
+ .replace(/^([.-]|[^a-z0-9_-])+/i, "")
130
+ // We keep the `@` symbol because it can be used in the package name (e.g. `@company/package`), and if we replace it with `_`, a class conflict may occur.
131
+ // For example - `@import "@foo/package/style.module.css"` and `@import "foo/package/style.module.css"` (`foo` is a package, `package` is just a directory) will create a class conflict.
132
+ .replace(/[^a-z0-9@_-]+/gi, "_")
133
+ );
120
134
  },
121
135
  filename: relativeResourcePath,
122
136
  hash: localIdentHash,
137
+ local,
123
138
  contentHash,
124
139
  chunkGraph,
125
140
  module
126
141
  });
127
142
 
128
- if (/\[local\]/.test(localIdentName)) {
143
+ // TODO move these things into interpolate
144
+ if (/\[local\]/.test(localIdent)) {
129
145
  localIdent = localIdent.replace(/\[local\]/g, local);
130
146
  }
131
147
 
132
- if (/\[uniqueName\]/.test(localIdentName)) {
148
+ if (/\[uniqueName\]/.test(localIdent)) {
133
149
  localIdent = localIdent.replace(
134
150
  /\[uniqueName\]/g,
135
151
  /** @type {string} */ (uniqueName)
@@ -140,10 +156,12 @@ const getLocalIdent = (local, module, chunkGraph, runtimeTemplate) => {
140
156
  return localIdent.replace(/^((-?\d)|--)/, "_$1");
141
157
  };
142
158
 
159
+ /** @typedef {string | [string, string]} Value */
160
+
143
161
  // 0 - replace, 1 - replace, 2 - append, 2 - once
144
162
  /** @typedef {0 | 1 | 2 | 3 | 4} ExportMode */
145
- // 0 - normal, 1 - custom css variable, 2 - grid custom ident
146
- /** @typedef {0 | 1 | 2} ExportType */
163
+ // 0 - normal, 1 - custom css variable, 2 - grid custom ident, 3 - composes
164
+ /** @typedef {0 | 1 | 2 | 3} ExportType */
147
165
 
148
166
  class CssIcssExportDependency extends NullDependency {
149
167
  /**
@@ -151,7 +169,7 @@ class CssIcssExportDependency extends NullDependency {
151
169
  *
152
170
  * :export { LOCAL_NAME: EXPORT_NAME }
153
171
  * @param {string} name export name
154
- * @param {string | [string, string, boolean]} value export value or true when we need interpolate name as a value
172
+ * @param {Value} value value or local name and import name
155
173
  * @param {Range=} range range
156
174
  * @param {boolean=} interpolate true when value need to be interpolated, otherwise false
157
175
  * @param {ExportMode=} exportMode export mode
@@ -234,11 +252,9 @@ class CssIcssExportDependency extends NullDependency {
234
252
  /** @type {CssGeneratorExportsConvention} */
235
253
  (generator.options.exportsConvention)
236
254
  );
255
+
237
256
  return {
238
- exports: [
239
- ...names,
240
- ...(Array.isArray(this.value) ? [this.value[1]] : [])
241
- ].map((name) => ({
257
+ exports: [...names].map((name) => ({
242
258
  name,
243
259
  canMangle: true
244
260
  })),
@@ -330,45 +346,157 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
330
346
  ) {
331
347
  // TODO looking how to cache
332
348
  /**
333
- * @param {string} symbol the name of symbol
349
+ * @param {string} localName local name
350
+ * @param {string} importName import name
334
351
  * @param {DependencyTemplateContext} templateContext the context object
352
+ * @param {Set<CssIcssExportDependency>} seen seen to prevent cyclical problems
335
353
  * @returns {string | undefined} found reference
336
354
  */
337
- static findReference(symbol, templateContext) {
338
- for (const item of templateContext.module.dependencies) {
339
- if (item instanceof CssIcssImportDependency) {
340
- // Looking for the referring module
341
- const module = templateContext.moduleGraph.getModule(item);
342
-
343
- if (!module) {
344
- return undefined;
345
- }
355
+ static resolve(localName, importName, templateContext, seen = new Set()) {
356
+ const { moduleGraph } = templateContext;
357
+ const importDep =
358
+ /** @type {CssIcssImportDependency | undefined} */
359
+ (
360
+ templateContext.module.dependencies.find(
361
+ (d) =>
362
+ d instanceof CssIcssImportDependency && d.localName === localName
363
+ )
364
+ );
365
+ if (!importDep) return undefined;
346
366
 
347
- for (let i = module.dependencies.length - 1; i >= 0; i--) {
348
- const nestedDep = module.dependencies[i];
349
- if (
350
- nestedDep instanceof CssIcssExportDependency &&
351
- symbol === nestedDep.name
352
- ) {
353
- if (Array.isArray(nestedDep.value)) {
354
- return this.findReference(nestedDep.value[1], {
355
- ...templateContext,
356
- module
357
- });
358
- }
367
+ const module = /** @type {CssModule} */ (moduleGraph.getModule(importDep));
368
+ if (!module) return undefined;
369
+
370
+ const exportDep =
371
+ /** @type {CssIcssExportDependency} */
372
+ (
373
+ module.dependencies.find(
374
+ (d) => d instanceof CssIcssExportDependency && d.name === importName
375
+ )
376
+ );
377
+
378
+ if (!exportDep) return undefined;
359
379
 
360
- return CssIcssExportDependency.Template.getIdentifier(
361
- nestedDep.value,
362
- nestedDep,
363
- {
380
+ if (seen.has(exportDep)) return undefined;
381
+ seen.add(exportDep);
382
+
383
+ const { value, interpolate } = exportDep;
384
+
385
+ if (Array.isArray(value)) {
386
+ return this.resolve(
387
+ value[0],
388
+ value[1],
389
+ {
390
+ ...templateContext,
391
+ module
392
+ },
393
+ seen
394
+ );
395
+ }
396
+
397
+ if (interpolate) {
398
+ return CssIcssExportDependency.Template.getIdentifier(value, exportDep, {
399
+ ...templateContext,
400
+ module
401
+ });
402
+ }
403
+
404
+ return value;
405
+ }
406
+
407
+ /**
408
+ * @param {CssIcssExportDependency} dep value
409
+ * @param {DependencyTemplateContext} templateContext template context
410
+ * @param {Set<CssIcssExportDependency>} seen to prevent cyclical problems
411
+ * @returns {string[]} final names
412
+ */
413
+ static resolveReferences(dep, templateContext, seen = new Set()) {
414
+ /** @type {string[]} */
415
+ const references = [];
416
+
417
+ if (seen.has(dep)) return references;
418
+ seen.add(dep);
419
+
420
+ if (Array.isArray(dep.value)) {
421
+ const importDep =
422
+ /** @type {CssIcssImportDependency | undefined} */
423
+ (
424
+ templateContext.module.dependencies.find(
425
+ (d) =>
426
+ d instanceof CssIcssImportDependency &&
427
+ d.localName === dep.value[0]
428
+ )
429
+ );
430
+ if (!importDep) return references;
431
+
432
+ const module =
433
+ /** @type {CssModule} */
434
+ (templateContext.moduleGraph.getModule(importDep));
435
+ if (!module) return references;
436
+
437
+ for (const d of module.dependencies) {
438
+ if (d instanceof CssIcssExportDependency && d.name === dep.value[1]) {
439
+ if (Array.isArray(d.value)) {
440
+ const deepReferences =
441
+ CssIcssExportDependencyTemplate.resolveReferences(
442
+ d,
443
+ {
444
+ ...templateContext,
445
+ module
446
+ },
447
+ seen
448
+ );
449
+
450
+ references.push(...deepReferences);
451
+ } else {
452
+ references.push(
453
+ CssIcssExportDependencyTemplate.getIdentifier(d.value, d, {
364
454
  ...templateContext,
365
455
  module
366
- }
456
+ })
457
+ );
458
+ }
459
+ }
460
+ }
461
+ } else {
462
+ // Adding basic class
463
+ references.push(
464
+ CssIcssExportDependencyTemplate.getIdentifier(
465
+ dep.value,
466
+ dep,
467
+ templateContext
468
+ )
469
+ );
470
+
471
+ for (const d of templateContext.module.dependencies) {
472
+ if (
473
+ d instanceof CssIcssExportDependency &&
474
+ d.exportType === CssIcssExportDependency.EXPORT_TYPE.COMPOSES &&
475
+ d.name === dep.value
476
+ ) {
477
+ if (Array.isArray(d.value)) {
478
+ const deepReferences =
479
+ CssIcssExportDependencyTemplate.resolveReferences(
480
+ d,
481
+ templateContext,
482
+ seen
483
+ );
484
+
485
+ references.push(...deepReferences);
486
+ } else {
487
+ references.push(
488
+ CssIcssExportDependencyTemplate.getIdentifier(
489
+ d.value,
490
+ d,
491
+ templateContext
492
+ )
367
493
  );
368
494
  }
369
495
  }
370
496
  }
371
497
  }
498
+
499
+ return [...new Set(references)];
372
500
  }
373
501
 
374
502
  /**
@@ -400,7 +528,7 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
400
528
  getLocalIdent(
401
529
  local,
402
530
  /** @type {CssModule} */
403
- (templateContext.module),
531
+ (m),
404
532
  templateContext.chunkGraph,
405
533
  templateContext.runtimeTemplate
406
534
  )
@@ -408,7 +536,7 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
408
536
  );
409
537
  }
410
538
 
411
- return /** @type {string} */ (dep.value);
539
+ return value;
412
540
  }
413
541
 
414
542
  /**
@@ -420,46 +548,35 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
420
548
  apply(dependency, source, templateContext) {
421
549
  const dep = /** @type {CssIcssExportDependency} */ (dependency);
422
550
  if (!dep.range && templateContext.type !== JAVASCRIPT_TYPE) return;
423
- const { cssData } = templateContext;
424
- const { module: m, moduleGraph, runtime } = templateContext;
551
+ const { module: m, moduleGraph, runtime, cssData } = templateContext;
425
552
  const module = /** @type {CssModule} */ (m);
426
553
  const generator = /** @type {CssGenerator} */ (module.generator);
427
- const names = dep.getExportsConventionNames(
428
- dep.name,
429
- /** @type {CssGeneratorExportsConvention} */
430
- (generator.options.exportsConvention)
431
- );
432
- const usedNames =
433
- /** @type {string[]} */
434
- (
435
- names
436
- .map((name) =>
437
- moduleGraph.getExportInfo(module, name).getUsedName(name, runtime)
438
- )
439
- .filter(Boolean)
440
- );
441
-
442
- const allNames = new Set([...usedNames, ...names]);
443
554
  const isReference = Array.isArray(dep.value);
444
555
 
445
556
  /** @type {string} */
446
557
  let value;
447
558
 
448
- if (isReference && dep.value[2] === true) {
449
- const resolved = CssIcssExportDependencyTemplate.findReference(
559
+ // The `composes` has more complex logic for collecting all the classes
560
+ if (
561
+ dep.exportType === CssIcssExportDependency.EXPORT_TYPE.COMPOSES &&
562
+ templateContext.type === JAVASCRIPT_TYPE
563
+ ) {
564
+ value = CssIcssExportDependencyTemplate.resolveReferences(
565
+ dep,
566
+ templateContext
567
+ ).join(" ");
568
+ } else if (isReference) {
569
+ const resolved = CssIcssExportDependencyTemplate.resolve(
570
+ dep.value[0],
450
571
  dep.value[1],
451
572
  templateContext
452
573
  );
453
574
 
454
- // Fallback to the original name if not found
575
+ // Fallback to the local name if not resolved
455
576
  value = resolved || dep.value[0];
456
577
  } else {
457
- value = isReference ? dep.value[1] : /** @type {string} */ (dep.value);
458
- }
459
-
460
- if (dep.interpolate) {
461
578
  value = CssIcssExportDependencyTemplate.getIdentifier(
462
- value,
579
+ /** @type {string} */ (dep.value),
463
580
  dep,
464
581
  templateContext
465
582
  );
@@ -476,31 +593,36 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
476
593
  templateContext.type === JAVASCRIPT_TYPE &&
477
594
  dep.exportMode !== CssIcssExportDependency.EXPORT_MODE.NONE
478
595
  ) {
596
+ const names = dep.getExportsConventionNames(
597
+ dep.name,
598
+ /** @type {CssGeneratorExportsConvention} */
599
+ (generator.options.exportsConvention)
600
+ );
601
+ const usedNames =
602
+ /** @type {string[]} */
603
+ (
604
+ names
605
+ .map((name) =>
606
+ moduleGraph.getExportInfo(module, name).getUsedName(name, runtime)
607
+ )
608
+ .filter(Boolean)
609
+ );
610
+ const allNames = new Set([...usedNames, ...names]);
611
+ const unescaped = getCssParser().unescapeIdentifier(value);
612
+
479
613
  for (const used of allNames) {
480
614
  if (dep.exportMode === CssIcssExportDependency.EXPORT_MODE.ONCE) {
481
- const newValue = getCssParser().unescapeIdentifier(value);
482
- if (isReference) {
483
- cssData.exports.set(dep.value[1], newValue);
484
- }
485
615
  if (cssData.exports.has(used)) return;
486
- cssData.exports.set(used, newValue);
616
+ cssData.exports.set(used, unescaped);
487
617
  } else {
488
618
  const originalValue =
489
619
  dep.exportMode === CssIcssExportDependency.EXPORT_MODE.REPLACE
490
620
  ? undefined
491
621
  : cssData.exports.get(used);
492
622
 
493
- const newValue =
494
- dep.exportMode ===
495
- CssIcssExportDependency.EXPORT_MODE.SELF_REFERENCE
496
- ? cssData.exports.get(
497
- isReference ? dep.value[0] : /** @type {string} */ (dep.value)
498
- ) || value
499
- : getCssParser().unescapeIdentifier(value);
500
-
501
623
  cssData.exports.set(
502
624
  used,
503
- `${originalValue ? `${originalValue}${newValue ? " " : ""}` : ""}${newValue}`
625
+ `${originalValue ? `${originalValue}${unescaped ? " " : ""}` : ""}${unescaped}`
504
626
  );
505
627
  }
506
628
  }
@@ -524,11 +646,12 @@ CssIcssExportDependency.EXPORT_MODE = {
524
646
  SELF_REFERENCE: 4
525
647
  };
526
648
 
527
- /** @type {Record<"NORMAL" | "CUSTOM_VARIABLE" | "GRID_CUSTOM_IDENTIFIER", ExportType>} */
649
+ /** @type {Record<"NORMAL" | "CUSTOM_VARIABLE" | "GRID_CUSTOM_IDENTIFIER" | "COMPOSES", ExportType>} */
528
650
  CssIcssExportDependency.EXPORT_TYPE = {
529
651
  NORMAL: 0,
530
652
  CUSTOM_VARIABLE: 1,
531
- GRID_CUSTOM_IDENTIFIER: 2
653
+ GRID_CUSTOM_IDENTIFIER: 2,
654
+ COMPOSES: 3
532
655
  };
533
656
 
534
657
  makeSerializable(