@depup/webpack 5.110.1-depup.0 → 5.111.1-depup.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (304) hide show
  1. package/README.md +7 -8
  2. package/changes.json +7 -11
  3. package/lib/APIPlugin.js +26 -11
  4. package/lib/AutomaticPrefetchPlugin.js +1 -1
  5. package/lib/Cache.js +8 -3
  6. package/lib/CacheFacade.js +1 -1
  7. package/lib/ChunkGraph.js +20 -18
  8. package/lib/CircularModulesPlugin.js +157 -55
  9. package/lib/CleanPlugin.js +2 -2
  10. package/lib/CompatibilityPlugin.js +3 -4
  11. package/lib/Compilation.js +337 -338
  12. package/lib/Compiler.js +213 -51
  13. package/lib/ConcatenationScope.js +25 -35
  14. package/lib/ConstPlugin.js +16 -132
  15. package/lib/CopyPlugin.js +1054 -0
  16. package/lib/DefinePlugin.js +24 -8
  17. package/lib/DependencyTemplate.js +2 -1
  18. package/lib/DotenvPlugin.js +64 -40
  19. package/lib/ErrorHelpers.js +113 -0
  20. package/lib/ExportsInfo.js +30 -16
  21. package/lib/ExternalModule.js +47 -22
  22. package/lib/FileSystemInfo.js +17 -14
  23. package/lib/FlagDependencyExportsPlugin.js +53 -34
  24. package/lib/FlagDependencyUsagePlugin.js +17 -15
  25. package/lib/Generator.js +24 -2
  26. package/lib/HotModuleReplacementPlugin.js +55 -7
  27. package/lib/IgnorePlugin.js +1 -1
  28. package/lib/JavascriptMetaInfoPlugin.js +5 -3
  29. package/lib/LoaderOptionsPlugin.js +1 -1
  30. package/lib/MainTemplate.js +5 -1
  31. package/lib/Module.js +19 -10
  32. package/lib/ModuleGraph.js +6 -9
  33. package/lib/MultiCompiler.js +7 -17
  34. package/lib/MultiWatching.js +1 -1
  35. package/lib/NormalModule.js +148 -70
  36. package/lib/NormalModuleFactory.js +1 -1
  37. package/lib/RuntimeGlobals.js +21 -7
  38. package/lib/RuntimeModule.js +28 -12
  39. package/lib/RuntimePlugin.js +33 -3
  40. package/lib/RuntimeTemplate.js +1147 -847
  41. package/lib/SourceMapDevToolPlugin.js +54 -104
  42. package/lib/TemplatedPathPlugin.js +16 -59
  43. package/lib/Watching.js +9 -0
  44. package/lib/WebpackOptionsApply.js +84 -91
  45. package/lib/asset/AssetBytesGenerator.js +7 -1
  46. package/lib/asset/AssetGenerator.js +50 -24
  47. package/lib/asset/AssetModule.js +3 -0
  48. package/lib/asset/AssetSourceGenerator.js +7 -1
  49. package/lib/asset/WebManifestParser.js +7 -5
  50. package/lib/async-modules/AsyncModuleHelpers.js +10 -4
  51. package/lib/buildChunkGraph.js +11 -15
  52. package/lib/cache/AddBuildDependenciesPlugin.js +33 -4
  53. package/lib/cache/IdleFileCachePlugin.js +2 -2
  54. package/lib/cache/MemoryCachePlugin.js +4 -4
  55. package/lib/cache/MemoryWithGcCachePlugin.js +7 -8
  56. package/lib/cache/PackFileCacheStrategy.js +17 -19
  57. package/lib/cache/getLazyHashedEtag.js +3 -5
  58. package/lib/config/browserslistTargetHandler.js +17 -4
  59. package/lib/config/defaults.js +162 -142
  60. package/lib/config/getClaimedAssetTypes.js +10 -11
  61. package/lib/config/normalization.js +100 -20
  62. package/lib/config/target.js +13 -4
  63. package/lib/container/ContainerReferencePlugin.js +6 -0
  64. package/lib/container/RemoteRuntimeModule.js +9 -0
  65. package/lib/container/declaredRemotes.js +39 -0
  66. package/lib/{ContextExclusionPlugin.js → context/ContextExclusionPlugin.js} +1 -1
  67. package/lib/{ContextModule.js → context/ContextModule.js} +54 -115
  68. package/lib/{ContextModuleFactory.js → context/ContextModuleFactory.js} +19 -21
  69. package/lib/{ContextReplacementPlugin.js → context/ContextReplacementPlugin.js} +4 -4
  70. package/lib/css/CssGenerator.js +27 -11
  71. package/lib/css/CssInjectStyleRuntimeModule.js +9 -0
  72. package/lib/css/CssLoadingRuntimeModule.js +92 -15
  73. package/lib/css/CssModule.js +1 -1
  74. package/lib/css/CssModulesPlugin.js +3 -10
  75. package/lib/css/CssParser.js +162 -31
  76. package/lib/css/CssServerStylesRuntimeModule.js +9 -0
  77. package/lib/css/cssMinify.js +43 -32
  78. package/lib/css/data.js +3526 -871
  79. package/lib/css/syntax.js +6455 -1237
  80. package/lib/debug/ProfilingPlugin.js +7 -4
  81. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +6 -3
  82. package/lib/dependencies/AMDRuntimeModules.js +18 -0
  83. package/lib/dependencies/CommonJsExportRequireDependency.js +13 -12
  84. package/lib/dependencies/CommonJsExportsParserPlugin.js +12 -13
  85. package/lib/dependencies/CommonJsImportsParserPlugin.js +5 -5
  86. package/lib/dependencies/CommonJsPlugin.js +19 -3
  87. package/lib/dependencies/CommonJsRequireDependency.js +32 -9
  88. package/lib/dependencies/CommonJsSelfReferenceDependency.js +2 -4
  89. package/lib/dependencies/ContextDependency.js +1 -1
  90. package/lib/dependencies/ContextDependencyHelpers.js +3 -9
  91. package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +20 -7
  92. package/lib/dependencies/ContextElementDependency.js +1 -1
  93. package/lib/dependencies/CssIcssExportDependency.js +13 -9
  94. package/lib/dependencies/CssIcssImportDependency.js +3 -6
  95. package/lib/dependencies/CssUrlDependency.js +3 -5
  96. package/lib/dependencies/HarmonyCompatibilityDependency.js +67 -22
  97. package/lib/dependencies/HarmonyDetectionParserPlugin.js +3 -4
  98. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +10 -4
  99. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +12 -7
  100. package/lib/dependencies/HarmonyExportExpressionDependency.js +47 -33
  101. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +217 -34
  102. package/lib/dependencies/HarmonyExportInitFragment.js +110 -23
  103. package/lib/dependencies/HarmonyExportSpecifierDependency.js +25 -58
  104. package/lib/dependencies/HarmonyImportBareSideEffectDependency.js +59 -0
  105. package/lib/dependencies/HarmonyImportDependency.js +99 -41
  106. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +198 -25
  107. package/lib/dependencies/HarmonyImportSideEffectDependency.js +117 -4
  108. package/lib/dependencies/HarmonyImportSpecifierDependency.js +40 -3
  109. package/lib/dependencies/HarmonyModulesPlugin.js +20 -0
  110. package/lib/dependencies/HtmlEntryDependency.js +136 -104
  111. package/lib/dependencies/HtmlInlineScriptDependency.js +3 -4
  112. package/lib/dependencies/HtmlInlineStyleDependency.js +3 -4
  113. package/lib/dependencies/ImportContextDependency.js +43 -3
  114. package/lib/dependencies/ImportDependency.js +8 -29
  115. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +1 -1
  116. package/lib/dependencies/ImportMetaGlobHelpers.js +1 -1
  117. package/lib/dependencies/ImportMetaMainDependency.js +104 -0
  118. package/lib/dependencies/ImportMetaPlugin.js +67 -25
  119. package/lib/dependencies/ImportParserPlugin.js +25 -15
  120. package/lib/dependencies/LoaderPlugin.js +26 -1
  121. package/lib/dependencies/RequireContextDependencyParserPlugin.js +1 -1
  122. package/lib/dependencies/RequireHeaderDependency.js +20 -21
  123. package/lib/dependencies/SystemRuntimeModule.js +9 -0
  124. package/lib/dependencies/URLContextDependency.js +1 -1
  125. package/lib/dependencies/URLDependency.js +6 -5
  126. package/lib/dependencies/WorkerAndWorkletPlugin.js +16 -21
  127. package/lib/dependencies/WorkerDependency.js +12 -18
  128. package/lib/dependencies/WorkletDependency.js +12 -20
  129. package/lib/dependencies/importOptionsCheck.js +47 -0
  130. package/lib/dll/DelegatedModule.js +18 -1
  131. package/lib/dll/DllReferencePlugin.js +11 -8
  132. package/lib/dll/LibManifestPlugin.js +1 -1
  133. package/lib/errors/AnalyzableBailoutsWarning.js +41 -0
  134. package/lib/errors/DotenvFileError.js +29 -0
  135. package/lib/errors/DuplicateModulesWarning.js +12 -7
  136. package/lib/errors/EmptyCopyPatternWarning.js +26 -0
  137. package/lib/errors/ExternalStarReexportError.js +44 -0
  138. package/lib/errors/HookWebpackError.js +3 -2
  139. package/lib/errors/ImportedBindingAssignmentError.js +30 -0
  140. package/lib/errors/MissingSourceMapsWarning.js +36 -0
  141. package/lib/errors/ModuleParseError.js +2 -1
  142. package/lib/errors/UnusedAssetsWarning.js +36 -0
  143. package/lib/errors/UnusedFederationWarning.js +35 -0
  144. package/lib/errors/UnusedModulesWarning.js +38 -0
  145. package/lib/esm/ExportWebpackRequireRuntimeModule.js +9 -0
  146. package/lib/esm/ModuleChunkFormatPlugin.js +28 -3
  147. package/lib/esm/ModuleChunkLoadingPlugin.js +21 -5
  148. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +91 -53
  149. package/lib/hmr/HotModuleReplacement.runtime.js +8 -2
  150. package/lib/hmr/HotModuleReplacementRuntimeModule.js +9 -0
  151. package/lib/hmr/LazyCompilationPlugin.js +3 -5
  152. package/lib/html/HtmlGenerator.js +72 -87
  153. package/lib/html/HtmlModulesPlugin.js +479 -215
  154. package/lib/html/HtmlParser.js +110 -147
  155. package/lib/html/builtinEmbeddedRenderer.js +107 -0
  156. package/lib/html/data.js +142 -7
  157. package/lib/html/htmlMinify.js +92 -122
  158. package/lib/html/syntax.js +2031 -1556
  159. package/lib/ids/HashedModuleIdsPlugin.js +2 -1
  160. package/lib/index.js +49 -3
  161. package/lib/javascript/ChunkFormatHelpers.js +4 -3
  162. package/lib/javascript/JavascriptGenerator.js +8 -1
  163. package/lib/javascript/JavascriptModule.js +1 -0
  164. package/lib/javascript/JavascriptModulesPlugin.js +76 -80
  165. package/lib/javascript/JavascriptParser.js +1970 -900
  166. package/lib/javascript/StartupHelpers.js +27 -3
  167. package/lib/javascript/data.js +172 -0
  168. package/lib/javascript/grammar.js +5546 -0
  169. package/lib/javascript/parser.js +1500 -0
  170. package/lib/javascript/regexp.js +1762 -0
  171. package/lib/javascript/regexpData.js +51 -0
  172. package/lib/javascript/syntax.js +9061 -5262
  173. package/lib/json/JsonGenerator.js +7 -1
  174. package/lib/library/ModuleLibraryPlugin.js +171 -132
  175. package/lib/loaders/LoaderRunner.js +170 -14
  176. package/lib/node/NodeWatchFileSystem.js +3 -9
  177. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +22 -0
  178. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +8 -15
  179. package/lib/node/RequireChunkLoadingRuntimeModule.js +22 -0
  180. package/lib/optimize/AggressiveMergingPlugin.js +3 -5
  181. package/lib/optimize/ConcatenatedModule.js +222 -125
  182. package/lib/optimize/ConstExportsPlugin.js +50 -34
  183. package/lib/optimize/FlagIncludedChunksPlugin.js +3 -11
  184. package/lib/optimize/InlineExports.js +20 -2
  185. package/lib/optimize/InnerGraphPlugin.js +7 -13
  186. package/lib/optimize/LimitChunkCountPlugin.js +5 -8
  187. package/lib/optimize/MangleExportsPlugin.js +13 -4
  188. package/lib/optimize/ModuleConcatenationPlugin.js +27 -5
  189. package/lib/optimize/RealContentHashPlugin.js +179 -44
  190. package/lib/optimize/SideEffectsFlagPlugin.js +24 -28
  191. package/lib/optimize/SplitChunksPlugin.js +2 -4
  192. package/lib/performance/AnalyzableBailoutsPlugin.js +115 -0
  193. package/lib/performance/BroadContextsPlugin.js +1 -1
  194. package/lib/performance/CacheEffectivenessPlugin.js +7 -7
  195. package/lib/performance/DuplicateModulesPlugin.js +57 -13
  196. package/lib/performance/EvalUsagePlugin.js +5 -2
  197. package/lib/performance/MissingSourceMapsPlugin.js +115 -0
  198. package/lib/performance/PureAnnotationsPlugin.js +6 -3
  199. package/lib/performance/SizeLimitsPlugin.js +2 -4
  200. package/lib/performance/TopLevelThisPlugin.js +5 -4
  201. package/lib/performance/UnusedAssetsPlugin.js +109 -0
  202. package/lib/performance/UnusedFederationPlugin.js +147 -0
  203. package/lib/performance/UnusedModulesPlugin.js +141 -0
  204. package/lib/performance/UnusedReexportsPlugin.js +1 -55
  205. package/lib/performance/isOnlyReexported.js +65 -0
  206. package/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js +25 -5
  207. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +8 -8
  208. package/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js +9 -0
  209. package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +9 -0
  210. package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +9 -0
  211. package/lib/prefetch/ResourceHintPlugin.js +29 -35
  212. package/lib/prefetch/ResourceHintRuntimeModule.js +9 -0
  213. package/lib/prefetch/StartupAssetHintRuntimeModule.js +16 -10
  214. package/lib/rules/RuleSetCompiler.js +211 -4
  215. package/lib/runtime/AsyncModuleRuntimeModule.js +103 -67
  216. package/lib/runtime/AutoPublicPathRuntimeModule.js +9 -0
  217. package/lib/runtime/BaseUriRuntimeModule.js +9 -0
  218. package/lib/runtime/ChunkNameRuntimeModule.js +9 -0
  219. package/lib/runtime/EnsureChunkRuntimeModule.js +35 -16
  220. package/lib/runtime/GetChunkFilenameRuntimeModule.js +12 -4
  221. package/lib/runtime/GetFullHashRuntimeModule.js +9 -0
  222. package/lib/runtime/GetMainFilenameRuntimeModule.js +9 -0
  223. package/lib/runtime/GetWorkletBootstrapRuntimeModule.js +9 -0
  224. package/lib/runtime/GlobalRuntimeModule.js +11 -4
  225. package/lib/runtime/HasOwnPropertyRuntimeModule.js +9 -0
  226. package/lib/runtime/HelperRuntimeModule.js +10 -0
  227. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +313 -222
  228. package/lib/runtime/NonceRuntimeModule.js +9 -0
  229. package/lib/runtime/OnChunksLoadedRuntimeModule.js +67 -20
  230. package/lib/runtime/PublicPathRuntimeModule.js +9 -0
  231. package/lib/runtime/RuntimeIdRuntimeModule.js +9 -0
  232. package/lib/runtime/SpecNamespaceObjectRuntimeModule.js +90 -0
  233. package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +9 -0
  234. package/lib/runtime/StartupEntrypointRuntimeModule.js +9 -0
  235. package/lib/runtime/SystemContextRuntimeModule.js +9 -0
  236. package/lib/runtime/ToBinaryRuntimeModule.js +9 -0
  237. package/lib/schemes/DataUriPlugin.js +3 -6
  238. package/lib/schemes/HttpUriPlugin.js +22 -5
  239. package/lib/schemes/VirtualUrlPlugin.js +1 -1
  240. package/lib/serialization/BinaryMiddleware.js +9 -9
  241. package/lib/serialization/FileMiddleware.js +31 -18
  242. package/lib/serialization/ObjectMiddleware.js +168 -139
  243. package/lib/sharing/ConsumeSharedPlugin.js +12 -0
  244. package/lib/sharing/ConsumeSharedRuntimeModule.js +11 -0
  245. package/lib/sharing/ShareRuntimeModule.js +9 -0
  246. package/lib/sharing/declaredShared.js +47 -0
  247. package/lib/stats/DefaultStatsFactoryPlugin.js +6 -5
  248. package/lib/stats/DefaultStatsPrinterPlugin.js +3 -0
  249. package/lib/typescript/TypeScriptPlugin.js +10 -13
  250. package/lib/url/URLParserPlugin.js +6 -8
  251. package/lib/util/ArrayQueue.js +3 -3
  252. package/lib/util/LocConverter.js +4 -7
  253. package/lib/util/SourceProcessor.js +115 -99
  254. package/lib/util/URLAbsoluteSpecifier.js +3 -1
  255. package/lib/util/async.js +292 -0
  256. package/lib/util/buildDiagnostics.js +69 -0
  257. package/lib/util/chainedImports.js +3 -4
  258. package/lib/util/concatenate.js +4 -4
  259. package/lib/util/conventions.js +5 -1
  260. package/lib/util/createHooksRegistry.js +1 -2
  261. package/lib/util/createMappings.js +25 -3
  262. package/lib/util/dataURL.js +2 -3
  263. package/lib/util/deterministicGrouping.js +8 -13
  264. package/lib/util/findGraphRoots.js +6 -13
  265. package/lib/util/fs.js +27 -1
  266. package/lib/util/globUtils.js +1 -1
  267. package/lib/util/handlerKeys.js +40 -0
  268. package/lib/util/hash/wasm-hash.js +3 -4
  269. package/lib/util/identifier.js +20 -0
  270. package/lib/util/internalSerializables.js +7 -1
  271. package/lib/util/registerExternalSerializer.js +6 -45
  272. package/lib/util/removeBOM.js +82 -1
  273. package/lib/util/semver.js +5 -3
  274. package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +14 -3
  275. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +14 -3
  276. package/lib/wasm-async/AsyncWebAssemblyGenerator.js +6 -1
  277. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +5 -1
  278. package/lib/wasm-async/UniversalCompileAsyncWasmPlugin.js +7 -12
  279. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +12 -4
  280. package/lib/wasm-sync/WebAssemblyGenerator.js +6 -1
  281. package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +5 -1
  282. package/lib/wasm-sync/WebAssemblyUtils.js +2 -4
  283. package/lib/web/FetchCompileAsyncWasmPlugin.js +10 -6
  284. package/lib/web/FetchCompileWasmPlugin.js +4 -2
  285. package/lib/web/JsonpChunkLoadingRuntimeModule.js +36 -0
  286. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +19 -0
  287. package/package.json +55 -46
  288. package/schemas/WebpackOptions.check.js +1 -1
  289. package/schemas/WebpackOptions.json +388 -76
  290. package/schemas/plugins/LoaderOptionsPlugin.check.js +1 -1
  291. package/schemas/plugins/ManifestPlugin.check.js +1 -1
  292. package/schemas/plugins/SourceMapDevToolPlugin.check.js +1 -1
  293. package/schemas/plugins/asset/AssetGeneratorOptions.check.js +1 -1
  294. package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js +1 -1
  295. package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
  296. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  297. package/schemas/plugins/debug/ProfilingPlugin.check.js +1 -1
  298. package/schemas/plugins/dll/DllReferencePlugin.check.js +1 -1
  299. package/schemas/plugins/ids/HashedModuleIdsPlugin.check.js +1 -1
  300. package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
  301. package/types.d.ts +1795 -608
  302. package/lib/dependencies/ExportBindingInitFragment.js +0 -191
  303. package/lib/errors/EntrypointOverlapWarning.js +0 -45
  304. package/lib/performance/EntrypointOverlapPlugin.js +0 -122
@@ -5,6 +5,7 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ const CircularModulesPlugin = require("../CircularModulesPlugin");
8
9
  const { UsageState } = require("../ExportsInfo");
9
10
  const {
10
11
  JAVASCRIPT_MODULE_TYPE_AUTO,
@@ -18,6 +19,8 @@ const {
18
19
  toInlinedValue
19
20
  } = require("./InlineExports");
20
21
 
22
+ const { CircularKind } = CircularModulesPlugin;
23
+
21
24
  /** @import { InlinedValue } from "./InlineExports" */
22
25
  /** @import Compiler from "../Compiler" */
23
26
  /** @import ExportsInfo from "../ExportsInfo" */
@@ -161,50 +164,63 @@ class ConstExportsPlugin {
161
164
  enableInlineExports(compilation.moduleGraph);
162
165
 
163
166
  const moduleGraph = compilation.moduleGraph;
164
- compilation.hooks.optimizeDependencies.tap(PLUGIN_NAME, (modules) => {
165
- /** @type {Set<ExportsInfo>} */
166
- const visited = new Set();
167
- /** @type {ExportsInfo[]} */
168
- let queue = [];
169
- for (const module of modules) {
170
- queue.push(moduleGraph.getExportsInfo(module));
171
- }
172
- while (queue.length > 0) {
173
- const items = queue;
174
- queue = [];
175
- for (const exportsInfo of items) {
176
- if (visited.has(exportsInfo)) continue;
177
- visited.add(exportsInfo);
178
- // Other-export usage means we can't safely inline (some non-statically-known consumer)
167
+ // After CircularModulesPlugin (STAGE_DETECT): needs Binding kind flags.
168
+ compilation.hooks.optimizeDependencies.tap(
169
+ {
170
+ name: PLUGIN_NAME,
171
+ stage: CircularModulesPlugin.STAGE_DETECT + 1
172
+ },
173
+ (modules) => {
174
+ /** @type {Set<ExportsInfo>} */
175
+ const visited = new Set();
176
+ /** @type {ExportsInfo[]} */
177
+ let queue = [];
178
+ for (const module of modules) {
179
+ // Binding-observable cycle peers must keep TDZ live bindings.
179
180
  if (
180
- exportsInfo.otherExportsInfo.getUsed(undefined) !==
181
- UsageState.Unused
181
+ CircularModulesPlugin.isCircular(module, CircularKind.Binding)
182
182
  ) {
183
183
  continue;
184
184
  }
185
- for (const exportInfo of exportsInfo.ownedExports) {
186
- const inlined = exportInfo.canInline();
187
- const doInline =
188
- !exportInfo.hasUsedName() &&
189
- inlined !== undefined &&
190
- exportInfo.provided === true;
191
- if (doInline) {
192
- exportInfo.setUsedName(new InlinedUsedName(inlined));
193
- exportsInfo.markInlinedExports();
185
+ queue.push(moduleGraph.getExportsInfo(module));
186
+ }
187
+ while (queue.length > 0) {
188
+ const items = queue;
189
+ queue = [];
190
+ for (const exportsInfo of items) {
191
+ if (visited.has(exportsInfo)) continue;
192
+ visited.add(exportsInfo);
193
+ // Other-export usage means we can't safely inline (some non-statically-known consumer)
194
+ if (
195
+ exportsInfo.otherExportsInfo.getUsed(undefined) !==
196
+ UsageState.Unused
197
+ ) {
198
+ continue;
194
199
  }
195
- if (exportInfo.exportsInfoOwned && exportInfo.exportsInfo) {
196
- const used = exportInfo.getUsed(undefined);
197
- if (
198
- used === UsageState.OnlyPropertiesUsed ||
199
- used === UsageState.Unused
200
- ) {
201
- queue.push(exportInfo.exportsInfo);
200
+ for (const exportInfo of exportsInfo.ownedExports) {
201
+ const inlined = exportInfo.canInline();
202
+ const doInline =
203
+ !exportInfo.hasUsedName() &&
204
+ inlined !== undefined &&
205
+ exportInfo.provided === true;
206
+ if (doInline) {
207
+ exportInfo.setUsedName(new InlinedUsedName(inlined));
208
+ exportsInfo.markInlinedExports();
209
+ }
210
+ if (exportInfo.exportsInfoOwned && exportInfo.exportsInfo) {
211
+ const used = exportInfo.getUsed(undefined);
212
+ if (
213
+ used === UsageState.OnlyPropertiesUsed ||
214
+ used === UsageState.Unused
215
+ ) {
216
+ queue.push(exportInfo.exportsInfo);
217
+ }
202
218
  }
203
219
  }
204
220
  }
205
221
  }
206
222
  }
207
- });
223
+ );
208
224
  }
209
225
  );
210
226
  }
@@ -24,17 +24,9 @@ class FlagIncludedChunksPlugin {
24
24
  compilation.hooks.optimizeChunkIds.tap(PLUGIN_NAME, (chunks) => {
25
25
  const chunkGraph = compilation.chunkGraph;
26
26
 
27
- // prepare two bit integers for each module
28
- // 2^31 is the max number represented as SMI in v8
29
- // we want the bits distributed this way:
30
- // the bit 2^31 is pretty rar and only one module should get it
31
- // so it has a probability of 1 / modulesCount
32
- // the first bit (2^0) is the easiest and every module could get it
33
- // if it doesn't get a better bit
34
- // from bit 2^n to 2^(n+1) there is a probability of p
35
- // so 1 / modulesCount == p^31
36
- // <=> p = sqrt31(1 / modulesCount)
37
- // so we use a modulo of 1 / sqrt31(1 / modulesCount)
27
+ // Two bit integers per module, within v8's 2^31 SMI range. The bits are
28
+ // spread so 2^31 falls to about one module in `modulesCount` and 2^0 to
29
+ // any module missing a better one, which gives the modulo below.
38
30
  /** @type {WeakMap<Module, number>} */
39
31
  const moduleBits = new WeakMap();
40
32
  const modulesCount = compilation.modules.size;
@@ -17,6 +17,7 @@ const { propertyAccess } = require("../util/property");
17
17
  /** @import ModuleGraph from "../ModuleGraph" */
18
18
  /** @import Module from "../Module" */
19
19
  /** @import { RuntimeSpec } from "../util/runtime" */
20
+ /** @import Hash from "../util/Hash" */
20
21
 
21
22
  const MAX_INLINE_BYTES = 6;
22
23
 
@@ -60,6 +61,14 @@ class InlinedValue {
60
61
  return `(${comment}${this.renderLiteral()})`;
61
62
  }
62
63
 
64
+ /**
65
+ * @param {InlinedValue} other other inlined value
66
+ * @returns {boolean} true when kind and value match
67
+ */
68
+ equals(other) {
69
+ return this.kind === other.kind && this.value === other.value;
70
+ }
71
+
63
72
  /**
64
73
  * @param {ObjectSerializerContext} context context
65
74
  */
@@ -96,12 +105,21 @@ class InlinedUsedName {
96
105
  }
97
106
 
98
107
  /**
99
- * @param {string} comment leading comment text
108
+ * @param {string=} comment leading comment text
100
109
  * @returns {string} rendered literal with property access suffix
101
110
  */
102
- render(comment) {
111
+ render(comment = "") {
103
112
  return this.value.render(comment) + propertyAccess(this.suffix);
104
113
  }
114
+
115
+ /**
116
+ * Updates the hash with the data contributed by this instance.
117
+ * @param {Hash} hash the hash used to track dependencies
118
+ * @returns {void}
119
+ */
120
+ updateHash(hash) {
121
+ hash.update(this.render());
122
+ }
105
123
  }
106
124
 
107
125
  /**
@@ -122,10 +122,8 @@ class InnerGraphPlugin {
122
122
  // nodes that have a TopLevelSymbol assigned and
123
123
  // variables are tagged with the assigned TopLevelSymbol
124
124
 
125
- // We differ 3 types of nodes:
126
- // 1. full statements (export default, function declaration)
127
- // 2. classes (class declaration, class expression)
128
- // 3. variable declarators (const x = ...)
125
+ // Three kinds of node carry a symbol: a full statement, a class, and a
126
+ // variable declarator.
129
127
 
130
128
  /** @type {WeakMap<Node | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration, TopLevelSymbol>} */
131
129
  let statementWithTopLevelSymbol = new WeakMap();
@@ -360,16 +358,12 @@ class InnerGraphPlugin {
360
358
  // During real walking we set the TopLevelSymbol state to the assigned
361
359
  // TopLevelSymbol by using the fill datastructures.
362
360
 
363
- // In addition to tracking TopLevelSymbols, we sometimes need to
364
- // add a PureExpressionDependency. This is needed to skip execution
365
- // of pure expressions, even when they are not dropped due to
366
- // minimizing. Otherwise symbols used there might not exist anymore
367
- // as they are removed as unused by this optimization
361
+ // A `PureExpressionDependency` is sometimes added too, so a pure
362
+ // expression is skipped even where minimizing leaves it: the symbols it
363
+ // uses may have been removed as unused by this optimization.
368
364
 
369
- // When we find a reference to a TopLevelSymbol, we register a
370
- // TopLevelSymbol dependency from TopLevelSymbol in state to the
371
- // referenced TopLevelSymbol. This way we get a graph of all
372
- // TopLevelSymbols.
365
+ // A reference registers a dependency from the symbol in state to the one
366
+ // referenced, which is how the graph of all of them is built.
373
367
 
374
368
  // The following hooks are called during walking:
375
369
 
@@ -101,10 +101,8 @@ class LimitChunkCountPlugin {
101
101
  /** @type {Chunk[]} */
102
102
  const orderedChunks = [...chunks].sort(compareChunksWithGraph);
103
103
 
104
- // create a lazy sorted data structure to keep all combinations
105
- // this is large. Size = chunks * (chunks - 1) / 2
106
- // It uses a multi layer bucket sort plus normal sort in the last layer
107
- // It's also lazy so only accessed buckets are sorted
104
+ // All `chunks * (chunks - 1) / 2` combinations, held in a multi-layer
105
+ // bucket sort that sorts only the buckets actually reached.
108
106
  /** @type {LazyBucketSortedSet<ChunkCombination, number>} */
109
107
  const combinations = new LazyBucketSortedSet(
110
108
  // Layer 1: ordered by largest size benefit
@@ -214,10 +212,9 @@ class LimitChunkCountPlugin {
214
212
  for (const group of queue) {
215
213
  for (const mChunk of modifiedChunks) {
216
214
  if (mChunk !== a && mChunk !== b && mChunk.isInGroup(group)) {
217
- // This is a potential pair which needs recalculation
218
- // We can't do that now, but it merge before following pairs
219
- // so we leave space for it, and consider chunks as modified
220
- // just for the worse case
215
+ // A pair needing recalculation, which cannot happen now yet may
216
+ // merge before the ones that follow, so room is left for it and
217
+ // the chunks count as modified for the worst case.
221
218
  remainingChunksToMerge--;
222
219
  if (remainingChunksToMerge <= 0) break loop;
223
220
  modifiedChunks.add(a);
@@ -15,6 +15,7 @@ const { assignDeterministicIds } = require("../ids/IdHelpers");
15
15
  const { compareSelect, compareStringsNumeric } = require("../util/comparators");
16
16
 
17
17
  /** @import Compiler from "../Compiler" */
18
+ /** @import { BuildInfo } from "../Module" */
18
19
  /** @import ExportsInfo, { ExportInfo } from "../ExportsInfo" */
19
20
  /** @import { UsedNames } from "../util/concatenate" */
20
21
 
@@ -59,10 +60,9 @@ const mangleExportsInfo = (deterministic, exportsInfo, isNamespace) => {
59
60
  /** @type {InstanceType<ExportInfo>[]} */
60
61
  const mangleableExports = [];
61
62
 
62
- // Avoid to renamed exports that are not provided when
63
- // 1. it's not a namespace export: non-provided exports can be found in prototype chain
64
- // 2. there are other provided exports and deterministic mode is chosen:
65
- // non-provided exports would break the determinism
63
+ // A non-provided export is left unmangled outside a namespace export, where the
64
+ // prototype chain may still carry it, and under deterministic mode beside other
65
+ // provided exports, where it would break the determinism.
66
66
  let avoidMangleNonProvided = !isNamespace;
67
67
  if (!avoidMangleNonProvided && deterministic) {
68
68
  for (const exportInfo of exportsInfo.ownedExports) {
@@ -184,6 +184,15 @@ class MangleExportsPlugin {
184
184
  );
185
185
  }
186
186
  for (const module of modules) {
187
+ // A spec namespace reports the names the module exports, so a
188
+ // module handing one out cannot have them renamed.
189
+ if (
190
+ /** @type {BuildInfo} */
191
+ (module.buildInfo).specNamespaceObject
192
+ ) {
193
+ continue;
194
+ }
195
+
187
196
  const isNamespace =
188
197
  module.buildMeta && module.buildMeta.exportsType === "namespace";
189
198
  const exportsInfo = moduleGraph.getExportsInfo(module);
@@ -5,7 +5,6 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const asyncLib = require("neo-async");
9
8
  const ChunkGraph = require("../ChunkGraph");
10
9
  const Dependency = require("../Dependency");
11
10
  const Module = require("../Module");
@@ -14,6 +13,7 @@ const { JAVASCRIPT_TYPE } = require("../ModuleSourceTypeConstants");
14
13
  const { STAGE_DEFAULT } = require("../OptimizationStages");
15
14
  const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency");
16
15
  const { ImportPhaseUtils } = require("../dependencies/ImportPhase");
16
+ const asyncLib = require("../util/async");
17
17
  const { compareModulesByIdentifier } = require("../util/comparators");
18
18
  const { isCommonJsConcatenationEnabled } = require("../util/concatenate");
19
19
  const {
@@ -28,6 +28,7 @@ const ConcatenatedModule = require("./ConcatenatedModule");
28
28
  /** @import Chunk from "../Chunk" */
29
29
  /** @import Compilation from "../Compilation" */
30
30
  /** @import Compiler from "../Compiler" */
31
+ /** @import { JavascriptModuleBuildInfo } from "../javascript/JavascriptModule" */
31
32
  /** @import { BuildInfo, BuildMeta } from "../Module" */
32
33
  /** @import RequestShortener from "../RequestShortener" */
33
34
  /** @import { RuntimeSpec } from "../util/runtime" */
@@ -235,6 +236,19 @@ class ModuleConcatenationPlugin {
235
236
  continue;
236
237
  }
237
238
 
239
+ // Concatenation materializes the namespace inline, which would
240
+ // silently drop the spec exotic object the module asked for.
241
+ if (
242
+ /** @type {BuildInfo} */
243
+ (module.buildInfo).specNamespaceObject
244
+ ) {
245
+ setBailoutReason(
246
+ module,
247
+ "Module hands out a spec namespace object"
248
+ );
249
+ continue;
250
+ }
251
+
238
252
  // Module must be in any chunk (we don't want to do useless work)
239
253
  if (chunkGraph.getNumberOfModuleChunks(module) === 0) {
240
254
  setBailoutReason(module, "Module is not in any chunk");
@@ -302,6 +316,15 @@ class ModuleConcatenationPlugin {
302
316
  canBeInner = false;
303
317
  }
304
318
 
319
+ // The root stands in for the whole concatenation, so an
320
+ // expression only an inner module can answer statically rules it out
321
+ if (
322
+ /** @type {JavascriptModuleBuildInfo} */
323
+ (module.buildInfo).moduleConcatenationRootBailout
324
+ ) {
325
+ canBeRoot = false;
326
+ }
327
+
305
328
  if (deferEnabled && moduleGraph.isDeferred(module)) {
306
329
  setInnerBailoutReason(module, "Module is deferred");
307
330
  canBeInner = false;
@@ -455,10 +478,9 @@ class ModuleConcatenationPlugin {
455
478
  logger.debug(
456
479
  `${statsCandidates} candidates were considered for adding (${stats.cached} cached failure, ${stats.alreadyInConfig} already in config, ${stats.invalidModule} invalid module, ${stats.incorrectChunks} incorrect chunks, ${stats.incorrectDependency} incorrect dependency, ${stats.incorrectChunksOfImporter} incorrect chunks of importer, ${stats.incorrectModuleDependency} incorrect module dependency, ${stats.incorrectRuntimeCondition} incorrect runtime condition, ${stats.importerFailed} importer failed, ${stats.added} added)`
457
480
  );
458
- // Create the largest configurations first: if a root also ended up inside
459
- // a bigger configuration, the bigger one wins (smaller skipped below).
460
- // Configurations can't be reused across roots: a module shared by several
461
- // chunks is concatenated into each consumer (module duplication).
481
+ // Largest configurations first, so a root that also landed inside a
482
+ // bigger one loses to it. None is reused across roots: a module shared by
483
+ // several chunks is concatenated into each consumer.
462
484
  logger.time("sort concat configurations");
463
485
  concatConfigurations.sort((a, b) => b.modules.size - a.modules.size);
464
486
  logger.timeEnd("sort concat configurations");
@@ -187,6 +187,7 @@ const createCompilationHooks = () => ({
187
187
  * @typedef {object} RealContentHashPluginOptions
188
188
  * @property {HashFunction} hashFunction the hash function to use
189
189
  * @property {HashDigest} hashDigest the hash digest to use
190
+ * @property {boolean=} onDemand run only where analyzable output marked a name for repair
190
191
  */
191
192
 
192
193
  const PLUGIN_NAME = "RealContentHashPlugin";
@@ -196,11 +197,13 @@ class RealContentHashPlugin {
196
197
  * Creates an instance of RealContentHashPlugin.
197
198
  * @param {RealContentHashPluginOptions} options options
198
199
  */
199
- constructor({ hashFunction, hashDigest }) {
200
+ constructor({ hashFunction, hashDigest, onDemand }) {
200
201
  /** @type {HashFunction} */
201
202
  this._hashFunction = hashFunction;
202
203
  /** @type {HashDigest} */
203
204
  this._hashDigest = hashDigest;
205
+ /** @type {boolean} */
206
+ this._onDemand = Boolean(onDemand);
204
207
  }
205
208
 
206
209
  /**
@@ -223,6 +226,14 @@ class RealContentHashPlugin {
223
226
  stage: Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_HASH
224
227
  },
225
228
  async () => {
229
+ // Set by the deferred fill where a baked name would leave a hashed name
230
+ // stale; only then is `[chunkhash]` repaired rather than left as named.
231
+ const repairing = compilation.runtimeTemplate.needsAnalyzableRepair();
232
+ if (this._onDemand && !repairing) return;
233
+ // On demand, only a name the fill left stale moves, and whatever names it.
234
+ const repairedAssets = this._onDemand
235
+ ? compilation.runtimeTemplate.analyzableRepairedAssets()
236
+ : undefined;
226
237
  const assets = compilation.getAssets();
227
238
  /** @type {AssetInfoForRealContentHash[]} */
228
239
  const assetsWithInfo = [];
@@ -238,6 +249,7 @@ class RealContentHashPlugin {
238
249
  /** @type {Hashes} */
239
250
  const hashes = new Set();
240
251
  addToList(info.contenthash, hashes);
252
+ if (repairing) addToList(info.chunkhash, hashes);
241
253
  if (info.contenthashDigest) {
242
254
  for (const hash of Object.keys(info.contenthashDigest)) {
243
255
  hashToDigest.set(hash, info.contenthashDigest[hash]);
@@ -345,47 +357,68 @@ ${referencingAssets
345
357
  }
346
358
  return hashes;
347
359
  };
360
+ // Tarjan: hashes naming each other come out as one group where a chain
361
+ // walk would never end, and groups arrive dependencies-first as needed.
362
+ /** @type {string[][]} */
363
+ const groupsInOrder = [];
364
+ /** @type {Map<string, number>} */
365
+ const indexOf = new Map();
366
+ /** @type {Map<string, number>} */
367
+ const lowOf = new Map();
368
+ /** @type {Set<string>} */
369
+ const onStack = new Set();
370
+ /** @type {string[]} */
371
+ const stack = [];
348
372
  /**
349
- * Returns the hash info.
373
+ * Visits one hash and everything its assets reference.
350
374
  * @param {string} hash the hash
351
- * @returns {string} the hash info
375
+ * @returns {void}
352
376
  */
353
- const hashInfo = (hash) => {
354
- const assets = hashToAssets.get(hash);
355
- return `${hash} (${Array.from(
356
- /** @type {AssetInfoForRealContentHash[]} */ (assets),
357
- (a) => a.name
358
- )})`;
359
- };
360
- /** @type {Hashes} */
361
- const hashesInOrder = new Set();
362
- for (const hash of hashToAssets.keys()) {
363
- /**
364
- * Processes the provided hash.
365
- * @param {string} hash the hash
366
- * @param {Set<string>} stack stack of hashes
367
- */
368
- const add = (hash, stack) => {
369
- const deps = getDependencies(hash);
370
- if (!deps) return;
371
- stack.add(hash);
377
+ const strongConnect = (hash) => {
378
+ const index = indexOf.size;
379
+ indexOf.set(hash, index);
380
+ lowOf.set(hash, index);
381
+ stack.push(hash);
382
+ onStack.add(hash);
383
+ // An unowned reference reports the caching problem and stays a leaf.
384
+ const deps = getDependencies(hash);
385
+ if (deps) {
372
386
  for (const dep of deps) {
373
- if (hashesInOrder.has(dep)) continue;
374
- if (stack.has(dep)) {
375
- throw new Error(
376
- `Circular hash dependency ${Array.from(
377
- stack,
378
- hashInfo
379
- ).join(" -> ")} -> ${hashInfo(dep)}`
387
+ if (!indexOf.has(dep)) {
388
+ strongConnect(dep);
389
+ lowOf.set(
390
+ hash,
391
+ Math.min(
392
+ /** @type {number} */ (lowOf.get(hash)),
393
+ /** @type {number} */ (lowOf.get(dep))
394
+ )
395
+ );
396
+ } else if (onStack.has(dep)) {
397
+ lowOf.set(
398
+ hash,
399
+ Math.min(
400
+ /** @type {number} */ (lowOf.get(hash)),
401
+ /** @type {number} */ (indexOf.get(dep))
402
+ )
380
403
  );
381
404
  }
382
- add(dep, stack);
383
405
  }
384
- hashesInOrder.add(hash);
385
- stack.delete(hash);
386
- };
387
- if (hashesInOrder.has(hash)) continue;
388
- add(hash, new Set());
406
+ }
407
+ if (lowOf.get(hash) === indexOf.get(hash)) {
408
+ /** @type {string[]} */
409
+ const group = [];
410
+ /** @type {string} */
411
+ let member;
412
+ do {
413
+ member = /** @type {string} */ (stack.pop());
414
+ onStack.delete(member);
415
+ if (hashToAssets.has(member)) group.push(member);
416
+ } while (member !== hash);
417
+ if (group.length > 0) groupsInOrder.push(group);
418
+ }
419
+ };
420
+ for (const hash of hashToAssets.keys()) {
421
+ if (!indexOf.has(hash)) strongConnect(hash);
389
422
  }
390
423
  /** @type {Map<string, string>} */
391
424
  const hashToNewHash = new Map();
@@ -474,7 +507,99 @@ ${referencingAssets
474
507
  };
475
508
  /** @type {Comparator<AssetInfoForRealContentHash>} */
476
509
  const comparator = compareSelect((a) => a.name, compareStrings);
477
- for (const oldHash of hashesInOrder) {
510
+ /**
511
+ * Whether a group's names went stale: the fill rewrote an asset of theirs, or
512
+ * one names a hash that already moved (groups arrive dependencies first).
513
+ * @param {string[]} group the hashes assigned together
514
+ * @returns {boolean} true when they have to be recomputed
515
+ */
516
+ const staleOnDemand = (group) => {
517
+ const own = new Set(group);
518
+ for (const hash of group) {
519
+ for (const asset of /** @type {AssetInfoForRealContentHash[]} */ (
520
+ hashToAssets.get(hash)
521
+ )) {
522
+ if (
523
+ /** @type {ReadonlySet<string>} */ (repairedAssets).has(
524
+ asset.name
525
+ )
526
+ ) {
527
+ return true;
528
+ }
529
+ for (const referenced of /** @type {Hashes} */ (
530
+ asset.referencedHashes
531
+ )) {
532
+ if (
533
+ !own.has(referenced) &&
534
+ hashToNewHash.get(referenced) !== referenced
535
+ ) {
536
+ return true;
537
+ }
538
+ }
539
+ }
540
+ }
541
+ return false;
542
+ };
543
+ for (const group of groupsInOrder) {
544
+ if (repairedAssets !== undefined && !staleOnDemand(group)) {
545
+ for (const hash of group) hashToNewHash.set(hash, hash);
546
+ continue;
547
+ }
548
+ // A cycle is assigned as one group: members are told apart by stable
549
+ // markers, so the group hashes to a fixed point instead of chasing one.
550
+ if (group.length > 1) {
551
+ const members = group.sort();
552
+ /** @type {Map<string, string>} */
553
+ const markerOf = new Map(
554
+ members.map((hash, i) => [hash, `|webpack/scc/${i}|`])
555
+ );
556
+ for (let i = 0; i < members.length; i++) {
557
+ const oldHash = members[i];
558
+ const memberAssets =
559
+ /** @type {AssetInfoForRealContentHash[]} */
560
+ (hashToAssets.get(oldHash));
561
+ memberAssets.sort(comparator);
562
+ const hash = createHash(this._hashFunction);
563
+ if (compilation.outputOptions.hashSalt) {
564
+ hash.update(compilation.outputOptions.hashSalt);
565
+ }
566
+ // Two members can normalize to the same text; the position keeps
567
+ // their hashes apart, and sorting keeps the position stable.
568
+ hash.update(`${i}`);
569
+ for (const asset of memberAssets) {
570
+ if (Buffer.isBuffer(asset.content)) {
571
+ hash.update(asset.content);
572
+ continue;
573
+ }
574
+ const withoutOwn =
575
+ /** @type {Hashes} */
576
+ (asset.ownHashes).has(oldHash);
577
+ hash.update(
578
+ asset.content.replace(hashRegExp, (matched) => {
579
+ // Its own occurrences vanish, exactly as a lone hash's do.
580
+ if (
581
+ withoutOwn &&
582
+ /** @type {Hashes} */ (asset.ownHashes).has(matched)
583
+ ) {
584
+ return "";
585
+ }
586
+ const marker = markerOf.get(matched);
587
+ if (marker !== undefined) return marker;
588
+ const mapped = hashToNewHash.get(matched);
589
+ return mapped === undefined ? matched : mapped;
590
+ })
591
+ );
592
+ }
593
+ const digest = hash.digest(
594
+ /** @type {HashDigest} */ (
595
+ hashToDigest.get(oldHash) || this._hashDigest
596
+ )
597
+ );
598
+ hashToNewHash.set(oldHash, digest.slice(0, oldHash.length));
599
+ }
600
+ continue;
601
+ }
602
+ const oldHash = group[0];
478
603
  const assets =
479
604
  /** @type {AssetInfoForRealContentHash[]} */
480
605
  (hashToAssets.get(oldHash));
@@ -532,15 +657,25 @@ ${referencingAssets
532
657
  (hash) => /** @type {string} */ (hashToNewHash.get(hash))
533
658
  );
534
659
 
660
+ /**
661
+ * @param {string | string[]} hash what the asset was named with
662
+ * @returns {string | string[]} the same, repaired
663
+ */
664
+ const repaired = (hash) =>
665
+ Array.isArray(hash)
666
+ ? hash.map(
667
+ (hash) => /** @type {string} */ (hashToNewHash.get(hash))
668
+ )
669
+ : /** @type {string} */ (hashToNewHash.get(hash));
670
+ /** @type {AssetInfo} */
535
671
  const infoUpdate = {};
536
- const hash =
537
- /** @type {Exclude<AssetInfo["contenthash"], undefined>} */
538
- (asset.info.contenthash);
539
- infoUpdate.contenthash = Array.isArray(hash)
540
- ? hash.map(
541
- (hash) => /** @type {string} */ (hashToNewHash.get(hash))
542
- )
543
- : /** @type {string} */ (hashToNewHash.get(hash));
672
+ if (asset.info.contenthash) {
673
+ infoUpdate.contenthash = repaired(asset.info.contenthash);
674
+ }
675
+ // Tracked only while repairing, so only then does it move with the name.
676
+ if (repairing && asset.info.chunkhash) {
677
+ infoUpdate.chunkhash = repaired(asset.info.chunkhash);
678
+ }
544
679
 
545
680
  if (asset.newSource !== undefined) {
546
681
  compilation.updateAsset(