@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
@@ -85,6 +85,7 @@ const { NODE_MODULES_REGEXP } = require("./util/identifier");
85
85
  /** @import { WebpackOptionsInterception } from "./config/normalization" */
86
86
  /** @import Compiler from "./Compiler" */
87
87
  /** @import { InputFileSystem, IntermediateFileSystem } from "./util/fs" */
88
+ /** @import { ResolveOptionsWithDependencyType } from "./ResolverFactory" */
88
89
 
89
90
  const CLASS_NAME = "WebpackOptionsApply";
90
91
 
@@ -425,6 +426,12 @@ class WebpackOptionsApply extends OptionsApply {
425
426
  ).apply(compiler);
426
427
  }
427
428
 
429
+ if (options.output.copy) {
430
+ const CopyPlugin = require("./CopyPlugin");
431
+
432
+ new CopyPlugin(options.output.copy).apply(compiler);
433
+ }
434
+
428
435
  if (options.dotenv) {
429
436
  const DotenvPlugin = require("./DotenvPlugin");
430
437
 
@@ -496,32 +503,6 @@ class WebpackOptionsApply extends OptionsApply {
496
503
  sideEffectFree: options.experiments.futureDefaults
497
504
  }).apply(compiler);
498
505
 
499
- if (!options.experiments.outputModule) {
500
- if (options.output.module) {
501
- throw new Error(
502
- "'output.module: true' is only allowed when 'experiments.outputModule' is enabled"
503
- );
504
- }
505
- if (options.output.enabledLibraryTypes.includes("module")) {
506
- throw new Error(
507
- "library type \"module\" is only allowed when 'experiments.outputModule' is enabled"
508
- );
509
- }
510
- if (options.output.enabledLibraryTypes.includes("modern-module")) {
511
- throw new Error(
512
- "library type \"modern-module\" is only allowed when 'experiments.outputModule' is enabled"
513
- );
514
- }
515
- if (
516
- options.externalsType === "module" ||
517
- options.externalsType === "module-import"
518
- ) {
519
- throw new Error(
520
- "'externalsType: \"module\"' is only allowed when 'experiments.outputModule' is enabled"
521
- );
522
- }
523
- }
524
-
525
506
  if (options.output.module) {
526
507
  // Analyzable output is ESM output, so this is every build that can reserve a name.
527
508
  const RuntimeTemplate = require("./RuntimeTemplate");
@@ -738,8 +719,10 @@ class WebpackOptionsApply extends OptionsApply {
738
719
  options.performance && options.performance.circularDependencies
739
720
  ? options.performance.hints
740
721
  : false;
722
+ // ConstExportsPlugin Binding checks need CircularModulesPlugin when this is on.
723
+ const inlineExports = options.optimization.inlineExports;
741
724
 
742
- if (options.mode === "production" || circularHints) {
725
+ if (options.mode === "production" || circularHints || inlineExports) {
743
726
  const CircularModulesPlugin = require("./CircularModulesPlugin");
744
727
 
745
728
  new CircularModulesPlugin({ hints: circularHints }).apply(compiler);
@@ -748,7 +731,7 @@ class WebpackOptionsApply extends OptionsApply {
748
731
  const ConstExportsPlugin = require("./optimize/ConstExportsPlugin");
749
732
 
750
733
  new ConstExportsPlugin({
751
- inlineExports: options.optimization.inlineExports
734
+ inlineExports
752
735
  }).apply(compiler);
753
736
 
754
737
  if (options.optimization.mangleExports) {
@@ -778,7 +761,9 @@ class WebpackOptionsApply extends OptionsApply {
778
761
 
779
762
  new NoEmitOnErrorsPlugin().apply(compiler);
780
763
  }
781
- if (options.optimization.realContentHash) {
764
+ // ESM output may bake a name into a chunk whose hashed name would then go stale;
765
+ // the repair runs for those alone where it was not asked for outright.
766
+ if (options.optimization.realContentHash || options.output.module) {
782
767
  const RealContentHashPlugin = require("./optimize/RealContentHashPlugin");
783
768
 
784
769
  new RealContentHashPlugin({
@@ -787,7 +772,8 @@ class WebpackOptionsApply extends OptionsApply {
787
772
  (options.output.hashFunction),
788
773
  hashDigest:
789
774
  /** @type {NonNullable<WebpackOptions["output"]["hashDigest"]>} */
790
- (options.output.hashDigest)
775
+ (options.output.hashDigest),
776
+ onDemand: !options.optimization.realContentHash
791
777
  }).apply(compiler);
792
778
  }
793
779
  if (options.optimization.checkWasmTypes) {
@@ -906,7 +892,7 @@ class WebpackOptionsApply extends OptionsApply {
906
892
  ? publicPath
907
893
  : "/";
908
894
 
909
- // Marked internal: these keys are webpack's, so `performance.unusedDefines`
895
+ // Marked internal: these keys are webpack's, so `performance.unusedConfig`
910
896
  // must not report them against the user.
911
897
  DefinePlugin.markInternal(
912
898
  new DefinePlugin({
@@ -966,18 +952,18 @@ class WebpackOptionsApply extends OptionsApply {
966
952
  new RedundantDynamicImportsPlugin(options.performance).apply(compiler);
967
953
  }
968
954
 
969
- if (options.performance.entrypointOverlap) {
970
- const EntrypointOverlapPlugin = require("./performance/EntrypointOverlapPlugin");
971
-
972
- new EntrypointOverlapPlugin(options.performance).apply(compiler);
973
- }
974
-
975
955
  if (options.performance.largeModules) {
976
956
  const LargeModulesPlugin = require("./performance/LargeModulesPlugin");
977
957
 
978
958
  new LargeModulesPlugin(options.performance).apply(compiler);
979
959
  }
980
960
 
961
+ if (options.performance.analyzableBailouts) {
962
+ const AnalyzableBailoutsPlugin = require("./performance/AnalyzableBailoutsPlugin");
963
+
964
+ new AnalyzableBailoutsPlugin(options.performance).apply(compiler);
965
+ }
966
+
981
967
  if (options.performance.asyncChunkWaterfalls) {
982
968
  const AsyncChunkWaterfallsPlugin = require("./performance/AsyncChunkWaterfallsPlugin");
983
969
 
@@ -1044,12 +1030,6 @@ class WebpackOptionsApply extends OptionsApply {
1044
1030
  new DynamicExportsPlugin(options.performance).apply(compiler);
1045
1031
  }
1046
1032
 
1047
- if (options.performance.embeddedSourceMaps) {
1048
- const EmbeddedSourceMapsPlugin = require("./performance/EmbeddedSourceMapsPlugin");
1049
-
1050
- new EmbeddedSourceMapsPlugin(options.performance).apply(compiler);
1051
- }
1052
-
1053
1033
  if (options.performance.inlinedAssets) {
1054
1034
  const InlinedAssetsPlugin = require("./performance/InlinedAssetsPlugin");
1055
1035
 
@@ -1068,42 +1048,56 @@ class WebpackOptionsApply extends OptionsApply {
1068
1048
  new ScopeHoistingBailoutsPlugin(options.performance).apply(compiler);
1069
1049
  }
1070
1050
 
1071
- if (options.performance.unusedReexports) {
1072
- const UnusedReexportsPlugin = require("./performance/UnusedReexportsPlugin");
1051
+ // One switch for source maps: a devtool that ships the map to everyone,
1052
+ // and a loader that loses it, are both about the map being worth its cost.
1053
+ if (options.performance.sourceMaps) {
1054
+ const EmbeddedSourceMapsPlugin = require("./performance/EmbeddedSourceMapsPlugin");
1055
+ const MissingSourceMapsPlugin = require("./performance/MissingSourceMapsPlugin");
1073
1056
 
1074
- new UnusedReexportsPlugin(options.performance).apply(compiler);
1057
+ new EmbeddedSourceMapsPlugin(options.performance).apply(compiler);
1058
+ new MissingSourceMapsPlugin(options.performance).apply(compiler);
1075
1059
  }
1076
1060
 
1077
- // Deliberately not gated on `hints`, like `unusedRules` below: a rule
1078
- // that only matches on one OS is a configuration mistake, not a size.
1079
- if (options.performance.osDependentRules) {
1080
- const OsDependentRuleWarningPlugin = require("./performance/OsDependentRuleWarningPlugin");
1061
+ // One switch for configuration that did nothing: the four read different
1062
+ // parts of the config, but the finding and the fix are the same.
1063
+ if (options.performance.unusedConfig) {
1064
+ const UnusedAliasesPlugin = require("./performance/UnusedAliasesPlugin");
1065
+ const UnusedDefinesPlugin = require("./performance/UnusedDefinesPlugin");
1066
+ const UnusedExternalsPlugin = require("./performance/UnusedExternalsPlugin");
1067
+ const UnusedFederationPlugin = require("./performance/UnusedFederationPlugin");
1068
+ // Reports even where size hints are off: a dead rule is a configuration
1069
+ // mistake either way.
1070
+ const UnusedRuleWarningPlugin = require("./performance/UnusedRuleWarningPlugin");
1081
1071
 
1082
- new OsDependentRuleWarningPlugin(options.performance).apply(compiler);
1072
+ new UnusedAliasesPlugin(options.performance).apply(compiler);
1073
+ new UnusedDefinesPlugin(options.performance).apply(compiler);
1074
+ new UnusedExternalsPlugin(options.performance).apply(compiler);
1075
+ new UnusedFederationPlugin(options.performance).apply(compiler);
1076
+ new UnusedRuleWarningPlugin(options.performance).apply(compiler);
1083
1077
  }
1084
1078
 
1085
- // Deliberately not gated on `hints`: an alias nothing matches is a
1086
- // configuration mistake, not a size.
1087
- if (options.performance.unusedAliases) {
1088
- const UnusedAliasesPlugin = require("./performance/UnusedAliasesPlugin");
1079
+ // One switch for a module nothing uses: the two differ only in what kept
1080
+ // it there, and each names the cause it knows about.
1081
+ if (options.performance.unusedModules) {
1082
+ const UnusedModulesPlugin = require("./performance/UnusedModulesPlugin");
1083
+ const UnusedReexportsPlugin = require("./performance/UnusedReexportsPlugin");
1089
1084
 
1090
- new UnusedAliasesPlugin(options.performance).apply(compiler);
1085
+ new UnusedModulesPlugin(options.performance).apply(compiler);
1086
+ new UnusedReexportsPlugin(options.performance).apply(compiler);
1091
1087
  }
1092
1088
 
1093
- // Deliberately not gated on `hints`: a key nothing reads is a
1094
- // configuration mistake, not a size.
1095
- if (options.performance.unusedDefines) {
1096
- const UnusedDefinesPlugin = require("./performance/UnusedDefinesPlugin");
1089
+ // Deliberately not gated on `hints`, like `unusedConfig` above: a rule
1090
+ // that only matches on one OS is a configuration mistake, not a size.
1091
+ if (options.performance.osDependentRules) {
1092
+ const OsDependentRuleWarningPlugin = require("./performance/OsDependentRuleWarningPlugin");
1097
1093
 
1098
- new UnusedDefinesPlugin(options.performance).apply(compiler);
1094
+ new OsDependentRuleWarningPlugin(options.performance).apply(compiler);
1099
1095
  }
1100
1096
 
1101
- // Deliberately not gated on `hints`: a misspelled external gets bundled
1102
- // instead, which no size limit would explain.
1103
- if (options.performance.unusedExternals) {
1104
- const UnusedExternalsPlugin = require("./performance/UnusedExternalsPlugin");
1097
+ if (options.performance.unusedAssets) {
1098
+ const UnusedAssetsPlugin = require("./performance/UnusedAssetsPlugin");
1105
1099
 
1106
- new UnusedExternalsPlugin(options.performance).apply(compiler);
1100
+ new UnusedAssetsPlugin(options.performance).apply(compiler);
1107
1101
  }
1108
1102
 
1109
1103
  // Deliberately not gated on `hints`: asking for both directives on one
@@ -1113,14 +1107,6 @@ class WebpackOptionsApply extends OptionsApply {
1113
1107
 
1114
1108
  new ConflictingResourceHintsPlugin(options.performance).apply(compiler);
1115
1109
  }
1116
-
1117
- // Deliberately not gated on `hints`: a dead rule is a configuration
1118
- // mistake worth reporting even where size hints are off.
1119
- if (options.performance.unusedRules) {
1120
- const UnusedRuleWarningPlugin = require("./performance/UnusedRuleWarningPlugin");
1121
-
1122
- new UnusedRuleWarningPlugin(options.performance).apply(compiler);
1123
- }
1124
1110
  }
1125
1111
 
1126
1112
  new TemplatedPathPlugin().apply(compiler);
@@ -1258,34 +1244,41 @@ class WebpackOptionsApply extends OptionsApply {
1258
1244
  if (!compiler.inputFileSystem) {
1259
1245
  throw new Error("No input filesystem provided");
1260
1246
  }
1261
- compiler.resolverFactory.hooks.resolveOptions
1262
- .for("normal")
1263
- .tap(CLASS_NAME, (resolveOptions) => {
1264
- resolveOptions = cleverMerge(options.resolve, resolveOptions);
1247
+ /**
1248
+ * Supplies the compiler's input filesystem as the default for a resolver.
1249
+ * A filesystem set in the configuration is kept, so that `resolve.fileSystem`
1250
+ * reaches enhanced-resolve the way `resolve.resolver` already does.
1251
+ * @param {ResolveOptionsWithDependencyType} resolveOptions merged resolve options
1252
+ * @returns {ResolveOptionsWithDependencyType} the same options
1253
+ */
1254
+ const withFileSystem = (resolveOptions) => {
1255
+ if (!resolveOptions.fileSystem) {
1265
1256
  resolveOptions.fileSystem =
1266
1257
  /** @type {InputFileSystem} */
1267
1258
  (compiler.inputFileSystem);
1268
- return resolveOptions;
1269
- });
1259
+ }
1260
+ return resolveOptions;
1261
+ };
1262
+
1263
+ compiler.resolverFactory.hooks.resolveOptions
1264
+ .for("normal")
1265
+ .tap(CLASS_NAME, (resolveOptions) =>
1266
+ withFileSystem(cleverMerge(options.resolve, resolveOptions))
1267
+ );
1270
1268
  compiler.resolverFactory.hooks.resolveOptions
1271
1269
  .for("context")
1272
1270
  .tap(CLASS_NAME, (resolveOptions) => {
1273
- resolveOptions = cleverMerge(options.resolve, resolveOptions);
1274
- resolveOptions.fileSystem =
1275
- /** @type {InputFileSystem} */
1276
- (compiler.inputFileSystem);
1271
+ resolveOptions = withFileSystem(
1272
+ cleverMerge(options.resolve, resolveOptions)
1273
+ );
1277
1274
  resolveOptions.resolveToContext = true;
1278
1275
  return resolveOptions;
1279
1276
  });
1280
1277
  compiler.resolverFactory.hooks.resolveOptions
1281
1278
  .for("loader")
1282
- .tap(CLASS_NAME, (resolveOptions) => {
1283
- resolveOptions = cleverMerge(options.resolveLoader, resolveOptions);
1284
- resolveOptions.fileSystem =
1285
- /** @type {InputFileSystem} */
1286
- (compiler.inputFileSystem);
1287
- return resolveOptions;
1288
- });
1279
+ .tap(CLASS_NAME, (resolveOptions) =>
1280
+ withFileSystem(cleverMerge(options.resolveLoader, resolveOptions))
1281
+ );
1289
1282
  compiler.hooks.afterResolvers.call(compiler);
1290
1283
  return options;
1291
1284
  }
@@ -114,7 +114,13 @@ class AssetBytesGenerator extends Generator {
114
114
  generateError(error, module, generateContext) {
115
115
  switch (generateContext.type) {
116
116
  case JAVASCRIPT_TYPE: {
117
- return new RawSource(Generator.throwBuildErrorCode(error));
117
+ return new RawSource(
118
+ Generator.throwBuildErrorCode(
119
+ error,
120
+ undefined,
121
+ generateContext.runtimeTemplate.requestShortener
122
+ )
123
+ );
118
124
  }
119
125
  default:
120
126
  return null;
@@ -28,7 +28,7 @@ const URLDependency = require("../dependencies/URLDependency");
28
28
  const { getScheme } = require("../util/URLAbsoluteSpecifier");
29
29
  const createHash = require("../util/createHash");
30
30
  const { languageOfMediaType } = require("../util/dataURL");
31
- const { makePathsRelative } = require("../util/identifier");
31
+ const { makePathsRelative, parseResource } = require("../util/identifier");
32
32
  const memoize = require("../util/memoize");
33
33
  const nonNumericOnlyHash = require("../util/nonNumericOnlyHash");
34
34
  const {
@@ -55,7 +55,6 @@ const getMimeTypes = memoize(() => require("../util/mimeTypes"));
55
55
  /** @import { GenerateContext, UpdateHashContext } from "../Generator" */
56
56
  /**
57
57
  * @import Module, {
58
- * NameForCondition,
59
58
  * ConcatenationBailoutReasonContext,
60
59
  * SourceType,
61
60
  * SourceTypes
@@ -250,12 +249,27 @@ class AssetGenerator extends Generator {
250
249
  static getSourceFileName(module, runtimeTemplate) {
251
250
  return makePathsRelative(
252
251
  runtimeTemplate.compilation.compiler.context,
253
- /** @type {string} */
254
- (module.getResource()),
252
+ AssetGenerator.getAssetResource(module),
255
253
  runtimeTemplate.compilation.compiler.root
256
254
  ).replace(/^\.\//, "");
257
255
  }
258
256
 
257
+ /**
258
+ * The resource this asset is named after, which something that re-encoded it
259
+ * may have changed. Its emitted name and inlined media type both read this.
260
+ * @param {NormalModule} module module
261
+ * @returns {string} the resource
262
+ */
263
+ static getAssetResource(module) {
264
+ const buildInfo = /** @type {AssetModuleBuildInfo | undefined} */ (
265
+ module.buildInfo
266
+ );
267
+
268
+ return /** @type {string} */ (
269
+ (buildInfo && buildInfo.assetResource) || module.getResource()
270
+ );
271
+ }
272
+
259
273
  /**
260
274
  * Gets the source file name as seen by a filename template. With
261
275
  * `experiments.futureDefaults` (webpack 6 default) `[path]` and `[file]` of a
@@ -504,11 +518,14 @@ class AssetGenerator extends Generator {
504
518
  /** @type {AssetGeneratorDataUrlOptions} */
505
519
  (this.dataUrlOptions).mimetype;
506
520
  if (mimeType === undefined) {
507
- const ext = path.extname(
508
- /** @type {NameForCondition} */
509
- (module.nameForCondition())
510
- );
521
+ // The resource as it now is, minus the query and fragment a request
522
+ // carries into it.
523
+ const resource = AssetGenerator.getAssetResource(module);
524
+ const ext = path.extname(parseResource(resource).path);
525
+ // `resourceResolveData` describes what was read; once something
526
+ // re-encoded it, only the new extension says what the bytes are.
511
527
  if (
528
+ resource === module.getResource() &&
512
529
  module.resourceResolveData &&
513
530
  module.resourceResolveData.mimetype !== undefined
514
531
  ) {
@@ -774,10 +791,21 @@ class AssetGenerator extends Generator {
774
791
  generateError(error, module, generateContext) {
775
792
  switch (generateContext.type) {
776
793
  case "asset": {
777
- return new RawSource(error.message);
794
+ return new RawSource(
795
+ Generator.buildErrorMessage(
796
+ error,
797
+ generateContext.runtimeTemplate.requestShortener
798
+ )
799
+ );
778
800
  }
779
801
  case JAVASCRIPT_TYPE: {
780
- return new RawSource(Generator.throwBuildErrorCode(error));
802
+ return new RawSource(
803
+ Generator.throwBuildErrorCode(
804
+ error,
805
+ undefined,
806
+ generateContext.runtimeTemplate.requestShortener
807
+ )
808
+ );
781
809
  }
782
810
  default:
783
811
  return null;
@@ -819,13 +847,14 @@ class AssetGenerator extends Generator {
819
847
  /** @type {AssetModuleBuildInfo} */ (module.buildInfo).dataUrl
820
848
  ) && this.emit !== false;
821
849
 
822
- // Only analyzable ESM output can drop a bare `new URL()` to an asset-url; without
823
- // it every JS consumer needs the wrapper, so skip the per-connection dependency
824
- // probe entirely and keep the pre-existing cheap path. Must match the condition
825
- // `URLDependency` uses to emit the literal, or the wrapper is dropped while the
826
- // call site still requires the module — except where the fallback spells the name
827
- // itself (`.p + <file>`), which needs no wrapper to read it out of.
828
- // Build-time execution instead emulates the wrapper (`AssetModulesPlugin`).
850
+ // WHY: only analyzable ESM output can drop a bare `new URL()` to an asset
851
+ // url; without it every JS consumer needs the wrapper, so the per-connection
852
+ // dependency probe is skipped entirely and the cheap path stands. This must
853
+ // match the condition `URLDependency` emits the literal under, or the wrapper
854
+ // is dropped while the call site still requires the module — except where the
855
+ // fallback spells the name itself (`.p + <file>`), which needs no wrapper to
856
+ // read it out of. Build-time execution emulates the wrapper instead
857
+ // (`AssetModulesPlugin`).
829
858
  const isModule = Boolean(
830
859
  this._compilation &&
831
860
  this._compilation.runtimeTemplate.supportsAnalyzable(
@@ -857,9 +886,8 @@ class AssetGenerator extends Generator {
857
886
  hasUrl = true;
858
887
  } else if (
859
888
  // Only a bare `new URL()` becomes the analyzable literal; a relative ref
860
- // keeps the runtime form and still needs the wrapper. Prefetch/preload
861
- // refs don't: their `<link>` is emitted at chunk startup, which resolves
862
- // the href from the asset filename when there is no wrapper.
889
+ // keeps the runtime form and its wrapper. A prefetch or preload ref needs
890
+ // none: its `<link>` resolves the href at chunk startup.
863
891
  isModule &&
864
892
  dependency instanceof URLDependency &&
865
893
  !dependency.relative
@@ -944,10 +972,8 @@ class AssetGenerator extends Generator {
944
972
  return 0;
945
973
  }
946
974
 
947
- // roughly for data url
948
- // Example: m.exports="data:image/png;base64,ag82/f+2=="
949
- // 4/3 = base64 encoding
950
- // 34 = ~ data url header + footer + rounding
975
+ // Rough data-url size: 4/3 for the base64 encoding, plus about 34 bytes
976
+ // of header, footer and rounding.
951
977
  return originalSource.size() * 1.34 + 36;
952
978
  }
953
979
  // it's only estimated so this number is probably fine
@@ -22,6 +22,9 @@ const makeSerializable = require("../util/makeSerializable");
22
22
  * @property {string=} filename
23
23
  * @property {AssetInfo=} assetInfo
24
24
  * @property {string=} fullContentHash
25
+ * @property {string=} assetResource the resource this asset is named after, when
26
+ * something re-encoded it. Unlike `matchResource` this is serialized, so a
27
+ * rename set while building survives the persistent cache
25
28
  */
26
29
 
27
30
  /** @typedef {NormalModuleBuildInfo & KnownAssetModuleBuildInfo} AssetModuleBuildInfo */
@@ -158,7 +158,13 @@ class AssetSourceGenerator extends Generator {
158
158
  generateError(error, module, generateContext) {
159
159
  switch (generateContext.type) {
160
160
  case JAVASCRIPT_TYPE: {
161
- return new RawSource(Generator.throwBuildErrorCode(error));
161
+ return new RawSource(
162
+ Generator.throwBuildErrorCode(
163
+ error,
164
+ undefined,
165
+ generateContext.runtimeTemplate.requestShortener
166
+ )
167
+ );
162
168
  }
163
169
  default:
164
170
  return null;
@@ -5,15 +5,15 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const { parse } = require("acorn");
9
8
  const Parser = require("../Parser");
10
9
  const HtmlSourceDependency = require("../dependencies/HtmlSourceDependency");
10
+ const { parse } = require("../javascript/syntax");
11
11
 
12
12
  /** @import { Expression, ObjectExpression, Program, Property } from "estree" */
13
13
  /** @import { BuildInfo } from "../Module" */
14
14
  /** @import { ParserState, PreparsedAst } from "../Parser" */
15
15
 
16
- // acorn decorates every node with numeric source offsets (absent from the estree types).
16
+ // the parser decorates every node with numeric source offsets (absent from the estree types).
17
17
  /** @typedef {{ start: number, end: number }} Positioned */
18
18
 
19
19
  // A URL carrying its own scheme (`https:`, `data:`, …) is external; it is only
@@ -70,9 +70,11 @@ class WebManifestParser extends Parser {
70
70
  let ast;
71
71
  try {
72
72
  // Wrap in parens so the top-level object is an expression, not a block.
73
- ast = /** @type {Program} */ (
74
- /** @type {unknown} */ (parse(`(${source})`, { ecmaVersion: "latest" }))
75
- );
73
+ ast = parse(`(${source})`, {
74
+ ecmaVersion: "latest",
75
+ sourceType: "script",
76
+ lazyNodes: true
77
+ });
76
78
  } catch (_err) {
77
79
  // Not valid JSON — leave the file untouched (still emitted as-is).
78
80
  ast = undefined;
@@ -32,16 +32,22 @@ const getOutgoingAsyncModules = (moduleGraph, module) => {
32
32
  const outgoingConnectionMap =
33
33
  moduleGraph.getOutgoingConnectionsByModule(module);
34
34
  if (outgoingConnectionMap) {
35
- for (const [module, connections] of outgoingConnectionMap) {
35
+ // Walk the imports in source order: the spec gathers these from
36
+ // `[[RequestedModules]]`, and their evaluation order is observable.
37
+ for (const dependency of module.dependencies) {
38
+ if (!(dependency instanceof HarmonyImportDependency)) continue;
39
+ const referenced = moduleGraph.getModule(dependency);
40
+ if (!referenced || seen.has(referenced)) continue;
41
+ const connections = outgoingConnectionMap.get(referenced);
36
42
  if (
43
+ connections &&
37
44
  connections.some(
38
45
  (c) =>
39
46
  c.dependency instanceof HarmonyImportDependency &&
40
47
  c.isTargetActive(undefined)
41
- ) &&
42
- module
48
+ )
43
49
  ) {
44
- g(module);
50
+ g(referenced);
45
51
  }
46
52
  }
47
53
  }
@@ -641,16 +641,13 @@ const visitModules = (
641
641
  }
642
642
  } else {
643
643
  entrypoint = /** @type {Entrypoint} */ (cgi.chunkGroup);
644
- // Fill in options the existing entrypoint hasn't set yet. We never
645
- // overwrite: blocks that dedupe to one entrypoint (e.g. several
646
- // workers pointing at the same module) legitimately carry distinct
647
- // values such as `runtime`, so the first block to create the
648
- // entrypoint wins and later ones only contribute missing keys.
649
- // `name` is excluded: it is the entrypoint's identity, fixed at
650
- // creation (and used to key namedChunkGroups), so back-filling it
651
- // from a block that deduped in via its module would leave
652
- // `entrypoint.name` out of sync and make module codegen
653
- // order-dependent, which breaks persistent caching.
644
+ // Fill in only the options still unset: blocks deduping to one
645
+ // entrypoint may carry different values, so the first to create it
646
+ // wins.
647
+
648
+ // `name` is excluded, being the entrypoint's identity and fixed at
649
+ // creation. Back-filling it would make codegen order-dependent, which
650
+ // breaks persistent caching.
654
651
  const existingOptions = entrypoint.options;
655
652
  for (const key_ of Object.keys(entryOptions)) {
656
653
  const key =
@@ -1370,11 +1367,10 @@ const connectChunkGroups = (
1370
1367
 
1371
1368
  // For each edge in the basic chunk graph
1372
1369
  for (const [block, connections] of blockConnections) {
1373
- // 1. Check if connection is needed
1374
- // When none of the dependencies need to be connected
1375
- // we can skip all of them
1376
- // It's not possible to filter each item so it doesn't create inconsistent
1377
- // connections and modules can only create one version
1370
+ // Skip the whole set when no dependency needs connecting. They cannot be
1371
+ // filtered one by one without inconsistent connections, since a module can
1372
+ // only carry one version.
1373
+
1378
1374
  // TODO maybe decide this per runtime
1379
1375
  if (
1380
1376
  // Blocks with nested blocks must stay connected — skipping orphans the
@@ -9,14 +9,36 @@
9
9
 
10
10
  const PLUGIN_NAME = "AddBuildDependenciesPlugin";
11
11
 
12
+ /**
13
+ * @typedef {object} NormalizedBuildDependencyItem
14
+ * @property {string} dependency request to resolve
15
+ * @property {boolean} optional when true the dependency may be missing
16
+ */
17
+
18
+ /**
19
+ * @param {string | { dependency: string, optional?: boolean }} item build dependency
20
+ * @returns {NormalizedBuildDependencyItem} normalized build dependency
21
+ */
22
+ const normalizeBuildDependencyItem = (item) => {
23
+ if (typeof item === "string") {
24
+ return { dependency: item, optional: false };
25
+ }
26
+ return {
27
+ dependency: item.dependency,
28
+ optional: Boolean(item.optional)
29
+ };
30
+ };
31
+
12
32
  class AddBuildDependenciesPlugin {
13
33
  /**
14
34
  * Creates an instance of AddBuildDependenciesPlugin.
15
- * @param {Iterable<string>} buildDependencies list of build dependencies
35
+ * @param {Iterable<string | { dependency: string, optional?: boolean }>} buildDependencies list of build dependencies
16
36
  */
17
37
  constructor(buildDependencies) {
18
- /** @type {Set<string>} */
19
- this.buildDependencies = new Set(buildDependencies);
38
+ /** @type {NormalizedBuildDependencyItem[]} */
39
+ this.buildDependencies = [...buildDependencies].map(
40
+ normalizeBuildDependencyItem
41
+ );
20
42
  }
21
43
 
22
44
  /**
@@ -26,7 +48,14 @@ class AddBuildDependenciesPlugin {
26
48
  */
27
49
  apply(compiler) {
28
50
  compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
29
- compilation.buildDependencies.addAll(this.buildDependencies);
51
+ for (const { dependency, optional } of this.buildDependencies) {
52
+ compilation.buildDependencies.add(dependency);
53
+ if (optional) {
54
+ compilation.optionalBuildDependencies.add(dependency);
55
+ compilation.missingDependencies.add(dependency);
56
+ compilation.fileDependencies.add(dependency);
57
+ }
58
+ }
30
59
  });
31
60
  }
32
61
  }
@@ -98,10 +98,10 @@ class IdleFileCachePlugin {
98
98
 
99
99
  compiler.cache.hooks.storeBuildDependencies.tap(
100
100
  { name: PLUGIN_NAME, stage: Cache.STAGE_DISK },
101
- (dependencies) => {
101
+ (dependencies, optionalDependencies) => {
102
102
  pendingIdleTasks.set(BUILD_DEPENDENCIES_KEY, () =>
103
103
  Promise.resolve().then(() =>
104
- strategy.storeBuildDependencies(dependencies)
104
+ strategy.storeBuildDependencies(dependencies, optionalDependencies)
105
105
  )
106
106
  );
107
107
  }