webpack 5.59.0 → 5.94.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 (570) hide show
  1. package/README.md +48 -38
  2. package/bin/webpack.js +34 -10
  3. package/hot/dev-server.js +19 -5
  4. package/hot/lazy-compilation-node.js +13 -1
  5. package/hot/lazy-compilation-web.js +9 -0
  6. package/hot/log-apply-result.js +5 -0
  7. package/hot/log.js +23 -4
  8. package/hot/only-dev-server.js +3 -2
  9. package/hot/poll.js +5 -2
  10. package/hot/signal.js +6 -2
  11. package/lib/APIPlugin.js +226 -122
  12. package/lib/AbstractMethodError.js +10 -5
  13. package/lib/AsyncDependenciesBlock.js +13 -5
  14. package/lib/AutomaticPrefetchPlugin.js +2 -1
  15. package/lib/BannerPlugin.js +33 -12
  16. package/lib/Cache.js +16 -12
  17. package/lib/CacheFacade.js +13 -16
  18. package/lib/CaseSensitiveModulesWarning.js +8 -8
  19. package/lib/Chunk.js +60 -33
  20. package/lib/ChunkGraph.js +207 -72
  21. package/lib/ChunkGroup.js +40 -20
  22. package/lib/ChunkTemplate.js +43 -0
  23. package/lib/CleanPlugin.js +117 -32
  24. package/lib/CodeGenerationResults.js +8 -7
  25. package/lib/CommentCompilationWarning.js +0 -1
  26. package/lib/CompatibilityPlugin.js +85 -46
  27. package/lib/Compilation.js +712 -392
  28. package/lib/Compiler.js +393 -172
  29. package/lib/ConcatenationScope.js +10 -13
  30. package/lib/ConditionalInitFragment.js +22 -14
  31. package/lib/ConstPlugin.js +104 -64
  32. package/lib/ContextExclusionPlugin.js +3 -3
  33. package/lib/ContextModule.js +283 -108
  34. package/lib/ContextModuleFactory.js +151 -63
  35. package/lib/ContextReplacementPlugin.js +25 -10
  36. package/lib/CssModule.js +166 -0
  37. package/lib/DefinePlugin.js +254 -148
  38. package/lib/DelegatedModule.js +29 -6
  39. package/lib/DelegatedModuleFactoryPlugin.js +42 -22
  40. package/lib/DelegatedPlugin.js +4 -0
  41. package/lib/DependenciesBlock.js +17 -2
  42. package/lib/Dependency.js +58 -29
  43. package/lib/DependencyTemplate.js +24 -3
  44. package/lib/DependencyTemplates.js +2 -2
  45. package/lib/DllEntryPlugin.js +18 -1
  46. package/lib/DllModule.js +21 -4
  47. package/lib/DllModuleFactory.js +2 -1
  48. package/lib/DllPlugin.js +9 -7
  49. package/lib/DllReferencePlugin.js +50 -19
  50. package/lib/EntryOptionPlugin.js +6 -1
  51. package/lib/EntryPlugin.js +7 -4
  52. package/lib/Entrypoint.js +2 -2
  53. package/lib/EnvironmentNotSupportAsyncWarning.js +52 -0
  54. package/lib/EnvironmentPlugin.js +5 -2
  55. package/lib/ErrorHelpers.js +65 -26
  56. package/lib/EvalDevToolModulePlugin.js +37 -13
  57. package/lib/EvalSourceMapDevToolPlugin.js +50 -20
  58. package/lib/ExportsInfo.js +234 -133
  59. package/lib/ExportsInfoApiPlugin.js +31 -15
  60. package/lib/ExternalModule.js +391 -129
  61. package/lib/ExternalModuleFactoryPlugin.js +65 -17
  62. package/lib/FileSystemInfo.js +1038 -523
  63. package/lib/FlagAllModulesAsUsedPlugin.js +27 -27
  64. package/lib/FlagDependencyExportsPlugin.js +352 -349
  65. package/lib/FlagDependencyUsagePlugin.js +10 -10
  66. package/lib/FlagEntryExportAsUsedPlugin.js +26 -23
  67. package/lib/Generator.js +16 -8
  68. package/lib/GraphHelpers.js +3 -2
  69. package/lib/HookWebpackError.js +11 -13
  70. package/lib/HotModuleReplacementPlugin.js +221 -128
  71. package/lib/IgnoreErrorModuleFactory.js +4 -4
  72. package/lib/IgnorePlugin.js +5 -4
  73. package/lib/IgnoreWarningsPlugin.js +6 -9
  74. package/lib/InitFragment.js +39 -15
  75. package/lib/JavascriptMetaInfoPlugin.js +27 -15
  76. package/lib/LibManifestPlugin.js +45 -16
  77. package/lib/LoaderOptionsPlugin.js +13 -3
  78. package/lib/MainTemplate.js +74 -21
  79. package/lib/Module.js +155 -34
  80. package/lib/ModuleBuildError.js +13 -11
  81. package/lib/ModuleDependencyError.js +6 -4
  82. package/lib/ModuleDependencyWarning.js +6 -4
  83. package/lib/ModuleError.js +10 -5
  84. package/lib/ModuleFactory.js +4 -4
  85. package/lib/ModuleFilenameHelpers.js +164 -54
  86. package/lib/ModuleGraph.js +93 -53
  87. package/lib/ModuleGraphConnection.js +27 -13
  88. package/lib/ModuleHashingError.js +29 -0
  89. package/lib/ModuleInfoHeaderPlugin.js +92 -33
  90. package/lib/ModuleNotFoundError.js +5 -2
  91. package/lib/ModuleParseError.js +17 -9
  92. package/lib/ModuleProfile.js +1 -0
  93. package/lib/ModuleRestoreError.js +3 -1
  94. package/lib/ModuleStoreError.js +3 -2
  95. package/lib/ModuleTemplate.js +33 -1
  96. package/lib/ModuleTypeConstants.js +168 -0
  97. package/lib/ModuleWarning.js +10 -5
  98. package/lib/MultiCompiler.js +115 -38
  99. package/lib/MultiStats.js +75 -33
  100. package/lib/MultiWatching.js +6 -2
  101. package/lib/NodeStuffPlugin.js +136 -37
  102. package/lib/NormalModule.js +437 -194
  103. package/lib/NormalModuleFactory.js +313 -116
  104. package/lib/NormalModuleReplacementPlugin.js +10 -4
  105. package/lib/NullFactory.js +1 -1
  106. package/lib/OptimizationStages.js +3 -3
  107. package/lib/Parser.js +1 -1
  108. package/lib/PlatformPlugin.js +39 -0
  109. package/lib/PrefetchPlugin.js +4 -0
  110. package/lib/ProgressPlugin.js +83 -28
  111. package/lib/ProvidePlugin.js +37 -19
  112. package/lib/RawModule.js +18 -5
  113. package/lib/RecordIdsPlugin.js +8 -8
  114. package/lib/RequireJsStuffPlugin.js +22 -15
  115. package/lib/ResolverFactory.js +8 -4
  116. package/lib/RuntimeGlobals.js +99 -65
  117. package/lib/RuntimeModule.js +17 -15
  118. package/lib/RuntimePlugin.js +116 -13
  119. package/lib/RuntimeTemplate.js +304 -102
  120. package/lib/SelfModuleFactory.js +12 -0
  121. package/lib/SizeFormatHelpers.js +2 -4
  122. package/lib/SourceMapDevToolModuleOptionsPlugin.js +4 -0
  123. package/lib/SourceMapDevToolPlugin.js +89 -42
  124. package/lib/Stats.js +12 -7
  125. package/lib/Template.js +30 -33
  126. package/lib/TemplatedPathPlugin.js +102 -34
  127. package/lib/UseStrictPlugin.js +37 -12
  128. package/lib/WarnCaseSensitiveModulesPlugin.js +12 -0
  129. package/lib/WarnDeprecatedOptionPlugin.js +6 -0
  130. package/lib/WatchIgnorePlugin.js +46 -13
  131. package/lib/Watching.js +139 -76
  132. package/lib/WebpackError.js +14 -5
  133. package/lib/WebpackIsIncludedPlugin.js +22 -13
  134. package/lib/WebpackOptionsApply.js +162 -56
  135. package/lib/WebpackOptionsDefaulter.js +10 -3
  136. package/lib/asset/AssetGenerator.js +351 -99
  137. package/lib/asset/AssetModulesPlugin.js +57 -33
  138. package/lib/asset/AssetParser.js +15 -6
  139. package/lib/asset/AssetSourceGenerator.js +30 -10
  140. package/lib/asset/AssetSourceParser.js +8 -2
  141. package/lib/asset/RawDataUrlModule.js +162 -0
  142. package/lib/async-modules/AwaitDependenciesInitFragment.js +16 -13
  143. package/lib/async-modules/InferAsyncModulesPlugin.js +1 -1
  144. package/lib/buildChunkGraph.js +376 -420
  145. package/lib/cache/AddManagedPathsPlugin.js +6 -1
  146. package/lib/cache/IdleFileCachePlugin.js +26 -13
  147. package/lib/cache/MemoryCachePlugin.js +1 -1
  148. package/lib/cache/MemoryWithGcCachePlugin.js +13 -7
  149. package/lib/cache/PackFileCacheStrategy.js +172 -94
  150. package/lib/cache/ResolverCachePlugin.js +115 -43
  151. package/lib/cache/getLazyHashedEtag.js +2 -2
  152. package/lib/cache/mergeEtags.js +16 -21
  153. package/lib/cli.js +195 -110
  154. package/lib/config/browserslistTargetHandler.js +106 -41
  155. package/lib/config/defaults.js +572 -154
  156. package/lib/config/normalization.js +361 -322
  157. package/lib/config/target.js +105 -66
  158. package/lib/container/ContainerEntryDependency.js +2 -1
  159. package/lib/container/ContainerEntryModule.js +27 -11
  160. package/lib/container/ContainerEntryModuleFactory.js +1 -1
  161. package/lib/container/ContainerExposedDependency.js +9 -0
  162. package/lib/container/ContainerPlugin.js +18 -12
  163. package/lib/container/ContainerReferencePlugin.js +1 -1
  164. package/lib/container/FallbackDependency.js +13 -0
  165. package/lib/container/FallbackItemDependency.js +3 -0
  166. package/lib/container/FallbackModule.js +19 -8
  167. package/lib/container/FallbackModuleFactory.js +1 -1
  168. package/lib/container/ModuleFederationPlugin.js +2 -0
  169. package/lib/container/RemoteModule.js +17 -4
  170. package/lib/container/RemoteRuntimeModule.js +31 -17
  171. package/lib/container/RemoteToExternalDependency.js +3 -0
  172. package/lib/container/options.js +18 -4
  173. package/lib/css/CssExportsGenerator.js +203 -0
  174. package/lib/css/CssGenerator.js +151 -0
  175. package/lib/css/CssLoadingRuntimeModule.js +592 -0
  176. package/lib/css/CssModulesPlugin.js +888 -0
  177. package/lib/css/CssParser.js +1049 -0
  178. package/lib/css/walkCssTokens.js +775 -0
  179. package/lib/debug/ProfilingPlugin.js +102 -54
  180. package/lib/dependencies/AMDDefineDependency.js +54 -10
  181. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +204 -61
  182. package/lib/dependencies/AMDPlugin.js +44 -24
  183. package/lib/dependencies/AMDRequireArrayDependency.js +34 -10
  184. package/lib/dependencies/AMDRequireContextDependency.js +15 -0
  185. package/lib/dependencies/AMDRequireDependenciesBlock.js +6 -0
  186. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +185 -54
  187. package/lib/dependencies/AMDRequireDependency.js +21 -6
  188. package/lib/dependencies/AMDRequireItemDependency.js +6 -0
  189. package/lib/dependencies/AMDRuntimeModules.js +4 -4
  190. package/lib/dependencies/CachedConstDependency.js +22 -1
  191. package/lib/dependencies/CommonJsDependencyHelpers.js +16 -2
  192. package/lib/dependencies/CommonJsExportRequireDependency.js +77 -47
  193. package/lib/dependencies/CommonJsExportsDependency.js +28 -5
  194. package/lib/dependencies/CommonJsExportsParserPlugin.js +111 -39
  195. package/lib/dependencies/CommonJsFullRequireDependency.js +42 -8
  196. package/lib/dependencies/CommonJsImportsParserPlugin.js +530 -130
  197. package/lib/dependencies/CommonJsPlugin.js +51 -26
  198. package/lib/dependencies/CommonJsRequireContextDependency.js +23 -2
  199. package/lib/dependencies/CommonJsRequireDependency.js +9 -1
  200. package/lib/dependencies/CommonJsSelfReferenceDependency.js +22 -8
  201. package/lib/dependencies/ConstDependency.js +12 -3
  202. package/lib/dependencies/ContextDependency.js +32 -5
  203. package/lib/dependencies/ContextDependencyHelpers.js +92 -62
  204. package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +4 -1
  205. package/lib/dependencies/ContextElementDependency.js +41 -4
  206. package/lib/dependencies/CreateScriptUrlDependency.js +22 -1
  207. package/lib/dependencies/CriticalDependencyWarning.js +4 -1
  208. package/lib/dependencies/CssExportDependency.js +156 -0
  209. package/lib/dependencies/CssImportDependency.js +125 -0
  210. package/lib/dependencies/CssLocalIdentifierDependency.js +245 -0
  211. package/lib/dependencies/CssSelfLocalIdentifierDependency.js +111 -0
  212. package/lib/dependencies/CssUrlDependency.js +164 -0
  213. package/lib/dependencies/DelegatedSourceDependency.js +3 -0
  214. package/lib/dependencies/DllEntryDependency.js +14 -0
  215. package/lib/dependencies/DynamicExports.js +15 -11
  216. package/lib/dependencies/ExportsInfoDependency.js +26 -5
  217. package/lib/dependencies/ExternalModuleDependency.js +109 -0
  218. package/lib/dependencies/ExternalModuleInitFragment.js +133 -0
  219. package/lib/dependencies/HarmonyAcceptDependency.js +11 -2
  220. package/lib/dependencies/HarmonyAcceptImportDependency.js +9 -4
  221. package/lib/dependencies/HarmonyCompatibilityDependency.js +6 -5
  222. package/lib/dependencies/HarmonyDetectionParserPlugin.js +29 -3
  223. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +152 -0
  224. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +96 -51
  225. package/lib/dependencies/HarmonyExportExpressionDependency.js +21 -4
  226. package/lib/dependencies/HarmonyExportHeaderDependency.js +13 -0
  227. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +216 -108
  228. package/lib/dependencies/HarmonyExportInitFragment.js +21 -9
  229. package/lib/dependencies/HarmonyExportSpecifierDependency.js +12 -0
  230. package/lib/dependencies/HarmonyExports.js +13 -7
  231. package/lib/dependencies/HarmonyImportDependency.js +65 -19
  232. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +268 -74
  233. package/lib/dependencies/HarmonyImportSideEffectDependency.js +11 -5
  234. package/lib/dependencies/HarmonyImportSpecifierDependency.js +180 -36
  235. package/lib/dependencies/HarmonyModulesPlugin.js +33 -5
  236. package/lib/dependencies/HarmonyTopLevelThisParserPlugin.js +15 -3
  237. package/lib/dependencies/ImportContextDependency.js +15 -2
  238. package/lib/dependencies/ImportDependency.js +50 -12
  239. package/lib/dependencies/ImportEagerDependency.js +11 -6
  240. package/lib/dependencies/ImportMetaContextDependency.js +42 -0
  241. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +301 -0
  242. package/lib/dependencies/ImportMetaContextPlugin.js +72 -0
  243. package/lib/dependencies/ImportMetaHotAcceptDependency.js +6 -0
  244. package/lib/dependencies/ImportMetaHotDeclineDependency.js +6 -0
  245. package/lib/dependencies/ImportMetaPlugin.js +128 -59
  246. package/lib/dependencies/ImportParserPlugin.js +153 -83
  247. package/lib/dependencies/ImportPlugin.js +21 -7
  248. package/lib/dependencies/ImportWeakDependency.js +11 -6
  249. package/lib/dependencies/JsonExportsDependency.js +38 -30
  250. package/lib/dependencies/LoaderDependency.js +14 -0
  251. package/lib/dependencies/LoaderImportDependency.js +14 -0
  252. package/lib/dependencies/LoaderPlugin.js +54 -40
  253. package/lib/dependencies/LocalModule.js +17 -1
  254. package/lib/dependencies/LocalModuleDependency.js +15 -0
  255. package/lib/dependencies/LocalModulesHelpers.js +22 -4
  256. package/lib/dependencies/ModuleDecoratorDependency.js +9 -1
  257. package/lib/dependencies/ModuleDependency.js +24 -7
  258. package/lib/dependencies/ModuleDependencyTemplateAsId.js +2 -1
  259. package/lib/dependencies/ModuleHotAcceptDependency.js +6 -0
  260. package/lib/dependencies/ModuleHotDeclineDependency.js +6 -0
  261. package/lib/dependencies/PrefetchDependency.js +3 -0
  262. package/lib/dependencies/ProvidedDependency.js +43 -8
  263. package/lib/dependencies/PureExpressionDependency.js +73 -39
  264. package/lib/dependencies/RequireContextDependency.js +6 -16
  265. package/lib/dependencies/RequireContextDependencyParserPlugin.js +14 -6
  266. package/lib/dependencies/RequireContextPlugin.js +20 -7
  267. package/lib/dependencies/RequireEnsureDependenciesBlock.js +7 -0
  268. package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +29 -12
  269. package/lib/dependencies/RequireEnsureDependency.js +16 -2
  270. package/lib/dependencies/RequireEnsureItemDependency.js +3 -0
  271. package/lib/dependencies/RequireEnsurePlugin.js +27 -7
  272. package/lib/dependencies/RequireHeaderDependency.js +14 -1
  273. package/lib/dependencies/RequireIncludeDependency.js +6 -1
  274. package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +29 -5
  275. package/lib/dependencies/RequireIncludePlugin.js +25 -5
  276. package/lib/dependencies/RequireResolveContextDependency.js +19 -2
  277. package/lib/dependencies/RequireResolveDependency.js +8 -1
  278. package/lib/dependencies/RequireResolveHeaderDependency.js +18 -0
  279. package/lib/dependencies/RuntimeRequirementsDependency.js +9 -1
  280. package/lib/dependencies/StaticExportsDependency.js +8 -0
  281. package/lib/dependencies/SystemPlugin.js +49 -22
  282. package/lib/dependencies/SystemRuntimeModule.js +1 -1
  283. package/lib/dependencies/URLDependency.js +20 -13
  284. package/lib/dependencies/URLPlugin.js +115 -27
  285. package/lib/dependencies/UnsupportedDependency.js +13 -0
  286. package/lib/dependencies/WebAssemblyExportImportedDependency.js +14 -0
  287. package/lib/dependencies/WebAssemblyImportDependency.js +9 -1
  288. package/lib/dependencies/WebpackIsIncludedDependency.js +6 -1
  289. package/lib/dependencies/WorkerDependency.js +47 -3
  290. package/lib/dependencies/WorkerPlugin.js +143 -59
  291. package/lib/dependencies/getFunctionExpression.js +9 -0
  292. package/lib/dependencies/processExportInfo.js +3 -1
  293. package/lib/electron/ElectronTargetPlugin.js +1 -0
  294. package/lib/esm/ExportWebpackRequireRuntimeModule.js +3 -2
  295. package/lib/esm/ModuleChunkFormatPlugin.js +92 -55
  296. package/lib/esm/ModuleChunkLoadingPlugin.js +12 -1
  297. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +141 -25
  298. package/lib/formatLocation.js +1 -2
  299. package/lib/hmr/HotModuleReplacement.runtime.js +37 -25
  300. package/lib/hmr/HotModuleReplacementRuntimeModule.js +2 -1
  301. package/lib/hmr/JavascriptHotModuleReplacement.runtime.js +13 -15
  302. package/lib/hmr/LazyCompilationPlugin.js +94 -41
  303. package/lib/hmr/lazyCompilationBackend.js +107 -44
  304. package/lib/ids/ChunkModuleIdRangePlugin.js +12 -3
  305. package/lib/ids/DeterministicChunkIdsPlugin.js +13 -6
  306. package/lib/ids/DeterministicModuleIdsPlugin.js +59 -35
  307. package/lib/ids/HashedModuleIdsPlugin.js +24 -16
  308. package/lib/ids/IdHelpers.js +59 -49
  309. package/lib/ids/NamedChunkIdsPlugin.js +13 -1
  310. package/lib/ids/NamedModuleIdsPlugin.js +20 -12
  311. package/lib/ids/NaturalModuleIdsPlugin.js +10 -13
  312. package/lib/ids/OccurrenceChunkIdsPlugin.js +6 -2
  313. package/lib/ids/OccurrenceModuleIdsPlugin.js +14 -11
  314. package/lib/ids/SyncModuleIdsPlugin.js +146 -0
  315. package/lib/index.js +44 -5
  316. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +9 -7
  317. package/lib/javascript/BasicEvaluatedExpression.js +133 -19
  318. package/lib/javascript/ChunkHelpers.js +33 -0
  319. package/lib/javascript/CommonJsChunkFormatPlugin.js +18 -15
  320. package/lib/javascript/EnableChunkLoadingPlugin.js +11 -6
  321. package/lib/javascript/JavascriptGenerator.js +37 -6
  322. package/lib/javascript/JavascriptModulesPlugin.js +523 -295
  323. package/lib/javascript/JavascriptParser.js +1591 -574
  324. package/lib/javascript/JavascriptParserHelpers.js +58 -37
  325. package/lib/javascript/StartupHelpers.js +69 -47
  326. package/lib/json/JsonData.js +33 -0
  327. package/lib/json/JsonGenerator.js +29 -21
  328. package/lib/json/JsonModulesPlugin.js +13 -7
  329. package/lib/json/JsonParser.js +30 -16
  330. package/lib/library/AbstractLibraryPlugin.js +6 -2
  331. package/lib/library/AmdLibraryPlugin.js +34 -18
  332. package/lib/library/AssignLibraryPlugin.js +68 -32
  333. package/lib/library/EnableLibraryPlugin.js +39 -14
  334. package/lib/library/ExportPropertyLibraryPlugin.js +14 -5
  335. package/lib/library/JsonpLibraryPlugin.js +4 -3
  336. package/lib/library/ModernModuleLibraryPlugin.js +144 -0
  337. package/lib/library/ModuleLibraryPlugin.js +12 -7
  338. package/lib/library/SystemLibraryPlugin.js +6 -4
  339. package/lib/library/UmdLibraryPlugin.js +119 -100
  340. package/lib/logging/Logger.js +59 -6
  341. package/lib/logging/createConsoleLogger.js +25 -40
  342. package/lib/logging/runtime.js +8 -9
  343. package/lib/logging/truncateArgs.js +9 -8
  344. package/lib/node/CommonJsChunkLoadingPlugin.js +18 -2
  345. package/lib/node/NodeEnvironmentPlugin.js +14 -8
  346. package/lib/node/NodeTargetPlugin.js +7 -0
  347. package/lib/node/NodeTemplatePlugin.js +10 -2
  348. package/lib/node/NodeWatchFileSystem.js +100 -50
  349. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +51 -26
  350. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +13 -2
  351. package/lib/node/ReadFileCompileWasmPlugin.js +21 -3
  352. package/lib/node/RequireChunkLoadingRuntimeModule.js +49 -26
  353. package/lib/node/nodeConsole.js +48 -31
  354. package/lib/optimize/AggressiveMergingPlugin.js +10 -4
  355. package/lib/optimize/AggressiveSplittingPlugin.js +26 -21
  356. package/lib/optimize/ConcatenatedModule.js +353 -212
  357. package/lib/optimize/EnsureChunkConditionsPlugin.js +4 -1
  358. package/lib/optimize/FlagIncludedChunksPlugin.js +14 -8
  359. package/lib/optimize/InnerGraph.js +30 -25
  360. package/lib/optimize/InnerGraphPlugin.js +105 -64
  361. package/lib/optimize/LimitChunkCountPlugin.js +32 -9
  362. package/lib/optimize/MangleExportsPlugin.js +7 -2
  363. package/lib/optimize/MinMaxSizeWarning.js +6 -1
  364. package/lib/optimize/ModuleConcatenationPlugin.js +150 -83
  365. package/lib/optimize/RealContentHashPlugin.js +99 -43
  366. package/lib/optimize/RemoveParentModulesPlugin.js +131 -48
  367. package/lib/optimize/RuntimeChunkPlugin.js +15 -2
  368. package/lib/optimize/SideEffectsFlagPlugin.js +119 -63
  369. package/lib/optimize/SplitChunksPlugin.js +129 -78
  370. package/lib/performance/SizeLimitsPlugin.js +22 -8
  371. package/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js +4 -2
  372. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +4 -1
  373. package/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js +8 -5
  374. package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +5 -3
  375. package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +5 -3
  376. package/lib/rules/BasicEffectRulePlugin.js +7 -1
  377. package/lib/rules/BasicMatcherRulePlugin.js +8 -1
  378. package/lib/rules/ObjectMatcherRulePlugin.js +19 -2
  379. package/lib/rules/RuleSetCompiler.js +53 -32
  380. package/lib/rules/UseEffectRulePlugin.js +42 -36
  381. package/lib/runtime/AsyncModuleRuntimeModule.js +56 -69
  382. package/lib/runtime/AutoPublicPathRuntimeModule.js +25 -9
  383. package/lib/runtime/BaseUriRuntimeModule.js +35 -0
  384. package/lib/runtime/ChunkNameRuntimeModule.js +1 -1
  385. package/lib/runtime/CompatGetDefaultExportRuntimeModule.js +5 -2
  386. package/lib/runtime/CompatRuntimeModule.js +7 -2
  387. package/lib/runtime/CreateFakeNamespaceObjectRuntimeModule.js +7 -4
  388. package/lib/runtime/CreateScriptRuntimeModule.js +38 -0
  389. package/lib/runtime/CreateScriptUrlRuntimeModule.js +13 -36
  390. package/lib/runtime/DefinePropertyGettersRuntimeModule.js +6 -3
  391. package/lib/runtime/EnsureChunkRuntimeModule.js +29 -15
  392. package/lib/runtime/GetChunkFilenameRuntimeModule.js +56 -43
  393. package/lib/runtime/GetFullHashRuntimeModule.js +4 -3
  394. package/lib/runtime/GetMainFilenameRuntimeModule.js +5 -2
  395. package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +98 -0
  396. package/lib/runtime/GlobalRuntimeModule.js +1 -1
  397. package/lib/runtime/HasOwnPropertyRuntimeModule.js +5 -2
  398. package/lib/runtime/LoadScriptRuntimeModule.js +61 -45
  399. package/lib/runtime/MakeNamespaceObjectRuntimeModule.js +5 -2
  400. package/lib/runtime/NonceRuntimeModule.js +24 -0
  401. package/lib/runtime/OnChunksLoadedRuntimeModule.js +4 -2
  402. package/lib/runtime/PublicPathRuntimeModule.js +9 -2
  403. package/lib/runtime/RelativeUrlRuntimeModule.js +5 -2
  404. package/lib/runtime/RuntimeIdRuntimeModule.js +6 -2
  405. package/lib/runtime/StartupChunkDependenciesPlugin.js +15 -0
  406. package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +36 -28
  407. package/lib/runtime/StartupEntrypointRuntimeModule.js +13 -9
  408. package/lib/runtime/SystemContextRuntimeModule.js +1 -1
  409. package/lib/schemes/DataUriPlugin.js +16 -3
  410. package/lib/schemes/HttpUriPlugin.js +336 -120
  411. package/lib/serialization/ArraySerializer.js +22 -6
  412. package/lib/serialization/BinaryMiddleware.js +212 -33
  413. package/lib/serialization/DateObjectSerializer.js +16 -4
  414. package/lib/serialization/ErrorObjectSerializer.js +23 -6
  415. package/lib/serialization/FileMiddleware.js +187 -86
  416. package/lib/serialization/MapObjectSerializer.js +25 -8
  417. package/lib/serialization/NullPrototypeObjectSerializer.js +26 -8
  418. package/lib/serialization/ObjectMiddleware.js +96 -66
  419. package/lib/serialization/PlainObjectSerializer.js +51 -14
  420. package/lib/serialization/RegExpObjectSerializer.js +17 -5
  421. package/lib/serialization/Serializer.js +23 -5
  422. package/lib/serialization/SerializerMiddleware.js +8 -8
  423. package/lib/serialization/SetObjectSerializer.js +22 -6
  424. package/lib/serialization/SingleItemMiddleware.js +2 -2
  425. package/lib/serialization/types.js +2 -2
  426. package/lib/sharing/ConsumeSharedFallbackDependency.js +3 -0
  427. package/lib/sharing/ConsumeSharedModule.js +40 -17
  428. package/lib/sharing/ConsumeSharedPlugin.js +139 -102
  429. package/lib/sharing/ConsumeSharedRuntimeModule.js +144 -130
  430. package/lib/sharing/ProvideForSharedDependency.js +0 -1
  431. package/lib/sharing/ProvideSharedDependency.js +17 -0
  432. package/lib/sharing/ProvideSharedModule.js +19 -6
  433. package/lib/sharing/ProvideSharedModuleFactory.js +1 -1
  434. package/lib/sharing/ProvideSharedPlugin.js +37 -30
  435. package/lib/sharing/SharePlugin.js +2 -2
  436. package/lib/sharing/ShareRuntimeModule.js +20 -10
  437. package/lib/sharing/resolveMatchedConfigs.js +6 -5
  438. package/lib/sharing/utils.js +338 -34
  439. package/lib/stats/DefaultStatsFactoryPlugin.js +660 -396
  440. package/lib/stats/DefaultStatsPresetPlugin.js +85 -25
  441. package/lib/stats/DefaultStatsPrinterPlugin.js +525 -145
  442. package/lib/stats/StatsFactory.js +128 -57
  443. package/lib/stats/StatsPrinter.js +77 -46
  444. package/lib/util/ArrayHelpers.js +35 -1
  445. package/lib/util/ArrayQueue.js +15 -22
  446. package/lib/util/AsyncQueue.js +37 -16
  447. package/lib/util/IterableHelpers.js +3 -4
  448. package/lib/util/LazyBucketSortedSet.js +60 -44
  449. package/lib/util/LazySet.js +11 -2
  450. package/lib/util/MapHelpers.js +17 -5
  451. package/lib/util/ParallelismFactorCalculator.js +11 -1
  452. package/lib/util/Queue.js +9 -3
  453. package/lib/util/Semaphore.js +4 -7
  454. package/lib/util/SetHelpers.js +5 -5
  455. package/lib/util/SortableSet.js +19 -6
  456. package/lib/util/StackedCacheMap.js +33 -3
  457. package/lib/util/StackedMap.js +1 -3
  458. package/lib/util/StringXor.js +46 -0
  459. package/lib/util/TupleQueue.js +9 -3
  460. package/lib/util/TupleSet.js +15 -5
  461. package/lib/util/URLAbsoluteSpecifier.js +8 -8
  462. package/lib/util/WeakTupleMap.js +70 -28
  463. package/lib/util/binarySearchBounds.js +51 -9
  464. package/lib/util/chainedImports.js +97 -0
  465. package/lib/util/cleverMerge.js +51 -36
  466. package/lib/util/comparators.js +146 -83
  467. package/lib/util/compileBooleanMatcher.js +35 -7
  468. package/lib/util/conventions.js +126 -0
  469. package/lib/util/create-schema-validation.js +9 -2
  470. package/lib/util/createHash.js +49 -14
  471. package/lib/util/deprecation.js +48 -15
  472. package/lib/util/deterministicGrouping.js +71 -39
  473. package/lib/util/extractUrlAndGlobal.js +3 -0
  474. package/lib/util/findGraphRoots.js +7 -5
  475. package/lib/util/fs.js +419 -94
  476. package/lib/util/hash/BatchedHash.js +10 -4
  477. package/lib/util/hash/md4.js +20 -0
  478. package/lib/util/hash/wasm-hash.js +163 -0
  479. package/lib/util/hash/xxhash64.js +7 -141
  480. package/lib/util/identifier.js +140 -93
  481. package/lib/util/internalSerializables.js +22 -0
  482. package/lib/util/makeSerializable.js +7 -0
  483. package/lib/util/memoize.js +10 -10
  484. package/lib/util/mergeScope.js +76 -0
  485. package/lib/util/nonNumericOnlyHash.js +22 -0
  486. package/lib/util/numberHash.js +84 -34
  487. package/lib/util/objectToMap.js +0 -1
  488. package/lib/util/processAsyncTree.js +7 -1
  489. package/lib/util/propertyAccess.js +7 -55
  490. package/lib/util/propertyName.js +77 -0
  491. package/lib/util/registerExternalSerializer.js +2 -2
  492. package/lib/util/runtime.js +188 -133
  493. package/lib/util/semver.js +64 -56
  494. package/lib/util/serialization.js +26 -1
  495. package/lib/util/smartGrouping.js +10 -10
  496. package/lib/util/source.js +1 -1
  497. package/lib/validateSchema.js +6 -2
  498. package/lib/wasm/EnableWasmLoadingPlugin.js +9 -4
  499. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +70 -30
  500. package/lib/wasm-async/AsyncWebAssemblyGenerator.js +9 -1
  501. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +34 -16
  502. package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +32 -12
  503. package/lib/wasm-async/AsyncWebAssemblyParser.js +17 -4
  504. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +72 -31
  505. package/lib/wasm-sync/WasmFinalizeExportsPlugin.js +17 -6
  506. package/lib/wasm-sync/WebAssemblyGenerator.js +72 -52
  507. package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +5 -4
  508. package/lib/wasm-sync/WebAssemblyModulesPlugin.js +53 -43
  509. package/lib/wasm-sync/WebAssemblyParser.js +23 -9
  510. package/lib/wasm-sync/WebAssemblyUtils.js +5 -4
  511. package/lib/web/FetchCompileAsyncWasmPlugin.js +11 -1
  512. package/lib/web/FetchCompileWasmPlugin.js +59 -42
  513. package/lib/web/JsonpChunkLoadingPlugin.js +9 -0
  514. package/lib/web/JsonpChunkLoadingRuntimeModule.js +71 -41
  515. package/lib/webpack.js +43 -12
  516. package/lib/webworker/ImportScriptsChunkLoadingPlugin.js +15 -12
  517. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +55 -40
  518. package/module.d.ts +233 -0
  519. package/package.json +85 -139
  520. package/schemas/WebpackOptions.check.js +1 -1
  521. package/schemas/WebpackOptions.json +679 -47
  522. package/schemas/plugins/BannerPlugin.check.js +1 -1
  523. package/schemas/plugins/BannerPlugin.json +9 -1
  524. package/schemas/plugins/DllReferencePlugin.check.js +1 -1
  525. package/schemas/plugins/HashedModuleIdsPlugin.check.js +1 -1
  526. package/schemas/plugins/ProgressPlugin.check.js +1 -1
  527. package/schemas/plugins/SourceMapDevToolPlugin.check.js +1 -1
  528. package/schemas/plugins/SourceMapDevToolPlugin.json +4 -0
  529. package/schemas/plugins/asset/AssetGeneratorOptions.check.js +1 -1
  530. package/schemas/plugins/asset/AssetInlineGeneratorOptions.check.js +1 -1
  531. package/schemas/plugins/asset/AssetParserOptions.check.js +1 -1
  532. package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js +1 -1
  533. package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
  534. package/schemas/plugins/container/ContainerPlugin.json +10 -1
  535. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  536. package/schemas/plugins/container/ContainerReferencePlugin.json +2 -0
  537. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  538. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  539. package/schemas/plugins/container/ModuleFederationPlugin.json +12 -1
  540. package/schemas/plugins/css/CssAutoGeneratorOptions.check.d.ts +7 -0
  541. package/schemas/plugins/css/CssAutoGeneratorOptions.check.js +6 -0
  542. package/schemas/plugins/css/CssAutoGeneratorOptions.json +3 -0
  543. package/schemas/plugins/css/CssAutoParserOptions.check.d.ts +7 -0
  544. package/schemas/plugins/css/CssAutoParserOptions.check.js +6 -0
  545. package/schemas/plugins/css/CssAutoParserOptions.json +3 -0
  546. package/schemas/plugins/css/CssGeneratorOptions.check.d.ts +7 -0
  547. package/schemas/plugins/css/CssGeneratorOptions.check.js +6 -0
  548. package/schemas/plugins/css/CssGeneratorOptions.json +3 -0
  549. package/schemas/plugins/css/CssGlobalGeneratorOptions.check.d.ts +7 -0
  550. package/schemas/plugins/css/CssGlobalGeneratorOptions.check.js +6 -0
  551. package/schemas/plugins/css/CssGlobalGeneratorOptions.json +3 -0
  552. package/schemas/plugins/css/CssGlobalParserOptions.check.d.ts +7 -0
  553. package/schemas/plugins/css/CssGlobalParserOptions.check.js +6 -0
  554. package/schemas/plugins/css/CssGlobalParserOptions.json +3 -0
  555. package/schemas/plugins/css/CssModuleGeneratorOptions.check.d.ts +7 -0
  556. package/schemas/plugins/css/CssModuleGeneratorOptions.check.js +6 -0
  557. package/schemas/plugins/css/CssModuleGeneratorOptions.json +3 -0
  558. package/schemas/plugins/css/CssModuleParserOptions.check.d.ts +7 -0
  559. package/schemas/plugins/css/CssModuleParserOptions.check.js +6 -0
  560. package/schemas/plugins/css/CssModuleParserOptions.json +3 -0
  561. package/schemas/plugins/css/CssParserOptions.check.d.ts +7 -0
  562. package/schemas/plugins/css/CssParserOptions.check.js +6 -0
  563. package/schemas/plugins/css/CssParserOptions.json +3 -0
  564. package/schemas/plugins/optimize/AggressiveSplittingPlugin.check.js +1 -1
  565. package/schemas/plugins/optimize/LimitChunkCountPlugin.check.js +1 -1
  566. package/schemas/plugins/optimize/MinChunkSizePlugin.check.js +1 -1
  567. package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
  568. package/schemas/plugins/schemes/HttpUriPlugin.json +4 -0
  569. package/schemas/plugins/sharing/SharePlugin.check.js +1 -1
  570. package/types.d.ts +5026 -1756
@@ -6,7 +6,9 @@
6
6
  "use strict";
7
7
 
8
8
  const { create: createResolver } = require("enhanced-resolve");
9
+ const nodeModule = require("module");
9
10
  const asyncLib = require("neo-async");
11
+ const { isAbsolute } = require("path");
10
12
  const AsyncQueue = require("./util/AsyncQueue");
11
13
  const StackedCacheMap = require("./util/StackedCacheMap");
12
14
  const createHash = require("./util/createHash");
@@ -14,13 +16,31 @@ const { join, dirname, relative, lstatReadlinkAbsolute } = require("./util/fs");
14
16
  const makeSerializable = require("./util/makeSerializable");
15
17
  const processAsyncTree = require("./util/processAsyncTree");
16
18
 
19
+ /** @typedef {import("enhanced-resolve").Resolver} Resolver */
20
+ /** @typedef {import("enhanced-resolve").ResolveRequest} ResolveRequest */
21
+ /** @typedef {import("enhanced-resolve").ResolveFunctionAsync} ResolveFunctionAsync */
17
22
  /** @typedef {import("./WebpackError")} WebpackError */
18
23
  /** @typedef {import("./logging/Logger").Logger} Logger */
24
+ /** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
25
+ /** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
19
26
  /** @typedef {typeof import("./util/Hash")} Hash */
20
27
  /** @typedef {import("./util/fs").IStats} IStats */
21
28
  /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
29
+ /** @typedef {import("./util/fs").PathLike} PathLike */
30
+ /** @typedef {import("./util/fs").StringCallback} StringCallback */
31
+ /**
32
+ * @template T
33
+ * @typedef {import("./util/AsyncQueue").Callback<T>} ProcessorCallback
34
+ */
35
+ /**
36
+ * @template T, R
37
+ * @typedef {import("./util/AsyncQueue").Processor<T, R>} Processor
38
+ */
39
+
40
+ const supportsEsm = Number(process.versions.modules) >= 83;
22
41
 
23
- const supportsEsm = +process.versions.modules >= 83;
42
+ /** @type {Set<string>} */
43
+ const builtinModules = new Set(nodeModule.builtinModules);
24
44
 
25
45
  let FS_ACCURACY = 2000;
26
46
 
@@ -37,22 +57,24 @@ const RBDT_FILE = 7;
37
57
  const RBDT_DIRECTORY_DEPENDENCIES = 8;
38
58
  const RBDT_FILE_DEPENDENCIES = 9;
39
59
 
60
+ /** @typedef {RBDT_RESOLVE_CJS | RBDT_RESOLVE_ESM | RBDT_RESOLVE_DIRECTORY | RBDT_RESOLVE_CJS_FILE | RBDT_RESOLVE_CJS_FILE_AS_CHILD | RBDT_RESOLVE_ESM_FILE | RBDT_DIRECTORY | RBDT_FILE | RBDT_DIRECTORY_DEPENDENCIES | RBDT_FILE_DEPENDENCIES} JobType */
61
+
40
62
  const INVALID = Symbol("invalid");
41
63
 
42
64
  /**
43
- * @typedef {Object} FileSystemInfoEntry
65
+ * @typedef {object} FileSystemInfoEntry
44
66
  * @property {number} safeTime
45
67
  * @property {number=} timestamp
46
68
  */
47
69
 
48
70
  /**
49
- * @typedef {Object} ResolvedContextFileSystemInfoEntry
71
+ * @typedef {object} ResolvedContextFileSystemInfoEntry
50
72
  * @property {number} safeTime
51
73
  * @property {string=} timestampHash
52
74
  */
53
75
 
54
76
  /**
55
- * @typedef {Object} ContextFileSystemInfoEntry
77
+ * @typedef {object} ContextFileSystemInfoEntry
56
78
  * @property {number} safeTime
57
79
  * @property {string=} timestampHash
58
80
  * @property {ResolvedContextFileSystemInfoEntry=} resolved
@@ -60,55 +82,65 @@ const INVALID = Symbol("invalid");
60
82
  */
61
83
 
62
84
  /**
63
- * @typedef {Object} TimestampAndHash
85
+ * @typedef {object} TimestampAndHash
64
86
  * @property {number} safeTime
65
87
  * @property {number=} timestamp
66
88
  * @property {string} hash
67
89
  */
68
90
 
69
91
  /**
70
- * @typedef {Object} ResolvedContextTimestampAndHash
92
+ * @typedef {object} ResolvedContextTimestampAndHash
71
93
  * @property {number} safeTime
72
94
  * @property {string=} timestampHash
73
95
  * @property {string} hash
74
96
  */
75
97
 
98
+ /** @typedef {Set<string>} Symlinks */
99
+
76
100
  /**
77
- * @typedef {Object} ContextTimestampAndHash
101
+ * @typedef {object} ContextTimestampAndHash
78
102
  * @property {number} safeTime
79
103
  * @property {string=} timestampHash
80
104
  * @property {string} hash
81
105
  * @property {ResolvedContextTimestampAndHash=} resolved
82
- * @property {Set<string>=} symlinks
106
+ * @property {Symlinks=} symlinks
83
107
  */
84
108
 
85
109
  /**
86
- * @typedef {Object} ContextHash
110
+ * @typedef {object} ContextHash
87
111
  * @property {string} hash
88
112
  * @property {string=} resolved
89
- * @property {Set<string>=} symlinks
113
+ * @property {Symlinks=} symlinks
90
114
  */
91
115
 
116
+ /** @typedef {Set<string>} SnapshotContent */
117
+
92
118
  /**
93
- * @typedef {Object} SnapshotOptimizationEntry
119
+ * @typedef {object} SnapshotOptimizationEntry
94
120
  * @property {Snapshot} snapshot
95
121
  * @property {number} shared
96
- * @property {Set<string>} snapshotContent
97
- * @property {Set<SnapshotOptimizationEntry>} children
122
+ * @property {SnapshotContent | undefined} snapshotContent
123
+ * @property {Set<SnapshotOptimizationEntry> | undefined} children
98
124
  */
99
125
 
100
126
  /**
101
- * @typedef {Object} ResolveBuildDependenciesResult
127
+ * @typedef {object} ResolveBuildDependenciesResult
102
128
  * @property {Set<string>} files list of files
103
129
  * @property {Set<string>} directories list of directories
104
130
  * @property {Set<string>} missing list of missing entries
105
- * @property {Map<string, string | false>} resolveResults stored resolve results
106
- * @property {Object} resolveDependencies dependencies of the resolving
131
+ * @property {Map<string, string | false | undefined>} resolveResults stored resolve results
132
+ * @property {object} resolveDependencies dependencies of the resolving
107
133
  * @property {Set<string>} resolveDependencies.files list of files
108
134
  * @property {Set<string>} resolveDependencies.directories list of directories
109
135
  * @property {Set<string>} resolveDependencies.missing list of missing entries
110
136
  */
111
137
 
138
+ /**
139
+ * @typedef {object} SnapshotOptions
140
+ * @property {boolean=} hash should use hash to snapshot
141
+ * @property {boolean=} timestamp should use timestamp to snapshot
142
+ */
143
+
112
144
  const DONE_ITERATOR_RESULT = new Set().keys().next();
113
145
 
114
146
  // cspell:word tshs
@@ -116,12 +148,23 @@ const DONE_ITERATOR_RESULT = new Set().keys().next();
116
148
  // Tshs = Timestamp + Hash combinations
117
149
 
118
150
  class SnapshotIterator {
151
+ /**
152
+ * @param {() => IteratorResult<string>} next next
153
+ */
119
154
  constructor(next) {
120
155
  this.next = next;
121
156
  }
122
157
  }
123
158
 
159
+ /**
160
+ * @typedef {(snapshot: Snapshot) => (Map<string, any> | Set<string> | undefined)[]} GetMapsFunction
161
+ */
162
+
124
163
  class SnapshotIterable {
164
+ /**
165
+ * @param {Snapshot} snapshot snapshot
166
+ * @param {GetMapsFunction} getMaps get maps function
167
+ */
125
168
  constructor(snapshot, getMaps) {
126
169
  this.snapshot = snapshot;
127
170
  this.getMaps = getMaps;
@@ -131,12 +174,13 @@ class SnapshotIterable {
131
174
  let state = 0;
132
175
  /** @type {IterableIterator<string>} */
133
176
  let it;
134
- /** @type {(Snapshot) => (Map<string, any> | Set<string>)[]} */
177
+ /** @type {(snapshot: Snapshot) => (Map<string, any> | Set<string> | undefined)[]} */
135
178
  let getMaps;
136
- /** @type {(Map<string, any> | Set<string>)[]} */
179
+ /** @type {(Map<string, any> | Set<string> | undefined)[]} */
137
180
  let maps;
138
181
  /** @type {Snapshot} */
139
182
  let snapshot;
183
+ /** @type {Snapshot[] | undefined} */
140
184
  let queue;
141
185
  return new SnapshotIterator(() => {
142
186
  for (;;) {
@@ -184,7 +228,7 @@ class SnapshotIterable {
184
228
  }
185
229
  }
186
230
  if (queue !== undefined && queue.length > 0) {
187
- snapshot = queue.pop();
231
+ snapshot = /** @type {Snapshot} */ (queue.pop());
188
232
  maps = getMaps(snapshot);
189
233
  state = 1;
190
234
  break;
@@ -201,34 +245,53 @@ class SnapshotIterable {
201
245
  }
202
246
  }
203
247
 
248
+ /** @typedef {Map<string, FileSystemInfoEntry | null>} FileTimestamps */
249
+ /** @typedef {Map<string, string | null>} FileHashes */
250
+ /** @typedef {Map<string, TimestampAndHash | string | null>} FileTshs */
251
+ /** @typedef {Map<string, ResolvedContextFileSystemInfoEntry | null>} ContextTimestamps */
252
+ /** @typedef {Map<string, string | null>} ContextHashes */
253
+ /** @typedef {Map<string, ResolvedContextTimestampAndHash | null>} ContextTshs */
254
+ /** @typedef {Map<string, boolean>} MissingExistence */
255
+ /** @typedef {Map<string, string>} ManagedItemInfo */
256
+ /** @typedef {Set<string>} ManagedFiles */
257
+ /** @typedef {Set<string>} ManagedContexts */
258
+ /** @typedef {Set<string>} ManagedMissing */
259
+ /** @typedef {Set<Snapshot>} Children */
260
+
204
261
  class Snapshot {
205
262
  constructor() {
206
263
  this._flags = 0;
264
+ /** @type {Iterable<string> | undefined} */
265
+ this._cachedFileIterable = undefined;
266
+ /** @type {Iterable<string> | undefined} */
267
+ this._cachedContextIterable = undefined;
268
+ /** @type {Iterable<string> | undefined} */
269
+ this._cachedMissingIterable = undefined;
207
270
  /** @type {number | undefined} */
208
271
  this.startTime = undefined;
209
- /** @type {Map<string, FileSystemInfoEntry | null> | undefined} */
272
+ /** @type {FileTimestamps | undefined} */
210
273
  this.fileTimestamps = undefined;
211
- /** @type {Map<string, string | null> | undefined} */
274
+ /** @type {FileHashes | undefined} */
212
275
  this.fileHashes = undefined;
213
- /** @type {Map<string, TimestampAndHash | string | null> | undefined} */
276
+ /** @type {FileTshs | undefined} */
214
277
  this.fileTshs = undefined;
215
- /** @type {Map<string, ResolvedContextFileSystemInfoEntry | null> | undefined} */
278
+ /** @type {ContextTimestamps | undefined} */
216
279
  this.contextTimestamps = undefined;
217
- /** @type {Map<string, string | null> | undefined} */
280
+ /** @type {ContextHashes | undefined} */
218
281
  this.contextHashes = undefined;
219
- /** @type {Map<string, ResolvedContextTimestampAndHash | null> | undefined} */
282
+ /** @type {ContextTshs | undefined} */
220
283
  this.contextTshs = undefined;
221
- /** @type {Map<string, boolean> | undefined} */
284
+ /** @type {MissingExistence | undefined} */
222
285
  this.missingExistence = undefined;
223
- /** @type {Map<string, string> | undefined} */
286
+ /** @type {ManagedItemInfo | undefined} */
224
287
  this.managedItemInfo = undefined;
225
- /** @type {Set<string> | undefined} */
288
+ /** @type {ManagedFiles | undefined} */
226
289
  this.managedFiles = undefined;
227
- /** @type {Set<string> | undefined} */
290
+ /** @type {ManagedContexts | undefined} */
228
291
  this.managedContexts = undefined;
229
- /** @type {Set<string> | undefined} */
292
+ /** @type {ManagedMissing | undefined} */
230
293
  this.managedMissing = undefined;
231
- /** @type {Set<Snapshot> | undefined} */
294
+ /** @type {Children | undefined} */
232
295
  this.children = undefined;
233
296
  }
234
297
 
@@ -236,20 +299,36 @@ class Snapshot {
236
299
  return (this._flags & 1) !== 0;
237
300
  }
238
301
 
302
+ /**
303
+ * @param {number} value start value
304
+ */
239
305
  setStartTime(value) {
240
306
  this._flags = this._flags | 1;
241
307
  this.startTime = value;
242
308
  }
243
309
 
310
+ /**
311
+ * @param {number | undefined} value value
312
+ * @param {Snapshot} snapshot snapshot
313
+ */
244
314
  setMergedStartTime(value, snapshot) {
245
315
  if (value) {
246
316
  if (snapshot.hasStartTime()) {
247
- this.setStartTime(Math.min(value, snapshot.startTime));
317
+ this.setStartTime(
318
+ Math.min(
319
+ value,
320
+ /** @type {NonNullable<Snapshot["startTime"]>} */
321
+ (snapshot.startTime)
322
+ )
323
+ );
248
324
  } else {
249
325
  this.setStartTime(value);
250
326
  }
251
- } else {
252
- if (snapshot.hasStartTime()) this.setStartTime(snapshot.startTime);
327
+ } else if (snapshot.hasStartTime()) {
328
+ this.setStartTime(
329
+ /** @type {NonNullable<Snapshot["startTime"]>} */
330
+ (snapshot.startTime)
331
+ );
253
332
  }
254
333
  }
255
334
 
@@ -257,6 +336,9 @@ class Snapshot {
257
336
  return (this._flags & 2) !== 0;
258
337
  }
259
338
 
339
+ /**
340
+ * @param {FileTimestamps} value file timestamps
341
+ */
260
342
  setFileTimestamps(value) {
261
343
  this._flags = this._flags | 2;
262
344
  this.fileTimestamps = value;
@@ -266,6 +348,9 @@ class Snapshot {
266
348
  return (this._flags & 4) !== 0;
267
349
  }
268
350
 
351
+ /**
352
+ * @param {FileHashes} value file hashes
353
+ */
269
354
  setFileHashes(value) {
270
355
  this._flags = this._flags | 4;
271
356
  this.fileHashes = value;
@@ -275,6 +360,9 @@ class Snapshot {
275
360
  return (this._flags & 8) !== 0;
276
361
  }
277
362
 
363
+ /**
364
+ * @param {FileTshs} value file tshs
365
+ */
278
366
  setFileTshs(value) {
279
367
  this._flags = this._flags | 8;
280
368
  this.fileTshs = value;
@@ -284,6 +372,9 @@ class Snapshot {
284
372
  return (this._flags & 0x10) !== 0;
285
373
  }
286
374
 
375
+ /**
376
+ * @param {ContextTimestamps} value context timestamps
377
+ */
287
378
  setContextTimestamps(value) {
288
379
  this._flags = this._flags | 0x10;
289
380
  this.contextTimestamps = value;
@@ -293,6 +384,9 @@ class Snapshot {
293
384
  return (this._flags & 0x20) !== 0;
294
385
  }
295
386
 
387
+ /**
388
+ * @param {ContextHashes} value context hashes
389
+ */
296
390
  setContextHashes(value) {
297
391
  this._flags = this._flags | 0x20;
298
392
  this.contextHashes = value;
@@ -302,6 +396,9 @@ class Snapshot {
302
396
  return (this._flags & 0x40) !== 0;
303
397
  }
304
398
 
399
+ /**
400
+ * @param {ContextTshs} value context tshs
401
+ */
305
402
  setContextTshs(value) {
306
403
  this._flags = this._flags | 0x40;
307
404
  this.contextTshs = value;
@@ -311,6 +408,9 @@ class Snapshot {
311
408
  return (this._flags & 0x80) !== 0;
312
409
  }
313
410
 
411
+ /**
412
+ * @param {MissingExistence} value context tshs
413
+ */
314
414
  setMissingExistence(value) {
315
415
  this._flags = this._flags | 0x80;
316
416
  this.missingExistence = value;
@@ -320,6 +420,9 @@ class Snapshot {
320
420
  return (this._flags & 0x100) !== 0;
321
421
  }
322
422
 
423
+ /**
424
+ * @param {ManagedItemInfo} value managed item info
425
+ */
323
426
  setManagedItemInfo(value) {
324
427
  this._flags = this._flags | 0x100;
325
428
  this.managedItemInfo = value;
@@ -329,6 +432,9 @@ class Snapshot {
329
432
  return (this._flags & 0x200) !== 0;
330
433
  }
331
434
 
435
+ /**
436
+ * @param {ManagedFiles} value managed files
437
+ */
332
438
  setManagedFiles(value) {
333
439
  this._flags = this._flags | 0x200;
334
440
  this.managedFiles = value;
@@ -338,6 +444,9 @@ class Snapshot {
338
444
  return (this._flags & 0x400) !== 0;
339
445
  }
340
446
 
447
+ /**
448
+ * @param {ManagedContexts} value managed contexts
449
+ */
341
450
  setManagedContexts(value) {
342
451
  this._flags = this._flags | 0x400;
343
452
  this.managedContexts = value;
@@ -347,6 +456,9 @@ class Snapshot {
347
456
  return (this._flags & 0x800) !== 0;
348
457
  }
349
458
 
459
+ /**
460
+ * @param {ManagedMissing} value managed missing
461
+ */
350
462
  setManagedMissing(value) {
351
463
  this._flags = this._flags | 0x800;
352
464
  this.managedMissing = value;
@@ -356,18 +468,28 @@ class Snapshot {
356
468
  return (this._flags & 0x1000) !== 0;
357
469
  }
358
470
 
471
+ /**
472
+ * @param {Children} value children
473
+ */
359
474
  setChildren(value) {
360
475
  this._flags = this._flags | 0x1000;
361
476
  this.children = value;
362
477
  }
363
478
 
479
+ /**
480
+ * @param {Snapshot} child children
481
+ */
364
482
  addChild(child) {
365
483
  if (!this.hasChildren()) {
366
484
  this.setChildren(new Set());
367
485
  }
368
- this.children.add(child);
486
+ /** @type {Children} */
487
+ (this.children).add(child);
369
488
  }
370
489
 
490
+ /**
491
+ * @param {ObjectSerializerContext} context context
492
+ */
371
493
  serialize({ write }) {
372
494
  write(this._flags);
373
495
  if (this.hasStartTime()) write(this.startTime);
@@ -385,6 +507,9 @@ class Snapshot {
385
507
  if (this.hasChildren()) write(this.children);
386
508
  }
387
509
 
510
+ /**
511
+ * @param {ObjectDeserializerContext} context context
512
+ */
388
513
  deserialize({ read }) {
389
514
  this._flags = read();
390
515
  if (this.hasStartTime()) this.startTime = read();
@@ -403,7 +528,7 @@ class Snapshot {
403
528
  }
404
529
 
405
530
  /**
406
- * @param {function(Snapshot): (ReadonlyMap<string, any> | ReadonlySet<string>)[]} getMaps first
531
+ * @param {GetMapsFunction} getMaps first
407
532
  * @returns {Iterable<string>} iterable
408
533
  */
409
534
  _createIterable(getMaps) {
@@ -414,31 +539,43 @@ class Snapshot {
414
539
  * @returns {Iterable<string>} iterable
415
540
  */
416
541
  getFileIterable() {
417
- return this._createIterable(s => [
418
- s.fileTimestamps,
419
- s.fileHashes,
420
- s.fileTshs,
421
- s.managedFiles
422
- ]);
542
+ if (this._cachedFileIterable === undefined) {
543
+ this._cachedFileIterable = this._createIterable(s => [
544
+ s.fileTimestamps,
545
+ s.fileHashes,
546
+ s.fileTshs,
547
+ s.managedFiles
548
+ ]);
549
+ }
550
+ return this._cachedFileIterable;
423
551
  }
424
552
 
425
553
  /**
426
554
  * @returns {Iterable<string>} iterable
427
555
  */
428
556
  getContextIterable() {
429
- return this._createIterable(s => [
430
- s.contextTimestamps,
431
- s.contextHashes,
432
- s.contextTshs,
433
- s.managedContexts
434
- ]);
557
+ if (this._cachedContextIterable === undefined) {
558
+ this._cachedContextIterable = this._createIterable(s => [
559
+ s.contextTimestamps,
560
+ s.contextHashes,
561
+ s.contextTshs,
562
+ s.managedContexts
563
+ ]);
564
+ }
565
+ return this._cachedContextIterable;
435
566
  }
436
567
 
437
568
  /**
438
569
  * @returns {Iterable<string>} iterable
439
570
  */
440
571
  getMissingIterable() {
441
- return this._createIterable(s => [s.missingExistence, s.managedMissing]);
572
+ if (this._cachedMissingIterable === undefined) {
573
+ this._cachedMissingIterable = this._createIterable(s => [
574
+ s.missingExistence,
575
+ s.managedMissing
576
+ ]);
577
+ }
578
+ return this._cachedMissingIterable;
442
579
  }
443
580
  }
444
581
 
@@ -446,22 +583,35 @@ makeSerializable(Snapshot, "webpack/lib/FileSystemInfo", "Snapshot");
446
583
 
447
584
  const MIN_COMMON_SNAPSHOT_SIZE = 3;
448
585
 
586
+ /**
587
+ * @template U, T
588
+ * @typedef {U extends true ? Set<string> : Map<string, T>} SnapshotOptimizationValue
589
+ */
590
+
449
591
  /**
450
592
  * @template T
593
+ * @template {boolean} [U=false]
451
594
  */
452
595
  class SnapshotOptimization {
453
596
  /**
454
597
  * @param {function(Snapshot): boolean} has has value
455
- * @param {function(Snapshot): Map<string, T> | Set<string>} get get value
456
- * @param {function(Snapshot, Map<string, T> | Set<string>): void} set set value
598
+ * @param {function(Snapshot): SnapshotOptimizationValue<U, T> | undefined} get get value
599
+ * @param {function(Snapshot, SnapshotOptimizationValue<U, T>): void} set set value
457
600
  * @param {boolean=} useStartTime use the start time of snapshots
458
- * @param {boolean=} isSet value is an Set instead of a Map
601
+ * @param {U=} isSet value is an Set instead of a Map
459
602
  */
460
- constructor(has, get, set, useStartTime = true, isSet = false) {
603
+ constructor(
604
+ has,
605
+ get,
606
+ set,
607
+ useStartTime = true,
608
+ isSet = /** @type {U} */ (false)
609
+ ) {
461
610
  this._has = has;
462
611
  this._get = get;
463
612
  this._set = set;
464
613
  this._useStartTime = useStartTime;
614
+ /** @type {U} */
465
615
  this._isSet = isSet;
466
616
  /** @type {Map<string, SnapshotOptimizationEntry>} */
467
617
  this._map = new Map();
@@ -473,7 +623,7 @@ class SnapshotOptimization {
473
623
 
474
624
  getStatisticMessage() {
475
625
  const total = this._statItemsShared + this._statItemsUnshared;
476
- if (total === 0) return undefined;
626
+ if (total === 0) return;
477
627
  return `${
478
628
  this._statItemsShared && Math.round((this._statItemsShared * 100) / total)
479
629
  }% (${this._statItemsShared}/${total}) entries shared via ${
@@ -503,7 +653,9 @@ class SnapshotOptimization {
503
653
  */
504
654
  const increaseSharedAndStoreOptimizationEntry = entry => {
505
655
  if (entry.children !== undefined) {
506
- entry.children.forEach(increaseSharedAndStoreOptimizationEntry);
656
+ for (const child of entry.children) {
657
+ increaseSharedAndStoreOptimizationEntry(child);
658
+ }
507
659
  }
508
660
  entry.shared++;
509
661
  storeOptimizationEntry(entry);
@@ -513,8 +665,12 @@ class SnapshotOptimization {
513
665
  * @returns {void}
514
666
  */
515
667
  const storeOptimizationEntry = entry => {
516
- for (const path of entry.snapshotContent) {
517
- const old = this._map.get(path);
668
+ for (const path of /** @type {SnapshotContent} */ (
669
+ entry.snapshotContent
670
+ )) {
671
+ const old =
672
+ /** @type {SnapshotOptimizationEntry} */
673
+ (this._map.get(path));
518
674
  if (old.shared < entry.shared) {
519
675
  this._map.set(path, entry);
520
676
  }
@@ -522,8 +678,8 @@ class SnapshotOptimization {
522
678
  }
523
679
  };
524
680
 
525
- /** @type {SnapshotOptimizationEntry} */
526
- let newOptimizationEntry = undefined;
681
+ /** @type {SnapshotOptimizationEntry | undefined} */
682
+ let newOptimizationEntry;
527
683
 
528
684
  const capturedFilesSize = capturedFiles.size;
529
685
 
@@ -548,7 +704,7 @@ class SnapshotOptimization {
548
704
  }
549
705
  }
550
706
 
551
- optimizationEntries: for (const optimizationEntry of optimizationEntries) {
707
+ optimizationEntriesLabel: for (const optimizationEntry of optimizationEntries) {
552
708
  const snapshot = optimizationEntry.snapshot;
553
709
  if (optimizationEntry.shared > 0) {
554
710
  // It's a shared snapshot
@@ -562,14 +718,18 @@ class SnapshotOptimization {
562
718
  continue;
563
719
  }
564
720
  const nonSharedFiles = new Set();
565
- const snapshotContent = optimizationEntry.snapshotContent;
566
- const snapshotEntries = this._get(snapshot);
721
+ const snapshotContent =
722
+ /** @type {NonNullable<SnapshotOptimizationEntry["snapshotContent"]>} */
723
+ (optimizationEntry.snapshotContent);
724
+ const snapshotEntries =
725
+ /** @type {SnapshotOptimizationValue<U, T>} */
726
+ (this._get(snapshot));
567
727
  for (const path of snapshotContent) {
568
728
  if (!capturedFiles.has(path)) {
569
729
  if (!snapshotEntries.has(path)) {
570
730
  // File is not shared and can't be removed from the snapshot
571
731
  // because it's in a child of the snapshot
572
- continue optimizationEntries;
732
+ continue optimizationEntriesLabel;
573
733
  }
574
734
  nonSharedFiles.add(path);
575
735
  continue;
@@ -586,7 +746,7 @@ class SnapshotOptimization {
586
746
  const sharedCount = snapshotContent.size - nonSharedFiles.size;
587
747
  if (sharedCount < MIN_COMMON_SNAPSHOT_SIZE) {
588
748
  // Common part it too small
589
- continue optimizationEntries;
749
+ continue;
590
750
  }
591
751
  // Extract common timestamps from both snapshots
592
752
  let commonMap;
@@ -611,7 +771,10 @@ class SnapshotOptimization {
611
771
  if (this._useStartTime) {
612
772
  commonSnapshot.setMergedStartTime(newSnapshot.startTime, snapshot);
613
773
  }
614
- this._set(commonSnapshot, commonMap);
774
+ this._set(
775
+ commonSnapshot,
776
+ /** @type {SnapshotOptimizationValue<U, T>} */ (commonMap)
777
+ );
615
778
  newSnapshot.addChild(commonSnapshot);
616
779
  snapshot.addChild(commonSnapshot);
617
780
  // Create optimization entry
@@ -634,7 +797,7 @@ class SnapshotOptimization {
634
797
  const snapshotEntries = this._get(snapshot);
635
798
  if (snapshotEntries === undefined) {
636
799
  // Incomplete snapshot, that can't be used
637
- continue optimizationEntries;
800
+ continue;
638
801
  }
639
802
  let commonMap;
640
803
  if (this._isSet) {
@@ -661,14 +824,18 @@ class SnapshotOptimization {
661
824
 
662
825
  if (commonMap.size < MIN_COMMON_SNAPSHOT_SIZE) {
663
826
  // Common part it too small
664
- continue optimizationEntries;
827
+ continue;
665
828
  }
666
829
  // Create and attach snapshot
667
830
  const commonSnapshot = new Snapshot();
668
831
  if (this._useStartTime) {
669
832
  commonSnapshot.setMergedStartTime(newSnapshot.startTime, snapshot);
670
833
  }
671
- this._set(commonSnapshot, commonMap);
834
+ this._set(
835
+ commonSnapshot,
836
+ /** @type {SnapshotOptimizationValue<U, T>} */
837
+ (commonMap)
838
+ );
672
839
  newSnapshot.addChild(commonSnapshot);
673
840
  snapshot.addChild(commonSnapshot);
674
841
  // Remove files from snapshot
@@ -692,6 +859,16 @@ class SnapshotOptimization {
692
859
  }
693
860
  }
694
861
 
862
+ /**
863
+ * @param {string} str input
864
+ * @returns {string} result
865
+ */
866
+ const parseString = str => {
867
+ if (str[0] === "'" || str[0] === "`")
868
+ str = `"${str.slice(1, -1).replace(/"/g, '\\"')}"`;
869
+ return JSON.parse(str);
870
+ };
871
+
695
872
  /* istanbul ignore next */
696
873
  /**
697
874
  * @param {number} mtime mtime
@@ -706,13 +883,14 @@ const applyMtime = mtime => {
706
883
  /**
707
884
  * @template T
708
885
  * @template K
709
- * @param {Map<T, K>} a source map
710
- * @param {Map<T, K>} b joining map
886
+ * @param {Map<T, K> | undefined} a source map
887
+ * @param {Map<T, K> | undefined} b joining map
711
888
  * @returns {Map<T, K>} joined map
712
889
  */
713
890
  const mergeMaps = (a, b) => {
714
- if (!b || b.size === 0) return a;
715
- if (!a || a.size === 0) return b;
891
+ if (!b || b.size === 0) return /** @type {Map<T, K>} */ (a);
892
+ if (!a || a.size === 0) return /** @type {Map<T, K>} */ (b);
893
+ /** @type {Map<T, K>} */
716
894
  const map = new Map(a);
717
895
  for (const [key, value] of b) {
718
896
  map.set(key, value);
@@ -722,14 +900,14 @@ const mergeMaps = (a, b) => {
722
900
 
723
901
  /**
724
902
  * @template T
725
- * @template K
726
- * @param {Set<T, K>} a source map
727
- * @param {Set<T, K>} b joining map
728
- * @returns {Set<T, K>} joined map
903
+ * @param {Set<T> | undefined} a source map
904
+ * @param {Set<T> | undefined} b joining map
905
+ * @returns {Set<T>} joined map
729
906
  */
730
907
  const mergeSets = (a, b) => {
731
- if (!b || b.size === 0) return a;
732
- if (!a || a.size === 0) return b;
908
+ if (!b || b.size === 0) return /** @type {Set<T>} */ (a);
909
+ if (!a || a.size === 0) return /** @type {Set<T>} */ (b);
910
+ /** @type {Set<T>} */
733
911
  const map = new Set(a);
734
912
  for (const item of b) {
735
913
  map.add(item);
@@ -823,8 +1001,8 @@ const getManagedItem = (managedPath, path) => {
823
1001
 
824
1002
  /**
825
1003
  * @template {ContextFileSystemInfoEntry | ContextTimestampAndHash} T
826
- * @param {T} entry entry
827
- * @returns {T["resolved"] | undefined} the resolved entry
1004
+ * @param {T | null} entry entry
1005
+ * @returns {T["resolved"] | null | undefined} the resolved entry
828
1006
  */
829
1007
  const getResolvedTimestamp = entry => {
830
1008
  if (entry === null) return null;
@@ -833,8 +1011,8 @@ const getResolvedTimestamp = entry => {
833
1011
  };
834
1012
 
835
1013
  /**
836
- * @param {ContextHash} entry entry
837
- * @returns {string | undefined} the resolved entry
1014
+ * @param {ContextHash | null} entry entry
1015
+ * @returns {string | null | undefined} the resolved entry
838
1016
  */
839
1017
  const getResolvedHash = entry => {
840
1018
  if (entry === null) return null;
@@ -842,17 +1020,25 @@ const getResolvedHash = entry => {
842
1020
  return entry.symlinks === undefined ? entry.hash : undefined;
843
1021
  };
844
1022
 
1023
+ /**
1024
+ * @template T
1025
+ * @param {Set<T>} source source
1026
+ * @param {Set<T>} target target
1027
+ */
845
1028
  const addAll = (source, target) => {
846
1029
  for (const key of source) target.add(key);
847
1030
  };
848
1031
 
1032
+ /** @typedef {Set<string>} LoggedPaths */
1033
+
849
1034
  /**
850
1035
  * Used to access information about the filesystem in a cached way
851
1036
  */
852
1037
  class FileSystemInfo {
853
1038
  /**
854
1039
  * @param {InputFileSystem} fs file system
855
- * @param {Object} options options
1040
+ * @param {object} options options
1041
+ * @param {Iterable<string | RegExp>=} options.unmanagedPaths paths that are not managed by a package manager and the contents are subject to change
856
1042
  * @param {Iterable<string | RegExp>=} options.managedPaths paths that are only managed by a package manager
857
1043
  * @param {Iterable<string | RegExp>=} options.immutablePaths paths that are immutable
858
1044
  * @param {Logger=} options.logger logger used to log invalid snapshots
@@ -861,6 +1047,7 @@ class FileSystemInfo {
861
1047
  constructor(
862
1048
  fs,
863
1049
  {
1050
+ unmanagedPaths = [],
864
1051
  managedPaths = [],
865
1052
  immutablePaths = [],
866
1053
  logger,
@@ -870,9 +1057,10 @@ class FileSystemInfo {
870
1057
  this.fs = fs;
871
1058
  this.logger = logger;
872
1059
  this._remainingLogs = logger ? 40 : 0;
1060
+ /** @type {LoggedPaths | undefined} */
873
1061
  this._loggedPaths = logger ? new Set() : undefined;
874
1062
  this._hashFunction = hashFunction;
875
- /** @type {WeakMap<Snapshot, boolean | (function(WebpackError=, boolean=): void)[]>} */
1063
+ /** @type {WeakMap<Snapshot, boolean | (function((WebpackError | null)=, boolean=): void)[]>} */
876
1064
  this._snapshotCache = new WeakMap();
877
1065
  this._fileTimestampsOptimization = new SnapshotOptimization(
878
1066
  s => s.hasFileTimestamps(),
@@ -941,7 +1129,7 @@ class FileSystemInfo {
941
1129
  );
942
1130
  /** @type {StackedCacheMap<string, FileSystemInfoEntry | "ignore" | null>} */
943
1131
  this._fileTimestamps = new StackedCacheMap();
944
- /** @type {Map<string, string>} */
1132
+ /** @type {Map<string, string | null>} */
945
1133
  this._fileHashes = new Map();
946
1134
  /** @type {Map<string, TimestampAndHash | string>} */
947
1135
  this._fileTshs = new Map();
@@ -953,37 +1141,37 @@ class FileSystemInfo {
953
1141
  this._contextTshs = new Map();
954
1142
  /** @type {Map<string, string>} */
955
1143
  this._managedItems = new Map();
956
- /** @type {AsyncQueue<string, string, FileSystemInfoEntry | null>} */
1144
+ /** @type {AsyncQueue<string, string, FileSystemInfoEntry>} */
957
1145
  this.fileTimestampQueue = new AsyncQueue({
958
1146
  name: "file timestamp",
959
1147
  parallelism: 30,
960
1148
  processor: this._readFileTimestamp.bind(this)
961
1149
  });
962
- /** @type {AsyncQueue<string, string, string | null>} */
1150
+ /** @type {AsyncQueue<string, string, string>} */
963
1151
  this.fileHashQueue = new AsyncQueue({
964
1152
  name: "file hash",
965
1153
  parallelism: 10,
966
1154
  processor: this._readFileHash.bind(this)
967
1155
  });
968
- /** @type {AsyncQueue<string, string, ContextFileSystemInfoEntry | null>} */
1156
+ /** @type {AsyncQueue<string, string, ContextFileSystemInfoEntry>} */
969
1157
  this.contextTimestampQueue = new AsyncQueue({
970
1158
  name: "context timestamp",
971
1159
  parallelism: 2,
972
1160
  processor: this._readContextTimestamp.bind(this)
973
1161
  });
974
- /** @type {AsyncQueue<string, string, ContextHash | null>} */
1162
+ /** @type {AsyncQueue<string, string, ContextHash>} */
975
1163
  this.contextHashQueue = new AsyncQueue({
976
1164
  name: "context hash",
977
1165
  parallelism: 2,
978
1166
  processor: this._readContextHash.bind(this)
979
1167
  });
980
- /** @type {AsyncQueue<string, string, ContextTimestampAndHash | null>} */
1168
+ /** @type {AsyncQueue<string, string, ContextTimestampAndHash>} */
981
1169
  this.contextTshQueue = new AsyncQueue({
982
1170
  name: "context hash and timestamp",
983
1171
  parallelism: 2,
984
1172
  processor: this._readContextTimestampAndHash.bind(this)
985
1173
  });
986
- /** @type {AsyncQueue<string, string, string | null>} */
1174
+ /** @type {AsyncQueue<string, string, string>} */
987
1175
  this.managedItemQueue = new AsyncQueue({
988
1176
  name: "managed item info",
989
1177
  parallelism: 10,
@@ -995,6 +1183,14 @@ class FileSystemInfo {
995
1183
  parallelism: 10,
996
1184
  processor: this._getManagedItemDirectoryInfo.bind(this)
997
1185
  });
1186
+ const _unmanagedPaths = Array.from(unmanagedPaths);
1187
+ this.unmanagedPathsWithSlash = /** @type {string[]} */ (
1188
+ _unmanagedPaths.filter(p => typeof p === "string")
1189
+ ).map(p => join(fs, p, "_").slice(0, -1));
1190
+ this.unmanagedPathsRegExps = /** @type {RegExp[]} */ (
1191
+ _unmanagedPaths.filter(p => typeof p !== "string")
1192
+ );
1193
+
998
1194
  this.managedPaths = Array.from(managedPaths);
999
1195
  this.managedPathsWithSlash = /** @type {string[]} */ (
1000
1196
  this.managedPaths.filter(p => typeof p === "string")
@@ -1025,13 +1221,18 @@ class FileSystemInfo {
1025
1221
  }
1026
1222
 
1027
1223
  logStatistics() {
1224
+ const logger = /** @type {Logger} */ (this.logger);
1225
+ /**
1226
+ * @param {string} header header
1227
+ * @param {string | undefined} message message
1228
+ */
1028
1229
  const logWhenMessage = (header, message) => {
1029
1230
  if (message) {
1030
- this.logger.log(`${header}: ${message}`);
1231
+ logger.log(`${header}: ${message}`);
1031
1232
  }
1032
1233
  };
1033
- this.logger.log(`${this._statCreatedSnapshots} new snapshots created`);
1034
- this.logger.log(
1234
+ logger.log(`${this._statCreatedSnapshots} new snapshots created`);
1235
+ logger.log(
1035
1236
  `${
1036
1237
  this._statTestedSnapshotsNotCached &&
1037
1238
  Math.round(
@@ -1043,7 +1244,7 @@ class FileSystemInfo {
1043
1244
  this._statTestedSnapshotsCached + this._statTestedSnapshotsNotCached
1044
1245
  })`
1045
1246
  );
1046
- this.logger.log(
1247
+ logger.log(
1047
1248
  `${
1048
1249
  this._statTestedChildrenNotCached &&
1049
1250
  Math.round(
@@ -1054,69 +1255,75 @@ class FileSystemInfo {
1054
1255
  this._statTestedChildrenCached + this._statTestedChildrenNotCached
1055
1256
  })`
1056
1257
  );
1057
- this.logger.log(`${this._statTestedEntries} entries tested`);
1058
- this.logger.log(
1258
+ logger.log(`${this._statTestedEntries} entries tested`);
1259
+ logger.log(
1059
1260
  `File info in cache: ${this._fileTimestamps.size} timestamps ${this._fileHashes.size} hashes ${this._fileTshs.size} timestamp hash combinations`
1060
1261
  );
1061
1262
  logWhenMessage(
1062
- `File timestamp snapshot optimization`,
1263
+ "File timestamp snapshot optimization",
1063
1264
  this._fileTimestampsOptimization.getStatisticMessage()
1064
1265
  );
1065
1266
  logWhenMessage(
1066
- `File hash snapshot optimization`,
1267
+ "File hash snapshot optimization",
1067
1268
  this._fileHashesOptimization.getStatisticMessage()
1068
1269
  );
1069
1270
  logWhenMessage(
1070
- `File timestamp hash combination snapshot optimization`,
1271
+ "File timestamp hash combination snapshot optimization",
1071
1272
  this._fileTshsOptimization.getStatisticMessage()
1072
1273
  );
1073
- this.logger.log(
1274
+ logger.log(
1074
1275
  `Directory info in cache: ${this._contextTimestamps.size} timestamps ${this._contextHashes.size} hashes ${this._contextTshs.size} timestamp hash combinations`
1075
1276
  );
1076
1277
  logWhenMessage(
1077
- `Directory timestamp snapshot optimization`,
1278
+ "Directory timestamp snapshot optimization",
1078
1279
  this._contextTimestampsOptimization.getStatisticMessage()
1079
1280
  );
1080
1281
  logWhenMessage(
1081
- `Directory hash snapshot optimization`,
1282
+ "Directory hash snapshot optimization",
1082
1283
  this._contextHashesOptimization.getStatisticMessage()
1083
1284
  );
1084
1285
  logWhenMessage(
1085
- `Directory timestamp hash combination snapshot optimization`,
1286
+ "Directory timestamp hash combination snapshot optimization",
1086
1287
  this._contextTshsOptimization.getStatisticMessage()
1087
1288
  );
1088
1289
  logWhenMessage(
1089
- `Missing items snapshot optimization`,
1290
+ "Missing items snapshot optimization",
1090
1291
  this._missingExistenceOptimization.getStatisticMessage()
1091
1292
  );
1092
- this.logger.log(
1093
- `Managed items info in cache: ${this._managedItems.size} items`
1094
- );
1293
+ logger.log(`Managed items info in cache: ${this._managedItems.size} items`);
1095
1294
  logWhenMessage(
1096
- `Managed items snapshot optimization`,
1295
+ "Managed items snapshot optimization",
1097
1296
  this._managedItemInfoOptimization.getStatisticMessage()
1098
1297
  );
1099
1298
  logWhenMessage(
1100
- `Managed files snapshot optimization`,
1299
+ "Managed files snapshot optimization",
1101
1300
  this._managedFilesOptimization.getStatisticMessage()
1102
1301
  );
1103
1302
  logWhenMessage(
1104
- `Managed contexts snapshot optimization`,
1303
+ "Managed contexts snapshot optimization",
1105
1304
  this._managedContextsOptimization.getStatisticMessage()
1106
1305
  );
1107
1306
  logWhenMessage(
1108
- `Managed missing snapshot optimization`,
1307
+ "Managed missing snapshot optimization",
1109
1308
  this._managedMissingOptimization.getStatisticMessage()
1110
1309
  );
1111
1310
  }
1112
1311
 
1312
+ /**
1313
+ * @param {string} path path
1314
+ * @param {string} reason reason
1315
+ * @param {any[]} args arguments
1316
+ */
1113
1317
  _log(path, reason, ...args) {
1114
1318
  const key = path + reason;
1115
- if (this._loggedPaths.has(key)) return;
1116
- this._loggedPaths.add(key);
1117
- this.logger.debug(`${path} invalidated because ${reason}`, ...args);
1319
+ const loggedPaths = /** @type {LoggedPaths} */ (this._loggedPaths);
1320
+ if (loggedPaths.has(key)) return;
1321
+ loggedPaths.add(key);
1322
+ /** @type {Logger} */
1323
+ (this.logger).debug(`${path} invalidated because ${reason}`, ...args);
1118
1324
  if (--this._remainingLogs === 0) {
1119
- this.logger.debug(
1325
+ /** @type {Logger} */
1326
+ (this.logger).debug(
1120
1327
  "Logging limit has been reached and no further logging will be emitted by FileSystemInfo"
1121
1328
  );
1122
1329
  }
@@ -1180,7 +1387,7 @@ class FileSystemInfo {
1180
1387
 
1181
1388
  /**
1182
1389
  * @param {string} path file path
1183
- * @param {function(WebpackError=, (FileSystemInfoEntry | "ignore" | null)=): void} callback callback function
1390
+ * @param {function((WebpackError | null)=, (FileSystemInfoEntry | "ignore" | null)=): void} callback callback function
1184
1391
  * @returns {void}
1185
1392
  */
1186
1393
  getFileTimestamp(path, callback) {
@@ -1191,7 +1398,7 @@ class FileSystemInfo {
1191
1398
 
1192
1399
  /**
1193
1400
  * @param {string} path context path
1194
- * @param {function(WebpackError=, (ResolvedContextFileSystemInfoEntry | "ignore" | null)=): void} callback callback function
1401
+ * @param {function((WebpackError | null)=, (ResolvedContextFileSystemInfoEntry | "ignore" | null)=): void} callback callback function
1195
1402
  * @returns {void}
1196
1403
  */
1197
1404
  getContextTimestamp(path, callback) {
@@ -1200,10 +1407,15 @@ class FileSystemInfo {
1200
1407
  if (cache === "ignore") return callback(null, "ignore");
1201
1408
  const resolved = getResolvedTimestamp(cache);
1202
1409
  if (resolved !== undefined) return callback(null, resolved);
1203
- return this._resolveContextTimestamp(cache, callback);
1410
+ return this._resolveContextTimestamp(
1411
+ /** @type {ResolvedContextFileSystemInfoEntry} */
1412
+ (cache),
1413
+ callback
1414
+ );
1204
1415
  }
1205
- this.contextTimestampQueue.add(path, (err, entry) => {
1416
+ this.contextTimestampQueue.add(path, (err, _entry) => {
1206
1417
  if (err) return callback(err);
1418
+ const entry = /** @type {ContextFileSystemInfoEntry} */ (_entry);
1207
1419
  const resolved = getResolvedTimestamp(entry);
1208
1420
  if (resolved !== undefined) return callback(null, resolved);
1209
1421
  this._resolveContextTimestamp(entry, callback);
@@ -1212,7 +1424,7 @@ class FileSystemInfo {
1212
1424
 
1213
1425
  /**
1214
1426
  * @param {string} path context path
1215
- * @param {function(WebpackError=, (ContextFileSystemInfoEntry | "ignore" | null)=): void} callback callback function
1427
+ * @param {function((WebpackError | null)=, (ContextFileSystemInfoEntry | "ignore" | null)=): void} callback callback function
1216
1428
  * @returns {void}
1217
1429
  */
1218
1430
  _getUnresolvedContextTimestamp(path, callback) {
@@ -1223,7 +1435,7 @@ class FileSystemInfo {
1223
1435
 
1224
1436
  /**
1225
1437
  * @param {string} path file path
1226
- * @param {function(WebpackError=, string=): void} callback callback function
1438
+ * @param {function((WebpackError | null)=, (string | null)=): void} callback callback function
1227
1439
  * @returns {void}
1228
1440
  */
1229
1441
  getFileHash(path, callback) {
@@ -1234,27 +1446,30 @@ class FileSystemInfo {
1234
1446
 
1235
1447
  /**
1236
1448
  * @param {string} path context path
1237
- * @param {function(WebpackError=, string=): void} callback callback function
1449
+ * @param {function((WebpackError | null)=, string=): void} callback callback function
1238
1450
  * @returns {void}
1239
1451
  */
1240
1452
  getContextHash(path, callback) {
1241
1453
  const cache = this._contextHashes.get(path);
1242
1454
  if (cache !== undefined) {
1243
1455
  const resolved = getResolvedHash(cache);
1244
- if (resolved !== undefined) return callback(null, resolved);
1456
+ if (resolved !== undefined)
1457
+ return callback(null, /** @type {string} */ (resolved));
1245
1458
  return this._resolveContextHash(cache, callback);
1246
1459
  }
1247
- this.contextHashQueue.add(path, (err, entry) => {
1460
+ this.contextHashQueue.add(path, (err, _entry) => {
1248
1461
  if (err) return callback(err);
1462
+ const entry = /** @type {ContextHash} */ (_entry);
1249
1463
  const resolved = getResolvedHash(entry);
1250
- if (resolved !== undefined) return callback(null, resolved);
1464
+ if (resolved !== undefined)
1465
+ return callback(null, /** @type {string} */ (resolved));
1251
1466
  this._resolveContextHash(entry, callback);
1252
1467
  });
1253
1468
  }
1254
1469
 
1255
1470
  /**
1256
1471
  * @param {string} path context path
1257
- * @param {function(WebpackError=, ContextHash=): void} callback callback function
1472
+ * @param {function((WebpackError | null)=, (ContextHash | null)=): void} callback callback function
1258
1473
  * @returns {void}
1259
1474
  */
1260
1475
  _getUnresolvedContextHash(path, callback) {
@@ -1265,7 +1480,7 @@ class FileSystemInfo {
1265
1480
 
1266
1481
  /**
1267
1482
  * @param {string} path context path
1268
- * @param {function(WebpackError=, ResolvedContextTimestampAndHash=): void} callback callback function
1483
+ * @param {function((WebpackError | null)=, (ResolvedContextTimestampAndHash | null)=): void} callback callback function
1269
1484
  * @returns {void}
1270
1485
  */
1271
1486
  getContextTsh(path, callback) {
@@ -1275,8 +1490,9 @@ class FileSystemInfo {
1275
1490
  if (resolved !== undefined) return callback(null, resolved);
1276
1491
  return this._resolveContextTsh(cache, callback);
1277
1492
  }
1278
- this.contextTshQueue.add(path, (err, entry) => {
1493
+ this.contextTshQueue.add(path, (err, _entry) => {
1279
1494
  if (err) return callback(err);
1495
+ const entry = /** @type {ContextTimestampAndHash} */ (_entry);
1280
1496
  const resolved = getResolvedTimestamp(entry);
1281
1497
  if (resolved !== undefined) return callback(null, resolved);
1282
1498
  this._resolveContextTsh(entry, callback);
@@ -1285,7 +1501,7 @@ class FileSystemInfo {
1285
1501
 
1286
1502
  /**
1287
1503
  * @param {string} path context path
1288
- * @param {function(WebpackError=, ContextTimestampAndHash=): void} callback callback function
1504
+ * @param {function((WebpackError | null)=, (ContextTimestampAndHash | null)=): void} callback callback function
1289
1505
  * @returns {void}
1290
1506
  */
1291
1507
  _getUnresolvedContextTsh(path, callback) {
@@ -1325,7 +1541,7 @@ class FileSystemInfo {
1325
1541
  /**
1326
1542
  * @param {string} context context directory
1327
1543
  * @param {Iterable<string>} deps dependencies
1328
- * @param {function(Error=, ResolveBuildDependenciesResult=): void} callback callback function
1544
+ * @param {function((Error | null)=, ResolveBuildDependenciesResult=): void} callback callback function
1329
1545
  * @returns {void}
1330
1546
  */
1331
1547
  resolveBuildDependencies(context, deps, callback) {
@@ -1348,7 +1564,7 @@ class FileSystemInfo {
1348
1564
  const resolveDirectories = new Set();
1349
1565
  /** @type {Set<string>} */
1350
1566
  const resolveMissing = new Set();
1351
- /** @type {Map<string, string | false>} */
1567
+ /** @type {Map<string, string | false | undefined>} */
1352
1568
  const resolveResults = new Map();
1353
1569
  const invalidResolveResults = new Set();
1354
1570
  const resolverContext = {
@@ -1356,9 +1572,18 @@ class FileSystemInfo {
1356
1572
  contextDependencies: resolveDirectories,
1357
1573
  missingDependencies: resolveMissing
1358
1574
  };
1359
- const expectedToString = expected => {
1360
- return expected ? ` (expected ${expected})` : "";
1361
- };
1575
+ /**
1576
+ * @param {undefined | boolean | string} expected expected result
1577
+ * @returns {string} expected result
1578
+ */
1579
+ const expectedToString = expected =>
1580
+ expected ? ` (expected ${expected})` : "";
1581
+ /** @typedef {{ type: JobType, context: string | undefined, path: string, issuer: Job | undefined, expected: undefined | boolean | string }} Job */
1582
+
1583
+ /**
1584
+ * @param {Job} job job
1585
+ * @returns {`resolve commonjs file ${string}${string}`|`resolve esm file ${string}${string}`|`resolve esm ${string}${string}`|`resolve directory ${string}`|`file ${string}`|`unknown ${string} ${string}`|`resolve commonjs ${string}${string}`|`directory ${string}`|`file dependencies ${string}`|`directory dependencies ${string}`} result
1586
+ */
1362
1587
  const jobToString = job => {
1363
1588
  switch (job.type) {
1364
1589
  case RBDT_RESOLVE_CJS:
@@ -1388,104 +1613,135 @@ class FileSystemInfo {
1388
1613
  }
1389
1614
  return `unknown ${job.type} ${job.path}`;
1390
1615
  };
1616
+ /**
1617
+ * @param {Job} job job
1618
+ * @returns {string} string value
1619
+ */
1391
1620
  const pathToString = job => {
1392
1621
  let result = ` at ${jobToString(job)}`;
1393
- job = job.issuer;
1622
+ /** @type {Job | undefined} */
1623
+ (job) = job.issuer;
1394
1624
  while (job !== undefined) {
1395
1625
  result += `\n at ${jobToString(job)}`;
1396
- job = job.issuer;
1626
+ job = /** @type {Job} */ (job.issuer);
1397
1627
  }
1398
1628
  return result;
1399
1629
  };
1630
+ const logger = /** @type {Logger} */ (this.logger);
1400
1631
  processAsyncTree(
1401
- Array.from(deps, dep => ({
1402
- type: RBDT_RESOLVE_CJS,
1403
- context,
1404
- path: dep,
1405
- expected: undefined,
1406
- issuer: undefined
1407
- })),
1632
+ Array.from(
1633
+ deps,
1634
+ dep =>
1635
+ /** @type {Job} */ ({
1636
+ type: RBDT_RESOLVE_CJS,
1637
+ context,
1638
+ path: dep,
1639
+ expected: undefined,
1640
+ issuer: undefined
1641
+ })
1642
+ ),
1408
1643
  20,
1409
1644
  (job, push, callback) => {
1410
1645
  const { type, context, path, expected } = job;
1646
+ /**
1647
+ * @param {string} path path
1648
+ * @returns {void}
1649
+ */
1411
1650
  const resolveDirectory = path => {
1412
1651
  const key = `d\n${context}\n${path}`;
1413
1652
  if (resolveResults.has(key)) {
1414
1653
  return callback();
1415
1654
  }
1416
1655
  resolveResults.set(key, undefined);
1417
- resolveContext(context, path, resolverContext, (err, _, result) => {
1418
- if (err) {
1419
- if (expected === false) {
1420
- resolveResults.set(key, false);
1421
- return callback();
1422
- }
1423
- invalidResolveResults.add(key);
1424
- err.message += `\nwhile resolving '${path}' in ${context} to a directory`;
1425
- return callback(err);
1426
- }
1427
- const resultPath = result.path;
1428
- resolveResults.set(key, resultPath);
1429
- push({
1430
- type: RBDT_DIRECTORY,
1431
- context: undefined,
1432
- path: resultPath,
1433
- expected: undefined,
1434
- issuer: job
1435
- });
1436
- callback();
1437
- });
1438
- };
1439
- const resolveFile = (path, symbol, resolve) => {
1440
- const key = `${symbol}\n${context}\n${path}`;
1441
- if (resolveResults.has(key)) {
1442
- return callback();
1443
- }
1444
- resolveResults.set(key, undefined);
1445
- resolve(context, path, resolverContext, (err, _, result) => {
1446
- if (typeof expected === "string") {
1447
- if (!err && result && result.path === expected) {
1448
- resolveResults.set(key, result.path);
1449
- } else {
1450
- invalidResolveResults.add(key);
1451
- this.logger.warn(
1452
- `Resolving '${path}' in ${context} for build dependencies doesn't lead to expected result '${expected}', but to '${
1453
- err || (result && result.path)
1454
- }' instead. Resolving dependencies are ignored for this path.\n${pathToString(
1455
- job
1456
- )}`
1457
- );
1458
- }
1459
- } else {
1656
+ resolveContext(
1657
+ /** @type {string} */ (context),
1658
+ path,
1659
+ resolverContext,
1660
+ (err, _, result) => {
1460
1661
  if (err) {
1461
1662
  if (expected === false) {
1462
1663
  resolveResults.set(key, false);
1463
1664
  return callback();
1464
1665
  }
1465
1666
  invalidResolveResults.add(key);
1466
- err.message += `\nwhile resolving '${path}' in ${context} as file\n${pathToString(
1467
- job
1468
- )}`;
1667
+ err.message += `\nwhile resolving '${path}' in ${context} to a directory`;
1469
1668
  return callback(err);
1470
1669
  }
1471
- const resultPath = result.path;
1670
+ const resultPath = /** @type {ResolveRequest} */ (result).path;
1472
1671
  resolveResults.set(key, resultPath);
1473
1672
  push({
1474
- type: RBDT_FILE,
1673
+ type: RBDT_DIRECTORY,
1475
1674
  context: undefined,
1476
- path: resultPath,
1675
+ path: /** @type {string} */ (resultPath),
1477
1676
  expected: undefined,
1478
1677
  issuer: job
1479
1678
  });
1679
+ callback();
1480
1680
  }
1481
- callback();
1482
- });
1681
+ );
1682
+ };
1683
+ /**
1684
+ * @param {string} path path
1685
+ * @param {("f" | "c" | "e")=} symbol symbol
1686
+ * @param {(ResolveFunctionAsync)=} resolve resolve fn
1687
+ * @returns {void}
1688
+ */
1689
+ const resolveFile = (path, symbol, resolve) => {
1690
+ const key = `${symbol}\n${context}\n${path}`;
1691
+ if (resolveResults.has(key)) {
1692
+ return callback();
1693
+ }
1694
+ resolveResults.set(key, undefined);
1695
+ /** @type {ResolveFunctionAsync} */
1696
+ (resolve)(
1697
+ /** @type {string} */ (context),
1698
+ path,
1699
+ resolverContext,
1700
+ (err, _, result) => {
1701
+ if (typeof expected === "string") {
1702
+ if (!err && result && result.path === expected) {
1703
+ resolveResults.set(key, result.path);
1704
+ } else {
1705
+ invalidResolveResults.add(key);
1706
+ logger.warn(
1707
+ `Resolving '${path}' in ${context} for build dependencies doesn't lead to expected result '${expected}', but to '${
1708
+ err || (result && result.path)
1709
+ }' instead. Resolving dependencies are ignored for this path.\n${pathToString(
1710
+ job
1711
+ )}`
1712
+ );
1713
+ }
1714
+ } else {
1715
+ if (err) {
1716
+ if (expected === false) {
1717
+ resolveResults.set(key, false);
1718
+ return callback();
1719
+ }
1720
+ invalidResolveResults.add(key);
1721
+ err.message += `\nwhile resolving '${path}' in ${context} as file\n${pathToString(
1722
+ job
1723
+ )}`;
1724
+ return callback(err);
1725
+ }
1726
+ const resultPath = /** @type {ResolveRequest} */ (result).path;
1727
+ resolveResults.set(key, resultPath);
1728
+ push({
1729
+ type: RBDT_FILE,
1730
+ context: undefined,
1731
+ path: /** @type {string} */ (resultPath),
1732
+ expected: undefined,
1733
+ issuer: job
1734
+ });
1735
+ }
1736
+ callback();
1737
+ }
1738
+ );
1483
1739
  };
1484
1740
  switch (type) {
1485
1741
  case RBDT_RESOLVE_CJS: {
1486
1742
  const isDirectory = /[\\/]$/.test(path);
1487
1743
  if (isDirectory) {
1488
- resolveDirectory(path.slice(0, path.length - 1));
1744
+ resolveDirectory(path.slice(0, -1));
1489
1745
  } else {
1490
1746
  resolveFile(path, "f", resolveCjs);
1491
1747
  }
@@ -1494,7 +1750,7 @@ class FileSystemInfo {
1494
1750
  case RBDT_RESOLVE_ESM: {
1495
1751
  const isDirectory = /[\\/]$/.test(path);
1496
1752
  if (isDirectory) {
1497
- resolveDirectory(path.slice(0, path.length - 1));
1753
+ resolveDirectory(path.slice(0, -1));
1498
1754
  } else {
1499
1755
  resolveFile(path);
1500
1756
  }
@@ -1522,7 +1778,8 @@ class FileSystemInfo {
1522
1778
  break;
1523
1779
  }
1524
1780
  files.add(path);
1525
- this.fs.realpath(path, (err, _realPath) => {
1781
+ /** @type {NonNullable<InputFileSystem["realpath"]>} */
1782
+ (this.fs.realpath)(path, (err, _realPath) => {
1526
1783
  if (err) return callback(err);
1527
1784
  const realPath = /** @type {string} */ (_realPath);
1528
1785
  if (realPath !== path) {
@@ -1548,7 +1805,8 @@ class FileSystemInfo {
1548
1805
  break;
1549
1806
  }
1550
1807
  directories.add(path);
1551
- this.fs.realpath(path, (err, _realPath) => {
1808
+ /** @type {NonNullable<InputFileSystem["realpath"]>} */
1809
+ (this.fs.realpath)(path, (err, _realPath) => {
1552
1810
  if (err) return callback(err);
1553
1811
  const realPath = /** @type {string} */ (_realPath);
1554
1812
  if (realPath !== path) {
@@ -1575,11 +1833,11 @@ class FileSystemInfo {
1575
1833
  break;
1576
1834
  }
1577
1835
  // Check commonjs cache for the module
1578
- /** @type {NodeModule} */
1836
+ /** @type {NodeModule | undefined} */
1579
1837
  const module = require.cache[path];
1580
1838
  if (module && Array.isArray(module.children)) {
1581
1839
  children: for (const child of module.children) {
1582
- let childPath = child.filename;
1840
+ const childPath = child.filename;
1583
1841
  if (childPath) {
1584
1842
  push({
1585
1843
  type: RBDT_FILE,
@@ -1591,7 +1849,7 @@ class FileSystemInfo {
1591
1849
  const context = dirname(this.fs, path);
1592
1850
  for (const modulePath of module.paths) {
1593
1851
  if (childPath.startsWith(modulePath)) {
1594
- let subPath = childPath.slice(modulePath.length + 1);
1852
+ const subPath = childPath.slice(modulePath.length + 1);
1595
1853
  const packageMatch = /^(@[^\\/]+[\\/])[^\\/]+/.exec(
1596
1854
  subPath
1597
1855
  );
@@ -1599,12 +1857,12 @@ class FileSystemInfo {
1599
1857
  push({
1600
1858
  type: RBDT_FILE,
1601
1859
  context: undefined,
1602
- path:
1860
+ path: `${
1603
1861
  modulePath +
1604
1862
  childPath[modulePath.length] +
1605
1863
  packageMatch[0] +
1606
- childPath[modulePath.length] +
1607
- "package.json",
1864
+ childPath[modulePath.length]
1865
+ }package.json`,
1608
1866
  expected: false,
1609
1867
  issuer: job
1610
1868
  });
@@ -1625,7 +1883,9 @@ class FileSystemInfo {
1625
1883
  let request = relative(this.fs, context, childPath);
1626
1884
  if (request.endsWith(".js")) request = request.slice(0, -3);
1627
1885
  request = request.replace(/\\/g, "/");
1628
- if (!request.startsWith("../")) request = `./${request}`;
1886
+ if (!request.startsWith("../") && !isAbsolute(request)) {
1887
+ request = `./${request}`;
1888
+ }
1629
1889
  push({
1630
1890
  type: RBDT_RESOLVE_CJS_FILE,
1631
1891
  context,
@@ -1637,7 +1897,7 @@ class FileSystemInfo {
1637
1897
  }
1638
1898
  } else if (supportsEsm && /\.m?js$/.test(path)) {
1639
1899
  if (!this._warnAboutExperimentalEsmTracking) {
1640
- this.logger.log(
1900
+ logger.log(
1641
1901
  "Node.js doesn't offer a (nice) way to introspect the ESM dependency graph yet.\n" +
1642
1902
  "Until a full solution is available webpack uses an experimental ESM tracking based on parsing.\n" +
1643
1903
  "As best effort webpack parses the ESM files to guess dependencies. But this can lead to expensive and incorrect tracking."
@@ -1650,63 +1910,64 @@ class FileSystemInfo {
1650
1910
  if (err) return callback(err);
1651
1911
  try {
1652
1912
  const context = dirname(this.fs, path);
1653
- const source = content.toString();
1913
+ const source = /** @type {Buffer} */ (content).toString();
1654
1914
  const [imports] = lexer.parse(source);
1655
1915
  for (const imp of imports) {
1656
1916
  try {
1657
1917
  let dependency;
1658
1918
  if (imp.d === -1) {
1659
1919
  // import ... from "..."
1660
- dependency = JSON.parse(
1920
+ dependency = parseString(
1661
1921
  source.substring(imp.s - 1, imp.e + 1)
1662
1922
  );
1663
1923
  } else if (imp.d > -1) {
1664
1924
  // import()
1665
- let expr = source.substring(imp.s, imp.e).trim();
1666
- if (expr[0] === "'")
1667
- expr = `"${expr
1668
- .slice(1, -1)
1669
- .replace(/"/g, '\\"')}"`;
1670
- dependency = JSON.parse(expr);
1925
+ const expr = source.substring(imp.s, imp.e).trim();
1926
+ dependency = parseString(expr);
1671
1927
  } else {
1672
1928
  // e.g. import.meta
1673
1929
  continue;
1674
1930
  }
1931
+
1932
+ // we should not track Node.js build dependencies
1933
+ if (dependency.startsWith("node:")) continue;
1934
+ if (builtinModules.has(dependency)) continue;
1935
+
1675
1936
  push({
1676
1937
  type: RBDT_RESOLVE_ESM_FILE,
1677
1938
  context,
1678
1939
  path: dependency,
1679
- expected: undefined,
1940
+ expected: imp.d > -1 ? false : undefined,
1680
1941
  issuer: job
1681
1942
  });
1682
- } catch (e) {
1683
- this.logger.warn(
1943
+ } catch (err1) {
1944
+ logger.warn(
1684
1945
  `Parsing of ${path} for build dependencies failed at 'import(${source.substring(
1685
1946
  imp.s,
1686
1947
  imp.e
1687
1948
  )})'.\n` +
1688
1949
  "Build dependencies behind this expression are ignored and might cause incorrect cache invalidation."
1689
1950
  );
1690
- this.logger.debug(pathToString(job));
1691
- this.logger.debug(e.stack);
1951
+ logger.debug(pathToString(job));
1952
+ logger.debug(/** @type {Error} */ (err1).stack);
1692
1953
  }
1693
1954
  }
1694
- } catch (e) {
1695
- this.logger.warn(
1955
+ } catch (err2) {
1956
+ logger.warn(
1696
1957
  `Parsing of ${path} for build dependencies failed and all dependencies of this file are ignored, which might cause incorrect cache invalidation..`
1697
1958
  );
1698
- this.logger.debug(pathToString(job));
1699
- this.logger.debug(e.stack);
1959
+ logger.debug(pathToString(job));
1960
+ logger.debug(/** @type {Error} */ (err2).stack);
1700
1961
  }
1701
1962
  process.nextTick(callback);
1702
1963
  });
1703
1964
  }, callback);
1704
1965
  break;
1705
1966
  } else {
1706
- this.logger.log(
1967
+ logger.log(
1707
1968
  `Assuming ${path} has no dependencies as we were unable to assign it to any module system.`
1708
1969
  );
1709
- this.logger.debug(pathToString(job));
1970
+ logger.debug(pathToString(job));
1710
1971
  }
1711
1972
  process.nextTick(callback);
1712
1973
  break;
@@ -1738,9 +1999,11 @@ class FileSystemInfo {
1738
1999
  resolveFiles.add(packageJson);
1739
2000
  let packageData;
1740
2001
  try {
1741
- packageData = JSON.parse(content.toString("utf-8"));
1742
- } catch (e) {
1743
- return callback(e);
2002
+ packageData = JSON.parse(
2003
+ /** @type {Buffer} */ (content).toString("utf-8")
2004
+ );
2005
+ } catch (parseErr) {
2006
+ return callback(/** @type {Error} */ (parseErr));
1744
2007
  }
1745
2008
  const depsObject = packageData.dependencies;
1746
2009
  const optionalDepsObject = packageData.optionalDependencies;
@@ -1797,7 +2060,7 @@ class FileSystemInfo {
1797
2060
 
1798
2061
  /**
1799
2062
  * @param {Map<string, string | false>} resolveResults results from resolving
1800
- * @param {function(Error=, boolean=): void} callback callback with true when resolveResults resolve the same way
2063
+ * @param {function((Error | null)=, boolean=): void} callback callback with true when resolveResults resolve the same way
1801
2064
  * @returns {void}
1802
2065
  */
1803
2066
  checkResolveResultsValid(resolveResults, callback) {
@@ -1814,7 +2077,7 @@ class FileSystemInfo {
1814
2077
  if (expectedResult === false)
1815
2078
  return callback(err ? undefined : INVALID);
1816
2079
  if (err) return callback(err);
1817
- const resultPath = result.path;
2080
+ const resultPath = /** @type {ResolveRequest} */ (result).path;
1818
2081
  if (resultPath !== expectedResult) return callback(INVALID);
1819
2082
  callback();
1820
2083
  });
@@ -1824,7 +2087,7 @@ class FileSystemInfo {
1824
2087
  if (expectedResult === false)
1825
2088
  return callback(err ? undefined : INVALID);
1826
2089
  if (err) return callback(err);
1827
- const resultPath = result.path;
2090
+ const resultPath = /** @type {ResolveRequest} */ (result).path;
1828
2091
  if (resultPath !== expectedResult) return callback(INVALID);
1829
2092
  callback();
1830
2093
  });
@@ -1834,7 +2097,7 @@ class FileSystemInfo {
1834
2097
  if (expectedResult === false)
1835
2098
  return callback(err ? undefined : INVALID);
1836
2099
  if (err) return callback(err);
1837
- const resultPath = result.path;
2100
+ const resultPath = /** @type {ResolveRequest} */ (result).path;
1838
2101
  if (resultPath !== expectedResult) return callback(INVALID);
1839
2102
  callback();
1840
2103
  });
@@ -1844,7 +2107,7 @@ class FileSystemInfo {
1844
2107
  if (expectedResult === false)
1845
2108
  return callback(err ? undefined : INVALID);
1846
2109
  if (err) return callback(err);
1847
- const resultPath = result.path;
2110
+ const resultPath = /** @type {ResolveRequest} */ (result).path;
1848
2111
  if (resultPath !== expectedResult) return callback(INVALID);
1849
2112
  callback();
1850
2113
  });
@@ -1871,41 +2134,38 @@ class FileSystemInfo {
1871
2134
  }
1872
2135
 
1873
2136
  /**
1874
- *
1875
- * @param {number} startTime when processing the files has started
1876
- * @param {Iterable<string>} files all files
1877
- * @param {Iterable<string>} directories all directories
1878
- * @param {Iterable<string>} missing all missing files or directories
1879
- * @param {Object} options options object (for future extensions)
1880
- * @param {boolean=} options.hash should use hash to snapshot
1881
- * @param {boolean=} options.timestamp should use timestamp to snapshot
1882
- * @param {function(WebpackError=, Snapshot=): void} callback callback function
2137
+ * @param {number | null | undefined} startTime when processing the files has started
2138
+ * @param {Iterable<string> | null} files all files
2139
+ * @param {Iterable<string> | null} directories all directories
2140
+ * @param {Iterable<string> | null} missing all missing files or directories
2141
+ * @param {SnapshotOptions | null | undefined} options options object (for future extensions)
2142
+ * @param {function(WebpackError | null, Snapshot | null): void} callback callback function
1883
2143
  * @returns {void}
1884
2144
  */
1885
2145
  createSnapshot(startTime, files, directories, missing, options, callback) {
1886
- /** @type {Map<string, FileSystemInfoEntry | null>} */
2146
+ /** @type {FileTimestamps} */
1887
2147
  const fileTimestamps = new Map();
1888
- /** @type {Map<string, string | null>} */
2148
+ /** @type {FileHashes} */
1889
2149
  const fileHashes = new Map();
1890
- /** @type {Map<string, TimestampAndHash | string | null>} */
2150
+ /** @type {FileTshs} */
1891
2151
  const fileTshs = new Map();
1892
- /** @type {Map<string, FileSystemInfoEntry | null>} */
2152
+ /** @type {ContextTimestamps} */
1893
2153
  const contextTimestamps = new Map();
1894
- /** @type {Map<string, string | null>} */
2154
+ /** @type {ContextHashes} */
1895
2155
  const contextHashes = new Map();
1896
- /** @type {Map<string, ResolvedContextTimestampAndHash | null>} */
2156
+ /** @type {ContextTshs} */
1897
2157
  const contextTshs = new Map();
1898
- /** @type {Map<string, boolean>} */
2158
+ /** @type {MissingExistence} */
1899
2159
  const missingExistence = new Map();
1900
- /** @type {Map<string, string>} */
2160
+ /** @type {ManagedItemInfo} */
1901
2161
  const managedItemInfo = new Map();
1902
- /** @type {Set<string>} */
2162
+ /** @type {ManagedFiles} */
1903
2163
  const managedFiles = new Set();
1904
- /** @type {Set<string>} */
2164
+ /** @type {ManagedContexts} */
1905
2165
  const managedContexts = new Set();
1906
- /** @type {Set<string>} */
2166
+ /** @type {ManagedMissing} */
1907
2167
  const managedMissing = new Set();
1908
- /** @type {Set<Snapshot>} */
2168
+ /** @type {Children} */
1909
2169
  const children = new Set();
1910
2170
 
1911
2171
  const snapshot = new Snapshot();
@@ -1972,7 +2232,18 @@ class FileSystemInfo {
1972
2232
  callback(null, null);
1973
2233
  }
1974
2234
  };
2235
+ /**
2236
+ * @param {string} path path
2237
+ * @param {Set<string>} managedSet managed set
2238
+ * @returns {boolean} true when managed
2239
+ */
1975
2240
  const checkManaged = (path, managedSet) => {
2241
+ for (const unmanagedPath of this.unmanagedPathsRegExps) {
2242
+ if (unmanagedPath.test(path)) return false;
2243
+ }
2244
+ for (const unmanagedPath of this.unmanagedPathsWithSlash) {
2245
+ if (path.startsWith(unmanagedPath)) return false;
2246
+ }
1976
2247
  for (const immutablePath of this.immutablePathsRegExps) {
1977
2248
  if (immutablePath.test(path)) {
1978
2249
  managedSet.add(path);
@@ -1988,7 +2259,7 @@ class FileSystemInfo {
1988
2259
  for (const managedPath of this.managedPathsRegExps) {
1989
2260
  const match = managedPath.exec(path);
1990
2261
  if (match) {
1991
- const managedItem = getManagedItem(managedPath[1], path);
2262
+ const managedItem = getManagedItem(match[1], path);
1992
2263
  if (managedItem) {
1993
2264
  managedItems.add(managedItem);
1994
2265
  managedSet.add(path);
@@ -2008,6 +2279,11 @@ class FileSystemInfo {
2008
2279
  }
2009
2280
  return false;
2010
2281
  };
2282
+ /**
2283
+ * @param {Iterable<string>} items items
2284
+ * @param {Set<string>} managedSet managed set
2285
+ * @returns {Set<string>} result
2286
+ */
2011
2287
  const captureNonManaged = (items, managedSet) => {
2012
2288
  const capturedItems = new Set();
2013
2289
  for (const path of items) {
@@ -2015,8 +2291,10 @@ class FileSystemInfo {
2015
2291
  }
2016
2292
  return capturedItems;
2017
2293
  };
2018
- if (files) {
2019
- const capturedFiles = captureNonManaged(files, managedFiles);
2294
+ /**
2295
+ * @param {Set<string>} capturedFiles captured files
2296
+ */
2297
+ const processCapturedFiles = capturedFiles => {
2020
2298
  switch (mode) {
2021
2299
  case 3:
2022
2300
  this._fileTshsOptimization.optimize(snapshot, capturedFiles);
@@ -2035,7 +2313,7 @@ class FileSystemInfo {
2035
2313
  }
2036
2314
  jobError();
2037
2315
  } else {
2038
- fileTshs.set(path, entry);
2316
+ fileTshs.set(path, /** @type {TimestampAndHash} */ (entry));
2039
2317
  jobDone();
2040
2318
  }
2041
2319
  });
@@ -2059,7 +2337,7 @@ class FileSystemInfo {
2059
2337
  }
2060
2338
  jobError();
2061
2339
  } else {
2062
- fileHashes.set(path, entry);
2340
+ fileHashes.set(path, /** @type {string} */ (entry));
2063
2341
  jobDone();
2064
2342
  }
2065
2343
  });
@@ -2085,7 +2363,11 @@ class FileSystemInfo {
2085
2363
  }
2086
2364
  jobError();
2087
2365
  } else {
2088
- fileTimestamps.set(path, entry);
2366
+ fileTimestamps.set(
2367
+ path,
2368
+ /** @type {FileSystemInfoEntry} */
2369
+ (entry)
2370
+ );
2089
2371
  jobDone();
2090
2372
  }
2091
2373
  });
@@ -2093,18 +2375,20 @@ class FileSystemInfo {
2093
2375
  }
2094
2376
  break;
2095
2377
  }
2378
+ };
2379
+ if (files) {
2380
+ processCapturedFiles(captureNonManaged(files, managedFiles));
2096
2381
  }
2097
- if (directories) {
2098
- const capturedDirectories = captureNonManaged(
2099
- directories,
2100
- managedContexts
2101
- );
2382
+ /**
2383
+ * @param {Set<string>} capturedDirectories captured directories
2384
+ */
2385
+ const processCapturedDirectories = capturedDirectories => {
2102
2386
  switch (mode) {
2103
2387
  case 3:
2104
2388
  this._contextTshsOptimization.optimize(snapshot, capturedDirectories);
2105
2389
  for (const path of capturedDirectories) {
2106
2390
  const cache = this._contextTshs.get(path);
2107
- /** @type {ResolvedContextTimestampAndHash} */
2391
+ /** @type {ResolvedContextTimestampAndHash | null | undefined} */
2108
2392
  let resolved;
2109
2393
  if (
2110
2394
  cache !== undefined &&
@@ -2114,8 +2398,8 @@ class FileSystemInfo {
2114
2398
  } else {
2115
2399
  jobs++;
2116
2400
  /**
2117
- * @param {Error=} err error
2118
- * @param {ResolvedContextTimestampAndHash=} entry entry
2401
+ * @param {(WebpackError | null)=} err error
2402
+ * @param {(ResolvedContextTimestampAndHash | null)=} entry entry
2119
2403
  * @returns {void}
2120
2404
  */
2121
2405
  const callback = (err, entry) => {
@@ -2127,7 +2411,11 @@ class FileSystemInfo {
2127
2411
  }
2128
2412
  jobError();
2129
2413
  } else {
2130
- contextTshs.set(path, entry);
2414
+ contextTshs.set(
2415
+ path,
2416
+ /** @type {ResolvedContextTimestampAndHash | null} */
2417
+ (entry)
2418
+ );
2131
2419
  jobDone();
2132
2420
  }
2133
2421
  };
@@ -2154,6 +2442,10 @@ class FileSystemInfo {
2154
2442
  contextHashes.set(path, resolved);
2155
2443
  } else {
2156
2444
  jobs++;
2445
+ /**
2446
+ * @param {(WebpackError | null)=} err err
2447
+ * @param {string=} entry entry
2448
+ */
2157
2449
  const callback = (err, entry) => {
2158
2450
  if (err) {
2159
2451
  if (this.logger) {
@@ -2163,7 +2455,7 @@ class FileSystemInfo {
2163
2455
  }
2164
2456
  jobError();
2165
2457
  } else {
2166
- contextHashes.set(path, entry);
2458
+ contextHashes.set(path, /** @type {string} */ (entry));
2167
2459
  jobDone();
2168
2460
  }
2169
2461
  };
@@ -2192,8 +2484,8 @@ class FileSystemInfo {
2192
2484
  } else {
2193
2485
  jobs++;
2194
2486
  /**
2195
- * @param {Error=} err error
2196
- * @param {ResolvedContextFileSystemInfoEntry=} entry entry
2487
+ * @param {(Error | null)=} err error
2488
+ * @param {(FileSystemInfoEntry | "ignore" | null)=} entry entry
2197
2489
  * @returns {void}
2198
2490
  */
2199
2491
  const callback = (err, entry) => {
@@ -2205,12 +2497,20 @@ class FileSystemInfo {
2205
2497
  }
2206
2498
  jobError();
2207
2499
  } else {
2208
- contextTimestamps.set(path, entry);
2500
+ contextTimestamps.set(
2501
+ path,
2502
+ /** @type {FileSystemInfoEntry | null} */
2503
+ (entry)
2504
+ );
2209
2505
  jobDone();
2210
2506
  }
2211
2507
  };
2212
2508
  if (cache !== undefined) {
2213
- this._resolveContextTimestamp(cache, callback);
2509
+ this._resolveContextTimestamp(
2510
+ /** @type {ContextFileSystemInfoEntry} */
2511
+ (cache),
2512
+ callback
2513
+ );
2214
2514
  } else {
2215
2515
  this.getContextTimestamp(path, callback);
2216
2516
  }
@@ -2218,9 +2518,16 @@ class FileSystemInfo {
2218
2518
  }
2219
2519
  break;
2220
2520
  }
2521
+ };
2522
+ if (directories) {
2523
+ processCapturedDirectories(
2524
+ captureNonManaged(directories, managedContexts)
2525
+ );
2221
2526
  }
2222
- if (missing) {
2223
- const capturedMissing = captureNonManaged(missing, managedMissing);
2527
+ /**
2528
+ * @param {Set<string>} capturedMissing captured missing
2529
+ */
2530
+ const processCapturedMissing = capturedMissing => {
2224
2531
  this._missingExistenceOptimization.optimize(snapshot, capturedMissing);
2225
2532
  for (const path of capturedMissing) {
2226
2533
  const cache = this._fileTimestamps.get(path);
@@ -2245,11 +2552,19 @@ class FileSystemInfo {
2245
2552
  });
2246
2553
  }
2247
2554
  }
2555
+ };
2556
+ if (missing) {
2557
+ processCapturedMissing(captureNonManaged(missing, managedMissing));
2248
2558
  }
2249
2559
  this._managedItemInfoOptimization.optimize(snapshot, managedItems);
2250
2560
  for (const path of managedItems) {
2251
2561
  const cache = this._managedItems.get(path);
2252
2562
  if (cache !== undefined) {
2563
+ if (!cache.startsWith("*")) {
2564
+ managedFiles.add(join(this.fs, path, "package.json"));
2565
+ } else if (cache === "*nested") {
2566
+ managedMissing.add(join(this.fs, path, "package.json"));
2567
+ }
2253
2568
  managedItemInfo.set(path, cache);
2254
2569
  } else {
2255
2570
  jobs++;
@@ -2261,9 +2576,32 @@ class FileSystemInfo {
2261
2576
  );
2262
2577
  }
2263
2578
  jobError();
2264
- } else {
2579
+ } else if (entry) {
2580
+ if (!entry.startsWith("*")) {
2581
+ managedFiles.add(join(this.fs, path, "package.json"));
2582
+ } else if (cache === "*nested") {
2583
+ managedMissing.add(join(this.fs, path, "package.json"));
2584
+ }
2265
2585
  managedItemInfo.set(path, entry);
2266
2586
  jobDone();
2587
+ } else {
2588
+ // Fallback to normal snapshotting
2589
+ /**
2590
+ * @param {Set<string>} set set
2591
+ * @param {function(Set<string>): void} fn fn
2592
+ */
2593
+ const process = (set, fn) => {
2594
+ if (set.size === 0) return;
2595
+ const captured = new Set();
2596
+ for (const file of set) {
2597
+ if (file.startsWith(path)) captured.add(file);
2598
+ }
2599
+ if (captured.size > 0) fn(captured);
2600
+ };
2601
+ process(managedFiles, processCapturedFiles);
2602
+ process(managedContexts, processCapturedDirectories);
2603
+ process(managedMissing, processCapturedMissing);
2604
+ jobDone();
2267
2605
  }
2268
2606
  });
2269
2607
  }
@@ -2278,10 +2616,20 @@ class FileSystemInfo {
2278
2616
  */
2279
2617
  mergeSnapshots(snapshot1, snapshot2) {
2280
2618
  const snapshot = new Snapshot();
2281
- if (snapshot1.hasStartTime() && snapshot2.hasStartTime())
2282
- snapshot.setStartTime(Math.min(snapshot1.startTime, snapshot2.startTime));
2283
- else if (snapshot2.hasStartTime()) snapshot.startTime = snapshot2.startTime;
2284
- else if (snapshot1.hasStartTime()) snapshot.startTime = snapshot1.startTime;
2619
+ if (snapshot1.hasStartTime() && snapshot2.hasStartTime()) {
2620
+ snapshot.setStartTime(
2621
+ Math.min(
2622
+ /** @type {NonNullable<Snapshot["startTime"]>} */
2623
+ (snapshot1.startTime),
2624
+ /** @type {NonNullable<Snapshot["startTime"]>} */
2625
+ (snapshot2.startTime)
2626
+ )
2627
+ );
2628
+ } else if (snapshot2.hasStartTime()) {
2629
+ snapshot.startTime = snapshot2.startTime;
2630
+ } else if (snapshot1.hasStartTime()) {
2631
+ snapshot.startTime = snapshot1.startTime;
2632
+ }
2285
2633
  if (snapshot1.hasFileTimestamps() || snapshot2.hasFileTimestamps()) {
2286
2634
  snapshot.setFileTimestamps(
2287
2635
  mergeMaps(snapshot1.fileTimestamps, snapshot2.fileTimestamps)
@@ -2349,7 +2697,7 @@ class FileSystemInfo {
2349
2697
 
2350
2698
  /**
2351
2699
  * @param {Snapshot} snapshot the snapshot made
2352
- * @param {function(WebpackError=, boolean=): void} callback callback function
2700
+ * @param {function((WebpackError | null)=, boolean=): void} callback callback function
2353
2701
  * @returns {void}
2354
2702
  */
2355
2703
  checkSnapshotValid(snapshot, callback) {
@@ -2369,12 +2717,12 @@ class FileSystemInfo {
2369
2717
 
2370
2718
  /**
2371
2719
  * @param {Snapshot} snapshot the snapshot made
2372
- * @param {function(WebpackError=, boolean=): void} callback callback function
2720
+ * @param {function((WebpackError | null)=, boolean=): void} callback callback function
2373
2721
  * @returns {void}
2374
2722
  */
2375
2723
  _checkSnapshotValidNoCache(snapshot, callback) {
2376
2724
  /** @type {number | undefined} */
2377
- let startTime = undefined;
2725
+ let startTime;
2378
2726
  if (snapshot.hasStartTime()) {
2379
2727
  startTime = snapshot.startTime;
2380
2728
  }
@@ -2393,23 +2741,27 @@ class FileSystemInfo {
2393
2741
  callback(null, false);
2394
2742
  }
2395
2743
  };
2744
+ /**
2745
+ * @param {string} path path
2746
+ * @param {WebpackError} err err
2747
+ */
2396
2748
  const invalidWithError = (path, err) => {
2397
2749
  if (this._remainingLogs > 0) {
2398
- this._log(path, `error occurred: %s`, err);
2750
+ this._log(path, "error occurred: %s", err);
2399
2751
  }
2400
2752
  invalid();
2401
2753
  };
2402
2754
  /**
2403
2755
  * @param {string} path file path
2404
- * @param {string} current current hash
2405
- * @param {string} snap snapshot hash
2756
+ * @param {string | null} current current hash
2757
+ * @param {string | null} snap snapshot hash
2406
2758
  * @returns {boolean} true, if ok
2407
2759
  */
2408
2760
  const checkHash = (path, current, snap) => {
2409
2761
  if (current !== snap) {
2410
2762
  // If hash differ it's invalid
2411
2763
  if (this._remainingLogs > 0) {
2412
- this._log(path, `hashes differ (%s != %s)`, current, snap);
2764
+ this._log(path, "hashes differ (%s != %s)", current, snap);
2413
2765
  }
2414
2766
  return false;
2415
2767
  }
@@ -2437,40 +2789,38 @@ class FileSystemInfo {
2437
2789
  };
2438
2790
  /**
2439
2791
  * @param {string} path file path
2440
- * @param {FileSystemInfoEntry} current current entry
2441
- * @param {FileSystemInfoEntry} snap entry from snapshot
2792
+ * @param {FileSystemInfoEntry | null} c current entry
2793
+ * @param {FileSystemInfoEntry | null} s entry from snapshot
2442
2794
  * @param {boolean} log log reason
2443
2795
  * @returns {boolean} true, if ok
2444
2796
  */
2445
- const checkFile = (path, current, snap, log = true) => {
2446
- if (current === snap) return true;
2447
- if (!checkExistence(path, Boolean(current), Boolean(snap))) return false;
2448
- if (current) {
2797
+ const checkFile = (path, c, s, log = true) => {
2798
+ if (c === s) return true;
2799
+ if (!checkExistence(path, Boolean(c), Boolean(s))) return false;
2800
+ if (c) {
2449
2801
  // For existing items only
2450
- if (typeof startTime === "number" && current.safeTime > startTime) {
2802
+ if (typeof startTime === "number" && c.safeTime > startTime) {
2451
2803
  // If a change happened after starting reading the item
2452
2804
  // this may no longer be valid
2453
2805
  if (log && this._remainingLogs > 0) {
2454
2806
  this._log(
2455
2807
  path,
2456
- `it may have changed (%d) after the start time of the snapshot (%d)`,
2457
- current.safeTime,
2808
+ "it may have changed (%d) after the start time of the snapshot (%d)",
2809
+ c.safeTime,
2458
2810
  startTime
2459
2811
  );
2460
2812
  }
2461
2813
  return false;
2462
2814
  }
2463
- if (
2464
- snap.timestamp !== undefined &&
2465
- current.timestamp !== snap.timestamp
2466
- ) {
2815
+ const snap = /** @type {FileSystemInfoEntry} */ (s);
2816
+ if (snap.timestamp !== undefined && c.timestamp !== snap.timestamp) {
2467
2817
  // If we have a timestamp (it was a file or symlink) and it differs from current timestamp
2468
2818
  // it's invalid
2469
2819
  if (log && this._remainingLogs > 0) {
2470
2820
  this._log(
2471
2821
  path,
2472
- `timestamps differ (%d != %d)`,
2473
- current.timestamp,
2822
+ "timestamps differ (%d != %d)",
2823
+ c.timestamp,
2474
2824
  snap.timestamp
2475
2825
  );
2476
2826
  }
@@ -2481,40 +2831,41 @@ class FileSystemInfo {
2481
2831
  };
2482
2832
  /**
2483
2833
  * @param {string} path file path
2484
- * @param {ResolvedContextFileSystemInfoEntry} current current entry
2485
- * @param {ResolvedContextFileSystemInfoEntry} snap entry from snapshot
2834
+ * @param {ResolvedContextFileSystemInfoEntry | null} c current entry
2835
+ * @param {ResolvedContextFileSystemInfoEntry | null} s entry from snapshot
2486
2836
  * @param {boolean} log log reason
2487
2837
  * @returns {boolean} true, if ok
2488
2838
  */
2489
- const checkContext = (path, current, snap, log = true) => {
2490
- if (current === snap) return true;
2491
- if (!checkExistence(path, Boolean(current), Boolean(snap))) return false;
2492
- if (current) {
2839
+ const checkContext = (path, c, s, log = true) => {
2840
+ if (c === s) return true;
2841
+ if (!checkExistence(path, Boolean(c), Boolean(s))) return false;
2842
+ if (c) {
2493
2843
  // For existing items only
2494
- if (typeof startTime === "number" && current.safeTime > startTime) {
2844
+ if (typeof startTime === "number" && c.safeTime > startTime) {
2495
2845
  // If a change happened after starting reading the item
2496
2846
  // this may no longer be valid
2497
2847
  if (log && this._remainingLogs > 0) {
2498
2848
  this._log(
2499
2849
  path,
2500
- `it may have changed (%d) after the start time of the snapshot (%d)`,
2501
- current.safeTime,
2850
+ "it may have changed (%d) after the start time of the snapshot (%d)",
2851
+ c.safeTime,
2502
2852
  startTime
2503
2853
  );
2504
2854
  }
2505
2855
  return false;
2506
2856
  }
2857
+ const snap = /** @type {ResolvedContextFileSystemInfoEntry} */ (s);
2507
2858
  if (
2508
2859
  snap.timestampHash !== undefined &&
2509
- current.timestampHash !== snap.timestampHash
2860
+ c.timestampHash !== snap.timestampHash
2510
2861
  ) {
2511
2862
  // If we have a timestampHash (it was a directory) and it differs from current timestampHash
2512
2863
  // it's invalid
2513
2864
  if (log && this._remainingLogs > 0) {
2514
2865
  this._log(
2515
2866
  path,
2516
- `timestamps hashes differ (%s != %s)`,
2517
- current.timestampHash,
2867
+ "timestamps hashes differ (%s != %s)",
2868
+ c.timestampHash,
2518
2869
  snap.timestampHash
2519
2870
  );
2520
2871
  }
@@ -2524,11 +2875,16 @@ class FileSystemInfo {
2524
2875
  return true;
2525
2876
  };
2526
2877
  if (snapshot.hasChildren()) {
2878
+ /**
2879
+ * @param {(WebpackError | null)=} err err
2880
+ * @param {boolean=} result result
2881
+ * @returns {void}
2882
+ */
2527
2883
  const childCallback = (err, result) => {
2528
2884
  if (err || !result) return invalid();
2529
- else jobDone();
2885
+ jobDone();
2530
2886
  };
2531
- for (const child of snapshot.children) {
2887
+ for (const child of /** @type {Children} */ (snapshot.children)) {
2532
2888
  const cache = this._snapshotCache.get(child);
2533
2889
  if (cache !== undefined) {
2534
2890
  this._statTestedChildrenCached++;
@@ -2550,7 +2906,9 @@ class FileSystemInfo {
2550
2906
  }
2551
2907
  }
2552
2908
  if (snapshot.hasFileTimestamps()) {
2553
- const { fileTimestamps } = snapshot;
2909
+ const fileTimestamps =
2910
+ /** @type {FileTimestamps} */
2911
+ (snapshot.fileTimestamps);
2554
2912
  this._statTestedEntries += fileTimestamps.size;
2555
2913
  for (const [path, ts] of fileTimestamps) {
2556
2914
  const cache = this._fileTimestamps.get(path);
@@ -2563,7 +2921,13 @@ class FileSystemInfo {
2563
2921
  jobs++;
2564
2922
  this.fileTimestampQueue.add(path, (err, entry) => {
2565
2923
  if (err) return invalidWithError(path, err);
2566
- if (!checkFile(path, entry, ts)) {
2924
+ if (
2925
+ !checkFile(
2926
+ path,
2927
+ /** @type {FileSystemInfoEntry | null} */ (entry),
2928
+ ts
2929
+ )
2930
+ ) {
2567
2931
  invalid();
2568
2932
  } else {
2569
2933
  jobDone();
@@ -2572,18 +2936,21 @@ class FileSystemInfo {
2572
2936
  }
2573
2937
  }
2574
2938
  }
2939
+ /**
2940
+ * @param {string} path file path
2941
+ * @param {string | null} hash hash
2942
+ */
2575
2943
  const processFileHashSnapshot = (path, hash) => {
2576
2944
  const cache = this._fileHashes.get(path);
2577
2945
  if (cache !== undefined) {
2578
2946
  if (cache !== "ignore" && !checkHash(path, cache, hash)) {
2579
2947
  invalid();
2580
- return;
2581
2948
  }
2582
2949
  } else {
2583
2950
  jobs++;
2584
2951
  this.fileHashQueue.add(path, (err, entry) => {
2585
2952
  if (err) return invalidWithError(path, err);
2586
- if (!checkHash(path, entry, hash)) {
2953
+ if (!checkHash(path, /** @type {string} */ (entry), hash)) {
2587
2954
  invalid();
2588
2955
  } else {
2589
2956
  jobDone();
@@ -2592,14 +2959,14 @@ class FileSystemInfo {
2592
2959
  }
2593
2960
  };
2594
2961
  if (snapshot.hasFileHashes()) {
2595
- const { fileHashes } = snapshot;
2962
+ const fileHashes = /** @type {FileHashes} */ (snapshot.fileHashes);
2596
2963
  this._statTestedEntries += fileHashes.size;
2597
2964
  for (const [path, hash] of fileHashes) {
2598
2965
  processFileHashSnapshot(path, hash);
2599
2966
  }
2600
2967
  }
2601
2968
  if (snapshot.hasFileTshs()) {
2602
- const { fileTshs } = snapshot;
2969
+ const fileTshs = /** @type {FileTshs} */ (snapshot.fileTshs);
2603
2970
  this._statTestedEntries += fileTshs.size;
2604
2971
  for (const [path, tsh] of fileTshs) {
2605
2972
  if (typeof tsh === "string") {
@@ -2614,7 +2981,15 @@ class FileSystemInfo {
2614
2981
  jobs++;
2615
2982
  this.fileTimestampQueue.add(path, (err, entry) => {
2616
2983
  if (err) return invalidWithError(path, err);
2617
- if (!checkFile(path, entry, tsh, false)) {
2984
+ if (
2985
+ !checkFile(
2986
+ path,
2987
+ /** @type {FileSystemInfoEntry | null} */
2988
+ (entry),
2989
+ tsh,
2990
+ false
2991
+ )
2992
+ ) {
2618
2993
  processFileHashSnapshot(path, tsh && tsh.hash);
2619
2994
  }
2620
2995
  jobDone();
@@ -2624,7 +2999,9 @@ class FileSystemInfo {
2624
2999
  }
2625
3000
  }
2626
3001
  if (snapshot.hasContextTimestamps()) {
2627
- const { contextTimestamps } = snapshot;
3002
+ const contextTimestamps =
3003
+ /** @type {ContextTimestamps} */
3004
+ (snapshot.contextTimestamps);
2628
3005
  this._statTestedEntries += contextTimestamps.size;
2629
3006
  for (const [path, ts] of contextTimestamps) {
2630
3007
  const cache = this._contextTimestamps.get(path);
@@ -2641,26 +3018,41 @@ class FileSystemInfo {
2641
3018
  } else {
2642
3019
  jobs++;
2643
3020
  /**
2644
- * @param {Error=} err error
2645
- * @param {ResolvedContextFileSystemInfoEntry=} entry entry
3021
+ * @param {(WebpackError | null)=} err error
3022
+ * @param {(ResolvedContextFileSystemInfoEntry | "ignore" | null)=} entry entry
2646
3023
  * @returns {void}
2647
3024
  */
2648
3025
  const callback = (err, entry) => {
2649
3026
  if (err) return invalidWithError(path, err);
2650
- if (!checkContext(path, entry, ts)) {
3027
+ if (
3028
+ !checkContext(
3029
+ path,
3030
+ /** @type {ResolvedContextFileSystemInfoEntry | null} */
3031
+ (entry),
3032
+ ts
3033
+ )
3034
+ ) {
2651
3035
  invalid();
2652
3036
  } else {
2653
3037
  jobDone();
2654
3038
  }
2655
3039
  };
2656
3040
  if (cache !== undefined) {
2657
- this._resolveContextTimestamp(cache, callback);
3041
+ this._resolveContextTimestamp(
3042
+ /** @type {ContextFileSystemInfoEntry} */
3043
+ (cache),
3044
+ callback
3045
+ );
2658
3046
  } else {
2659
3047
  this.getContextTimestamp(path, callback);
2660
3048
  }
2661
3049
  }
2662
3050
  }
2663
3051
  }
3052
+ /**
3053
+ * @param {string} path path
3054
+ * @param {string | null} hash hash
3055
+ */
2664
3056
  const processContextHashSnapshot = (path, hash) => {
2665
3057
  const cache = this._contextHashes.get(path);
2666
3058
  let resolved;
@@ -2670,13 +3062,17 @@ class FileSystemInfo {
2670
3062
  ) {
2671
3063
  if (!checkHash(path, resolved, hash)) {
2672
3064
  invalid();
2673
- return;
2674
3065
  }
2675
3066
  } else {
2676
3067
  jobs++;
3068
+ /**
3069
+ * @param {(WebpackError | null)=} err err
3070
+ * @param {string=} entry entry
3071
+ * @returns {void}
3072
+ */
2677
3073
  const callback = (err, entry) => {
2678
3074
  if (err) return invalidWithError(path, err);
2679
- if (!checkHash(path, entry, hash)) {
3075
+ if (!checkHash(path, /** @type {string} */ (entry), hash)) {
2680
3076
  invalid();
2681
3077
  } else {
2682
3078
  jobDone();
@@ -2690,14 +3086,16 @@ class FileSystemInfo {
2690
3086
  }
2691
3087
  };
2692
3088
  if (snapshot.hasContextHashes()) {
2693
- const { contextHashes } = snapshot;
3089
+ const contextHashes =
3090
+ /** @type {ContextHashes} */
3091
+ (snapshot.contextHashes);
2694
3092
  this._statTestedEntries += contextHashes.size;
2695
3093
  for (const [path, hash] of contextHashes) {
2696
3094
  processContextHashSnapshot(path, hash);
2697
3095
  }
2698
3096
  }
2699
3097
  if (snapshot.hasContextTshs()) {
2700
- const { contextTshs } = snapshot;
3098
+ const contextTshs = /** @type {ContextTshs} */ (snapshot.contextTshs);
2701
3099
  this._statTestedEntries += contextTshs.size;
2702
3100
  for (const [path, tsh] of contextTshs) {
2703
3101
  if (typeof tsh === "string") {
@@ -2710,25 +3108,46 @@ class FileSystemInfo {
2710
3108
  cache !== undefined &&
2711
3109
  (resolved = getResolvedTimestamp(cache)) !== undefined
2712
3110
  ) {
2713
- if (!checkContext(path, resolved, tsh, false)) {
3111
+ if (
3112
+ !checkContext(
3113
+ path,
3114
+ /** @type {ResolvedContextFileSystemInfoEntry | null} */
3115
+ (resolved),
3116
+ tsh,
3117
+ false
3118
+ )
3119
+ ) {
2714
3120
  processContextHashSnapshot(path, tsh && tsh.hash);
2715
3121
  }
2716
3122
  } else {
2717
3123
  jobs++;
2718
3124
  /**
2719
- * @param {Error=} err error
2720
- * @param {ResolvedContextFileSystemInfoEntry=} entry entry
3125
+ * @param {(WebpackError | null)=} err error
3126
+ * @param {(ResolvedContextFileSystemInfoEntry | "ignore" | null)=} entry entry
2721
3127
  * @returns {void}
2722
3128
  */
2723
3129
  const callback = (err, entry) => {
2724
3130
  if (err) return invalidWithError(path, err);
2725
- if (!checkContext(path, entry, tsh, false)) {
3131
+ if (
3132
+ !checkContext(
3133
+ path,
3134
+ // TODO: test with `"ignore"`
3135
+ /** @type {ResolvedContextFileSystemInfoEntry | null} */
3136
+ (entry),
3137
+ tsh,
3138
+ false
3139
+ )
3140
+ ) {
2726
3141
  processContextHashSnapshot(path, tsh && tsh.hash);
2727
3142
  }
2728
3143
  jobDone();
2729
3144
  };
2730
3145
  if (cache !== undefined) {
2731
- this._resolveContextTimestamp(cache, callback);
3146
+ this._resolveContextTimestamp(
3147
+ /** @type {ContextFileSystemInfoEntry} */
3148
+ (cache),
3149
+ callback
3150
+ );
2732
3151
  } else {
2733
3152
  this.getContextTimestamp(path, callback);
2734
3153
  }
@@ -2737,7 +3156,9 @@ class FileSystemInfo {
2737
3156
  }
2738
3157
  }
2739
3158
  if (snapshot.hasMissingExistence()) {
2740
- const { missingExistence } = snapshot;
3159
+ const missingExistence =
3160
+ /** @type {MissingExistence} */
3161
+ (snapshot.missingExistence);
2741
3162
  this._statTestedEntries += missingExistence.size;
2742
3163
  for (const [path, existence] of missingExistence) {
2743
3164
  const cache = this._fileTimestamps.get(path);
@@ -2763,7 +3184,9 @@ class FileSystemInfo {
2763
3184
  }
2764
3185
  }
2765
3186
  if (snapshot.hasManagedItemInfo()) {
2766
- const { managedItemInfo } = snapshot;
3187
+ const managedItemInfo =
3188
+ /** @type {ManagedItemInfo} */
3189
+ (snapshot.managedItemInfo);
2767
3190
  this._statTestedEntries += managedItemInfo.size;
2768
3191
  for (const [path, info] of managedItemInfo) {
2769
3192
  const cache = this._managedItems.get(path);
@@ -2776,7 +3199,7 @@ class FileSystemInfo {
2776
3199
  jobs++;
2777
3200
  this.managedItemQueue.add(path, (err, entry) => {
2778
3201
  if (err) return invalidWithError(path, err);
2779
- if (!checkHash(path, entry, info)) {
3202
+ if (!checkHash(path, /** @type {string} */ (entry), info)) {
2780
3203
  invalid();
2781
3204
  } else {
2782
3205
  jobDone();
@@ -2798,17 +3221,21 @@ class FileSystemInfo {
2798
3221
  }
2799
3222
  }
2800
3223
 
3224
+ /**
3225
+ * @type {Processor<string, FileSystemInfoEntry>}
3226
+ * @private
3227
+ */
2801
3228
  _readFileTimestamp(path, callback) {
2802
- this.fs.stat(path, (err, stat) => {
3229
+ this.fs.stat(path, (err, _stat) => {
2803
3230
  if (err) {
2804
3231
  if (err.code === "ENOENT") {
2805
3232
  this._fileTimestamps.set(path, null);
2806
3233
  this._cachedDeprecatedFileTimestamps = undefined;
2807
3234
  return callback(null, null);
2808
3235
  }
2809
- return callback(err);
3236
+ return callback(/** @type {WebpackError} */ (err));
2810
3237
  }
2811
-
3238
+ const stat = /** @type {IStats} */ (_stat);
2812
3239
  let ts;
2813
3240
  if (stat.isDirectory()) {
2814
3241
  ts = {
@@ -2816,7 +3243,7 @@ class FileSystemInfo {
2816
3243
  timestamp: undefined
2817
3244
  };
2818
3245
  } else {
2819
- const mtime = +stat.mtime;
3246
+ const mtime = Number(stat.mtime);
2820
3247
 
2821
3248
  if (mtime) applyMtime(mtime);
2822
3249
 
@@ -2833,6 +3260,10 @@ class FileSystemInfo {
2833
3260
  });
2834
3261
  }
2835
3262
 
3263
+ /**
3264
+ * @type {Processor<string, string>}
3265
+ * @private
3266
+ */
2836
3267
  _readFileHash(path, callback) {
2837
3268
  this.fs.readFile(path, (err, content) => {
2838
3269
  if (err) {
@@ -2845,16 +3276,17 @@ class FileSystemInfo {
2845
3276
  return callback(null, null);
2846
3277
  }
2847
3278
  if (err.code === "ERR_FS_FILE_TOO_LARGE") {
2848
- this.logger.warn(`Ignoring ${path} for hashing as it's very large`);
3279
+ /** @type {Logger} */
3280
+ (this.logger).warn(`Ignoring ${path} for hashing as it's very large`);
2849
3281
  this._fileHashes.set(path, "too large");
2850
3282
  return callback(null, "too large");
2851
3283
  }
2852
- return callback(err);
3284
+ return callback(/** @type {WebpackError} */ (err));
2853
3285
  }
2854
3286
 
2855
3287
  const hash = createHash(this._hashFunction);
2856
3288
 
2857
- hash.update(content);
3289
+ hash.update(/** @type {string | Buffer} */ (content));
2858
3290
 
2859
3291
  const digest = /** @type {string} */ (hash.digest("hex"));
2860
3292
 
@@ -2864,45 +3296,54 @@ class FileSystemInfo {
2864
3296
  });
2865
3297
  }
2866
3298
 
3299
+ /**
3300
+ * @param {string} path path
3301
+ * @param {function(WebpackError | null, TimestampAndHash=) : void} callback callback
3302
+ * @private
3303
+ */
2867
3304
  _getFileTimestampAndHash(path, callback) {
3305
+ /**
3306
+ * @param {string} hash hash
3307
+ * @returns {void}
3308
+ */
2868
3309
  const continueWithHash = hash => {
2869
3310
  const cache = this._fileTimestamps.get(path);
2870
3311
  if (cache !== undefined) {
2871
3312
  if (cache !== "ignore") {
3313
+ /** @type {TimestampAndHash} */
2872
3314
  const result = {
2873
- ...cache,
3315
+ .../** @type {FileSystemInfoEntry} */ (cache),
2874
3316
  hash
2875
3317
  };
2876
3318
  this._fileTshs.set(path, result);
2877
3319
  return callback(null, result);
2878
- } else {
2879
- this._fileTshs.set(path, hash);
2880
- return callback(null, hash);
2881
3320
  }
2882
- } else {
2883
- this.fileTimestampQueue.add(path, (err, entry) => {
2884
- if (err) {
2885
- return callback(err);
2886
- }
2887
- const result = {
2888
- ...entry,
2889
- hash
2890
- };
2891
- this._fileTshs.set(path, result);
2892
- return callback(null, result);
2893
- });
3321
+ this._fileTshs.set(path, hash);
3322
+ return callback(null, /** @type {TODO} */ (hash));
2894
3323
  }
3324
+ this.fileTimestampQueue.add(path, (err, entry) => {
3325
+ if (err) {
3326
+ return callback(err);
3327
+ }
3328
+ /** @type {TimestampAndHash} */
3329
+ const result = {
3330
+ .../** @type {FileSystemInfoEntry} */ (entry),
3331
+ hash
3332
+ };
3333
+ this._fileTshs.set(path, result);
3334
+ return callback(null, result);
3335
+ });
2895
3336
  };
2896
3337
 
2897
3338
  const cache = this._fileHashes.get(path);
2898
3339
  if (cache !== undefined) {
2899
- continueWithHash(cache);
3340
+ continueWithHash(/** @type {string} */ (cache));
2900
3341
  } else {
2901
3342
  this.fileHashQueue.add(path, (err, entry) => {
2902
3343
  if (err) {
2903
3344
  return callback(err);
2904
3345
  }
2905
- continueWithHash(entry);
3346
+ continueWithHash(/** @type {string} */ (entry));
2906
3347
  });
2907
3348
  }
2908
3349
  }
@@ -2910,15 +3351,15 @@ class FileSystemInfo {
2910
3351
  /**
2911
3352
  * @template T
2912
3353
  * @template ItemType
2913
- * @param {Object} options options
3354
+ * @param {object} options options
2914
3355
  * @param {string} options.path path
2915
3356
  * @param {function(string): ItemType} options.fromImmutablePath called when context item is an immutable path
2916
3357
  * @param {function(string): ItemType} options.fromManagedItem called when context item is a managed path
2917
- * @param {function(string, string, function(Error=, ItemType=): void): void} options.fromSymlink called when context item is a symlink
2918
- * @param {function(string, IStats, function(Error=, ItemType=): void): void} options.fromFile called when context item is a file
2919
- * @param {function(string, IStats, function(Error=, ItemType=): void): void} options.fromDirectory called when context item is a directory
3358
+ * @param {function(string, string, function((WebpackError | null)=, ItemType=): void): void} options.fromSymlink called when context item is a symlink
3359
+ * @param {function(string, IStats, function((WebpackError | null)=, (ItemType | null)=): void): void} options.fromFile called when context item is a file
3360
+ * @param {function(string, IStats, function((WebpackError | null)=, ItemType=): void): void} options.fromDirectory called when context item is a directory
2920
3361
  * @param {function(string[], ItemType[]): T} options.reduce called from all context items
2921
- * @param {function(Error=, (T)=): void} callback callback
3362
+ * @param {function((Error | null)=, (T | null)=): void} callback callback
2922
3363
  */
2923
3364
  _readContext(
2924
3365
  {
@@ -2962,12 +3403,15 @@ class FileSystemInfo {
2962
3403
  for (const managedPath of this.managedPathsRegExps) {
2963
3404
  const match = managedPath.exec(path);
2964
3405
  if (match) {
2965
- const managedItem = getManagedItem(managedPath[1], path);
3406
+ const managedItem = getManagedItem(match[1], path);
2966
3407
  if (managedItem) {
2967
3408
  // construct timestampHash from managed info
2968
3409
  return this.managedItemQueue.add(managedItem, (err, info) => {
2969
3410
  if (err) return callback(err);
2970
- return callback(null, fromManagedItem(info));
3411
+ return callback(
3412
+ null,
3413
+ fromManagedItem(/** @type {string} */ (info))
3414
+ );
2971
3415
  });
2972
3416
  }
2973
3417
  }
@@ -2979,15 +3423,20 @@ class FileSystemInfo {
2979
3423
  // construct timestampHash from managed info
2980
3424
  return this.managedItemQueue.add(managedItem, (err, info) => {
2981
3425
  if (err) return callback(err);
2982
- return callback(null, fromManagedItem(info));
3426
+ return callback(
3427
+ null,
3428
+ fromManagedItem(/** @type {string} */ (info))
3429
+ );
2983
3430
  });
2984
3431
  }
2985
3432
  }
2986
3433
  }
2987
3434
 
2988
- lstatReadlinkAbsolute(this.fs, child, (err, stat) => {
3435
+ lstatReadlinkAbsolute(this.fs, child, (err, _stat) => {
2989
3436
  if (err) return callback(err);
2990
3437
 
3438
+ const stat = /** @type {IStats | string} */ (_stat);
3439
+
2991
3440
  if (typeof stat === "string") {
2992
3441
  return fromSymlink(child, stat, callback);
2993
3442
  }
@@ -3003,27 +3452,37 @@ class FileSystemInfo {
3003
3452
  },
3004
3453
  (err, results) => {
3005
3454
  if (err) return callback(err);
3006
- const result = reduce(files, results);
3455
+ const result = reduce(files, /** @type {ItemType[]} */ (results));
3007
3456
  callback(null, result);
3008
3457
  }
3009
3458
  );
3010
3459
  });
3011
3460
  }
3012
3461
 
3462
+ /**
3463
+ * @type {Processor<string, ContextFileSystemInfoEntry>}
3464
+ * @private
3465
+ */
3013
3466
  _readContextTimestamp(path, callback) {
3014
3467
  this._readContext(
3015
3468
  {
3016
3469
  path,
3017
- fromImmutablePath: () => null,
3470
+ fromImmutablePath: () =>
3471
+ /** @type {ContextFileSystemInfoEntry | FileSystemInfoEntry | "ignore" | null} */
3472
+ (null),
3018
3473
  fromManagedItem: info => ({
3019
3474
  safeTime: 0,
3020
3475
  timestampHash: info
3021
3476
  }),
3022
3477
  fromSymlink: (file, target, callback) => {
3023
- callback(null, {
3024
- timestampHash: target,
3025
- symlinks: new Set([target])
3026
- });
3478
+ callback(
3479
+ null,
3480
+ /** @type {ContextFileSystemInfoEntry} */
3481
+ ({
3482
+ timestampHash: target,
3483
+ symlinks: new Set([target])
3484
+ })
3485
+ );
3027
3486
  },
3028
3487
  fromFile: (file, stat, callback) => {
3029
3488
  // Prefer the cached value over our new stat to report consistent results
@@ -3031,10 +3490,11 @@ class FileSystemInfo {
3031
3490
  if (cache !== undefined)
3032
3491
  return callback(null, cache === "ignore" ? null : cache);
3033
3492
 
3034
- const mtime = +stat.mtime;
3493
+ const mtime = Number(stat.mtime);
3035
3494
 
3036
3495
  if (mtime) applyMtime(mtime);
3037
3496
 
3497
+ /** @type {FileSystemInfoEntry} */
3038
3498
  const ts = {
3039
3499
  safeTime: mtime ? mtime + FS_ACCURACY : Infinity,
3040
3500
  timestamp: mtime
@@ -3052,27 +3512,42 @@ class FileSystemInfo {
3052
3512
  });
3053
3513
  },
3054
3514
  reduce: (files, tsEntries) => {
3055
- let symlinks = undefined;
3515
+ let symlinks;
3056
3516
 
3057
3517
  const hash = createHash(this._hashFunction);
3058
3518
 
3059
3519
  for (const file of files) hash.update(file);
3060
3520
  let safeTime = 0;
3061
- for (const entry of tsEntries) {
3062
- if (!entry) {
3521
+ for (const _e of tsEntries) {
3522
+ if (!_e) {
3063
3523
  hash.update("n");
3064
3524
  continue;
3065
3525
  }
3066
- if (entry.timestamp) {
3526
+ const entry =
3527
+ /** @type {FileSystemInfoEntry | ContextFileSystemInfoEntry} */
3528
+ (_e);
3529
+ if (/** @type {FileSystemInfoEntry} */ (entry).timestamp) {
3067
3530
  hash.update("f");
3068
- hash.update(`${entry.timestamp}`);
3069
- } else if (entry.timestampHash) {
3531
+ hash.update(
3532
+ `${/** @type {FileSystemInfoEntry} */ (entry).timestamp}`
3533
+ );
3534
+ } else if (
3535
+ /** @type {ContextFileSystemInfoEntry} */ (entry).timestampHash
3536
+ ) {
3070
3537
  hash.update("d");
3071
- hash.update(`${entry.timestampHash}`);
3538
+ hash.update(
3539
+ `${/** @type {ContextFileSystemInfoEntry} */ (entry).timestampHash}`
3540
+ );
3072
3541
  }
3073
- if (entry.symlinks !== undefined) {
3542
+ if (
3543
+ /** @type {ContextFileSystemInfoEntry} */
3544
+ (entry).symlinks !== undefined
3545
+ ) {
3074
3546
  if (symlinks === undefined) symlinks = new Set();
3075
- addAll(entry.symlinks, symlinks);
3547
+ addAll(
3548
+ /** @type {ContextFileSystemInfoEntry} */ (entry).symlinks,
3549
+ symlinks
3550
+ );
3076
3551
  }
3077
3552
  if (entry.safeTime) {
3078
3553
  safeTime = Math.max(safeTime, entry.safeTime);
@@ -3080,7 +3555,7 @@ class FileSystemInfo {
3080
3555
  }
3081
3556
 
3082
3557
  const digest = /** @type {string} */ (hash.digest("hex"));
3083
-
3558
+ /** @type {ContextFileSystemInfoEntry} */
3084
3559
  const result = {
3085
3560
  safeTime,
3086
3561
  timestampHash: digest
@@ -3090,7 +3565,7 @@ class FileSystemInfo {
3090
3565
  }
3091
3566
  },
3092
3567
  (err, result) => {
3093
- if (err) return callback(err);
3568
+ if (err) return callback(/** @type {WebpackError} */ (err));
3094
3569
  this._contextTimestamps.set(path, result);
3095
3570
  this._cachedDeprecatedContextTimestamps = undefined;
3096
3571
 
@@ -3101,20 +3576,21 @@ class FileSystemInfo {
3101
3576
 
3102
3577
  /**
3103
3578
  * @param {ContextFileSystemInfoEntry} entry entry
3104
- * @param {function(Error=, ResolvedContextFileSystemInfoEntry=): void} callback callback
3579
+ * @param {function((WebpackError | null)=, (ResolvedContextFileSystemInfoEntry | "ignore" | null)=): void} callback callback
3105
3580
  * @returns {void}
3106
3581
  */
3107
3582
  _resolveContextTimestamp(entry, callback) {
3583
+ /** @type {string[]} */
3108
3584
  const hashes = [];
3109
3585
  let safeTime = 0;
3110
3586
  processAsyncTree(
3111
- entry.symlinks,
3587
+ /** @type {NonNullable<ContextHash["symlinks"]>} */ (entry.symlinks),
3112
3588
  10,
3113
3589
  (target, push, callback) => {
3114
3590
  this._getUnresolvedContextTimestamp(target, (err, entry) => {
3115
3591
  if (err) return callback(err);
3116
3592
  if (entry && entry !== "ignore") {
3117
- hashes.push(entry.timestampHash);
3593
+ hashes.push(/** @type {string} */ (entry.timestampHash));
3118
3594
  if (entry.safeTime) {
3119
3595
  safeTime = Math.max(safeTime, entry.safeTime);
3120
3596
  }
@@ -3126,9 +3602,9 @@ class FileSystemInfo {
3126
3602
  });
3127
3603
  },
3128
3604
  err => {
3129
- if (err) return callback(err);
3605
+ if (err) return callback(/** @type {WebpackError} */ (err));
3130
3606
  const hash = createHash(this._hashFunction);
3131
- hash.update(entry.timestampHash);
3607
+ hash.update(/** @type {string} */ (entry.timestampHash));
3132
3608
  if (entry.safeTime) {
3133
3609
  safeTime = Math.max(safeTime, entry.safeTime);
3134
3610
  }
@@ -3147,17 +3623,26 @@ class FileSystemInfo {
3147
3623
  );
3148
3624
  }
3149
3625
 
3626
+ /**
3627
+ * @type {Processor<string, ContextHash>}
3628
+ * @private
3629
+ */
3150
3630
  _readContextHash(path, callback) {
3151
3631
  this._readContext(
3152
3632
  {
3153
3633
  path,
3154
- fromImmutablePath: () => "",
3634
+ fromImmutablePath: () =>
3635
+ /** @type {ContextHash} */ (/** @type {unknown} */ ("")),
3155
3636
  fromManagedItem: info => info || "",
3156
3637
  fromSymlink: (file, target, callback) => {
3157
- callback(null, {
3158
- hash: target,
3159
- symlinks: new Set([target])
3160
- });
3638
+ callback(
3639
+ null,
3640
+ /** @type {ContextHash} */
3641
+ ({
3642
+ hash: target,
3643
+ symlinks: new Set([target])
3644
+ })
3645
+ );
3161
3646
  },
3162
3647
  fromFile: (file, stat, callback) =>
3163
3648
  this.getFileHash(file, (err, hash) => {
@@ -3176,7 +3661,7 @@ class FileSystemInfo {
3176
3661
  * @returns {ContextHash} reduced hash
3177
3662
  */
3178
3663
  reduce: (files, fileHashes) => {
3179
- let symlinks = undefined;
3664
+ let symlinks;
3180
3665
  const hash = createHash(this._hashFunction);
3181
3666
 
3182
3667
  for (const file of files) hash.update(file);
@@ -3192,6 +3677,7 @@ class FileSystemInfo {
3192
3677
  }
3193
3678
  }
3194
3679
 
3680
+ /** @type {ContextHash} */
3195
3681
  const result = {
3196
3682
  hash: /** @type {string} */ (hash.digest("hex"))
3197
3683
  };
@@ -3199,8 +3685,9 @@ class FileSystemInfo {
3199
3685
  return result;
3200
3686
  }
3201
3687
  },
3202
- (err, result) => {
3203
- if (err) return callback(err);
3688
+ (err, _result) => {
3689
+ if (err) return callback(/** @type {WebpackError} */ (err));
3690
+ const result = /** @type {ContextHash} */ (_result);
3204
3691
  this._contextHashes.set(path, result);
3205
3692
  return callback(null, result);
3206
3693
  }
@@ -3209,13 +3696,14 @@ class FileSystemInfo {
3209
3696
 
3210
3697
  /**
3211
3698
  * @param {ContextHash} entry context hash
3212
- * @param {function(Error=, string=): void} callback callback
3699
+ * @param {function(WebpackError | null, string=): void} callback callback
3213
3700
  * @returns {void}
3214
3701
  */
3215
3702
  _resolveContextHash(entry, callback) {
3703
+ /** @type {string[]} */
3216
3704
  const hashes = [];
3217
3705
  processAsyncTree(
3218
- entry.symlinks,
3706
+ /** @type {NonNullable<ContextHash["symlinks"]>} */ (entry.symlinks),
3219
3707
  10,
3220
3708
  (target, push, callback) => {
3221
3709
  this._getUnresolvedContextHash(target, (err, hash) => {
@@ -3230,7 +3718,7 @@ class FileSystemInfo {
3230
3718
  });
3231
3719
  },
3232
3720
  err => {
3233
- if (err) return callback(err);
3721
+ if (err) return callback(/** @type {WebpackError} */ (err));
3234
3722
  const hash = createHash(this._hashFunction);
3235
3723
  hash.update(entry.hash);
3236
3724
  hashes.sort();
@@ -3245,15 +3733,19 @@ class FileSystemInfo {
3245
3733
  );
3246
3734
  }
3247
3735
 
3736
+ /**
3737
+ * @type {Processor<string, ContextTimestampAndHash>}
3738
+ * @private
3739
+ */
3248
3740
  _readContextTimestampAndHash(path, callback) {
3741
+ /**
3742
+ * @param {ContextFileSystemInfoEntry | "ignore" | null} timestamp timestamp
3743
+ * @param {ContextHash} hash hash
3744
+ */
3249
3745
  const finalize = (timestamp, hash) => {
3250
3746
  const result =
3251
- timestamp === "ignore"
3252
- ? hash
3253
- : {
3254
- ...timestamp,
3255
- ...hash
3256
- };
3747
+ /** @type {ContextTimestampAndHash} */
3748
+ (timestamp === "ignore" ? hash : { ...timestamp, ...hash });
3257
3749
  this._contextTshs.set(path, result);
3258
3750
  callback(null, result);
3259
3751
  };
@@ -3265,115 +3757,121 @@ class FileSystemInfo {
3265
3757
  } else {
3266
3758
  this.contextTimestampQueue.add(path, (err, entry) => {
3267
3759
  if (err) return callback(err);
3268
- finalize(entry, cachedHash);
3760
+ finalize(
3761
+ /** @type {ContextFileSystemInfoEntry} */
3762
+ (entry),
3763
+ cachedHash
3764
+ );
3269
3765
  });
3270
3766
  }
3767
+ } else if (cachedTimestamp !== undefined) {
3768
+ this.contextHashQueue.add(path, (err, entry) => {
3769
+ if (err) return callback(err);
3770
+ finalize(cachedTimestamp, /** @type {ContextHash} */ (entry));
3771
+ });
3271
3772
  } else {
3272
- if (cachedTimestamp !== undefined) {
3273
- this.contextHashQueue.add(path, (err, entry) => {
3274
- if (err) return callback(err);
3275
- finalize(cachedTimestamp, entry);
3276
- });
3277
- } else {
3278
- this._readContext(
3279
- {
3280
- path,
3281
- fromImmutablePath: () => null,
3282
- fromManagedItem: info => ({
3283
- safeTime: 0,
3284
- timestampHash: info,
3285
- hash: info || ""
3286
- }),
3287
- fromSymlink: (fle, target, callback) => {
3288
- callback(null, {
3289
- timestampHash: target,
3290
- hash: target,
3291
- symlinks: new Set([target])
3292
- });
3293
- },
3294
- fromFile: (file, stat, callback) => {
3295
- this._getFileTimestampAndHash(file, callback);
3296
- },
3297
- fromDirectory: (directory, stat, callback) => {
3298
- this.contextTshQueue.increaseParallelism();
3299
- this.contextTshQueue.add(directory, (err, result) => {
3300
- this.contextTshQueue.decreaseParallelism();
3301
- callback(err, result);
3302
- });
3303
- },
3304
- /**
3305
- * @param {string[]} files files
3306
- * @param {(Partial<TimestampAndHash> & Partial<ContextTimestampAndHash> | string | null)[]} results results
3307
- * @returns {ContextTimestampAndHash} tsh
3308
- */
3309
- reduce: (files, results) => {
3310
- let symlinks = undefined;
3773
+ this._readContext(
3774
+ {
3775
+ path,
3776
+ fromImmutablePath: () => null,
3777
+ fromManagedItem: info => ({
3778
+ safeTime: 0,
3779
+ timestampHash: info,
3780
+ hash: info || ""
3781
+ }),
3782
+ fromSymlink: (file, target, callback) => {
3783
+ callback(null, {
3784
+ timestampHash: target,
3785
+ hash: target,
3786
+ symlinks: new Set([target])
3787
+ });
3788
+ },
3789
+ fromFile: (file, stat, callback) => {
3790
+ this._getFileTimestampAndHash(file, callback);
3791
+ },
3792
+ fromDirectory: (directory, stat, callback) => {
3793
+ this.contextTshQueue.increaseParallelism();
3794
+ this.contextTshQueue.add(directory, (err, result) => {
3795
+ this.contextTshQueue.decreaseParallelism();
3796
+ callback(err, result);
3797
+ });
3798
+ },
3799
+ /**
3800
+ * @param {string[]} files files
3801
+ * @param {(Partial<TimestampAndHash> & Partial<ContextTimestampAndHash> | string | null)[]} results results
3802
+ * @returns {ContextTimestampAndHash} tsh
3803
+ */
3804
+ reduce: (files, results) => {
3805
+ let symlinks;
3311
3806
 
3312
- const tsHash = createHash(this._hashFunction);
3313
- const hash = createHash(this._hashFunction);
3807
+ const tsHash = createHash(this._hashFunction);
3808
+ const hash = createHash(this._hashFunction);
3314
3809
 
3315
- for (const file of files) {
3316
- tsHash.update(file);
3317
- hash.update(file);
3810
+ for (const file of files) {
3811
+ tsHash.update(file);
3812
+ hash.update(file);
3813
+ }
3814
+ let safeTime = 0;
3815
+ for (const entry of results) {
3816
+ if (!entry) {
3817
+ tsHash.update("n");
3818
+ continue;
3318
3819
  }
3319
- let safeTime = 0;
3320
- for (const entry of results) {
3321
- if (!entry) {
3322
- tsHash.update("n");
3323
- continue;
3324
- }
3325
- if (typeof entry === "string") {
3326
- tsHash.update("n");
3327
- hash.update(entry);
3328
- continue;
3329
- }
3330
- if (entry.timestamp) {
3331
- tsHash.update("f");
3332
- tsHash.update(`${entry.timestamp}`);
3333
- } else if (entry.timestampHash) {
3334
- tsHash.update("d");
3335
- tsHash.update(`${entry.timestampHash}`);
3336
- }
3337
- if (entry.symlinks !== undefined) {
3338
- if (symlinks === undefined) symlinks = new Set();
3339
- addAll(entry.symlinks, symlinks);
3340
- }
3341
- if (entry.safeTime) {
3342
- safeTime = Math.max(safeTime, entry.safeTime);
3343
- }
3344
- hash.update(entry.hash);
3820
+ if (typeof entry === "string") {
3821
+ tsHash.update("n");
3822
+ hash.update(entry);
3823
+ continue;
3345
3824
  }
3346
-
3347
- const result = {
3348
- safeTime,
3349
- timestampHash: /** @type {string} */ (tsHash.digest("hex")),
3350
- hash: /** @type {string} */ (hash.digest("hex"))
3351
- };
3352
- if (symlinks) result.symlinks = symlinks;
3353
- return result;
3825
+ if (entry.timestamp) {
3826
+ tsHash.update("f");
3827
+ tsHash.update(`${entry.timestamp}`);
3828
+ } else if (entry.timestampHash) {
3829
+ tsHash.update("d");
3830
+ tsHash.update(`${entry.timestampHash}`);
3831
+ }
3832
+ if (entry.symlinks !== undefined) {
3833
+ if (symlinks === undefined) symlinks = new Set();
3834
+ addAll(entry.symlinks, symlinks);
3835
+ }
3836
+ if (entry.safeTime) {
3837
+ safeTime = Math.max(safeTime, entry.safeTime);
3838
+ }
3839
+ hash.update(/** @type {string} */ (entry.hash));
3354
3840
  }
3355
- },
3356
- (err, result) => {
3357
- if (err) return callback(err);
3358
- this._contextTshs.set(path, result);
3359
- return callback(null, result);
3841
+
3842
+ /** @type {ContextTimestampAndHash} */
3843
+ const result = {
3844
+ safeTime,
3845
+ timestampHash: /** @type {string} */ (tsHash.digest("hex")),
3846
+ hash: /** @type {string} */ (hash.digest("hex"))
3847
+ };
3848
+ if (symlinks) result.symlinks = symlinks;
3849
+ return result;
3360
3850
  }
3361
- );
3362
- }
3851
+ },
3852
+ (err, _result) => {
3853
+ if (err) return callback(/** @type {WebpackError} */ (err));
3854
+ const result = /** @type {ContextTimestampAndHash} */ (_result);
3855
+ this._contextTshs.set(path, result);
3856
+ return callback(null, result);
3857
+ }
3858
+ );
3363
3859
  }
3364
3860
  }
3365
3861
 
3366
3862
  /**
3367
3863
  * @param {ContextTimestampAndHash} entry entry
3368
- * @param {function(Error=, ResolvedContextTimestampAndHash=): void} callback callback
3864
+ * @param {ProcessorCallback<ResolvedContextTimestampAndHash>} callback callback
3369
3865
  * @returns {void}
3370
3866
  */
3371
3867
  _resolveContextTsh(entry, callback) {
3868
+ /** @type {string[]} */
3372
3869
  const hashes = [];
3870
+ /** @type {string[]} */
3373
3871
  const tsHashes = [];
3374
3872
  let safeTime = 0;
3375
3873
  processAsyncTree(
3376
- entry.symlinks,
3874
+ /** @type {NonNullable<ContextHash["symlinks"]>} */ (entry.symlinks),
3377
3875
  10,
3378
3876
  (target, push, callback) => {
3379
3877
  this._getUnresolvedContextTsh(target, (err, entry) => {
@@ -3392,7 +3890,7 @@ class FileSystemInfo {
3392
3890
  });
3393
3891
  },
3394
3892
  err => {
3395
- if (err) return callback(err);
3893
+ if (err) return callback(/** @type {WebpackError} */ (err));
3396
3894
  const hash = createHash(this._hashFunction);
3397
3895
  const tsHash = createHash(this._hashFunction);
3398
3896
  hash.update(entry.hash);
@@ -3420,13 +3918,17 @@ class FileSystemInfo {
3420
3918
  );
3421
3919
  }
3422
3920
 
3921
+ /**
3922
+ * @type {Processor<string, Set<string>>}
3923
+ * @private
3924
+ */
3423
3925
  _getManagedItemDirectoryInfo(path, callback) {
3424
3926
  this.fs.readdir(path, (err, elements) => {
3425
3927
  if (err) {
3426
3928
  if (err.code === "ENOENT" || err.code === "ENOTDIR") {
3427
3929
  return callback(null, EMPTY_SET);
3428
3930
  }
3429
- return callback(err);
3931
+ return callback(/** @type {WebpackError} */ (err));
3430
3932
  }
3431
3933
  const set = new Set(
3432
3934
  /** @type {string[]} */ (elements).map(element =>
@@ -3437,16 +3939,20 @@ class FileSystemInfo {
3437
3939
  });
3438
3940
  }
3439
3941
 
3942
+ /**
3943
+ * @type {Processor<string, string>}
3944
+ * @private
3945
+ */
3440
3946
  _getManagedItemInfo(path, callback) {
3441
3947
  const dir = dirname(this.fs, path);
3442
3948
  this.managedItemDirectoryQueue.add(dir, (err, elements) => {
3443
3949
  if (err) {
3444
3950
  return callback(err);
3445
3951
  }
3446
- if (!elements.has(path)) {
3952
+ if (!(/** @type {Set<string>} */ (elements).has(path))) {
3447
3953
  // file or directory doesn't exist
3448
- this._managedItems.set(path, "missing");
3449
- return callback(null, "missing");
3954
+ this._managedItems.set(path, "*missing");
3955
+ return callback(null, "*missing");
3450
3956
  }
3451
3957
  // something exists
3452
3958
  // it may be a file or directory
@@ -3455,8 +3961,8 @@ class FileSystemInfo {
3455
3961
  (path.endsWith("/node_modules") || path.endsWith("\\node_modules"))
3456
3962
  ) {
3457
3963
  // we are only interested in existence of this special directory
3458
- this._managedItems.set(path, "exists");
3459
- return callback(null, "exists");
3964
+ this._managedItems.set(path, "*node_modules");
3965
+ return callback(null, "*node_modules");
3460
3966
  }
3461
3967
 
3462
3968
  // we assume it's a directory, as files shouldn't occur in managed paths
@@ -3468,27 +3974,36 @@ class FileSystemInfo {
3468
3974
  this.fs.readdir(path, (err, elements) => {
3469
3975
  if (
3470
3976
  !err &&
3471
- elements.length === 1 &&
3472
- elements[0] === "node_modules"
3977
+ /** @type {string[]} */ (elements).length === 1 &&
3978
+ /** @type {string[]} */ (elements)[0] === "node_modules"
3473
3979
  ) {
3474
- // This is only a grouping folder e. g. used by yarn
3980
+ // This is only a grouping folder e.g. used by yarn
3475
3981
  // we are only interested in existence of this special directory
3476
- this._managedItems.set(path, "nested");
3477
- return callback(null, "nested");
3982
+ this._managedItems.set(path, "*nested");
3983
+ return callback(null, "*nested");
3478
3984
  }
3479
- const problem = `Managed item ${path} isn't a directory or doesn't contain a package.json`;
3480
- this.logger.warn(problem);
3481
- return callback(new Error(problem));
3985
+ /** @type {Logger} */
3986
+ (this.logger).warn(
3987
+ `Managed item ${path} isn't a directory or doesn't contain a package.json (see snapshot.managedPaths option)`
3988
+ );
3989
+ return callback();
3482
3990
  });
3483
3991
  return;
3484
3992
  }
3485
- return callback(err);
3993
+ return callback(/** @type {WebpackError} */ (err));
3486
3994
  }
3487
3995
  let data;
3488
3996
  try {
3489
- data = JSON.parse(content.toString("utf-8"));
3490
- } catch (e) {
3491
- return callback(e);
3997
+ data = JSON.parse(/** @type {Buffer} */ (content).toString("utf-8"));
3998
+ } catch (parseErr) {
3999
+ return callback(/** @type {WebpackError} */ (parseErr));
4000
+ }
4001
+ if (!data.name) {
4002
+ /** @type {Logger} */
4003
+ (this.logger).warn(
4004
+ `${packageJsonPath} doesn't contain a "name" property (see snapshot.managedPaths option)`
4005
+ );
4006
+ return callback();
3492
4007
  }
3493
4008
  const info = `${data.name || ""}@${data.version || ""}`;
3494
4009
  this._managedItems.set(path, info);