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
@@ -5,6 +5,8 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ const { makeCacheable } = require("../util/identifier");
9
+
8
10
  /**
9
11
  * Defines the css token callbacks type used by this module.
10
12
  * @typedef {object} CssTokenCallbacks
@@ -161,6 +163,143 @@ const isIdentStartCodePoint = (cc) =>
161
163
  cc === CC_LOW_LINE ||
162
164
  cc >= 0x80;
163
165
 
166
+ const REGEX_SINGLE_ESCAPE = /[ -,./:-@[\]^`{-~]/;
167
+ const REGEX_EXCESSIVE_SPACES = /(^|\\+)?(\\[A-F0-9]{1,6}) (?![a-fA-F0-9 ])/g;
168
+ const REGEX_CTRL_WHITESPACE = /[\t\n\f\r\v]/;
169
+ const REGEX_LEADING_HYPHEN_DIGIT = /^-[-\d]/;
170
+ const REGEX_DIGIT = /\d/;
171
+ const CONTAINS_ESCAPE = /\\/;
172
+
173
+ /**
174
+ * Returns escaped identifier.
175
+ * @param {string} str string
176
+ * @returns {string} escaped identifier
177
+ */
178
+ const _escapeIdentifier = (str) => {
179
+ let output = "";
180
+ let counter = 0;
181
+
182
+ while (counter < str.length) {
183
+ const character = str.charAt(counter++);
184
+
185
+ /** @type {string} */
186
+ let value;
187
+
188
+ if (REGEX_CTRL_WHITESPACE.test(character)) {
189
+ const codePoint = character.charCodeAt(0);
190
+
191
+ value = `\\${codePoint.toString(16).toUpperCase()} `;
192
+ } else if (character === "\\" || REGEX_SINGLE_ESCAPE.test(character)) {
193
+ value = `\\${character}`;
194
+ } else {
195
+ value = character;
196
+ }
197
+
198
+ output += value;
199
+ }
200
+
201
+ const firstChar = str.charAt(0);
202
+
203
+ if (REGEX_LEADING_HYPHEN_DIGIT.test(output)) {
204
+ output = `\\-${output.slice(1)}`;
205
+ } else if (REGEX_DIGIT.test(firstChar)) {
206
+ output = `\\3${firstChar} ${output.slice(1)}`;
207
+ }
208
+
209
+ // Remove spaces after `\HEX` escapes that are not followed by a hex digit,
210
+ // since they’re redundant. Note that this is only possible if the escape
211
+ // sequence isn’t preceded by an odd number of backslashes.
212
+ output = output.replace(REGEX_EXCESSIVE_SPACES, ($0, $1, $2) => {
213
+ if ($1 && $1.length % 2) {
214
+ // It’s not safe to remove the space, so don’t.
215
+ return $0;
216
+ }
217
+
218
+ // Strip the space.
219
+ return ($1 || "") + $2;
220
+ });
221
+
222
+ return output;
223
+ };
224
+
225
+ /**
226
+ * Returns hex.
227
+ * @param {string} str string
228
+ * @returns {[string, number] | undefined} hex
229
+ */
230
+ const gobbleHex = (str) => {
231
+ const lower = str.toLowerCase();
232
+ let hex = "";
233
+ let spaceTerminated = false;
234
+
235
+ for (let i = 0; i < 6 && lower[i] !== undefined; i++) {
236
+ const code = lower.charCodeAt(i);
237
+ // check to see if we are dealing with a valid hex char [a-f|0-9]
238
+ const valid = (code >= 97 && code <= 102) || (code >= 48 && code <= 57);
239
+ // https://drafts.csswg.org/css-syntax/#consume-escaped-code-point
240
+ spaceTerminated = code === 32;
241
+ if (!valid) break;
242
+ hex += lower[i];
243
+ }
244
+
245
+ if (hex.length === 0) return undefined;
246
+
247
+ const codePoint = Number.parseInt(hex, 16);
248
+ const isSurrogate = codePoint >= 0xd800 && codePoint <= 0xdfff;
249
+
250
+ // Add special case for
251
+ // "If this number is zero, or is for a surrogate, or is greater than the maximum allowed code point"
252
+ // https://drafts.csswg.org/css-syntax/#maximum-allowed-code-point
253
+ if (isSurrogate || codePoint === 0x0000 || codePoint > 0x10ffff) {
254
+ return ["�", hex.length + (spaceTerminated ? 1 : 0)];
255
+ }
256
+
257
+ return [
258
+ String.fromCodePoint(codePoint),
259
+ hex.length + (spaceTerminated ? 1 : 0)
260
+ ];
261
+ };
262
+
263
+ /**
264
+ * Unescape identifier.
265
+ * @param {string} str string
266
+ * @returns {string} unescaped string
267
+ */
268
+ const _unescapeIdentifier = (str) => {
269
+ const needToProcess = CONTAINS_ESCAPE.test(str);
270
+ if (!needToProcess) return str;
271
+ let ret = "";
272
+ for (let i = 0; i < str.length; i++) {
273
+ if (str[i] === "\\") {
274
+ const gobbled = gobbleHex(str.slice(i + 1, i + 7));
275
+ if (gobbled !== undefined) {
276
+ ret += gobbled[0];
277
+ i += gobbled[1];
278
+ continue;
279
+ }
280
+ // Retain a pair of \\ if double escaped `\\\\`
281
+ // https://github.com/postcss/postcss-selector-parser/commit/268c9a7656fb53f543dc620aa5b73a30ec3ff20e
282
+ if (str[i + 1] === "\\") {
283
+ ret += "\\";
284
+ i += 1;
285
+ continue;
286
+ }
287
+ // if \\ is at the end of the string retain it
288
+ // https://github.com/postcss/postcss-selector-parser/commit/01a6b346e3612ce1ab20219acc26abdc259ccefb
289
+ if (str.length === i + 1) {
290
+ ret += str[i];
291
+ }
292
+ continue;
293
+ }
294
+ ret += str[i];
295
+ }
296
+
297
+ return ret;
298
+ };
299
+
300
+ const escapeIdentifier = makeCacheable(_escapeIdentifier);
301
+ const unescapeIdentifier = makeCacheable(_unescapeIdentifier);
302
+
164
303
  /** @type {CharHandler} */
165
304
  const consumeDelimToken = (input, pos, callbacks) => {
166
305
  // Return a <delim-token> with its value set to the current input code point.
@@ -1632,11 +1771,11 @@ const eatImageSetStrings = (input, pos, cbs) => {
1632
1771
  * @param {string} input input
1633
1772
  * @param {number} pos position
1634
1773
  * @param {CssTokenCallbacks} cbs callbacks
1635
- * @returns {[[number, number, number, number] | undefined, [number, number] | undefined, [number, number] | undefined, [number, number] | undefined]} positions of top level tokens
1774
+ * @returns {[[number, number, number, number, boolean?] | undefined, [number, number] | undefined, [number, number] | undefined, [number, number] | undefined]} positions of top level tokens — the URL tuple's optional 5th element is `true` when the URL was given as an identifier (CSS Modules `@value` reference)
1636
1775
  */
1637
1776
  const eatImportTokens = (input, pos, cbs) => {
1638
1777
  const result =
1639
- /** @type {[[number, number, number, number] | undefined, [number, number] | undefined, [number, number] | undefined, [number, number] | undefined]} */
1778
+ /** @type {[[number, number, number, number, boolean?] | undefined, [number, number] | undefined, [number, number] | undefined, [number, number] | undefined]} */
1640
1779
  (Array.from({ length: 4 }));
1641
1780
 
1642
1781
  /** @type {0 | 1 | 2 | undefined} */
@@ -1740,6 +1879,11 @@ const eatImportTokens = (input, pos, cbs) => {
1740
1879
  if (name === "layer") {
1741
1880
  result[1] = [start, end];
1742
1881
  scope = undefined;
1882
+ } else if (result[0] === undefined) {
1883
+ // Capture as URL identifier (e.g. `@import myValue;` where
1884
+ // `myValue` is a CSS Modules `@value` definition).
1885
+ result[0] = [start, end, start, end, true];
1886
+ scope = undefined;
1743
1887
  }
1744
1888
  }
1745
1889
 
@@ -1868,7 +2012,9 @@ module.exports.eatUntil = eatUntil;
1868
2012
  module.exports.eatWhiteLine = eatWhiteLine;
1869
2013
  module.exports.eatWhitespace = eatWhitespace;
1870
2014
  module.exports.eatWhitespaceAndComments = eatWhitespaceAndComments;
2015
+ module.exports.escapeIdentifier = escapeIdentifier;
1871
2016
  module.exports.isIdentStartCodePoint = isIdentStartCodePoint;
1872
2017
  module.exports.isWhiteSpace = _isWhiteSpace;
1873
2018
  module.exports.skipCommentsAndEatIdentSequence =
1874
2019
  skipCommentsAndEatIdentSequence;
2020
+ module.exports.unescapeIdentifier = unescapeIdentifier;
@@ -6,7 +6,7 @@
6
6
  "use strict";
7
7
 
8
8
  const RuntimeGlobals = require("../RuntimeGlobals");
9
- const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning");
9
+ const UnsupportedFeatureWarning = require("../errors/UnsupportedFeatureWarning");
10
10
  const AMDRequireArrayDependency = require("./AMDRequireArrayDependency");
11
11
  const AMDRequireContextDependency = require("./AMDRequireContextDependency");
12
12
  const AMDRequireDependenciesBlock = require("./AMDRequireDependenciesBlock");
@@ -6,11 +6,72 @@
6
6
  "use strict";
7
7
 
8
8
  const RuntimeGlobals = require("../RuntimeGlobals");
9
+ const { propertyAccess } = require("../util/property");
9
10
 
10
11
  /** @typedef {import("../Module")} Module */
11
12
  /** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */
13
+ /** @typedef {import("../ModuleGraph")} ModuleGraph */
14
+ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
12
15
  /** @typedef {"exports" | "module.exports" | "this" | "Object.defineProperty(exports)" | "Object.defineProperty(module.exports)" | "Object.defineProperty(this)"} CommonJSDependencyBaseKeywords */
13
16
 
17
+ /**
18
+ * The well-known name of the ESM named export that, when present, is unwrapped
19
+ * by CommonJS `require()` to match Node.js v23+ `require(esm)` semantics:
20
+ * https://nodejs.org/docs/latest/api/modules.html#loading-ecmascript-modules-using-require
21
+ */
22
+ const ESM_MODULE_EXPORTS_NAME = "module.exports";
23
+
24
+ /**
25
+ * Whether `require()` of `importedModule` would trigger Node.js's
26
+ * `require(esm)` `"module.exports"` named-export unwrap. This is the
27
+ * usage-independent eligibility check: it only looks at module type and
28
+ * whether the export is declared, so it can be safely used from
29
+ * `getReferencedExports` before usage info is finalized (otherwise the
30
+ * check would be circular — we'd need `"module.exports"` to already be
31
+ * marked used in order to ask whether to mark it used).
32
+ * @param {Module} importedModule the imported module
33
+ * @param {ModuleGraph} moduleGraph the module graph
34
+ * @returns {boolean} true if `require()` should unwrap `"module.exports"`
35
+ */
36
+ const isRequireEsmModuleExportsModule = (importedModule, moduleGraph) => {
37
+ if (importedModule.getExportsType(moduleGraph, false) !== "namespace") {
38
+ return false;
39
+ }
40
+ const exportsInfo = moduleGraph.getExportsInfo(importedModule);
41
+ const exportInfo = exportsInfo.getReadOnlyExportInfo(ESM_MODULE_EXPORTS_NAME);
42
+ return exportInfo.provided === true;
43
+ };
44
+
45
+ /**
46
+ * When CommonJS `require()` resolves to an ES module that has a named export
47
+ * with the literal string name `"module.exports"`, Node.js returns the value of
48
+ * that export instead of the namespace object. Returns the property-access
49
+ * expression to apply to the require result for that unwrapping, or `null` if
50
+ * the imported module is not eligible (not strictly ESM, or no such export,
51
+ * or the export was tree-shaken away).
52
+ * @param {Module} importedModule the imported module
53
+ * @param {ModuleGraph} moduleGraph the module graph
54
+ * @param {RuntimeSpec} runtime the runtime for which the module is analysed
55
+ * @returns {string | null} property-access expression (e.g. `["module.exports"]`), or `null`
56
+ */
57
+ const getRequireEsmModuleExportsAccess = (
58
+ importedModule,
59
+ moduleGraph,
60
+ runtime
61
+ ) => {
62
+ if (!isRequireEsmModuleExportsModule(importedModule, moduleGraph)) {
63
+ return null;
64
+ }
65
+ const exportsInfo = moduleGraph.getExportsInfo(importedModule);
66
+ const usedName = exportsInfo.getUsedName([ESM_MODULE_EXPORTS_NAME], runtime);
67
+ if (usedName === false) return null;
68
+ return propertyAccess(/** @type {readonly string[]} */ (usedName));
69
+ };
70
+
71
+ module.exports.ESM_MODULE_EXPORTS_NAME = ESM_MODULE_EXPORTS_NAME;
72
+ module.exports.getRequireEsmModuleExportsAccess =
73
+ getRequireEsmModuleExportsAccess;
74
+
14
75
  /**
15
76
  * Returns type and base.
16
77
  * @param {CommonJSDependencyBaseKeywords} depBase commonjs dependency base
@@ -64,3 +125,5 @@ module.exports.handleDependencyBase = (
64
125
 
65
126
  return [type, base];
66
127
  };
128
+ module.exports.isRequireEsmModuleExportsModule =
129
+ isRequireEsmModuleExportsModule;
@@ -11,7 +11,12 @@ const Template = require("../Template");
11
11
  const { equals } = require("../util/ArrayHelpers");
12
12
  const makeSerializable = require("../util/makeSerializable");
13
13
  const { propertyAccess } = require("../util/property");
14
- const { handleDependencyBase } = require("./CommonJsDependencyHelpers");
14
+ const {
15
+ ESM_MODULE_EXPORTS_NAME,
16
+ getRequireEsmModuleExportsAccess,
17
+ handleDependencyBase,
18
+ isRequireEsmModuleExportsModule
19
+ } = require("./CommonJsDependencyHelpers");
15
20
  const ModuleDependency = require("./ModuleDependency");
16
21
  const processExportInfo = require("./processExportInfo");
17
22
 
@@ -107,6 +112,16 @@ class CommonJsExportRequireDependency extends ModuleDependency {
107
112
  */
108
113
  getReferencedExports(moduleGraph, runtime) {
109
114
  const ids = this.getIds(moduleGraph);
115
+ const importedModule = moduleGraph.getModule(this);
116
+ if (
117
+ importedModule &&
118
+ isRequireEsmModuleExportsModule(importedModule, moduleGraph)
119
+ ) {
120
+ // `require(esm)` unwraps the "module.exports" named export; any
121
+ // further property access lands on that value (which webpack does
122
+ // not model), so only the "module.exports" export is observable.
123
+ return [[ESM_MODULE_EXPORTS_NAME]];
124
+ }
110
125
  const getFullResult = () => {
111
126
  if (ids.length === 0) {
112
127
  return Dependency.EXPORTS_OBJECT_REFERENCED;
@@ -159,17 +174,26 @@ class CommonJsExportRequireDependency extends ModuleDependency {
159
174
  * @returns {ExportsSpec | undefined} export names
160
175
  */
161
176
  getExports(moduleGraph) {
177
+ const importedModule = moduleGraph.getModule(this);
178
+ const esmUnwrap =
179
+ importedModule &&
180
+ isRequireEsmModuleExportsModule(importedModule, moduleGraph);
162
181
  if (this.names.length === 1) {
163
182
  const ids = this.getIds(moduleGraph);
164
183
  const name = this.names[0];
165
184
  const from = moduleGraph.getConnection(this);
166
185
  if (!from) return;
186
+ const exportChain = esmUnwrap
187
+ ? [ESM_MODULE_EXPORTS_NAME, ...ids]
188
+ : ids.length === 0
189
+ ? null
190
+ : ids;
167
191
  return {
168
192
  exports: [
169
193
  {
170
194
  name,
171
195
  from,
172
- export: ids.length === 0 ? null : ids,
196
+ export: exportChain,
173
197
  // we can't mangle names that are in an empty object
174
198
  // because one could access the prototype property
175
199
  // when export isn't set yet
@@ -195,6 +219,17 @@ class CommonJsExportRequireDependency extends ModuleDependency {
195
219
  }
196
220
  const from = moduleGraph.getConnection(this);
197
221
  if (!from) return;
222
+ if (esmUnwrap) {
223
+ // Full re-export `module.exports = require("./esm")` of a module
224
+ // with a `"module.exports"` named export: the wrapping module's
225
+ // `module.exports` becomes the unwrapped value, whose own
226
+ // properties webpack cannot enumerate statically.
227
+ return {
228
+ exports: true,
229
+ canMangle: false,
230
+ dependencies: [from.module]
231
+ };
232
+ }
198
233
  const reexportInfo = this.getStarReexports(
199
234
  moduleGraph,
200
235
  undefined,
@@ -393,14 +428,23 @@ CommonJsExportRequireDependency.Template = class CommonJsExportRequireDependency
393
428
  });
394
429
  if (importedModule) {
395
430
  const ids = dep.getIds(moduleGraph);
396
- const usedImported = moduleGraph
397
- .getExportsInfo(importedModule)
398
- .getUsedName(ids, runtime);
399
- if (usedImported) {
400
- const comment = equals(usedImported, ids)
401
- ? ""
402
- : `${Template.toNormalComment(propertyAccess(ids))} `;
403
- requireExpr += `${comment}${propertyAccess(usedImported)}`;
431
+ const esmRequireAccess = getRequireEsmModuleExportsAccess(
432
+ importedModule,
433
+ moduleGraph,
434
+ runtime
435
+ );
436
+ if (esmRequireAccess !== null) {
437
+ requireExpr += `${esmRequireAccess}${propertyAccess(ids)}`;
438
+ } else {
439
+ const usedImported = moduleGraph
440
+ .getExportsInfo(importedModule)
441
+ .getUsedName(ids, runtime);
442
+ if (usedImported) {
443
+ const comment = equals(usedImported, ids)
444
+ ? ""
445
+ : `${Template.toNormalComment(propertyAccess(ids))} `;
446
+ requireExpr += `${comment}${propertyAccess(usedImported)}`;
447
+ }
404
448
  }
405
449
  }
406
450
 
@@ -6,8 +6,8 @@
6
6
  "use strict";
7
7
 
8
8
  const RuntimeGlobals = require("../RuntimeGlobals");
9
- const formatLocation = require("../formatLocation");
10
9
  const { evaluateToString } = require("../javascript/JavascriptParserHelpers");
10
+ const formatLocation = require("../util/formatLocation");
11
11
  const { propertyAccess } = require("../util/property");
12
12
  const CommonJsExportRequireDependency = require("./CommonJsExportRequireDependency");
13
13
  const CommonJsExportsDependency = require("./CommonJsExportsDependency");
@@ -10,6 +10,11 @@ const { equals } = require("../util/ArrayHelpers");
10
10
  const { getTrimmedIdsAndRange } = require("../util/chainedImports");
11
11
  const makeSerializable = require("../util/makeSerializable");
12
12
  const { propertyAccess } = require("../util/property");
13
+ const {
14
+ ESM_MODULE_EXPORTS_NAME,
15
+ getRequireEsmModuleExportsAccess,
16
+ isRequireEsmModuleExportsModule
17
+ } = require("./CommonJsDependencyHelpers");
13
18
  const ModuleDependency = require("./ModuleDependency");
14
19
 
15
20
  /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
@@ -55,14 +60,22 @@ class CommonJsFullRequireDependency extends ModuleDependency {
55
60
  * @returns {ReferencedExports} referenced exports
56
61
  */
57
62
  getReferencedExports(moduleGraph, runtime) {
58
- if (this.call) {
59
- const importedModule = moduleGraph.getModule(this);
60
- if (
61
- !importedModule ||
62
- importedModule.getExportsType(moduleGraph, false) !== "namespace"
63
- ) {
64
- return [this.names.slice(0, -1)];
65
- }
63
+ const importedModule = moduleGraph.getModule(this);
64
+ if (
65
+ importedModule &&
66
+ isRequireEsmModuleExportsModule(importedModule, moduleGraph)
67
+ ) {
68
+ // When `require(esm)` unwraps a `"module.exports"` named export, the
69
+ // user's property access lands on that value (which webpack does not
70
+ // model), so only the "module.exports" export itself is referenced.
71
+ return [[ESM_MODULE_EXPORTS_NAME]];
72
+ }
73
+ if (
74
+ this.call &&
75
+ (!importedModule ||
76
+ importedModule.getExportsType(moduleGraph, false) !== "namespace")
77
+ ) {
78
+ return [this.names.slice(0, -1)];
66
79
  }
67
80
  return [this.names];
68
81
  }
@@ -128,6 +141,10 @@ CommonJsFullRequireDependency.Template = class CommonJsFullRequireDependencyTemp
128
141
  runtimeRequirements
129
142
  });
130
143
 
144
+ const esmRequireAccess = importedModule
145
+ ? getRequireEsmModuleExportsAccess(importedModule, moduleGraph, runtime)
146
+ : null;
147
+
131
148
  const {
132
149
  trimmedRange: [trimmedRangeStart, trimmedRangeEnd],
133
150
  trimmedIds
@@ -139,7 +156,13 @@ CommonJsFullRequireDependency.Template = class CommonJsFullRequireDependencyTemp
139
156
  dep
140
157
  );
141
158
 
142
- if (importedModule) {
159
+ if (esmRequireAccess !== null) {
160
+ const access = `${esmRequireAccess}${propertyAccess(trimmedIds)}`;
161
+ requireExpr =
162
+ dep.asiSafe === true
163
+ ? `(${requireExpr}${access})`
164
+ : `${requireExpr}${access}`;
165
+ } else if (importedModule) {
143
166
  const usedImported = moduleGraph
144
167
  .getExportsInfo(importedModule)
145
168
  .getUsedName(trimmedIds, runtime);
@@ -5,9 +5,9 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const CommentCompilationWarning = require("../CommentCompilationWarning");
9
8
  const RuntimeGlobals = require("../RuntimeGlobals");
10
- const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning");
9
+ const CommentCompilationWarning = require("../errors/CommentCompilationWarning");
10
+ const UnsupportedFeatureWarning = require("../errors/UnsupportedFeatureWarning");
11
11
  const {
12
12
  evaluateToIdentifier,
13
13
  evaluateToString,
@@ -48,6 +48,22 @@ const RequireResolveHeaderDependency = require("./RequireResolveHeaderDependency
48
48
  * @property {string} context
49
49
  */
50
50
 
51
+ /**
52
+ * Per-`const NAME = require(LITERAL)` binding state used to forward
53
+ * member-access references on `NAME` to the `CommonJsRequireDependency`
54
+ * created for the `require()` call.
55
+ * @typedef {object} RequireBindingData
56
+ * @property {RawReferencedExports} referencedExports mutable list shared with the dependency; pushed to as `NAME.x.y` accesses are walked
57
+ * @property {InstanceType<typeof import("./CommonJsRequireDependency")> | null} dep dependency for the `require()` call (assigned during walk)
58
+ */
59
+
60
+ /** @type {WeakMap<CallExpression, RequireBindingData>} */
61
+ const requireBindingData = new WeakMap();
62
+
63
+ const REQUIRE_BINDING_TAG = Symbol(
64
+ "CommonJsImportsParserPlugin require binding"
65
+ );
66
+
51
67
  const PLUGIN_NAME = "CommonJsImportsParserPlugin";
52
68
 
53
69
  /**
@@ -152,16 +168,26 @@ const createRequireCallHandler = (parser, options, getContext) => {
152
168
  */
153
169
  const processRequireItem = (expr, param) => {
154
170
  if (param.isString()) {
155
- const referencedExports = getRequireReferencedExportsFromDestructuring(
171
+ let referencedExports = getRequireReferencedExportsFromDestructuring(
156
172
  parser,
157
173
  expr
158
174
  );
175
+ const binding = requireBindingData.get(
176
+ /** @type {CallExpression} */ (expr)
177
+ );
178
+ if (binding && !referencedExports) {
179
+ // `const NAME = require(LITERAL)` — let later member-access walks
180
+ // on `NAME` populate the dependency's referenced exports.
181
+ referencedExports = binding.referencedExports;
182
+ }
159
183
  const dep = new CommonJsRequireDependency(
160
184
  /** @type {string} */ (param.string),
161
185
  /** @type {Range} */ (param.range),
162
186
  getContext(),
163
- referencedExports
187
+ referencedExports,
188
+ /** @type {Range} */ (expr.range)
164
189
  );
190
+ if (binding) binding.dep = dep;
165
191
  dep.loc = /** @type {DependencyLocation} */ (expr.loc);
166
192
  dep.optional = Boolean(parser.scope.inTry);
167
193
  parser.state.current.addDependency(dep);
@@ -661,6 +687,88 @@ class CommonJsImportsParserPlugin {
661
687
  .tap(PLUGIN_NAME, callChainHandler);
662
688
  // #endregion
663
689
 
690
+ // #region Require bound to a const variable
691
+ // Track `const NAME = require(LITERAL)` so that static member accesses on
692
+ // `NAME` (e.g. `NAME.foo`, `NAME.foo()`) are forwarded to the same
693
+ // `CommonJsRequireDependency` as referenced exports — enabling tree
694
+ // shaking of CommonJS modules that are imported into a named binding
695
+ // rather than destructured.
696
+ parser.hooks.preDeclarator.tap(PLUGIN_NAME, (declarator, statement) => {
697
+ if (statement.kind !== "const") return;
698
+ if (declarator.id.type !== "Identifier") return;
699
+ if (!declarator.init || declarator.init.type !== "CallExpression") {
700
+ return;
701
+ }
702
+ const init = declarator.init;
703
+ if (
704
+ init.callee.type !== "Identifier" ||
705
+ init.callee.name !== "require" ||
706
+ init.arguments.length !== 1
707
+ ) {
708
+ return;
709
+ }
710
+ const arg = init.arguments[0];
711
+ if (arg.type !== "Literal" || typeof arg.value !== "string") return;
712
+ // Only attach binding state when `require` resolves to the free
713
+ // `require` (i.e. it isn't shadowed in the current scope).
714
+ const requireInfo = parser.getFreeInfoFromVariable("require");
715
+ if (!requireInfo || requireInfo.name !== "require") return;
716
+ /** @type {RequireBindingData} */
717
+ const binding = {
718
+ referencedExports: [],
719
+ dep: null
720
+ };
721
+ requireBindingData.set(init, binding);
722
+ parser.tagVariable(declarator.id.name, REQUIRE_BINDING_TAG, binding);
723
+ return true;
724
+ });
725
+
726
+ parser.hooks.expression.for(REQUIRE_BINDING_TAG).tap(PLUGIN_NAME, () => {
727
+ const binding =
728
+ /** @type {RequireBindingData} */
729
+ (parser.currentTagData);
730
+ if (binding && binding.dep) {
731
+ // `NAME` is read as a value (not as the object of a static member
732
+ // chain), so we have to assume the whole exports object is used.
733
+ binding.dep.referencedExports = null;
734
+ }
735
+ });
736
+
737
+ parser.hooks.expressionMemberChain
738
+ .for(REQUIRE_BINDING_TAG)
739
+ .tap(PLUGIN_NAME, (_expr, members) => {
740
+ const binding =
741
+ /** @type {RequireBindingData} */
742
+ (parser.currentTagData);
743
+ if (binding && binding.dep && binding.dep.referencedExports) {
744
+ binding.dep.referencedExports.push(members);
745
+ }
746
+ // Returning truthy suppresses the parser's fallback chain (which
747
+ // would otherwise walk `NAME` as a bare expression and trigger our
748
+ // `expression` hook above, marking the whole namespace as used).
749
+ return true;
750
+ });
751
+
752
+ parser.hooks.callMemberChain
753
+ .for(REQUIRE_BINDING_TAG)
754
+ .tap(PLUGIN_NAME, (expr, members) => {
755
+ const binding =
756
+ /** @type {RequireBindingData} */
757
+ (parser.currentTagData);
758
+ if (binding && binding.dep && binding.dep.referencedExports) {
759
+ if (members.length === 0) {
760
+ // `NAME(...)` — calling the require result directly; the
761
+ // whole exports object is observable.
762
+ binding.dep.referencedExports = null;
763
+ } else {
764
+ binding.dep.referencedExports.push(members);
765
+ }
766
+ }
767
+ if (expr.arguments) parser.walkExpressions(expr.arguments);
768
+ return true;
769
+ });
770
+ // #endregion
771
+
664
772
  // #region Require.resolve
665
773
  /**
666
774
  * Processes the provided expr.