@depup/webpack 5.110.3-depup.0 → 5.111.1-depup.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 (283) hide show
  1. package/README.md +7 -8
  2. package/changes.json +7 -11
  3. package/lib/APIPlugin.js +26 -11
  4. package/lib/AutomaticPrefetchPlugin.js +1 -1
  5. package/lib/Cache.js +8 -3
  6. package/lib/CacheFacade.js +1 -1
  7. package/lib/CircularModulesPlugin.js +157 -55
  8. package/lib/CleanPlugin.js +2 -2
  9. package/lib/CompatibilityPlugin.js +3 -4
  10. package/lib/Compilation.js +336 -337
  11. package/lib/Compiler.js +213 -51
  12. package/lib/ConstPlugin.js +16 -132
  13. package/lib/CopyPlugin.js +1054 -0
  14. package/lib/DefinePlugin.js +24 -8
  15. package/lib/DependencyTemplate.js +2 -1
  16. package/lib/DotenvPlugin.js +24 -28
  17. package/lib/ErrorHelpers.js +113 -0
  18. package/lib/ExportsInfo.js +20 -16
  19. package/lib/ExternalModule.js +47 -22
  20. package/lib/FileSystemInfo.js +17 -14
  21. package/lib/FlagDependencyExportsPlugin.js +53 -34
  22. package/lib/FlagDependencyUsagePlugin.js +9 -13
  23. package/lib/Generator.js +24 -2
  24. package/lib/HotModuleReplacementPlugin.js +55 -7
  25. package/lib/IgnorePlugin.js +1 -1
  26. package/lib/JavascriptMetaInfoPlugin.js +5 -3
  27. package/lib/LoaderOptionsPlugin.js +1 -1
  28. package/lib/MainTemplate.js +5 -1
  29. package/lib/Module.js +19 -10
  30. package/lib/ModuleGraph.js +6 -9
  31. package/lib/MultiCompiler.js +7 -17
  32. package/lib/MultiWatching.js +1 -1
  33. package/lib/NormalModule.js +135 -50
  34. package/lib/NormalModuleFactory.js +1 -1
  35. package/lib/RuntimeGlobals.js +21 -7
  36. package/lib/RuntimeModule.js +28 -12
  37. package/lib/RuntimePlugin.js +30 -3
  38. package/lib/RuntimeTemplate.js +813 -518
  39. package/lib/SourceMapDevToolPlugin.js +54 -104
  40. package/lib/TemplatedPathPlugin.js +16 -59
  41. package/lib/Watching.js +9 -0
  42. package/lib/WebpackOptionsApply.js +84 -91
  43. package/lib/asset/AssetBytesGenerator.js +7 -1
  44. package/lib/asset/AssetGenerator.js +50 -24
  45. package/lib/asset/AssetModule.js +3 -0
  46. package/lib/asset/AssetSourceGenerator.js +7 -1
  47. package/lib/asset/WebManifestParser.js +7 -5
  48. package/lib/buildChunkGraph.js +11 -15
  49. package/lib/cache/AddBuildDependenciesPlugin.js +33 -4
  50. package/lib/cache/IdleFileCachePlugin.js +2 -2
  51. package/lib/cache/MemoryCachePlugin.js +4 -4
  52. package/lib/cache/MemoryWithGcCachePlugin.js +7 -8
  53. package/lib/cache/PackFileCacheStrategy.js +17 -19
  54. package/lib/cache/getLazyHashedEtag.js +3 -5
  55. package/lib/config/browserslistTargetHandler.js +17 -4
  56. package/lib/config/defaults.js +138 -128
  57. package/lib/config/getClaimedAssetTypes.js +10 -11
  58. package/lib/config/normalization.js +82 -12
  59. package/lib/config/target.js +13 -4
  60. package/lib/container/ContainerReferencePlugin.js +6 -0
  61. package/lib/container/RemoteRuntimeModule.js +9 -0
  62. package/lib/container/declaredRemotes.js +39 -0
  63. package/lib/{ContextExclusionPlugin.js → context/ContextExclusionPlugin.js} +1 -1
  64. package/lib/{ContextModule.js → context/ContextModule.js} +54 -115
  65. package/lib/{ContextModuleFactory.js → context/ContextModuleFactory.js} +19 -21
  66. package/lib/{ContextReplacementPlugin.js → context/ContextReplacementPlugin.js} +4 -4
  67. package/lib/css/CssGenerator.js +27 -11
  68. package/lib/css/CssInjectStyleRuntimeModule.js +9 -0
  69. package/lib/css/CssLoadingRuntimeModule.js +94 -36
  70. package/lib/css/CssModule.js +1 -1
  71. package/lib/css/CssModulesPlugin.js +7 -6
  72. package/lib/css/CssParser.js +162 -31
  73. package/lib/css/CssServerStylesRuntimeModule.js +9 -0
  74. package/lib/css/cssMinify.js +43 -32
  75. package/lib/css/data.js +3514 -869
  76. package/lib/css/syntax.js +6370 -1220
  77. package/lib/debug/ProfilingPlugin.js +7 -4
  78. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +6 -3
  79. package/lib/dependencies/AMDRuntimeModules.js +18 -0
  80. package/lib/dependencies/CommonJsExportRequireDependency.js +13 -12
  81. package/lib/dependencies/CommonJsExportsParserPlugin.js +12 -13
  82. package/lib/dependencies/CommonJsImportsParserPlugin.js +5 -5
  83. package/lib/dependencies/CommonJsPlugin.js +19 -3
  84. package/lib/dependencies/CommonJsRequireDependency.js +14 -5
  85. package/lib/dependencies/CommonJsSelfReferenceDependency.js +2 -4
  86. package/lib/dependencies/ContextDependency.js +1 -1
  87. package/lib/dependencies/ContextDependencyHelpers.js +3 -9
  88. package/lib/dependencies/ContextElementDependency.js +1 -1
  89. package/lib/dependencies/CssIcssExportDependency.js +13 -9
  90. package/lib/dependencies/CssIcssImportDependency.js +3 -6
  91. package/lib/dependencies/CssUrlDependency.js +3 -5
  92. package/lib/dependencies/HarmonyCompatibilityDependency.js +67 -22
  93. package/lib/dependencies/HarmonyDetectionParserPlugin.js +3 -4
  94. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +10 -7
  95. package/lib/dependencies/HarmonyExportExpressionDependency.js +47 -33
  96. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +74 -17
  97. package/lib/dependencies/HarmonyExportInitFragment.js +110 -23
  98. package/lib/dependencies/HarmonyExportSpecifierDependency.js +25 -58
  99. package/lib/dependencies/HarmonyImportBareSideEffectDependency.js +59 -0
  100. package/lib/dependencies/HarmonyImportDependency.js +6 -1
  101. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +111 -17
  102. package/lib/dependencies/HarmonyImportSideEffectDependency.js +3 -4
  103. package/lib/dependencies/HarmonyImportSpecifierDependency.js +40 -3
  104. package/lib/dependencies/HarmonyModulesPlugin.js +20 -0
  105. package/lib/dependencies/HtmlEntryDependency.js +124 -102
  106. package/lib/dependencies/HtmlInlineScriptDependency.js +3 -4
  107. package/lib/dependencies/HtmlInlineStyleDependency.js +3 -4
  108. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +1 -1
  109. package/lib/dependencies/ImportMetaGlobHelpers.js +1 -1
  110. package/lib/dependencies/ImportMetaMainDependency.js +104 -0
  111. package/lib/dependencies/ImportMetaPlugin.js +67 -25
  112. package/lib/dependencies/ImportParserPlugin.js +1 -1
  113. package/lib/dependencies/LoaderPlugin.js +26 -1
  114. package/lib/dependencies/RequireContextDependencyParserPlugin.js +1 -1
  115. package/lib/dependencies/SystemRuntimeModule.js +9 -0
  116. package/lib/dependencies/URLContextDependency.js +1 -1
  117. package/lib/dependencies/URLDependency.js +6 -5
  118. package/lib/dependencies/WorkerAndWorkletPlugin.js +15 -21
  119. package/lib/dependencies/WorkerDependency.js +7 -7
  120. package/lib/dependencies/WorkletDependency.js +7 -11
  121. package/lib/dll/DelegatedModule.js +18 -1
  122. package/lib/dll/DllReferencePlugin.js +11 -8
  123. package/lib/dll/LibManifestPlugin.js +1 -1
  124. package/lib/errors/AnalyzableBailoutsWarning.js +41 -0
  125. package/lib/errors/DuplicateModulesWarning.js +12 -7
  126. package/lib/errors/EmptyCopyPatternWarning.js +26 -0
  127. package/lib/errors/ExternalStarReexportError.js +44 -0
  128. package/lib/errors/HookWebpackError.js +3 -2
  129. package/lib/errors/MissingSourceMapsWarning.js +36 -0
  130. package/lib/errors/ModuleParseError.js +2 -1
  131. package/lib/errors/UnusedAssetsWarning.js +36 -0
  132. package/lib/errors/UnusedFederationWarning.js +35 -0
  133. package/lib/errors/UnusedModulesWarning.js +38 -0
  134. package/lib/esm/ExportWebpackRequireRuntimeModule.js +9 -0
  135. package/lib/esm/ModuleChunkFormatPlugin.js +28 -3
  136. package/lib/esm/ModuleChunkLoadingPlugin.js +30 -11
  137. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +92 -60
  138. package/lib/hmr/HotModuleReplacement.runtime.js +8 -2
  139. package/lib/hmr/HotModuleReplacementRuntimeModule.js +9 -0
  140. package/lib/hmr/LazyCompilationPlugin.js +3 -5
  141. package/lib/html/HtmlGenerator.js +72 -87
  142. package/lib/html/HtmlModulesPlugin.js +418 -200
  143. package/lib/html/HtmlParser.js +110 -147
  144. package/lib/html/builtinEmbeddedRenderer.js +107 -0
  145. package/lib/html/data.js +142 -7
  146. package/lib/html/htmlMinify.js +92 -122
  147. package/lib/html/syntax.js +1618 -1391
  148. package/lib/ids/HashedModuleIdsPlugin.js +2 -1
  149. package/lib/index.js +49 -3
  150. package/lib/javascript/ChunkFormatHelpers.js +4 -3
  151. package/lib/javascript/JavascriptGenerator.js +8 -1
  152. package/lib/javascript/JavascriptModule.js +1 -0
  153. package/lib/javascript/JavascriptModulesPlugin.js +73 -72
  154. package/lib/javascript/JavascriptParser.js +1970 -900
  155. package/lib/javascript/StartupHelpers.js +27 -3
  156. package/lib/javascript/data.js +172 -0
  157. package/lib/javascript/grammar.js +5546 -0
  158. package/lib/javascript/parser.js +1500 -0
  159. package/lib/javascript/regexp.js +1762 -0
  160. package/lib/javascript/regexpData.js +51 -0
  161. package/lib/javascript/syntax.js +9061 -5262
  162. package/lib/json/JsonGenerator.js +7 -1
  163. package/lib/library/ModuleLibraryPlugin.js +171 -132
  164. package/lib/loaders/LoaderRunner.js +137 -9
  165. package/lib/node/NodeWatchFileSystem.js +3 -9
  166. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +22 -0
  167. package/lib/node/RequireChunkLoadingRuntimeModule.js +22 -0
  168. package/lib/optimize/AggressiveMergingPlugin.js +3 -5
  169. package/lib/optimize/ConcatenatedModule.js +178 -120
  170. package/lib/optimize/ConstExportsPlugin.js +50 -39
  171. package/lib/optimize/FlagIncludedChunksPlugin.js +3 -11
  172. package/lib/optimize/InlineExports.js +20 -123
  173. package/lib/optimize/InnerGraphPlugin.js +7 -13
  174. package/lib/optimize/LimitChunkCountPlugin.js +5 -8
  175. package/lib/optimize/MangleExportsPlugin.js +13 -4
  176. package/lib/optimize/ModuleConcatenationPlugin.js +27 -5
  177. package/lib/optimize/RealContentHashPlugin.js +68 -9
  178. package/lib/optimize/SideEffectsFlagPlugin.js +24 -28
  179. package/lib/optimize/SplitChunksPlugin.js +2 -4
  180. package/lib/performance/AnalyzableBailoutsPlugin.js +115 -0
  181. package/lib/performance/BroadContextsPlugin.js +1 -1
  182. package/lib/performance/CacheEffectivenessPlugin.js +7 -7
  183. package/lib/performance/DuplicateModulesPlugin.js +57 -13
  184. package/lib/performance/EvalUsagePlugin.js +5 -2
  185. package/lib/performance/MissingSourceMapsPlugin.js +115 -0
  186. package/lib/performance/PureAnnotationsPlugin.js +6 -3
  187. package/lib/performance/SizeLimitsPlugin.js +2 -4
  188. package/lib/performance/TopLevelThisPlugin.js +5 -4
  189. package/lib/performance/UnusedAssetsPlugin.js +109 -0
  190. package/lib/performance/UnusedFederationPlugin.js +147 -0
  191. package/lib/performance/UnusedModulesPlugin.js +141 -0
  192. package/lib/performance/UnusedReexportsPlugin.js +1 -55
  193. package/lib/performance/isOnlyReexported.js +65 -0
  194. package/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js +25 -5
  195. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +8 -8
  196. package/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js +9 -0
  197. package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +9 -0
  198. package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +9 -0
  199. package/lib/prefetch/ResourceHintPlugin.js +18 -23
  200. package/lib/prefetch/ResourceHintRuntimeModule.js +9 -0
  201. package/lib/prefetch/StartupAssetHintRuntimeModule.js +16 -10
  202. package/lib/rules/RuleSetCompiler.js +211 -4
  203. package/lib/runtime/AsyncModuleRuntimeModule.js +98 -66
  204. package/lib/runtime/AutoPublicPathRuntimeModule.js +9 -0
  205. package/lib/runtime/BaseUriRuntimeModule.js +9 -0
  206. package/lib/runtime/ChunkNameRuntimeModule.js +9 -0
  207. package/lib/runtime/EnsureChunkRuntimeModule.js +35 -16
  208. package/lib/runtime/GetChunkFilenameRuntimeModule.js +12 -4
  209. package/lib/runtime/GetFullHashRuntimeModule.js +9 -0
  210. package/lib/runtime/GetMainFilenameRuntimeModule.js +9 -0
  211. package/lib/runtime/GetWorkletBootstrapRuntimeModule.js +9 -0
  212. package/lib/runtime/GlobalRuntimeModule.js +11 -4
  213. package/lib/runtime/HasOwnPropertyRuntimeModule.js +9 -0
  214. package/lib/runtime/HelperRuntimeModule.js +10 -0
  215. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +305 -224
  216. package/lib/runtime/NonceRuntimeModule.js +9 -0
  217. package/lib/runtime/OnChunksLoadedRuntimeModule.js +67 -20
  218. package/lib/runtime/PublicPathRuntimeModule.js +9 -0
  219. package/lib/runtime/RuntimeIdRuntimeModule.js +9 -0
  220. package/lib/runtime/SpecNamespaceObjectRuntimeModule.js +90 -0
  221. package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +9 -0
  222. package/lib/runtime/StartupEntrypointRuntimeModule.js +9 -0
  223. package/lib/runtime/SystemContextRuntimeModule.js +9 -0
  224. package/lib/runtime/ToBinaryRuntimeModule.js +9 -0
  225. package/lib/schemes/DataUriPlugin.js +3 -6
  226. package/lib/schemes/VirtualUrlPlugin.js +1 -1
  227. package/lib/serialization/BinaryMiddleware.js +9 -9
  228. package/lib/serialization/FileMiddleware.js +16 -16
  229. package/lib/serialization/ObjectMiddleware.js +168 -139
  230. package/lib/sharing/ConsumeSharedPlugin.js +12 -0
  231. package/lib/sharing/ConsumeSharedRuntimeModule.js +11 -0
  232. package/lib/sharing/ShareRuntimeModule.js +9 -0
  233. package/lib/sharing/declaredShared.js +47 -0
  234. package/lib/stats/DefaultStatsFactoryPlugin.js +6 -5
  235. package/lib/stats/DefaultStatsPrinterPlugin.js +3 -0
  236. package/lib/typescript/TypeScriptPlugin.js +2 -3
  237. package/lib/url/URLParserPlugin.js +6 -8
  238. package/lib/util/LocConverter.js +4 -7
  239. package/lib/util/SourceProcessor.js +91 -91
  240. package/lib/util/async.js +292 -0
  241. package/lib/util/buildDiagnostics.js +69 -0
  242. package/lib/util/chainedImports.js +3 -4
  243. package/lib/util/concatenate.js +4 -4
  244. package/lib/util/createHooksRegistry.js +1 -2
  245. package/lib/util/dataURL.js +2 -3
  246. package/lib/util/deterministicGrouping.js +8 -13
  247. package/lib/util/findGraphRoots.js +6 -13
  248. package/lib/util/fs.js +27 -1
  249. package/lib/util/globUtils.js +1 -1
  250. package/lib/util/handlerKeys.js +40 -0
  251. package/lib/util/hash/wasm-hash.js +3 -4
  252. package/lib/util/identifier.js +20 -0
  253. package/lib/util/internalSerializables.js +5 -1
  254. package/lib/util/registerExternalSerializer.js +6 -45
  255. package/lib/util/semver.js +5 -3
  256. package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +9 -0
  257. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +9 -0
  258. package/lib/wasm-async/AsyncWebAssemblyGenerator.js +6 -1
  259. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +5 -1
  260. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +12 -4
  261. package/lib/wasm-sync/WebAssemblyGenerator.js +6 -1
  262. package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +5 -1
  263. package/lib/wasm-sync/WebAssemblyUtils.js +2 -4
  264. package/lib/web/JsonpChunkLoadingRuntimeModule.js +36 -0
  265. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +19 -0
  266. package/package.json +55 -46
  267. package/schemas/WebpackOptions.check.js +1 -1
  268. package/schemas/WebpackOptions.json +379 -66
  269. package/schemas/plugins/LoaderOptionsPlugin.check.js +1 -1
  270. package/schemas/plugins/ManifestPlugin.check.js +1 -1
  271. package/schemas/plugins/SourceMapDevToolPlugin.check.js +1 -1
  272. package/schemas/plugins/asset/AssetGeneratorOptions.check.js +1 -1
  273. package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js +1 -1
  274. package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
  275. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  276. package/schemas/plugins/debug/ProfilingPlugin.check.js +1 -1
  277. package/schemas/plugins/dll/DllReferencePlugin.check.js +1 -1
  278. package/schemas/plugins/ids/HashedModuleIdsPlugin.check.js +1 -1
  279. package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
  280. package/types.d.ts +1723 -604
  281. package/lib/dependencies/ExportBindingInitFragment.js +0 -191
  282. package/lib/errors/EntrypointOverlapWarning.js +0 -45
  283. package/lib/performance/EntrypointOverlapPlugin.js +0 -122
@@ -63,13 +63,10 @@ class LocConverter {
63
63
  // Retreat on line 1: no `\n` precedes `pos`, the cache stays valid.
64
64
  this.column = pos;
65
65
  } else {
66
- // Retreat: count newlines crossed in (pos, this.pos), i.e.
67
- // exclude the newline at `this.pos` itself. By convention a
68
- // `\n` is the last column of its line, so when `this.pos`
69
- // sits on one we're already on the line containing it; only
70
- // newlines strictly **before** `this.pos` and at-or-after
71
- // `pos` represent crossed line boundaries. The smallest
72
- // crossed one is the next newline after the new position.
66
+ // WHY: A `\n` counts as the last column of its own line here, so a
67
+ // `this.pos` sitting on one is already on that line. Retreating
68
+ // therefore crosses only the newlines at or after `pos` and strictly
69
+ // before `this.pos` — the newline at `this.pos` is not one of them.
73
70
  let i = input.lastIndexOf("\n", this.pos - 1);
74
71
  while (i >= pos) {
75
72
  this._nextNewline = i;
@@ -261,20 +261,20 @@ class PrintContext {
261
261
  /** @type {NodePrinter<TPath, TNode, TPrintOptions>} */
262
262
  this._printer = printer;
263
263
  // Printed text by node handle, in two columns rather than one `Map`: the
264
- // handles are dense integers, and a stylesheet prints ~300k nodes through
265
- // a store that never holds more than a few dozen of them at once.
264
+ // handles are dense integers, and `_moveEpoch` keeps the live set small.
266
265
  /** @type {string[]} each finished node's printed text */
267
266
  this._storeText = [];
268
267
  /** @type {Int32Array} the epoch each slot was written in */
269
268
  this._storeGen = new Int32Array(0);
270
269
  /** @type {number} current epoch; a slot from an older one reads as absent */
271
270
  this._gen = 1;
272
- // Output accumulates into `_tail`, a plain string append, so printing that
273
- // never takes anything back costs exactly what appending to one string
274
- // costs. A piece is cut off into `_chunks` only for text that may still be
275
- // taken back ({@link emitRetractable}) — that is what lets a printer emit
276
- // before it knows a later sibling overrides it, without every other emit
277
- // paying for the ability. The output is `_chunks` joined, then `_tail`.
271
+ /** @type {number} lowest slot written since the epoch last moved */
272
+ this._storeLow = 0x7fffffff;
273
+ /** @type {number} highest slot written since the epoch last moved */
274
+ this._storeHigh = -1;
275
+ // Output is `_chunks` joined, then `_tail`. Printing that never takes
276
+ // anything back only appends to `_tail`; a piece is cut off into `_chunks`
277
+ // for retractable text alone, so no other emit pays for that ability.
278
278
  /** @type {string[]} pieces already cut off, in output order */
279
279
  this._chunks = [];
280
280
  /** @type {string} output after the last cut piece */
@@ -285,7 +285,7 @@ class PrintContext {
285
285
  this._flattened = 0;
286
286
  /** @type {[number, number, number, number][]} `[chunkIndex, offsetInChunk, srcLine, srcCol]`, output-ordered; a `srcLine` of -1 is one {@link retract} took back with its piece */
287
287
  this._mappings = [];
288
- /** @type {Map<number, number> | null} a retractable piece -> the mapping anchored to it, so taking the piece back takes its mapping too */
288
+ /** @type {number[] | null} by retractable piece index, the mapping anchored to it, so taking the piece back takes its mapping too */
289
289
  this._retractableMappings = null;
290
290
  // A map is built only for a caller that named the input, and that is known
291
291
  // before printing — so a print nobody asks a map of collects none.
@@ -296,10 +296,9 @@ class PrintContext {
296
296
  this._inserts = [];
297
297
  /** @type {number} next `_inserts` entry not yet flushed */
298
298
  this._insertIdx = 0;
299
- // Openers of the nodes being printed in pieces, innermost last, held back
300
- // until one of them turns out to have content: a node whose children all
301
- // print to nothing can then still be dropped whole, which is the one thing
302
- // emitting an opener eagerly would give up.
299
+ // Openers of the nodes printed in pieces, innermost last, held back until
300
+ // one has content — which is what lets a node whose children all print to
301
+ // nothing still be dropped whole.
303
302
  /** @type {string[]} openers not yet emitted, outermost first */
304
303
  this._pending = [];
305
304
  /** @type {[number | undefined, number | undefined, number | undefined] | null} anchor for the first pending opener */
@@ -424,8 +423,25 @@ class PrintContext {
424
423
  * node's text.
425
424
  */
426
425
  dropStore() {
427
- // Bumping the epoch invalidates every slot at once, so this stays O(1) —
428
- // it runs per node, and clearing a column by length would not.
426
+ this._moveEpoch();
427
+ }
428
+
429
+ /**
430
+ * Move the epoch on and release the text every slot written under the old one
431
+ * holds. Only the range actually written is walked, so the drop stays O(1)
432
+ * per node.
433
+ * @returns {void}
434
+ */
435
+ _moveEpoch() {
436
+ const high = this._storeHigh;
437
+ if (high !== -1) {
438
+ // `""` rather than a hole: the column is packed, and a hole in it would
439
+ // cost every read after this one.
440
+ const text = this._storeText;
441
+ for (let i = this._storeLow; i <= high; i++) text[i] = "";
442
+ this._storeLow = 0x7fffffff;
443
+ this._storeHigh = -1;
444
+ }
429
445
  this._gen++;
430
446
  }
431
447
 
@@ -469,6 +485,8 @@ class PrintContext {
469
485
  if (n >= this._storeText.length) this._growStore(n + 1);
470
486
  this._storeText[n] = text;
471
487
  this._storeGen[n] = this._gen;
488
+ if (n < this._storeLow) this._storeLow = n;
489
+ if (n > this._storeHigh) this._storeHigh = n;
472
490
  }
473
491
 
474
492
  /**
@@ -502,14 +520,12 @@ class PrintContext {
502
520
  _emit(text) {
503
521
  this._tail += text;
504
522
  this._tailLength += text.length;
505
- // A printer returns its text as a rope of its children's pieces, and
506
- // appending a rope onto a rope keeps every fragment of every node reachable
507
- // until the output is finally flattened — on a stylesheet of many top-level
508
- // rules, a second copy of the whole output. So cut the tail off once it has
509
- // grown past a block and force that block flat, which drops every fragment
510
- // behind it. Per block rather than per piece: the flattening copy is one
511
- // the result would have paid for anyway, but paying it per piece means an
512
- // allocation for each, and the pieces are small.
523
+ // WHY: A printer returns a rope of its children's pieces, and appending a
524
+ // rope onto a rope keeps every fragment reachable until the output is
525
+ // flattened — a second copy of a large stylesheet. Cutting the tail once it
526
+ // passes a block forces that block flat and drops the fragments behind it.
527
+ // Per block rather than per piece: the copy is one the result pays anyway,
528
+ // while per piece it would be an allocation each, and the pieces are small.
513
529
  if (this._tailLength >= FLATTEN_BLOCK) this._cutTail();
514
530
  }
515
531
 
@@ -552,7 +568,7 @@ class PrintContext {
552
568
  retract(index) {
553
569
  this._chunks[index] = "";
554
570
  if (this._retractableMappings === null) return;
555
- const mapping = this._retractableMappings.get(index);
571
+ const mapping = this._retractableMappings[index];
556
572
  if (mapping !== undefined) this._mappings[mapping][2] = -1;
557
573
  }
558
574
 
@@ -598,12 +614,12 @@ class PrintContext {
598
614
  this.anchor(srcOffset, srcLine, srcCol);
599
615
  const mapping = this._mappings.length > before ? before : -1;
600
616
  const at = this.emitRetractable(text === undefined ? this.get(node) : text);
601
- this._gen++;
617
+ this._moveEpoch();
602
618
  if (mapping !== -1) {
603
- if (this._retractableMappings === null) {
604
- this._retractableMappings = new Map();
605
- }
606
- this._retractableMappings.set(at, mapping);
619
+ // Indexed by piece rather than a `Map`: pieces are dense integers, and
620
+ // nearly every rule minifying goes out as one.
621
+ if (this._retractableMappings === null) this._retractableMappings = [];
622
+ this._retractableMappings[at] = mapping;
607
623
  }
608
624
  return at;
609
625
  }
@@ -627,7 +643,7 @@ class PrintContext {
627
643
  this._emit(
628
644
  text === undefined ? this.get(/** @type {TNode} */ (node)) : text
629
645
  );
630
- this._gen++;
646
+ this._moveEpoch();
631
647
  }
632
648
 
633
649
  /**
@@ -739,68 +755,44 @@ class PrintContext {
739
755
 
740
756
  /**
741
757
  * @param {SourceMapOptions} options the input's name / content
758
+ * @param {string=} code the output {@link result} built, walked for its line breaks
742
759
  * @returns {SourceMap} the input->output source map
743
760
  */
744
- sourceMap(options) {
761
+ sourceMap(options, code) {
745
762
  let out = "";
746
763
  let genLine = 0;
747
764
  let genCol = 0;
748
765
  let srcLine = 0;
749
766
  let srcCol = 0;
750
767
  let atLineStart = true;
751
- // Where each anchor landed, walked once alongside the mappings — both are
752
- // in output order, so this is one pass over the output, not a position
753
- // recomputed per mapping. An anchor can sit inside a piece rather than at
754
- // its start, since output accumulates into the piece it is appending to.
768
+ // Walked over the flat output rather than piece by piece: a piece is a rope
769
+ // until something reads it, and reading each one flattens each one.
770
+ const text = code === undefined ? this.result() : code;
755
771
  const chunks = this._chunks;
756
- const tail = this._tail;
757
- /**
758
- * @param {number} i piece index, `chunks.length` being the tail
759
- * @returns {string} that piece
760
- */
761
- const pieceAt = (i) => (i === chunks.length ? tail : chunks[i]);
762
772
  let atChunk = 0;
773
+ let chunkStart = 0;
763
774
  let atOffset = 0;
764
775
  let atLine = 0;
765
776
  let atCol = 0;
766
- // Offset of the next newline at or after the cursor, `-1` for none left in
767
- // this piece. Carried rather than searched for per mapping: `indexOf` has no
768
- // end bound, so asking it again for each of a piece's mappings scans again to
769
- // the end of the piece every time — and minified output, the case with no
770
- // newlines at all, is the one where that is the whole piece.
771
- let nextNewline = pieceAt(0).indexOf("\n");
772
- /**
773
- * @param {string} text the piece to walk
774
- * @param {number} to offset to walk to
775
- */
776
- const advanceOver = (text, to) => {
777
- while (nextNewline !== -1 && nextNewline < to) {
778
- atLine++;
779
- atCol = 0;
780
- atOffset = nextNewline + 1;
781
- nextNewline = text.indexOf("\n", atOffset);
782
- }
783
- atCol += to - atOffset;
784
- atOffset = to;
785
- };
786
- /**
787
- * @param {number} chunk piece index to advance to
788
- * @param {number} offset offset within it
789
- */
790
- const advanceTo = (chunk, offset) => {
791
- while (atChunk < chunk) {
792
- const text = pieceAt(atChunk);
793
- advanceOver(text, text.length);
794
- atChunk++;
795
- atOffset = 0;
796
- nextNewline = pieceAt(atChunk).indexOf("\n");
797
- }
798
- if (offset > atOffset) advanceOver(pieceAt(atChunk), offset);
799
- };
777
+ // Offset of the next newline at or after the cursor, `-1` for none left.
778
+ // Carried rather than searched for per mapping: `indexOf` has no end bound.
779
+ let nextNewline = text.indexOf("\n");
800
780
  for (const [chunkIndex, chunkOffset, sl, sc] of this._mappings) {
801
781
  // Its piece was taken back, so there is no output left to anchor.
802
782
  if (sl === -1) continue;
803
- advanceTo(chunkIndex, chunkOffset);
783
+ // A piece's length is stored, so summing them costs nothing per byte.
784
+ while (atChunk < chunkIndex) chunkStart += chunks[atChunk++].length;
785
+ const to = chunkStart + chunkOffset;
786
+ if (to > atOffset) {
787
+ while (nextNewline !== -1 && nextNewline < to) {
788
+ atLine++;
789
+ atCol = 0;
790
+ atOffset = nextNewline + 1;
791
+ nextNewline = text.indexOf("\n", atOffset);
792
+ }
793
+ atCol += to - atOffset;
794
+ atOffset = to;
795
+ }
804
796
  const gl = atLine;
805
797
  const gc = atCol;
806
798
  while (genLine < gl) {
@@ -915,7 +907,11 @@ class PrintContext {
915
907
  if (this._insertIdx < this._inserts.length) this._flushBefore(Infinity);
916
908
  // Nothing was ever cut into its own piece, so there is nothing to join.
917
909
  const chunks = this._chunks;
918
- return chunks.length === 0 ? this._tail : chunks.join("") + this._tail;
910
+ if (chunks.length === 0) return this._tail;
911
+ // The tail joins as a piece of its own, so the output comes back flat
912
+ // rather than as a rope over the join that every reader flattens again.
913
+ this._cutTail();
914
+ return chunks.join("");
919
915
  }
920
916
  }
921
917
 
@@ -1018,10 +1014,9 @@ class SourceProcessor {
1018
1014
  this._grammar(input, this._visitors, undefined, opts);
1019
1015
  return undefined;
1020
1016
  }
1021
- // Handed over whole rather than copied entry by entry: which of them are
1022
- // print options is the language's to say, and listing them here is what
1023
- // made every new one an edit to this file. A grammar-only entry riding
1024
- // along is inert — a printer reads only what its own type declares.
1017
+ // Handed over whole rather than copied entry by entry: which entries are
1018
+ // print options is the language's to say, and a grammar-only one riding
1019
+ // along is inert, since a printer reads only what its own type declares.
1025
1020
  const ctx = new PrintContext(
1026
1021
  /** @type {PrintOptions & TPrintOptions} */ (
1027
1022
  /** @type {unknown} */ ({ ...opts, mode: asked })
@@ -1030,16 +1025,21 @@ class SourceProcessor {
1030
1025
  );
1031
1026
  this._grammar(input, this._visitors, ctx, opts);
1032
1027
  const name = /** @type {{ source?: string, content?: string }} */ (opts);
1033
- const build = () => ({
1034
- code: ctx.result(),
1035
- // Built only for a caller that named the input: building one walks the
1036
- // whole output for its line breaks, and the minifier prints an inline
1037
- // `style=""` — which asks for no map — thousands of times a document.
1038
- map:
1039
- name.source === undefined
1040
- ? undefined
1041
- : ctx.sourceMap({ source: name.source, content: name.content })
1042
- });
1028
+ const build = () => {
1029
+ const code = ctx.result();
1030
+ return {
1031
+ code,
1032
+ // Built only for a caller that named the input: a map walks the whole
1033
+ // output, and an inline `style=""` asks for none thousands of times a page.
1034
+ map:
1035
+ name.source === undefined
1036
+ ? undefined
1037
+ : ctx.sourceMap(
1038
+ { source: name.source, content: name.content },
1039
+ code
1040
+ )
1041
+ };
1042
+ };
1043
1043
  if (this._deferred !== null) {
1044
1044
  const finish = this._deferred;
1045
1045
 
@@ -0,0 +1,292 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Alexander Akait @alexander-akait
4
+ */
5
+
6
+ "use strict";
7
+
8
+ /**
9
+ * Wraps the shared completion callback for one item, so an iterator that
10
+ * reports twice fails loudly instead of settling the run early.
11
+ * @template E
12
+ * @param {(err?: E | null) => void} done shared completion callback
13
+ * @returns {(err?: E | null) => void} completion callback for a single item
14
+ */
15
+ const once = (done) => {
16
+ /** @type {((err?: E | null) => void) | undefined} */
17
+ let pending = done;
18
+ return (err) => {
19
+ const fn = pending;
20
+ if (fn === undefined) throw new Error("Callback was already called");
21
+ pending = undefined;
22
+ fn(err);
23
+ };
24
+ };
25
+
26
+ /**
27
+ * Runs `iterator` over every item with unlimited concurrency.
28
+ * Every item is started from one flat loop, so a synchronous iterator never
29
+ * grows the stack.
30
+ * @template T
31
+ * @template E
32
+ * @param {Iterable<T>} collection items to iterate
33
+ * @param {(item: T, callback: (err?: E | null) => void) => void} iterator called once per item
34
+ * @param {(err?: E | null) => void} callback called when every item is done, or with the first error
35
+ * @returns {void}
36
+ */
37
+ const each = (collection, iterator, callback) => {
38
+ let remaining = 1;
39
+ let finished = false;
40
+
41
+ /**
42
+ * @param {(E | null)=} err error
43
+ * @returns {void}
44
+ */
45
+ const done = (err) => {
46
+ if (finished) return;
47
+ if (err) {
48
+ finished = true;
49
+ callback(err);
50
+ return;
51
+ }
52
+ if (--remaining === 0) {
53
+ finished = true;
54
+ callback(null);
55
+ }
56
+ };
57
+
58
+ if (Array.isArray(collection)) {
59
+ const array = /** @type {T[]} */ (collection);
60
+ const length = array.length;
61
+ if (length === 0) return callback(null);
62
+ remaining = length;
63
+ // Dispatching continues past an error on purpose: callers rely on every
64
+ // item being started, e.g. to close every watcher when one close fails.
65
+ for (let i = 0; i < length; i++) iterator(array[i], once(done));
66
+ return;
67
+ }
68
+
69
+ // `remaining` starts at 1 so that completion cannot fire while items of a
70
+ // collection of unknown length are still being dispatched.
71
+ for (const item of collection) {
72
+ remaining++;
73
+ iterator(item, once(done));
74
+ }
75
+ done(null);
76
+ };
77
+
78
+ /**
79
+ * Runs `iterator` over every item, keeping at most `limit` of them in flight.
80
+ * A synchronous iterator is drained by the dispatch loop instead of by
81
+ * recursion, so the stack stays flat however long the collection is.
82
+ * @template T
83
+ * @template E
84
+ * @param {Iterable<T>} collection items to iterate
85
+ * @param {number} limit maximum number of items in flight
86
+ * @param {(item: T, callback: (err?: E | null) => void) => void} iterator called once per item
87
+ * @param {(err?: E | null) => void} callback called when every item is done, or with the first error
88
+ * @returns {void}
89
+ */
90
+ const eachLimit = (collection, limit, iterator, callback) => {
91
+ const array = Array.isArray(collection)
92
+ ? /** @type {T[]} */ (collection)
93
+ : undefined;
94
+ const length = array === undefined ? 0 : array.length;
95
+ const values =
96
+ array === undefined ? collection[Symbol.iterator]() : undefined;
97
+ let index = 0;
98
+ let running = 0;
99
+ let exhausted = false;
100
+ let finished = false;
101
+ let dispatching = false;
102
+
103
+ const dispatch = () => {
104
+ // A re-entrant call returns at once; the loop already running sees the
105
+ // slot the completed item freed and takes the next one itself.
106
+ if (dispatching) return;
107
+ dispatching = true;
108
+ while (running < limit && !exhausted) {
109
+ // `finished` is set from `done`, which an iterator may call before it
110
+ // returns, so it has to be re-read on every turn of this loop.
111
+ if (finished) break;
112
+ /** @type {T} */
113
+ let item;
114
+ if (array === undefined) {
115
+ const next = /** @type {Iterator<T>} */ (values).next();
116
+ if (next.done) {
117
+ exhausted = true;
118
+ break;
119
+ }
120
+ item = next.value;
121
+ } else {
122
+ if (index === length) {
123
+ exhausted = true;
124
+ break;
125
+ }
126
+ item = array[index++];
127
+ }
128
+ running++;
129
+ iterator(item, once(done));
130
+ }
131
+ dispatching = false;
132
+ if (exhausted && running === 0 && !finished) {
133
+ finished = true;
134
+ callback(null);
135
+ }
136
+ };
137
+
138
+ /**
139
+ * @param {(E | null)=} err error
140
+ * @returns {void}
141
+ */
142
+ const done = (err) => {
143
+ if (finished) return;
144
+ running--;
145
+ if (err) {
146
+ finished = true;
147
+ callback(err);
148
+ return;
149
+ }
150
+ dispatch();
151
+ };
152
+
153
+ if (limit < 1) return callback(null);
154
+
155
+ dispatch();
156
+ };
157
+
158
+ /**
159
+ * Runs `iterator` over every item with unlimited concurrency and collects the
160
+ * results in the order of the collection, not the order of completion.
161
+ * @template T
162
+ * @template R
163
+ * @template E
164
+ * @param {Iterable<T>} collection items to iterate
165
+ * @param {(item: T, callback: (err?: E | null, result?: R) => void) => void} iterator called once per item
166
+ * @param {(err?: E | null, results?: R[]) => void} callback called with every result, or with the first error
167
+ * @returns {void}
168
+ */
169
+ const map = (collection, iterator, callback) => {
170
+ const array = Array.isArray(collection)
171
+ ? /** @type {T[]} */ (collection)
172
+ : undefined;
173
+ // Pre-sized, because growing it or `Array.from` costs measurably more on
174
+ // the small collections this is called with.
175
+ /** @type {R[]} */
176
+ // eslint-disable-next-line unicorn/no-new-array
177
+ const results = array === undefined ? [] : new Array(array.length);
178
+ let remaining = 1;
179
+ let finished = false;
180
+
181
+ /**
182
+ * @param {(E | null)=} err error
183
+ * @returns {void}
184
+ */
185
+ const settle = (err) => {
186
+ if (finished) return;
187
+ if (err) {
188
+ finished = true;
189
+ callback(err, results);
190
+ return;
191
+ }
192
+ if (--remaining === 0) {
193
+ finished = true;
194
+ callback(null, results);
195
+ }
196
+ };
197
+
198
+ /**
199
+ * @param {number} index position the result of that item belongs at
200
+ * @returns {(err?: E | null, result?: R) => void} completion callback for that item
201
+ */
202
+ const createCallback = (index) => {
203
+ let position = index;
204
+ return (err, result) => {
205
+ const at = position;
206
+ if (at === -1) throw new Error("Callback was already called");
207
+ position = -1;
208
+ // A result arriving after the run settled must not reach `results`,
209
+ // which the callback already handed to the caller.
210
+ if (finished) return;
211
+ if (!err) results[at] = /** @type {R} */ (result);
212
+ settle(err);
213
+ };
214
+ };
215
+
216
+ if (array !== undefined) {
217
+ const length = array.length;
218
+ if (length === 0) return callback(null, results);
219
+ remaining = length;
220
+ for (let i = 0; i < length; i++) iterator(array[i], createCallback(i));
221
+ return;
222
+ }
223
+
224
+ let index = 0;
225
+ for (const item of collection) {
226
+ remaining++;
227
+ iterator(item, createCallback(index++));
228
+ }
229
+ results.length = index;
230
+ settle(null);
231
+ };
232
+
233
+ /**
234
+ * Runs `iterator` over every item, at most `limit` of them in flight, and
235
+ * collects the results in the order of the collection, not of completion.
236
+ * @template T
237
+ * @template R
238
+ * @template E
239
+ * @param {Iterable<T>} collection items to iterate
240
+ * @param {number} limit maximum number of items in flight
241
+ * @param {(item: T, callback: (err?: E | null, result?: R) => void) => void} iterator called once per item
242
+ * @param {(err?: E | null, results?: R[]) => void} callback called with every result, or with the first error
243
+ * @returns {void}
244
+ */
245
+ const mapLimit = (collection, limit, iterator, callback) => {
246
+ /** @type {R[]} */
247
+ const results = [];
248
+ let index = 0;
249
+ eachLimit(
250
+ collection,
251
+ limit,
252
+ (item, done) => {
253
+ // the dispatch loop hands out one item at a time, so this counts the
254
+ // position of the item rather than of whichever finishes first
255
+ const position = index++;
256
+ iterator(item, (err, result) => {
257
+ if (err) return done(err);
258
+ results[position] = /** @type {R} */ (result);
259
+ done(null);
260
+ });
261
+ },
262
+ (err) => {
263
+ if (err) return callback(err);
264
+ callback(null, results);
265
+ }
266
+ );
267
+ };
268
+
269
+ /**
270
+ * @template R
271
+ * @template E
272
+ * @param {(callback: (err?: E | null, result?: R) => void) => void} task task to run
273
+ * @param {(err?: E | null, result?: R) => void} callback called when the task is done
274
+ * @returns {void}
275
+ */
276
+ const runTask = (task, callback) => task(callback);
277
+
278
+ /**
279
+ * Runs every task in parallel and collects the results in task order.
280
+ * @template R
281
+ * @template E
282
+ * @param {((callback: (err?: E | null, result?: R) => void) => void)[]} tasks tasks to run
283
+ * @param {(err?: E | null, results?: R[]) => void} callback called with every result, or with the first error
284
+ * @returns {void}
285
+ */
286
+ const parallel = (tasks, callback) => map(tasks, runTask, callback);
287
+
288
+ module.exports.each = each;
289
+ module.exports.eachLimit = eachLimit;
290
+ module.exports.map = map;
291
+ module.exports.mapLimit = mapLimit;
292
+ module.exports.parallel = parallel;
@@ -0,0 +1,69 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Haijie Xie @hai-x
4
+ */
5
+
6
+ "use strict";
7
+
8
+ /** @import Module, { BuildDiagnostics, BuildInfo } from "../Module" */
9
+ /** @import ModuleGraph from "../ModuleGraph" */
10
+
11
+ /**
12
+ * The diagnostics record of a build info, created on first use so a module nothing reports about carries none.
13
+ * @param {BuildInfo} buildInfo the build info of the module
14
+ * @returns {BuildDiagnostics} the record
15
+ */
16
+ const getBuildDiagnostics = (buildInfo) => {
17
+ let diagnostics = buildInfo.diagnostics;
18
+ if (diagnostics === undefined) {
19
+ diagnostics = buildInfo.diagnostics = {
20
+ optimizationBailouts: undefined,
21
+ sideEffectStatement: undefined,
22
+ ineffectivePureAnnotations: undefined,
23
+ topLevelThis: undefined,
24
+ usesEval: undefined,
25
+ notCacheableReasons: undefined
26
+ };
27
+ }
28
+ return diagnostics;
29
+ };
30
+
31
+ /**
32
+ * Records a bailout a parser plugin found, where a module restored from the cache still has it for the module graph to report.
33
+ * @param {BuildInfo} buildInfo the build info of the module being parsed
34
+ * @param {string} reason the bailout as reported
35
+ * @returns {void}
36
+ */
37
+ const recordOptimizationBailout = (buildInfo, reason) => {
38
+ const diagnostics = getBuildDiagnostics(buildInfo);
39
+ const bailouts =
40
+ diagnostics.optimizationBailouts || (diagnostics.optimizationBailouts = []);
41
+ bailouts.push(reason);
42
+ };
43
+
44
+ /**
45
+ * Replays the bailouts parser plugins recorded for a module into the module graph,
46
+ * which a module reused from the cache never parses into.
47
+ * @param {ModuleGraph} moduleGraph the module graph
48
+ * @param {Module} module the built or still valid module
49
+ * @returns {void}
50
+ */
51
+ const replayOptimizationBailouts = (moduleGraph, module) => {
52
+ const buildInfo = module.buildInfo;
53
+ if (buildInfo === undefined) return;
54
+ const diagnostics = buildInfo.diagnostics;
55
+ if (
56
+ diagnostics === undefined ||
57
+ diagnostics.optimizationBailouts === undefined
58
+ ) {
59
+ return;
60
+ }
61
+ const bailouts = moduleGraph.getOptimizationBailout(module);
62
+ for (const reason of diagnostics.optimizationBailouts) bailouts.push(reason);
63
+ };
64
+
65
+ module.exports = {
66
+ getBuildDiagnostics,
67
+ recordOptimizationBailout,
68
+ replayOptimizationBailouts
69
+ };