webpack 5.108.4 → 5.109.1

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 (200) hide show
  1. package/bin/webpack.js +12 -0
  2. package/lib/APIPlugin.js +48 -29
  3. package/lib/CacheFacade.js +8 -0
  4. package/lib/ChunkGraph.js +17 -15
  5. package/lib/ChunkGroup.js +1 -0
  6. package/lib/CompatibilityPlugin.js +62 -29
  7. package/lib/Compilation.js +58 -6
  8. package/lib/ConstPlugin.js +11 -11
  9. package/lib/ContextModule.js +239 -6
  10. package/lib/ContextModuleFactory.js +139 -14
  11. package/lib/DefinePlugin.js +433 -112
  12. package/lib/Entrypoint.js +1 -1
  13. package/lib/ExportsInfo.js +22 -5
  14. package/lib/ExportsInfoApiPlugin.js +2 -2
  15. package/lib/ExternalModule.js +107 -5
  16. package/lib/ExternalModuleFactoryPlugin.js +20 -1
  17. package/lib/FileSystemInfo.js +256 -100
  18. package/lib/FlagDependencyUsagePlugin.js +33 -12
  19. package/lib/HotModuleReplacementPlugin.js +18 -15
  20. package/lib/InitFragment.js +20 -32
  21. package/lib/Module.js +3 -0
  22. package/lib/ModuleFilenameHelpers.js +2 -2
  23. package/lib/ModuleTypeConstants.js +8 -1
  24. package/lib/MultiCompiler.js +13 -2
  25. package/lib/MultiWatching.js +1 -0
  26. package/lib/NodeStuffPlugin.js +51 -33
  27. package/lib/NormalModule.js +175 -401
  28. package/lib/NormalModuleFactory.js +76 -2
  29. package/lib/ProgressPlugin.js +211 -119
  30. package/lib/ProvidePlugin.js +2 -2
  31. package/lib/RuntimeGlobals.js +47 -0
  32. package/lib/RuntimePlugin.js +67 -107
  33. package/lib/RuntimeTemplate.js +304 -16
  34. package/lib/Template.js +23 -3
  35. package/lib/UseStrictPlugin.js +1 -1
  36. package/lib/WebpackIsIncludedPlugin.js +1 -1
  37. package/lib/WebpackOptionsApply.js +24 -19
  38. package/lib/asset/AssetGenerator.js +110 -28
  39. package/lib/asset/AssetModulesPlugin.js +92 -2
  40. package/lib/asset/WebManifestGenerator.js +164 -0
  41. package/lib/asset/WebManifestParser.js +130 -0
  42. package/lib/async-modules/AwaitDependenciesInitFragment.js +14 -4
  43. package/lib/async-modules/isGeneratorLowered.js +26 -0
  44. package/lib/cache/PackFileCacheStrategy.js +9 -3
  45. package/lib/config/browserslistTargetHandler.js +40 -0
  46. package/lib/config/defaults.js +219 -29
  47. package/lib/config/normalization.js +26 -0
  48. package/lib/config/target.js +9 -1
  49. package/lib/container/HoistContainerReferencesPlugin.js +47 -55
  50. package/lib/css/CssGenerator.js +40 -31
  51. package/lib/css/CssLoadingRuntimeModule.js +5 -1
  52. package/lib/css/CssModulesPlugin.js +13 -0
  53. package/lib/css/CssParser.js +729 -313
  54. package/lib/css/syntax.js +1371 -861
  55. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +6 -6
  56. package/lib/dependencies/AMDPlugin.js +2 -2
  57. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +13 -13
  58. package/lib/dependencies/CommonJsDependencyHelpers.js +39 -0
  59. package/lib/dependencies/CommonJsExportRequireDependency.js +19 -0
  60. package/lib/dependencies/CommonJsExportsDependency.js +47 -2
  61. package/lib/dependencies/CommonJsExportsParserPlugin.js +10 -10
  62. package/lib/dependencies/CommonJsImportsParserPlugin.js +18 -18
  63. package/lib/dependencies/CommonJsPlugin.js +2 -2
  64. package/lib/dependencies/CommonJsRequireDependency.js +26 -1
  65. package/lib/dependencies/CommonJsSelfReferenceDependency.js +32 -1
  66. package/lib/dependencies/ContextDependencyHelpers.js +3 -3
  67. package/lib/dependencies/CreateRequireParserPlugin.js +6 -6
  68. package/lib/dependencies/CssIcssExportDependency.js +162 -71
  69. package/lib/dependencies/CssUrlDependency.js +35 -4
  70. package/lib/dependencies/ExternalModuleInitFragmentDependency.js +2 -2
  71. package/lib/dependencies/HarmonyCompatibilityDependency.js +32 -14
  72. package/lib/dependencies/HarmonyDetectionParserPlugin.js +43 -13
  73. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +2 -1
  74. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +7 -19
  75. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +17 -9
  76. package/lib/dependencies/HarmonyImportDependency.js +13 -2
  77. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +11 -11
  78. package/lib/dependencies/HarmonyImportSpecifierDependency.js +10 -7
  79. package/lib/dependencies/HarmonyModulesPlugin.js +6 -0
  80. package/lib/dependencies/HarmonyTopLevelThisParserPlugin.js +1 -1
  81. package/lib/dependencies/HtmlEntryDependency.js +797 -172
  82. package/lib/dependencies/HtmlSourceDependency.js +26 -0
  83. package/lib/dependencies/ImportDependency.js +43 -1
  84. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +31 -18
  85. package/lib/dependencies/ImportMetaContextPlugin.js +38 -7
  86. package/lib/dependencies/ImportMetaGlobDependency.js +81 -0
  87. package/lib/dependencies/ImportMetaGlobDependencyParserPlugin.js +78 -0
  88. package/lib/dependencies/ImportMetaGlobHelpers.js +660 -0
  89. package/lib/dependencies/ImportMetaPlugin.js +532 -180
  90. package/lib/dependencies/ImportMetaResolveDependency.js +90 -0
  91. package/lib/dependencies/ImportParserPlugin.js +80 -17
  92. package/lib/dependencies/ImportPhase.js +10 -8
  93. package/lib/dependencies/LoaderPlugin.js +5 -1
  94. package/lib/dependencies/RequireContextDependencyParserPlugin.js +1 -1
  95. package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +3 -6
  96. package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +4 -11
  97. package/lib/dependencies/SystemPlugin.js +2 -4
  98. package/lib/dependencies/TopLevelAwaitDependency.js +93 -0
  99. package/lib/dependencies/URLDependency.js +141 -21
  100. package/lib/dependencies/{WorkerPlugin.js → WorkerAndWorkletPlugin.js} +324 -112
  101. package/lib/dependencies/WorkerDependency.js +86 -18
  102. package/lib/dependencies/WorkletDependency.js +278 -0
  103. package/lib/dll/DelegatedModuleFactoryPlugin.js +19 -0
  104. package/lib/errors/EnvironmentNotSupportAsyncWarning.js +1 -1
  105. package/lib/errors/LoaderLoadingError.js +20 -0
  106. package/lib/errors/ModuleParseError.js +39 -22
  107. package/lib/errors/NodeStuffInWebError.js +1 -1
  108. package/lib/esm/ModuleChunkFormatPlugin.js +47 -14
  109. package/lib/esm/ModuleChunkLoadingPlugin.js +8 -1
  110. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +29 -1
  111. package/lib/hmr/lazyCompilationBackend.js +51 -12
  112. package/lib/html/HtmlGenerator.js +907 -15
  113. package/lib/html/HtmlModule.js +2 -2
  114. package/lib/html/HtmlModulesPlugin.js +610 -166
  115. package/lib/html/HtmlParser.js +603 -247
  116. package/lib/html/favicon.svg +1 -0
  117. package/lib/html/syntax.js +3451 -2762
  118. package/lib/ids/IdHelpers.js +25 -11
  119. package/lib/index.js +6 -0
  120. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +4 -5
  121. package/lib/javascript/BasicEvaluatedExpression.js +366 -48
  122. package/lib/javascript/JavascriptGenerator.js +197 -49
  123. package/lib/javascript/JavascriptModulesPlugin.js +178 -24
  124. package/lib/javascript/JavascriptParser.js +704 -355
  125. package/lib/javascript/JavascriptParserHelpers.js +3 -6
  126. package/lib/javascript/syntax.js +5037 -0
  127. package/lib/library/ModuleLibraryPlugin.js +38 -1
  128. package/lib/loaders/LoaderRunner.js +714 -0
  129. package/lib/loaders/loadLoader.js +100 -0
  130. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +29 -2
  131. package/lib/node/ReadFileCompileWasmPlugin.js +24 -2
  132. package/lib/optimize/AggressiveMergingPlugin.js +19 -15
  133. package/lib/optimize/ConcatenatedModule.js +139 -31
  134. package/lib/optimize/FlagIncludedChunksPlugin.js +13 -3
  135. package/lib/optimize/InnerGraphPlugin.js +50 -30
  136. package/lib/optimize/ModuleConcatenationPlugin.js +139 -24
  137. package/lib/optimize/SideEffectsFlagPlugin.js +86 -43
  138. package/lib/optimize/SplitChunksPlugin.js +146 -44
  139. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +15 -0
  140. package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +24 -13
  141. package/lib/prefetch/ResourceHintPlugin.js +687 -0
  142. package/lib/prefetch/ResourceHintRuntimeModule.js +149 -0
  143. package/lib/prefetch/StartupAssetHintRuntimeModule.js +210 -0
  144. package/lib/prefetch/parseResourceHintOptions.js +103 -0
  145. package/lib/rules/RuleSetCompiler.js +114 -0
  146. package/lib/runtime/AsyncModuleGeneratorRuntimeModule.js +56 -0
  147. package/lib/runtime/AsyncModuleRuntimeModule.js +24 -8
  148. package/lib/runtime/AutoPublicPathRuntimeModule.js +7 -1
  149. package/lib/runtime/CommonJsWrapRuntimeModule.js +37 -0
  150. package/lib/runtime/GetWorkletBootstrapRuntimeModule.js +59 -0
  151. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +204 -8
  152. package/lib/runtime/SetAnonymousDefaultNameRuntimeModule.js +4 -1
  153. package/lib/schemes/HttpUriPlugin.js +40 -1
  154. package/lib/schemes/VirtualUrlPlugin.js +1 -2
  155. package/lib/serialization/BinaryMiddleware.js +270 -938
  156. package/lib/serialization/FileMiddleware.js +29 -3
  157. package/lib/stats/DefaultStatsFactoryPlugin.js +229 -194
  158. package/lib/stats/DefaultStatsPresetPlugin.js +2 -0
  159. package/lib/stats/DefaultStatsPrinterPlugin.js +36 -168
  160. package/lib/stats/StatsFactory.js +46 -17
  161. package/lib/url/URLParserPlugin.js +66 -13
  162. package/lib/util/AsyncQueue.js +122 -72
  163. package/lib/util/SetHelpers.js +1 -1
  164. package/lib/util/StackedMap.js +122 -48
  165. package/lib/util/binarySearchBounds.js +2 -2
  166. package/lib/util/concatenate.js +40 -14
  167. package/lib/util/createHooksRegistry.js +13 -5
  168. package/lib/util/dataURL.js +2 -2
  169. package/lib/util/deterministicGrouping.js +7 -5
  170. package/lib/util/formatSize.js +6 -2
  171. package/lib/util/globUtils.js +710 -0
  172. package/lib/util/identifier.js +23 -6
  173. package/lib/util/implicitTypeLoaderFallback.js +62 -0
  174. package/lib/util/internalSerializables.js +88 -71
  175. package/lib/util/magicComment.js +121 -25
  176. package/lib/util/numberHash.js +2 -2
  177. package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +24 -18
  178. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +33 -22
  179. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +79 -16
  180. package/lib/web/FetchCompileAsyncWasmPlugin.js +19 -0
  181. package/lib/web/FetchCompileWasmPlugin.js +14 -0
  182. package/lib/web/JsonpChunkLoadingRuntimeModule.js +2 -0
  183. package/lib/webpack.js +65 -0
  184. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +3 -0
  185. package/module.d.ts +21 -0
  186. package/package.json +12 -11
  187. package/schemas/WebpackOptions.check.js +1 -1
  188. package/schemas/WebpackOptions.json +759 -36
  189. package/schemas/plugins/HtmlParserOptions.check.js +1 -1
  190. package/schemas/plugins/ProgressPlugin.check.js +1 -1
  191. package/schemas/plugins/ProgressPlugin.json +17 -1
  192. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  193. package/schemas/plugins/container/ContainerReferencePlugin.json +1 -0
  194. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  195. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  196. package/schemas/plugins/container/ModuleFederationPlugin.json +1 -0
  197. package/schemas/plugins/css/CssAutoOrModuleParserOptions.check.js +1 -1
  198. package/schemas/plugins/css/CssModuleParserOptions.check.js +1 -1
  199. package/schemas/plugins/css/CssParserOptions.check.js +1 -1
  200. package/types.d.ts +1212 -99
@@ -6,6 +6,16 @@
6
6
  "use strict";
7
7
 
8
8
  const InitFragment = require("./InitFragment");
9
+ const {
10
+ JAVASCRIPT_TYPE,
11
+ RUNTIME_TYPE
12
+ } = require("./ModuleSourceTypeConstants");
13
+ const {
14
+ WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE,
15
+ WEBPACK_MODULE_TYPE_FALLBACK,
16
+ WEBPACK_MODULE_TYPE_PROVIDE,
17
+ WEBPACK_MODULE_TYPE_REMOTE
18
+ } = require("./ModuleTypeConstants");
9
19
  const RuntimeGlobals = require("./RuntimeGlobals");
10
20
  const Template = require("./Template");
11
21
  const {
@@ -14,11 +24,14 @@ const {
14
24
  const { ImportPhaseUtils } = require("./dependencies/ImportPhase");
15
25
  const { InlinedUsedName } = require("./optimize/InlineExports");
16
26
  const {
27
+ getDeferredCycleModuleIds,
28
+ getDeferredCycleModules,
17
29
  getMakeDeferredNamespaceModeFromExportsType,
18
30
  getOptimizedDeferredModule
19
31
  } = require("./runtime/MakeDeferredNamespaceObjectRuntime");
20
32
  const { equals } = require("./util/ArrayHelpers");
21
33
  const compileBooleanMatcher = require("./util/compileBooleanMatcher");
34
+ const { getUndoPath, toJsStringLiteral } = require("./util/identifier");
22
35
  const memoize = require("./util/memoize");
23
36
  const { propertyAccess, propertyName } = require("./util/property");
24
37
  const { forEachRuntime, subtractRuntime } = require("./util/runtime");
@@ -29,6 +42,28 @@ const getHarmonyImportDependency = memoize(() =>
29
42
  const getImportDependency = memoize(() =>
30
43
  require("./dependencies/ImportDependency")
31
44
  );
45
+ const getJavascriptModulesPlugin = memoize(() =>
46
+ require("./javascript/JavascriptModulesPlugin")
47
+ );
48
+ const getModuleHotAcceptDependency = memoize(() =>
49
+ require("./dependencies/ModuleHotAcceptDependency")
50
+ );
51
+ const getAPIPlugin = memoize(() => require("./APIPlugin"));
52
+
53
+ // Module-federation module types whose chunks load through the federation runtime.
54
+ /** @type {Set<string>} */
55
+ const FEDERATION_MODULE_TYPES = new Set([
56
+ WEBPACK_MODULE_TYPE_REMOTE,
57
+ WEBPACK_MODULE_TYPE_PROVIDE,
58
+ WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE,
59
+ WEBPACK_MODULE_TYPE_FALLBACK
60
+ ]);
61
+
62
+ // Any `[hash]`/`[fullhash]`/`[chunkhash]`/`[contenthash]` token, incl. a `:<length>`
63
+ // or `:<digest>[:<length>]` suffix (e.g. `[contenthash:base64:8]`). Its value is only
64
+ // resolved after code generation, so a filename using one can't be an inline literal.
65
+ const HASH_IN_FILENAME = /\[(?:full|chunk|content)?hash(?::[^\]]+)?\]/;
66
+ const HASH_IN_FILENAME_GLOBAL = /\[(?:full|chunk|content)?hash(?::[^\]]+)?\]/g;
32
67
 
33
68
  /** @typedef {import("./config/defaults").OutputNormalizedWithDefaults} OutputOptions */
34
69
  /** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock */
@@ -192,6 +227,10 @@ class RuntimeTemplate {
192
227
  return this.outputOptions.environment.asyncFunction;
193
228
  }
194
229
 
230
+ supportsGenerator() {
231
+ return this.outputOptions.environment.generator;
232
+ }
233
+
195
234
  supportsOptionalChaining() {
196
235
  return this.outputOptions.environment.optionalChaining;
197
236
  }
@@ -228,6 +267,24 @@ class RuntimeTemplate {
228
267
  return this.outputOptions.environment.module;
229
268
  }
230
269
 
270
+ supportsModulePreload() {
271
+ return this.outputOptions.environment.modulePreload;
272
+ }
273
+
274
+ supportsAnalyzableEsm() {
275
+ // `eval` devtool wraps each module in `eval(...)`, where `import.meta` is a
276
+ // syntax error, so the literal `new URL(…, import.meta.url)` form can't be used.
277
+ const { devtool } = this.compilation.options;
278
+ return (
279
+ this.isModule() &&
280
+ this.supportsEcmaScriptModuleSyntax() &&
281
+ !(typeof devtool === "string" && devtool.includes("eval")) &&
282
+ // A runtime `__webpack_public_path__` override can't be reflected in a
283
+ // baked literal, so keep the runtime form that reads `__webpack_require__.p`.
284
+ !getAPIPlugin().usesRuntimePublicPathOverride(this.compilation)
285
+ );
286
+ }
287
+
231
288
  supportTemplateLiteral() {
232
289
  return this.outputOptions.environment.templateLiteral;
233
290
  }
@@ -805,6 +862,7 @@ class RuntimeTemplate {
805
862
  * @param {boolean=} options.weak if the dependency is weak (will create a nice error message)
806
863
  * @param {Dependency} options.dependency dependency
807
864
  * @param {RuntimeRequirements} options.runtimeRequirements if set, will be filled with runtime requirements
865
+ * @param {Module=} options.originModule the module the `import()` is emitted into
808
866
  * @returns {string} the promise expression
809
867
  */
810
868
  moduleNamespacePromise({
@@ -816,7 +874,8 @@ class RuntimeTemplate {
816
874
  strict,
817
875
  weak,
818
876
  dependency,
819
- runtimeRequirements
877
+ runtimeRequirements,
878
+ originModule
820
879
  }) {
821
880
  if (!module) {
822
881
  return this.missingModulePromise({
@@ -846,7 +905,8 @@ class RuntimeTemplate {
846
905
  chunkGraph,
847
906
  block,
848
907
  message,
849
- runtimeRequirements
908
+ runtimeRequirements,
909
+ originModule
850
910
  });
851
911
 
852
912
  /** @type {string} */
@@ -1123,6 +1183,10 @@ class RuntimeTemplate {
1123
1183
  moduleId,
1124
1184
  exportsType,
1125
1185
  Array.from(outgoingAsyncModules, (mod) => chunkGraph.getModuleId(mod)),
1186
+ getDeferredCycleModuleIds(
1187
+ getDeferredCycleModules(moduleGraph, module),
1188
+ (mod) => chunkGraph.getModuleId(mod)
1189
+ ),
1126
1190
  runtimeRequirements
1127
1191
  )};\n`;
1128
1192
 
@@ -1218,7 +1282,9 @@ class RuntimeTemplate {
1218
1282
  "Can't inline the exports of defer imported module"
1219
1283
  );
1220
1284
  }
1221
- const access = `${importVar}.a${propertyAccess(Array.isArray(used) ? used : [used])}`;
1285
+ const access = `${importVar}.a${propertyAccess(
1286
+ Array.isArray(used) ? used : [used]
1287
+ )}`;
1222
1288
  if (isCall || asiSafe === undefined) {
1223
1289
  return access;
1224
1290
  }
@@ -1446,9 +1512,16 @@ class RuntimeTemplate {
1446
1512
  * @param {string} options.message the message
1447
1513
  * @param {ChunkGraph} options.chunkGraph the chunk graph
1448
1514
  * @param {RuntimeRequirements} options.runtimeRequirements if set, will be filled with runtime requirements
1515
+ * @param {Module=} options.originModule the module the `import()` is emitted into
1449
1516
  * @returns {string} expression
1450
1517
  */
1451
- blockPromise({ block, message, chunkGraph, runtimeRequirements }) {
1518
+ blockPromise({
1519
+ block,
1520
+ message,
1521
+ chunkGraph,
1522
+ runtimeRequirements,
1523
+ originModule
1524
+ }) {
1452
1525
  if (!block) {
1453
1526
  const comment = this.comment({
1454
1527
  message
@@ -1469,12 +1542,25 @@ class RuntimeTemplate {
1469
1542
  message,
1470
1543
  chunkName: block.chunkName
1471
1544
  });
1545
+ // A `fetchPriority` hint rides on the runtime `ensureChunk(id, priority)` call;
1546
+ // the analyzable literal `import()` can't carry it, so keep the runtime form.
1547
+ const fetchPriority = chunkGroup.options.fetchPriority;
1472
1548
  if (chunks.length === 1) {
1549
+ const analyzable = fetchPriority
1550
+ ? null
1551
+ : this._analyzableChunkImport(
1552
+ chunks[0],
1553
+ comment,
1554
+ runtimeRequirements,
1555
+ originModule,
1556
+ chunkGraph
1557
+ );
1558
+ if (analyzable !== null) {
1559
+ return analyzable;
1560
+ }
1473
1561
  const chunkId = JSON.stringify(chunks[0].id);
1474
1562
  runtimeRequirements.add(RuntimeGlobals.ensureChunk);
1475
1563
 
1476
- const fetchPriority = chunkGroup.options.fetchPriority;
1477
-
1478
1564
  if (fetchPriority) {
1479
1565
  runtimeRequirements.add(RuntimeGlobals.hasFetchPriority);
1480
1566
  }
@@ -1483,30 +1569,232 @@ class RuntimeTemplate {
1483
1569
  fetchPriority ? `, ${JSON.stringify(fetchPriority)}` : ""
1484
1570
  })`;
1485
1571
  } else if (chunks.length > 0) {
1486
- runtimeRequirements.add(RuntimeGlobals.ensureChunk);
1487
-
1488
- const fetchPriority = chunkGroup.options.fetchPriority;
1489
-
1490
1572
  if (fetchPriority) {
1491
1573
  runtimeRequirements.add(RuntimeGlobals.hasFetchPriority);
1492
1574
  }
1493
1575
 
1576
+ let needEnsureChunk = false;
1494
1577
  /**
1495
- * Returns require chunk id code.
1578
+ * Analyzable `import()` for a solely-owned JS chunk, else runtime ensureChunk.
1496
1579
  * @param {Chunk} chunk chunk
1497
1580
  * @returns {string} require chunk id code
1498
1581
  */
1499
- const requireChunkId = (chunk) =>
1500
- `${RuntimeGlobals.ensureChunk}(${JSON.stringify(chunk.id)}${
1582
+ const requireChunkId = (chunk) => {
1583
+ const analyzable = fetchPriority
1584
+ ? null
1585
+ : this._analyzableChunkImport(
1586
+ chunk,
1587
+ "",
1588
+ runtimeRequirements,
1589
+ originModule,
1590
+ chunkGraph
1591
+ );
1592
+ if (analyzable !== null) return analyzable;
1593
+ needEnsureChunk = true;
1594
+ return `${RuntimeGlobals.ensureChunk}(${JSON.stringify(chunk.id)}${
1501
1595
  fetchPriority ? `, ${JSON.stringify(fetchPriority)}` : ""
1502
1596
  })`;
1503
- return `Promise.all(${comment.trim()}[${chunks
1504
- .map(requireChunkId)
1505
- .join(", ")}])`;
1597
+ };
1598
+ const items = chunks.map(requireChunkId);
1599
+ if (needEnsureChunk) {
1600
+ runtimeRequirements.add(RuntimeGlobals.ensureChunk);
1601
+ }
1602
+ return `Promise.all(${comment.trim()}[${items.join(", ")}])`;
1506
1603
  }
1507
1604
  return `Promise.resolve(${comment.trim()})`;
1508
1605
  }
1509
1606
 
1607
+ /**
1608
+ * For ESM module output, load a single statically-named chunk through the
1609
+ * `analyzableChunkImport` helper — a literal `import("./chunk.js")` other bundlers
1610
+ * and webpack itself can follow, wrapped to keep `ensureChunk` timing and deduplication.
1611
+ * Returns `null` to fall back to the runtime `ensureChunk` form.
1612
+ * @param {Chunk} chunk the chunk to load
1613
+ * @param {string} comment leading comment (chunk name / message)
1614
+ * @param {RuntimeRequirements} runtimeRequirements runtime requirements
1615
+ * @param {Module=} originModule the module the `import()` is emitted into
1616
+ * @param {ChunkGraph=} chunkGraph the chunk graph
1617
+ * @returns {string | null} the import expression, or `null`
1618
+ */
1619
+ _analyzableChunkImport(
1620
+ chunk,
1621
+ comment,
1622
+ runtimeRequirements,
1623
+ originModule,
1624
+ chunkGraph
1625
+ ) {
1626
+ const { outputOptions } = this;
1627
+ if (
1628
+ !outputOptions.module ||
1629
+ outputOptions.chunkFormat !== "module" ||
1630
+ outputOptions.importFunctionName !== "import" ||
1631
+ chunk.id === null ||
1632
+ !originModule ||
1633
+ !chunkGraph
1634
+ ) {
1635
+ return null;
1636
+ }
1637
+ // HMR wraps `ensureChunk` (`.e`) to track in-flight loads and relies on it being
1638
+ // present in the runtime; the analyzable `import()` (`.ei`) replaces `.e` and would
1639
+ // leave a lazy-compilation proxy's own `.e` call undefined, so keep the runtime form.
1640
+ // A runtime `__webpack_public_path__` override likewise can't reach a baked literal.
1641
+ if (
1642
+ this.compilation.dependencyFactories.has(
1643
+ getModuleHotAcceptDependency()
1644
+ ) ||
1645
+ getAPIPlugin().usesRuntimePublicPathOverride(this.compilation)
1646
+ ) {
1647
+ return null;
1648
+ }
1649
+ // A worker entry loads its own chunks through the worker runtime; keep that path.
1650
+ for (const originChunk of chunkGraph.getModuleChunksIterable(
1651
+ originModule
1652
+ )) {
1653
+ const entryOptions = originChunk.getEntryOptions();
1654
+ if (entryOptions && entryOptions.worker) {
1655
+ return null;
1656
+ }
1657
+ }
1658
+ // Only a chunk that is loaded solely through this `import()` and holds pure JS:
1659
+ // a shared chunk (splitChunks / module federation) or one with css/wasm/other
1660
+ // assets needs the runtime's deduplication and per-type loaders, so keep it.
1661
+ if (chunk.getNumberOfGroups() !== 1) {
1662
+ return null;
1663
+ }
1664
+ // Prefetch/preload children (incl. CSS-only preload) are injected by the runtime
1665
+ // `.f` handlers when the chunk loads, which the analyzable `import()` bypasses —
1666
+ // keep the runtime form for them.
1667
+ if (
1668
+ chunk.hasChildByOrder(chunkGraph, "prefetch", true) ||
1669
+ chunk.hasChildByOrder(chunkGraph, "preload", true) ||
1670
+ chunk.hasChildByOrder(chunkGraph, "cssPreload", true)
1671
+ ) {
1672
+ return null;
1673
+ }
1674
+ for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
1675
+ // Module federation (remote/shared/provide) loads through its own runtime.
1676
+ if (FEDERATION_MODULE_TYPES.has(module.type)) {
1677
+ return null;
1678
+ }
1679
+ for (const type of chunkGraph.getModuleSourceTypes(module)) {
1680
+ if (type !== JAVASCRIPT_TYPE && type !== RUNTIME_TYPE) {
1681
+ return null;
1682
+ }
1683
+ }
1684
+ }
1685
+ // Relative to the consuming chunk (`import.meta.url`) for `auto`, else an
1686
+ // absolute publicPath prefix.
1687
+ const specifier = this._getAnalyzableChunkSpecifier(
1688
+ undefined,
1689
+ chunk,
1690
+ originModule,
1691
+ chunkGraph
1692
+ );
1693
+ // `import()` needs a resolvable specifier — relative (`./`, `../`), absolute (`/`)
1694
+ // or a URL scheme. A bare one (empty/relative publicPath) is treated as a package,
1695
+ // so keep the runtime form. (`new URL(...)` callers accept bare, resolving vs base.)
1696
+ if (
1697
+ specifier === null ||
1698
+ !/^"(?:\.{0,2}\/|[a-zA-Z][\w+.-]*:)/.test(specifier)
1699
+ ) {
1700
+ return null;
1701
+ }
1702
+ runtimeRequirements.add(RuntimeGlobals.analyzableChunkImport);
1703
+ // Drop-in for `ensureChunk(id)`: the literal `import()` can be statically
1704
+ // followed, the helper keeps webpack's install timing and deduplication.
1705
+ return `${RuntimeGlobals.analyzableChunkImport}(${JSON.stringify(
1706
+ chunk.id
1707
+ )}, () => import(${comment}${specifier}))`;
1708
+ }
1709
+
1710
+ /**
1711
+ * Computes the `../`-path from the consuming module's chunk(s) back to the output
1712
+ * root, so a chunk or asset can be referenced relative to `import.meta.url`. Returns
1713
+ * `null` when the module lives in chunks of different depths (no single path works).
1714
+ * @param {Module} module the consuming module
1715
+ * @param {ChunkGraph} chunkGraph the chunk graph
1716
+ * @returns {string | null} relative undo path, or `null` when ambiguous
1717
+ */
1718
+ _getModuleUndoPath(module, chunkGraph) {
1719
+ const { compilation } = this;
1720
+ const { outputOptions } = compilation;
1721
+ const outputPath = /** @type {string} */ (outputOptions.path);
1722
+ /** @type {string | null} */
1723
+ let result = null;
1724
+ let found = false;
1725
+ for (const chunk of chunkGraph.getModuleChunksIterable(module)) {
1726
+ const template = getJavascriptModulesPlugin().getChunkFilenameTemplate(
1727
+ chunk,
1728
+ outputOptions
1729
+ );
1730
+ const chunkName = compilation.getPath(
1731
+ // Hashes aren't known during code generation and only sit in the basename
1732
+ // (never a directory), so neutralize them — only the `../` depth matters.
1733
+ typeof template === "string"
1734
+ ? template.replace(HASH_IN_FILENAME_GLOBAL, "x")
1735
+ : template,
1736
+ { chunk, contentHashType: JAVASCRIPT_TYPE }
1737
+ );
1738
+ const undo = getUndoPath(chunkName, outputPath, true);
1739
+ if (!found) {
1740
+ result = undo;
1741
+ found = true;
1742
+ } else if (result !== undo) {
1743
+ return null;
1744
+ }
1745
+ }
1746
+ return found ? result : null;
1747
+ }
1748
+
1749
+ /**
1750
+ * Static literal specifier (already quoted) for a `new URL(<here>, import.meta.url)`
1751
+ * or `import(<here>)` pointing at `chunk`'s JS file, or `null` when it can't be known
1752
+ * statically — a content hash in the filename, or a dynamic/templated publicPath.
1753
+ * @param {string | undefined} overridePublicPath per-dependency public path (wins over `output.publicPath`)
1754
+ * @param {Chunk} chunk the chunk to reference
1755
+ * @param {Module} consumingModule the module the reference is emitted into
1756
+ * @param {ChunkGraph} chunkGraph the chunk graph
1757
+ * @returns {string | null} a JS string literal, or `null` to fall back to the runtime form
1758
+ */
1759
+ _getAnalyzableChunkSpecifier(
1760
+ overridePublicPath,
1761
+ chunk,
1762
+ consumingModule,
1763
+ chunkGraph
1764
+ ) {
1765
+ const { compilation } = this;
1766
+ const { outputOptions } = compilation;
1767
+ const filenameTemplate =
1768
+ getJavascriptModulesPlugin().getChunkFilenameTemplate(
1769
+ chunk,
1770
+ outputOptions
1771
+ );
1772
+ if (
1773
+ typeof filenameTemplate !== "string" ||
1774
+ HASH_IN_FILENAME.test(filenameTemplate)
1775
+ ) {
1776
+ return null;
1777
+ }
1778
+ const filename = compilation.getPath(filenameTemplate, {
1779
+ chunk,
1780
+ contentHashType: JAVASCRIPT_TYPE
1781
+ });
1782
+ if (overridePublicPath) {
1783
+ return overridePublicPath.includes("[")
1784
+ ? null
1785
+ : toJsStringLiteral(overridePublicPath + filename);
1786
+ }
1787
+ const { publicPath } = outputOptions;
1788
+ if (publicPath === "auto") {
1789
+ const undo = this._getModuleUndoPath(consumingModule, chunkGraph);
1790
+ return undo === null ? null : toJsStringLiteral(undo + filename);
1791
+ }
1792
+ if (typeof publicPath === "string" && !publicPath.includes("[")) {
1793
+ return toJsStringLiteral(publicPath + filename);
1794
+ }
1795
+ return null;
1796
+ }
1797
+
1510
1798
  /**
1511
1799
  * Async module factory.
1512
1800
  * @param {object} options options
package/lib/Template.js CHANGED
@@ -46,6 +46,22 @@ const COMMENT_END_REGEX = /\*\//g;
46
46
  const PATH_NAME_NORMALIZE_REPLACE_REGEX = /[^a-z0-9_!§$()=\-^°]+/gi;
47
47
  const MATCH_PADDED_HYPHENS_REPLACE_REGEX = /^-|-$/g;
48
48
 
49
+ /**
50
+ * Decimal digit count of a non-negative integer, without allocating a string.
51
+ * @param {number} n non-negative integer
52
+ * @returns {number} number of decimal digits
53
+ */
54
+ const numberLength = (n) => {
55
+ if (n < 10) return 1;
56
+ if (n < 100) return 2;
57
+ if (n < 1000) return 3;
58
+ if (n < 10000) return 4;
59
+ if (n < 100000) return 5;
60
+ if (n < 1000000) return 6;
61
+ if (n < 10000000) return 7;
62
+ return String(n).length;
63
+ };
64
+
49
65
  /**
50
66
  * Defines the render manifest options type used by this module.
51
67
  * @typedef {object} RenderManifestOptions
@@ -296,11 +312,15 @@ class Template {
296
312
  // start with -1 because the first module needs no comma
297
313
  let objectOverhead = -1;
298
314
  for (const module of modules) {
299
- // module id + colon + comma
300
- objectOverhead += `${module.id}`.length + 2;
315
+ // module id digits + colon + comma; ids are non-negative integers here
316
+ // (non-number ids already returned false above), so count digits
317
+ // arithmetically instead of allocating a string per module.
318
+ const id = /** @type {number} */ (module.id);
319
+ objectOverhead += numberLength(id) + 2;
301
320
  }
302
321
  // number of commas, or when starting non-zero the length of Array(minId).concat()
303
- const arrayOverhead = minId === 0 ? maxId : 16 + `${minId}`.length + maxId;
322
+ const arrayOverhead =
323
+ minId === 0 ? maxId : 16 + numberLength(minId) + maxId;
304
324
  return arrayOverhead < objectOverhead ? [minId, maxId] : false;
305
325
  }
306
326
 
@@ -52,7 +52,7 @@ class UseStrictPlugin {
52
52
  "",
53
53
  /** @type {Range} */ (firstNode.range)
54
54
  );
55
- dep.loc = /** @type {DependencyLocation} */ (firstNode.loc);
55
+ dep.loc = parser.getLocation(firstNode);
56
56
  parser.state.module.addPresentationalDependency(dep);
57
57
  /** @type {BuildInfo} */
58
58
  (parser.state.module.buildInfo).strict = true;
@@ -67,7 +67,7 @@ class WebpackIsIncludedPlugin {
67
67
  /** @type {string} */ (request.string),
68
68
  /** @type {Range} */ (expr.range)
69
69
  );
70
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
70
+ dep.loc = parser.getLocation(expr);
71
71
  parser.state.module.addDependency(dep);
72
72
  return true;
73
73
  });
@@ -57,14 +57,14 @@ const SystemPlugin = require("./dependencies/SystemPlugin");
57
57
 
58
58
  const URLPlugin = require("./dependencies/URLPlugin");
59
59
 
60
- const WorkerPlugin = require("./dependencies/WorkerPlugin");
60
+ const WorkerAndWorkletPlugin = require("./dependencies/WorkerAndWorkletPlugin");
61
61
 
62
62
  const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin");
63
- const JavascriptParser = require("./javascript/JavascriptParser");
64
63
 
65
64
  const JsonModulesPlugin = require("./json/JsonModulesPlugin");
66
65
 
67
66
  const ChunkPrefetchPreloadPlugin = require("./prefetch/ChunkPrefetchPreloadPlugin");
67
+ const ResourceHintPlugin = require("./prefetch/ResourceHintPlugin");
68
68
 
69
69
  const DataUriPlugin = require("./schemes/DataUriPlugin");
70
70
  const FileUriPlugin = require("./schemes/FileUriPlugin");
@@ -241,6 +241,7 @@ class WebpackOptionsApply extends OptionsApply {
241
241
  }
242
242
 
243
243
  new ChunkPrefetchPreloadPlugin().apply(compiler);
244
+ new ResourceHintPlugin(options.output.resourceHints).apply(compiler);
244
245
 
245
246
  if (typeof options.output.chunkFormat === "string") {
246
247
  switch (options.output.chunkFormat) {
@@ -529,20 +530,6 @@ class WebpackOptionsApply extends OptionsApply {
529
530
  new HttpUriPlugin(httpOptions).apply(compiler);
530
531
  }
531
532
 
532
- if (
533
- !(
534
- /** @type {typeof JavascriptParser & { __importPhasesExtended?: true }} */
535
- (JavascriptParser).__importPhasesExtended
536
- ) &&
537
- (options.experiments.deferImport || options.experiments.sourceImport)
538
- ) {
539
- const importPhases = require("acorn-import-phases");
540
-
541
- JavascriptParser.extend(importPhases({ source: true, defer: true }));
542
- /** @type {typeof JavascriptParser & { __importPhasesExtended?: true }} */
543
- (JavascriptParser).__importPhasesExtended = true;
544
- }
545
-
546
533
  new EntryOptionPlugin().apply(compiler);
547
534
  compiler.hooks.entryOption.call(options.context, options.entry);
548
535
 
@@ -584,11 +571,12 @@ class WebpackOptionsApply extends OptionsApply {
584
571
  new SystemPlugin().apply(compiler);
585
572
  new ImportMetaPlugin().apply(compiler);
586
573
  new URLPlugin().apply(compiler);
587
- new WorkerPlugin(
574
+ new WorkerAndWorkletPlugin(
588
575
  options.output.workerChunkLoading,
589
576
  options.output.workerWasmLoading,
590
577
  options.output.module,
591
- options.output.workerPublicPath
578
+ options.output.workerPublicPath,
579
+ options.experiments.futureDefaults
592
580
  ).apply(compiler);
593
581
 
594
582
  new DefaultStatsFactoryPlugin().apply(compiler);
@@ -805,10 +793,27 @@ class WebpackOptionsApply extends OptionsApply {
805
793
  const DefinePlugin = require("./DefinePlugin");
806
794
 
807
795
  const defValue = JSON.stringify(options.optimization.nodeEnv);
796
+ const development = options.mode === "development";
797
+ // SSR = server-only build (node, not browser); a universal (node+browser) target is null here, so not SSR.
798
+ const ssr =
799
+ compiler.platform.node === true && compiler.platform.browser !== true;
800
+ const { publicPath } = options.output;
801
+ // Vite-compatible base URL; fall back to "/" for runtime ("auto") or empty publicPath.
802
+ const baseUrl =
803
+ typeof publicPath === "string" &&
804
+ publicPath !== "auto" &&
805
+ publicPath !== ""
806
+ ? publicPath
807
+ : "/";
808
808
 
809
809
  new DefinePlugin({
810
810
  "process.env.NODE_ENV": defValue,
811
- "import.meta.env.NODE_ENV": defValue
811
+ "import.meta.env.NODE_ENV": defValue,
812
+ "import.meta.env.MODE": defValue,
813
+ "import.meta.env.DEV": JSON.stringify(development),
814
+ "import.meta.env.PROD": JSON.stringify(!development),
815
+ "import.meta.env.SSR": JSON.stringify(ssr),
816
+ "import.meta.env.BASE_URL": JSON.stringify(baseUrl)
812
817
  }).apply(compiler);
813
818
  }
814
819
  if (options.optimization.minimize) {