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
@@ -20,6 +20,7 @@ const {
20
20
  evaluateToString,
21
21
  toConstantDependency
22
22
  } = require("./javascript/JavascriptParserHelpers");
23
+ const { getBuildDiagnostics } = require("./util/buildDiagnostics");
23
24
  const createHash = require("./util/createHash");
24
25
  const createHooksRegistry = require("./util/createHooksRegistry");
25
26
 
@@ -92,8 +93,10 @@ class RuntimeValue {
92
93
  const buildInfo = /** @type {BuildInfo} */ (parser.state.module.buildInfo);
93
94
  if (this.options === true) {
94
95
  buildInfo.cacheable = false;
96
+ const diagnostics = getBuildDiagnostics(buildInfo);
95
97
  const reasons =
96
- buildInfo.notCacheableReasons || (buildInfo.notCacheableReasons = []);
98
+ diagnostics.notCacheableReasons ||
99
+ (diagnostics.notCacheableReasons = []);
97
100
  const reason = `DefinePlugin runtime value ${key}`;
98
101
  if (!reasons.includes(reason)) reasons.push(reason);
99
102
  } else {
@@ -375,7 +378,7 @@ const PLUGIN_NAME = "DefinePlugin";
375
378
  const VALUE_DEP_PREFIX = `webpack/${PLUGIN_NAME} `;
376
379
  const VALUE_DEP_MAIN = `webpack/${PLUGIN_NAME}_hash`;
377
380
 
378
- // Keys webpack injects itself are not the user's to remove, so `performance.unusedDefines`
381
+ // Keys webpack injects itself are not the user's to remove, so `performance.unusedConfig`
379
382
  // never sees them.
380
383
  /** @type {WeakSet<DefinePlugin>} */
381
384
  const INTERNAL_PLUGINS = new WeakSet();
@@ -721,11 +724,11 @@ class DefinePlugin {
721
724
  (compilation, { normalModuleFactory }) => {
722
725
  const definitions = this.definitions;
723
726
  const { performance } = compilation.options;
724
- // Only `performance.unusedDefines` reads these, so a build without it
727
+ // Only `performance.unusedConfig` reads these, so a build without it
725
728
  // collects nothing.
726
729
  const collectDeclared =
727
730
  performance !== false &&
728
- performance.unusedDefines === true &&
731
+ performance.unusedConfig === true &&
729
732
  !INTERNAL_PLUGINS.has(this);
730
733
  /** @type {Set<string> | undefined} */
731
734
  let declaredKeys;
@@ -1218,13 +1221,26 @@ class DefinePlugin {
1218
1221
  }
1219
1222
  return -1;
1220
1223
  };
1224
+ // Cut the chain at the undefined member, so a read after it still
1225
+ // throws; an optional link there short-circuits the whole chain.
1221
1226
  parser.hooks.expressionMemberChain
1222
1227
  .for(chainRoot)
1223
- .tap(PLUGIN_NAME, (expr, members) => {
1228
+ .tap(PLUGIN_NAME, (expr, members, membersOptionals) => {
1224
1229
  const deps = [key];
1225
- if (findUndefinedMemberAccess(members, deps) === -1) return;
1230
+ const undefinedIndex = findUndefinedMemberAccess(members, deps);
1231
+ if (undefinedIndex === -1) return;
1226
1232
  for (const dep of deps) addValueDependency(dep);
1227
- return toConstantDependency(parser, "undefined")(expr);
1233
+ return toConstantDependency(
1234
+ parser,
1235
+ "undefined"
1236
+ )(
1237
+ membersOptionals[undefinedIndex + 1]
1238
+ ? expr
1239
+ : dropTrailingMembers(
1240
+ expr,
1241
+ members.length - 1 - undefinedIndex
1242
+ )
1243
+ );
1228
1244
  });
1229
1245
  // Cut the chain at the undefined member, so what follows still
1230
1246
  // throws; an optional link there takes the call, arguments unevaluated.
@@ -1331,7 +1347,7 @@ class DefinePlugin {
1331
1347
  DefinePlugin.getCompilationHooks = createHooksRegistry(createCompilationHooks);
1332
1348
 
1333
1349
  /**
1334
- * Marks an instance as webpack's own, so `performance.unusedDefines` never
1350
+ * Marks an instance as webpack's own, so `performance.unusedConfig` never
1335
1351
  * reports the keys it declares against the user.
1336
1352
  * @param {DefinePlugin} plugin the instance webpack constructed itself
1337
1353
  * @returns {DefinePlugin} the same instance
@@ -29,6 +29,7 @@ const { coreModules } = require("./node/nodeBuiltins");
29
29
  const createHash = require("./util/createHash");
30
30
  const createHooksRegistry = require("./util/createHooksRegistry");
31
31
  const extractUrlAndGlobal = require("./util/extractUrlAndGlobal");
32
+ const { toJsStringLiteral } = require("./util/identifier");
32
33
  const makeSerializable = require("./util/makeSerializable");
33
34
  const memoize = require("./util/memoize");
34
35
  const { propertyAccess } = require("./util/property");
@@ -110,6 +111,7 @@ const getEnvironmentNotSupportAsyncWarning = memoize(() =>
110
111
  * @property {InitFragment<ChunkRenderContext>[]=} chunkInitFragments
111
112
  * @property {ReadOnlyRuntimeRequirements=} runtimeRequirements
112
113
  * @property {[string, string][]=} specifiers
114
+ * @property {string=} externalReexport native reexport source and attributes
113
115
  */
114
116
 
115
117
  /** @typedef {true | [string, string][]} Imported */
@@ -417,6 +419,18 @@ const importAssertionReplacer = (key, value) => {
417
419
  return value;
418
420
  };
419
421
 
422
+ /**
423
+ * Renders the import attributes clause of a static import or reexport.
424
+ * @param {ImportDependencyMeta | undefined} dependencyMeta import metadata
425
+ * @returns {string} static import attributes
426
+ */
427
+ const getImportAttributes = (dependencyMeta) =>
428
+ dependencyMeta && dependencyMeta.attributes
429
+ ? dependencyMeta.attributes._isLegacyAssert
430
+ ? ` assert ${JSON.stringify(dependencyMeta.attributes, importAssertionReplacer)}`
431
+ : ` with ${JSON.stringify(dependencyMeta.attributes)}`
432
+ : "";
433
+
420
434
  /**
421
435
  * Represents ModuleExternalInitFragment.
422
436
  * @extends {InitFragment<GenerateContext>}
@@ -503,33 +517,25 @@ class ModuleExternalInitFragment extends InitFragment {
503
517
  _request: request,
504
518
  _identifier: identifier
505
519
  } = this;
506
- const attributes =
507
- dependencyMeta && dependencyMeta.attributes
508
- ? dependencyMeta.attributes._isLegacyAssert
509
- ? ` assert ${JSON.stringify(
510
- dependencyMeta.attributes,
511
- importAssertionReplacer
512
- )}`
513
- : ` with ${JSON.stringify(dependencyMeta.attributes)}`
514
- : "";
520
+ const attributes = getImportAttributes(dependencyMeta);
515
521
  const phase = dependencyMeta && dependencyMeta.phase;
516
522
  checkPhaseIsSupported(phase, context.runtimeTemplate);
517
523
  let content = "";
518
524
  if (ImportPhaseUtils.isSource(phase) && imported === true) {
519
525
  // There is no `import source * as ns` form: the source phase binds one
520
526
  // identifier, so it stands in for the namespace the other branches build.
521
- content = `import source ${identifier} from ${JSON.stringify(
527
+ content = `import source ${identifier} from ${toJsStringLiteral(
522
528
  request
523
529
  )}${attributes};\n`;
524
530
  } else if (imported === true) {
525
531
  // namespace
526
532
  const phaseKeyword = ImportPhaseUtils.isDefer(phase) ? "defer " : "";
527
- content = `import ${phaseKeyword}* as ${identifier} from ${JSON.stringify(
533
+ content = `import ${phaseKeyword}* as ${identifier} from ${toJsStringLiteral(
528
534
  request
529
535
  )}${attributes};\n`;
530
536
  } else if (imported.length === 0) {
531
537
  // just import, no use
532
- content = `import ${JSON.stringify(request)}${attributes};\n`;
538
+ content = `import ${toJsStringLiteral(request)}${attributes};\n`;
533
539
  } else if (
534
540
  ImportPhaseUtils.isSource(phase) &&
535
541
  imported.length === 1 &&
@@ -537,7 +543,7 @@ class ModuleExternalInitFragment extends InitFragment {
537
543
  ) {
538
544
  // `import source x from "…"` — the source-phase form binds the source
539
545
  // object directly to a single identifier (no namespace, no destructuring).
540
- content = `import source ${imported[0][1]} from ${JSON.stringify(
546
+ content = `import source ${imported[0][1]} from ${toJsStringLiteral(
541
547
  request
542
548
  )}${attributes};\n`;
543
549
  } else {
@@ -548,7 +554,7 @@ class ModuleExternalInitFragment extends InitFragment {
548
554
  }
549
555
  return name;
550
556
  })
551
- .join(", ")} } from ${JSON.stringify(request)}${attributes};\n`;
557
+ .join(", ")} } from ${toJsStringLiteral(request)}${attributes};\n`;
552
558
  }
553
559
  return content;
554
560
  }
@@ -738,6 +744,12 @@ const getSourceForModuleExternal = (
738
744
  }
739
745
  return {
740
746
  expression,
747
+ externalReexport:
748
+ moduleAndSpecifiers.length === 1 &&
749
+ !ImportPhaseUtils.isDefer(phase) &&
750
+ !ImportPhaseUtils.isSource(phase)
751
+ ? `from ${toJsStringLiteral(moduleAndSpecifiers[0])}${getImportAttributes(dependencyMeta)}`
752
+ : undefined,
741
753
  init: moduleRemapping
742
754
  ? `${runtimeTemplate.renderConst()} x = ${runtimeTemplate.basicFunction(
743
755
  "y",
@@ -1238,6 +1250,17 @@ class ExternalModule extends Module {
1238
1250
  return this._resolveExternalType(this.externalType) !== "module";
1239
1251
  }
1240
1252
 
1253
+ /**
1254
+ * The request this external resolves to for its own type, with the record form
1255
+ * narrowed to its entry. An array is a module specifier plus a property path.
1256
+ * @returns {string | string[] | undefined} the resolved request
1257
+ */
1258
+ getResolvedRequest() {
1259
+ return /** @type {string | string[] | undefined} */ (
1260
+ this._getRequestAndExternalType().request
1261
+ );
1262
+ }
1263
+
1241
1264
  /**
1242
1265
  * Get request and external type.
1243
1266
  * @private
@@ -1535,6 +1558,10 @@ class ExternalModule extends Module {
1535
1558
  data = new Map();
1536
1559
  data.set("chunkInitFragments", sourceData.chunkInitFragments);
1537
1560
  }
1561
+ if (sourceData.externalReexport) {
1562
+ if (!data) data = new Map();
1563
+ data.set("externalReexport", sourceData.externalReexport);
1564
+ }
1538
1565
 
1539
1566
  /** @type {Sources} */
1540
1567
  const sources = new Map();
@@ -8,11 +8,11 @@
8
8
  const nodeModule = require("module");
9
9
  const { isAbsolute } = require("path");
10
10
  const { create: createResolver } = require("enhanced-resolve");
11
- const asyncLib = require("neo-async");
12
11
  const { DEFAULTS } = require("./config/defaults");
13
12
  const { collectCjsRequireSpecifiers } = require("./javascript/syntax");
14
13
  const AsyncQueue = require("./util/AsyncQueue");
15
14
  const StackedCacheMap = require("./util/StackedCacheMap");
15
+ const asyncLib = require("./util/async");
16
16
  const createHash = require("./util/createHash");
17
17
  const { dirname, join, lstatReadlinkAbsolute, relative } = require("./util/fs");
18
18
  const makeSerializable = require("./util/makeSerializable");
@@ -1884,10 +1884,13 @@ class FileSystemInfo {
1884
1884
  * Resolves build dependencies.
1885
1885
  * @param {string} context context directory
1886
1886
  * @param {Iterable<string>} deps dependencies
1887
+ * @param {Iterable<string> | undefined} optionalDeps optional dependencies that may be missing
1887
1888
  * @param {(err?: Error | null, resolveBuildDependenciesResult?: ResolveBuildDependenciesResult) => void} callback callback function
1888
1889
  * @returns {void}
1889
1890
  */
1890
- resolveBuildDependencies(context, deps, callback) {
1891
+ resolveBuildDependencies(context, deps, optionalDeps, callback) {
1892
+ /** @type {Set<string>} */
1893
+ const optional = new Set(optionalDeps);
1891
1894
  const { resolveContext, resolveEsm, resolveCjs, resolveCjsAsChild } =
1892
1895
  this._createBuildDependenciesResolvers();
1893
1896
 
@@ -1979,7 +1982,7 @@ class FileSystemInfo {
1979
1982
  type: RBDT_RESOLVE_INITIAL,
1980
1983
  context,
1981
1984
  path: dep,
1982
- expected: undefined,
1985
+ expected: optional.has(dep) ? false : undefined,
1983
1986
  issuer: undefined
1984
1987
  })
1985
1988
  ),
@@ -2005,6 +2008,7 @@ class FileSystemInfo {
2005
2008
  if (err) {
2006
2009
  if (expected === false) {
2007
2010
  resolveResults.set(key, false);
2011
+ resolveMissing.add(path);
2008
2012
  return callback();
2009
2013
  }
2010
2014
  invalidResolveResults.add(key);
@@ -2060,6 +2064,7 @@ class FileSystemInfo {
2060
2064
  if (err) {
2061
2065
  if (expected === false) {
2062
2066
  resolveResults.set(key, false);
2067
+ resolveMissing.add(path);
2063
2068
  return callback();
2064
2069
  }
2065
2070
  invalidResolveResults.add(key);
@@ -2514,20 +2519,18 @@ class FileSystemInfo {
2514
2519
  },
2515
2520
  /**
2516
2521
  * Processes the provided err.
2517
- * @param {Error | typeof INVALID=} err error or invalid flag
2522
+ * @param {(Error | typeof INVALID | null)=} err error or invalid flag
2518
2523
  * @returns {void}
2519
2524
  */
2520
- /** @type {import("neo-async").ErrorCallback<Error | typeof INVALID>} */ (
2521
- (err) => {
2522
- if (err === INVALID) {
2523
- return callback(null, false);
2524
- }
2525
- if (err) {
2526
- return callback(err);
2527
- }
2528
- return callback(null, true);
2525
+ (err) => {
2526
+ if (err === INVALID) {
2527
+ return callback(null, false);
2529
2528
  }
2530
- )
2529
+ if (err) {
2530
+ return callback(err);
2531
+ }
2532
+ return callback(null, true);
2533
+ }
2531
2534
  );
2532
2535
  }
2533
2536
 
@@ -5,8 +5,8 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const asyncLib = require("neo-async");
9
8
  const Queue = require("./util/Queue");
9
+ const asyncLib = require("./util/async");
10
10
  const { compareModulesByIdentifier } = require("./util/comparators");
11
11
  const createHash = require("./util/createHash");
12
12
 
@@ -30,15 +30,40 @@ const PLUGIN_LOGGER_NAME = `webpack.${PLUGIN_NAME}`;
30
30
  /** @typedef {{ etag: string, data: InstanceType<RestoreProvidedData> }} MemCacheEntry */
31
31
 
32
32
  /**
33
+ * Cache key fragment for what changes provided exports without changing the
34
+ * module's source: still-lazy barrel requests and DefinePlugin value versions.
33
35
  * @param {Module} module the module
34
36
  * @param {LazyBarrelController} lazyBarrelController the compilation's lazy barrel controller
35
37
  * @param {HashFunction} hashFunction hash function for long keys
36
- * @returns {string} the hash
38
+ * @returns {string} etag for provided-exports mem/persistent cache, "" when neither applies
37
39
  */
38
- const getLazyRequestsHash = (module, lazyBarrelController, hashFunction) => {
39
- const lazyKeys = lazyBarrelController.getLazyRequests(module);
40
- if (!lazyKeys) return "";
41
- const joined = [...lazyKeys].join("|");
40
+ const getProvidedExportsEtag = (module, lazyBarrelController, hashFunction) => {
41
+ const lazyRequests = lazyBarrelController.getLazyRequests(module);
42
+ const buildInfo = /** @type {BuildInfo | undefined} */ (module.buildInfo);
43
+ const valueDependencies = buildInfo && buildInfo.valueDependencies;
44
+ const hasValueDependencies =
45
+ valueDependencies !== undefined && valueDependencies.size > 0;
46
+ if (!lazyRequests && !hasValueDependencies) return "";
47
+ /** @type {(string | string[] | undefined)[][]} */
48
+ const valueEntries = [];
49
+ if (hasValueDependencies) {
50
+ const versions =
51
+ /** @type {NonNullable<BuildInfo["valueDependencies"]>} */
52
+ (valueDependencies);
53
+ for (const key of [...versions.keys()].sort()) {
54
+ const value = versions.get(key);
55
+ // An absent version serializes as null, distinct from both other shapes
56
+ valueEntries.push([
57
+ key,
58
+ value instanceof Set ? [...value].sort() : value
59
+ ]);
60
+ }
61
+ }
62
+ // JSON, so a separator inside a request or a version cannot forge another entry
63
+ const joined = JSON.stringify([
64
+ lazyRequests ? [...lazyRequests] : [],
65
+ valueEntries
66
+ ]);
42
67
  if (joined.length < 100) return joined;
43
68
  const hash = createHash(hashFunction);
44
69
  hash.update(joined);
@@ -78,9 +103,7 @@ class FlagDependencyExportsPlugin {
78
103
  // Step 1: Try to restore cached provided export info from cache
79
104
  logger.time("restore cached provided exports");
80
105
  asyncLib.each(
81
- /** @type {import("neo-async").IterableCollection<Module>} */ (
82
- /** @type {unknown} */ (modules)
83
- ),
106
+ modules,
84
107
  (module, callback) => {
85
108
  const exportsInfo = moduleGraph.getExportsInfo(module);
86
109
  // If the module doesn't have an exportsType, it's a module
@@ -109,7 +132,7 @@ class FlagDependencyExportsPlugin {
109
132
  const memCache = moduleMemCaches && moduleMemCaches.get(module);
110
133
  /** @type {MemCacheEntry | undefined} */
111
134
  const memCacheEntry = memCache && memCache.get(this);
112
- const hash = getLazyRequestsHash(
135
+ const etag = getProvidedExportsEtag(
113
136
  module,
114
137
  lazyBarrelController,
115
138
  hashFunction
@@ -118,7 +141,7 @@ class FlagDependencyExportsPlugin {
118
141
  // detection cannot invalidate the mem cache when the un-lazied
119
142
  // connections are unsafe-cached (they are skipped when comparing
120
143
  // references)
121
- if (memCacheEntry !== undefined && memCacheEntry.etag === hash) {
144
+ if (memCacheEntry !== undefined && memCacheEntry.etag === etag) {
122
145
  statRestoredFromMemCache++;
123
146
  exportsInfo.restoreProvided(memCacheEntry.data);
124
147
  return callback();
@@ -128,7 +151,7 @@ class FlagDependencyExportsPlugin {
128
151
  );
129
152
  cache.get(
130
153
  module.identifier(),
131
- hash ? `${buildHash}|${hash}` : buildHash,
154
+ etag ? `${buildHash}|${etag}` : buildHash,
132
155
  (err, result) => {
133
156
  if (err) return callback(err);
134
157
 
@@ -351,12 +374,13 @@ class FlagDependencyExportsPlugin {
351
374
  changed = true;
352
375
  }
353
376
 
354
- if (
355
- inlined !== undefined &&
356
- exportInfo.canInlineProvide === undefined
357
- ) {
358
- exportInfo.canInlineProvide = inlined;
359
- changed = true;
377
+ if (inlined !== undefined) {
378
+ const prev = exportInfo.canInlineProvide;
379
+ // Watch rebuilds keep ExportInfo; refresh when the constant changes
380
+ if (prev === undefined || !prev.equals(inlined)) {
381
+ exportInfo.canInlineProvide = inlined;
382
+ changed = true;
383
+ }
360
384
  }
361
385
 
362
386
  if (terminalBinding && !exportInfo.terminalBinding) {
@@ -513,7 +537,7 @@ class FlagDependencyExportsPlugin {
513
537
  .getRestoreProvidedData();
514
538
  const memCache =
515
539
  moduleMemCaches && moduleMemCaches.get(module);
516
- const hash = getLazyRequestsHash(
540
+ const etag = getProvidedExportsEtag(
517
541
  module,
518
542
  lazyBarrelController,
519
543
  hashFunction
@@ -521,7 +545,7 @@ class FlagDependencyExportsPlugin {
521
545
  if (memCache) {
522
546
  /** @type {MemCacheEntry} */
523
547
  const entry = {
524
- etag: hash,
548
+ etag,
525
549
  data: cachedData
526
550
  };
527
551
  memCache.set(this, entry);
@@ -531,7 +555,7 @@ class FlagDependencyExportsPlugin {
531
555
  );
532
556
  cache.store(
533
557
  module.identifier(),
534
- hash ? `${buildHash}|${hash}` : buildHash,
558
+ etag ? `${buildHash}|${etag}` : buildHash,
535
559
  cachedData,
536
560
  callback
537
561
  );
@@ -17,7 +17,11 @@ const {
17
17
  } = require("./ModuleTypeConstants");
18
18
  const NormalModule = require("./NormalModule");
19
19
  const RuntimeGlobals = require("./RuntimeGlobals");
20
- const { chunkHasCss } = require("./css/CssModulesPlugin");
20
+ const { getPresentKinds } = require("./TemplatedPathPlugin");
21
+ const {
22
+ chunkHasCss,
23
+ getChunkFilenameTemplate: getCssChunkFilenameTemplate
24
+ } = require("./css/CssModulesPlugin");
21
25
  const ConstDependency = require("./dependencies/ConstDependency");
22
26
  const ImportMetaHotAcceptDependency = require("./dependencies/ImportMetaHotAcceptDependency");
23
27
  const ImportMetaHotDeclineDependency = require("./dependencies/ImportMetaHotDeclineDependency");
@@ -72,6 +76,22 @@ const {
72
76
  /** @typedef {{ updatedChunkIds: ChunkIds, removedChunkIds: ChunkIds, removedModules: ModuleSet, forceLoadChunkIds: ChunkIds, filename: string, assetInfo: AssetInfo }} HotUpdateMainContentByRuntimeItem */
73
77
  /** @typedef {Map<string, HotUpdateMainContentByRuntimeItem>} HotUpdateMainContentByRuntime */
74
78
 
79
+ /**
80
+ * Whether a filename template reads any hash, so the name it gives a chunk can move
81
+ * between two builds.
82
+ * @param {string} template the filename template
83
+ * @returns {boolean} true when a hash is part of the name
84
+ */
85
+ const templateReadsHash = (template) => {
86
+ const kinds = getPresentKinds(template);
87
+ return (
88
+ kinds.has("hash") ||
89
+ kinds.has("fullhash") ||
90
+ kinds.has("chunkhash") ||
91
+ kinds.has("contenthash")
92
+ );
93
+ };
94
+
75
95
  const PLUGIN_NAME = "HotModuleReplacementPlugin";
76
96
 
77
97
  class HotModuleReplacementPlugin {
@@ -856,7 +876,7 @@ To fix this, make sure to include [runtime] in the output.hotUpdateMainFilename
856
876
  assetInfo
857
877
  }
858
878
  ] of hotUpdateMainContentByFilename) {
859
- /** @type {{ c: ChunkId[], r: ChunkId[], m: ModuleId[], f?: ChunkId[], css?: { r: ChunkId[] } }} */
879
+ /** @type {{ c: ChunkId[], r: ChunkId[], m: ModuleId[], f?: ChunkId[], css?: { r: ChunkId[], n?: Record<ChunkId, string> } }} */
860
880
  const hotUpdateMainJson = {
861
881
  c: [...updatedChunkIds],
862
882
  r: [...removedChunkIds],
@@ -882,21 +902,47 @@ To fix this, make sure to include [runtime] in the output.hotUpdateMainFilename
882
902
  // Build CSS removed chunks list (chunks in updatedChunkIds that no longer have CSS)
883
903
  /** @type {ChunkId[]} */
884
904
  const cssRemovedChunkIds = [];
905
+ /** @type {Record<ChunkId, string> | undefined} */
906
+ let cssChunkNames;
885
907
  if (compilation.options.experiments.css) {
886
908
  for (const chunkId of updatedChunkIds) {
887
909
  for (const /** @type {Chunk} */ chunk of compilation.chunks) {
888
- if (chunk.id === chunkId) {
889
- if (!chunkHasCss(chunk, chunkGraph)) {
890
- cssRemovedChunkIds.push(chunkId);
891
- }
910
+ if (chunk.id !== chunkId) continue;
911
+ if (!chunkHasCss(chunk, chunkGraph)) {
912
+ cssRemovedChunkIds.push(chunkId);
892
913
  break;
893
914
  }
915
+ // The runtime's name map is refreshed only by the update chunk
916
+ // itself, so a name that moved with the content travels here.
917
+ const template = getCssChunkFilenameTemplate(
918
+ chunk,
919
+ compilation.outputOptions
920
+ );
921
+ if (
922
+ typeof template !== "string" ||
923
+ templateReadsHash(template)
924
+ ) {
925
+ if (cssChunkNames === undefined) cssChunkNames = {};
926
+ cssChunkNames[chunkId] = compilation.getPath(template, {
927
+ hash: compilation.hash,
928
+ runtime: chunk.runtime,
929
+ chunk,
930
+ contentHashType: "css"
931
+ });
932
+ }
933
+ break;
894
934
  }
895
935
  }
896
936
  }
897
937
 
898
- if (cssRemovedChunkIds.length > 0) {
938
+ if (
939
+ cssRemovedChunkIds.length > 0 ||
940
+ cssChunkNames !== undefined
941
+ ) {
899
942
  hotUpdateMainJson.css = { r: cssRemovedChunkIds };
943
+ if (cssChunkNames !== undefined) {
944
+ hotUpdateMainJson.css.n = cssChunkNames;
945
+ }
900
946
  }
901
947
 
902
948
  const source = new RawSource(
@@ -11,6 +11,7 @@ const {
11
11
  JAVASCRIPT_MODULE_TYPE_ESM
12
12
  } = require("./ModuleTypeConstants");
13
13
  const { getInnerGraphUtils } = require("./optimize/InnerGraph");
14
+ const { recordOptimizationBailout } = require("./util/buildDiagnostics");
14
15
 
15
16
  /** @import Compiler from "./Compiler" */
16
17
  /** @import { BuildInfo } from "./Module" */
@@ -73,9 +74,10 @@ class JavascriptMetaInfoPlugin {
73
74
  const wasEnabled = innerGraph.isEnabled(parser.state);
74
75
  innerGraph.bailout(parser.state);
75
76
  if (wasEnabled) {
76
- compilation.moduleGraph
77
- .getOptimizationBailout(parser.state.module)
78
- .push("Inner graph bailout: eval()");
77
+ recordOptimizationBailout(
78
+ buildInfo,
79
+ "Inner graph bailout: eval()"
80
+ );
79
81
  }
80
82
  }
81
83
  });
@@ -21,7 +21,11 @@ const getJsonpTemplatePlugin = memoize(() =>
21
21
 
22
22
  /** @import { Tap } from "tapable" */
23
23
  /** @import { Source } from "webpack-sources" */
24
- /** @import { Output as OutputOptions } from "../declarations/WebpackOptions" */
24
+ /**
25
+ * @import {
26
+ * OutputNormalizedWithDefaults as OutputOptions
27
+ * } from "./config/defaults"
28
+ */
25
29
  /** @import ModuleTemplate from "./ModuleTemplate" */
26
30
  /** @import Chunk from "./Chunk" */
27
31
  /**
package/lib/Module.js CHANGED
@@ -128,6 +128,7 @@ const makeSerializable = require("./util/makeSerializable");
128
128
  * @property {Set<string>} topLevelDeclarations top level declarations for javascript modules
129
129
  * @property {Set<string>} freeNames free identifier names in the rendered source for javascript modules
130
130
  * @property {InitFragment<EXPECTED_ANY>[]} chunkInitFragments chunk init fragments for javascript modules
131
+ * @property {string} externalReexport native external reexport source and attributes
131
132
  * @property {{ javascript?: string, ["asset-url"]?: string }} url url for asset modules
132
133
  * @property {string} filename a filename for asset modules
133
134
  * @property {AssetInfo} assetInfo an asset info for asset modules
@@ -186,23 +187,33 @@ const makeSerializable = require("./util/makeSerializable");
186
187
  * @property {Map<string, string>=} exportsBindingSourceByRuntime export definitions `ModuleLibraryPlugin` took over, re-emitted only where the module is wrapped
187
188
  */
188
189
 
190
+ /**
191
+ * What a build recorded for stats and the performance hints to report, kept on the build info so a module restored from the cache still has it.
192
+ * @typedef {object} BuildDiagnostics
193
+ * @property {string[]=} optimizationBailouts what parser plugins reported as optimization bailouts, replayed into the module graph of every compilation that reuses the module
194
+ * @property {string=} sideEffectStatement the statement whose side effect keeps the module in the bundle, as `type at location`
195
+ * @property {number=} ineffectivePureAnnotations how many `#__PURE__` annotations sit where the parser does not read them
196
+ * @property {number=} topLevelThis how many times the module reads `this` at its top level
197
+ * @property {boolean=} usesEval true when the module calls `eval` directly
198
+ * @property {string[]=} notCacheableReasons reasons why the module is not cacheable (e.g. paths of loaders that marked it)
199
+ */
200
+
189
201
  /**
190
202
  * Defines the build info properties common to all module types.
191
203
  * Module type specific properties live in the `Known*BuildInfo` typedef of the dedicated module class.
192
204
  * @typedef {object} KnownBuildInfo
205
+ * @property {boolean=} specNamespaceObject the module hands out a spec Module Namespace Exotic Object
193
206
  * @property {boolean=} cacheable
194
- * @property {string[]=} notCacheableReasons reasons why the module is not cacheable (e.g. paths of loaders that marked it)
195
207
  * @property {boolean=} strict
196
208
  * @property {string=} moduleArgument
197
209
  * @property {string=} exportsArgument
198
210
  * @property {Record<string, Source>=} assets assets added by loaders or plugins
199
211
  * @property {Map<string, AssetInfo | undefined>=} assetsInfo
200
212
  * @property {Set<string>=} topLevelDeclarations top level declaration names
201
- * @property {boolean=} isCircular true when the module is part of a circular dependency chain
202
- * @property {boolean=} usesEval true when the module calls `eval` directly
203
- * @property {number=} ineffectivePureAnnotations how many `#__PURE__` annotations sit where the parser does not read them
204
- * @property {number=} topLevelThis how many times the module reads `this` at its top level
213
+ * @property {boolean=} isCircular true when the module is in a synchronous circular dependency chain
214
+ * @property {number=} circularKind CircularKind bit flags from CircularModulesPlugin; unset when the plugin did not run
205
215
  * @property {boolean=} usesTopLevelAwaitForOf module uses top-level `for await…of` or `await using`, which can't be lowered to a generator
216
+ * @property {BuildDiagnostics=} diagnostics what the build recorded for stats and the performance hints to report
206
217
  */
207
218
 
208
219
  /** @typedef {string | Set<string>} ValueCacheVersion */
@@ -1310,7 +1321,6 @@ class Module extends DependenciesBlock {
1310
1321
  write(this.type);
1311
1322
  write(this.layer);
1312
1323
  write(this.context);
1313
- write(this.resolveOptions);
1314
1324
  write(this.factoryMeta);
1315
1325
  write(this.useSourceMap);
1316
1326
  write(this.useSimpleSourceMap);
@@ -1340,7 +1350,6 @@ class Module extends DependenciesBlock {
1340
1350
  this.type = read();
1341
1351
  this.layer = read();
1342
1352
  this.context = read();
1343
- this.resolveOptions = read();
1344
1353
  this.factoryMeta = read();
1345
1354
  this.useSourceMap = read();
1346
1355
  this.useSimpleSourceMap = read();
@@ -5,13 +5,13 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const asyncLib = require("neo-async");
9
8
  const { MultiHook, SyncHook } = require("tapable");
10
9
 
11
10
  const MultiStats = require("./MultiStats");
12
11
  const MultiWatching = require("./MultiWatching");
13
12
  const WebpackError = require("./errors/WebpackError");
14
13
  const ArrayQueue = require("./util/ArrayQueue");
14
+ const asyncLib = require("./util/async");
15
15
  const memoize = require("./util/memoize");
16
16
 
17
17
  const getConcurrentCompilationError = memoize(() =>
@@ -5,7 +5,7 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const asyncLib = require("neo-async");
8
+ const asyncLib = require("./util/async");
9
9
 
10
10
  /** @import MultiCompiler from "./MultiCompiler" */
11
11
  /** @import Watching from "./Watching" */