webpack 5.108.3 → 5.109.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 (191) hide show
  1. package/lib/APIPlugin.js +48 -29
  2. package/lib/CacheFacade.js +8 -0
  3. package/lib/ChunkGroup.js +1 -0
  4. package/lib/CompatibilityPlugin.js +31 -29
  5. package/lib/Compilation.js +50 -8
  6. package/lib/ConstPlugin.js +11 -11
  7. package/lib/ContextModule.js +239 -6
  8. package/lib/ContextModuleFactory.js +139 -14
  9. package/lib/DefinePlugin.js +396 -101
  10. package/lib/Entrypoint.js +1 -1
  11. package/lib/ExportsInfoApiPlugin.js +2 -2
  12. package/lib/ExternalModule.js +107 -5
  13. package/lib/ExternalModuleFactoryPlugin.js +20 -1
  14. package/lib/FileSystemInfo.js +130 -74
  15. package/lib/FlagDependencyExportsPlugin.js +55 -8
  16. package/lib/HotModuleReplacementPlugin.js +18 -15
  17. package/lib/LazyBarrel.js +30 -3
  18. package/lib/Module.js +3 -0
  19. package/lib/ModuleFilenameHelpers.js +2 -2
  20. package/lib/ModuleTypeConstants.js +8 -1
  21. package/lib/MultiCompiler.js +13 -2
  22. package/lib/MultiWatching.js +1 -0
  23. package/lib/NodeStuffPlugin.js +51 -33
  24. package/lib/NormalModule.js +169 -405
  25. package/lib/NormalModuleFactory.js +76 -2
  26. package/lib/ProgressPlugin.js +211 -119
  27. package/lib/ProvidePlugin.js +2 -2
  28. package/lib/RuntimeGlobals.js +47 -0
  29. package/lib/RuntimePlugin.js +33 -0
  30. package/lib/RuntimeTemplate.js +304 -16
  31. package/lib/UseStrictPlugin.js +1 -1
  32. package/lib/WebpackIsIncludedPlugin.js +1 -1
  33. package/lib/WebpackOptionsApply.js +24 -19
  34. package/lib/asset/AssetGenerator.js +110 -28
  35. package/lib/asset/AssetModulesPlugin.js +92 -2
  36. package/lib/asset/WebManifestGenerator.js +164 -0
  37. package/lib/asset/WebManifestParser.js +130 -0
  38. package/lib/async-modules/AwaitDependenciesInitFragment.js +14 -4
  39. package/lib/async-modules/isGeneratorLowered.js +26 -0
  40. package/lib/cache/PackFileCacheStrategy.js +9 -3
  41. package/lib/config/browserslistTargetHandler.js +40 -0
  42. package/lib/config/defaults.js +222 -32
  43. package/lib/config/normalization.js +26 -0
  44. package/lib/config/target.js +9 -1
  45. package/lib/css/CssGenerator.js +73 -73
  46. package/lib/css/CssLoadingRuntimeModule.js +5 -1
  47. package/lib/css/CssModulesPlugin.js +92 -53
  48. package/lib/css/CssParser.js +843 -302
  49. package/lib/css/syntax.js +1219 -483
  50. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +6 -6
  51. package/lib/dependencies/AMDPlugin.js +2 -2
  52. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +13 -13
  53. package/lib/dependencies/CommonJsDependencyHelpers.js +39 -0
  54. package/lib/dependencies/CommonJsExportsDependency.js +47 -2
  55. package/lib/dependencies/CommonJsExportsParserPlugin.js +10 -10
  56. package/lib/dependencies/CommonJsImportsParserPlugin.js +18 -18
  57. package/lib/dependencies/CommonJsPlugin.js +2 -2
  58. package/lib/dependencies/CommonJsRequireDependency.js +26 -1
  59. package/lib/dependencies/CommonJsSelfReferenceDependency.js +32 -1
  60. package/lib/dependencies/ContextDependencyHelpers.js +3 -3
  61. package/lib/dependencies/CreateRequireParserPlugin.js +6 -6
  62. package/lib/dependencies/CssIcssExportDependency.js +190 -87
  63. package/lib/dependencies/CssUrlDependency.js +35 -4
  64. package/lib/dependencies/ExternalModuleInitFragmentDependency.js +2 -2
  65. package/lib/dependencies/HarmonyCompatibilityDependency.js +32 -14
  66. package/lib/dependencies/HarmonyDetectionParserPlugin.js +43 -13
  67. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +7 -19
  68. package/lib/dependencies/HarmonyImportDependency.js +12 -1
  69. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +34 -107
  70. package/lib/dependencies/HarmonyImportGuard.js +192 -20
  71. package/lib/dependencies/HarmonyModulesPlugin.js +6 -0
  72. package/lib/dependencies/HarmonyTopLevelThisParserPlugin.js +1 -1
  73. package/lib/dependencies/HtmlEntryDependency.js +797 -172
  74. package/lib/dependencies/HtmlSourceDependency.js +26 -0
  75. package/lib/dependencies/ImportDependency.js +43 -1
  76. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +31 -18
  77. package/lib/dependencies/ImportMetaContextPlugin.js +38 -7
  78. package/lib/dependencies/ImportMetaGlobDependency.js +81 -0
  79. package/lib/dependencies/ImportMetaGlobDependencyParserPlugin.js +78 -0
  80. package/lib/dependencies/ImportMetaGlobHelpers.js +660 -0
  81. package/lib/dependencies/ImportMetaPlugin.js +532 -180
  82. package/lib/dependencies/ImportMetaResolveDependency.js +90 -0
  83. package/lib/dependencies/ImportParserPlugin.js +87 -26
  84. package/lib/dependencies/ImportPhase.js +10 -8
  85. package/lib/dependencies/LoaderPlugin.js +5 -1
  86. package/lib/dependencies/RequireContextDependencyParserPlugin.js +1 -1
  87. package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +3 -6
  88. package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +4 -11
  89. package/lib/dependencies/SystemPlugin.js +2 -4
  90. package/lib/dependencies/TopLevelAwaitDependency.js +93 -0
  91. package/lib/dependencies/URLDependency.js +141 -21
  92. package/lib/dependencies/{WorkerPlugin.js → WorkerAndWorkletPlugin.js} +324 -112
  93. package/lib/dependencies/WorkerDependency.js +86 -18
  94. package/lib/dependencies/WorkletDependency.js +278 -0
  95. package/lib/dll/DelegatedModuleFactoryPlugin.js +19 -0
  96. package/lib/errors/EnvironmentNotSupportAsyncWarning.js +1 -1
  97. package/lib/errors/LoaderLoadingError.js +20 -0
  98. package/lib/errors/ModuleParseError.js +39 -22
  99. package/lib/errors/NodeStuffInWebError.js +1 -1
  100. package/lib/esm/ModuleChunkFormatPlugin.js +47 -14
  101. package/lib/esm/ModuleChunkLoadingPlugin.js +8 -1
  102. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +29 -1
  103. package/lib/hmr/lazyCompilationBackend.js +32 -8
  104. package/lib/html/HtmlGenerator.js +940 -91
  105. package/lib/html/HtmlModule.js +3 -2
  106. package/lib/html/HtmlModulesPlugin.js +625 -170
  107. package/lib/html/HtmlParser.js +812 -340
  108. package/lib/html/favicon.svg +1 -0
  109. package/lib/html/syntax.js +2116 -834
  110. package/lib/ids/IdHelpers.js +1 -1
  111. package/lib/index.js +6 -0
  112. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +4 -5
  113. package/lib/javascript/BasicEvaluatedExpression.js +366 -48
  114. package/lib/javascript/JavascriptGenerator.js +197 -49
  115. package/lib/javascript/JavascriptModulesPlugin.js +178 -24
  116. package/lib/javascript/JavascriptParser.js +711 -355
  117. package/lib/javascript/JavascriptParserHelpers.js +3 -6
  118. package/lib/javascript/syntax.js +4380 -0
  119. package/lib/library/ModuleLibraryPlugin.js +38 -1
  120. package/lib/loaders/LoaderRunner.js +714 -0
  121. package/lib/loaders/loadLoader.js +100 -0
  122. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +19 -0
  123. package/lib/node/ReadFileCompileWasmPlugin.js +14 -0
  124. package/lib/optimize/ConcatenatedModule.js +120 -16
  125. package/lib/optimize/FlagIncludedChunksPlugin.js +13 -3
  126. package/lib/optimize/InnerGraphPlugin.js +50 -30
  127. package/lib/optimize/ModuleConcatenationPlugin.js +69 -3
  128. package/lib/optimize/SideEffectsFlagPlugin.js +86 -43
  129. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +15 -0
  130. package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +24 -13
  131. package/lib/prefetch/ResourceHintPlugin.js +663 -0
  132. package/lib/prefetch/ResourceHintRuntimeModule.js +149 -0
  133. package/lib/prefetch/StartupAssetHintRuntimeModule.js +210 -0
  134. package/lib/prefetch/parseResourceHintOptions.js +103 -0
  135. package/lib/rules/RuleSetCompiler.js +114 -0
  136. package/lib/runtime/AsyncModuleGeneratorRuntimeModule.js +56 -0
  137. package/lib/runtime/AsyncModuleRuntimeModule.js +24 -8
  138. package/lib/runtime/AutoPublicPathRuntimeModule.js +7 -1
  139. package/lib/runtime/CommonJsWrapRuntimeModule.js +37 -0
  140. package/lib/runtime/GetWorkletBootstrapRuntimeModule.js +59 -0
  141. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +204 -8
  142. package/lib/runtime/SetAnonymousDefaultNameRuntimeModule.js +4 -1
  143. package/lib/schemes/HttpUriPlugin.js +40 -1
  144. package/lib/schemes/VirtualUrlPlugin.js +1 -2
  145. package/lib/serialization/FileMiddleware.js +29 -3
  146. package/lib/stats/DefaultStatsFactoryPlugin.js +32 -3
  147. package/lib/stats/DefaultStatsPresetPlugin.js +2 -0
  148. package/lib/stats/DefaultStatsPrinterPlugin.js +12 -2
  149. package/lib/stats/StatsFactory.js +15 -8
  150. package/lib/url/URLParserPlugin.js +98 -19
  151. package/lib/util/AsyncQueue.js +122 -72
  152. package/lib/util/LocConverter.js +9 -8
  153. package/lib/util/SetHelpers.js +1 -1
  154. package/lib/util/SourceProcessor.js +41 -28
  155. package/lib/util/StackedMap.js +122 -48
  156. package/lib/util/binarySearchBounds.js +2 -2
  157. package/lib/util/concatenate.js +40 -14
  158. package/lib/util/createHooksRegistry.js +13 -5
  159. package/lib/util/dataURL.js +2 -2
  160. package/lib/util/deterministicGrouping.js +7 -5
  161. package/lib/util/formatSize.js +6 -2
  162. package/lib/util/globUtils.js +710 -0
  163. package/lib/util/identifier.js +23 -6
  164. package/lib/util/implicitTypeLoaderFallback.js +62 -0
  165. package/lib/util/internalSerializables.js +88 -71
  166. package/lib/util/magicComment.js +121 -25
  167. package/lib/util/numberHash.js +2 -2
  168. package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +24 -18
  169. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +33 -22
  170. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +79 -16
  171. package/lib/web/FetchCompileAsyncWasmPlugin.js +19 -0
  172. package/lib/web/FetchCompileWasmPlugin.js +14 -0
  173. package/lib/web/JsonpChunkLoadingRuntimeModule.js +2 -0
  174. package/lib/webpack.js +65 -0
  175. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +3 -0
  176. package/module.d.ts +21 -0
  177. package/package.json +14 -13
  178. package/schemas/WebpackOptions.check.js +1 -1
  179. package/schemas/WebpackOptions.json +759 -36
  180. package/schemas/plugins/HtmlParserOptions.check.js +1 -1
  181. package/schemas/plugins/ProgressPlugin.check.js +1 -1
  182. package/schemas/plugins/ProgressPlugin.json +17 -1
  183. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  184. package/schemas/plugins/container/ContainerReferencePlugin.json +1 -0
  185. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  186. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  187. package/schemas/plugins/container/ModuleFederationPlugin.json +1 -0
  188. package/schemas/plugins/css/CssAutoOrModuleParserOptions.check.js +1 -1
  189. package/schemas/plugins/css/CssModuleParserOptions.check.js +1 -1
  190. package/schemas/plugins/css/CssParserOptions.check.js +1 -1
  191. package/types.d.ts +1300 -325
@@ -98,7 +98,7 @@ class CreateRequireParserPlugin {
98
98
  "undefined",
99
99
  /** @type {Range} */ (expr.range)
100
100
  );
101
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
101
+ dep.loc = parser.getLocation(expr);
102
102
  parser.state.module.addPresentationalDependency(dep);
103
103
  return false;
104
104
  };
@@ -161,7 +161,7 @@ class CreateRequireParserPlugin {
161
161
  const err = new WebpackError(
162
162
  "module.createRequire supports only one argument."
163
163
  );
164
- err.loc = /** @type {DependencyLocation} */ (expr.loc);
164
+ err.loc = parser.getLocation(expr);
165
165
  parser.state.module.addWarning(err);
166
166
  return;
167
167
  }
@@ -171,7 +171,7 @@ class CreateRequireParserPlugin {
171
171
  const err = new WebpackError(
172
172
  "module.createRequire failed parsing argument."
173
173
  );
174
- err.loc = /** @type {DependencyLocation} */ (arg.loc);
174
+ err.loc = parser.getLocation(arg);
175
175
  parser.state.module.addWarning(err);
176
176
  return;
177
177
  }
@@ -249,7 +249,7 @@ class CreateRequireParserPlugin {
249
249
  : "",
250
250
  /** @type {Range} */ (statement.range)
251
251
  );
252
- clearDep.loc = /** @type {DependencyLocation} */ (statement.loc);
252
+ clearDep.loc = parser.getLocation(statement);
253
253
  parser.state.module.addPresentationalDependency(clearDep);
254
254
  parser.unsetAsiPosition(/** @type {Range} */ (statement.range)[1]);
255
255
  return true;
@@ -342,7 +342,7 @@ class CreateRequireParserPlugin {
342
342
  "/* createRequire */ undefined",
343
343
  /** @type {Range} */ (expr.range)
344
344
  );
345
- clearDep.loc = /** @type {DependencyLocation} */ (expr.loc);
345
+ clearDep.loc = parser.getLocation(expr);
346
346
  parser.state.module.addPresentationalDependency(clearDep);
347
347
  return true;
348
348
  });
@@ -353,7 +353,7 @@ class CreateRequireParserPlugin {
353
353
  "/* createRequire() */ undefined",
354
354
  /** @type {Range} */ (expr.range)
355
355
  );
356
- clearDep.loc = /** @type {DependencyLocation} */ (expr.loc);
356
+ clearDep.loc = parser.getLocation(expr);
357
357
  parser.state.module.addPresentationalDependency(clearDep);
358
358
  return true;
359
359
  });
@@ -245,7 +245,10 @@ const computeInterpolatedIdentifier = (
245
245
  * @property {boolean} interpolate whether the value needs interpolation
246
246
  * @property {ExportMode} exportMode export mode
247
247
  * @property {ExportType} exportType export type
248
- * @property {DependencyLocation=} loc per-export source location (for export source maps)
248
+ * @property {number} locStartLine per-export source start line (1-based; flat numbers instead of a nested `DependencyLocation` — entries are per-export hot allocations)
249
+ * @property {number} locStartColumn per-export source start column
250
+ * @property {number} locEndLine per-export source end line
251
+ * @property {number} locEndColumn per-export source end column
249
252
  * @property {string[]=} _conventionNames memoized convention names for `name`
250
253
  * @property {string[]=} _valueConventionNames memoized convention names for `value`
251
254
  */
@@ -289,6 +292,28 @@ class CssIcssExportDependency extends NullDependency {
289
292
  this.entries = entries;
290
293
  /** @type {undefined | string} */
291
294
  this._hashUpdate = undefined;
295
+ /** @type {undefined | Map<string, CssExportEntry[]>} lazily-built `name -> entries` index, reused across every importer's codegen */
296
+ this._entriesByName = undefined;
297
+ }
298
+
299
+ /**
300
+ * The `entries` grouped by export name, built once and reused. `entries` is
301
+ * immutable after construction/deserialization, so this stays valid for the
302
+ * dependency's lifetime (the composes/`@value` target of many importers).
303
+ * @returns {Map<string, CssExportEntry[]>} entries grouped by export name
304
+ */
305
+ getEntriesByName() {
306
+ if (this._entriesByName === undefined) {
307
+ /** @type {Map<string, CssExportEntry[]>} */
308
+ const map = new Map();
309
+ for (const e of this.entries) {
310
+ const list = map.get(e.name);
311
+ if (list) list.push(e);
312
+ else map.set(e.name, [e]);
313
+ }
314
+ this._entriesByName = map;
315
+ }
316
+ return this._entriesByName;
292
317
  }
293
318
 
294
319
  get type() {
@@ -412,8 +437,14 @@ class CssIcssExportDependency extends NullDependency {
412
437
  );
413
438
  error.module = module;
414
439
  // Per-entry loc so Compilation attributes the warning precisely
415
- // (it can't use the consolidated dependency's single loc).
416
- if (entry.loc) error.loc = entry.loc;
440
+ // (it can't use the consolidated dependency's single loc). Built
441
+ // on demand — entries carry flat numbers, not location objects.
442
+ if (entry.locStartLine > 0) {
443
+ error.loc = {
444
+ start: { line: entry.locStartLine, column: entry.locStartColumn },
445
+ end: { line: entry.locEndLine, column: entry.locEndColumn }
446
+ };
447
+ }
417
448
  if (warnings === null) warnings = [];
418
449
  warnings.push(error);
419
450
  }
@@ -464,7 +495,10 @@ class CssIcssExportDependency extends NullDependency {
464
495
  write(entry.interpolate);
465
496
  write(entry.exportMode);
466
497
  write(entry.exportType);
467
- write(entry.loc);
498
+ write(entry.locStartLine);
499
+ write(entry.locStartColumn);
500
+ write(entry.locEndLine);
501
+ write(entry.locEndColumn);
468
502
  }
469
503
  super.serialize(context);
470
504
  }
@@ -486,58 +520,139 @@ class CssIcssExportDependency extends NullDependency {
486
520
  interpolate: /** @type {boolean} */ (read()),
487
521
  exportMode: /** @type {ExportMode} */ (read()),
488
522
  exportType: /** @type {ExportType} */ (read()),
489
- loc: /** @type {DependencyLocation=} */ (read())
523
+ locStartLine: /** @type {number} */ (read()),
524
+ locStartColumn: /** @type {number} */ (read()),
525
+ locEndLine: /** @type {number} */ (read()),
526
+ locEndColumn: /** @type {number} */ (read())
490
527
  });
491
528
  }
492
529
  this.entries = entries;
493
530
  this._hashUpdate = undefined;
531
+ this._entriesByName = undefined;
494
532
  super.deserialize(context);
495
533
  }
496
534
  }
497
535
 
498
536
  /**
499
- * Get (or lazily build into `indexCache`) a name -> entries index for `dep`,
500
- * so composes resolution does a Map lookup instead of scanning all entries per
501
- * reference. The cache is owned by one `apply` call and GC'd with it.
502
- * @param {Map<CssIcssExportDependency, Map<string, CssExportEntry[]>>} indexCache transient cache
503
- * @param {CssIcssExportDependency} dep export dependency
504
- * @returns {Map<string, CssExportEntry[]>} entries grouped by name
537
+ * @typedef {object} ResolutionCache
538
+ * @property {Map<CssModule, Map<string, CssExportEntry[]>>} exports module -> (export name -> entries) across all its export deps
539
+ * @property {Map<CssIcssImportDependency, CssModule | null>} targets import dep -> resolved target module
540
+ */
541
+
542
+ /**
543
+ * Creates the transient per-`apply` cache shared by `resolve` and
544
+ * `resolveReferences`. It is GC'd when the codegen call returns and is never
545
+ * retained on the dependency.
546
+ * @returns {ResolutionCache} empty resolution cache
547
+ */
548
+ const createResolutionCache = () => ({
549
+ exports: new Map(),
550
+ targets: new Map()
551
+ });
552
+
553
+ /**
554
+ * Shared read-only index for modules that own no export dep.
555
+ * @type {Map<string, CssExportEntry[]>}
556
+ */
557
+ const EMPTY_INDEX = new Map();
558
+
559
+ /**
560
+ * Per-module `local name -> import deps` index, keyed by module and validated by
561
+ * `buildInfo` identity (a fresh object per build). `apply` runs once per source
562
+ * type (CSS and JS), so this survives both passes — the index is built once per
563
+ * build instead of once per `apply`. Weakly held, so it never keeps a module
564
+ * alive.
565
+ * @type {WeakMap<CssModule, { buildInfo: unknown, index: Map<string, CssIcssImportDependency[]> }>}
566
+ */
567
+ const moduleImportIndexes = new WeakMap();
568
+
569
+ /**
570
+ * Get (or lazily resolve) the target module of an `@value`/composes import dep.
571
+ * The same import dep is followed by many entries within one codegen, so the
572
+ * `moduleGraph.getModule` lookup is memoized per dep.
573
+ * @param {ResolutionCache} cache resolution cache
574
+ * @param {ModuleGraph} moduleGraph module graph
575
+ * @param {CssIcssImportDependency} importDep import dependency
576
+ * @returns {CssModule | null} resolved target module, or `null` if none
577
+ */
578
+ const getTargetModule = (cache, moduleGraph, importDep) => {
579
+ let module = cache.targets.get(importDep);
580
+ if (module === undefined) {
581
+ module = /** @type {CssModule | null} */ (moduleGraph.getModule(importDep));
582
+ cache.targets.set(importDep, module);
583
+ }
584
+ return module;
585
+ };
586
+
587
+ /**
588
+ * Get (or lazily build) the `name -> entries` index for `module`. There is one
589
+ * consolidated `CssIcssExportDependency` per module, and its own index is cached
590
+ * on the dep — so a module composed/imported by many others builds its index
591
+ * once per build rather than once per importer, and resolution does a single Map
592
+ * lookup instead of re-scanning `module.dependencies` per reference.
593
+ * @param {ResolutionCache} cache resolution cache
594
+ * @param {CssModule} module css module
595
+ * @returns {Map<string, CssExportEntry[]>} entries grouped by export name
505
596
  */
506
- const indexEntries = (indexCache, dep) => {
507
- let map = indexCache.get(dep);
597
+ const getExportIndex = (cache, module) => {
598
+ let map = cache.exports.get(module);
508
599
  if (map === undefined) {
509
- map = new Map();
510
- for (const e of dep.entries) {
511
- const list = map.get(e.name);
512
- if (list) list.push(e);
513
- else map.set(e.name, [e]);
600
+ map = EMPTY_INDEX;
601
+ for (const dep of module.dependencies) {
602
+ if (dep instanceof CssIcssExportDependency) {
603
+ map = dep.getEntriesByName();
604
+ break;
605
+ }
514
606
  }
515
- indexCache.set(dep, map);
607
+ cache.exports.set(module, map);
516
608
  }
517
609
  return map;
518
610
  };
519
611
 
612
+ /**
613
+ * Get (or lazily build) the `local name -> import deps` index for `module`, so
614
+ * `findImportDep` is a Map lookup instead of a linear scan of every dependency.
615
+ * Cached per build on the module (validated by `buildInfo` identity) so both the
616
+ * CSS and JS codegen passes reuse one scan of `module.dependencies`.
617
+ * @param {CssModule} module css module
618
+ * @returns {Map<string, CssIcssImportDependency[]>} import deps grouped by local name
619
+ */
620
+ const getImportIndex = (module) => {
621
+ const buildInfo = module.buildInfo;
622
+ const cached = moduleImportIndexes.get(module);
623
+ if (cached !== undefined && cached.buildInfo === buildInfo) {
624
+ return cached.index;
625
+ }
626
+ /** @type {Map<string, CssIcssImportDependency[]>} */
627
+ const index = new Map();
628
+ for (const d of module.dependencies) {
629
+ if (!(d instanceof CssIcssImportDependency)) continue;
630
+ const list = index.get(d.localName);
631
+ if (list) list.push(d);
632
+ else index.set(d.localName, [d]);
633
+ }
634
+ moduleImportIndexes.set(module, { buildInfo, index });
635
+ return index;
636
+ };
637
+
520
638
  /**
521
639
  * Finds the active `CssIcssImportDependency` for a given local name. When a
522
640
  * `request` is provided the lookup also requires the import dependency's
523
641
  * `request` to match, so references between two `@value foo from "..."`
524
642
  * declarations resolve through the import in scope at the reference site.
525
- * @param {Iterable<Dependency>} dependencies module dependencies to search
643
+ * @param {CssModule} module module owning the dependencies to search
526
644
  * @param {string} localName local name
527
645
  * @param {string=} request user request of the `@value` import to match
528
646
  * @returns {CssIcssImportDependency | undefined} matching import dep, if any
529
647
  */
530
- const findImportDep = (dependencies, localName, request) => {
531
- /** @type {CssIcssImportDependency | undefined} */
532
- let firstMatch;
533
- for (const d of dependencies) {
534
- if (d instanceof CssIcssImportDependency && d.localName === localName) {
535
- if (request === undefined) return d;
536
- if (d.request === request) return d;
537
- if (firstMatch === undefined) firstMatch = d;
538
- }
539
- }
540
- return firstMatch;
648
+ const findImportDep = (module, localName, request) => {
649
+ const list = getImportIndex(module).get(localName);
650
+ if (list === undefined) return undefined;
651
+ // Import deps keep dependency order, so `list[0]` is the first match (the
652
+ // legacy `firstMatch` fallback when no request-specific match exists).
653
+ if (request === undefined) return list[0];
654
+ for (const d of list) if (d.request === request) return d;
655
+ return list[0];
541
656
  };
542
657
 
543
658
  CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends (
@@ -552,7 +667,7 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
552
667
  * @param {DependencyTemplateContext} templateContext the context object
553
668
  * @param {string | undefined} request user request of the `@value` import
554
669
  * @param {Set<CssExportEntry>=} seen cycle guard
555
- * @param {Map<CssIcssExportDependency, Map<string, CssExportEntry[]>>=} indexCache transient per-codegen name index (shared with `resolveReferences` within one `apply`)
670
+ * @param {ResolutionCache=} cache transient per-codegen index (shared with `resolveReferences` within one `apply`)
556
671
  * @returns {string | undefined} found reference
557
672
  */
558
673
  static resolve(
@@ -561,29 +676,21 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
561
676
  templateContext,
562
677
  request,
563
678
  seen = new Set(),
564
- indexCache = new Map()
679
+ cache = createResolutionCache()
565
680
  ) {
566
681
  const { moduleGraph } = templateContext;
567
682
  const importDep = findImportDep(
568
- templateContext.module.dependencies,
683
+ /** @type {CssModule} */ (templateContext.module),
569
684
  localName,
570
685
  request
571
686
  );
572
687
  if (!importDep) return undefined;
573
688
 
574
- const module = /** @type {CssModule} */ (moduleGraph.getModule(importDep));
689
+ const module = getTargetModule(cache, moduleGraph, importDep);
575
690
  if (!module) return undefined;
576
691
 
577
- /** @type {CssExportEntry | undefined} */
578
- let exportEntry;
579
- for (const dep of module.dependencies) {
580
- if (!(dep instanceof CssIcssExportDependency)) continue;
581
- const matches = indexEntries(indexCache, dep).get(importName);
582
- if (matches) {
583
- exportEntry = matches[0];
584
- break;
585
- }
586
- }
692
+ const matches = getExportIndex(cache, module).get(importName);
693
+ const exportEntry = matches && matches[0];
587
694
  if (!exportEntry) return undefined;
588
695
  if (seen.has(exportEntry)) return undefined;
589
696
  seen.add(exportEntry);
@@ -597,7 +704,7 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
597
704
  { ...templateContext, module },
598
705
  value[2],
599
706
  seen,
600
- indexCache
707
+ cache
601
708
  );
602
709
  }
603
710
 
@@ -616,10 +723,10 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
616
723
  * @param {CssExportEntry} entry composes entry
617
724
  * @param {DependencyTemplateContext} templateContext template context
618
725
  * @param {Set<CssExportEntry>} seen cycle guard
619
- * @param {Map<CssIcssExportDependency, Map<string, CssExportEntry[]>>} indexCache transient per-codegen name index, discarded after the module's `apply` (so it isn't retained on the dependency)
726
+ * @param {ResolutionCache} cache transient per-codegen index, discarded after the module's `apply` (so it isn't retained on the dependency)
620
727
  * @returns {string[]} final names
621
728
  */
622
- static resolveReferences(entry, templateContext, seen, indexCache) {
729
+ static resolveReferences(entry, templateContext, seen, cache) {
623
730
  /** @type {string[]} */
624
731
  const references = [];
625
732
 
@@ -628,24 +735,24 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
628
735
 
629
736
  if (Array.isArray(entry.value)) {
630
737
  const importDep = findImportDep(
631
- templateContext.module.dependencies,
738
+ /** @type {CssModule} */ (templateContext.module),
632
739
  entry.value[0],
633
740
  entry.value[2]
634
741
  );
635
742
  if (!importDep) return references;
636
743
 
637
- const module =
638
- /** @type {CssModule} */
639
- (templateContext.moduleGraph.getModule(importDep));
744
+ const module = getTargetModule(
745
+ cache,
746
+ templateContext.moduleGraph,
747
+ importDep
748
+ );
640
749
  if (!module) return references;
641
750
 
642
751
  // Same overridden context and target name for every matched entry — build once, not per entry.
643
752
  const subContext = { ...templateContext, module };
644
753
  const name = /** @type {string[]} */ (entry.value)[1];
645
- for (const dep of module.dependencies) {
646
- if (!(dep instanceof CssIcssExportDependency)) continue;
647
- const matches = indexEntries(indexCache, dep).get(name);
648
- if (!matches) continue;
754
+ const matches = getExportIndex(cache, module).get(name);
755
+ if (matches) {
649
756
  for (const d of matches) {
650
757
  if (Array.isArray(d.value)) {
651
758
  references.push(
@@ -653,7 +760,7 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
653
760
  d,
654
761
  subContext,
655
762
  seen,
656
- indexCache
763
+ cache
657
764
  )
658
765
  );
659
766
  } else {
@@ -676,12 +783,11 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
676
783
  )
677
784
  );
678
785
 
679
- for (const dep of templateContext.module.dependencies) {
680
- if (!(dep instanceof CssIcssExportDependency)) continue;
681
- const matches = indexEntries(indexCache, dep).get(
682
- /** @type {string} */ (entry.value)
683
- );
684
- if (!matches) continue;
786
+ const matches = getExportIndex(
787
+ cache,
788
+ /** @type {CssModule} */ (templateContext.module)
789
+ ).get(/** @type {string} */ (entry.value));
790
+ if (matches) {
685
791
  for (const d of matches) {
686
792
  if (d.exportType !== EXPORT_TYPE.COMPOSES) continue;
687
793
  if (Array.isArray(d.value)) {
@@ -690,7 +796,7 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
690
796
  d,
691
797
  templateContext,
692
798
  seen,
693
- indexCache
799
+ cache
694
800
  )
695
801
  );
696
802
  } else {
@@ -746,9 +852,9 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
746
852
  // All entries belong to this one module, so resolve its ExportsInfo once
747
853
  // instead of re-resolving `module -> exportsInfo` per export name.
748
854
  const exportsInfo = isJs ? moduleGraph.getExportsInfo(module) : undefined;
749
- // Transient name index for composes resolution within this module's codegen; GC'd when apply returns (never retained on the dependency).
750
- /** @type {Map<CssIcssExportDependency, Map<string, CssExportEntry[]>>} */
751
- const indexCache = new Map();
855
+ // Transient per-module indexes for composes resolution within this
856
+ // module's codegen; GC'd when apply returns (never retained on the dependency).
857
+ const cache = createResolutionCache();
752
858
 
753
859
  for (const entry of dep.entries) {
754
860
  if (!entry.range && !isJs) continue;
@@ -761,7 +867,7 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
761
867
  entry,
762
868
  templateContext,
763
869
  new Set(),
764
- indexCache
870
+ cache
765
871
  ).join(" ");
766
872
  } else if (isReference) {
767
873
  const resolved = CssIcssExportDependencyTemplate.resolve(
@@ -770,7 +876,7 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
770
876
  templateContext,
771
877
  /** @type {string[]} */ (entry.value)[2],
772
878
  new Set(),
773
- indexCache
879
+ cache
774
880
  );
775
881
  value = resolved || /** @type {string[]} */ (entry.value)[0];
776
882
  } else {
@@ -794,36 +900,33 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
794
900
  /** @type {Set<string>} */
795
901
  const allNames = new Set();
796
902
  for (const name of names) {
797
- const usedName = /** @type {NonNullable<typeof exportsInfo>} */ (
798
- exportsInfo
799
- )
800
- .getExportInfo(name)
801
- .getUsedName(name, runtime);
802
- if (usedName) allNames.add(/** @type {string} */ (usedName));
903
+ if (
904
+ /** @type {NonNullable<typeof exportsInfo>} */ (exportsInfo)
905
+ .getExportInfo(name)
906
+ .getUsedName(name, runtime)
907
+ ) {
908
+ allNames.add(name);
909
+ }
803
910
  }
804
- for (const name of names) allNames.add(name);
805
911
  const unescaped = getCssTokens().unescapeIdentifier(
806
912
  value,
807
913
  templateContext.runtimeTemplate.compilation.compiler.root
808
914
  );
809
915
 
810
- const depLocStart =
811
- entry.loc &&
812
- /** @type {{ start?: { line: number, column: number } }} */ (
813
- entry.loc
814
- ).start;
916
+ const depLocLine = entry.locStartLine;
917
+ const depLocColumn = entry.locStartColumn;
815
918
  for (const used of allNames) {
816
919
  if (entry.exportMode === EXPORT_MODE.ONCE) {
817
920
  if (cssData.exports.has(used)) continue;
818
921
  cssData.exports.set(used, unescaped);
819
922
  if (
820
- depLocStart &&
923
+ depLocLine > 0 &&
821
924
  cssData.exportLocs &&
822
925
  !cssData.exportLocs.has(used)
823
926
  ) {
824
927
  cssData.exportLocs.set(used, {
825
- line: depLocStart.line,
826
- column: depLocStart.column
928
+ line: depLocLine,
929
+ column: depLocColumn
827
930
  });
828
931
  }
829
932
  } else {
@@ -836,13 +939,13 @@ CssIcssExportDependency.Template = class CssIcssExportDependencyTemplate extends
836
939
  `${originalValue ? `${originalValue}${unescaped ? " " : ""}` : ""}${unescaped}`
837
940
  );
838
941
  if (
839
- depLocStart &&
942
+ depLocLine > 0 &&
840
943
  cssData.exportLocs &&
841
944
  !cssData.exportLocs.has(used)
842
945
  ) {
843
946
  cssData.exportLocs.set(used, {
844
- line: depLocStart.line,
845
- column: depLocStart.column
947
+ line: depLocLine,
948
+ column: depLocColumn
846
949
  });
847
950
  }
848
951
  }
@@ -21,8 +21,8 @@ const ModuleDependency = require("./ModuleDependency");
21
21
  /** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
22
22
  /** @typedef {import("../Module").CodeGenerationResultData} CodeGenerationResultData */
23
23
  /** @typedef {import("../javascript/JavascriptParser").Range} Range */
24
- /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext<["string" | "url" | "src"]>} ObjectDeserializerContext */
25
- /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext<["string" | "url" | "src"]>} ObjectSerializerContext */
24
+ /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext<["string" | "url" | "src", true | undefined, true | undefined, ("high" | "low" | "auto" | undefined), string | undefined, string | undefined, string | undefined]>} ObjectDeserializerContext */
25
+ /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext<["string" | "url" | "src", true | undefined, true | undefined, ("high" | "low" | "auto" | undefined), string | undefined, string | undefined, string | undefined]>} ObjectSerializerContext */
26
26
  /** @typedef {import("../util/Hash")} Hash */
27
27
  /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
28
28
  /** @typedef {import("../NormalModule").NormalModuleBuildInfo} NormalModuleBuildInfo */
@@ -42,6 +42,18 @@ class CssUrlDependency extends ModuleDependency {
42
42
  super(request);
43
43
  this.range = range;
44
44
  this.urlType = urlType;
45
+ /** @type {true | undefined} */
46
+ this.prefetch = undefined;
47
+ /** @type {true | undefined} */
48
+ this.preload = undefined;
49
+ /** @type {"low" | "high" | "auto" | undefined} */
50
+ this.fetchPriority = undefined;
51
+ /** @type {string | undefined} */
52
+ this.asAttribute = undefined;
53
+ /** @type {string | undefined} */
54
+ this.typeAttribute = undefined;
55
+ /** @type {string | undefined} */
56
+ this.mediaAttribute = undefined;
45
57
  }
46
58
 
47
59
  get type() {
@@ -89,7 +101,14 @@ class CssUrlDependency extends ModuleDependency {
89
101
  * @param {ObjectSerializerContext} context context
90
102
  */
91
103
  serialize(context) {
92
- context.write(this.urlType);
104
+ context
105
+ .write(this.urlType)
106
+ .write(this.prefetch)
107
+ .write(this.preload)
108
+ .write(this.fetchPriority)
109
+ .write(this.asAttribute)
110
+ .write(this.typeAttribute)
111
+ .write(this.mediaAttribute);
93
112
  super.serialize(context);
94
113
  }
95
114
 
@@ -99,7 +118,19 @@ class CssUrlDependency extends ModuleDependency {
99
118
  */
100
119
  deserialize(context) {
101
120
  this.urlType = context.read();
102
- super.deserialize(context.rest);
121
+ const c1 = context.rest;
122
+ this.prefetch = c1.read();
123
+ const c2 = c1.rest;
124
+ this.preload = c2.read();
125
+ const c3 = c2.rest;
126
+ this.fetchPriority = c3.read();
127
+ const c4 = c3.rest;
128
+ this.asAttribute = c4.read();
129
+ const c5 = c4.rest;
130
+ this.typeAttribute = c5.read();
131
+ const c6 = c5.rest;
132
+ this.mediaAttribute = c6.read();
133
+ super.deserialize(c6.rest);
103
134
  }
104
135
  }
105
136
 
@@ -60,10 +60,10 @@ class ExternalModuleInitFragmentDependency extends NullDependency {
60
60
 
61
61
  makeSerializable(
62
62
  ExternalModuleInitFragmentDependency,
63
- "webpack/lib/dependencies/ExternalModuleConstDependency"
63
+ "webpack/lib/dependencies/ExternalModuleInitFragmentDependency"
64
64
  );
65
65
 
66
- ExternalModuleInitFragmentDependency.Template = class ExternalModuleConstDependencyTemplate extends (
66
+ ExternalModuleInitFragmentDependency.Template = class ExternalModuleInitFragmentDependencyTemplate extends (
67
67
  DependencyTemplate
68
68
  ) {
69
69
  /**
@@ -8,6 +8,7 @@
8
8
  const { UsageState } = require("../ExportsInfo");
9
9
  const InitFragment = require("../InitFragment");
10
10
  const RuntimeGlobals = require("../RuntimeGlobals");
11
+ const isGeneratorLowered = require("../async-modules/isGeneratorLowered");
11
12
  const makeSerializable = require("../util/makeSerializable");
12
13
  const NullDependency = require("./NullDependency");
13
14
 
@@ -71,20 +72,37 @@ HarmonyCompatibilityDependency.Template = class HarmonyExportDependencyTemplate
71
72
  }
72
73
  if (moduleGraph.isAsync(module)) {
73
74
  runtimeRequirements.add(RuntimeGlobals.module);
74
- runtimeRequirements.add(RuntimeGlobals.asyncModule);
75
- initFragments.push(
76
- new InitFragment(
77
- runtimeTemplate.supportsArrowFunction()
78
- ? `${RuntimeGlobals.asyncModule}(${module.moduleArgument}, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {\n`
79
- : `${RuntimeGlobals.asyncModule}(${module.moduleArgument}, async function (__webpack_handle_async_dependencies__, __webpack_async_result__) { try {\n`,
80
- InitFragment.STAGE_ASYNC_BOUNDARY,
81
- 0,
82
- undefined,
83
- `\n__webpack_async_result__();\n} catch(e) { __webpack_async_result__(e); } }${
84
- /** @type {BuildMeta} */ (module.buildMeta).async ? ", 1" : ""
85
- });`
86
- )
87
- );
75
+ const hasAwait = /** @type {BuildMeta} */ (module.buildMeta).async
76
+ ? ", 1"
77
+ : "";
78
+ // Target has no `async`/`await` but has generators: drive the body as a
79
+ // generator so `await` becomes `yield`, keeping the module in a single
80
+ // scope (unlike a `.then` callback) without transpiling to a state machine.
81
+ if (isGeneratorLowered(module, moduleGraph, runtimeTemplate)) {
82
+ runtimeRequirements.add(RuntimeGlobals.asyncModuleGenerator);
83
+ initFragments.push(
84
+ new InitFragment(
85
+ `${RuntimeGlobals.asyncModule}(${module.moduleArgument}, ${RuntimeGlobals.asyncModuleGenerator}(function* (__webpack_handle_async_dependencies__, __webpack_async_result__) { try {\n`,
86
+ InitFragment.STAGE_ASYNC_BOUNDARY,
87
+ 0,
88
+ undefined,
89
+ `\n__webpack_async_result__();\n} catch(e) { __webpack_async_result__(e); } })${hasAwait});`
90
+ )
91
+ );
92
+ } else {
93
+ runtimeRequirements.add(RuntimeGlobals.asyncModule);
94
+ initFragments.push(
95
+ new InitFragment(
96
+ runtimeTemplate.supportsArrowFunction()
97
+ ? `${RuntimeGlobals.asyncModule}(${module.moduleArgument}, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {\n`
98
+ : `${RuntimeGlobals.asyncModule}(${module.moduleArgument}, async function (__webpack_handle_async_dependencies__, __webpack_async_result__) { try {\n`,
99
+ InitFragment.STAGE_ASYNC_BOUNDARY,
100
+ 0,
101
+ undefined,
102
+ `\n__webpack_async_result__();\n} catch(e) { __webpack_async_result__(e); } }${hasAwait});`
103
+ )
104
+ );
105
+ }
88
106
  }
89
107
  }
90
108
  };