@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
@@ -5,8 +5,8 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const asyncLib = require("neo-async");
9
8
  const Queue = require("./util/Queue");
9
+ const asyncLib = require("./util/async");
10
10
  const { compareModulesByIdentifier } = require("./util/comparators");
11
11
  const createHash = require("./util/createHash");
12
12
 
@@ -30,15 +30,40 @@ const PLUGIN_LOGGER_NAME = `webpack.${PLUGIN_NAME}`;
30
30
  /** @typedef {{ etag: string, data: InstanceType<RestoreProvidedData> }} MemCacheEntry */
31
31
 
32
32
  /**
33
+ * Cache key fragment for what changes provided exports without changing the
34
+ * module's source: still-lazy barrel requests and DefinePlugin value versions.
33
35
  * @param {Module} module the module
34
36
  * @param {LazyBarrelController} lazyBarrelController the compilation's lazy barrel controller
35
37
  * @param {HashFunction} hashFunction hash function for long keys
36
- * @returns {string} the hash
38
+ * @returns {string} etag for provided-exports mem/persistent cache, "" when neither applies
37
39
  */
38
- const getLazyRequestsHash = (module, lazyBarrelController, hashFunction) => {
39
- const lazyKeys = lazyBarrelController.getLazyRequests(module);
40
- if (!lazyKeys) return "";
41
- const joined = [...lazyKeys].join("|");
40
+ const getProvidedExportsEtag = (module, lazyBarrelController, hashFunction) => {
41
+ const lazyRequests = lazyBarrelController.getLazyRequests(module);
42
+ const buildInfo = /** @type {BuildInfo | undefined} */ (module.buildInfo);
43
+ const valueDependencies = buildInfo && buildInfo.valueDependencies;
44
+ const hasValueDependencies =
45
+ valueDependencies !== undefined && valueDependencies.size > 0;
46
+ if (!lazyRequests && !hasValueDependencies) return "";
47
+ /** @type {(string | string[] | undefined)[][]} */
48
+ const valueEntries = [];
49
+ if (hasValueDependencies) {
50
+ const versions =
51
+ /** @type {NonNullable<BuildInfo["valueDependencies"]>} */
52
+ (valueDependencies);
53
+ for (const key of [...versions.keys()].sort()) {
54
+ const value = versions.get(key);
55
+ // An absent version serializes as null, distinct from both other shapes
56
+ valueEntries.push([
57
+ key,
58
+ value instanceof Set ? [...value].sort() : value
59
+ ]);
60
+ }
61
+ }
62
+ // JSON, so a separator inside a request or a version cannot forge another entry
63
+ const joined = JSON.stringify([
64
+ lazyRequests ? [...lazyRequests] : [],
65
+ valueEntries
66
+ ]);
42
67
  if (joined.length < 100) return joined;
43
68
  const hash = createHash(hashFunction);
44
69
  hash.update(joined);
@@ -78,9 +103,7 @@ class FlagDependencyExportsPlugin {
78
103
  // Step 1: Try to restore cached provided export info from cache
79
104
  logger.time("restore cached provided exports");
80
105
  asyncLib.each(
81
- /** @type {import("neo-async").IterableCollection<Module>} */ (
82
- /** @type {unknown} */ (modules)
83
- ),
106
+ modules,
84
107
  (module, callback) => {
85
108
  const exportsInfo = moduleGraph.getExportsInfo(module);
86
109
  // If the module doesn't have an exportsType, it's a module
@@ -109,16 +132,15 @@ class FlagDependencyExportsPlugin {
109
132
  const memCache = moduleMemCaches && moduleMemCaches.get(module);
110
133
  /** @type {MemCacheEntry | undefined} */
111
134
  const memCacheEntry = memCache && memCache.get(this);
112
- const hash = getLazyRequestsHash(
135
+ const etag = getProvidedExportsEtag(
113
136
  module,
114
137
  lazyBarrelController,
115
138
  hashFunction
116
139
  );
117
140
  // validated by the still-lazy request keys: reference-change
118
- // detection cannot invalidate the mem cache when the un-lazied
119
- // connections are unsafe-cached (they are skipped when comparing
120
- // references)
121
- if (memCacheEntry !== undefined && memCacheEntry.etag === hash) {
141
+ // detection cannot invalidate the mem cache while the un-lazied
142
+ // connections are unsafe-cached, being skipped in the comparison
143
+ if (memCacheEntry !== undefined && memCacheEntry.etag === etag) {
122
144
  statRestoredFromMemCache++;
123
145
  exportsInfo.restoreProvided(memCacheEntry.data);
124
146
  return callback();
@@ -128,7 +150,7 @@ class FlagDependencyExportsPlugin {
128
150
  );
129
151
  cache.get(
130
152
  module.identifier(),
131
- hash ? `${buildHash}|${hash}` : buildHash,
153
+ etag ? `${buildHash}|${etag}` : buildHash,
132
154
  (err, result) => {
133
155
  if (err) return callback(err);
134
156
 
@@ -149,16 +171,12 @@ class FlagDependencyExportsPlugin {
149
171
  logger.timeEnd("restore cached provided exports");
150
172
  if (err) return callback(err);
151
173
 
152
- // Seed the queue with targets before the modules that read
153
- // them. Enqueueing at the two branches above ordered the work by
154
- // how fast each cache lookup answered — one is synchronous, the
155
- // other a `cache.get` callback — so the persistent cache decided
156
- // it. A module analysed before the module it re-exports from
157
- // reads exports that are not determined yet and over-estimates,
158
- // and this loop can add exports info but never retract it, so
159
- // the over-estimate survives the pass that corrects it. The
160
- // roots are sorted so the walk is stable, and post-order visits
161
- // each module after everything it points at.
174
+ // WHY: enqueueing at the branches above ordered the work by how
175
+ // fast each cache lookup answered, letting the persistent cache
176
+ // decide it. A module analyzed before the one it re-exports from
177
+ // over-estimates its exports, and this loop can add exports info
178
+ // but never retract it, so that over-estimate would survive. Sorted
179
+ // roots and post-order visit each module after what it points at.
162
180
  /** @type {Set<Module>} */
163
181
  const visited = new Set();
164
182
  /** @type {Module[]} */
@@ -351,12 +369,13 @@ class FlagDependencyExportsPlugin {
351
369
  changed = true;
352
370
  }
353
371
 
354
- if (
355
- inlined !== undefined &&
356
- exportInfo.canInlineProvide === undefined
357
- ) {
358
- exportInfo.canInlineProvide = inlined;
359
- changed = true;
372
+ if (inlined !== undefined) {
373
+ const prev = exportInfo.canInlineProvide;
374
+ // Watch rebuilds keep ExportInfo; refresh when the constant changes
375
+ if (prev === undefined || !prev.equals(inlined)) {
376
+ exportInfo.canInlineProvide = inlined;
377
+ changed = true;
378
+ }
360
379
  }
361
380
 
362
381
  if (terminalBinding && !exportInfo.terminalBinding) {
@@ -513,7 +532,7 @@ class FlagDependencyExportsPlugin {
513
532
  .getRestoreProvidedData();
514
533
  const memCache =
515
534
  moduleMemCaches && moduleMemCaches.get(module);
516
- const hash = getLazyRequestsHash(
535
+ const etag = getProvidedExportsEtag(
517
536
  module,
518
537
  lazyBarrelController,
519
538
  hashFunction
@@ -521,7 +540,7 @@ class FlagDependencyExportsPlugin {
521
540
  if (memCache) {
522
541
  /** @type {MemCacheEntry} */
523
542
  const entry = {
524
- etag: hash,
543
+ etag,
525
544
  data: cachedData
526
545
  };
527
546
  memCache.set(this, entry);
@@ -531,7 +550,7 @@ class FlagDependencyExportsPlugin {
531
550
  );
532
551
  cache.store(
533
552
  module.identifier(),
534
- hash ? `${buildHash}|${hash}` : buildHash,
553
+ etag ? `${buildHash}|${etag}` : buildHash,
535
554
  cachedData,
536
555
  callback
537
556
  );
@@ -93,10 +93,9 @@ class FlagDependencyUsagePlugin {
93
93
  const processReferencedModule = (module, usedExports, runtime) => {
94
94
  const exportsInfo = moduleGraph.getExportsInfo(module);
95
95
  if (usedExports === EXPORTS_OBJECT_REFERENCED_MANGLEABLE) {
96
- // The whole namespace object escapes via a reference that codegen
97
- // can materialize as a decoupled namespace object. When all exports
98
- // are statically known we keep them mangleable instead of marking
99
- // them used-in-unknown-way.
96
+ // The namespace object escapes through a reference codegen can
97
+ // materialize, so with every export statically known they stay
98
+ // mangleable rather than used-in-unknown-way.
100
99
  if (
101
100
  this.mangleEscapingNamespaces &&
102
101
  module.buildMeta &&
@@ -237,10 +236,9 @@ class FlagDependencyUsagePlugin {
237
236
  /** @typedef {Map<string, string[] | ReferencedExport>} ExportMaps */
238
237
  /** @type {Map<Module, ReferencedExports | ExportMaps>} */
239
238
  const map = new Map();
240
- // Modules whose whole namespace object escapes in a mangleable way.
241
- // Tracked separately so specific member references are still merged
242
- // (and marked used) instead of being dropped by the escape marker.
243
- // Lazily allocated — usually empty.
239
+ // Modules whose whole namespace escapes but stays mangleable, kept
240
+ // apart so specific member references are still merged and marked
241
+ // used rather than dropped by the escape marker. Usually empty.
244
242
  /** @type {Set<Module> | undefined} */
245
243
  let mangleableEscapeModules;
246
244
 
@@ -289,11 +287,9 @@ class FlagDependencyUsagePlugin {
289
287
  }
290
288
  continue;
291
289
  }
292
- // A mangleable whole-object escape keeps the module's exports
293
- // mangleable (applied after the merge). Unlike the conservative
294
- // marker it must not drop specific member references: those still
295
- // need their own (possibly non-existent) export marked used so
296
- // they render as a qualified access, not a bare `undefined`.
290
+ // A mangleable escape keeps the exports mangleable, applied after
291
+ // the merge. It must not drop specific member references: each
292
+ // still needs marking, or it renders as a bare `undefined`.
297
293
  if (
298
294
  referencedExports === EXPORTS_OBJECT_REFERENCED_MANGLEABLE
299
295
  ) {
package/lib/Generator.js CHANGED
@@ -5,6 +5,7 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ const { contextifyStackFrames } = require("./ErrorHelpers");
8
9
  const { JAVASCRIPT_TYPE } = require("./ModuleSourceTypeConstants");
9
10
  const memoize = require("./util/memoize");
10
11
 
@@ -23,6 +24,7 @@ const memoize = require("./util/memoize");
23
24
  * } from "./Module"
24
25
  */
25
26
  /** @import ModuleGraph from "./ModuleGraph" */
27
+ /** @import RequestShortener from "./RequestShortener" */
26
28
  /** @import NormalModule from "./NormalModule" */
27
29
  /** @import RuntimeTemplate from "./RuntimeTemplate" */
28
30
  /** @import Hash from "./util/Hash" */
@@ -73,18 +75,38 @@ class Generator {
73
75
  return new ByTypeGenerator(map);
74
76
  }
75
77
 
78
+ /**
79
+ * Returns what a module that failed to build says about it in the output.
80
+ * The stack it carries is written relative to the context, keeping a
81
+ * position only where a second build names the same one.
82
+ * @param {Error} error the build error
83
+ * @param {RequestShortener=} requestShortener request shortener, absolute paths are kept without one
84
+ * @returns {string} message to emit
85
+ */
86
+ static buildErrorMessage(error, requestShortener) {
87
+ return requestShortener
88
+ ? contextifyStackFrames(error.message, requestShortener)
89
+ : error.message;
90
+ }
91
+
76
92
  /**
77
93
  * Returns the statement a module that failed to build throws when executed.
78
94
  * @param {Error} error the build error
79
95
  * @param {string=} parseErrorConstructor constructor for a rejected source, defaults to `SyntaxError` (WebAssembly rejects with `WebAssembly.CompileError` instead)
96
+ * @param {RequestShortener=} requestShortener request shortener for the stack the message carries
80
97
  * @returns {string} javascript statement
81
98
  */
82
- static throwBuildErrorCode(error, parseErrorConstructor = "SyntaxError") {
99
+ static throwBuildErrorCode(
100
+ error,
101
+ parseErrorConstructor = "SyntaxError",
102
+ requestShortener = undefined
103
+ ) {
83
104
  // A source the parser rejected throws what a native load of it would.
84
105
  const name =
85
106
  error instanceof getModuleParseError() ? parseErrorConstructor : "Error";
107
+ const message = Generator.buildErrorMessage(error, requestShortener);
86
108
 
87
- return `throw new ${name}(${JSON.stringify(error.message)});`;
109
+ return `throw new ${name}(${JSON.stringify(message)});`;
88
110
  }
89
111
 
90
112
  /* istanbul ignore next */
@@ -17,7 +17,11 @@ const {
17
17
  } = require("./ModuleTypeConstants");
18
18
  const NormalModule = require("./NormalModule");
19
19
  const RuntimeGlobals = require("./RuntimeGlobals");
20
- const { chunkHasCss } = require("./css/CssModulesPlugin");
20
+ const { getPresentKinds } = require("./TemplatedPathPlugin");
21
+ const {
22
+ chunkHasCss,
23
+ getChunkFilenameTemplate: getCssChunkFilenameTemplate
24
+ } = require("./css/CssModulesPlugin");
21
25
  const ConstDependency = require("./dependencies/ConstDependency");
22
26
  const ImportMetaHotAcceptDependency = require("./dependencies/ImportMetaHotAcceptDependency");
23
27
  const ImportMetaHotDeclineDependency = require("./dependencies/ImportMetaHotDeclineDependency");
@@ -72,6 +76,24 @@ const {
72
76
  /** @typedef {{ updatedChunkIds: ChunkIds, removedChunkIds: ChunkIds, removedModules: ModuleSet, forceLoadChunkIds: ChunkIds, filename: string, assetInfo: AssetInfo }} HotUpdateMainContentByRuntimeItem */
73
77
  /** @typedef {Map<string, HotUpdateMainContentByRuntimeItem>} HotUpdateMainContentByRuntime */
74
78
 
79
+ /** @typedef {{ hot?: boolean }} HotModuleReplacementPluginLoaderContext */
80
+
81
+ /**
82
+ * Whether a filename template reads any hash, so the name it gives a chunk can move
83
+ * between two builds.
84
+ * @param {string} template the filename template
85
+ * @returns {boolean} true when a hash is part of the name
86
+ */
87
+ const templateReadsHash = (template) => {
88
+ const kinds = getPresentKinds(template);
89
+ return (
90
+ kinds.has("hash") ||
91
+ kinds.has("fullhash") ||
92
+ kinds.has("chunkhash") ||
93
+ kinds.has("contenthash")
94
+ );
95
+ };
96
+
75
97
  const PLUGIN_NAME = "HotModuleReplacementPlugin";
76
98
 
77
99
  class HotModuleReplacementPlugin {
@@ -856,7 +878,7 @@ To fix this, make sure to include [runtime] in the output.hotUpdateMainFilename
856
878
  assetInfo
857
879
  }
858
880
  ] of hotUpdateMainContentByFilename) {
859
- /** @type {{ c: ChunkId[], r: ChunkId[], m: ModuleId[], f?: ChunkId[], css?: { r: ChunkId[] } }} */
881
+ /** @type {{ c: ChunkId[], r: ChunkId[], m: ModuleId[], f?: ChunkId[], css?: { r: ChunkId[], n?: Record<ChunkId, string> } }} */
860
882
  const hotUpdateMainJson = {
861
883
  c: [...updatedChunkIds],
862
884
  r: [...removedChunkIds],
@@ -882,21 +904,47 @@ To fix this, make sure to include [runtime] in the output.hotUpdateMainFilename
882
904
  // Build CSS removed chunks list (chunks in updatedChunkIds that no longer have CSS)
883
905
  /** @type {ChunkId[]} */
884
906
  const cssRemovedChunkIds = [];
907
+ /** @type {Record<ChunkId, string> | undefined} */
908
+ let cssChunkNames;
885
909
  if (compilation.options.experiments.css) {
886
910
  for (const chunkId of updatedChunkIds) {
887
911
  for (const /** @type {Chunk} */ chunk of compilation.chunks) {
888
- if (chunk.id === chunkId) {
889
- if (!chunkHasCss(chunk, chunkGraph)) {
890
- cssRemovedChunkIds.push(chunkId);
891
- }
912
+ if (chunk.id !== chunkId) continue;
913
+ if (!chunkHasCss(chunk, chunkGraph)) {
914
+ cssRemovedChunkIds.push(chunkId);
892
915
  break;
893
916
  }
917
+ // The runtime's name map is refreshed only by the update chunk
918
+ // itself, so a name that moved with the content travels here.
919
+ const template = getCssChunkFilenameTemplate(
920
+ chunk,
921
+ compilation.outputOptions
922
+ );
923
+ if (
924
+ typeof template !== "string" ||
925
+ templateReadsHash(template)
926
+ ) {
927
+ if (cssChunkNames === undefined) cssChunkNames = {};
928
+ cssChunkNames[chunkId] = compilation.getPath(template, {
929
+ hash: compilation.hash,
930
+ runtime: chunk.runtime,
931
+ chunk,
932
+ contentHashType: "css"
933
+ });
934
+ }
935
+ break;
894
936
  }
895
937
  }
896
938
  }
897
939
 
898
- if (cssRemovedChunkIds.length > 0) {
940
+ if (
941
+ cssRemovedChunkIds.length > 0 ||
942
+ cssChunkNames !== undefined
943
+ ) {
899
944
  hotUpdateMainJson.css = { r: cssRemovedChunkIds };
945
+ if (cssChunkNames !== undefined) {
946
+ hotUpdateMainJson.css.n = cssChunkNames;
947
+ }
900
948
  }
901
949
 
902
950
  const source = new RawSource(
@@ -15,7 +15,7 @@ const EntryDependency = require("./dependencies/EntryDependency");
15
15
  */
16
16
  /** @import Compiler from "./Compiler" */
17
17
  /** @import { ResolveData } from "./NormalModuleFactory" */
18
- /** @import { BeforeContextResolveData } from "./ContextModuleFactory" */
18
+ /** @import { BeforeContextResolveData } from "./context/ContextModuleFactory" */
19
19
 
20
20
  /** @typedef {(resource: string, context: string) => boolean} CheckResourceFn */
21
21
 
@@ -11,6 +11,7 @@ const {
11
11
  JAVASCRIPT_MODULE_TYPE_ESM
12
12
  } = require("./ModuleTypeConstants");
13
13
  const { getInnerGraphUtils } = require("./optimize/InnerGraph");
14
+ const { recordOptimizationBailout } = require("./util/buildDiagnostics");
14
15
 
15
16
  /** @import Compiler from "./Compiler" */
16
17
  /** @import { BuildInfo } from "./Module" */
@@ -73,9 +74,10 @@ class JavascriptMetaInfoPlugin {
73
74
  const wasEnabled = innerGraph.isEnabled(parser.state);
74
75
  innerGraph.bailout(parser.state);
75
76
  if (wasEnabled) {
76
- compilation.moduleGraph
77
- .getOptimizationBailout(parser.state.module)
78
- .push("Inner graph bailout: eval()");
77
+ recordOptimizationBailout(
78
+ buildInfo,
79
+ "Inner graph bailout: eval()"
80
+ );
79
81
  }
80
82
  }
81
83
  });
@@ -19,7 +19,7 @@ const NormalModule = require("./NormalModule");
19
19
  /**
20
20
  * Defines the loader context type used by this module.
21
21
  * @template T
22
- * @typedef {import("../declarations/LoaderContext").LoaderContext<T>} LoaderContext
22
+ * @typedef {import("./NormalModule").LoaderContext<T>} LoaderContext
23
23
  */
24
24
 
25
25
  const PLUGIN_NAME = "LoaderOptionsPlugin";
@@ -21,7 +21,11 @@ const getJsonpTemplatePlugin = memoize(() =>
21
21
 
22
22
  /** @import { Tap } from "tapable" */
23
23
  /** @import { Source } from "webpack-sources" */
24
- /** @import { Output as OutputOptions } from "../declarations/WebpackOptions" */
24
+ /**
25
+ * @import {
26
+ * OutputNormalizedWithDefaults as OutputOptions
27
+ * } from "./config/defaults"
28
+ */
25
29
  /** @import ModuleTemplate from "./ModuleTemplate" */
26
30
  /** @import Chunk from "./Chunk" */
27
31
  /**
package/lib/Module.js CHANGED
@@ -128,6 +128,10 @@ const makeSerializable = require("./util/makeSerializable");
128
128
  * @property {Set<string>} topLevelDeclarations top level declarations for javascript modules
129
129
  * @property {Set<string>} freeNames free identifier names in the rendered source for javascript modules
130
130
  * @property {InitFragment<EXPECTED_ANY>[]} chunkInitFragments chunk init fragments for javascript modules
131
+ * @property {string} externalReexport native external reexport source and attributes
132
+ * @property {string} exportsSource export definitions left out of a javascript module's source on demand (see `KnownMeta.onDemandExports`), to be placed before its body where it is wrapped
133
+ * @property {string} exportsBindingSource export definitions left out on demand that read the module's own declarations, to be placed after its body where it is wrapped
134
+ * @property {Record<string, string>} exportsFinalName final name of each used export of a concatenated module whose definitions were left out on demand
131
135
  * @property {{ javascript?: string, ["asset-url"]?: string }} url url for asset modules
132
136
  * @property {string} filename a filename for asset modules
133
137
  * @property {AssetInfo} assetInfo an asset info for asset modules
@@ -181,28 +185,35 @@ const makeSerializable = require("./util/makeSerializable");
181
185
  * @property {(false | "redirect" | "redirect-warn")=} defaultObject
182
186
  * @property {boolean=} async
183
187
  * @property {boolean=} sideEffectFree
184
- * @property {Map<string, Record<string, string>>=} exportsFinalNameByRuntime using in ModuleLibraryPlugin
185
- * @property {Map<string, string>=} exportsSourceByRuntime using in ModuleLibraryPlugin
186
- * @property {Map<string, string>=} exportsBindingSourceByRuntime export definitions `ModuleLibraryPlugin` took over, re-emitted only where the module is wrapped
188
+ */
189
+
190
+ /**
191
+ * What a build recorded for stats and the performance hints to report, kept on the build info so a module restored from the cache still has it.
192
+ * @typedef {object} BuildDiagnostics
193
+ * @property {string[]=} optimizationBailouts what parser plugins reported as optimization bailouts, replayed into the module graph of every compilation that reuses the module
194
+ * @property {string=} sideEffectStatement the statement whose side effect keeps the module in the bundle, as `type at location`
195
+ * @property {number=} ineffectivePureAnnotations how many `#__PURE__` annotations sit where the parser does not read them
196
+ * @property {number=} topLevelThis how many times the module reads `this` at its top level
197
+ * @property {boolean=} usesEval true when the module calls `eval` directly
198
+ * @property {string[]=} notCacheableReasons reasons why the module is not cacheable (e.g. paths of loaders that marked it)
187
199
  */
188
200
 
189
201
  /**
190
202
  * Defines the build info properties common to all module types.
191
203
  * Module type specific properties live in the `Known*BuildInfo` typedef of the dedicated module class.
192
204
  * @typedef {object} KnownBuildInfo
205
+ * @property {boolean=} specNamespaceObject the module hands out a spec Module Namespace Exotic Object
193
206
  * @property {boolean=} cacheable
194
- * @property {string[]=} notCacheableReasons reasons why the module is not cacheable (e.g. paths of loaders that marked it)
195
207
  * @property {boolean=} strict
196
208
  * @property {string=} moduleArgument
197
209
  * @property {string=} exportsArgument
198
210
  * @property {Record<string, Source>=} assets assets added by loaders or plugins
199
211
  * @property {Map<string, AssetInfo | undefined>=} assetsInfo
200
212
  * @property {Set<string>=} topLevelDeclarations top level declaration names
201
- * @property {boolean=} isCircular true when the module is part of a circular dependency chain
202
- * @property {boolean=} usesEval true when the module calls `eval` directly
203
- * @property {number=} ineffectivePureAnnotations how many `#__PURE__` annotations sit where the parser does not read them
204
- * @property {number=} topLevelThis how many times the module reads `this` at its top level
213
+ * @property {boolean=} isCircular true when the module is in a synchronous circular dependency chain
214
+ * @property {number=} circularKind CircularKind bit flags from CircularModulesPlugin; unset when the plugin did not run
205
215
  * @property {boolean=} usesTopLevelAwaitForOf module uses top-level `for await…of` or `await using`, which can't be lowered to a generator
216
+ * @property {BuildDiagnostics=} diagnostics what the build recorded for stats and the performance hints to report
206
217
  */
207
218
 
208
219
  /** @typedef {string | Set<string>} ValueCacheVersion */
@@ -1310,7 +1321,6 @@ class Module extends DependenciesBlock {
1310
1321
  write(this.type);
1311
1322
  write(this.layer);
1312
1323
  write(this.context);
1313
- write(this.resolveOptions);
1314
1324
  write(this.factoryMeta);
1315
1325
  write(this.useSourceMap);
1316
1326
  write(this.useSimpleSourceMap);
@@ -1340,7 +1350,6 @@ class Module extends DependenciesBlock {
1340
1350
  this.type = read();
1341
1351
  this.layer = read();
1342
1352
  this.context = read();
1343
- this.resolveOptions = read();
1344
1353
  this.factoryMeta = read();
1345
1354
  this.useSourceMap = read();
1346
1355
  this.useSimpleSourceMap = read();
@@ -143,6 +143,7 @@ class ModuleGraphModule {
143
143
  * @typedef {object} KnownMeta
144
144
  * @property {Map<Module, string>=} importVarMap
145
145
  * @property {Map<Module, string>=} deferredImportVarMap
146
+ * @property {boolean=} onDemandExports generate export definitions on demand
146
147
  */
147
148
 
148
149
  /** @typedef {KnownMeta & Record<CommonJsExportRequireDependencyIDsSymbol | HarmonyImportSpecifierDependencyIDsSymbol | HarmonyExportImportedSpecifierDependencyIDsSymbol, string[]> & Record<string, EXPECTED_ANY>} Meta */
@@ -342,10 +343,8 @@ class ModuleGraph {
342
343
  }
343
344
  const originDependency = connection.dependency;
344
345
 
345
- // src/index.js
346
- // import { c } from "lib/c" -> c = 0
347
- // import { a, b } from "lib" -> a and b have the same source order -> a = b = 1
348
- // import { d } from "lib/d" -> d = 2
346
+ // Specifiers of one import statement share its source order, so `a` and `b`
347
+ // of `import { a, b } from "lib"` both take the statement's index.
349
348
  const currentSourceOrder =
350
349
  /** @type {HarmonyImportSideEffectDependency | HarmonyImportSpecifierDependency} */
351
350
  (dependency).sourceOrder;
@@ -360,11 +359,9 @@ class ModuleGraph {
360
359
  typeof currentSourceOrder === "number" &&
361
360
  typeof originSourceOrder === "number"
362
361
  ) {
363
- // src/index.js
364
- // import { c } from "lib/c" -> c = 0
365
- // import { a } from "lib/a" -> a = 1.0 = 1(main) + 0.0(sub)
366
- // import { b } from "lib/b" -> b = 1.1 = 1(main) + 0.1(sub)
367
- // import { d } from "lib/d" -> d = 2
362
+ // A re-exported specifier keeps the importing statement's order as `main`
363
+ // and its own position as `sub`, so the pair orders it within that
364
+ // statement without disturbing the statements around it.
368
365
  this._dependencySourceOrderMap.set(dependency, {
369
366
  main: currentSourceOrder,
370
367
  sub: originSourceOrder
@@ -5,13 +5,13 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const asyncLib = require("neo-async");
9
8
  const { MultiHook, SyncHook } = require("tapable");
10
9
 
11
10
  const MultiStats = require("./MultiStats");
12
11
  const MultiWatching = require("./MultiWatching");
13
12
  const WebpackError = require("./errors/WebpackError");
14
13
  const ArrayQueue = require("./util/ArrayQueue");
14
+ const asyncLib = require("./util/async");
15
15
  const memoize = require("./util/memoize");
16
16
 
17
17
  const getConcurrentCompilationError = memoize(() =>
@@ -158,11 +158,9 @@ module.exports = class MultiCompiler {
158
158
  doneCompilers--;
159
159
  }
160
160
  });
161
- // Release fields on this child's Compilation once it's done. The
162
- // stage: Infinity tap runs after every afterDone tap at a lower
163
- // stage, so plugins observing compilation state in afterDone still
164
- // see it intact. Stats remains usable; only fields Stats never reads
165
- // (and that the persistent cache never serializes) are dropped.
161
+ // Release this child's Compilation fields once it is done. The
162
+ // `stage: Infinity` tap runs last, so a plugin watching in afterDone still
163
+ // sees it intact, and only fields Stats never reads are dropped.
166
164
 
167
165
  compiler.hooks.afterDone.tap(
168
166
  { name: CLASS_NAME, stage: Infinity },
@@ -478,17 +476,9 @@ module.exports = class MultiCompiler {
478
476
  _runGraph(setup, run, callback) {
479
477
  /** @typedef {{ compiler: Compiler, setupResult: undefined | SetupResult, result: undefined | Stats, state: "pending" | "blocked" | "queued" | "starting" | "running" | "running-outdated" | "done", children: Node[], parents: Node[] }} Node */
480
478
 
481
- // State transitions for nodes:
482
- // -> blocked (initial)
483
- // blocked -> starting [running++] (when all parents done)
484
- // queued -> starting [running++] (when processing the queue)
485
- // starting -> running (when run has been called)
486
- // running -> done [running--] (when compilation is done)
487
- // done -> pending (when invalidated from file change)
488
- // pending -> blocked [add to queue] (when invalidated from aggregated changes)
489
- // done -> blocked [add to queue] (when invalidated, from parent invalidation)
490
- // running -> running-outdated (when invalidated, either from change or parent invalidation)
491
- // running-outdated -> blocked [running--] (when compilation is done)
479
+ // A node starts blocked and reaches `starting` once its parents are done or
480
+ // the queue reaches it, then `running`, then `done`. Invalidation sends it
481
+ // back to `blocked`, or to `running-outdated` if it is mid-compilation.
492
482
 
493
483
  /** @type {Node[]} */
494
484
  const nodes = this.compilers.map((compiler) => ({
@@ -5,7 +5,7 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const asyncLib = require("neo-async");
8
+ const asyncLib = require("./util/async");
9
9
 
10
10
  /** @import MultiCompiler from "./MultiCompiler" */
11
11
  /** @import Watching from "./Watching" */