webpack 5.108.4 → 5.109.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. package/bin/webpack.js +12 -0
  2. package/lib/APIPlugin.js +48 -29
  3. package/lib/CacheFacade.js +8 -0
  4. package/lib/ChunkGraph.js +17 -15
  5. package/lib/ChunkGroup.js +1 -0
  6. package/lib/CompatibilityPlugin.js +62 -29
  7. package/lib/Compilation.js +58 -6
  8. package/lib/ConstPlugin.js +11 -11
  9. package/lib/ContextModule.js +239 -6
  10. package/lib/ContextModuleFactory.js +139 -14
  11. package/lib/DefinePlugin.js +433 -112
  12. package/lib/Entrypoint.js +1 -1
  13. package/lib/ExportsInfo.js +22 -5
  14. package/lib/ExportsInfoApiPlugin.js +2 -2
  15. package/lib/ExternalModule.js +107 -5
  16. package/lib/ExternalModuleFactoryPlugin.js +20 -1
  17. package/lib/FileSystemInfo.js +256 -100
  18. package/lib/FlagDependencyUsagePlugin.js +33 -12
  19. package/lib/HotModuleReplacementPlugin.js +18 -15
  20. package/lib/InitFragment.js +20 -32
  21. package/lib/Module.js +3 -0
  22. package/lib/ModuleFilenameHelpers.js +2 -2
  23. package/lib/ModuleTypeConstants.js +8 -1
  24. package/lib/MultiCompiler.js +13 -2
  25. package/lib/MultiWatching.js +1 -0
  26. package/lib/NodeStuffPlugin.js +51 -33
  27. package/lib/NormalModule.js +175 -401
  28. package/lib/NormalModuleFactory.js +76 -2
  29. package/lib/ProgressPlugin.js +211 -119
  30. package/lib/ProvidePlugin.js +2 -2
  31. package/lib/RuntimeGlobals.js +47 -0
  32. package/lib/RuntimePlugin.js +67 -107
  33. package/lib/RuntimeTemplate.js +304 -16
  34. package/lib/Template.js +23 -3
  35. package/lib/UseStrictPlugin.js +1 -1
  36. package/lib/WebpackIsIncludedPlugin.js +1 -1
  37. package/lib/WebpackOptionsApply.js +24 -19
  38. package/lib/asset/AssetGenerator.js +110 -28
  39. package/lib/asset/AssetModulesPlugin.js +92 -2
  40. package/lib/asset/WebManifestGenerator.js +164 -0
  41. package/lib/asset/WebManifestParser.js +130 -0
  42. package/lib/async-modules/AwaitDependenciesInitFragment.js +14 -4
  43. package/lib/async-modules/isGeneratorLowered.js +26 -0
  44. package/lib/cache/PackFileCacheStrategy.js +9 -3
  45. package/lib/config/browserslistTargetHandler.js +40 -0
  46. package/lib/config/defaults.js +219 -29
  47. package/lib/config/normalization.js +26 -0
  48. package/lib/config/target.js +9 -1
  49. package/lib/container/HoistContainerReferencesPlugin.js +47 -55
  50. package/lib/css/CssGenerator.js +40 -31
  51. package/lib/css/CssLoadingRuntimeModule.js +5 -1
  52. package/lib/css/CssModulesPlugin.js +13 -0
  53. package/lib/css/CssParser.js +729 -313
  54. package/lib/css/syntax.js +1371 -861
  55. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +6 -6
  56. package/lib/dependencies/AMDPlugin.js +2 -2
  57. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +13 -13
  58. package/lib/dependencies/CommonJsDependencyHelpers.js +39 -0
  59. package/lib/dependencies/CommonJsExportRequireDependency.js +19 -0
  60. package/lib/dependencies/CommonJsExportsDependency.js +47 -2
  61. package/lib/dependencies/CommonJsExportsParserPlugin.js +10 -10
  62. package/lib/dependencies/CommonJsImportsParserPlugin.js +18 -18
  63. package/lib/dependencies/CommonJsPlugin.js +2 -2
  64. package/lib/dependencies/CommonJsRequireDependency.js +26 -1
  65. package/lib/dependencies/CommonJsSelfReferenceDependency.js +32 -1
  66. package/lib/dependencies/ContextDependencyHelpers.js +3 -3
  67. package/lib/dependencies/CreateRequireParserPlugin.js +6 -6
  68. package/lib/dependencies/CssIcssExportDependency.js +162 -71
  69. package/lib/dependencies/CssUrlDependency.js +35 -4
  70. package/lib/dependencies/ExternalModuleInitFragmentDependency.js +2 -2
  71. package/lib/dependencies/HarmonyCompatibilityDependency.js +32 -14
  72. package/lib/dependencies/HarmonyDetectionParserPlugin.js +43 -13
  73. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +2 -1
  74. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +7 -19
  75. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +17 -9
  76. package/lib/dependencies/HarmonyImportDependency.js +13 -2
  77. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +11 -11
  78. package/lib/dependencies/HarmonyImportSpecifierDependency.js +10 -7
  79. package/lib/dependencies/HarmonyModulesPlugin.js +6 -0
  80. package/lib/dependencies/HarmonyTopLevelThisParserPlugin.js +1 -1
  81. package/lib/dependencies/HtmlEntryDependency.js +797 -172
  82. package/lib/dependencies/HtmlSourceDependency.js +26 -0
  83. package/lib/dependencies/ImportDependency.js +43 -1
  84. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +31 -18
  85. package/lib/dependencies/ImportMetaContextPlugin.js +38 -7
  86. package/lib/dependencies/ImportMetaGlobDependency.js +81 -0
  87. package/lib/dependencies/ImportMetaGlobDependencyParserPlugin.js +78 -0
  88. package/lib/dependencies/ImportMetaGlobHelpers.js +660 -0
  89. package/lib/dependencies/ImportMetaPlugin.js +532 -180
  90. package/lib/dependencies/ImportMetaResolveDependency.js +90 -0
  91. package/lib/dependencies/ImportParserPlugin.js +80 -17
  92. package/lib/dependencies/ImportPhase.js +10 -8
  93. package/lib/dependencies/LoaderPlugin.js +5 -1
  94. package/lib/dependencies/RequireContextDependencyParserPlugin.js +1 -1
  95. package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +3 -6
  96. package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +4 -11
  97. package/lib/dependencies/SystemPlugin.js +2 -4
  98. package/lib/dependencies/TopLevelAwaitDependency.js +93 -0
  99. package/lib/dependencies/URLDependency.js +141 -21
  100. package/lib/dependencies/{WorkerPlugin.js → WorkerAndWorkletPlugin.js} +324 -112
  101. package/lib/dependencies/WorkerDependency.js +86 -18
  102. package/lib/dependencies/WorkletDependency.js +278 -0
  103. package/lib/dll/DelegatedModuleFactoryPlugin.js +19 -0
  104. package/lib/errors/EnvironmentNotSupportAsyncWarning.js +1 -1
  105. package/lib/errors/LoaderLoadingError.js +20 -0
  106. package/lib/errors/ModuleParseError.js +39 -22
  107. package/lib/errors/NodeStuffInWebError.js +1 -1
  108. package/lib/esm/ModuleChunkFormatPlugin.js +47 -14
  109. package/lib/esm/ModuleChunkLoadingPlugin.js +8 -1
  110. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +29 -1
  111. package/lib/hmr/lazyCompilationBackend.js +51 -12
  112. package/lib/html/HtmlGenerator.js +907 -15
  113. package/lib/html/HtmlModule.js +2 -2
  114. package/lib/html/HtmlModulesPlugin.js +610 -166
  115. package/lib/html/HtmlParser.js +603 -247
  116. package/lib/html/favicon.svg +1 -0
  117. package/lib/html/syntax.js +3451 -2762
  118. package/lib/ids/IdHelpers.js +25 -11
  119. package/lib/index.js +6 -0
  120. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +4 -5
  121. package/lib/javascript/BasicEvaluatedExpression.js +366 -48
  122. package/lib/javascript/JavascriptGenerator.js +197 -49
  123. package/lib/javascript/JavascriptModulesPlugin.js +178 -24
  124. package/lib/javascript/JavascriptParser.js +704 -355
  125. package/lib/javascript/JavascriptParserHelpers.js +3 -6
  126. package/lib/javascript/syntax.js +5037 -0
  127. package/lib/library/ModuleLibraryPlugin.js +38 -1
  128. package/lib/loaders/LoaderRunner.js +714 -0
  129. package/lib/loaders/loadLoader.js +100 -0
  130. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +29 -2
  131. package/lib/node/ReadFileCompileWasmPlugin.js +24 -2
  132. package/lib/optimize/AggressiveMergingPlugin.js +19 -15
  133. package/lib/optimize/ConcatenatedModule.js +139 -31
  134. package/lib/optimize/FlagIncludedChunksPlugin.js +13 -3
  135. package/lib/optimize/InnerGraphPlugin.js +50 -30
  136. package/lib/optimize/ModuleConcatenationPlugin.js +139 -24
  137. package/lib/optimize/SideEffectsFlagPlugin.js +86 -43
  138. package/lib/optimize/SplitChunksPlugin.js +146 -44
  139. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +15 -0
  140. package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +24 -13
  141. package/lib/prefetch/ResourceHintPlugin.js +687 -0
  142. package/lib/prefetch/ResourceHintRuntimeModule.js +149 -0
  143. package/lib/prefetch/StartupAssetHintRuntimeModule.js +210 -0
  144. package/lib/prefetch/parseResourceHintOptions.js +103 -0
  145. package/lib/rules/RuleSetCompiler.js +114 -0
  146. package/lib/runtime/AsyncModuleGeneratorRuntimeModule.js +56 -0
  147. package/lib/runtime/AsyncModuleRuntimeModule.js +24 -8
  148. package/lib/runtime/AutoPublicPathRuntimeModule.js +7 -1
  149. package/lib/runtime/CommonJsWrapRuntimeModule.js +37 -0
  150. package/lib/runtime/GetWorkletBootstrapRuntimeModule.js +59 -0
  151. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +204 -8
  152. package/lib/runtime/SetAnonymousDefaultNameRuntimeModule.js +4 -1
  153. package/lib/schemes/HttpUriPlugin.js +40 -1
  154. package/lib/schemes/VirtualUrlPlugin.js +1 -2
  155. package/lib/serialization/BinaryMiddleware.js +270 -938
  156. package/lib/serialization/FileMiddleware.js +29 -3
  157. package/lib/stats/DefaultStatsFactoryPlugin.js +229 -194
  158. package/lib/stats/DefaultStatsPresetPlugin.js +2 -0
  159. package/lib/stats/DefaultStatsPrinterPlugin.js +36 -168
  160. package/lib/stats/StatsFactory.js +46 -17
  161. package/lib/url/URLParserPlugin.js +66 -13
  162. package/lib/util/AsyncQueue.js +122 -72
  163. package/lib/util/SetHelpers.js +1 -1
  164. package/lib/util/StackedMap.js +122 -48
  165. package/lib/util/binarySearchBounds.js +2 -2
  166. package/lib/util/concatenate.js +40 -14
  167. package/lib/util/createHooksRegistry.js +13 -5
  168. package/lib/util/dataURL.js +2 -2
  169. package/lib/util/deterministicGrouping.js +7 -5
  170. package/lib/util/formatSize.js +6 -2
  171. package/lib/util/globUtils.js +710 -0
  172. package/lib/util/identifier.js +23 -6
  173. package/lib/util/implicitTypeLoaderFallback.js +62 -0
  174. package/lib/util/internalSerializables.js +88 -71
  175. package/lib/util/magicComment.js +121 -25
  176. package/lib/util/numberHash.js +2 -2
  177. package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +24 -18
  178. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +33 -22
  179. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +79 -16
  180. package/lib/web/FetchCompileAsyncWasmPlugin.js +19 -0
  181. package/lib/web/FetchCompileWasmPlugin.js +14 -0
  182. package/lib/web/JsonpChunkLoadingRuntimeModule.js +2 -0
  183. package/lib/webpack.js +65 -0
  184. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +3 -0
  185. package/module.d.ts +21 -0
  186. package/package.json +12 -11
  187. package/schemas/WebpackOptions.check.js +1 -1
  188. package/schemas/WebpackOptions.json +759 -36
  189. package/schemas/plugins/HtmlParserOptions.check.js +1 -1
  190. package/schemas/plugins/ProgressPlugin.check.js +1 -1
  191. package/schemas/plugins/ProgressPlugin.json +17 -1
  192. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  193. package/schemas/plugins/container/ContainerReferencePlugin.json +1 -0
  194. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  195. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  196. package/schemas/plugins/container/ModuleFederationPlugin.json +1 -0
  197. package/schemas/plugins/css/CssAutoOrModuleParserOptions.check.js +1 -1
  198. package/schemas/plugins/css/CssModuleParserOptions.check.js +1 -1
  199. package/schemas/plugins/css/CssParserOptions.check.js +1 -1
  200. package/types.d.ts +1212 -99
@@ -297,6 +297,22 @@ class SnapshotIterable {
297
297
  /** @typedef {Set<string>} ManagedMissing */
298
298
  /** @typedef {Set<Snapshot>} Children */
299
299
 
300
+ // `Snapshot._flags` bit for each optional field. Serialized as a whole integer,
301
+ // so these values are a persisted-cache format contract — never renumber them.
302
+ const SNAPSHOT_FLAG_START_TIME = 1;
303
+ const SNAPSHOT_FLAG_FILE_TIMESTAMPS = 2;
304
+ const SNAPSHOT_FLAG_FILE_HASHES = 4;
305
+ const SNAPSHOT_FLAG_FILE_TSHS = 8;
306
+ const SNAPSHOT_FLAG_CONTEXT_TIMESTAMPS = 0x10;
307
+ const SNAPSHOT_FLAG_CONTEXT_HASHES = 0x20;
308
+ const SNAPSHOT_FLAG_CONTEXT_TSHS = 0x40;
309
+ const SNAPSHOT_FLAG_MISSING_EXISTENCE = 0x80;
310
+ const SNAPSHOT_FLAG_MANAGED_ITEM_INFO = 0x100;
311
+ const SNAPSHOT_FLAG_MANAGED_FILES = 0x200;
312
+ const SNAPSHOT_FLAG_MANAGED_CONTEXTS = 0x400;
313
+ const SNAPSHOT_FLAG_MANAGED_MISSING = 0x800;
314
+ const SNAPSHOT_FLAG_CHILDREN = 0x1000;
315
+
300
316
  class Snapshot {
301
317
  constructor() {
302
318
  /** @type {number} */
@@ -336,7 +352,7 @@ class Snapshot {
336
352
  }
337
353
 
338
354
  hasStartTime() {
339
- return (this._flags & 1) !== 0;
355
+ return (this._flags & SNAPSHOT_FLAG_START_TIME) !== 0;
340
356
  }
341
357
 
342
358
  /**
@@ -344,7 +360,7 @@ class Snapshot {
344
360
  * @param {number} value start value
345
361
  */
346
362
  setStartTime(value) {
347
- this._flags |= 1;
363
+ this._flags |= SNAPSHOT_FLAG_START_TIME;
348
364
  this.startTime = value;
349
365
  }
350
366
 
@@ -375,7 +391,7 @@ class Snapshot {
375
391
  }
376
392
 
377
393
  hasFileTimestamps() {
378
- return (this._flags & 2) !== 0;
394
+ return (this._flags & SNAPSHOT_FLAG_FILE_TIMESTAMPS) !== 0;
379
395
  }
380
396
 
381
397
  /**
@@ -383,12 +399,12 @@ class Snapshot {
383
399
  * @param {FileTimestamps} value file timestamps
384
400
  */
385
401
  setFileTimestamps(value) {
386
- this._flags |= 2;
402
+ this._flags |= SNAPSHOT_FLAG_FILE_TIMESTAMPS;
387
403
  this.fileTimestamps = value;
388
404
  }
389
405
 
390
406
  hasFileHashes() {
391
- return (this._flags & 4) !== 0;
407
+ return (this._flags & SNAPSHOT_FLAG_FILE_HASHES) !== 0;
392
408
  }
393
409
 
394
410
  /**
@@ -396,12 +412,12 @@ class Snapshot {
396
412
  * @param {FileHashes} value file hashes
397
413
  */
398
414
  setFileHashes(value) {
399
- this._flags |= 4;
415
+ this._flags |= SNAPSHOT_FLAG_FILE_HASHES;
400
416
  this.fileHashes = value;
401
417
  }
402
418
 
403
419
  hasFileTshs() {
404
- return (this._flags & 8) !== 0;
420
+ return (this._flags & SNAPSHOT_FLAG_FILE_TSHS) !== 0;
405
421
  }
406
422
 
407
423
  /**
@@ -409,12 +425,12 @@ class Snapshot {
409
425
  * @param {FileTshs} value file tshs
410
426
  */
411
427
  setFileTshs(value) {
412
- this._flags |= 8;
428
+ this._flags |= SNAPSHOT_FLAG_FILE_TSHS;
413
429
  this.fileTshs = value;
414
430
  }
415
431
 
416
432
  hasContextTimestamps() {
417
- return (this._flags & 0x10) !== 0;
433
+ return (this._flags & SNAPSHOT_FLAG_CONTEXT_TIMESTAMPS) !== 0;
418
434
  }
419
435
 
420
436
  /**
@@ -422,12 +438,12 @@ class Snapshot {
422
438
  * @param {ContextTimestamps} value context timestamps
423
439
  */
424
440
  setContextTimestamps(value) {
425
- this._flags |= 0x10;
441
+ this._flags |= SNAPSHOT_FLAG_CONTEXT_TIMESTAMPS;
426
442
  this.contextTimestamps = value;
427
443
  }
428
444
 
429
445
  hasContextHashes() {
430
- return (this._flags & 0x20) !== 0;
446
+ return (this._flags & SNAPSHOT_FLAG_CONTEXT_HASHES) !== 0;
431
447
  }
432
448
 
433
449
  /**
@@ -435,12 +451,12 @@ class Snapshot {
435
451
  * @param {ContextHashes} value context hashes
436
452
  */
437
453
  setContextHashes(value) {
438
- this._flags |= 0x20;
454
+ this._flags |= SNAPSHOT_FLAG_CONTEXT_HASHES;
439
455
  this.contextHashes = value;
440
456
  }
441
457
 
442
458
  hasContextTshs() {
443
- return (this._flags & 0x40) !== 0;
459
+ return (this._flags & SNAPSHOT_FLAG_CONTEXT_TSHS) !== 0;
444
460
  }
445
461
 
446
462
  /**
@@ -448,12 +464,12 @@ class Snapshot {
448
464
  * @param {ContextTshs} value context tshs
449
465
  */
450
466
  setContextTshs(value) {
451
- this._flags |= 0x40;
467
+ this._flags |= SNAPSHOT_FLAG_CONTEXT_TSHS;
452
468
  this.contextTshs = value;
453
469
  }
454
470
 
455
471
  hasMissingExistence() {
456
- return (this._flags & 0x80) !== 0;
472
+ return (this._flags & SNAPSHOT_FLAG_MISSING_EXISTENCE) !== 0;
457
473
  }
458
474
 
459
475
  /**
@@ -461,12 +477,12 @@ class Snapshot {
461
477
  * @param {MissingExistence} value context tshs
462
478
  */
463
479
  setMissingExistence(value) {
464
- this._flags |= 0x80;
480
+ this._flags |= SNAPSHOT_FLAG_MISSING_EXISTENCE;
465
481
  this.missingExistence = value;
466
482
  }
467
483
 
468
484
  hasManagedItemInfo() {
469
- return (this._flags & 0x100) !== 0;
485
+ return (this._flags & SNAPSHOT_FLAG_MANAGED_ITEM_INFO) !== 0;
470
486
  }
471
487
 
472
488
  /**
@@ -474,12 +490,12 @@ class Snapshot {
474
490
  * @param {ManagedItemInfo} value managed item info
475
491
  */
476
492
  setManagedItemInfo(value) {
477
- this._flags |= 0x100;
493
+ this._flags |= SNAPSHOT_FLAG_MANAGED_ITEM_INFO;
478
494
  this.managedItemInfo = value;
479
495
  }
480
496
 
481
497
  hasManagedFiles() {
482
- return (this._flags & 0x200) !== 0;
498
+ return (this._flags & SNAPSHOT_FLAG_MANAGED_FILES) !== 0;
483
499
  }
484
500
 
485
501
  /**
@@ -487,12 +503,12 @@ class Snapshot {
487
503
  * @param {ManagedFiles} value managed files
488
504
  */
489
505
  setManagedFiles(value) {
490
- this._flags |= 0x200;
506
+ this._flags |= SNAPSHOT_FLAG_MANAGED_FILES;
491
507
  this.managedFiles = value;
492
508
  }
493
509
 
494
510
  hasManagedContexts() {
495
- return (this._flags & 0x400) !== 0;
511
+ return (this._flags & SNAPSHOT_FLAG_MANAGED_CONTEXTS) !== 0;
496
512
  }
497
513
 
498
514
  /**
@@ -500,12 +516,12 @@ class Snapshot {
500
516
  * @param {ManagedContexts} value managed contexts
501
517
  */
502
518
  setManagedContexts(value) {
503
- this._flags |= 0x400;
519
+ this._flags |= SNAPSHOT_FLAG_MANAGED_CONTEXTS;
504
520
  this.managedContexts = value;
505
521
  }
506
522
 
507
523
  hasManagedMissing() {
508
- return (this._flags & 0x800) !== 0;
524
+ return (this._flags & SNAPSHOT_FLAG_MANAGED_MISSING) !== 0;
509
525
  }
510
526
 
511
527
  /**
@@ -513,12 +529,12 @@ class Snapshot {
513
529
  * @param {ManagedMissing} value managed missing
514
530
  */
515
531
  setManagedMissing(value) {
516
- this._flags |= 0x800;
532
+ this._flags |= SNAPSHOT_FLAG_MANAGED_MISSING;
517
533
  this.managedMissing = value;
518
534
  }
519
535
 
520
536
  hasChildren() {
521
- return (this._flags & 0x1000) !== 0;
537
+ return (this._flags & SNAPSHOT_FLAG_CHILDREN) !== 0;
522
538
  }
523
539
 
524
540
  /**
@@ -526,7 +542,7 @@ class Snapshot {
526
542
  * @param {Children} value children
527
543
  */
528
544
  setChildren(value) {
529
- this._flags |= 0x1000;
545
+ this._flags |= SNAPSHOT_FLAG_CHILDREN;
530
546
  this.children = value;
531
547
  }
532
548
 
@@ -1221,6 +1237,58 @@ const addAll = (source, target) => {
1221
1237
 
1222
1238
  const getEsModuleLexer = memoize(() => require("es-module-lexer"));
1223
1239
 
1240
+ const getAcorn = memoize(/* istanbul ignore next */ () => require("acorn"));
1241
+
1242
+ // Bun doesn't populate `require.cache` `module.children`, so the CJS build-dependency
1243
+ // walk needs a source-parsing fallback there. Node/Deno populate it — never pay for it.
1244
+ const IS_BUN = Boolean(process.versions.bun);
1245
+
1246
+ /**
1247
+ * Collects static `require("literal")` specifiers from CommonJS source. Used as a
1248
+ * fallback where `require.cache` children aren't populated (e.g. Bun), so build
1249
+ * dependencies of a CJS file are still tracked. Dynamic requires can't be seen here.
1250
+ * @param {string} source source
1251
+ * @returns {Set<string>} required specifiers
1252
+ */
1253
+ // Bun-only: exercised by BuildDependencies.longtest under the Bun CI job (no coverage upload).
1254
+ /* istanbul ignore next */
1255
+ const parseCjsRequires = (source) => {
1256
+ /** @type {Set<string>} */
1257
+ const requires = new Set();
1258
+ const ast = getAcorn().parse(source, {
1259
+ ecmaVersion: "latest",
1260
+ sourceType: "script",
1261
+ allowReturnOutsideFunction: true
1262
+ });
1263
+ /** @type {EXPECTED_ANY[]} */
1264
+ const stack = [ast];
1265
+ while (stack.length > 0) {
1266
+ const node = stack.pop();
1267
+ if (!node || typeof node.type !== "string") continue;
1268
+ if (
1269
+ node.type === "CallExpression" &&
1270
+ node.callee.type === "Identifier" &&
1271
+ node.callee.name === "require" &&
1272
+ node.arguments.length === 1 &&
1273
+ node.arguments[0].type === "Literal" &&
1274
+ typeof node.arguments[0].value === "string"
1275
+ ) {
1276
+ requires.add(node.arguments[0].value);
1277
+ }
1278
+ for (const key of Object.keys(node)) {
1279
+ const value = node[key];
1280
+ if (Array.isArray(value)) {
1281
+ for (const item of value) {
1282
+ if (item && typeof item.type === "string") stack.push(item);
1283
+ }
1284
+ } else if (value && typeof value.type === "string") {
1285
+ stack.push(value);
1286
+ }
1287
+ }
1288
+ }
1289
+ return requires;
1290
+ };
1291
+
1224
1292
  /** @typedef {Set<string>} LoggedPaths */
1225
1293
 
1226
1294
  /** @typedef {FileSystemInfoEntry | ExistenceOnlyTimeEntry | "ignore" | null} FileTimestamp */
@@ -1243,6 +1311,17 @@ const isExistenceOnly = (entry) => {
1243
1311
  );
1244
1312
  };
1245
1313
 
1314
+ /**
1315
+ * Watchpack directory entries may carry `safeTime` / `timestamp` but never
1316
+ * `timestampHash`; such object caches cannot back snapshot checks or symlink walks.
1317
+ * @param {ContextFileSystemInfoEntry | null | "ignore" | undefined} entry cache entry
1318
+ * @returns {boolean} true when a non-null object entry lacks `timestampHash`
1319
+ */
1320
+ const contextCacheEntryLacksTimestampHash = (entry) =>
1321
+ entry !== null &&
1322
+ typeof entry === "object" &&
1323
+ /** @type {ContextFileSystemInfoEntry} */ (entry).timestampHash === undefined;
1324
+
1246
1325
  /** @typedef {(err?: WebpackError | null, result?: boolean) => void} CheckSnapshotValidCallback */
1247
1326
 
1248
1327
  /**
@@ -1367,6 +1446,9 @@ class FileSystemInfo {
1367
1446
  this._contextTshs = new Map();
1368
1447
  /** @type {Map<string, string>} */
1369
1448
  this._managedItems = new Map();
1449
+ // memoized checkManaged results: 0 = not managed, 1 = immutable, string = managed item
1450
+ /** @type {Map<string, 0 | 1 | string>} */
1451
+ this._pathClassificationCache = new Map();
1370
1452
  /** @type {AsyncQueue<string, string, FileSystemInfoEntry>} */
1371
1453
  this.fileTimestampQueue = new AsyncQueue({
1372
1454
  name: "file timestamp",
@@ -1596,7 +1678,7 @@ class FileSystemInfo {
1596
1678
  this._contextHashes.clear();
1597
1679
  this._contextTshs.clear();
1598
1680
  this._managedItems.clear();
1599
- this._managedItems.clear();
1681
+ this._pathClassificationCache.clear();
1600
1682
 
1601
1683
  this._cachedDeprecatedFileTimestamps = undefined;
1602
1684
  this._cachedDeprecatedContextTimestamps = undefined;
@@ -1705,7 +1787,13 @@ class FileSystemInfo {
1705
1787
  */
1706
1788
  _getUnresolvedContextTimestamp(path, callback) {
1707
1789
  const cache = this._contextTimestamps.get(path);
1708
- if (cache !== undefined && !isExistenceOnly(cache)) {
1790
+ if (
1791
+ cache !== undefined &&
1792
+ !isExistenceOnly(cache) &&
1793
+ !contextCacheEntryLacksTimestampHash(
1794
+ /** @type {ContextFileSystemInfoEntry | null | "ignore"} */ (cache)
1795
+ )
1796
+ ) {
1709
1797
  return callback(
1710
1798
  null,
1711
1799
  /** @type {ContextFileSystemInfoEntry | "ignore" | null} */ (cache)
@@ -2193,6 +2281,38 @@ class FileSystemInfo {
2193
2281
  });
2194
2282
  }
2195
2283
  }
2284
+ // On Bun the children array is empty (unpopulated), so recover the
2285
+ // static require() specifiers by parsing the source; Node/Deno don't.
2286
+ /* istanbul ignore next */
2287
+ if (IS_BUN && module.children.length === 0) {
2288
+ this.fs.readFile(path, (err, content) => {
2289
+ if (err) return callback(err);
2290
+ try {
2291
+ const context = dirname(this.fs, path);
2292
+ const source = /** @type {Buffer} */ (content).toString();
2293
+ /** @type {Set<string>} */
2294
+ const added = new Set();
2295
+ for (const dependency of parseCjsRequires(source)) {
2296
+ if (dependency.startsWith("node:")) continue;
2297
+ if (builtinModules.has(dependency)) continue;
2298
+ if (added.has(dependency)) continue;
2299
+ push({
2300
+ type: RBDT_RESOLVE_CJS_FILE,
2301
+ context,
2302
+ path: dependency,
2303
+ // Best effort: tolerate specifiers that don't resolve.
2304
+ expected: false,
2305
+ issuer: job
2306
+ });
2307
+ added.add(dependency);
2308
+ }
2309
+ } catch (_err) {
2310
+ // Source we can't parse as CommonJS — ignore its dependencies.
2311
+ }
2312
+ process.nextTick(callback);
2313
+ });
2314
+ break;
2315
+ }
2196
2316
  } else if (supportsEsm && /\.m?js$/.test(path)) {
2197
2317
  if (!this._warnAboutExperimentalEsmTracking) {
2198
2318
  logger.log(
@@ -2460,30 +2580,29 @@ class FileSystemInfo {
2460
2580
  * @returns {void}
2461
2581
  */
2462
2582
  createSnapshot(startTime, files, directories, missing, options, callback) {
2463
- /** @type {FileTimestamps} */
2464
- const fileTimestamps = new Map();
2465
- /** @type {FileHashes} */
2466
- const fileHashes = new Map();
2467
- /** @type {FileTshs} */
2468
- const fileTshs = new Map();
2469
- /** @type {ContextTimestamps} */
2470
- const contextTimestamps = new Map();
2471
- /** @type {ContextHashes} */
2472
- const contextHashes = new Map();
2473
- /** @type {ContextTshs} */
2474
- const contextTshs = new Map();
2475
- /** @type {MissingExistence} */
2476
- const missingExistence = new Map();
2477
- /** @type {ManagedItemInfo} */
2478
- const managedItemInfo = new Map();
2583
+ // collections are allocated lazily to avoid per-snapshot garbage for unused modes
2584
+ /** @type {FileTimestamps | undefined} */
2585
+ let fileTimestamps;
2586
+ /** @type {FileHashes | undefined} */
2587
+ let fileHashes;
2588
+ /** @type {FileTshs | undefined} */
2589
+ let fileTshs;
2590
+ /** @type {ContextTimestamps | undefined} */
2591
+ let contextTimestamps;
2592
+ /** @type {ContextHashes | undefined} */
2593
+ let contextHashes;
2594
+ /** @type {ContextTshs | undefined} */
2595
+ let contextTshs;
2596
+ /** @type {MissingExistence | undefined} */
2597
+ let missingExistence;
2598
+ /** @type {ManagedItemInfo | undefined} */
2599
+ let managedItemInfo;
2479
2600
  /** @type {ManagedFiles} */
2480
2601
  const managedFiles = new Set();
2481
2602
  /** @type {ManagedContexts} */
2482
2603
  const managedContexts = new Set();
2483
2604
  /** @type {ManagedMissing} */
2484
2605
  const managedMissing = new Set();
2485
- /** @type {Children} */
2486
- const children = new Set();
2487
2606
 
2488
2607
  const snapshot = new Snapshot();
2489
2608
  if (startTime) snapshot.setStartTime(startTime);
@@ -2497,28 +2616,28 @@ class FileSystemInfo {
2497
2616
  let jobs = 1;
2498
2617
  const jobDone = () => {
2499
2618
  if (--jobs === 0) {
2500
- if (fileTimestamps.size !== 0) {
2619
+ if (fileTimestamps !== undefined && fileTimestamps.size !== 0) {
2501
2620
  snapshot.setFileTimestamps(fileTimestamps);
2502
2621
  }
2503
- if (fileHashes.size !== 0) {
2622
+ if (fileHashes !== undefined && fileHashes.size !== 0) {
2504
2623
  snapshot.setFileHashes(fileHashes);
2505
2624
  }
2506
- if (fileTshs.size !== 0) {
2625
+ if (fileTshs !== undefined && fileTshs.size !== 0) {
2507
2626
  snapshot.setFileTshs(fileTshs);
2508
2627
  }
2509
- if (contextTimestamps.size !== 0) {
2628
+ if (contextTimestamps !== undefined && contextTimestamps.size !== 0) {
2510
2629
  snapshot.setContextTimestamps(contextTimestamps);
2511
2630
  }
2512
- if (contextHashes.size !== 0) {
2631
+ if (contextHashes !== undefined && contextHashes.size !== 0) {
2513
2632
  snapshot.setContextHashes(contextHashes);
2514
2633
  }
2515
- if (contextTshs.size !== 0) {
2634
+ if (contextTshs !== undefined && contextTshs.size !== 0) {
2516
2635
  snapshot.setContextTshs(contextTshs);
2517
2636
  }
2518
- if (missingExistence.size !== 0) {
2637
+ if (missingExistence !== undefined && missingExistence.size !== 0) {
2519
2638
  snapshot.setMissingExistence(missingExistence);
2520
2639
  }
2521
- if (managedItemInfo.size !== 0) {
2640
+ if (managedItemInfo !== undefined && managedItemInfo.size !== 0) {
2522
2641
  snapshot.setManagedItemInfo(managedItemInfo);
2523
2642
  }
2524
2643
  this._managedFilesOptimization.optimize(snapshot, managedFiles);
@@ -2533,9 +2652,6 @@ class FileSystemInfo {
2533
2652
  if (managedMissing.size !== 0) {
2534
2653
  snapshot.setManagedMissing(managedMissing);
2535
2654
  }
2536
- if (children.size !== 0) {
2537
- snapshot.setChildren(children);
2538
- }
2539
2655
  this._snapshotCache.set(snapshot, true);
2540
2656
  this._statCreatedSnapshots++;
2541
2657
 
@@ -2549,6 +2665,7 @@ class FileSystemInfo {
2549
2665
  callback(null, null);
2550
2666
  }
2551
2667
  };
2668
+ const classificationCache = this._pathClassificationCache;
2552
2669
  /**
2553
2670
  * Checks true when managed.
2554
2671
  * @param {string} path path
@@ -2556,20 +2673,36 @@ class FileSystemInfo {
2556
2673
  * @returns {boolean} true when managed
2557
2674
  */
2558
2675
  const checkManaged = (path, managedSet) => {
2676
+ // classification is a pure function of the path, so it's shared across snapshots
2677
+ const cached = classificationCache.get(path);
2678
+ if (cached !== undefined) {
2679
+ if (cached === 0) return false;
2680
+ if (cached !== 1) managedItems.add(cached);
2681
+ managedSet.add(path);
2682
+ return true;
2683
+ }
2559
2684
  for (const unmanagedPath of this.unmanagedPathsRegExps) {
2560
- if (unmanagedPath.test(path)) return false;
2685
+ if (unmanagedPath.test(path)) {
2686
+ classificationCache.set(path, 0);
2687
+ return false;
2688
+ }
2561
2689
  }
2562
2690
  for (const unmanagedPath of this.unmanagedPathsWithSlash) {
2563
- if (path.startsWith(unmanagedPath)) return false;
2691
+ if (path.startsWith(unmanagedPath)) {
2692
+ classificationCache.set(path, 0);
2693
+ return false;
2694
+ }
2564
2695
  }
2565
2696
  for (const immutablePath of this.immutablePathsRegExps) {
2566
2697
  if (immutablePath.test(path)) {
2698
+ classificationCache.set(path, 1);
2567
2699
  managedSet.add(path);
2568
2700
  return true;
2569
2701
  }
2570
2702
  }
2571
2703
  for (const immutablePath of this.immutablePathsWithSlash) {
2572
2704
  if (path.startsWith(immutablePath)) {
2705
+ classificationCache.set(path, 1);
2573
2706
  managedSet.add(path);
2574
2707
  return true;
2575
2708
  }
@@ -2579,6 +2712,7 @@ class FileSystemInfo {
2579
2712
  if (match) {
2580
2713
  const managedItem = getManagedItem(match[1], path);
2581
2714
  if (managedItem) {
2715
+ classificationCache.set(path, managedItem);
2582
2716
  managedItems.add(managedItem);
2583
2717
  managedSet.add(path);
2584
2718
  return true;
@@ -2589,12 +2723,14 @@ class FileSystemInfo {
2589
2723
  if (path.startsWith(managedPath)) {
2590
2724
  const managedItem = getManagedItem(managedPath, path);
2591
2725
  if (managedItem) {
2726
+ classificationCache.set(path, managedItem);
2592
2727
  managedItems.add(managedItem);
2593
2728
  managedSet.add(path);
2594
2729
  return true;
2595
2730
  }
2596
2731
  }
2597
2732
  }
2733
+ classificationCache.set(path, 0);
2598
2734
  return false;
2599
2735
  };
2600
2736
  /**
@@ -2620,12 +2756,14 @@ class FileSystemInfo {
2620
2756
  return;
2621
2757
  }
2622
2758
  switch (mode) {
2623
- case 3:
2759
+ case 3: {
2624
2760
  this._fileTshsOptimization.optimize(snapshot, capturedFiles);
2761
+ if (fileTshs === undefined) fileTshs = new Map();
2762
+ const fileTshsMap = fileTshs;
2625
2763
  for (const path of capturedFiles) {
2626
2764
  const cache = this._fileTshs.get(path);
2627
2765
  if (cache !== undefined) {
2628
- fileTshs.set(path, cache);
2766
+ fileTshsMap.set(path, cache);
2629
2767
  } else {
2630
2768
  jobs++;
2631
2769
  this._getFileTimestampAndHash(path, (err, entry) => {
@@ -2637,19 +2775,25 @@ class FileSystemInfo {
2637
2775
  }
2638
2776
  jobError();
2639
2777
  } else {
2640
- fileTshs.set(path, /** @type {TimestampAndHash} */ (entry));
2778
+ fileTshsMap.set(
2779
+ path,
2780
+ /** @type {TimestampAndHash} */ (entry)
2781
+ );
2641
2782
  jobDone();
2642
2783
  }
2643
2784
  });
2644
2785
  }
2645
2786
  }
2646
2787
  break;
2647
- case 2:
2788
+ }
2789
+ case 2: {
2648
2790
  this._fileHashesOptimization.optimize(snapshot, capturedFiles);
2791
+ if (fileHashes === undefined) fileHashes = new Map();
2792
+ const fileHashesMap = fileHashes;
2649
2793
  for (const path of capturedFiles) {
2650
2794
  const cache = this._fileHashes.get(path);
2651
2795
  if (cache !== undefined) {
2652
- fileHashes.set(path, cache);
2796
+ fileHashesMap.set(path, cache);
2653
2797
  } else {
2654
2798
  jobs++;
2655
2799
  this.fileHashQueue.add(path, (err, entry) => {
@@ -2661,20 +2805,23 @@ class FileSystemInfo {
2661
2805
  }
2662
2806
  jobError();
2663
2807
  } else {
2664
- fileHashes.set(path, /** @type {string} */ (entry));
2808
+ fileHashesMap.set(path, /** @type {string} */ (entry));
2665
2809
  jobDone();
2666
2810
  }
2667
2811
  });
2668
2812
  }
2669
2813
  }
2670
2814
  break;
2671
- case 1:
2815
+ }
2816
+ case 1: {
2672
2817
  this._fileTimestampsOptimization.optimize(snapshot, capturedFiles);
2818
+ if (fileTimestamps === undefined) fileTimestamps = new Map();
2819
+ const fileTimestampsMap = fileTimestamps;
2673
2820
  for (const path of capturedFiles) {
2674
2821
  const cache = this._fileTimestamps.get(path);
2675
2822
  if (cache !== undefined && !isExistenceOnly(cache)) {
2676
2823
  if (cache !== "ignore") {
2677
- fileTimestamps.set(
2824
+ fileTimestampsMap.set(
2678
2825
  path,
2679
2826
  /** @type {FileSystemInfoEntry | null} */ (cache)
2680
2827
  );
@@ -2690,7 +2837,7 @@ class FileSystemInfo {
2690
2837
  }
2691
2838
  jobError();
2692
2839
  } else {
2693
- fileTimestamps.set(
2840
+ fileTimestampsMap.set(
2694
2841
  path,
2695
2842
  /** @type {FileSystemInfoEntry} */
2696
2843
  (entry)
@@ -2701,6 +2848,7 @@ class FileSystemInfo {
2701
2848
  }
2702
2849
  }
2703
2850
  break;
2851
+ }
2704
2852
  }
2705
2853
  };
2706
2854
  if (files) {
@@ -2715,8 +2863,10 @@ class FileSystemInfo {
2715
2863
  return;
2716
2864
  }
2717
2865
  switch (mode) {
2718
- case 3:
2866
+ case 3: {
2719
2867
  this._contextTshsOptimization.optimize(snapshot, capturedDirectories);
2868
+ if (contextTshs === undefined) contextTshs = new Map();
2869
+ const contextTshsMap = contextTshs;
2720
2870
  for (const path of capturedDirectories) {
2721
2871
  const cache = this._contextTshs.get(path);
2722
2872
  /** @type {ResolvedContextTimestampAndHash | null | undefined} */
@@ -2725,7 +2875,7 @@ class FileSystemInfo {
2725
2875
  cache !== undefined &&
2726
2876
  (resolved = getResolvedTimestamp(cache)) !== undefined
2727
2877
  ) {
2728
- contextTshs.set(path, resolved);
2878
+ contextTshsMap.set(path, resolved);
2729
2879
  } else {
2730
2880
  jobs++;
2731
2881
  /**
@@ -2743,7 +2893,7 @@ class FileSystemInfo {
2743
2893
  }
2744
2894
  jobError();
2745
2895
  } else {
2746
- contextTshs.set(
2896
+ contextTshsMap.set(
2747
2897
  path,
2748
2898
  /** @type {ResolvedContextTimestampAndHash | null} */
2749
2899
  (entry)
@@ -2759,11 +2909,14 @@ class FileSystemInfo {
2759
2909
  }
2760
2910
  }
2761
2911
  break;
2762
- case 2:
2912
+ }
2913
+ case 2: {
2763
2914
  this._contextHashesOptimization.optimize(
2764
2915
  snapshot,
2765
2916
  capturedDirectories
2766
2917
  );
2918
+ if (contextHashes === undefined) contextHashes = new Map();
2919
+ const contextHashesMap = contextHashes;
2767
2920
  for (const path of capturedDirectories) {
2768
2921
  const cache = this._contextHashes.get(path);
2769
2922
  /** @type {undefined | null | string} */
@@ -2772,7 +2925,7 @@ class FileSystemInfo {
2772
2925
  cache !== undefined &&
2773
2926
  (resolved = getResolvedHash(cache)) !== undefined
2774
2927
  ) {
2775
- contextHashes.set(path, resolved);
2928
+ contextHashesMap.set(path, resolved);
2776
2929
  } else {
2777
2930
  jobs++;
2778
2931
  /**
@@ -2789,7 +2942,7 @@ class FileSystemInfo {
2789
2942
  }
2790
2943
  jobError();
2791
2944
  } else {
2792
- contextHashes.set(path, /** @type {string} */ (entry));
2945
+ contextHashesMap.set(path, /** @type {string} */ (entry));
2793
2946
  jobDone();
2794
2947
  }
2795
2948
  };
@@ -2801,11 +2954,14 @@ class FileSystemInfo {
2801
2954
  }
2802
2955
  }
2803
2956
  break;
2804
- case 1:
2957
+ }
2958
+ case 1: {
2805
2959
  this._contextTimestampsOptimization.optimize(
2806
2960
  snapshot,
2807
2961
  capturedDirectories
2808
2962
  );
2963
+ if (contextTimestamps === undefined) contextTimestamps = new Map();
2964
+ const contextTimestampsMap = contextTimestamps;
2809
2965
  for (const path of capturedDirectories) {
2810
2966
  const cache = this._contextTimestamps.get(path);
2811
2967
  if (cache === "ignore") continue;
@@ -2814,14 +2970,8 @@ class FileSystemInfo {
2814
2970
  cache === undefined || isExistenceOnly(cache)
2815
2971
  ? undefined
2816
2972
  : /** @type {ContextFileSystemInfoEntry | null} */ (cache);
2817
- // A non-null cache entry without `timestampHash` cannot be
2818
- // used to populate the snapshot — the snapshot would then
2819
- // miss directory-change detection, since validity relies on
2820
- // `timestampHash`. Re-read the directory in that case.
2821
2973
  const cacheLacksHash =
2822
- usableCache !== undefined &&
2823
- usableCache !== null &&
2824
- usableCache.timestampHash === undefined;
2974
+ contextCacheEntryLacksTimestampHash(usableCache);
2825
2975
  /** @type {undefined | null | ResolvedContextFileSystemInfoEntry} */
2826
2976
  let resolved;
2827
2977
  if (
@@ -2829,7 +2979,7 @@ class FileSystemInfo {
2829
2979
  !cacheLacksHash &&
2830
2980
  (resolved = getResolvedTimestamp(usableCache)) !== undefined
2831
2981
  ) {
2832
- contextTimestamps.set(path, resolved);
2982
+ contextTimestampsMap.set(path, resolved);
2833
2983
  } else {
2834
2984
  jobs++;
2835
2985
  /**
@@ -2847,7 +2997,7 @@ class FileSystemInfo {
2847
2997
  }
2848
2998
  jobError();
2849
2999
  } else {
2850
- contextTimestamps.set(
3000
+ contextTimestampsMap.set(
2851
3001
  path,
2852
3002
  /** @type {ResolvedContextFileSystemInfoEntry | null} */
2853
3003
  (entry)
@@ -2867,6 +3017,7 @@ class FileSystemInfo {
2867
3017
  }
2868
3018
  }
2869
3019
  break;
3020
+ }
2870
3021
  }
2871
3022
  };
2872
3023
  if (directories) {
@@ -2883,11 +3034,13 @@ class FileSystemInfo {
2883
3034
  return;
2884
3035
  }
2885
3036
  this._missingExistenceOptimization.optimize(snapshot, capturedMissing);
3037
+ if (missingExistence === undefined) missingExistence = new Map();
3038
+ const missingExistenceMap = missingExistence;
2886
3039
  for (const path of capturedMissing) {
2887
3040
  const cache = this._fileTimestamps.get(path);
2888
3041
  if (cache !== undefined && !isExistenceOnly(cache)) {
2889
3042
  if (cache !== "ignore") {
2890
- missingExistence.set(path, Boolean(cache));
3043
+ missingExistenceMap.set(path, Boolean(cache));
2891
3044
  }
2892
3045
  } else {
2893
3046
  jobs++;
@@ -2900,7 +3053,7 @@ class FileSystemInfo {
2900
3053
  }
2901
3054
  jobError();
2902
3055
  } else {
2903
- missingExistence.set(path, Boolean(entry));
3056
+ missingExistenceMap.set(path, Boolean(entry));
2904
3057
  jobDone();
2905
3058
  }
2906
3059
  });
@@ -2911,6 +3064,10 @@ class FileSystemInfo {
2911
3064
  processCapturedMissing(captureNonManaged(missing, managedMissing));
2912
3065
  }
2913
3066
  this._managedItemInfoOptimization.optimize(snapshot, managedItems);
3067
+ if (managedItems.size !== 0 && managedItemInfo === undefined) {
3068
+ managedItemInfo = new Map();
3069
+ }
3070
+ const managedItemInfoMap = managedItemInfo;
2914
3071
  for (const path of managedItems) {
2915
3072
  const cache = this._managedItems.get(path);
2916
3073
  if (cache !== undefined) {
@@ -2919,7 +3076,7 @@ class FileSystemInfo {
2919
3076
  } else if (cache === "*nested") {
2920
3077
  managedMissing.add(join(this.fs, path, "package.json"));
2921
3078
  }
2922
- managedItemInfo.set(path, cache);
3079
+ /** @type {ManagedItemInfo} */ (managedItemInfoMap).set(path, cache);
2923
3080
  } else {
2924
3081
  jobs++;
2925
3082
  this.managedItemQueue.add(path, (err, entry) => {
@@ -2936,7 +3093,10 @@ class FileSystemInfo {
2936
3093
  } else if (cache === "*nested") {
2937
3094
  managedMissing.add(join(this.fs, path, "package.json"));
2938
3095
  }
2939
- managedItemInfo.set(path, entry);
3096
+ /** @type {ManagedItemInfo} */ (managedItemInfoMap).set(
3097
+ path,
3098
+ entry
3099
+ );
2940
3100
  jobDone();
2941
3101
  } else {
2942
3102
  // Fallback to normal snapshotting
@@ -3396,13 +3556,8 @@ class FileSystemInfo {
3396
3556
  cache === undefined || isExistenceOnly(cache)
3397
3557
  ? undefined
3398
3558
  : /** @type {ContextFileSystemInfoEntry | null} */ (cache);
3399
- // A non-null cache entry that lacks `timestampHash` while the
3400
- // snapshot has one cannot be used either; we re-read the
3401
- // directory through the disk-backed queue instead.
3402
3559
  const cacheLacksHash =
3403
- usableCache !== undefined &&
3404
- usableCache !== null &&
3405
- usableCache.timestampHash === undefined &&
3560
+ contextCacheEntryLacksTimestampHash(usableCache) &&
3406
3561
  ts !== null &&
3407
3562
  ts.timestampHash !== undefined;
3408
3563
  /** @type {undefined | null | ResolvedContextFileSystemInfoEntry} */
@@ -3513,9 +3668,7 @@ class FileSystemInfo {
3513
3668
  ? undefined
3514
3669
  : /** @type {ContextFileSystemInfoEntry | null} */ (cache);
3515
3670
  const cacheLacksHash =
3516
- usableCache !== undefined &&
3517
- usableCache !== null &&
3518
- usableCache.timestampHash === undefined &&
3671
+ contextCacheEntryLacksTimestampHash(usableCache) &&
3519
3672
  tsh !== null &&
3520
3673
  tsh.timestampHash !== undefined;
3521
3674
  /** @type {undefined | null | ResolvedContextFileSystemInfoEntry} */
@@ -4085,7 +4238,7 @@ class FileSystemInfo {
4085
4238
  /**
4086
4239
  * Returns reduced hash.
4087
4240
  * @param {string[]} files files
4088
- * @param {(string | ContextHash)[]} fileHashes hashes
4241
+ * @param {(string | ContextHash | null)[]} fileHashes hashes
4089
4242
  * @returns {ContextHash} reduced hash
4090
4243
  */
4091
4244
  reduce: (files, fileHashes) => {
@@ -4095,10 +4248,13 @@ class FileSystemInfo {
4095
4248
 
4096
4249
  for (const file of files) hash.update(file);
4097
4250
  for (const entry of fileHashes) {
4098
- if (typeof entry === "string") {
4251
+ // null for unsupported entry kinds (FIFO, socket); skip like the tsh reduce
4252
+ if (!entry) {
4253
+ continue;
4254
+ } else if (typeof entry === "string") {
4099
4255
  hash.update(entry);
4100
4256
  } else {
4101
- hash.update(entry.hash);
4257
+ if (entry.hash) hash.update(entry.hash);
4102
4258
  if (entry.symlinks) {
4103
4259
  if (symlinks === undefined) symlinks = new Set();
4104
4260
  addAll(entry.symlinks, symlinks);