webpack 5.108.4 → 5.109.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 (200) hide show
  1. package/bin/webpack.js +12 -0
  2. package/lib/APIPlugin.js +48 -29
  3. package/lib/CacheFacade.js +8 -0
  4. package/lib/ChunkGraph.js +17 -15
  5. package/lib/ChunkGroup.js +1 -0
  6. package/lib/CompatibilityPlugin.js +62 -29
  7. package/lib/Compilation.js +58 -6
  8. package/lib/ConstPlugin.js +11 -11
  9. package/lib/ContextModule.js +239 -6
  10. package/lib/ContextModuleFactory.js +139 -14
  11. package/lib/DefinePlugin.js +433 -112
  12. package/lib/Entrypoint.js +1 -1
  13. package/lib/ExportsInfo.js +22 -5
  14. package/lib/ExportsInfoApiPlugin.js +2 -2
  15. package/lib/ExternalModule.js +107 -5
  16. package/lib/ExternalModuleFactoryPlugin.js +20 -1
  17. package/lib/FileSystemInfo.js +256 -100
  18. package/lib/FlagDependencyUsagePlugin.js +33 -12
  19. package/lib/HotModuleReplacementPlugin.js +18 -15
  20. package/lib/InitFragment.js +20 -32
  21. package/lib/Module.js +3 -0
  22. package/lib/ModuleFilenameHelpers.js +2 -2
  23. package/lib/ModuleTypeConstants.js +8 -1
  24. package/lib/MultiCompiler.js +13 -2
  25. package/lib/MultiWatching.js +1 -0
  26. package/lib/NodeStuffPlugin.js +51 -33
  27. package/lib/NormalModule.js +175 -401
  28. package/lib/NormalModuleFactory.js +76 -2
  29. package/lib/ProgressPlugin.js +211 -119
  30. package/lib/ProvidePlugin.js +2 -2
  31. package/lib/RuntimeGlobals.js +47 -0
  32. package/lib/RuntimePlugin.js +67 -107
  33. package/lib/RuntimeTemplate.js +304 -16
  34. package/lib/Template.js +23 -3
  35. package/lib/UseStrictPlugin.js +1 -1
  36. package/lib/WebpackIsIncludedPlugin.js +1 -1
  37. package/lib/WebpackOptionsApply.js +24 -19
  38. package/lib/asset/AssetGenerator.js +110 -28
  39. package/lib/asset/AssetModulesPlugin.js +92 -2
  40. package/lib/asset/WebManifestGenerator.js +164 -0
  41. package/lib/asset/WebManifestParser.js +130 -0
  42. package/lib/async-modules/AwaitDependenciesInitFragment.js +14 -4
  43. package/lib/async-modules/isGeneratorLowered.js +26 -0
  44. package/lib/cache/PackFileCacheStrategy.js +9 -3
  45. package/lib/config/browserslistTargetHandler.js +40 -0
  46. package/lib/config/defaults.js +219 -29
  47. package/lib/config/normalization.js +26 -0
  48. package/lib/config/target.js +9 -1
  49. package/lib/container/HoistContainerReferencesPlugin.js +47 -55
  50. package/lib/css/CssGenerator.js +40 -31
  51. package/lib/css/CssLoadingRuntimeModule.js +5 -1
  52. package/lib/css/CssModulesPlugin.js +13 -0
  53. package/lib/css/CssParser.js +729 -313
  54. package/lib/css/syntax.js +1371 -861
  55. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +6 -6
  56. package/lib/dependencies/AMDPlugin.js +2 -2
  57. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +13 -13
  58. package/lib/dependencies/CommonJsDependencyHelpers.js +39 -0
  59. package/lib/dependencies/CommonJsExportRequireDependency.js +19 -0
  60. package/lib/dependencies/CommonJsExportsDependency.js +47 -2
  61. package/lib/dependencies/CommonJsExportsParserPlugin.js +10 -10
  62. package/lib/dependencies/CommonJsImportsParserPlugin.js +18 -18
  63. package/lib/dependencies/CommonJsPlugin.js +2 -2
  64. package/lib/dependencies/CommonJsRequireDependency.js +26 -1
  65. package/lib/dependencies/CommonJsSelfReferenceDependency.js +32 -1
  66. package/lib/dependencies/ContextDependencyHelpers.js +3 -3
  67. package/lib/dependencies/CreateRequireParserPlugin.js +6 -6
  68. package/lib/dependencies/CssIcssExportDependency.js +162 -71
  69. package/lib/dependencies/CssUrlDependency.js +35 -4
  70. package/lib/dependencies/ExternalModuleInitFragmentDependency.js +2 -2
  71. package/lib/dependencies/HarmonyCompatibilityDependency.js +32 -14
  72. package/lib/dependencies/HarmonyDetectionParserPlugin.js +43 -13
  73. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +2 -1
  74. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +7 -19
  75. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +17 -9
  76. package/lib/dependencies/HarmonyImportDependency.js +13 -2
  77. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +11 -11
  78. package/lib/dependencies/HarmonyImportSpecifierDependency.js +10 -7
  79. package/lib/dependencies/HarmonyModulesPlugin.js +6 -0
  80. package/lib/dependencies/HarmonyTopLevelThisParserPlugin.js +1 -1
  81. package/lib/dependencies/HtmlEntryDependency.js +797 -172
  82. package/lib/dependencies/HtmlSourceDependency.js +26 -0
  83. package/lib/dependencies/ImportDependency.js +43 -1
  84. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +31 -18
  85. package/lib/dependencies/ImportMetaContextPlugin.js +38 -7
  86. package/lib/dependencies/ImportMetaGlobDependency.js +81 -0
  87. package/lib/dependencies/ImportMetaGlobDependencyParserPlugin.js +78 -0
  88. package/lib/dependencies/ImportMetaGlobHelpers.js +660 -0
  89. package/lib/dependencies/ImportMetaPlugin.js +532 -180
  90. package/lib/dependencies/ImportMetaResolveDependency.js +90 -0
  91. package/lib/dependencies/ImportParserPlugin.js +80 -17
  92. package/lib/dependencies/ImportPhase.js +10 -8
  93. package/lib/dependencies/LoaderPlugin.js +5 -1
  94. package/lib/dependencies/RequireContextDependencyParserPlugin.js +1 -1
  95. package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +3 -6
  96. package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +4 -11
  97. package/lib/dependencies/SystemPlugin.js +2 -4
  98. package/lib/dependencies/TopLevelAwaitDependency.js +93 -0
  99. package/lib/dependencies/URLDependency.js +141 -21
  100. package/lib/dependencies/{WorkerPlugin.js → WorkerAndWorkletPlugin.js} +324 -112
  101. package/lib/dependencies/WorkerDependency.js +86 -18
  102. package/lib/dependencies/WorkletDependency.js +278 -0
  103. package/lib/dll/DelegatedModuleFactoryPlugin.js +19 -0
  104. package/lib/errors/EnvironmentNotSupportAsyncWarning.js +1 -1
  105. package/lib/errors/LoaderLoadingError.js +20 -0
  106. package/lib/errors/ModuleParseError.js +39 -22
  107. package/lib/errors/NodeStuffInWebError.js +1 -1
  108. package/lib/esm/ModuleChunkFormatPlugin.js +47 -14
  109. package/lib/esm/ModuleChunkLoadingPlugin.js +8 -1
  110. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +29 -1
  111. package/lib/hmr/lazyCompilationBackend.js +51 -12
  112. package/lib/html/HtmlGenerator.js +907 -15
  113. package/lib/html/HtmlModule.js +2 -2
  114. package/lib/html/HtmlModulesPlugin.js +610 -166
  115. package/lib/html/HtmlParser.js +603 -247
  116. package/lib/html/favicon.svg +1 -0
  117. package/lib/html/syntax.js +3451 -2762
  118. package/lib/ids/IdHelpers.js +25 -11
  119. package/lib/index.js +6 -0
  120. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +4 -5
  121. package/lib/javascript/BasicEvaluatedExpression.js +366 -48
  122. package/lib/javascript/JavascriptGenerator.js +197 -49
  123. package/lib/javascript/JavascriptModulesPlugin.js +178 -24
  124. package/lib/javascript/JavascriptParser.js +704 -355
  125. package/lib/javascript/JavascriptParserHelpers.js +3 -6
  126. package/lib/javascript/syntax.js +5037 -0
  127. package/lib/library/ModuleLibraryPlugin.js +38 -1
  128. package/lib/loaders/LoaderRunner.js +714 -0
  129. package/lib/loaders/loadLoader.js +100 -0
  130. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +29 -2
  131. package/lib/node/ReadFileCompileWasmPlugin.js +24 -2
  132. package/lib/optimize/AggressiveMergingPlugin.js +19 -15
  133. package/lib/optimize/ConcatenatedModule.js +139 -31
  134. package/lib/optimize/FlagIncludedChunksPlugin.js +13 -3
  135. package/lib/optimize/InnerGraphPlugin.js +50 -30
  136. package/lib/optimize/ModuleConcatenationPlugin.js +139 -24
  137. package/lib/optimize/SideEffectsFlagPlugin.js +86 -43
  138. package/lib/optimize/SplitChunksPlugin.js +146 -44
  139. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +15 -0
  140. package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +24 -13
  141. package/lib/prefetch/ResourceHintPlugin.js +687 -0
  142. package/lib/prefetch/ResourceHintRuntimeModule.js +149 -0
  143. package/lib/prefetch/StartupAssetHintRuntimeModule.js +210 -0
  144. package/lib/prefetch/parseResourceHintOptions.js +103 -0
  145. package/lib/rules/RuleSetCompiler.js +114 -0
  146. package/lib/runtime/AsyncModuleGeneratorRuntimeModule.js +56 -0
  147. package/lib/runtime/AsyncModuleRuntimeModule.js +24 -8
  148. package/lib/runtime/AutoPublicPathRuntimeModule.js +7 -1
  149. package/lib/runtime/CommonJsWrapRuntimeModule.js +37 -0
  150. package/lib/runtime/GetWorkletBootstrapRuntimeModule.js +59 -0
  151. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +204 -8
  152. package/lib/runtime/SetAnonymousDefaultNameRuntimeModule.js +4 -1
  153. package/lib/schemes/HttpUriPlugin.js +40 -1
  154. package/lib/schemes/VirtualUrlPlugin.js +1 -2
  155. package/lib/serialization/BinaryMiddleware.js +270 -938
  156. package/lib/serialization/FileMiddleware.js +29 -3
  157. package/lib/stats/DefaultStatsFactoryPlugin.js +229 -194
  158. package/lib/stats/DefaultStatsPresetPlugin.js +2 -0
  159. package/lib/stats/DefaultStatsPrinterPlugin.js +36 -168
  160. package/lib/stats/StatsFactory.js +46 -17
  161. package/lib/url/URLParserPlugin.js +66 -13
  162. package/lib/util/AsyncQueue.js +122 -72
  163. package/lib/util/SetHelpers.js +1 -1
  164. package/lib/util/StackedMap.js +122 -48
  165. package/lib/util/binarySearchBounds.js +2 -2
  166. package/lib/util/concatenate.js +40 -14
  167. package/lib/util/createHooksRegistry.js +13 -5
  168. package/lib/util/dataURL.js +2 -2
  169. package/lib/util/deterministicGrouping.js +7 -5
  170. package/lib/util/formatSize.js +6 -2
  171. package/lib/util/globUtils.js +710 -0
  172. package/lib/util/identifier.js +23 -6
  173. package/lib/util/implicitTypeLoaderFallback.js +62 -0
  174. package/lib/util/internalSerializables.js +88 -71
  175. package/lib/util/magicComment.js +121 -25
  176. package/lib/util/numberHash.js +2 -2
  177. package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +24 -18
  178. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +33 -22
  179. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +79 -16
  180. package/lib/web/FetchCompileAsyncWasmPlugin.js +19 -0
  181. package/lib/web/FetchCompileWasmPlugin.js +14 -0
  182. package/lib/web/JsonpChunkLoadingRuntimeModule.js +2 -0
  183. package/lib/webpack.js +65 -0
  184. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +3 -0
  185. package/module.d.ts +21 -0
  186. package/package.json +12 -11
  187. package/schemas/WebpackOptions.check.js +1 -1
  188. package/schemas/WebpackOptions.json +759 -36
  189. package/schemas/plugins/HtmlParserOptions.check.js +1 -1
  190. package/schemas/plugins/ProgressPlugin.check.js +1 -1
  191. package/schemas/plugins/ProgressPlugin.json +17 -1
  192. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  193. package/schemas/plugins/container/ContainerReferencePlugin.json +1 -0
  194. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  195. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  196. package/schemas/plugins/container/ModuleFederationPlugin.json +1 -0
  197. package/schemas/plugins/css/CssAutoOrModuleParserOptions.check.js +1 -1
  198. package/schemas/plugins/css/CssModuleParserOptions.check.js +1 -1
  199. package/schemas/plugins/css/CssParserOptions.check.js +1 -1
  200. package/types.d.ts +1212 -99
@@ -508,8 +508,18 @@ const MODULE_SIMPLE_PRINTERS = {
508
508
  "module.chunks[]": (id, { formatChunkId }) => formatChunkId(id),
509
509
  "module.depth": (depth, { formatFlag }) =>
510
510
  depth !== null ? formatFlag(`depth ${depth}`) : undefined,
511
- "module.cacheable": (cacheable, { formatFlag, red }) =>
512
- cacheable === false ? red(formatFlag("not cacheable")) : undefined,
511
+ "module.cacheable": (cacheable, { formatFlag, red, module }) =>
512
+ cacheable === false
513
+ ? red(
514
+ formatFlag(
515
+ module.notCacheableReasons && module.notCacheableReasons.length > 0
516
+ ? `not cacheable: ${module.notCacheableReasons.join(", ")}`
517
+ : "not cacheable"
518
+ )
519
+ )
520
+ : undefined,
521
+ // rendered as part of the "module.cacheable" flag
522
+ "module.notCacheableReasons": () => undefined,
513
523
  "module.orphan": (orphan, { formatFlag, yellow }) =>
514
524
  orphan ? yellow(formatFlag("orphan")) : undefined,
515
525
  // "module.runtime": (runtime, { formatFlag, yellow }) =>
@@ -1685,172 +1695,30 @@ class DefaultStatsPrinterPlugin {
1685
1695
  context.timeReference = compilation.time;
1686
1696
  });
1687
1697
 
1688
- for (const key of /** @type {(keyof CompilationSimplePrinters)[]} */ (
1689
- Object.keys(COMPILATION_SIMPLE_PRINTERS)
1690
- )) {
1691
- stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
1692
- /** @type {NonNullable<CompilationSimplePrinters[keyof CompilationSimplePrinters]>} */
1693
- (COMPILATION_SIMPLE_PRINTERS[key])(
1694
- obj,
1695
- /** @type {DefineStatsPrinterContext<"compilation">} */
1696
- (ctx),
1697
- stats
1698
- )
1699
- );
1700
- }
1701
-
1702
- for (const key of /** @type {(keyof AssetSimplePrinters)[]} */ (
1703
- Object.keys(ASSET_SIMPLE_PRINTERS)
1704
- )) {
1705
- stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
1706
- /** @type {NonNullable<AssetSimplePrinters[keyof AssetSimplePrinters]>} */
1707
- (ASSET_SIMPLE_PRINTERS[key])(
1708
- obj,
1709
- /** @type {DefineStatsPrinterContext<"asset" | "asset.info">} */
1710
- (ctx),
1711
- stats
1712
- )
1713
- );
1714
- }
1715
-
1716
- for (const key of /** @type {(keyof ModuleSimplePrinters)[]} */ (
1717
- Object.keys(MODULE_SIMPLE_PRINTERS)
1718
- )) {
1719
- stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
1720
- /** @type {SimplePrinter<EXPECTED_ANY, "module">} */
1721
- (MODULE_SIMPLE_PRINTERS[key])(
1722
- obj,
1723
- /** @type {DefineStatsPrinterContext<"module">} */
1724
- (ctx),
1725
- stats
1726
- )
1727
- );
1728
- }
1729
-
1730
- for (const key of /** @type {(keyof ModuleIssuerPrinters)[]} */ (
1731
- Object.keys(MODULE_ISSUER_PRINTERS)
1732
- )) {
1733
- stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
1734
- /** @type {NonNullable<ModuleIssuerPrinters[keyof ModuleIssuerPrinters]>} */
1735
- (MODULE_ISSUER_PRINTERS[key])(
1736
- obj,
1737
- /** @type {DefineStatsPrinterContext<"moduleIssuer">} */
1738
- (ctx),
1739
- stats
1740
- )
1741
- );
1742
- }
1743
-
1744
- for (const key of /** @type {(keyof ModuleReasonsPrinters)[]} */ (
1745
- Object.keys(MODULE_REASON_PRINTERS)
1746
- )) {
1747
- stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
1748
- /** @type {SimplePrinter<EXPECTED_ANY, "moduleReason">} */
1749
- (MODULE_REASON_PRINTERS[key])(
1750
- obj,
1751
- /** @type {DefineStatsPrinterContext<"moduleReason">} */
1752
- (ctx),
1753
- stats
1754
- )
1755
- );
1756
- }
1757
-
1758
- for (const key of /** @type {(keyof ModuleProfilePrinters)[]} */ (
1759
- Object.keys(MODULE_PROFILE_PRINTERS)
1760
- )) {
1761
- stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
1762
- /** @type {NonNullable<ModuleProfilePrinters[keyof ModuleProfilePrinters]>} */
1763
- (MODULE_PROFILE_PRINTERS[key])(
1764
- obj,
1765
- /** @type {DefineStatsPrinterContext<"profile">} */
1766
- (ctx),
1767
- stats
1768
- )
1769
- );
1770
- }
1771
-
1772
- for (const key of /** @type {(keyof ChunkGroupPrinters)[]} */ (
1773
- Object.keys(CHUNK_GROUP_PRINTERS)
1774
- )) {
1775
- stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
1776
- /** @type {SimplePrinter<EXPECTED_ANY, "chunkGroupKind" | "chunkGroup">} */
1777
- (CHUNK_GROUP_PRINTERS[key])(
1778
- obj,
1779
- /** @type {DefineStatsPrinterContext<"chunkGroupKind" | "chunkGroup">} */
1780
- (ctx),
1781
- stats
1782
- )
1783
- );
1784
- }
1785
-
1786
- for (const key of /** @type {(keyof ChunkPrinters)[]} */ (
1787
- Object.keys(CHUNK_PRINTERS)
1788
- )) {
1789
- stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
1790
- /** @type {SimplePrinter<EXPECTED_ANY, "chunk">} */
1791
- (CHUNK_PRINTERS[key])(
1792
- obj,
1793
- /** @type {DefineStatsPrinterContext<"chunk">} */
1794
- (ctx),
1795
- stats
1796
- )
1797
- );
1798
- }
1799
-
1800
- for (const key of /** @type {(keyof ErrorPrinters)[]} */ (
1801
- Object.keys(ERROR_PRINTERS)
1802
- )) {
1803
- stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
1804
- /** @type {SimplePrinter<EXPECTED_ANY, "error">} */
1805
- (ERROR_PRINTERS[key])(
1806
- obj,
1807
- /** @type {DefineStatsPrinterContext<"error">} */
1808
- (ctx),
1809
- stats
1810
- )
1811
- );
1812
- }
1813
-
1814
- for (const key of /** @type {(keyof LogEntryPrinters)[]} */ (
1815
- Object.keys(LOG_ENTRY_PRINTERS)
1816
- )) {
1817
- stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
1818
- /** @type {SimplePrinter<EXPECTED_ANY, "logging">} */
1819
- (LOG_ENTRY_PRINTERS[key])(
1820
- obj,
1821
- /** @type {DefineStatsPrinterContext<"logging">} */
1822
- (ctx),
1823
- stats
1824
- )
1825
- );
1826
- }
1827
-
1828
- for (const key of /** @type {(keyof ModuleTraceDependencyPrinters)[]} */ (
1829
- Object.keys(MODULE_TRACE_DEPENDENCY_PRINTERS)
1830
- )) {
1831
- stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
1832
- /** @type {NonNullable<ModuleTraceDependencyPrinters[keyof ModuleTraceDependencyPrinters]>} */
1833
- (MODULE_TRACE_DEPENDENCY_PRINTERS[key])(
1834
- obj,
1835
- /** @type {DefineStatsPrinterContext<"moduleTraceDependency">} */
1836
- (ctx),
1837
- stats
1838
- )
1839
- );
1840
- }
1841
-
1842
- for (const key of /** @type {(keyof ModuleTraceItemPrinters)[]} */ (
1843
- Object.keys(MODULE_TRACE_ITEM_PRINTERS)
1844
- )) {
1845
- stats.hooks.print.for(key).tap(PLUGIN_NAME, (obj, ctx) =>
1846
- /** @type {NonNullable<ModuleTraceItemPrinters[keyof ModuleTraceItemPrinters]>} */
1847
- (MODULE_TRACE_ITEM_PRINTERS[key])(
1848
- obj,
1849
- /** @type {DefineStatsPrinterContext<"moduleTraceItem">} */
1850
- (ctx),
1851
- stats
1852
- )
1853
- );
1698
+ // Every `*_SIMPLE_PRINTERS` map registers identically: tap
1699
+ // `print.for(key)` with a formatter called as `(obj, ctx, stats)`.
1700
+ // One loop over all maps replaces a dozen near-identical blocks.
1701
+ for (const simplePrinters of /** @type {Record<string, EXPECTED_ANY>[]} */ ([
1702
+ COMPILATION_SIMPLE_PRINTERS,
1703
+ ASSET_SIMPLE_PRINTERS,
1704
+ MODULE_SIMPLE_PRINTERS,
1705
+ MODULE_ISSUER_PRINTERS,
1706
+ MODULE_REASON_PRINTERS,
1707
+ MODULE_PROFILE_PRINTERS,
1708
+ CHUNK_GROUP_PRINTERS,
1709
+ CHUNK_PRINTERS,
1710
+ ERROR_PRINTERS,
1711
+ LOG_ENTRY_PRINTERS,
1712
+ MODULE_TRACE_DEPENDENCY_PRINTERS,
1713
+ MODULE_TRACE_ITEM_PRINTERS
1714
+ ])) {
1715
+ for (const key of Object.keys(simplePrinters)) {
1716
+ stats.hooks.print
1717
+ .for(key)
1718
+ .tap(PLUGIN_NAME, (obj, ctx) =>
1719
+ simplePrinters[key](obj, ctx, stats)
1720
+ );
1721
+ }
1854
1722
  }
1855
1723
 
1856
1724
  for (const key of Object.keys(PREFERRED_ORDERS)) {
@@ -6,7 +6,6 @@
6
6
  "use strict";
7
7
 
8
8
  const { HookMap, SyncBailHook, SyncWaterfallHook } = require("tapable");
9
- const { concatComparators, keepOriginalOrder } = require("../util/comparators");
10
9
  const smartGrouping = require("../util/smartGrouping");
11
10
 
12
11
  /** @typedef {import("../Chunk")} Chunk */
@@ -294,10 +293,7 @@ class StatsFactory {
294
293
  h.call(comparators, context)
295
294
  );
296
295
  if (comparators.length > 0) {
297
- items.sort(
298
- // @ts-expect-error number of arguments is correct
299
- concatComparators(...comparators, keepOriginalOrder(items))
300
- );
296
+ sortWithOriginalOrder(items, comparators);
301
297
  }
302
298
 
303
299
  // run filter on sorted items
@@ -310,23 +306,30 @@ class StatsFactory {
310
306
  false
311
307
  );
312
308
 
313
- // for each item
309
+ // reuse one item context; create() spreads it synchronously, so mutating
310
+ // `_index`/the name key between items is safe and skips a per-item spread
311
+ /** @type {StatsFactoryContext} */
312
+ const itemContext = { ...context };
313
+ const itemNameType = `${type}[]`;
314
+ /** @type {string | void} */
315
+ let prevItemName;
314
316
  let resultItems = items2.map((item, i) => {
315
- /** @type {StatsFactoryContext} */
316
- const itemContext = {
317
- ...context,
318
- _index: i
319
- };
317
+ itemContext._index = i;
320
318
 
321
319
  // run getItemName
322
320
  const itemName = this._forEachLevel(
323
321
  this.hooks.getItemName,
324
322
  this._caches.getItemName,
325
- `${type}[]`,
323
+ itemNameType,
326
324
  (h) => h.call(item, itemContext)
327
325
  );
326
+ // drop a previous item's name key before adding this one's
327
+ if (prevItemName !== undefined && prevItemName !== itemName) {
328
+ delete itemContext[prevItemName];
329
+ }
328
330
  if (itemName) itemContext[itemName] = item;
329
- const innerType = itemName ? `${type}[].${itemName}` : `${type}[]`;
331
+ prevItemName = itemName;
332
+ const innerType = itemName ? `${type}[].${itemName}` : itemNameType;
330
333
 
331
334
  // run getItemFactory
332
335
  const itemFactory =
@@ -351,10 +354,7 @@ class StatsFactory {
351
354
  (h) => h.call(comparators2, context)
352
355
  );
353
356
  if (comparators2.length > 0) {
354
- resultItems.sort(
355
- // @ts-expect-error number of arguments is correct
356
- concatComparators(...comparators2, keepOriginalOrder(resultItems))
357
- );
357
+ sortWithOriginalOrder(resultItems, comparators2);
358
358
  }
359
359
 
360
360
  // group result items
@@ -417,4 +417,33 @@ class StatsFactory {
417
417
  }
418
418
  }
419
419
 
420
+ /**
421
+ * Stable in-place sort applying comparators in order, keeping the original order
422
+ * for equal items. Inlined instead of `concatComparators(...c, keepOriginalOrder())`
423
+ * because that combination is single-use per sort and only thrashes the comparator
424
+ * caches (a fresh tiebreaker closure every call allocates a new cache entry).
425
+ * @param {EXPECTED_ANY[]} items items to sort in place
426
+ * @param {Comparator[]} comparators comparators applied in order
427
+ * @returns {void}
428
+ */
429
+ const sortWithOriginalOrder = (items, comparators) => {
430
+ // original-index tiebreaker keeps the sort stable on engines without a stable Array.sort
431
+ /** @type {Map<EXPECTED_ANY, number>} */
432
+ const originalOrder = new Map();
433
+ for (let i = 0; i < items.length; i++) {
434
+ originalOrder.set(items[i], i);
435
+ }
436
+ const count = comparators.length;
437
+ items.sort((a, b) => {
438
+ for (let i = 0; i < count; i++) {
439
+ const res = comparators[i](a, b);
440
+ if (res !== 0) return res;
441
+ }
442
+ return (
443
+ /** @type {number} */ (originalOrder.get(a)) -
444
+ /** @type {number} */ (originalOrder.get(b))
445
+ );
446
+ });
447
+ };
448
+
420
449
  module.exports = StatsFactory;
@@ -9,6 +9,9 @@ const { pathToFileURL } = require("url");
9
9
  const RuntimeGlobals = require("../RuntimeGlobals");
10
10
  const ConstDependency = require("../dependencies/ConstDependency");
11
11
  const ContextDependencyHelpers = require("../dependencies/ContextDependencyHelpers");
12
+ const {
13
+ isImportMetaFieldEnabled
14
+ } = require("../dependencies/ImportMetaPlugin");
12
15
  const URLContextDependency = require("../dependencies/URLContextDependency");
13
16
  const URLDependency = require("../dependencies/URLDependency");
14
17
  const CommentCompilationWarning = require("../errors/CommentCompilationWarning");
@@ -16,6 +19,7 @@ const UnsupportedFeatureWarning = require("../errors/UnsupportedFeatureWarning")
16
19
  const BasicEvaluatedExpression = require("../javascript/BasicEvaluatedExpression");
17
20
  const { approve } = require("../javascript/JavascriptParserHelpers");
18
21
  const { getInnerGraphUtils } = require("../optimize/InnerGraph");
22
+ const ResourceHintPlugin = require("../prefetch/ResourceHintPlugin");
19
23
 
20
24
  /** @typedef {import("estree").MemberExpression} MemberExpression */
21
25
  /** @typedef {import("estree").NewExpression} NewExpressionNode */
@@ -78,7 +82,7 @@ const keepNewURL = (parser, expr) => {
78
82
  /** @type {Range} */ (arg2.range),
79
83
  [RuntimeGlobals.baseURI]
80
84
  );
81
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
85
+ dep.loc = parser.getLocation(expr);
82
86
  parser.state.module.addPresentationalDependency(dep);
83
87
  };
84
88
 
@@ -89,9 +93,10 @@ const getEvaluatedExprCache = new WeakMap();
89
93
  * Gets evaluated expr.
90
94
  * @param {NewExpressionNode} expr expression
91
95
  * @param {JavascriptParser} parser parser parser
96
+ * @param {boolean} importMetaUrlEnabled true when import.meta.url should be handled
92
97
  * @returns {BasicEvaluatedExpression | undefined} basic evaluated expression
93
98
  */
94
- const getEvaluatedExpr = (expr, parser) => {
99
+ const getEvaluatedExpr = (expr, parser, importMetaUrlEnabled) => {
95
100
  let result = getEvaluatedExprCache.get(expr);
96
101
  if (result !== undefined) return result;
97
102
 
@@ -107,7 +112,9 @@ const getEvaluatedExpr = (expr, parser) => {
107
112
  if (arg2.type !== "MemberExpression" || arg1.type === "SpreadElement") {
108
113
  return;
109
114
  }
110
- if (!isMetaUrl(parser, arg2)) return;
115
+ if (!importMetaUrlEnabled || !isMetaUrl(parser, arg2)) {
116
+ return;
117
+ }
111
118
 
112
119
  return parser.evaluateExpression(arg1);
113
120
  };
@@ -118,6 +125,13 @@ const getEvaluatedExpr = (expr, parser) => {
118
125
  return result;
119
126
  };
120
127
 
128
+ /**
129
+ * @typedef {object} ResolvedResourceHints
130
+ * @property {boolean=} prefetch project-wide prefetch default
131
+ * @property {boolean=} preload project-wide preload default
132
+ * @property {("low" | "high" | "auto" | false)=} fetchPriority project-wide fetchPriority default
133
+ */
134
+
121
135
  class URLParserPlugin {
122
136
  /**
123
137
  * Creates an instance of URLParserPlugin.
@@ -135,10 +149,18 @@ class URLParserPlugin {
135
149
  */
136
150
  apply(parser) {
137
151
  const relative = this.options.url === "relative";
152
+ const importMetaUrlEnabled = isImportMetaFieldEnabled(
153
+ this.options.importMeta,
154
+ "url"
155
+ );
138
156
 
139
157
  parser.hooks.canRename.for("URL").tap(PLUGIN_NAME, approve);
140
158
  parser.hooks.evaluateNewExpression.for("URL").tap(PLUGIN_NAME, (expr) => {
141
- const evaluatedExpr = getEvaluatedExpr(expr, parser);
159
+ const evaluatedExpr = getEvaluatedExpr(
160
+ expr,
161
+ parser,
162
+ importMetaUrlEnabled
163
+ );
142
164
  const request = evaluatedExpr && evaluatedExpr.asString();
143
165
 
144
166
  if (!request) return;
@@ -159,7 +181,7 @@ class URLParserPlugin {
159
181
  parser.state.module.addWarning(
160
182
  new CommentCompilationWarning(
161
183
  `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
162
- /** @type {DependencyLocation} */ (comment.loc)
184
+ parser.getLocation(comment)
163
185
  )
164
186
  );
165
187
  }
@@ -170,7 +192,7 @@ class URLParserPlugin {
170
192
  parser.state.module.addWarning(
171
193
  new UnsupportedFeatureWarning(
172
194
  `\`webpackIgnore\` expected a boolean, but received: ${importOptions.webpackIgnore}.`,
173
- /** @type {DependencyLocation} */ (expr.loc)
195
+ parser.getLocation(expr)
174
196
  )
175
197
  );
176
198
  return;
@@ -179,7 +201,11 @@ class URLParserPlugin {
179
201
 
180
202
  const [, arg2] = expr.arguments;
181
203
 
182
- if (arg2.type !== "MemberExpression" || !isMetaUrl(parser, arg2)) {
204
+ if (
205
+ arg2.type !== "MemberExpression" ||
206
+ !importMetaUrlEnabled ||
207
+ !isMetaUrl(parser, arg2)
208
+ ) {
183
209
  return;
184
210
  }
185
211
 
@@ -189,7 +215,11 @@ class URLParserPlugin {
189
215
  }
190
216
  }
191
217
 
192
- const evaluatedExpr = getEvaluatedExpr(expr, parser);
218
+ const evaluatedExpr = getEvaluatedExpr(
219
+ expr,
220
+ parser,
221
+ importMetaUrlEnabled
222
+ );
193
223
  if (!evaluatedExpr) return;
194
224
 
195
225
  /** @type {string | undefined} */
@@ -213,8 +243,27 @@ class URLParserPlugin {
213
243
  /** @type {Range} */ (expr.range),
214
244
  relative
215
245
  );
216
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
246
+ dep.loc = parser.getLocation(expr);
247
+ // `parser.javascript.urlHints` provides project-wide defaults
248
+ // (resolved per-request, with `test` / `include` / `exclude`
249
+ // matching); a per-URL magic comment for the same hint wins
250
+ // when both are set.
251
+ ResourceHintPlugin.applyResourceHints(
252
+ dep,
253
+ this.options.urlHints,
254
+ request,
255
+ importOptions,
256
+ parser.state.module,
257
+ parser.getLocation(expr)
258
+ );
217
259
  parser.state.current.addDependency(dep);
260
+ // For ESM module output the template embeds the asset's resolved
261
+ // filename, so the asset must be code-generated first. Only added in
262
+ // that mode — a code-gen dependency on an asset that a later watch
263
+ // rebuild leaves unaffected can otherwise deadlock the scheduler.
264
+ if (parser.state.compilation.options.output.module) {
265
+ parser.state.module.addCodeGenerationDependency(dep);
266
+ }
218
267
  getInnerGraphUtils(parser.state.compilation).onUsage(
219
268
  parser.state,
220
269
  (e) => (dep.usedByExports = e)
@@ -239,7 +288,7 @@ class URLParserPlugin {
239
288
  parser.state.module.addWarning(
240
289
  new UnsupportedFeatureWarning(
241
290
  `\`webpackInclude\` expected a regular expression, but received: ${importOptions.webpackInclude}.`,
242
- /** @type {DependencyLocation} */ (expr.loc)
291
+ parser.getLocation(expr)
243
292
  )
244
293
  );
245
294
  } else {
@@ -254,7 +303,7 @@ class URLParserPlugin {
254
303
  parser.state.module.addWarning(
255
304
  new UnsupportedFeatureWarning(
256
305
  `\`webpackExclude\` expected a regular expression, but received: ${importOptions.webpackExclude}.`,
257
- /** @type {DependencyLocation} */ (expr.loc)
306
+ parser.getLocation(expr)
258
307
  )
259
308
  );
260
309
  } else {
@@ -278,7 +327,7 @@ class URLParserPlugin {
278
327
  parser
279
328
  );
280
329
  if (!dep) return;
281
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
330
+ dep.loc = parser.getLocation(expr);
282
331
  dep.optional = Boolean(parser.scope.inTry);
283
332
  parser.state.current.addDependency(dep);
284
333
  return true;
@@ -290,7 +339,11 @@ class URLParserPlugin {
290
339
  const calleeInfo = parser.getFreeInfoFromVariable(callee.name);
291
340
  if (!calleeInfo || calleeInfo.name !== "URL") return;
292
341
 
293
- const evaluatedExpr = getEvaluatedExpr(expr, parser);
342
+ const evaluatedExpr = getEvaluatedExpr(
343
+ expr,
344
+ parser,
345
+ importMetaUrlEnabled
346
+ );
294
347
  const request = evaluatedExpr && evaluatedExpr.asString();
295
348
 
296
349
  if (request) return true;