webpack 5.110.2 → 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 (226) hide show
  1. package/README.md +5 -2
  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/ChunkGraph.js +20 -18
  7. package/lib/CircularModulesPlugin.js +157 -55
  8. package/lib/CleanPlugin.js +2 -2
  9. package/lib/Compilation.js +321 -303
  10. package/lib/Compiler.js +209 -46
  11. package/lib/ConcatenationScope.js +25 -35
  12. package/lib/ContextModule.js +17 -81
  13. package/lib/ContextModuleFactory.js +1 -1
  14. package/lib/CopyPlugin.js +1054 -0
  15. package/lib/DefinePlugin.js +24 -8
  16. package/lib/DotenvPlugin.js +41 -13
  17. package/lib/ExternalModule.js +41 -14
  18. package/lib/FileSystemInfo.js +17 -14
  19. package/lib/FlagDependencyExportsPlugin.js +45 -21
  20. package/lib/FlagDependencyUsagePlugin.js +8 -2
  21. package/lib/HotModuleReplacementPlugin.js +53 -7
  22. package/lib/JavascriptMetaInfoPlugin.js +5 -3
  23. package/lib/MainTemplate.js +5 -1
  24. package/lib/Module.js +16 -7
  25. package/lib/MultiCompiler.js +1 -1
  26. package/lib/MultiWatching.js +1 -1
  27. package/lib/NormalModule.js +58 -32
  28. package/lib/NormalModuleFactory.js +1 -1
  29. package/lib/RuntimeGlobals.js +21 -7
  30. package/lib/RuntimeModule.js +28 -12
  31. package/lib/RuntimePlugin.js +33 -3
  32. package/lib/RuntimeTemplate.js +794 -477
  33. package/lib/SourceMapDevToolPlugin.js +1 -1
  34. package/lib/Watching.js +9 -0
  35. package/lib/WebpackOptionsApply.js +84 -91
  36. package/lib/asset/AssetGenerator.js +25 -8
  37. package/lib/asset/AssetModule.js +3 -0
  38. package/lib/asset/WebManifestParser.js +7 -5
  39. package/lib/async-modules/AsyncModuleHelpers.js +10 -4
  40. package/lib/cache/AddBuildDependenciesPlugin.js +33 -4
  41. package/lib/cache/IdleFileCachePlugin.js +2 -2
  42. package/lib/cache/PackFileCacheStrategy.js +14 -1
  43. package/lib/config/browserslistTargetHandler.js +19 -0
  44. package/lib/config/defaults.js +110 -64
  45. package/lib/config/normalization.js +100 -20
  46. package/lib/config/target.js +10 -0
  47. package/lib/container/ContainerReferencePlugin.js +6 -0
  48. package/lib/container/RemoteRuntimeModule.js +9 -0
  49. package/lib/container/declaredRemotes.js +39 -0
  50. package/lib/css/CssGenerator.js +8 -0
  51. package/lib/css/CssInjectStyleRuntimeModule.js +9 -0
  52. package/lib/css/CssLoadingRuntimeModule.js +94 -36
  53. package/lib/css/CssModule.js +1 -1
  54. package/lib/css/CssModulesPlugin.js +7 -6
  55. package/lib/css/CssParser.js +144 -11
  56. package/lib/css/CssServerStylesRuntimeModule.js +9 -0
  57. package/lib/css/cssMinify.js +11 -3
  58. package/lib/css/data.js +2814 -678
  59. package/lib/css/syntax.js +4082 -248
  60. package/lib/debug/ProfilingPlugin.js +4 -0
  61. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +6 -3
  62. package/lib/dependencies/AMDRuntimeModules.js +18 -0
  63. package/lib/dependencies/CommonJsExportRequireDependency.js +3 -1
  64. package/lib/dependencies/CommonJsExportsParserPlugin.js +12 -13
  65. package/lib/dependencies/CommonJsImportsParserPlugin.js +1 -0
  66. package/lib/dependencies/CommonJsPlugin.js +19 -3
  67. package/lib/dependencies/CommonJsRequireDependency.js +32 -9
  68. package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +20 -7
  69. package/lib/dependencies/CssIcssExportDependency.js +7 -1
  70. package/lib/dependencies/HarmonyCompatibilityDependency.js +58 -4
  71. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +8 -3
  72. package/lib/dependencies/HarmonyExportExpressionDependency.js +44 -29
  73. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +171 -32
  74. package/lib/dependencies/HarmonyExportInitFragment.js +99 -19
  75. package/lib/dependencies/HarmonyExportSpecifierDependency.js +18 -30
  76. package/lib/dependencies/HarmonyImportBareSideEffectDependency.js +59 -0
  77. package/lib/dependencies/HarmonyImportDependency.js +99 -41
  78. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +20 -3
  79. package/lib/dependencies/HarmonyImportSpecifierDependency.js +24 -1
  80. package/lib/dependencies/HarmonyModulesPlugin.js +20 -0
  81. package/lib/dependencies/HtmlEntryDependency.js +62 -2
  82. package/lib/dependencies/ImportContextDependency.js +43 -3
  83. package/lib/dependencies/ImportDependency.js +8 -29
  84. package/lib/dependencies/ImportMetaMainDependency.js +104 -0
  85. package/lib/dependencies/ImportMetaPlugin.js +59 -15
  86. package/lib/dependencies/ImportParserPlugin.js +24 -14
  87. package/lib/dependencies/RequireHeaderDependency.js +20 -21
  88. package/lib/dependencies/SystemRuntimeModule.js +9 -0
  89. package/lib/dependencies/WorkerDependency.js +1 -2
  90. package/lib/dependencies/WorkletDependency.js +1 -2
  91. package/lib/dependencies/importOptionsCheck.js +47 -0
  92. package/lib/dll/DelegatedModule.js +18 -1
  93. package/lib/dll/DllReferencePlugin.js +11 -8
  94. package/lib/dll/LibManifestPlugin.js +1 -1
  95. package/lib/errors/AnalyzableBailoutsWarning.js +41 -0
  96. package/lib/errors/DotenvFileError.js +29 -0
  97. package/lib/errors/DuplicateModulesWarning.js +12 -7
  98. package/lib/errors/EmptyCopyPatternWarning.js +26 -0
  99. package/lib/errors/ExternalStarReexportError.js +44 -0
  100. package/lib/errors/ImportedBindingAssignmentError.js +30 -0
  101. package/lib/errors/MissingSourceMapsWarning.js +36 -0
  102. package/lib/errors/ModuleParseError.js +2 -1
  103. package/lib/errors/UnusedAssetsWarning.js +36 -0
  104. package/lib/errors/UnusedFederationWarning.js +35 -0
  105. package/lib/errors/UnusedModulesWarning.js +38 -0
  106. package/lib/esm/ExportWebpackRequireRuntimeModule.js +9 -0
  107. package/lib/esm/ModuleChunkFormatPlugin.js +28 -3
  108. package/lib/esm/ModuleChunkLoadingPlugin.js +30 -11
  109. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +92 -60
  110. package/lib/hmr/HotModuleReplacement.runtime.js +8 -2
  111. package/lib/hmr/HotModuleReplacementRuntimeModule.js +9 -0
  112. package/lib/html/HtmlGenerator.js +11 -5
  113. package/lib/html/HtmlModulesPlugin.js +360 -84
  114. package/lib/html/HtmlParser.js +13 -6
  115. package/lib/html/builtinEmbeddedRenderer.js +107 -0
  116. package/lib/html/data.js +121 -7
  117. package/lib/html/htmlMinify.js +84 -113
  118. package/lib/html/syntax.js +1067 -569
  119. package/lib/ids/HashedModuleIdsPlugin.js +2 -1
  120. package/lib/index.js +3 -0
  121. package/lib/javascript/JavascriptModule.js +1 -0
  122. package/lib/javascript/JavascriptModulesPlugin.js +52 -22
  123. package/lib/javascript/JavascriptParser.js +1255 -728
  124. package/lib/javascript/StartupHelpers.js +27 -3
  125. package/lib/javascript/data.js +172 -0
  126. package/lib/javascript/grammar.js +5546 -0
  127. package/lib/javascript/parser.js +1494 -0
  128. package/lib/javascript/regexp.js +1762 -0
  129. package/lib/javascript/regexpData.js +51 -0
  130. package/lib/javascript/syntax.js +8696 -5225
  131. package/lib/library/ModuleLibraryPlugin.js +116 -5
  132. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +22 -0
  133. package/lib/node/RequireChunkLoadingRuntimeModule.js +22 -0
  134. package/lib/optimize/ConcatenatedModule.js +133 -25
  135. package/lib/optimize/ConstExportsPlugin.js +50 -39
  136. package/lib/optimize/InlineExports.js +20 -123
  137. package/lib/optimize/MangleExportsPlugin.js +10 -0
  138. package/lib/optimize/ModuleConcatenationPlugin.js +24 -1
  139. package/lib/optimize/RealContentHashPlugin.js +68 -9
  140. package/lib/optimize/SideEffectsFlagPlugin.js +17 -9
  141. package/lib/performance/AnalyzableBailoutsPlugin.js +115 -0
  142. package/lib/performance/CacheEffectivenessPlugin.js +4 -3
  143. package/lib/performance/DuplicateModulesPlugin.js +57 -13
  144. package/lib/performance/EvalUsagePlugin.js +5 -2
  145. package/lib/performance/MissingSourceMapsPlugin.js +115 -0
  146. package/lib/performance/PureAnnotationsPlugin.js +6 -3
  147. package/lib/performance/TopLevelThisPlugin.js +5 -4
  148. package/lib/performance/UnusedAssetsPlugin.js +109 -0
  149. package/lib/performance/UnusedFederationPlugin.js +147 -0
  150. package/lib/performance/UnusedModulesPlugin.js +141 -0
  151. package/lib/performance/UnusedReexportsPlugin.js +1 -55
  152. package/lib/performance/isOnlyReexported.js +65 -0
  153. package/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js +25 -5
  154. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +2 -0
  155. package/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js +9 -0
  156. package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +9 -0
  157. package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +9 -0
  158. package/lib/prefetch/ResourceHintPlugin.js +7 -3
  159. package/lib/prefetch/ResourceHintRuntimeModule.js +9 -0
  160. package/lib/prefetch/StartupAssetHintRuntimeModule.js +9 -0
  161. package/lib/rules/RuleSetCompiler.js +211 -4
  162. package/lib/runtime/AsyncModuleRuntimeModule.js +105 -67
  163. package/lib/runtime/AutoPublicPathRuntimeModule.js +9 -0
  164. package/lib/runtime/BaseUriRuntimeModule.js +9 -0
  165. package/lib/runtime/ChunkNameRuntimeModule.js +9 -0
  166. package/lib/runtime/EnsureChunkRuntimeModule.js +35 -16
  167. package/lib/runtime/GetChunkFilenameRuntimeModule.js +9 -0
  168. package/lib/runtime/GetFullHashRuntimeModule.js +9 -0
  169. package/lib/runtime/GetMainFilenameRuntimeModule.js +9 -0
  170. package/lib/runtime/GetWorkletBootstrapRuntimeModule.js +9 -0
  171. package/lib/runtime/GlobalRuntimeModule.js +9 -0
  172. package/lib/runtime/HasOwnPropertyRuntimeModule.js +9 -0
  173. package/lib/runtime/HelperRuntimeModule.js +10 -0
  174. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +338 -217
  175. package/lib/runtime/NonceRuntimeModule.js +9 -0
  176. package/lib/runtime/OnChunksLoadedRuntimeModule.js +67 -20
  177. package/lib/runtime/PublicPathRuntimeModule.js +9 -0
  178. package/lib/runtime/RuntimeIdRuntimeModule.js +9 -0
  179. package/lib/runtime/SpecNamespaceObjectRuntimeModule.js +90 -0
  180. package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +9 -0
  181. package/lib/runtime/StartupEntrypointRuntimeModule.js +9 -0
  182. package/lib/runtime/SystemContextRuntimeModule.js +9 -0
  183. package/lib/runtime/ToBinaryRuntimeModule.js +9 -0
  184. package/lib/schemes/HttpUriPlugin.js +22 -5
  185. package/lib/serialization/FileMiddleware.js +15 -2
  186. package/lib/serialization/ObjectMiddleware.js +138 -106
  187. package/lib/sharing/ConsumeSharedPlugin.js +12 -0
  188. package/lib/sharing/ConsumeSharedRuntimeModule.js +11 -0
  189. package/lib/sharing/ShareRuntimeModule.js +9 -0
  190. package/lib/sharing/declaredShared.js +47 -0
  191. package/lib/stats/DefaultStatsFactoryPlugin.js +3 -1
  192. package/lib/stats/DefaultStatsPrinterPlugin.js +3 -0
  193. package/lib/util/ArrayQueue.js +3 -3
  194. package/lib/util/SourceProcessor.js +76 -69
  195. package/lib/util/URLAbsoluteSpecifier.js +3 -1
  196. package/lib/util/async.js +292 -0
  197. package/lib/util/buildDiagnostics.js +69 -0
  198. package/lib/util/conventions.js +5 -1
  199. package/lib/util/fs.js +27 -1
  200. package/lib/util/handlerKeys.js +40 -0
  201. package/lib/util/identifier.js +20 -0
  202. package/lib/util/internalSerializables.js +6 -0
  203. package/lib/util/registerExternalSerializer.js +6 -45
  204. package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +9 -0
  205. package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +9 -0
  206. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +9 -0
  207. package/lib/web/JsonpChunkLoadingRuntimeModule.js +36 -0
  208. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +19 -0
  209. package/package.json +22 -16
  210. package/schemas/WebpackOptions.check.js +1 -1
  211. package/schemas/WebpackOptions.json +388 -76
  212. package/schemas/plugins/LoaderOptionsPlugin.check.js +1 -1
  213. package/schemas/plugins/ManifestPlugin.check.js +1 -1
  214. package/schemas/plugins/SourceMapDevToolPlugin.check.js +1 -1
  215. package/schemas/plugins/asset/AssetGeneratorOptions.check.js +1 -1
  216. package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js +1 -1
  217. package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
  218. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  219. package/schemas/plugins/debug/ProfilingPlugin.check.js +1 -1
  220. package/schemas/plugins/dll/DllReferencePlugin.check.js +1 -1
  221. package/schemas/plugins/ids/HashedModuleIdsPlugin.check.js +1 -1
  222. package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
  223. package/types.d.ts +1440 -331
  224. package/lib/dependencies/ExportBindingInitFragment.js +0 -191
  225. package/lib/errors/EntrypointOverlapWarning.js +0 -45
  226. package/lib/performance/EntrypointOverlapPlugin.js +0 -122
@@ -14,9 +14,11 @@ const Template = require("../Template");
14
14
  const HarmonyExportExpressionDependency = require("../dependencies/HarmonyExportExpressionDependency");
15
15
  const HarmonyExportImportedSpecifierDependency = require("../dependencies/HarmonyExportImportedSpecifierDependency");
16
16
  const HarmonyExportSpecifierDependency = require("../dependencies/HarmonyExportSpecifierDependency");
17
+ const ExternalStarReexportError = require("../errors/ExternalStarReexportError");
17
18
  const JavascriptModulesPlugin = require("../javascript/JavascriptModulesPlugin");
18
19
  const ConcatenatedModule = require("../optimize/ConcatenatedModule");
19
20
  const { InlinedUsedName } = require("../optimize/InlineExports");
21
+ const { toJsStringLiteral } = require("../util/identifier");
20
22
  const {
21
23
  RESERVED_IDENTIFIER,
22
24
  SAFE_IDENTIFIER,
@@ -44,6 +46,7 @@ const AbstractLibraryPlugin = require("./AbstractLibraryPlugin");
44
46
  * ModuleRenderContext
45
47
  * } from "../javascript/JavascriptModulesPlugin"
46
48
  */
49
+ /** @import { ImportAttributes } from "../javascript/JavascriptParser" */
47
50
  /** @import { RuntimeSpec } from "../util/runtime" */
48
51
  /**
49
52
  * @import {
@@ -122,6 +125,18 @@ const definesOnlyNativeExports = (module, moduleGraph) => {
122
125
  const toExportName = (name) =>
123
126
  SAFE_IDENTIFIER.test(name) ? name : JSON.stringify(name);
124
127
 
128
+ /**
129
+ * Renders the import attributes of a reexport in the syntax the author wrote,
130
+ * since a legacy `assert` clause and a `with` clause are not interchangeable.
131
+ * @param {ImportAttributes | undefined} attributes the import attributes
132
+ * @returns {string} the attributes clause, empty when there are none
133
+ */
134
+ const toAttributesClause = (attributes) => {
135
+ if (!attributes) return "";
136
+ const { _isLegacyAssert: isLegacyAssert, ...values } = attributes;
137
+ return ` ${isLegacyAssert ? "assert" : "with"} ${JSON.stringify(values)}`;
138
+ };
139
+
125
140
  /**
126
141
  * Whether the export name can also be used as the declared binding name.
127
142
  * @param {string} name export name
@@ -367,6 +382,7 @@ class ModuleLibraryPlugin extends AbstractLibraryPlugin {
367
382
  }
368
383
  }
369
384
  }
385
+ this._checkStarReexportedExternals(module, compilation);
370
386
  moduleGraph.addExtraReason(module, "used as library export");
371
387
  let entries = libraryEntryModules.get(compilation);
372
388
  if (entries === undefined) {
@@ -376,6 +392,61 @@ class ModuleLibraryPlugin extends AbstractLibraryPlugin {
376
392
  entries.add(module);
377
393
  }
378
394
 
395
+ /**
396
+ * Reports every external the entry star-reexports whose request names a property
397
+ * path, which `export *` has no way to reference.
398
+ * @param {Module} module the library entry module
399
+ * @param {Compilation} compilation the compilation
400
+ * @returns {void}
401
+ */
402
+ _checkStarReexportedExternals(module, compilation) {
403
+ const { moduleGraph } = compilation;
404
+ /** @type {Set<Module>} */
405
+ const visitedReexportModules = new Set([module]);
406
+ /** @type {Module[]} */
407
+ const queue = [module];
408
+ /** @type {Set<ExternalModule>} */
409
+ const unsupportedExternals = new Set();
410
+
411
+ for (const current of queue) {
412
+ for (const connection of moduleGraph.getOutgoingConnections(current)) {
413
+ const dep = connection.dependency;
414
+
415
+ // Only handle star-reexport statement
416
+ if (
417
+ !(dep instanceof HarmonyExportImportedSpecifierDependency) ||
418
+ dep.name !== null
419
+ ) {
420
+ continue;
421
+ }
422
+ const importedModule = connection.resolvedModule;
423
+
424
+ // Only a module providing unknown exports keeps its reexport rendered
425
+ if (
426
+ moduleGraph.getExportsInfo(importedModule)._otherExportsInfo
427
+ .provided !== null
428
+ ) {
429
+ continue;
430
+ }
431
+ if (importedModule instanceof ExternalModule) {
432
+ const request = importedModule.getResolvedRequest();
433
+ if (Array.isArray(request) && request.length > 1) {
434
+ unsupportedExternals.add(importedModule);
435
+ }
436
+ } else if (!visitedReexportModules.has(importedModule)) {
437
+ visitedReexportModules.add(importedModule);
438
+ queue.push(importedModule);
439
+ }
440
+ }
441
+ }
442
+
443
+ for (const externalModule of unsupportedExternals) {
444
+ compilation.errors.push(
445
+ new ExternalStarReexportError(externalModule, module)
446
+ );
447
+ }
448
+ }
449
+
379
450
  /**
380
451
  * Returns preprocess as needed by overriding.
381
452
  * @param {LibraryOptions} library normalized library option
@@ -415,14 +486,17 @@ class ModuleLibraryPlugin extends AbstractLibraryPlugin {
415
486
  ) {
416
487
  const result = new ConcatSource(source);
417
488
  /** @type {Set<string>} */
418
- const moduleRequests = new Set();
489
+ const externalReexports = new Set();
419
490
  /** @type {Map<string, string | InlinedUsedName>} */
420
491
  const unknownProvidedExports = new Map();
492
+ /** @type {Set<Module>} */
493
+ const visitedReexportModules = new Set();
421
494
 
422
495
  /**
423
496
  * Resolves dynamic star reexport.
424
497
  * @param {Module} module the module
425
498
  * @param {boolean} isDynamicReexport if module is dynamic reexported
499
+ * @returns {void}
426
500
  */
427
501
  const resolveDynamicStarReexport = (module, isDynamicReexport) => {
428
502
  for (const connection of moduleGraph.getOutgoingConnections(module)) {
@@ -445,8 +519,22 @@ class ModuleLibraryPlugin extends AbstractLibraryPlugin {
445
519
  ) {
446
520
  // Handle export * from 'external'
447
521
  if (importedModule instanceof ExternalModule) {
448
- moduleRequests.add(importedModule.userRequest);
449
- } else {
522
+ const request = importedModule.getResolvedRequest();
523
+ // A property path is reported by `_checkStarReexportedExternals`,
524
+ // and an absent one by the external's own build
525
+ const specifier =
526
+ typeof request === "string"
527
+ ? request
528
+ : Array.isArray(request) && request.length === 1
529
+ ? request[0]
530
+ : undefined;
531
+ if (specifier !== undefined) {
532
+ externalReexports.add(
533
+ `export * from ${toJsStringLiteral(specifier)}${toAttributesClause(dep.attributes)};\n`
534
+ );
535
+ }
536
+ } else if (!visitedReexportModules.has(importedModule)) {
537
+ visitedReexportModules.add(importedModule);
450
538
  resolveDynamicStarReexport(importedModule, true);
451
539
  }
452
540
  }
@@ -473,8 +561,8 @@ class ModuleLibraryPlugin extends AbstractLibraryPlugin {
473
561
 
474
562
  resolveDynamicStarReexport(module, false);
475
563
 
476
- for (const request of moduleRequests) {
477
- result.add(`export * from "${request}";\n`);
564
+ for (const reexport of externalReexports) {
565
+ result.add(reexport);
478
566
  }
479
567
 
480
568
  for (const [origin, used] of unknownProvidedExports) {
@@ -648,6 +736,29 @@ class ModuleLibraryPlugin extends AbstractLibraryPlugin {
648
736
  }
649
737
  }
650
738
 
739
+ const externalTarget = exportInfo.getTarget(moduleGraph);
740
+ if (
741
+ externalTarget &&
742
+ externalTarget.module instanceof ExternalModule &&
743
+ externalTarget.export &&
744
+ externalTarget.export.length === 1 &&
745
+ codeGenerationResults.has(externalTarget.module, chunk.runtime)
746
+ ) {
747
+ const reexport = codeGenerationResults.getData(
748
+ externalTarget.module,
749
+ chunk.runtime,
750
+ "externalReexport"
751
+ );
752
+ if (reexport) {
753
+ if (!bindingsTakenOver) needExportsDeclaration = true;
754
+ result.add(
755
+ `export { ${toExportName(externalTarget.export[0])} as ${toExportName(originalName)} } ${reexport};\n`
756
+ );
757
+ alreadyRenderedExports.add(originalName);
758
+ continue;
759
+ }
760
+ }
761
+
651
762
  // The exports of entry module are never inlined
652
763
  const usedName =
653
764
  /** @type {string} */
@@ -32,6 +32,28 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule {
32
32
  this.runtimeRequirements = runtimeRequirements;
33
33
  }
34
34
 
35
+ /**
36
+ * The `[handlerMap, key]` pairs this module installs onto a chunk handler map
37
+ * such as `__webpack_require__.f`, or `null` where it cannot name them.
38
+ * @returns {[string, string][] | null} installed chunk handlers (do not mutate)
39
+ */
40
+ getInstalledChunkHandlers() {
41
+ const runtimeRequirements = this.runtimeRequirements;
42
+ /** @type {[string, string][]} */
43
+ const handlers = [];
44
+ if (runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers)) {
45
+ handlers.push([RuntimeGlobals.ensureChunkHandlers, "readFileVm"]);
46
+ }
47
+ // The hot update flow installs this one onto the same map while it runs.
48
+ if (runtimeRequirements.has(RuntimeGlobals.hmrDownloadUpdateHandlers)) {
49
+ handlers.push([RuntimeGlobals.ensureChunkHandlers, "readFileVmHmr"]);
50
+ }
51
+ if (runtimeRequirements.has(RuntimeGlobals.onChunksLoaded)) {
52
+ handlers.push([RuntimeGlobals.onChunksLoaded, "readFileVm"]);
53
+ }
54
+ return handlers;
55
+ }
56
+
35
57
  /**
36
58
  * Returns generated code.
37
59
  * @private
@@ -32,6 +32,28 @@ class RequireChunkLoadingRuntimeModule extends RuntimeModule {
32
32
  this.runtimeRequirements = runtimeRequirements;
33
33
  }
34
34
 
35
+ /**
36
+ * The `[handlerMap, key]` pairs this module installs onto a chunk handler map
37
+ * such as `__webpack_require__.f`, or `null` where it cannot name them.
38
+ * @returns {[string, string][] | null} installed chunk handlers (do not mutate)
39
+ */
40
+ getInstalledChunkHandlers() {
41
+ const runtimeRequirements = this.runtimeRequirements;
42
+ /** @type {[string, string][]} */
43
+ const handlers = [];
44
+ if (runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers)) {
45
+ handlers.push([RuntimeGlobals.ensureChunkHandlers, "require"]);
46
+ }
47
+ // The hot update flow installs this one onto the same map while it runs.
48
+ if (runtimeRequirements.has(RuntimeGlobals.hmrDownloadUpdateHandlers)) {
49
+ handlers.push([RuntimeGlobals.ensureChunkHandlers, "requireHmr"]);
50
+ }
51
+ if (runtimeRequirements.has(RuntimeGlobals.onChunksLoaded)) {
52
+ handlers.push([RuntimeGlobals.onChunksLoaded, "require"]);
53
+ }
54
+ return handlers;
55
+ }
56
+
35
57
  /**
36
58
  * Returns generated code.
37
59
  * @private
@@ -34,11 +34,13 @@ const analyzeScope = require("../javascript/ScopeAnalyzer");
34
34
  const {
35
35
  getDeferredCycleModuleIds,
36
36
  getDeferredCycleModules,
37
+ getKnownExportNames,
37
38
  getMakeDeferredNamespaceModeFromExportsType,
38
39
  getOptimizedDeferredModule
39
40
  } = require("../runtime/MakeDeferredNamespaceObjectRuntime");
40
41
  const { equals } = require("../util/ArrayHelpers");
41
42
  const LazySet = require("../util/LazySet");
43
+ const { getBuildDiagnostics } = require("../util/buildDiagnostics");
42
44
  const {
43
45
  compareModulesByFullName,
44
46
  concatComparators
@@ -116,8 +118,7 @@ const { InlinedUsedName } = require("./InlineExports");
116
118
  * @import {
117
119
  * ChunkRenderContext,
118
120
  * Scope,
119
- * Reference,
120
- * Variable
121
+ * Reference
121
122
  * } from "../javascript/JavascriptModulesPlugin"
122
123
  */
123
124
  /** @import { Range } from "../javascript/JavascriptParser" */
@@ -181,6 +182,7 @@ const findIdentifiers = (source) => {
181
182
  * @property {string=} comment
182
183
  * @property {ExportName} ids
183
184
  * @property {ExportName} exportName
185
+ * @property {boolean=} accessorCall the raw name is the wrapper accessor call itself, so it binds looser than the identifier it replaces
184
186
  */
185
187
 
186
188
  /**
@@ -246,6 +248,7 @@ const findIdentifiers = (source) => {
246
248
  * @property {boolean} deferred the module is deferred at least once
247
249
  * @property {boolean} deferredNamespaceObjectUsed deferred namespace object that being used in a not-analyzable way so it must be materialized
248
250
  * @property {string | undefined} deferredNamespaceObjectName deferred namespace object that being used in a not-analyzable way so it must be materialized
251
+ * @property {boolean} specNamespaceObjectUsed an import reads the spec namespace object the module hands out
249
252
  * @property {boolean} interopNamespaceObjectUsed "default-with-named" namespace
250
253
  * @property {string | undefined} interopNamespaceObjectName "default-with-named" namespace
251
254
  * @property {boolean} interopNamespaceObject2Used "default-only" namespace
@@ -422,13 +425,26 @@ const getInteropExpr = (info, interopName) =>
422
425
  * slot, but a wrapped one only runs when its accessor is called, so dropping
423
426
  * the reference would drop the module's side effects with it.
424
427
  * @param {ConcatenatedModuleInfo} info module info
428
+ * @param {boolean | undefined} asiSafe asiSafe
425
429
  * @returns {string} expression evaluating to undefined
426
430
  */
427
- const getUnusedExportExpr = (info) =>
431
+ const getUnusedExportExpr = (info, asiSafe) =>
428
432
  info.wrapped
429
- ? `/* unused export */ (${info.namespaceObjectName}, undefined)`
433
+ ? `${asiSafe === false ? ";" : ""}/* unused export */ (${info.namespaceObjectName}, undefined)`
430
434
  : "/* unused export */ undefined";
431
435
 
436
+ /**
437
+ * Parenthesizes a reference that may already carry an ASI guard of its own,
438
+ * keeping that guard outside the new parentheses — nested it would not parse.
439
+ * @param {string} reference the reference
440
+ * @param {boolean | undefined} asiSafe asiSafe
441
+ * @returns {string} the parenthesized reference
442
+ */
443
+ const parenthesizeReference = (reference, asiSafe) =>
444
+ asiSafe === false
445
+ ? `;(${reference.startsWith(";") ? reference.slice(1) : reference})`
446
+ : `(${reference})`;
447
+
432
448
  /**
433
449
  * @param {ModuleGraph} moduleGraph the module graph
434
450
  * @param {ModuleInfo} info module info
@@ -483,7 +499,7 @@ const getFinalBinding = (
483
499
  if (!usedName) {
484
500
  return {
485
501
  info,
486
- rawName: getUnusedExportExpr(info),
502
+ rawName: getUnusedExportExpr(info, asiSafe),
487
503
  ids: [],
488
504
  exportName
489
505
  };
@@ -494,11 +510,14 @@ const getFinalBinding = (
494
510
  /** @type {NonNullable<ConcatenatedModuleInfo["namespaceObjectName"]>} */
495
511
  (info.namespaceObjectName),
496
512
  ids: /** @type {ExportName} */ (usedName),
497
- exportName
513
+ exportName,
514
+ accessorCall: info.wrapped
498
515
  };
499
516
  }
500
517
 
501
- if (exportName.length === 0) {
518
+ if (moduleExportsAccess) {
519
+ // Skip ESM interop when require() targets a module outside the concatenation
520
+ } else if (exportName.length === 0) {
502
521
  switch (exportsType) {
503
522
  case "default-only":
504
523
  if (deferred) info.deferredNamespaceObjectUsed = true;
@@ -509,7 +528,8 @@ const getFinalBinding = (
509
528
  ? /** @type {string} */ (info.deferredNamespaceObjectName)
510
529
  : getInteropExpr(info, info.interopNamespaceObject2Name),
511
530
  ids: exportName,
512
- exportName
531
+ exportName,
532
+ accessorCall: !deferred && info.wrapped
513
533
  };
514
534
  case "default-with-named":
515
535
  if (deferred) info.deferredNamespaceObjectUsed = true;
@@ -520,7 +540,8 @@ const getFinalBinding = (
520
540
  ? /** @type {string} */ (info.deferredNamespaceObjectName)
521
541
  : getInteropExpr(info, info.interopNamespaceObjectName),
522
542
  ids: exportName,
523
- exportName
543
+ exportName,
544
+ accessorCall: !deferred && info.wrapped
524
545
  };
525
546
  case "namespace":
526
547
  case "dynamic":
@@ -611,7 +632,8 @@ const getFinalBinding = (
611
632
  info,
612
633
  rawName: getExternalModuleExpr(info),
613
634
  ids: exportName,
614
- exportName
635
+ exportName,
636
+ accessorCall: info.wrapped
615
637
  };
616
638
  }
617
639
  info.interopDefaultAccessUsed = true;
@@ -657,9 +679,10 @@ const getFinalBinding = (
657
679
  /** @type {NonNullable<ConcatenatedModuleInfo["namespaceObjectName"]>} */
658
680
  (info.namespaceObjectName),
659
681
  ids: exportName,
660
- exportName
682
+ exportName,
683
+ accessorCall: info.wrapped
661
684
  };
662
- case "external":
685
+ case "external": {
663
686
  if (deferred) {
664
687
  info.deferredNamespaceObjectUsed = true;
665
688
  return {
@@ -669,12 +692,30 @@ const getFinalBinding = (
669
692
  exportName
670
693
  };
671
694
  }
695
+
696
+ // `require()` reads the exports object rather than a namespace, so
697
+ // only an import gets the spec object and interop keeps working.
698
+ const spec =
699
+ !moduleExportsAccess &&
700
+ exportsType === "namespace" &&
701
+ Boolean(
702
+ /** @type {BuildInfo} */
703
+ (info.module.buildInfo).specNamespaceObject
704
+ );
705
+ const rawName = getExternalModuleExpr(info);
706
+
707
+ if (spec) info.specNamespaceObjectUsed = true;
708
+
672
709
  return {
673
710
  info,
674
- rawName: getExternalModuleExpr(info),
711
+ rawName: spec
712
+ ? `${RuntimeGlobals.specNamespaceObject}(${rawName})`
713
+ : rawName,
675
714
  ids: exportName,
676
- exportName
715
+ exportName,
716
+ accessorCall: spec || info.wrapped
677
717
  };
718
+ }
678
719
  }
679
720
  }
680
721
  const exportsInfo = moduleGraph.getExportsInfo(info.module);
@@ -938,9 +979,13 @@ const getFinalName = (
938
979
  let reference;
939
980
  /** @type {boolean} */
940
981
  let isPropertyAccess;
982
+ // the raw name is the wrapper accessor call itself, so the reference binds
983
+ // looser than the identifier it stands in for
984
+ let accessorCall = false;
941
985
  if ("rawName" in binding) {
942
986
  reference = `${binding.rawName}${comment || ""}${propertyAccess(ids)}`;
943
987
  isPropertyAccess = ids.length > 0;
988
+ accessorCall = binding.accessorCall === true;
944
989
  } else {
945
990
  const { info, name: exportId } = binding;
946
991
  const name = info.internalNames.get(exportId);
@@ -968,8 +1013,12 @@ const getFinalName = (
968
1013
  ? `;(0,${reference})`
969
1014
  : `/*#__PURE__*/Object(${reference})`;
970
1015
  } else if (binding.info.wrapped) {
971
- return asiSafe === false ? `;(${reference})` : `(${reference})`;
1016
+ return parenthesizeReference(reference, asiSafe);
972
1017
  }
1018
+ } else if (accessorCall && !asCall) {
1019
+ // without parentheses `new X()` would construct the accessor rather
1020
+ // than what it returns
1021
+ return parenthesizeReference(reference, asiSafe);
973
1022
  }
974
1023
 
975
1024
  return reference;
@@ -1166,15 +1215,17 @@ class ConcatenatedModule extends Module {
1166
1215
 
1167
1216
  for (const m of this._modules) {
1168
1217
  // populate cacheable
1169
- const { cacheable, notCacheableReasons } = /** @type {BuildInfo} */ (
1170
- m.buildInfo
1171
- );
1218
+ const { cacheable, diagnostics } = /** @type {BuildInfo} */ (m.buildInfo);
1172
1219
  if (!cacheable) {
1173
1220
  this.buildInfo.cacheable = false;
1221
+ const notCacheableReasons =
1222
+ diagnostics === undefined
1223
+ ? undefined
1224
+ : diagnostics.notCacheableReasons;
1174
1225
  if (notCacheableReasons) {
1226
+ const own = getBuildDiagnostics(this.buildInfo);
1175
1227
  const reasons =
1176
- this.buildInfo.notCacheableReasons ||
1177
- (this.buildInfo.notCacheableReasons = []);
1228
+ own.notCacheableReasons || (own.notCacheableReasons = []);
1178
1229
  for (const reason of notCacheableReasons) {
1179
1230
  if (!reasons.includes(reason)) reasons.push(reason);
1180
1231
  }
@@ -1804,6 +1855,15 @@ class ConcatenatedModule extends Module {
1804
1855
  return info.escapeNamespaceObjectName;
1805
1856
  }
1806
1857
  const exportsInfo = moduleGraph.getExportsInfo(info.module);
1858
+ // Its names are not mangled, and the wrapped binding is already the
1859
+ // namespace, so a decoupled object would only shadow it.
1860
+ if (
1861
+ /** @type {BuildInfo} */
1862
+ (info.module.buildInfo).specNamespaceObject
1863
+ ) {
1864
+ return undefined;
1865
+ }
1866
+
1807
1867
  let mangled = false;
1808
1868
  for (const exportInfo of exportsInfo.orderedExports) {
1809
1869
  if (exportInfo.provided === false) continue;
@@ -1849,6 +1909,13 @@ class ConcatenatedModule extends Module {
1849
1909
  for (const reference of ConcatenationScope.findModuleReferences(
1850
1910
  /** @type {Source} */ (info.internalSource)
1851
1911
  )) {
1912
+ if (reference.leaked) {
1913
+ throw new Error(
1914
+ `Unsubstituted module reference "${reference.name}" in ${info.module.readableIdentifier(
1915
+ requestShortener
1916
+ )}`
1917
+ );
1918
+ }
1852
1919
  if (visitedReferences.has(reference.name)) continue;
1853
1920
  visitedReferences.add(reference.name);
1854
1921
  const match = ConcatenationScope.matchModuleReference(
@@ -1942,6 +2009,13 @@ class ConcatenatedModule extends Module {
1942
2009
  ignoredScopes
1943
2010
  );
1944
2011
  } else {
2012
+ if (ConcatenationScope.isLeakedModuleReference(name)) {
2013
+ throw new Error(
2014
+ `Unsubstituted module reference "${name}" in ${info.module.readableIdentifier(
2015
+ requestShortener
2016
+ )}`
2017
+ );
2018
+ }
1945
2019
  allUsedNames.add(name);
1946
2020
  freeNames.add(name);
1947
2021
  }
@@ -2688,10 +2762,18 @@ ${defineGetters}`
2688
2762
  runtimeRequirements
2689
2763
  });
2690
2764
  const moduleId = JSON.stringify(chunkGraph.getModuleId(info.module));
2765
+ const required = `${RuntimeGlobals.require}(${moduleId})`;
2766
+
2767
+ // The wrapping happens per reference, so only the helper has to be
2768
+ // declared here.
2769
+ if (info.specNamespaceObjectUsed) {
2770
+ runtimeRequirements.add(RuntimeGlobals.specNamespaceObject);
2771
+ }
2772
+
2691
2773
  const body =
2692
2774
  condition === "true"
2693
- ? `return ${RuntimeGlobals.require}(${moduleId});`
2694
- : `if (${condition}) return ${RuntimeGlobals.require}(${moduleId});`;
2775
+ ? `return ${required};`
2776
+ : `if (${condition}) return ${required};`;
2695
2777
  result.add(
2696
2778
  `\n// EXTERNAL MODULE: ${info.module.readableIdentifier(
2697
2779
  requestShortener
@@ -2747,14 +2829,31 @@ ${defineGetters}`
2747
2829
  );
2748
2830
  if (info.deferredNamespaceObjectUsed) {
2749
2831
  runtimeRequirements.add(RuntimeGlobals.makeDeferredNamespaceObject);
2832
+ // Every call site for a module must agree on the shape, since the
2833
+ // runtime caches one namespace object per module and mode.
2834
+ const deferredExportsType = getExportsType(
2835
+ moduleGraph,
2836
+ info,
2837
+ strictHarmonyModule
2838
+ );
2839
+ const names = getKnownExportNames(
2840
+ moduleGraph,
2841
+ info.module,
2842
+ deferredExportsType
2843
+ );
2844
+ runtimeRequirements.add(
2845
+ names
2846
+ ? RuntimeGlobals.hasSealedDeferredNamespace
2847
+ : RuntimeGlobals.hasSynthesizedDeferredNamespace
2848
+ );
2750
2849
  result.add(
2751
2850
  `\nvar ${info.deferredNamespaceObjectName} = /*#__PURE__*/${
2752
2851
  RuntimeGlobals.makeDeferredNamespaceObject
2753
2852
  }(${JSON.stringify(
2754
2853
  chunkGraph.getModuleId(info.module)
2755
2854
  )}, ${getMakeDeferredNamespaceModeFromExportsType(
2756
- getExportsType(moduleGraph, info, strictHarmonyModule)
2757
- )});`
2855
+ deferredExportsType
2856
+ )}${names ? `, ${JSON.stringify(names)}` : ""});`
2758
2857
  );
2759
2858
  }
2760
2859
  }
@@ -2840,7 +2939,15 @@ ${defineGetters}`
2840
2939
  // External module bindings may be wrapped in
2841
2940
  // runtime-condition `if` blocks but referenced outside,
2842
2941
  // so they must remain function-scoped (`var`).
2843
- result.add(`var ${info.name} = __webpack_require__(${moduleId});`);
2942
+ const required = `__webpack_require__(${moduleId})`;
2943
+
2944
+ // The wrapping happens per reference, so only the helper has
2945
+ // to be declared here.
2946
+ if (info.specNamespaceObjectUsed) {
2947
+ runtimeRequirements.add(RuntimeGlobals.specNamespaceObject);
2948
+ }
2949
+
2950
+ result.add(`var ${info.name} = ${required};`);
2844
2951
 
2845
2952
  // Decoupled namespace object for an escaping mangled external
2846
2953
  // module must come after its import variable is defined.
@@ -3148,6 +3255,7 @@ ${defineGetters}`
3148
3255
  namespaceFnName: undefined,
3149
3256
  escapeNamespaceObjectName: undefined,
3150
3257
  deferredName: undefined,
3258
+ specNamespaceObjectUsed: false,
3151
3259
  interopNamespaceObjectUsed: false,
3152
3260
  interopNamespaceObjectName: undefined,
3153
3261
  interopNamespaceObject2Used: false,