webpack 5.110.3 → 5.111.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 (208) hide show
  1. package/README.md +5 -0
  2. package/lib/APIPlugin.js +23 -7
  3. package/lib/AutomaticPrefetchPlugin.js +1 -1
  4. package/lib/Cache.js +8 -3
  5. package/lib/CacheFacade.js +1 -1
  6. package/lib/CircularModulesPlugin.js +157 -55
  7. package/lib/CleanPlugin.js +2 -2
  8. package/lib/Compilation.js +320 -302
  9. package/lib/Compiler.js +209 -46
  10. package/lib/ContextModule.js +17 -81
  11. package/lib/ContextModuleFactory.js +1 -1
  12. package/lib/CopyPlugin.js +1054 -0
  13. package/lib/DefinePlugin.js +24 -8
  14. package/lib/ExternalModule.js +41 -14
  15. package/lib/FileSystemInfo.js +17 -14
  16. package/lib/FlagDependencyExportsPlugin.js +45 -21
  17. package/lib/HotModuleReplacementPlugin.js +53 -7
  18. package/lib/JavascriptMetaInfoPlugin.js +5 -3
  19. package/lib/MainTemplate.js +5 -1
  20. package/lib/Module.js +16 -7
  21. package/lib/MultiCompiler.js +1 -1
  22. package/lib/MultiWatching.js +1 -1
  23. package/lib/NormalModule.js +45 -12
  24. package/lib/NormalModuleFactory.js +1 -1
  25. package/lib/RuntimeGlobals.js +21 -7
  26. package/lib/RuntimeModule.js +28 -12
  27. package/lib/RuntimePlugin.js +30 -3
  28. package/lib/RuntimeTemplate.js +780 -475
  29. package/lib/SourceMapDevToolPlugin.js +1 -1
  30. package/lib/Watching.js +9 -0
  31. package/lib/WebpackOptionsApply.js +84 -91
  32. package/lib/asset/AssetGenerator.js +25 -8
  33. package/lib/asset/AssetModule.js +3 -0
  34. package/lib/asset/WebManifestParser.js +7 -5
  35. package/lib/cache/AddBuildDependenciesPlugin.js +33 -4
  36. package/lib/cache/IdleFileCachePlugin.js +2 -2
  37. package/lib/cache/PackFileCacheStrategy.js +14 -1
  38. package/lib/config/browserslistTargetHandler.js +19 -0
  39. package/lib/config/defaults.js +86 -50
  40. package/lib/config/normalization.js +82 -12
  41. package/lib/config/target.js +10 -0
  42. package/lib/container/ContainerReferencePlugin.js +6 -0
  43. package/lib/container/RemoteRuntimeModule.js +9 -0
  44. package/lib/container/declaredRemotes.js +39 -0
  45. package/lib/css/CssGenerator.js +8 -0
  46. package/lib/css/CssInjectStyleRuntimeModule.js +9 -0
  47. package/lib/css/CssLoadingRuntimeModule.js +94 -36
  48. package/lib/css/CssModule.js +1 -1
  49. package/lib/css/CssModulesPlugin.js +7 -6
  50. package/lib/css/CssParser.js +144 -11
  51. package/lib/css/CssServerStylesRuntimeModule.js +9 -0
  52. package/lib/css/cssMinify.js +11 -3
  53. package/lib/css/data.js +2814 -678
  54. package/lib/css/syntax.js +4082 -248
  55. package/lib/debug/ProfilingPlugin.js +4 -0
  56. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +6 -3
  57. package/lib/dependencies/AMDRuntimeModules.js +18 -0
  58. package/lib/dependencies/CommonJsExportRequireDependency.js +3 -1
  59. package/lib/dependencies/CommonJsExportsParserPlugin.js +12 -13
  60. package/lib/dependencies/CommonJsImportsParserPlugin.js +1 -0
  61. package/lib/dependencies/CommonJsPlugin.js +19 -3
  62. package/lib/dependencies/CommonJsRequireDependency.js +14 -5
  63. package/lib/dependencies/CssIcssExportDependency.js +7 -1
  64. package/lib/dependencies/HarmonyCompatibilityDependency.js +58 -4
  65. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +8 -3
  66. package/lib/dependencies/HarmonyExportExpressionDependency.js +44 -29
  67. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +71 -13
  68. package/lib/dependencies/HarmonyExportInitFragment.js +99 -19
  69. package/lib/dependencies/HarmonyExportSpecifierDependency.js +18 -30
  70. package/lib/dependencies/HarmonyImportBareSideEffectDependency.js +59 -0
  71. package/lib/dependencies/HarmonyImportDependency.js +6 -1
  72. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +8 -1
  73. package/lib/dependencies/HarmonyImportSpecifierDependency.js +24 -1
  74. package/lib/dependencies/HarmonyModulesPlugin.js +20 -0
  75. package/lib/dependencies/HtmlEntryDependency.js +50 -0
  76. package/lib/dependencies/ImportMetaMainDependency.js +104 -0
  77. package/lib/dependencies/ImportMetaPlugin.js +59 -15
  78. package/lib/dependencies/SystemRuntimeModule.js +9 -0
  79. package/lib/dependencies/WorkerDependency.js +1 -2
  80. package/lib/dependencies/WorkletDependency.js +1 -2
  81. package/lib/dll/DelegatedModule.js +18 -1
  82. package/lib/dll/DllReferencePlugin.js +11 -8
  83. package/lib/dll/LibManifestPlugin.js +1 -1
  84. package/lib/errors/AnalyzableBailoutsWarning.js +41 -0
  85. package/lib/errors/DuplicateModulesWarning.js +12 -7
  86. package/lib/errors/EmptyCopyPatternWarning.js +26 -0
  87. package/lib/errors/ExternalStarReexportError.js +44 -0
  88. package/lib/errors/MissingSourceMapsWarning.js +36 -0
  89. package/lib/errors/ModuleParseError.js +2 -1
  90. package/lib/errors/UnusedAssetsWarning.js +36 -0
  91. package/lib/errors/UnusedFederationWarning.js +35 -0
  92. package/lib/errors/UnusedModulesWarning.js +38 -0
  93. package/lib/esm/ExportWebpackRequireRuntimeModule.js +9 -0
  94. package/lib/esm/ModuleChunkFormatPlugin.js +28 -3
  95. package/lib/esm/ModuleChunkLoadingPlugin.js +30 -11
  96. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +92 -60
  97. package/lib/hmr/HotModuleReplacement.runtime.js +8 -2
  98. package/lib/hmr/HotModuleReplacementRuntimeModule.js +9 -0
  99. package/lib/html/HtmlGenerator.js +11 -5
  100. package/lib/html/HtmlModulesPlugin.js +331 -62
  101. package/lib/html/HtmlParser.js +13 -6
  102. package/lib/html/builtinEmbeddedRenderer.js +107 -0
  103. package/lib/html/data.js +121 -7
  104. package/lib/html/htmlMinify.js +84 -113
  105. package/lib/html/syntax.js +763 -426
  106. package/lib/ids/HashedModuleIdsPlugin.js +2 -1
  107. package/lib/index.js +3 -0
  108. package/lib/javascript/JavascriptModule.js +1 -0
  109. package/lib/javascript/JavascriptModulesPlugin.js +52 -24
  110. package/lib/javascript/JavascriptParser.js +1255 -728
  111. package/lib/javascript/StartupHelpers.js +27 -3
  112. package/lib/javascript/data.js +172 -0
  113. package/lib/javascript/grammar.js +5546 -0
  114. package/lib/javascript/parser.js +1494 -0
  115. package/lib/javascript/regexp.js +1762 -0
  116. package/lib/javascript/regexpData.js +51 -0
  117. package/lib/javascript/syntax.js +8696 -5225
  118. package/lib/library/ModuleLibraryPlugin.js +116 -5
  119. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +22 -0
  120. package/lib/node/RequireChunkLoadingRuntimeModule.js +22 -0
  121. package/lib/optimize/ConcatenatedModule.js +97 -20
  122. package/lib/optimize/ConstExportsPlugin.js +50 -39
  123. package/lib/optimize/InlineExports.js +20 -123
  124. package/lib/optimize/MangleExportsPlugin.js +10 -0
  125. package/lib/optimize/ModuleConcatenationPlugin.js +24 -1
  126. package/lib/optimize/RealContentHashPlugin.js +68 -9
  127. package/lib/optimize/SideEffectsFlagPlugin.js +17 -9
  128. package/lib/performance/AnalyzableBailoutsPlugin.js +115 -0
  129. package/lib/performance/CacheEffectivenessPlugin.js +4 -3
  130. package/lib/performance/DuplicateModulesPlugin.js +57 -13
  131. package/lib/performance/EvalUsagePlugin.js +5 -2
  132. package/lib/performance/MissingSourceMapsPlugin.js +115 -0
  133. package/lib/performance/PureAnnotationsPlugin.js +6 -3
  134. package/lib/performance/TopLevelThisPlugin.js +5 -4
  135. package/lib/performance/UnusedAssetsPlugin.js +109 -0
  136. package/lib/performance/UnusedFederationPlugin.js +147 -0
  137. package/lib/performance/UnusedModulesPlugin.js +141 -0
  138. package/lib/performance/UnusedReexportsPlugin.js +1 -55
  139. package/lib/performance/isOnlyReexported.js +65 -0
  140. package/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js +25 -5
  141. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +2 -0
  142. package/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js +9 -0
  143. package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +9 -0
  144. package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +9 -0
  145. package/lib/prefetch/ResourceHintPlugin.js +1 -2
  146. package/lib/prefetch/ResourceHintRuntimeModule.js +9 -0
  147. package/lib/prefetch/StartupAssetHintRuntimeModule.js +9 -0
  148. package/lib/rules/RuleSetCompiler.js +211 -4
  149. package/lib/runtime/AsyncModuleRuntimeModule.js +100 -66
  150. package/lib/runtime/AutoPublicPathRuntimeModule.js +9 -0
  151. package/lib/runtime/BaseUriRuntimeModule.js +9 -0
  152. package/lib/runtime/ChunkNameRuntimeModule.js +9 -0
  153. package/lib/runtime/EnsureChunkRuntimeModule.js +35 -16
  154. package/lib/runtime/GetChunkFilenameRuntimeModule.js +9 -0
  155. package/lib/runtime/GetFullHashRuntimeModule.js +9 -0
  156. package/lib/runtime/GetMainFilenameRuntimeModule.js +9 -0
  157. package/lib/runtime/GetWorkletBootstrapRuntimeModule.js +9 -0
  158. package/lib/runtime/GlobalRuntimeModule.js +9 -0
  159. package/lib/runtime/HasOwnPropertyRuntimeModule.js +9 -0
  160. package/lib/runtime/HelperRuntimeModule.js +10 -0
  161. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +330 -219
  162. package/lib/runtime/NonceRuntimeModule.js +9 -0
  163. package/lib/runtime/OnChunksLoadedRuntimeModule.js +67 -20
  164. package/lib/runtime/PublicPathRuntimeModule.js +9 -0
  165. package/lib/runtime/RuntimeIdRuntimeModule.js +9 -0
  166. package/lib/runtime/SpecNamespaceObjectRuntimeModule.js +90 -0
  167. package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +9 -0
  168. package/lib/runtime/StartupEntrypointRuntimeModule.js +9 -0
  169. package/lib/runtime/SystemContextRuntimeModule.js +9 -0
  170. package/lib/runtime/ToBinaryRuntimeModule.js +9 -0
  171. package/lib/serialization/ObjectMiddleware.js +138 -106
  172. package/lib/sharing/ConsumeSharedPlugin.js +12 -0
  173. package/lib/sharing/ConsumeSharedRuntimeModule.js +11 -0
  174. package/lib/sharing/ShareRuntimeModule.js +9 -0
  175. package/lib/sharing/declaredShared.js +47 -0
  176. package/lib/stats/DefaultStatsFactoryPlugin.js +3 -1
  177. package/lib/stats/DefaultStatsPrinterPlugin.js +3 -0
  178. package/lib/util/SourceProcessor.js +76 -69
  179. package/lib/util/async.js +292 -0
  180. package/lib/util/buildDiagnostics.js +69 -0
  181. package/lib/util/fs.js +27 -1
  182. package/lib/util/handlerKeys.js +40 -0
  183. package/lib/util/identifier.js +20 -0
  184. package/lib/util/internalSerializables.js +4 -0
  185. package/lib/util/registerExternalSerializer.js +6 -45
  186. package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +9 -0
  187. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +9 -0
  188. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +9 -0
  189. package/lib/web/JsonpChunkLoadingRuntimeModule.js +36 -0
  190. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +19 -0
  191. package/package.json +22 -16
  192. package/schemas/WebpackOptions.check.js +1 -1
  193. package/schemas/WebpackOptions.json +379 -66
  194. package/schemas/plugins/LoaderOptionsPlugin.check.js +1 -1
  195. package/schemas/plugins/ManifestPlugin.check.js +1 -1
  196. package/schemas/plugins/SourceMapDevToolPlugin.check.js +1 -1
  197. package/schemas/plugins/asset/AssetGeneratorOptions.check.js +1 -1
  198. package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js +1 -1
  199. package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
  200. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  201. package/schemas/plugins/debug/ProfilingPlugin.check.js +1 -1
  202. package/schemas/plugins/dll/DllReferencePlugin.check.js +1 -1
  203. package/schemas/plugins/ids/HashedModuleIdsPlugin.check.js +1 -1
  204. package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
  205. package/types.d.ts +1414 -314
  206. package/lib/dependencies/ExportBindingInitFragment.js +0 -191
  207. package/lib/errors/EntrypointOverlapWarning.js +0 -45
  208. package/lib/performance/EntrypointOverlapPlugin.js +0 -122
@@ -5,13 +5,13 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const asyncLib = require("neo-async");
9
8
  const { ConcatSource, RawSource } = require("webpack-sources");
10
9
  const Compilation = require("./Compilation");
11
10
  const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");
12
11
  const ProgressPlugin = require("./ProgressPlugin");
13
12
  const SourceMapDevToolModuleOptionsPlugin = require("./SourceMapDevToolModuleOptionsPlugin");
14
13
  const { getPresentKinds } = require("./TemplatedPathPlugin");
14
+ const asyncLib = require("./util/async");
15
15
  const createHash = require("./util/createHash");
16
16
  const { dirname, relative } = require("./util/fs");
17
17
  const generateDebugId = require("./util/generateDebugId");
package/lib/Watching.js CHANGED
@@ -307,6 +307,7 @@ class Watching {
307
307
  logger.time("storeBuildDependencies");
308
308
  this.compiler.cache.storeBuildDependencies(
309
309
  compilation.buildDependencies,
310
+ compilation.optionalBuildDependencies,
310
311
  (err) => {
311
312
  logger.timeEnd("storeBuildDependencies");
312
313
  if (err) return handleError(err);
@@ -338,6 +339,8 @@ class Watching {
338
339
  this.compiler.cache.storeBuildDependencies(
339
340
  /** @type {Compilation} */
340
341
  (compilation).buildDependencies,
342
+ /** @type {Compilation} */
343
+ (compilation).optionalBuildDependencies,
341
344
  (err) => {
342
345
  logger.timeEnd("storeBuildDependencies");
343
346
  if (err) return handleError(err, cbs);
@@ -359,6 +362,11 @@ class Watching {
359
362
  });
360
363
  for (const cb of cbs) cb(null);
361
364
  this.compiler.hooks.afterDone.call(/** @type {Stats} */ (stats));
365
+ // A watch run goes idle here rather than closing, so seal-only
366
+ // data would be held until the next build starts.
367
+ this.compiler._releaseUnusedCompilationData(
368
+ /** @type {Compilation} */ (compilation)
369
+ );
362
370
  }
363
371
  );
364
372
  });
@@ -518,6 +526,7 @@ class Watching {
518
526
  logger.time("storeBuildDependencies");
519
527
  this.compiler.cache.storeBuildDependencies(
520
528
  compilation.buildDependencies,
529
+ compilation.optionalBuildDependencies,
521
530
  (err2) => {
522
531
  logger.timeEnd("storeBuildDependencies");
523
532
  shutdown(err || err2);
@@ -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
  }
@@ -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
  ) {
@@ -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 */
@@ -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;
@@ -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
  }
@@ -1263,6 +1263,8 @@ class PackFileCacheStrategy {
1263
1263
  this.buildDependencies = new Set();
1264
1264
  /** @type {FileSystemDependencies} */
1265
1265
  this.newBuildDependencies = new LazySet();
1266
+ /** @type {FileSystemDependencies} */
1267
+ this.newOptionalBuildDependencies = new LazySet();
1266
1268
  /** @type {InstanceType<Snapshot> | undefined} */
1267
1269
  this.resolveBuildDependenciesSnapshot = undefined;
1268
1270
  /** @type {ResolveResults | undefined} */
@@ -1492,10 +1494,13 @@ class PackFileCacheStrategy {
1492
1494
  /**
1493
1495
  * Stores build dependencies.
1494
1496
  * @param {FileSystemDependencies | Iterable<string>} dependencies dependencies to store
1497
+ * @param {FileSystemDependencies | Iterable<string>} optionalDependencies optional dependencies to store
1498
+ * @returns {void}
1495
1499
  */
1496
- storeBuildDependencies(dependencies) {
1500
+ storeBuildDependencies(dependencies, optionalDependencies) {
1497
1501
  if (this.readonly) return;
1498
1502
  this.newBuildDependencies.addAll(dependencies);
1503
+ this.newOptionalBuildDependencies.addAll(optionalDependencies);
1499
1504
  }
1500
1505
 
1501
1506
  afterAllStored() {
@@ -1512,9 +1517,14 @@ class PackFileCacheStrategy {
1512
1517
  let promise;
1513
1518
  /** @type {Set<string>} */
1514
1519
  const newBuildDependencies = new Set();
1520
+ /** @type {Set<string>} */
1521
+ const optionalBuildDependencies = new Set();
1515
1522
  for (const dep of this.newBuildDependencies) {
1516
1523
  if (!this.buildDependencies.has(dep)) {
1517
1524
  newBuildDependencies.add(dep);
1525
+ if (this.newOptionalBuildDependencies.has(dep)) {
1526
+ optionalBuildDependencies.add(dep);
1527
+ }
1518
1528
  }
1519
1529
  }
1520
1530
  if (newBuildDependencies.size > 0 || !this.buildSnapshot) {
@@ -1533,6 +1543,7 @@ class PackFileCacheStrategy {
1533
1543
  this.fileSystemInfo.resolveBuildDependencies(
1534
1544
  this.context,
1535
1545
  newBuildDependencies,
1546
+ optionalBuildDependencies,
1536
1547
  (err, result) => {
1537
1548
  this.logger.timeEnd("resolve build dependencies");
1538
1549
  if (err) return reject(err);
@@ -1667,6 +1678,7 @@ class PackFileCacheStrategy {
1667
1678
  this.buildDependencies.add(dep);
1668
1679
  }
1669
1680
  this.newBuildDependencies.clear();
1681
+ this.newOptionalBuildDependencies.clear();
1670
1682
  this.logger.timeEnd("store pack");
1671
1683
  const stats = pack.getContentStats();
1672
1684
  this.logger.log(
@@ -1887,6 +1899,7 @@ class PackFileCacheStrategy {
1887
1899
  this.fileSystemInfo.clear();
1888
1900
  this.buildDependencies.clear();
1889
1901
  this.newBuildDependencies.clear();
1902
+ this.newOptionalBuildDependencies.clear();
1890
1903
  this.resolveBuildDependenciesSnapshot = undefined;
1891
1904
  this.resolveResults = undefined;
1892
1905
  this.buildSnapshot = undefined;
@@ -428,6 +428,25 @@ const resolve = (browsers) => {
428
428
  // kaios: Not supported
429
429
  node: [16, 9]
430
430
  }),
431
+ topLevelAwait: rawChecker({
432
+ chrome: 89,
433
+ and_chr: 89,
434
+ edge: 89,
435
+ firefox: 89,
436
+ and_ff: 89,
437
+ // ie: Not supported,
438
+ opera: 75,
439
+ op_mob: 63,
440
+ safari: 15,
441
+ ios_saf: 15,
442
+ samsung: 15,
443
+ android: 89,
444
+ // and_qq: Not supported
445
+ // baidu: Not supported
446
+ // and_uc: Not supported
447
+ // kaios: Not supported
448
+ node: [14, 8]
449
+ }),
431
450
  spread: rawChecker({
432
451
  chrome: 60,
433
452
  and_chr: 60,