webpack 5.106.2 → 5.107.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 (220) hide show
  1. package/README.md +2 -2
  2. package/lib/APIPlugin.js +1 -1
  3. package/lib/Cache.js +3 -6
  4. package/lib/CompatibilityPlugin.js +8 -7
  5. package/lib/Compilation.js +34 -26
  6. package/lib/Compiler.js +4 -13
  7. package/lib/ContextModule.js +2 -2
  8. package/lib/DefinePlugin.js +2 -2
  9. package/lib/Dependency.js +22 -1
  10. package/lib/DependencyTemplate.js +2 -1
  11. package/lib/EnvironmentPlugin.js +1 -1
  12. package/lib/EvalSourceMapDevToolPlugin.js +8 -9
  13. package/lib/ExternalModule.js +76 -15
  14. package/lib/ExternalModuleFactoryPlugin.js +5 -0
  15. package/lib/FileSystemInfo.js +187 -72
  16. package/lib/Generator.js +3 -3
  17. package/lib/HotModuleReplacementPlugin.js +26 -8
  18. package/lib/IgnorePlugin.js +2 -1
  19. package/lib/Module.js +19 -18
  20. package/lib/ModuleFactory.js +1 -1
  21. package/lib/ModuleSourceTypeConstants.js +31 -1
  22. package/lib/ModuleTypeConstants.js +12 -3
  23. package/lib/MultiCompiler.js +2 -2
  24. package/lib/NodeStuffPlugin.js +1 -1
  25. package/lib/NormalModule.js +13 -31
  26. package/lib/NormalModuleFactory.js +10 -2
  27. package/lib/Parser.js +1 -1
  28. package/lib/ProgressPlugin.js +129 -56
  29. package/lib/RuntimeGlobals.js +5 -5
  30. package/lib/RuntimeModule.js +9 -7
  31. package/lib/RuntimePlugin.js +11 -0
  32. package/lib/WarnCaseSensitiveModulesPlugin.js +70 -2
  33. package/lib/WarnDeprecatedOptionPlugin.js +1 -1
  34. package/lib/WarnNoModeSetPlugin.js +16 -1
  35. package/lib/Watching.js +2 -3
  36. package/lib/WebpackError.js +3 -77
  37. package/lib/WebpackIsIncludedPlugin.js +1 -1
  38. package/lib/WebpackOptionsApply.js +13 -1
  39. package/lib/asset/AssetBytesGenerator.js +6 -2
  40. package/lib/asset/AssetGenerator.js +22 -8
  41. package/lib/asset/AssetModulesPlugin.js +3 -1
  42. package/lib/asset/AssetSourceGenerator.js +6 -2
  43. package/lib/buildChunkGraph.js +4 -6
  44. package/lib/cache/PackFileCacheStrategy.js +4 -4
  45. package/lib/cli.js +3 -1
  46. package/lib/config/defaults.js +197 -10
  47. package/lib/config/normalization.js +3 -1
  48. package/lib/css/CssGenerator.js +320 -105
  49. package/lib/css/CssInjectStyleRuntimeModule.js +44 -42
  50. package/lib/css/CssLoadingRuntimeModule.js +22 -4
  51. package/lib/{CssModule.js → css/CssModule.js} +15 -15
  52. package/lib/css/CssModulesPlugin.js +166 -86
  53. package/lib/css/CssParser.js +566 -269
  54. package/lib/css/walkCssTokens.js +148 -2
  55. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +1 -1
  56. package/lib/dependencies/CommonJsDependencyHelpers.js +63 -0
  57. package/lib/dependencies/CommonJsExportRequireDependency.js +54 -10
  58. package/lib/dependencies/CommonJsExportsParserPlugin.js +1 -1
  59. package/lib/dependencies/CommonJsFullRequireDependency.js +32 -9
  60. package/lib/dependencies/CommonJsImportsParserPlugin.js +4 -3
  61. package/lib/dependencies/CommonJsRequireDependency.js +67 -4
  62. package/lib/dependencies/ContextDependency.js +1 -1
  63. package/lib/dependencies/ContextDependencyHelpers.js +1 -1
  64. package/lib/dependencies/CreateRequireParserPlugin.js +1 -1
  65. package/lib/dependencies/CriticalDependencyWarning.js +1 -1
  66. package/lib/dependencies/CssIcssExportDependency.js +332 -67
  67. package/lib/dependencies/CssIcssImportDependency.js +49 -7
  68. package/lib/dependencies/CssIcssSymbolDependency.js +11 -3
  69. package/lib/dependencies/CssImportDependency.js +8 -0
  70. package/lib/dependencies/CssUrlDependency.js +25 -0
  71. package/lib/dependencies/HarmonyDetectionParserPlugin.js +1 -1
  72. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +8 -7
  73. package/lib/dependencies/HarmonyExportExpressionDependency.js +22 -14
  74. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +110 -3
  75. package/lib/dependencies/HarmonyImportDependency.js +10 -2
  76. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +22 -1
  77. package/lib/dependencies/HarmonyImportSpecifierDependency.js +1 -1
  78. package/lib/{HarmonyLinkingError.js → dependencies/HarmonyLinkingError.js} +5 -3
  79. package/lib/dependencies/HtmlInlineScriptDependency.js +133 -0
  80. package/lib/dependencies/HtmlInlineStyleDependency.js +101 -0
  81. package/lib/dependencies/HtmlScriptSrcDependency.js +318 -0
  82. package/lib/dependencies/HtmlSourceDependency.js +127 -0
  83. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +1 -1
  84. package/lib/dependencies/ImportParserPlugin.js +2 -2
  85. package/lib/dependencies/ImportPhase.js +1 -1
  86. package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +1 -1
  87. package/lib/{RequireJsStuffPlugin.js → dependencies/RequireJsStuffPlugin.js} +7 -7
  88. package/lib/dependencies/SystemPlugin.js +1 -1
  89. package/lib/dependencies/WebAssemblyImportDependency.js +1 -1
  90. package/lib/dependencies/WorkerPlugin.js +2 -2
  91. package/lib/{DelegatedModule.js → dll/DelegatedModule.js} +31 -31
  92. package/lib/{DelegatedModuleFactoryPlugin.js → dll/DelegatedModuleFactoryPlugin.js} +4 -4
  93. package/lib/{DelegatedPlugin.js → dll/DelegatedPlugin.js} +2 -2
  94. package/lib/{DllEntryPlugin.js → dll/DllEntryPlugin.js} +4 -4
  95. package/lib/{DllModule.js → dll/DllModule.js} +24 -24
  96. package/lib/{DllModuleFactory.js → dll/DllModuleFactory.js} +4 -4
  97. package/lib/{DllPlugin.js → dll/DllPlugin.js} +6 -5
  98. package/lib/{DllReferencePlugin.js → dll/DllReferencePlugin.js} +14 -14
  99. package/lib/{LibManifestPlugin.js → dll/LibManifestPlugin.js} +9 -9
  100. package/lib/{AsyncDependencyToInitialChunkError.js → errors/AsyncDependencyToInitialChunkError.js} +2 -2
  101. package/lib/errors/BuildCycleError.js +1 -1
  102. package/lib/{ChunkRenderError.js → errors/ChunkRenderError.js} +1 -1
  103. package/lib/{CodeGenerationError.js → errors/CodeGenerationError.js} +1 -1
  104. package/lib/{CommentCompilationWarning.js → errors/CommentCompilationWarning.js} +3 -3
  105. package/lib/{ConcurrentCompilationError.js → errors/ConcurrentCompilationError.js} +4 -2
  106. package/lib/{EnvironmentNotSupportAsyncWarning.js → errors/EnvironmentNotSupportAsyncWarning.js} +4 -4
  107. package/lib/{HookWebpackError.js → errors/HookWebpackError.js} +5 -5
  108. package/lib/{IgnoreErrorModuleFactory.js → errors/IgnoreErrorModuleFactory.js} +4 -4
  109. package/lib/{InvalidDependenciesModuleWarning.js → errors/InvalidDependenciesModuleWarning.js} +3 -3
  110. package/lib/errors/JSONParseError.js +114 -0
  111. package/lib/{ModuleBuildError.js → errors/ModuleBuildError.js} +5 -5
  112. package/lib/{ModuleDependencyError.js → errors/ModuleDependencyError.js} +2 -2
  113. package/lib/{ModuleDependencyWarning.js → errors/ModuleDependencyWarning.js} +4 -4
  114. package/lib/{ModuleError.js → errors/ModuleError.js} +5 -5
  115. package/lib/{ModuleHashingError.js → errors/ModuleHashingError.js} +1 -1
  116. package/lib/{ModuleNotFoundError.js → errors/ModuleNotFoundError.js} +2 -2
  117. package/lib/{ModuleParseError.js → errors/ModuleParseError.js} +8 -6
  118. package/lib/{ModuleRestoreError.js → errors/ModuleRestoreError.js} +1 -1
  119. package/lib/{ModuleStoreError.js → errors/ModuleStoreError.js} +1 -1
  120. package/lib/{ModuleWarning.js → errors/ModuleWarning.js} +5 -5
  121. package/lib/{NodeStuffInWebError.js → errors/NodeStuffInWebError.js} +4 -4
  122. package/lib/errors/NonErrorEmittedError.js +28 -0
  123. package/lib/{UnhandledSchemeError.js → errors/UnhandledSchemeError.js} +2 -2
  124. package/lib/{UnsupportedFeatureWarning.js → errors/UnsupportedFeatureWarning.js} +3 -3
  125. package/lib/errors/WebpackError.js +84 -0
  126. package/lib/html/HtmlGenerator.js +379 -0
  127. package/lib/html/HtmlModulesPlugin.js +433 -0
  128. package/lib/html/HtmlParser.js +1489 -0
  129. package/lib/html/walkHtmlTokens.js +2733 -0
  130. package/lib/ids/IdHelpers.js +2 -1
  131. package/lib/index.js +34 -15
  132. package/lib/javascript/JavascriptModulesPlugin.js +89 -8
  133. package/lib/javascript/JavascriptParser.js +197 -16
  134. package/lib/javascript/JavascriptParserHelpers.js +1 -1
  135. package/lib/json/JsonParser.js +7 -16
  136. package/lib/library/AbstractLibraryPlugin.js +1 -1
  137. package/lib/library/EnableLibraryPlugin.js +1 -1
  138. package/lib/{FalseIIFEUmdWarning.js → library/FalseIIFEUmdWarning.js} +1 -1
  139. package/lib/library/ModuleLibraryPlugin.js +74 -0
  140. package/lib/node/NodeEnvironmentPlugin.js +4 -2
  141. package/lib/node/nodeConsole.js +113 -64
  142. package/lib/optimize/ConcatenatedModule.js +51 -6
  143. package/lib/optimize/InnerGraph.js +1 -1
  144. package/lib/optimize/InnerGraphPlugin.js +11 -1
  145. package/lib/optimize/MinMaxSizeWarning.js +4 -4
  146. package/lib/optimize/ModuleConcatenationPlugin.js +15 -7
  147. package/lib/optimize/RealContentHashPlugin.js +89 -26
  148. package/lib/optimize/SideEffectsFlagPlugin.js +111 -3
  149. package/lib/optimize/SplitChunksPlugin.js +1 -1
  150. package/lib/performance/AssetsOverSizeLimitWarning.js +2 -2
  151. package/lib/performance/EntrypointsOverSizeLimitWarning.js +2 -2
  152. package/lib/performance/NoAsyncChunksWarning.js +5 -3
  153. package/lib/performance/SizeLimitsPlugin.js +1 -1
  154. package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +4 -1
  155. package/lib/rules/UseEffectRulePlugin.js +4 -3
  156. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +119 -13
  157. package/lib/runtime/SetAnonymousDefaultNameRuntimeModule.js +35 -0
  158. package/lib/schemes/DataUriPlugin.js +13 -1
  159. package/lib/schemes/VirtualUrlPlugin.js +1 -1
  160. package/lib/serialization/SerializerMiddleware.js +2 -2
  161. package/lib/sharing/ConsumeSharedPlugin.js +2 -2
  162. package/lib/sharing/ConsumeSharedRuntimeModule.js +8 -4
  163. package/lib/sharing/ProvideSharedModule.js +1 -1
  164. package/lib/sharing/ProvideSharedPlugin.js +1 -1
  165. package/lib/sharing/resolveMatchedConfigs.js +1 -1
  166. package/lib/stats/DefaultStatsFactoryPlugin.js +2 -2
  167. package/lib/stats/DefaultStatsPresetPlugin.js +1 -1
  168. package/lib/stats/DefaultStatsPrinterPlugin.js +1 -1
  169. package/lib/stats/StatsFactory.js +1 -1
  170. package/lib/typescript/TypeScriptPlugin.js +210 -0
  171. package/lib/url/URLParserPlugin.js +2 -2
  172. package/lib/util/AsyncQueue.js +2 -2
  173. package/lib/util/Hash.js +2 -2
  174. package/lib/util/LocConverter.js +53 -0
  175. package/lib/util/SortableSet.js +1 -1
  176. package/lib/util/cleverMerge.js +2 -2
  177. package/lib/util/comparators.js +3 -3
  178. package/lib/util/concatenate.js +3 -3
  179. package/lib/util/conventions.js +42 -1
  180. package/lib/util/createMappings.js +118 -0
  181. package/lib/{formatLocation.js → util/formatLocation.js} +2 -2
  182. package/lib/{SizeFormatHelpers.js → util/formatSize.js} +3 -1
  183. package/lib/util/fs.js +8 -8
  184. package/lib/util/hash/md4.js +1 -1
  185. package/lib/util/hash/xxhash64.js +1 -1
  186. package/lib/util/identifier.js +48 -0
  187. package/lib/util/internalSerializables.js +35 -19
  188. package/lib/util/magicComment.js +10 -7
  189. package/lib/util/parseJson.js +2 -73
  190. package/lib/util/source.js +21 -0
  191. package/lib/util/topologicalSort.js +69 -0
  192. package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +2 -2
  193. package/lib/wasm-async/AsyncWebAssemblyParser.js +1 -1
  194. package/lib/wasm-sync/UnsupportedWebAssemblyFeatureError.js +5 -3
  195. package/lib/wasm-sync/WasmFinalizeExportsPlugin.js +1 -1
  196. package/lib/wasm-sync/WebAssemblyInInitialChunkError.js +5 -3
  197. package/lib/webpack.js +3 -1
  198. package/package.json +22 -20
  199. package/schemas/WebpackOptions.check.js +1 -1
  200. package/schemas/WebpackOptions.json +118 -3
  201. package/schemas/plugins/{DllPlugin.check.d.ts → HtmlGeneratorOptions.check.d.ts} +1 -1
  202. package/schemas/plugins/HtmlGeneratorOptions.check.js +6 -0
  203. package/schemas/plugins/HtmlGeneratorOptions.json +3 -0
  204. package/schemas/plugins/ProgressPlugin.check.js +1 -1
  205. package/schemas/plugins/ProgressPlugin.json +22 -0
  206. package/schemas/plugins/{DllReferencePlugin.check.d.ts → css/CssAutoOrModuleParserOptions.check.d.ts} +1 -1
  207. package/schemas/plugins/css/CssAutoOrModuleParserOptions.check.js +6 -0
  208. package/schemas/plugins/css/CssAutoOrModuleParserOptions.json +3 -0
  209. package/schemas/plugins/dll/DllPlugin.check.d.ts +7 -0
  210. package/schemas/plugins/dll/DllReferencePlugin.check.d.ts +7 -0
  211. package/types.d.ts +810 -101
  212. package/lib/CaseSensitiveModulesWarning.js +0 -80
  213. package/lib/GraphHelpers.js +0 -49
  214. package/lib/NoModeWarning.js +0 -23
  215. package/lib/css/CssMergeStyleSheetsRuntimeModule.js +0 -57
  216. /package/lib/{AbstractMethodError.js → errors/AbstractMethodError.js} +0 -0
  217. /package/schemas/plugins/{DllPlugin.check.js → dll/DllPlugin.check.js} +0 -0
  218. /package/schemas/plugins/{DllPlugin.json → dll/DllPlugin.json} +0 -0
  219. /package/schemas/plugins/{DllReferencePlugin.check.js → dll/DllReferencePlugin.check.js} +0 -0
  220. /package/schemas/plugins/{DllReferencePlugin.json → dll/DllReferencePlugin.json} +0 -0
@@ -20,14 +20,14 @@ const processAsyncTree = require("./util/processAsyncTree");
20
20
 
21
21
  /** @typedef {import("enhanced-resolve").ResolveRequest} ResolveRequest */
22
22
  /** @typedef {import("enhanced-resolve").ResolveFunctionAsync} ResolveFunctionAsync */
23
- /** @typedef {import("./WebpackError")} WebpackError */
24
- /** @typedef {import("./logging/Logger").Logger} Logger */
25
- /** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
26
- /** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
27
23
  /** @typedef {import("../declarations/WebpackOptions").HashFunction} HashFunction */
24
+ /** @typedef {import("./logging/Logger").Logger} Logger */
25
+ /** @typedef {import("./errors/WebpackError")} WebpackError */
28
26
  /** @typedef {import("./util/fs").JsonObject} JsonObject */
29
27
  /** @typedef {import("./util/fs").IStats} IStats */
30
28
  /** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
29
+ /** @typedef {import("./serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
30
+ /** @typedef {import("./serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
31
31
  /**
32
32
  * Defines the processor callback type used by this module.
33
33
  * @template T
@@ -231,7 +231,7 @@ class SnapshotIterable {
231
231
  const map = maps.pop();
232
232
  if (map !== undefined) {
233
233
  it =
234
- /** @type {Set<EXPECTED_ANY> | Map<string, EXPECTED_ANY>} */
234
+ /** @type {Set<string> | Map<string, EXPECTED_ANY>} */
235
235
  (map).keys();
236
236
  state = 2;
237
237
  } else {
@@ -1111,10 +1111,26 @@ const getEsModuleLexer = memoize(() => require("es-module-lexer"));
1111
1111
 
1112
1112
  /** @typedef {Set<string>} LoggedPaths */
1113
1113
 
1114
- /** @typedef {FileSystemInfoEntry | "ignore" | null} FileTimestamp */
1115
- /** @typedef {ContextFileSystemInfoEntry | "ignore" | null} ContextTimestamp */
1114
+ /** @typedef {FileSystemInfoEntry | ExistenceOnlyTimeEntry | "ignore" | null} FileTimestamp */
1115
+ /** @typedef {ContextFileSystemInfoEntry | ExistenceOnlyTimeEntry | "ignore" | null} ContextTimestamp */
1116
1116
  /** @typedef {ResolvedContextFileSystemInfoEntry | "ignore" | null} ResolvedContextTimestamp */
1117
1117
 
1118
+ /**
1119
+ * `watchpack` may report `{}` (existence-only) for files and directories it
1120
+ * is watching but has no time information for. Such entries cannot be used
1121
+ * for snapshot comparison, so cache lookups treat them as "no cached value"
1122
+ * and fall back to a fresh on-disk read.
1123
+ * @param {FileTimestamp | ContextTimestamp | undefined} entry cache entry
1124
+ * @returns {entry is ExistenceOnlyTimeEntry} true if the entry exists but carries no time info
1125
+ */
1126
+ const isExistenceOnly = (entry) => {
1127
+ if (entry === undefined || entry === null || entry === "ignore") return false;
1128
+ return (
1129
+ /** @type {Partial<FileSystemInfoEntry> & Partial<ContextFileSystemInfoEntry>} */
1130
+ (entry).safeTime === undefined
1131
+ );
1132
+ };
1133
+
1118
1134
  /** @typedef {(err?: WebpackError | null, result?: boolean) => void} CheckSnapshotValidCallback */
1119
1135
 
1120
1136
  /**
@@ -1463,43 +1479,40 @@ class FileSystemInfo {
1463
1479
 
1464
1480
  /**
1465
1481
  * Adds file timestamps.
1466
- * @param {ReadonlyMap<string, FileSystemInfoEntry | ExistenceOnlyTimeEntry | "ignore" | null>} map timestamps
1482
+ * @param {ReadonlyMap<string, FileTimestamp>} map timestamps
1467
1483
  * @param {boolean=} immutable if 'map' is immutable and FileSystemInfo can keep referencing it
1468
1484
  * @returns {void}
1469
1485
  */
1470
1486
  addFileTimestamps(map, immutable) {
1471
- this._fileTimestamps.addAll(
1472
- /** @type {ReadonlyMap<string, FileTimestamp>} */
1473
- (map),
1474
- immutable
1475
- );
1487
+ this._fileTimestamps.addAll(map, immutable);
1476
1488
  this._cachedDeprecatedFileTimestamps = undefined;
1477
1489
  }
1478
1490
 
1479
1491
  /**
1480
1492
  * Adds context timestamps.
1481
- * @param {ReadonlyMap<string, ContextFileSystemInfoEntry | ExistenceOnlyTimeEntry | "ignore" | null>} map timestamps
1493
+ * @param {ReadonlyMap<string, ContextTimestamp>} map timestamps
1482
1494
  * @param {boolean=} immutable if 'map' is immutable and FileSystemInfo can keep referencing it
1483
1495
  * @returns {void}
1484
1496
  */
1485
1497
  addContextTimestamps(map, immutable) {
1486
- this._contextTimestamps.addAll(
1487
- /** @type {ReadonlyMap<string, ContextTimestamp>} */
1488
- (map),
1489
- immutable
1490
- );
1498
+ this._contextTimestamps.addAll(map, immutable);
1491
1499
  this._cachedDeprecatedContextTimestamps = undefined;
1492
1500
  }
1493
1501
 
1494
1502
  /**
1495
1503
  * Gets file timestamp.
1496
1504
  * @param {string} path file path
1497
- * @param {(err?: WebpackError | null, fileTimestamp?: FileTimestamp) => void} callback callback function
1505
+ * @param {(err?: WebpackError | null, fileTimestamp?: FileSystemInfoEntry | "ignore" | null) => void} callback callback function
1498
1506
  * @returns {void}
1499
1507
  */
1500
1508
  getFileTimestamp(path, callback) {
1501
1509
  const cache = this._fileTimestamps.get(path);
1502
- if (cache !== undefined) return callback(null, cache);
1510
+ if (cache !== undefined && !isExistenceOnly(cache)) {
1511
+ return callback(
1512
+ null,
1513
+ /** @type {FileSystemInfoEntry | "ignore" | null} */ (cache)
1514
+ );
1515
+ }
1503
1516
  this.fileTimestampQueue.add(path, callback);
1504
1517
  }
1505
1518
 
@@ -1511,19 +1524,38 @@ class FileSystemInfo {
1511
1524
  */
1512
1525
  getContextTimestamp(path, callback) {
1513
1526
  const cache = this._contextTimestamps.get(path);
1514
- if (cache !== undefined) {
1527
+ if (cache !== undefined && !isExistenceOnly(cache)) {
1515
1528
  if (cache === "ignore") return callback(null, "ignore");
1516
- const resolved = getResolvedTimestamp(cache);
1529
+ const fullEntry =
1530
+ /** @type {ContextFileSystemInfoEntry | null} */
1531
+ (cache);
1532
+ const resolved = getResolvedTimestamp(fullEntry);
1517
1533
  if (resolved !== undefined) return callback(null, resolved);
1518
1534
  return this._resolveContextTimestamp(
1519
- /** @type {ResolvedContextFileSystemInfoEntry} */
1520
- (cache),
1535
+ /** @type {ContextFileSystemInfoEntry} */
1536
+ (fullEntry),
1521
1537
  callback
1522
1538
  );
1523
1539
  }
1540
+ this._readFreshContextTimestamp(path, callback);
1541
+ }
1542
+
1543
+ /**
1544
+ * Reads a context timestamp directly from disk, bypassing any cached
1545
+ * entry. Used by `getContextTimestamp` and the snapshot validity
1546
+ * checks when the cached entry is missing or is an `ExistenceOnlyTimeEntry`
1547
+ * (`{}`) supplied by watchpack — both cases require a fresh read to
1548
+ * obtain the `timestampHash`.
1549
+ * @private
1550
+ * @param {string} path context path
1551
+ * @param {(err?: WebpackError | null, resolvedContextTimestamp?: ResolvedContextTimestamp) => void} callback callback function
1552
+ * @returns {void}
1553
+ */
1554
+ _readFreshContextTimestamp(path, callback) {
1524
1555
  this.contextTimestampQueue.add(path, (err, _entry) => {
1525
1556
  if (err) return callback(err);
1526
- const entry = /** @type {ContextFileSystemInfoEntry} */ (_entry);
1557
+ const entry = /** @type {ContextFileSystemInfoEntry | null} */ (_entry);
1558
+ if (entry === null) return callback(null, null);
1527
1559
  const resolved = getResolvedTimestamp(entry);
1528
1560
  if (resolved !== undefined) return callback(null, resolved);
1529
1561
  this._resolveContextTimestamp(entry, callback);
@@ -1531,15 +1563,22 @@ class FileSystemInfo {
1531
1563
  }
1532
1564
 
1533
1565
  /**
1534
- * Get unresolved context timestamp.
1566
+ * Get unresolved context timestamp. Existence-only cache entries (`{}`)
1567
+ * are bypassed so the callback always receives a complete entry, "ignore"
1568
+ * or null.
1535
1569
  * @private
1536
1570
  * @param {string} path context path
1537
- * @param {(err?: WebpackError | null, contextTimestamp?: ContextTimestamp) => void} callback callback function
1571
+ * @param {(err?: WebpackError | null, contextTimestamp?: ContextFileSystemInfoEntry | "ignore" | null) => void} callback callback function
1538
1572
  * @returns {void}
1539
1573
  */
1540
1574
  _getUnresolvedContextTimestamp(path, callback) {
1541
1575
  const cache = this._contextTimestamps.get(path);
1542
- if (cache !== undefined) return callback(null, cache);
1576
+ if (cache !== undefined && !isExistenceOnly(cache)) {
1577
+ return callback(
1578
+ null,
1579
+ /** @type {ContextFileSystemInfoEntry | "ignore" | null} */ (cache)
1580
+ );
1581
+ }
1543
1582
  this.contextTimestampQueue.add(path, callback);
1544
1583
  }
1545
1584
 
@@ -1637,20 +1676,20 @@ class FileSystemInfo {
1637
1676
  });
1638
1677
  const resolveCjs = createResolver({
1639
1678
  extensions: [".js", ".json", ".node"],
1640
- conditionNames: ["require", "node"],
1679
+ conditionNames: ["require", "module-sync", "node"],
1641
1680
  exportsFields: ["exports"],
1642
1681
  fileSystem: this.fs
1643
1682
  });
1644
1683
  const resolveCjsAsChild = createResolver({
1645
1684
  extensions: [".js", ".json", ".node"],
1646
- conditionNames: ["require", "node"],
1685
+ conditionNames: ["require", "module-sync", "node"],
1647
1686
  exportsFields: [],
1648
1687
  fileSystem: this.fs
1649
1688
  });
1650
1689
  const resolveEsm = createResolver({
1651
1690
  extensions: [".js", ".json", ".node"],
1652
1691
  fullySpecified: true,
1653
- conditionNames: ["import", "node"],
1692
+ conditionNames: ["import", "module-sync", "node"],
1654
1693
  exportsFields: ["exports"],
1655
1694
  fileSystem: this.fs
1656
1695
  });
@@ -2503,9 +2542,12 @@ class FileSystemInfo {
2503
2542
  this._fileTimestampsOptimization.optimize(snapshot, capturedFiles);
2504
2543
  for (const path of capturedFiles) {
2505
2544
  const cache = this._fileTimestamps.get(path);
2506
- if (cache !== undefined) {
2545
+ if (cache !== undefined && !isExistenceOnly(cache)) {
2507
2546
  if (cache !== "ignore") {
2508
- fileTimestamps.set(path, cache);
2547
+ fileTimestamps.set(
2548
+ path,
2549
+ /** @type {FileSystemInfoEntry | null} */ (cache)
2550
+ );
2509
2551
  }
2510
2552
  } else {
2511
2553
  jobs++;
@@ -2637,19 +2679,33 @@ class FileSystemInfo {
2637
2679
  for (const path of capturedDirectories) {
2638
2680
  const cache = this._contextTimestamps.get(path);
2639
2681
  if (cache === "ignore") continue;
2682
+ /** @type {ContextFileSystemInfoEntry | null | undefined} */
2683
+ const usableCache =
2684
+ cache === undefined || isExistenceOnly(cache)
2685
+ ? undefined
2686
+ : /** @type {ContextFileSystemInfoEntry | null} */ (cache);
2687
+ // A non-null cache entry without `timestampHash` cannot be
2688
+ // used to populate the snapshot — the snapshot would then
2689
+ // miss directory-change detection, since validity relies on
2690
+ // `timestampHash`. Re-read the directory in that case.
2691
+ const cacheLacksHash =
2692
+ usableCache !== undefined &&
2693
+ usableCache !== null &&
2694
+ usableCache.timestampHash === undefined;
2640
2695
  /** @type {undefined | null | ResolvedContextFileSystemInfoEntry} */
2641
2696
  let resolved;
2642
2697
  if (
2643
- cache !== undefined &&
2644
- (resolved = getResolvedTimestamp(cache)) !== undefined
2698
+ usableCache !== undefined &&
2699
+ !cacheLacksHash &&
2700
+ (resolved = getResolvedTimestamp(usableCache)) !== undefined
2645
2701
  ) {
2646
2702
  contextTimestamps.set(path, resolved);
2647
2703
  } else {
2648
2704
  jobs++;
2649
2705
  /**
2650
2706
  * Processes the provided err.
2651
- * @param {(Error | null)=} err error
2652
- * @param {FileTimestamp=} entry entry
2707
+ * @param {(WebpackError | null)=} err error
2708
+ * @param {ResolvedContextTimestamp=} entry entry
2653
2709
  * @returns {void}
2654
2710
  */
2655
2711
  const callback = (err, entry) => {
@@ -2663,20 +2719,20 @@ class FileSystemInfo {
2663
2719
  } else {
2664
2720
  contextTimestamps.set(
2665
2721
  path,
2666
- /** @type {FileSystemInfoEntry | null} */
2722
+ /** @type {ResolvedContextFileSystemInfoEntry | null} */
2667
2723
  (entry)
2668
2724
  );
2669
2725
  jobDone();
2670
2726
  }
2671
2727
  };
2672
- if (cache !== undefined) {
2673
- this._resolveContextTimestamp(
2674
- /** @type {ContextFileSystemInfoEntry} */
2675
- (cache),
2676
- callback
2677
- );
2728
+ if (cacheLacksHash) {
2729
+ this._readFreshContextTimestamp(path, callback);
2730
+ } else if (usableCache !== undefined && usableCache !== null) {
2731
+ this._resolveContextTimestamp(usableCache, callback);
2678
2732
  } else {
2679
- this.getContextTimestamp(path, callback);
2733
+ // Force a fresh on-disk read so the snapshot stores a
2734
+ // complete entry (with `timestampHash`).
2735
+ this._readFreshContextTimestamp(path, callback);
2680
2736
  }
2681
2737
  }
2682
2738
  }
@@ -2699,7 +2755,7 @@ class FileSystemInfo {
2699
2755
  this._missingExistenceOptimization.optimize(snapshot, capturedMissing);
2700
2756
  for (const path of capturedMissing) {
2701
2757
  const cache = this._fileTimestamps.get(path);
2702
- if (cache !== undefined) {
2758
+ if (cache !== undefined && !isExistenceOnly(cache)) {
2703
2759
  if (cache !== "ignore") {
2704
2760
  missingExistence.set(path, Boolean(cache));
2705
2761
  }
@@ -3092,8 +3148,15 @@ class FileSystemInfo {
3092
3148
  this._statTestedEntries += fileTimestamps.size;
3093
3149
  for (const [path, ts] of fileTimestamps) {
3094
3150
  const cache = this._fileTimestamps.get(path);
3095
- if (cache !== undefined) {
3096
- if (cache !== "ignore" && !checkFile(path, cache, ts)) {
3151
+ if (cache !== undefined && !isExistenceOnly(cache)) {
3152
+ if (
3153
+ cache !== "ignore" &&
3154
+ !checkFile(
3155
+ path,
3156
+ /** @type {FileSystemInfoEntry | null} */ (cache),
3157
+ ts
3158
+ )
3159
+ ) {
3097
3160
  invalid();
3098
3161
  return;
3099
3162
  }
@@ -3154,8 +3217,16 @@ class FileSystemInfo {
3154
3217
  processFileHashSnapshot(path, tsh);
3155
3218
  } else {
3156
3219
  const cache = this._fileTimestamps.get(path);
3157
- if (cache !== undefined) {
3158
- if (cache === "ignore" || !checkFile(path, cache, tsh, false)) {
3220
+ if (cache !== undefined && !isExistenceOnly(cache)) {
3221
+ if (
3222
+ cache === "ignore" ||
3223
+ !checkFile(
3224
+ path,
3225
+ /** @type {FileSystemInfoEntry | null} */ (cache),
3226
+ tsh,
3227
+ false
3228
+ )
3229
+ ) {
3159
3230
  processFileHashSnapshot(path, tsh && tsh.hash);
3160
3231
  }
3161
3232
  } else {
@@ -3187,11 +3258,29 @@ class FileSystemInfo {
3187
3258
  for (const [path, ts] of contextTimestamps) {
3188
3259
  const cache = this._contextTimestamps.get(path);
3189
3260
  if (cache === "ignore") continue;
3261
+ // Treat existence-only entries (`{}` from watchpack) as a cache
3262
+ // miss — they carry no time info, so we cannot compare them to
3263
+ // the snapshot.
3264
+ /** @type {ContextFileSystemInfoEntry | null | undefined} */
3265
+ const usableCache =
3266
+ cache === undefined || isExistenceOnly(cache)
3267
+ ? undefined
3268
+ : /** @type {ContextFileSystemInfoEntry | null} */ (cache);
3269
+ // A non-null cache entry that lacks `timestampHash` while the
3270
+ // snapshot has one cannot be used either; we re-read the
3271
+ // directory through the disk-backed queue instead.
3272
+ const cacheLacksHash =
3273
+ usableCache !== undefined &&
3274
+ usableCache !== null &&
3275
+ usableCache.timestampHash === undefined &&
3276
+ ts !== null &&
3277
+ ts.timestampHash !== undefined;
3190
3278
  /** @type {undefined | null | ResolvedContextFileSystemInfoEntry} */
3191
3279
  let resolved;
3192
3280
  if (
3193
- cache !== undefined &&
3194
- (resolved = getResolvedTimestamp(cache)) !== undefined
3281
+ usableCache !== undefined &&
3282
+ !cacheLacksHash &&
3283
+ (resolved = getResolvedTimestamp(usableCache)) !== undefined
3195
3284
  ) {
3196
3285
  if (!checkContext(path, resolved, ts)) {
3197
3286
  invalid();
@@ -3220,12 +3309,10 @@ class FileSystemInfo {
3220
3309
  jobDone();
3221
3310
  }
3222
3311
  };
3223
- if (cache !== undefined) {
3224
- this._resolveContextTimestamp(
3225
- /** @type {ContextFileSystemInfoEntry} */
3226
- (cache),
3227
- callback
3228
- );
3312
+ if (cacheLacksHash) {
3313
+ this._readFreshContextTimestamp(path, callback);
3314
+ } else if (usableCache !== undefined && usableCache !== null) {
3315
+ this._resolveContextTimestamp(usableCache, callback);
3229
3316
  } else {
3230
3317
  this.getContextTimestamp(path, callback);
3231
3318
  }
@@ -3289,11 +3376,24 @@ class FileSystemInfo {
3289
3376
  } else {
3290
3377
  const cache = this._contextTimestamps.get(path);
3291
3378
  if (cache === "ignore") continue;
3379
+ // See the matching block in `hasContextTimestamps` above.
3380
+ /** @type {ContextFileSystemInfoEntry | null | undefined} */
3381
+ const usableCache =
3382
+ cache === undefined || isExistenceOnly(cache)
3383
+ ? undefined
3384
+ : /** @type {ContextFileSystemInfoEntry | null} */ (cache);
3385
+ const cacheLacksHash =
3386
+ usableCache !== undefined &&
3387
+ usableCache !== null &&
3388
+ usableCache.timestampHash === undefined &&
3389
+ tsh !== null &&
3390
+ tsh.timestampHash !== undefined;
3292
3391
  /** @type {undefined | null | ResolvedContextFileSystemInfoEntry} */
3293
3392
  let resolved;
3294
3393
  if (
3295
- cache !== undefined &&
3296
- (resolved = getResolvedTimestamp(cache)) !== undefined
3394
+ usableCache !== undefined &&
3395
+ !cacheLacksHash &&
3396
+ (resolved = getResolvedTimestamp(usableCache)) !== undefined
3297
3397
  ) {
3298
3398
  if (!checkContext(path, resolved, tsh, false)) {
3299
3399
  processContextHashSnapshot(path, tsh && tsh.hash);
@@ -3322,12 +3422,10 @@ class FileSystemInfo {
3322
3422
  }
3323
3423
  jobDone();
3324
3424
  };
3325
- if (cache !== undefined) {
3326
- this._resolveContextTimestamp(
3327
- /** @type {ContextFileSystemInfoEntry} */
3328
- (cache),
3329
- callback
3330
- );
3425
+ if (cacheLacksHash) {
3426
+ this._readFreshContextTimestamp(path, callback);
3427
+ } else if (usableCache !== undefined && usableCache !== null) {
3428
+ this._resolveContextTimestamp(usableCache, callback);
3331
3429
  } else {
3332
3430
  this.getContextTimestamp(path, callback);
3333
3431
  }
@@ -3342,7 +3440,7 @@ class FileSystemInfo {
3342
3440
  this._statTestedEntries += missingExistence.size;
3343
3441
  for (const [path, existence] of missingExistence) {
3344
3442
  const cache = this._fileTimestamps.get(path);
3345
- if (cache !== undefined) {
3443
+ if (cache !== undefined && !isExistenceOnly(cache)) {
3346
3444
  if (
3347
3445
  cache !== "ignore" &&
3348
3446
  !checkExistence(path, Boolean(cache), Boolean(existence))
@@ -3672,8 +3770,13 @@ class FileSystemInfo {
3672
3770
  fromFile: (file, stat, callback) => {
3673
3771
  // Prefer the cached value over our new stat to report consistent results
3674
3772
  const cache = this._fileTimestamps.get(file);
3675
- if (cache !== undefined) {
3676
- return callback(null, cache === "ignore" ? null : cache);
3773
+ if (cache !== undefined && !isExistenceOnly(cache)) {
3774
+ return callback(
3775
+ null,
3776
+ cache === "ignore"
3777
+ ? null
3778
+ : /** @type {FileSystemInfoEntry | null} */ (cache)
3779
+ );
3677
3780
  }
3678
3781
 
3679
3782
  const mtime = Number(stat.mtime);
@@ -4216,7 +4319,13 @@ class FileSystemInfo {
4216
4319
  /** @type {Map<string, number | null>} */
4217
4320
  const map = new Map();
4218
4321
  for (const [path, info] of this._fileTimestamps) {
4219
- if (info) map.set(path, typeof info === "object" ? info.safeTime : null);
4322
+ if (info) {
4323
+ const safeTime =
4324
+ typeof info === "object"
4325
+ ? /** @type {Partial<FileSystemInfoEntry>} */ (info).safeTime
4326
+ : undefined;
4327
+ map.set(path, safeTime === undefined ? null : safeTime);
4328
+ }
4220
4329
  }
4221
4330
  return (this._cachedDeprecatedFileTimestamps = map);
4222
4331
  }
@@ -4228,7 +4337,13 @@ class FileSystemInfo {
4228
4337
  /** @type {Map<string, number | null>} */
4229
4338
  const map = new Map();
4230
4339
  for (const [path, info] of this._contextTimestamps) {
4231
- if (info) map.set(path, typeof info === "object" ? info.safeTime : null);
4340
+ if (info) {
4341
+ const safeTime =
4342
+ typeof info === "object"
4343
+ ? /** @type {Partial<ContextFileSystemInfoEntry>} */ (info).safeTime
4344
+ : undefined;
4345
+ map.set(path, safeTime === undefined ? null : safeTime);
4346
+ }
4232
4347
  }
4233
4348
  return (this._cachedDeprecatedContextTimestamps = map);
4234
4349
  }
package/lib/Generator.js CHANGED
@@ -74,7 +74,7 @@ class Generator {
74
74
  * @returns {SourceTypes} available types (do not mutate)
75
75
  */
76
76
  getTypes(module) {
77
- const AbstractMethodError = require("./AbstractMethodError");
77
+ const AbstractMethodError = require("./errors/AbstractMethodError");
78
78
 
79
79
  throw new AbstractMethodError();
80
80
  }
@@ -88,7 +88,7 @@ class Generator {
88
88
  * @returns {number} estimate size of the module
89
89
  */
90
90
  getSize(module, type) {
91
- const AbstractMethodError = require("./AbstractMethodError");
91
+ const AbstractMethodError = require("./errors/AbstractMethodError");
92
92
 
93
93
  throw new AbstractMethodError();
94
94
  }
@@ -105,7 +105,7 @@ class Generator {
105
105
  module,
106
106
  { dependencyTemplates, runtimeTemplate, moduleGraph, type }
107
107
  ) {
108
- const AbstractMethodError = require("./AbstractMethodError");
108
+ const AbstractMethodError = require("./errors/AbstractMethodError");
109
109
 
110
110
  throw new AbstractMethodError();
111
111
  }
@@ -18,18 +18,19 @@ const {
18
18
  } = require("./ModuleTypeConstants");
19
19
  const NormalModule = require("./NormalModule");
20
20
  const RuntimeGlobals = require("./RuntimeGlobals");
21
- const WebpackError = require("./WebpackError");
22
21
  const { chunkHasCss } = require("./css/CssModulesPlugin");
23
22
  const ConstDependency = require("./dependencies/ConstDependency");
24
23
  const ImportMetaHotAcceptDependency = require("./dependencies/ImportMetaHotAcceptDependency");
25
24
  const ImportMetaHotDeclineDependency = require("./dependencies/ImportMetaHotDeclineDependency");
26
25
  const ModuleHotAcceptDependency = require("./dependencies/ModuleHotAcceptDependency");
27
26
  const ModuleHotDeclineDependency = require("./dependencies/ModuleHotDeclineDependency");
27
+ const WebpackError = require("./errors/WebpackError");
28
28
  const HotModuleReplacementRuntimeModule = require("./hmr/HotModuleReplacementRuntimeModule");
29
29
  const JavascriptParser = require("./javascript/JavascriptParser");
30
30
  const {
31
31
  evaluateToIdentifier
32
32
  } = require("./javascript/JavascriptParserHelpers");
33
+ const ConcatenatedModule = require("./optimize/ConcatenatedModule");
33
34
  const { find, isSubset } = require("./util/SetHelpers");
34
35
  const TupleSet = require("./util/TupleSet");
35
36
  const { compareModulesById } = require("./util/comparators");
@@ -389,13 +390,30 @@ class HotModuleReplacementPlugin {
389
390
  for (const chunk of compilation.chunks) {
390
391
  const chunkId = /** @type {ChunkId} */ (chunk.id);
391
392
 
392
- records.chunkModuleIds[chunkId] = Array.from(
393
- chunkGraph.getOrderedChunkModulesIterable(
394
- chunk,
395
- compareModulesById(chunkGraph)
396
- ),
397
- (m) => /** @type {ModuleId} */ (chunkGraph.getModuleId(m))
398
- );
393
+ /** @type {ModuleId[]} */
394
+ const moduleIds = [];
395
+ for (const m of chunkGraph.getOrderedChunkModulesIterable(
396
+ chunk,
397
+ compareModulesById(chunkGraph)
398
+ )) {
399
+ moduleIds.push(
400
+ /** @type {ModuleId} */ (chunkGraph.getModuleId(m))
401
+ );
402
+ if (m instanceof ConcatenatedModule && m.modules) {
403
+ for (const innerModule of m.modules) {
404
+ if (
405
+ innerModule.buildMeta &&
406
+ innerModule.buildMeta.needIdInConcatenation
407
+ ) {
408
+ const innerId = chunkGraph.getModuleId(innerModule);
409
+ if (innerId !== null) {
410
+ moduleIds.push(innerId);
411
+ }
412
+ }
413
+ }
414
+ }
415
+ }
416
+ records.chunkModuleIds[chunkId] = moduleIds;
399
417
  }
400
418
  });
401
419
  /** @type {TupleSet<Module, Chunk>} */
@@ -66,7 +66,8 @@ class IgnorePlugin {
66
66
  apply(compiler) {
67
67
  compiler.hooks.validate.tap(PLUGIN_NAME, () => {
68
68
  compiler.validate(
69
- require("../schemas/plugins/IgnorePlugin.json"),
69
+ /** @type {EXPECTED_ANY} */
70
+ (require("../schemas/plugins/IgnorePlugin.json")),
70
71
  this.options,
71
72
  {
72
73
  name: "Ignore Plugin",