webpack 5.110.3 → 5.111.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 (208) hide show
  1. package/README.md +5 -0
  2. package/lib/APIPlugin.js +23 -7
  3. package/lib/AutomaticPrefetchPlugin.js +1 -1
  4. package/lib/Cache.js +8 -3
  5. package/lib/CacheFacade.js +1 -1
  6. package/lib/CircularModulesPlugin.js +157 -55
  7. package/lib/CleanPlugin.js +2 -2
  8. package/lib/Compilation.js +320 -302
  9. package/lib/Compiler.js +209 -46
  10. package/lib/ContextModule.js +17 -81
  11. package/lib/ContextModuleFactory.js +1 -1
  12. package/lib/CopyPlugin.js +1054 -0
  13. package/lib/DefinePlugin.js +24 -8
  14. package/lib/ExternalModule.js +41 -14
  15. package/lib/FileSystemInfo.js +17 -14
  16. package/lib/FlagDependencyExportsPlugin.js +45 -21
  17. package/lib/HotModuleReplacementPlugin.js +53 -7
  18. package/lib/JavascriptMetaInfoPlugin.js +5 -3
  19. package/lib/MainTemplate.js +5 -1
  20. package/lib/Module.js +16 -7
  21. package/lib/MultiCompiler.js +1 -1
  22. package/lib/MultiWatching.js +1 -1
  23. package/lib/NormalModule.js +45 -12
  24. package/lib/NormalModuleFactory.js +1 -1
  25. package/lib/RuntimeGlobals.js +21 -7
  26. package/lib/RuntimeModule.js +28 -12
  27. package/lib/RuntimePlugin.js +30 -3
  28. package/lib/RuntimeTemplate.js +780 -475
  29. package/lib/SourceMapDevToolPlugin.js +1 -1
  30. package/lib/Watching.js +9 -0
  31. package/lib/WebpackOptionsApply.js +84 -91
  32. package/lib/asset/AssetGenerator.js +25 -8
  33. package/lib/asset/AssetModule.js +3 -0
  34. package/lib/asset/WebManifestParser.js +7 -5
  35. package/lib/cache/AddBuildDependenciesPlugin.js +33 -4
  36. package/lib/cache/IdleFileCachePlugin.js +2 -2
  37. package/lib/cache/PackFileCacheStrategy.js +14 -1
  38. package/lib/config/browserslistTargetHandler.js +19 -0
  39. package/lib/config/defaults.js +86 -50
  40. package/lib/config/normalization.js +82 -12
  41. package/lib/config/target.js +10 -0
  42. package/lib/container/ContainerReferencePlugin.js +6 -0
  43. package/lib/container/RemoteRuntimeModule.js +9 -0
  44. package/lib/container/declaredRemotes.js +39 -0
  45. package/lib/css/CssGenerator.js +8 -0
  46. package/lib/css/CssInjectStyleRuntimeModule.js +9 -0
  47. package/lib/css/CssLoadingRuntimeModule.js +94 -36
  48. package/lib/css/CssModule.js +1 -1
  49. package/lib/css/CssModulesPlugin.js +7 -6
  50. package/lib/css/CssParser.js +144 -11
  51. package/lib/css/CssServerStylesRuntimeModule.js +9 -0
  52. package/lib/css/cssMinify.js +11 -3
  53. package/lib/css/data.js +2814 -678
  54. package/lib/css/syntax.js +4082 -248
  55. package/lib/debug/ProfilingPlugin.js +4 -0
  56. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +6 -3
  57. package/lib/dependencies/AMDRuntimeModules.js +18 -0
  58. package/lib/dependencies/CommonJsExportRequireDependency.js +3 -1
  59. package/lib/dependencies/CommonJsExportsParserPlugin.js +12 -13
  60. package/lib/dependencies/CommonJsImportsParserPlugin.js +1 -0
  61. package/lib/dependencies/CommonJsPlugin.js +19 -3
  62. package/lib/dependencies/CommonJsRequireDependency.js +14 -5
  63. package/lib/dependencies/CssIcssExportDependency.js +7 -1
  64. package/lib/dependencies/HarmonyCompatibilityDependency.js +58 -4
  65. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +8 -3
  66. package/lib/dependencies/HarmonyExportExpressionDependency.js +44 -29
  67. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +71 -13
  68. package/lib/dependencies/HarmonyExportInitFragment.js +99 -19
  69. package/lib/dependencies/HarmonyExportSpecifierDependency.js +18 -30
  70. package/lib/dependencies/HarmonyImportBareSideEffectDependency.js +59 -0
  71. package/lib/dependencies/HarmonyImportDependency.js +6 -1
  72. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +8 -1
  73. package/lib/dependencies/HarmonyImportSpecifierDependency.js +24 -1
  74. package/lib/dependencies/HarmonyModulesPlugin.js +20 -0
  75. package/lib/dependencies/HtmlEntryDependency.js +50 -0
  76. package/lib/dependencies/ImportMetaMainDependency.js +104 -0
  77. package/lib/dependencies/ImportMetaPlugin.js +59 -15
  78. package/lib/dependencies/SystemRuntimeModule.js +9 -0
  79. package/lib/dependencies/WorkerDependency.js +1 -2
  80. package/lib/dependencies/WorkletDependency.js +1 -2
  81. package/lib/dll/DelegatedModule.js +18 -1
  82. package/lib/dll/DllReferencePlugin.js +11 -8
  83. package/lib/dll/LibManifestPlugin.js +1 -1
  84. package/lib/errors/AnalyzableBailoutsWarning.js +41 -0
  85. package/lib/errors/DuplicateModulesWarning.js +12 -7
  86. package/lib/errors/EmptyCopyPatternWarning.js +26 -0
  87. package/lib/errors/ExternalStarReexportError.js +44 -0
  88. package/lib/errors/MissingSourceMapsWarning.js +36 -0
  89. package/lib/errors/ModuleParseError.js +2 -1
  90. package/lib/errors/UnusedAssetsWarning.js +36 -0
  91. package/lib/errors/UnusedFederationWarning.js +35 -0
  92. package/lib/errors/UnusedModulesWarning.js +38 -0
  93. package/lib/esm/ExportWebpackRequireRuntimeModule.js +9 -0
  94. package/lib/esm/ModuleChunkFormatPlugin.js +28 -3
  95. package/lib/esm/ModuleChunkLoadingPlugin.js +30 -11
  96. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +92 -60
  97. package/lib/hmr/HotModuleReplacement.runtime.js +8 -2
  98. package/lib/hmr/HotModuleReplacementRuntimeModule.js +9 -0
  99. package/lib/html/HtmlGenerator.js +11 -5
  100. package/lib/html/HtmlModulesPlugin.js +331 -62
  101. package/lib/html/HtmlParser.js +13 -6
  102. package/lib/html/builtinEmbeddedRenderer.js +107 -0
  103. package/lib/html/data.js +121 -7
  104. package/lib/html/htmlMinify.js +84 -113
  105. package/lib/html/syntax.js +763 -426
  106. package/lib/ids/HashedModuleIdsPlugin.js +2 -1
  107. package/lib/index.js +3 -0
  108. package/lib/javascript/JavascriptModule.js +1 -0
  109. package/lib/javascript/JavascriptModulesPlugin.js +52 -24
  110. package/lib/javascript/JavascriptParser.js +1255 -728
  111. package/lib/javascript/StartupHelpers.js +27 -3
  112. package/lib/javascript/data.js +172 -0
  113. package/lib/javascript/grammar.js +5546 -0
  114. package/lib/javascript/parser.js +1494 -0
  115. package/lib/javascript/regexp.js +1762 -0
  116. package/lib/javascript/regexpData.js +51 -0
  117. package/lib/javascript/syntax.js +8696 -5225
  118. package/lib/library/ModuleLibraryPlugin.js +116 -5
  119. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +22 -0
  120. package/lib/node/RequireChunkLoadingRuntimeModule.js +22 -0
  121. package/lib/optimize/ConcatenatedModule.js +97 -20
  122. package/lib/optimize/ConstExportsPlugin.js +50 -39
  123. package/lib/optimize/InlineExports.js +20 -123
  124. package/lib/optimize/MangleExportsPlugin.js +10 -0
  125. package/lib/optimize/ModuleConcatenationPlugin.js +24 -1
  126. package/lib/optimize/RealContentHashPlugin.js +68 -9
  127. package/lib/optimize/SideEffectsFlagPlugin.js +17 -9
  128. package/lib/performance/AnalyzableBailoutsPlugin.js +115 -0
  129. package/lib/performance/CacheEffectivenessPlugin.js +4 -3
  130. package/lib/performance/DuplicateModulesPlugin.js +57 -13
  131. package/lib/performance/EvalUsagePlugin.js +5 -2
  132. package/lib/performance/MissingSourceMapsPlugin.js +115 -0
  133. package/lib/performance/PureAnnotationsPlugin.js +6 -3
  134. package/lib/performance/TopLevelThisPlugin.js +5 -4
  135. package/lib/performance/UnusedAssetsPlugin.js +109 -0
  136. package/lib/performance/UnusedFederationPlugin.js +147 -0
  137. package/lib/performance/UnusedModulesPlugin.js +141 -0
  138. package/lib/performance/UnusedReexportsPlugin.js +1 -55
  139. package/lib/performance/isOnlyReexported.js +65 -0
  140. package/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js +25 -5
  141. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +2 -0
  142. package/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js +9 -0
  143. package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +9 -0
  144. package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +9 -0
  145. package/lib/prefetch/ResourceHintPlugin.js +1 -2
  146. package/lib/prefetch/ResourceHintRuntimeModule.js +9 -0
  147. package/lib/prefetch/StartupAssetHintRuntimeModule.js +9 -0
  148. package/lib/rules/RuleSetCompiler.js +211 -4
  149. package/lib/runtime/AsyncModuleRuntimeModule.js +100 -66
  150. package/lib/runtime/AutoPublicPathRuntimeModule.js +9 -0
  151. package/lib/runtime/BaseUriRuntimeModule.js +9 -0
  152. package/lib/runtime/ChunkNameRuntimeModule.js +9 -0
  153. package/lib/runtime/EnsureChunkRuntimeModule.js +35 -16
  154. package/lib/runtime/GetChunkFilenameRuntimeModule.js +9 -0
  155. package/lib/runtime/GetFullHashRuntimeModule.js +9 -0
  156. package/lib/runtime/GetMainFilenameRuntimeModule.js +9 -0
  157. package/lib/runtime/GetWorkletBootstrapRuntimeModule.js +9 -0
  158. package/lib/runtime/GlobalRuntimeModule.js +9 -0
  159. package/lib/runtime/HasOwnPropertyRuntimeModule.js +9 -0
  160. package/lib/runtime/HelperRuntimeModule.js +10 -0
  161. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +330 -219
  162. package/lib/runtime/NonceRuntimeModule.js +9 -0
  163. package/lib/runtime/OnChunksLoadedRuntimeModule.js +67 -20
  164. package/lib/runtime/PublicPathRuntimeModule.js +9 -0
  165. package/lib/runtime/RuntimeIdRuntimeModule.js +9 -0
  166. package/lib/runtime/SpecNamespaceObjectRuntimeModule.js +90 -0
  167. package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +9 -0
  168. package/lib/runtime/StartupEntrypointRuntimeModule.js +9 -0
  169. package/lib/runtime/SystemContextRuntimeModule.js +9 -0
  170. package/lib/runtime/ToBinaryRuntimeModule.js +9 -0
  171. package/lib/serialization/ObjectMiddleware.js +138 -106
  172. package/lib/sharing/ConsumeSharedPlugin.js +12 -0
  173. package/lib/sharing/ConsumeSharedRuntimeModule.js +11 -0
  174. package/lib/sharing/ShareRuntimeModule.js +9 -0
  175. package/lib/sharing/declaredShared.js +47 -0
  176. package/lib/stats/DefaultStatsFactoryPlugin.js +3 -1
  177. package/lib/stats/DefaultStatsPrinterPlugin.js +3 -0
  178. package/lib/util/SourceProcessor.js +76 -69
  179. package/lib/util/async.js +292 -0
  180. package/lib/util/buildDiagnostics.js +69 -0
  181. package/lib/util/fs.js +27 -1
  182. package/lib/util/handlerKeys.js +40 -0
  183. package/lib/util/identifier.js +20 -0
  184. package/lib/util/internalSerializables.js +4 -0
  185. package/lib/util/registerExternalSerializer.js +6 -45
  186. package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +9 -0
  187. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +9 -0
  188. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +9 -0
  189. package/lib/web/JsonpChunkLoadingRuntimeModule.js +36 -0
  190. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +19 -0
  191. package/package.json +22 -16
  192. package/schemas/WebpackOptions.check.js +1 -1
  193. package/schemas/WebpackOptions.json +379 -66
  194. package/schemas/plugins/LoaderOptionsPlugin.check.js +1 -1
  195. package/schemas/plugins/ManifestPlugin.check.js +1 -1
  196. package/schemas/plugins/SourceMapDevToolPlugin.check.js +1 -1
  197. package/schemas/plugins/asset/AssetGeneratorOptions.check.js +1 -1
  198. package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js +1 -1
  199. package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
  200. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  201. package/schemas/plugins/debug/ProfilingPlugin.check.js +1 -1
  202. package/schemas/plugins/dll/DllReferencePlugin.check.js +1 -1
  203. package/schemas/plugins/ids/HashedModuleIdsPlugin.check.js +1 -1
  204. package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
  205. package/types.d.ts +1414 -314
  206. package/lib/dependencies/ExportBindingInitFragment.js +0 -191
  207. package/lib/errors/EntrypointOverlapWarning.js +0 -45
  208. package/lib/performance/EntrypointOverlapPlugin.js +0 -122
@@ -15,6 +15,7 @@ const createHooksRegistry = require("../util/createHooksRegistry");
15
15
  const { chunkHasCss } = require("./CssModulesPlugin");
16
16
 
17
17
  /** @import Chunk, { ChunkId } from "../Chunk" */
18
+ /** @import ChunkGraph from "../ChunkGraph" */
18
19
  /** @import { ReadOnlyRuntimeRequirements } from "../Module" */
19
20
 
20
21
  const createCompilationHooks = () => ({
@@ -56,26 +57,14 @@ class CssLoadingRuntimeModule extends RuntimeModule {
56
57
  }
57
58
 
58
59
  /**
59
- * Generates runtime code for this runtime module.
60
- * @returns {string | null} runtime code
60
+ * The initial chunks carrying a stylesheet, and the matcher for the ones the
61
+ * handler can still be asked to load.
62
+ * @private
63
+ * @returns {{ initialChunkIds: Set<ChunkId>, hasCssMatcher: ReturnType<typeof compileBooleanMatcher> }} loadable chunks
61
64
  */
62
- generate() {
63
- const { _runtimeRequirements } = this;
64
- const compilation = /** @type {Compilation} */ (this.compilation);
65
+ _getLoadableChunks() {
65
66
  const chunk = /** @type {Chunk} */ (this.chunk);
66
- const {
67
- chunkGraph,
68
- runtimeTemplate,
69
- outputOptions: {
70
- crossOriginLoading,
71
- uniqueName,
72
- chunkLoadTimeout: loadTimeout,
73
- charset,
74
- resourceHints
75
- }
76
- } = compilation;
77
- const dedupePrefetch = Boolean(resourceHints && resourceHints.dedupe);
78
- const fn = RuntimeGlobals.ensureChunkHandlers;
67
+ const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph);
79
68
  /** @type {Set<ChunkId>} */
80
69
  const initialChunkIds = new Set();
81
70
  for (const c of chunk.getAllInitialChunks()) {
@@ -96,6 +85,75 @@ class CssLoadingRuntimeModule extends RuntimeModule {
96
85
  compileBooleanMatcher(loadableConditionMap) === false
97
86
  ? false
98
87
  : compileBooleanMatcher(conditionMap);
88
+ return { initialChunkIds, hasCssMatcher };
89
+ }
90
+
91
+ /**
92
+ * The `[handlerMap, key]` pairs this module installs onto a chunk handler map
93
+ * such as `__webpack_require__.f`, or `null` where it cannot name them.
94
+ * @returns {[string, string][] | null} installed chunk handlers (do not mutate)
95
+ */
96
+ getInstalledChunkHandlers() {
97
+ const compilation = /** @type {Compilation} */ (this.compilation);
98
+ const chunk = /** @type {Chunk} */ (this.chunk);
99
+ const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph);
100
+ const runtimeRequirements = this._runtimeRequirements;
101
+ const withLoading =
102
+ runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers) &&
103
+ this._getLoadableChunks().hasCssMatcher !== false;
104
+ // Nothing at all is emitted without either, so nothing is installed either.
105
+ if (
106
+ !withLoading &&
107
+ !runtimeRequirements.has(RuntimeGlobals.hmrDownloadUpdateHandlers)
108
+ ) {
109
+ return [];
110
+ }
111
+ const withHint =
112
+ compilation.outputOptions.environment.document ||
113
+ compilation.runtimeTemplate.isNeutralPlatform();
114
+ /** @type {[string, string][]} */
115
+ const handlers = [];
116
+ if (withLoading) handlers.push([RuntimeGlobals.ensureChunkHandlers, "css"]);
117
+ if (
118
+ withHint &&
119
+ runtimeRequirements.has(RuntimeGlobals.prefetchChunkHandlers) &&
120
+ chunk.hasChildByOrder(chunkGraph, "prefetch", true, chunkHasCss)
121
+ ) {
122
+ handlers.push([RuntimeGlobals.prefetchChunkHandlers, "s"]);
123
+ }
124
+ if (
125
+ withHint &&
126
+ runtimeRequirements.has(RuntimeGlobals.preloadChunkHandlers) &&
127
+ (chunk.hasChildByOrder(chunkGraph, "preload", true, chunkHasCss) ||
128
+ chunk.hasChildByOrder(chunkGraph, "cssPreload", true, chunkHasCss))
129
+ ) {
130
+ handlers.push([RuntimeGlobals.preloadChunkHandlers, "s"]);
131
+ }
132
+ return handlers;
133
+ }
134
+
135
+ /**
136
+ * Generates runtime code for this runtime module.
137
+ * @returns {string | null} runtime code
138
+ */
139
+ generate() {
140
+ const { _runtimeRequirements } = this;
141
+ const compilation = /** @type {Compilation} */ (this.compilation);
142
+ const chunk = /** @type {Chunk} */ (this.chunk);
143
+ const {
144
+ chunkGraph,
145
+ runtimeTemplate,
146
+ outputOptions: {
147
+ crossOriginLoading,
148
+ uniqueName,
149
+ chunkLoadTimeout: loadTimeout,
150
+ charset,
151
+ resourceHints
152
+ }
153
+ } = compilation;
154
+ const dedupePrefetch = Boolean(resourceHints && resourceHints.dedupe);
155
+ const fn = RuntimeGlobals.ensureChunkHandlers;
156
+ const { initialChunkIds, hasCssMatcher } = this._getLoadableChunks();
99
157
 
100
158
  const withLoading =
101
159
  _runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers) &&
@@ -185,32 +243,22 @@ class CssLoadingRuntimeModule extends RuntimeModule {
185
243
  ",\n"
186
244
  )
187
245
  )}\n}`;
188
- /**
189
- * @param {string} id expression naming the chunk whose stylesheet is wanted
190
- * @returns {string} expression building its url at runtime
191
- */
192
- const runtimeCssUrl = (id) =>
193
- `${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkCssFilename}(${id})`;
194
246
  // The url is read through a thunk so a runtime carrying many stylesheets builds
195
247
  // only the one it loads.
196
248
  /**
197
249
  * @param {string} id expression naming the chunk whose stylesheet is wanted
198
250
  * @returns {string} expression evaluating to its url
199
251
  */
200
- const cssUrl = (id) => {
201
- if (!cssUrls) return runtimeCssUrl(id);
202
- // An id the incomplete map lacks still resolves through the runtime lookup,
203
- // which the plugin kept required for exactly this case.
204
- return cssUrls.complete
205
- ? `cssUrls[${id}]()`
206
- : `(cssUrls[${id}] ? cssUrls[${id}]() : ${runtimeCssUrl(id)})`;
207
- };
252
+ const cssUrl = (id) =>
253
+ cssUrls === null
254
+ ? `${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkCssFilename}(${id})`
255
+ : `cssUrls[${id}]()`;
208
256
  return Template.asString([
209
257
  ...(cssUrls
210
258
  ? [
211
259
  `${cst} cssUrls = {\n${Template.indent(
212
260
  Array.from(
213
- cssUrls.urls,
261
+ cssUrls,
214
262
  ([id, url]) =>
215
263
  `${JSON.stringify(String(id))}: ${runtimeTemplate.returningFunction(url)}`
216
264
  ).join(",\n")
@@ -395,6 +443,10 @@ class CssLoadingRuntimeModule extends RuntimeModule {
395
443
  ]
396
444
  )});`
397
445
  ]
446
+ // No fs to import, or a url `readFile` rejects on sight (a CDN public
447
+ // path): nothing to collect, which is what a missing file already means.
448
+ )}).catch(${runtimeTemplate.expressionFunction(
449
+ "loadingEnded({ type: 'load' })"
398
450
  )});`
399
451
  ]),
400
452
  "}"
@@ -552,6 +604,7 @@ class CssLoadingRuntimeModule extends RuntimeModule {
552
604
  Template.indent([
553
605
  // node SSR: refresh the server style registry from the re-emitted CSS instead of touching the DOM
554
606
  `${cst} cssRemovedChunks = css && css.r;`,
607
+ `${cst} cssNames = css && css.n;`,
555
608
  `${cst} registry = ${runtimeTemplate.cssServerStyleRegistry()};`,
556
609
  `chunkIds.forEach(${runtimeTemplate.basicFunction(
557
610
  "chunkId",
@@ -561,7 +614,7 @@ class CssLoadingRuntimeModule extends RuntimeModule {
561
614
  "cssRemovedChunks",
562
615
  "indexOf(chunkId)"
563
616
  )} >= 0) { delete registry[key]; return; }`,
564
- `${cst} url = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkCssFilename}(chunkId);`,
617
+ `${cst} url = ${RuntimeGlobals.publicPath} + (cssNames && cssNames[chunkId] || ${RuntimeGlobals.getChunkCssFilename}(chunkId));`,
565
618
  `promises.push(Promise.all([import('fs'), import('url')]).then(${runtimeTemplate.basicFunction(
566
619
  "[{ readFile }, { URL }]",
567
620
  [
@@ -594,9 +647,14 @@ class CssLoadingRuntimeModule extends RuntimeModule {
594
647
  "applyHandlers.push(applyHandler);",
595
648
  "// Read CSS removed chunks from update manifest",
596
649
  `${cst} cssRemovedChunks = css && css.r;`,
650
+ // The name map this runtime holds is refreshed by the update chunk, which
651
+ // has not run yet, so a name that moved is read off the manifest.
652
+ `${cst} cssNames = css && css.n;`,
597
653
  `chunkIds.forEach(${runtimeTemplate.basicFunction("chunkId", [
598
- `${cst} url = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkCssFilename}(chunkId);`,
599
- `${cst} oldTag = loadStylesheet(chunkId, url);`,
654
+ `${cst} url = ${RuntimeGlobals.publicPath} + (cssNames && cssNames[chunkId] || ${RuntimeGlobals.getChunkCssFilename}(chunkId));`,
655
+ // The stylesheet in the document was loaded at the name this runtime
656
+ // still holds, so that is the name it is found by.
657
+ `${cst} oldTag = loadStylesheet(chunkId, ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkCssFilename}(chunkId));`,
600
658
  `if(!oldTag && !${withHmr} ) return;`,
601
659
  "// Skip if CSS was removed",
602
660
  `if(${runtimeTemplate.optionalChaining(
@@ -197,7 +197,7 @@ class CssModule extends NormalModule {
197
197
  parserOptions: /** @type {EXPECTED_ANY} */ (null),
198
198
  generator: /** @type {EXPECTED_ANY} */ (null),
199
199
  generatorOptions: /** @type {EXPECTED_ANY} */ (null),
200
- resolveOptions: /** @type {EXPECTED_ANY} */ (null),
200
+ resolveOptions: undefined,
201
201
  cssLayer: /** @type {EXPECTED_ANY} */ (null),
202
202
  supports: /** @type {EXPECTED_ANY} */ (null),
203
203
  media: /** @type {EXPECTED_ANY} */ (null),
@@ -772,12 +772,13 @@ class CssModulesPlugin {
772
772
  // A baked url carries where the stylesheet is, so neither the public
773
773
  // path nor the name lookup is read for it. Asked exactly as the
774
774
  // loading runtime module asks, so the two always agree.
775
- const baked = compilation.runtimeTemplate.analyzableCssChunkUrls(
776
- chunk,
777
- chunkGraph,
778
- set
779
- );
780
- if (baked === null || !baked.complete) {
775
+ if (
776
+ compilation.runtimeTemplate.analyzableCssChunkUrls(
777
+ chunk,
778
+ chunkGraph,
779
+ set
780
+ ) === null
781
+ ) {
781
782
  set.add(RuntimeGlobals.publicPath);
782
783
  set.add(RuntimeGlobals.getChunkCssFilename);
783
784
  }
@@ -207,6 +207,10 @@ const VALUE_AS_ALIAS = /\s+as\s+/;
207
207
  // `@value name value`: end of the name run (first non-space followed by space).
208
208
  const VALUE_NAME_BOUNDARY = /\S\s/;
209
209
  const ONLY_WHITESPACE = /^\s+$/;
210
+ // A `@value` whose whole value is one `.class` / `#id`, the only shape whose
211
+ // localizable ident is knowable without re-parsing the substitution.
212
+ const SIMPLE_CLASS_OR_ID_VALUE =
213
+ /^([.#])(-?(?:[A-Za-z_]|[\u0080-\uFFFF])(?:[\w-]|[\u0080-\uFFFF])*)$/;
210
214
  // Relative request prefix (`./` or `../`) — `isSelfReferenceRequest` per `from`.
211
215
  const RELATIVE_REQUEST = /^\.{1,2}\//;
212
216
 
@@ -994,6 +998,19 @@ class CssParser extends Parser {
994
998
  d.entries.push(cssExportEntries.length);
995
999
  };
996
1000
 
1001
+ // Start offsets of the idents an at-rule's own prelude handler already
1002
+ // replaced: two deps over one range concatenate rather than the later winning.
1003
+ /** @type {Set<number>} */
1004
+ const handledPreludeIdents = new Set();
1005
+ // Only a prelude is walked by both a handler and the value visitors, so
1006
+ // nothing outside one pays for the bookkeeping.
1007
+ let trackingPreludeIdents = false;
1008
+
1009
+ // Start offsets of `@value`-named dashed idents a `var()` handler already
1010
+ // scoped; only those are walked twice, so plain dashed idents cost nothing.
1011
+ /** @type {Set<number>} */
1012
+ const handledDashedValueIdents = new Set();
1013
+
997
1014
  // All `:export`-style exports are collected into a single
998
1015
  // `CssIcssExportDependency` per module (emitted at parse end) instead of one
999
1016
  // `Dependency` per export — far fewer retained objects on CSS-heavy builds.
@@ -1024,6 +1041,7 @@ class CssParser extends Parser {
1024
1041
  exportMode = CssIcssExportDependency.EXPORT_MODE.REPLACE,
1025
1042
  exportType = CssIcssExportDependency.EXPORT_TYPE.NORMAL
1026
1043
  ) => {
1044
+ if (trackingPreludeIdents && range) handledPreludeIdents.add(range[0]);
1027
1045
  // Flat location numbers — the nested loc objects were the parser's
1028
1046
  // hottest allocation (3 objects per exported name).
1029
1047
  cssExportEntries.push({
@@ -1556,13 +1574,15 @@ class CssParser extends Parser {
1556
1574
  };
1557
1575
 
1558
1576
  /**
1559
- * Emit a `CssIcssSymbolDependency` rewrite for an ident resolving to an `@value`-defined ICSS symbol (source-order semantics hold since the walker handles each `@value` before later references).
1577
+ * Emit a `CssIcssSymbolDependency` rewrite for an ident resolving to an `@value`-defined ICSS symbol (source-order semantics hold since the walker handles each `@value` before later references). A no-op for an ident an at-rule's own prelude handler already replaced.
1560
1578
  * @param {string} name ICSS symbol name
1561
1579
  * @param {number} start start position
1562
1580
  * @param {number} end end position
1563
1581
  * @returns {number} `end` of the rewritten ident range
1564
1582
  */
1565
1583
  const emitICSSSymbol = (name, start, end) => {
1584
+ if (handledPreludeIdents.has(start)) return end;
1585
+ if (trackingPreludeIdents) handledPreludeIdents.add(start);
1566
1586
  const def =
1567
1587
  /** @type {IcssDefinition} */
1568
1588
  (icssDefinitions.get(name));
@@ -1580,6 +1600,37 @@ class CssParser extends Parser {
1580
1600
  return end;
1581
1601
  };
1582
1602
 
1603
+ /**
1604
+ * The `.class` / `#id` a locally defined `@value` stands for, when its whole value is exactly one of those. Undefined for an imported value or any richer selector, which stay a plain textual substitution.
1605
+ * @param {string} name `@value` name used where a selector is expected
1606
+ * @returns {["." | "#", string] | undefined} the selector's prefix and the ident to localize
1607
+ */
1608
+ const localizableSelectorValue = (name) => {
1609
+ const def = icssDefinitions.get(name);
1610
+ if (!def || def.importName || typeof def.value !== "string") {
1611
+ return undefined;
1612
+ }
1613
+ const match = SIMPLE_CLASS_OR_ID_VALUE.exec(def.value.trim());
1614
+ return match
1615
+ ? [/** @type {"." | "#"} */ (match[1]), match[2]]
1616
+ : undefined;
1617
+ };
1618
+
1619
+ /**
1620
+ * The dashed ident a locally defined `@value` stands for, without its `--` prefix, when its whole value is exactly one. Undefined for an imported value or any richer value, which stay a plain textual substitution.
1621
+ * @param {string} name `@value` name used where a dashed ident is expected
1622
+ * @returns {string | undefined} the name to localize, sans `--`
1623
+ */
1624
+ const localizableDashedValue = (name) => {
1625
+ if (icssDefinitions.size === 0) return undefined;
1626
+ const def = icssDefinitions.get(name);
1627
+ if (!def || def.importName || typeof def.value !== "string") {
1628
+ return undefined;
1629
+ }
1630
+ const value = def.value.trim();
1631
+ return isDashedIdentifier(value) ? value.slice(2) : undefined;
1632
+ };
1633
+
1583
1634
  /**
1584
1635
  * Process a `local(...)` / `global(...)` pseudo-function: strip the call (and a leading legacy `:`) via a presentational dep, then emit `local()`'s inner top-level idents as ICSS exports.
1585
1636
  * @param {FunctionNode} fn parsed local/global function node
@@ -1740,12 +1791,12 @@ class CssParser extends Parser {
1740
1791
  : unescapeRange(identStart, identEnd).slice(2);
1741
1792
 
1742
1793
  /**
1743
- * Emit the ICSS export declaring this module exports the given custom property.
1744
- * @param {number} identStart start of the `--<name>` ident
1794
+ * Emit the ICSS export declaring this module exports the given custom property, naming it explicitly rather than reading it back from the replaced range. A `@value` standing in for a dashed ident is scoped under the name it resolves to, not the name written at the use site.
1795
+ * @param {string} identifier custom property name, sans `--`
1796
+ * @param {number} identStart start of the replaced ident
1745
1797
  * @param {number} identEnd end of the ident (exclusive)
1746
1798
  */
1747
- const emitDashedIdentExport = (identStart, identEnd) => {
1748
- const identifier = dashedIdentName(identStart, identEnd);
1799
+ const emitNamedDashedIdentExport = (identifier, identStart, identEnd) => {
1749
1800
  const { line: sl, column: sc } = locConverter.get(identStart);
1750
1801
  const { line: el, column: ec } = locConverter.get(identEnd);
1751
1802
  recordDeclaration(identifier, "custom property", sl, sc);
@@ -1763,6 +1814,19 @@ class CssParser extends Parser {
1763
1814
  );
1764
1815
  };
1765
1816
 
1817
+ /**
1818
+ * Emit the ICSS export declaring this module exports the given custom property.
1819
+ * @param {number} identStart start of the `--<name>` ident
1820
+ * @param {number} identEnd end of the ident (exclusive)
1821
+ */
1822
+ const emitDashedIdentExport = (identStart, identEnd) => {
1823
+ emitNamedDashedIdentExport(
1824
+ dashedIdentName(identStart, identEnd),
1825
+ identStart,
1826
+ identEnd
1827
+ );
1828
+ };
1829
+
1766
1830
  /**
1767
1831
  * Emit `--<name> from "<path>"` as an ICSS import + export, stripping ` from "<path>"` so the runtime sees just `--<name>` (dep ranges end at `sourceEnd - 1`, the closing quote).
1768
1832
  * @param {number} identStart start of the `--<name>` ident
@@ -1846,7 +1910,16 @@ class CssParser extends Parser {
1846
1910
 
1847
1911
  const identStart = A.start(identNode);
1848
1912
  const identEnd = A.end(identNode);
1849
- if (!rangeIsDashedIdentifier(input, identStart, identEnd)) return;
1913
+ if (!rangeIsDashedIdentifier(input, identStart, identEnd)) {
1914
+ // `var(v)` where `@value v: --foo` names the same property `var(--foo)`
1915
+ // does, so it is scoped here rather than substituted verbatim.
1916
+ const dashedName = localizableDashedValue(A.value(identNode));
1917
+ if (dashedName !== undefined) {
1918
+ handledDashedValueIdents.add(identStart);
1919
+ emitNamedDashedIdentExport(dashedName, identStart, identEnd);
1920
+ }
1921
+ return;
1922
+ }
1850
1923
 
1851
1924
  let j = identIdx + 1;
1852
1925
  while (j < fv.length && A.type(fv[j]) === NodeType.Whitespace) {
@@ -2351,12 +2424,52 @@ class CssParser extends Parser {
2351
2424
  break;
2352
2425
  }
2353
2426
  case NodeType.Ident: {
2354
- // ICSS rewrite for a bare `@value`-defined ident used as a type-style selector; only worth the slice when definitions exist.
2427
+ // A bare `@value`-defined ident stands in for a selector; only worth the slice when definitions exist.
2355
2428
  if (icssDefinitions.size === 0) break;
2356
2429
  const ident = A.value(v);
2357
- if (!isDashedIdentifier(ident) && icssDefinitions.has(ident)) {
2358
- emitICSSSymbol(ident, A.start(v), A.end(v));
2430
+ if (isDashedIdentifier(ident) || !icssDefinitions.has(ident)) {
2431
+ break;
2432
+ }
2433
+ const identStart = A.start(v);
2434
+ const identEnd = A.end(v);
2435
+ // A value naming one class / id is localized like the selector the
2436
+ // author would have written; anything else is substituted verbatim.
2437
+ const localizable =
2438
+ segmentMode === "local"
2439
+ ? localizableSelectorValue(ident)
2440
+ : undefined;
2441
+ if (localizable === undefined) {
2442
+ emitICSSSymbol(ident, identStart, identEnd);
2443
+ break;
2444
+ }
2445
+ const [prefix, localName] = localizable;
2446
+ const { line: sl, column: sc } = locConverter.get(identStart);
2447
+ const { line: el, column: ec } = locConverter.get(identEnd);
2448
+ module.addPresentationalDependency(
2449
+ new ConstDependency(prefix, [identStart, identStart])
2450
+ );
2451
+ recordDeclaration(
2452
+ localName,
2453
+ prefix === "." ? "class" : "id",
2454
+ sl,
2455
+ sc
2456
+ );
2457
+ addCssExport(
2458
+ sl,
2459
+ sc,
2460
+ el,
2461
+ ec,
2462
+ localName,
2463
+ getReexport(localName),
2464
+ [identStart, identEnd],
2465
+ true,
2466
+ CssIcssExportDependency.EXPORT_MODE.ONCE
2467
+ );
2468
+ if (prefix === ".") {
2469
+ currentRule.hasLocalAnchor = true;
2470
+ currentRule.localIdentifiers.push(localName);
2359
2471
  }
2472
+ pure.markLocal();
2360
2473
  break;
2361
2474
  }
2362
2475
  default:
@@ -4074,6 +4187,10 @@ class CssParser extends Parser {
4074
4187
  // truncates back to this length (no per-rule copy).
4075
4188
  const savedLocalIdentifierCount = currentRule.localIdentifiers.length;
4076
4189
  const name = `@${toLowerCaseIfNeeded(A.unescapedName(at))}`;
4190
+ // The dispatch below is the only place a prelude is rewritten ahead
4191
+ // of the value visitors, so the marks live exactly as long as it.
4192
+ if (handledPreludeIdents.size !== 0) handledPreludeIdents.clear();
4193
+ trackingPreludeIdents = true;
4077
4194
  switch (name) {
4078
4195
  case "@namespace": {
4079
4196
  this._emitWarning(
@@ -4173,6 +4290,7 @@ class CssParser extends Parser {
4173
4290
  )
4174
4291
  );
4175
4292
  }
4293
+ trackingPreludeIdents = false;
4176
4294
 
4177
4295
  // Prelude value-visitor context; AST-handled at-rules emit their own deps so they're excluded from the local() / global() / ICSS walks.
4178
4296
  const effectiveLocalMode = isEffectivelyLocal();
@@ -4777,9 +4895,24 @@ class CssParser extends Parser {
4777
4895
  if (dashed.counterArgs) return;
4778
4896
  // Deferred: only the ICSS probe needs the ident's string value.
4779
4897
  const identValue = A.value(node);
4780
- if (icssDefinitions.has(identValue)) {
4781
- emitICSSSymbol(identValue, identStart, identEnd);
4898
+ if (!icssDefinitions.has(identValue)) return;
4899
+ // Already scoped by the enclosing `var()` handler.
4900
+ if (
4901
+ handledDashedValueIdents.size !== 0 &&
4902
+ handledDashedValueIdents.has(identStart)
4903
+ ) {
4904
+ return;
4905
+ }
4906
+ // A `@value` resolving to a dashed ident sits where `--foo` would be
4907
+ // scoped, so it is localized rather than substituted verbatim.
4908
+ if (dashedActive && dashed.emit) {
4909
+ const dashedName = localizableDashedValue(identValue);
4910
+ if (dashedName !== undefined) {
4911
+ emitNamedDashedIdentExport(dashedName, identStart, identEnd);
4912
+ return;
4913
+ }
4782
4914
  }
4915
+ emitICSSSymbol(identValue, identStart, identEnd);
4783
4916
  }
4784
4917
  };
4785
4918
  // `as` selects the top-level production (§5.3): a `style` attribute is a
@@ -26,6 +26,15 @@ class CssServerStylesRuntimeModule extends RuntimeModule {
26
26
  return false;
27
27
  }
28
28
 
29
+ /**
30
+ * The `[handlerMap, key]` pairs this module installs onto a chunk handler map
31
+ * such as `__webpack_require__.f`, or `null` where it cannot name them.
32
+ * @returns {[string, string][] | null} installed chunk handlers (do not mutate)
33
+ */
34
+ getInstalledChunkHandlers() {
35
+ return RuntimeModule.NO_CHUNK_HANDLERS;
36
+ }
37
+
29
38
  /**
30
39
  * Generates runtime code for this runtime module.
31
40
  * @returns {string | null} runtime code
@@ -31,9 +31,9 @@
31
31
  * imported at module scope: `minimizer-webpack-plugin` ships this function to its
32
32
  * worker pool as source (a top-level import wouldn't survive), and `require("webpack")`
33
33
  * re-resolves in the worker — via the installed package, or the dev self-link.
34
- * @param {{ [file: string]: string }} input a single `{ filename: code }` entry
34
+ * @param {{ [file: string]: string | Buffer }} input a single `{ filename: code }` entry; a `Buffer` is read as UTF-8
35
35
  * @param {object=} sourceMap the asset's input source map — the plugin chains it onto the map returned here, so it isn't read directly
36
- * @param {{ as?: "stylesheet" | "block-contents", environment?: CssEnvironment, convertLengthUnits?: boolean, rewriteCustomProperties?: boolean, renderEmbeddedSource?: AsyncEmbeddedSourceRenderer } & CssTransformOptions=} minimizerOptions minimizer options — `environment` carries the target's CSS abilities (see `output.environment`), so a spelling the target cannot read is not reached for; the rest is `optimization.minimize.css` (e.g. `convertLengthUnits`, and the per-transform switches). `renderEmbeddedSource` minifies source this stylesheet embeds, and may be asynchronous: one parse serves both it and the output
36
+ * @param {{ as?: "stylesheet" | "block-contents", environment?: CssEnvironment, convertLengthUnits?: boolean, mergeDistantRules?: boolean, rewriteCustomProperties?: boolean, unusedSymbols?: string[], pseudoClasses?: { [name: string]: string }, renderEmbeddedSource?: AsyncEmbeddedSourceRenderer } & CssTransformOptions=} minimizerOptions minimizer options — `environment` carries the target's CSS abilities (see `output.environment`), so a spelling the target cannot read is not reached for; the rest is `optimization.minimize.css` (e.g. `convertLengthUnits`, and the per-transform switches). `renderEmbeddedSource` minifies source this stylesheet embeds, and may be asynchronous: one parse serves both it and the output
37
37
  * @returns {Promise<{ code: string, map?: SourceMap, warnings?: (Error | string)[], errors?: (Error | string)[] }>} the minified CSS, its input->output source map (one anchor for the whole of a `block-contents` print, which is emitted as one piece), and what a renderer reported over what this embeds
38
38
  */
39
39
  const cssMinify = async (input, sourceMap, minimizerOptions = {}) => {
@@ -81,7 +81,9 @@ const cssMinify = async (input, sourceMap, minimizerOptions = {}) => {
81
81
  embeddedText,
82
82
  pickTransforms
83
83
  } = webpack.css.syntax;
84
- const [[file, code]] = Object.entries(input);
84
+ const [[file, given]] = Object.entries(input);
85
+ // The plugin hands a text minifier a string; the type admits an image's bytes.
86
+ const code = typeof given === "string" ? given : given.toString("utf8");
85
87
  // `process` parses once, and with `mode: "minify"` the same walk also prints
86
88
  // the safely minified serialization — no second parse. Naming the input with
87
89
  // `source` / `content` is what asks for the map, which the plugin composes
@@ -90,7 +92,10 @@ const cssMinify = async (input, sourceMap, minimizerOptions = {}) => {
90
92
  as,
91
93
  environment,
92
94
  convertLengthUnits,
95
+ mergeDistantRules,
93
96
  rewriteCustomProperties,
97
+ unusedSymbols,
98
+ pseudoClasses,
94
99
  renderEmbeddedSource
95
100
  } = minimizerOptions;
96
101
  // One set of options, handed to the print. `as` names the production: a
@@ -103,7 +108,10 @@ const cssMinify = async (input, sourceMap, minimizerOptions = {}) => {
103
108
  content: code,
104
109
  environment,
105
110
  convertLengthUnits,
111
+ mergeDistantRules,
106
112
  rewriteCustomProperties,
113
+ unusedSymbols,
114
+ pseudoClasses,
107
115
  // The per-transform switches stand beside those rather than nested in
108
116
  // them, so a config names one the way it names `convertLengthUnits`;
109
117
  // `pickTransforms` is what knows which names those are.