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 {
15
15
  InlinedUsedName,
16
16
  isExportInlined,
17
- isInlineEnabled
17
+ isInlineEnabled,
18
+ isInlineExportsEnabled
18
19
  } = require("../optimize/InlineExports");
19
20
  const {
21
+ getKnownExportNames,
20
22
  getMakeDeferredNamespaceModeFromExportsType
21
23
  } = require("../runtime/MakeDeferredNamespaceObjectRuntime");
22
24
  const { countIterable } = require("../util/IterableHelpers");
@@ -29,6 +31,9 @@ const {
29
31
  keyToRuntime
30
32
  } = require("../util/runtime");
31
33
  const HarmonyExportInitFragment = require("./HarmonyExportInitFragment");
34
+
35
+ const { ExportBindingType } = HarmonyExportInitFragment;
36
+
32
37
  const HarmonyImportDependency = require("./HarmonyImportDependency");
33
38
  const HarmonyLinkingError = require("./HarmonyLinkingError");
34
39
  const { ImportPhaseUtils } = require("./ImportPhase");
@@ -44,7 +49,8 @@ const processExportInfo = require("./processExportInfo");
44
49
  * RawReferencedExports,
45
50
  * ReferencedExports,
46
51
  * TRANSITIVE,
47
- * ExportInfoName
52
+ * ExportInfoName,
53
+ * UpdateHashContext
48
54
  * } from "../Dependency"
49
55
  */
50
56
  /** @import { DependencyTemplateContext } from "../DependencyTemplate" */
@@ -58,6 +64,7 @@ const processExportInfo = require("./processExportInfo");
58
64
  * } from "../Module"
59
65
  */
60
66
  /** @import ModuleGraph from "../ModuleGraph" */
67
+ /** @import Hash from "../util/Hash" */
61
68
  /**
62
69
  * @import ModuleGraphConnection, {
63
70
  * ConnectionState
@@ -237,12 +244,28 @@ const isStarReexportBackToParent = (moduleGraph, exportInfo, parentModule) => {
237
244
  }
238
245
  };
239
246
 
247
+ /**
248
+ * Two `export *` sources are ambiguous for a name when they resolve to
249
+ * different bindings; a diamond re-export of the same binding is not.
250
+ * @param {ModuleGraph} moduleGraph module graph
251
+ * @param {InstanceType<ExportInfo>} previous export info of the star source that first provided the name
252
+ * @param {InstanceType<ExportInfo>} exportInfo export info of a later star source providing the same name
253
+ * @returns {boolean} true when the two sources provide different bindings
254
+ */
255
+ const isAmbiguousWith = (moduleGraph, previous, exportInfo) => {
256
+ const previousBinding = previous.getTerminalBinding(moduleGraph);
257
+ if (!previousBinding) return false;
258
+ const binding = exportInfo.getTerminalBinding(moduleGraph);
259
+ if (!binding) return false;
260
+ return previousBinding !== binding;
261
+ };
262
+
240
263
  /**
241
264
  * Determine export assignments.
242
265
  * @param {ModuleGraph} moduleGraph module graph
243
266
  * @param {HarmonyExportImportedSpecifierDependency[]} dependencies dependencies
244
267
  * @param {HarmonyExportImportedSpecifierDependency=} additionalDependency additional dependency
245
- * @returns {{ names: ExportInfoName[], dependencyIndices: DependencyIndices }} result
268
+ * @returns {{ names: ExportInfoName[], dependencyIndices: DependencyIndices, conflicting: Set<ExportInfoName> | undefined }} result
246
269
  */
247
270
  const determineExportAssignments = (
248
271
  moduleGraph,
@@ -253,6 +276,10 @@ const determineExportAssignments = (
253
276
  const names = new Set();
254
277
  /** @type {DependencyIndices} */
255
278
  const dependencyIndices = [];
279
+ /** @type {Map<ExportInfoName, InstanceType<ExportInfo>>} */
280
+ const firstProvider = new Map();
281
+ /** @type {Set<ExportInfoName> | undefined} */
282
+ let conflicting;
256
283
 
257
284
  if (additionalDependency) {
258
285
  dependencies = [...dependencies, additionalDependency];
@@ -270,24 +297,42 @@ const determineExportAssignments = (
270
297
  if (otherImportedModule) {
271
298
  const exportsInfo = moduleGraph.getExportsInfo(otherImportedModule);
272
299
  for (const exportInfo of exportsInfo.exports) {
300
+ if (exportInfo.provided !== true || exportInfo.name === "default") {
301
+ continue;
302
+ }
303
+ if (names.has(exportInfo.name)) {
304
+ const previous =
305
+ /** @type {InstanceType<ExportInfo>} */
306
+ (firstProvider.get(exportInfo.name));
307
+ if (
308
+ isAmbiguousWith(moduleGraph, previous, exportInfo) &&
309
+ // A cyclic contribution resolves to nothing, so it never competes
310
+ // with the binding a sibling `export *` provides.
311
+ !(
312
+ parentModule &&
313
+ isStarReexportBackToParent(moduleGraph, exportInfo, parentModule)
314
+ )
315
+ ) {
316
+ if (conflicting === undefined) conflicting = new Set();
317
+ conflicting.add(exportInfo.name);
318
+ }
319
+ continue;
320
+ }
273
321
  if (
274
- exportInfo.provided === true &&
275
- exportInfo.name !== "default" &&
276
- !names.has(exportInfo.name) &&
277
- !(
278
- parentModule &&
279
- isStarReexportBackToParent(moduleGraph, exportInfo, parentModule)
280
- )
322
+ parentModule &&
323
+ isStarReexportBackToParent(moduleGraph, exportInfo, parentModule)
281
324
  ) {
282
- names.add(exportInfo.name);
283
- dependencyIndices[i] = names.size;
325
+ continue;
284
326
  }
327
+ names.add(exportInfo.name);
328
+ firstProvider.set(exportInfo.name, exportInfo);
329
+ dependencyIndices[i] = names.size;
285
330
  }
286
331
  }
287
332
  }
288
333
  dependencyIndices.push(names.size);
289
334
 
290
- return { names: [...names], dependencyIndices };
335
+ return { names: [...names], dependencyIndices, conflicting };
291
336
  };
292
337
 
293
338
  /**
@@ -666,6 +711,12 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
666
711
  /** @type {IgnoredExports} */
667
712
  const ignoredExports = new Set(this.activeExports);
668
713
  ignoredExports.add("default");
714
+ // An ambiguous name resolves to no binding at all, so no `export *` in this
715
+ // module may contribute it — not even the first one.
716
+ const conflicting = this._getConflictingStarExportNames(moduleGraph);
717
+ if (conflicting !== undefined) {
718
+ for (const name of conflicting) ignoredExports.add(name);
719
+ }
669
720
 
670
721
  /** @type {Hidden | undefined} */
671
722
  let hiddenExports;
@@ -785,6 +836,31 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
785
836
  };
786
837
  }
787
838
 
839
+ /**
840
+ * Updates the hash with the data contributed by this instance.
841
+ * @param {Hash} hash hash to be updated
842
+ * @param {UpdateHashContext} context context
843
+ * @returns {void}
844
+ */
845
+ updateHash(hash, context) {
846
+ const { chunkGraph, runtime } = context;
847
+ const moduleGraph = chunkGraph.moduleGraph;
848
+ if (!isInlineExportsEnabled(moduleGraph)) return;
849
+ const module = moduleGraph.getModule(this);
850
+ if (!module || !isInlineEnabled(module)) return;
851
+ const mode = this.getMode(moduleGraph, runtime);
852
+ if (mode.type !== "normal-reexport") return;
853
+ const exportsInfo = moduleGraph.getExportsInfo(module);
854
+ for (const item of /** @type {NormalReexportItem[]} */ (mode.items)) {
855
+ if (item.hidden || item.checked) continue;
856
+ const usedName = exportsInfo.getUsedName(item.ids, runtime);
857
+ if (usedName instanceof InlinedUsedName) {
858
+ hash.update(`${item.name}:${item.ids.join(".")}:`);
859
+ usedName.updateHash(hash);
860
+ }
861
+ }
862
+ }
863
+
788
864
  /**
789
865
  * Gets module evaluation side effects state.
790
866
  * @param {ModuleGraph} moduleGraph the module graph
@@ -871,6 +947,21 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
871
947
  }
872
948
  }
873
949
 
950
+ /**
951
+ * Names this module's `export *` sources provide with conflicting bindings.
952
+ * @param {ModuleGraph} moduleGraph the module graph
953
+ * @returns {Set<ExportInfoName> | undefined} ambiguous names, or nothing when there are none
954
+ */
955
+ _getConflictingStarExportNames(moduleGraph) {
956
+ // Every `export *` carries the module's full star list; a lone one has
957
+ // nothing to be ambiguous with, so skip the walk.
958
+ if (!this.allStarExports) return;
959
+ const { dependencies } = this.allStarExports;
960
+ if (dependencies.length < 2) return;
961
+ return moduleGraph.cached(determineExportAssignments, dependencies)
962
+ .conflicting;
963
+ }
964
+
874
965
  /**
875
966
  * Discover active exports from other star exports.
876
967
  * @param {ModuleGraph} moduleGraph the module graph
@@ -1072,7 +1163,10 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
1072
1163
  */
1073
1164
  getWarnings(moduleGraph) {
1074
1165
  const exportsPresence = this._getEffectiveExportPresenceLevel(moduleGraph);
1075
- const circular = this._getCircularReexportWarnings(moduleGraph);
1166
+ const circular =
1167
+ this._getCircularReexportPresenceLevel() === ExportPresenceModes.WARN
1168
+ ? this._getCircularReexportErrors(moduleGraph)
1169
+ : undefined;
1076
1170
  if (exportsPresence === ExportPresenceModes.WARN) {
1077
1171
  const errors = this._getErrors(moduleGraph);
1078
1172
  if (!circular) return errors;
@@ -1082,12 +1176,23 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
1082
1176
  }
1083
1177
 
1084
1178
  /**
1085
- * Returns warnings for a name resolving through a circular reexport chain,
1086
- * off the export-presence path so a strict harmony module warns, not fails.
1179
+ * Reporting level for a circular reexport chain. It skips the promotion to
1180
+ * an error that AUTO gives a strict harmony module — a cycle warns by
1181
+ * default — but an explicit setting still says whether and how to report.
1182
+ * @returns {ExportPresenceMode} effective mode
1183
+ */
1184
+ _getCircularReexportPresenceLevel() {
1185
+ return this.exportPresenceMode === ExportPresenceModes.AUTO
1186
+ ? ExportPresenceModes.WARN
1187
+ : this.exportPresenceMode;
1188
+ }
1189
+
1190
+ /**
1191
+ * Returns errors for a name resolving through a circular reexport chain.
1087
1192
  * @param {ModuleGraph} moduleGraph module graph
1088
- * @returns {WebpackError[] | undefined} warnings
1193
+ * @returns {WebpackError[] | undefined} errors
1089
1194
  */
1090
- _getCircularReexportWarnings(moduleGraph) {
1195
+ _getCircularReexportErrors(moduleGraph) {
1091
1196
  const ids = this.getIds(moduleGraph);
1092
1197
  if (ids.length === 0 || !this.name) return;
1093
1198
  const parentModule = /** @type {Module} */ (
@@ -1115,10 +1220,18 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
1115
1220
  */
1116
1221
  getErrors(moduleGraph) {
1117
1222
  const exportsPresence = this._getEffectiveExportPresenceLevel(moduleGraph);
1118
- if (exportsPresence === ExportPresenceModes.ERROR) {
1119
- return this._getErrors(moduleGraph);
1223
+ const errors =
1224
+ exportsPresence === ExportPresenceModes.ERROR
1225
+ ? this._getErrors(moduleGraph)
1226
+ : null;
1227
+ if (
1228
+ this._getCircularReexportPresenceLevel() !== ExportPresenceModes.ERROR
1229
+ ) {
1230
+ return errors;
1120
1231
  }
1121
- return null;
1232
+ const circular = this._getCircularReexportErrors(moduleGraph);
1233
+ if (!circular) return errors;
1234
+ return errors ? [...errors, ...circular] : circular;
1122
1235
  }
1123
1236
 
1124
1237
  /**
@@ -1500,7 +1613,19 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS
1500
1613
  );
1501
1614
  break;
1502
1615
 
1503
- case "reexport-namespace-object":
1616
+ case "reexport-namespace-object": {
1617
+ let value = namespaceImportVar;
1618
+
1619
+ // The re-exported binding is the namespace itself, so it has to be
1620
+ // the same object every importer of that module is handed.
1621
+ if (
1622
+ importedModule.buildInfo &&
1623
+ importedModule.buildInfo.specNamespaceObject
1624
+ ) {
1625
+ runtimeRequirements.add(RuntimeGlobals.specNamespaceObject);
1626
+ value = `${RuntimeGlobals.specNamespaceObject}(${value})`;
1627
+ }
1628
+
1504
1629
  initFragments.push(
1505
1630
  this.getReexportFragment(
1506
1631
  module,
@@ -1508,12 +1633,13 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS
1508
1633
  moduleGraph
1509
1634
  .getExportsInfo(module)
1510
1635
  .getUsedName(/** @type {string} */ (mode.name), runtime),
1511
- namespaceImportVar,
1636
+ value,
1512
1637
  "",
1513
1638
  runtimeRequirements
1514
1639
  )
1515
1640
  );
1516
1641
  break;
1642
+ }
1517
1643
 
1518
1644
  case "normal-reexport": {
1519
1645
  // loop-invariants hoisted out of the per-item loop below (a barrel
@@ -1648,7 +1774,10 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS
1648
1774
 
1649
1775
  /** @type {ExportMap} */
1650
1776
  const map = new Map();
1651
- map.set(key, `/* ${comment} */ ${returnValue}`);
1777
+ map.set(key, {
1778
+ value: `/* ${comment} */ ${returnValue}`,
1779
+ type: ExportBindingType.Getter
1780
+ });
1652
1781
 
1653
1782
  return new HarmonyExportInitFragment(module.exportsArgument, map);
1654
1783
  }
@@ -1675,12 +1804,12 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS
1675
1804
 
1676
1805
  /** @type {ExportMap} */
1677
1806
  const map = new Map();
1678
- map.set(
1679
- key,
1680
- `/* reexport fake namespace object from non-harmony */ ${name}_namespace_cache || (${name}_namespace_cache = ${
1807
+ map.set(key, {
1808
+ value: `/* reexport fake namespace object from non-harmony */ ${name}_namespace_cache || (${name}_namespace_cache = ${
1681
1809
  RuntimeGlobals.createFakeNamespaceObject
1682
- }(${name}${fakeType ? `, ${fakeType}` : ""}))`
1683
- );
1810
+ }(${name}${fakeType ? `, ${fakeType}` : ""}))`,
1811
+ type: ExportBindingType.Getter
1812
+ });
1684
1813
 
1685
1814
  return [
1686
1815
  new InitFragment(
@@ -1719,10 +1848,20 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS
1719
1848
  const map = new Map();
1720
1849
  const moduleId = JSON.stringify(chunkGraph.getModuleId(module));
1721
1850
  const mode = getMakeDeferredNamespaceModeFromExportsType(exportsType);
1722
- map.set(
1723
- key,
1724
- `/* reexport deferred namespace object */ ${name}_deferred_namespace_cache || (${name}_deferred_namespace_cache = ${RuntimeGlobals.makeDeferredNamespaceObject}(${moduleId}, ${mode}))`
1851
+ const names = getKnownExportNames(
1852
+ chunkGraph.moduleGraph,
1853
+ module,
1854
+ exportsType
1855
+ );
1856
+ runtimeRequirements.add(
1857
+ names
1858
+ ? RuntimeGlobals.hasSealedDeferredNamespace
1859
+ : RuntimeGlobals.hasSynthesizedDeferredNamespace
1725
1860
  );
1861
+ map.set(key, {
1862
+ value: `/* reexport deferred namespace object */ ${name}_deferred_namespace_cache || (${name}_deferred_namespace_cache = ${RuntimeGlobals.makeDeferredNamespaceObject}(${moduleId}, ${mode}${names ? `, ${JSON.stringify(names)}` : ""}))`,
1863
+ type: ExportBindingType.Getter
1864
+ });
1726
1865
 
1727
1866
  return [
1728
1867
  new InitFragment(
@@ -35,9 +35,19 @@ const joinIterableWithComma = (iterable) => {
35
35
  return str;
36
36
  };
37
37
 
38
- /** @typedef {Map<UsedName, string>} ExportMap */
38
+ const ExportBindingType = Object.freeze({
39
+ Getter: 0b00,
40
+ Value: 0b01
41
+ });
42
+
43
+ /** @typedef {Map<UsedName, { value: string, type: typeof ExportBindingType.Getter | typeof ExportBindingType.Value }>} ExportMap */
39
44
  /** @typedef {Set<string>} UnusedExports */
40
- /** @import { OnDemandGeneration } from "./ExportBindingInitFragment" */
45
+
46
+ /**
47
+ * Lets a consumer take over the rendered `d()` call at its required position.
48
+ * End-position value bindings cannot move before the module body.
49
+ * @typedef {(source: string, placeAtEnd: boolean) => boolean} OnDemandGeneration
50
+ */
41
51
 
42
52
  /** @type {ExportMap} */
43
53
  const EMPTY_MAP = new Map();
@@ -71,6 +81,49 @@ class HarmonyExportInitFragment extends InitFragment {
71
81
  this.unusedExports = unusedExports;
72
82
  /** @type {OnDemandGeneration | undefined} */
73
83
  this.onDemand = onDemand;
84
+
85
+ this._generated = false;
86
+ this._defsValue = undefined;
87
+ this._defsGetter = undefined;
88
+ }
89
+
90
+ /**
91
+ * Returns the source code that will be included as initialization code.
92
+ * @param {GenerateContext} context context
93
+ * @returns {void}
94
+ */
95
+ _generate({ runtimeTemplate }) {
96
+ if (this._generated) return;
97
+ this._generated = true;
98
+
99
+ if (this.exportMap.size > 0) {
100
+ /** @type {string[]} */
101
+ const _defsValue = [];
102
+ const _defsGetter = [];
103
+ const orderedExportMap =
104
+ this.exportMap.size > 1
105
+ ? [...this.exportMap].sort(([a], [b]) => (a < b ? -1 : 1))
106
+ : this.exportMap;
107
+ for (const [key, { value, type }] of orderedExportMap) {
108
+ switch (type) {
109
+ case ExportBindingType.Getter:
110
+ _defsGetter.push(
111
+ `\n/* harmony export */ ${propertyName(
112
+ /** @type {string} */ (key)
113
+ )}: ${runtimeTemplate.returningFunction(value)}`
114
+ );
115
+ break;
116
+
117
+ case ExportBindingType.Value:
118
+ _defsValue.push(
119
+ `\n/* harmony export */ ${JSON.stringify(key)}, 0, ${value}`
120
+ );
121
+ }
122
+ }
123
+
124
+ this._defsGetter = _defsGetter;
125
+ this._defsValue = _defsValue;
126
+ }
74
127
  }
75
128
 
76
129
  /**
@@ -85,12 +138,15 @@ class HarmonyExportInitFragment extends InitFragment {
85
138
  /** @type {undefined | UnusedExports} */
86
139
  let unusedExports;
87
140
  let unusedExportsOwned = false;
141
+ /** @type {OnDemandGeneration=} */
142
+ let onDemand;
88
143
 
89
144
  for (const fragment of fragments) {
90
145
  if (fragment.exportMap.size !== 0) {
91
146
  if (exportMap === undefined) {
92
147
  exportMap = fragment.exportMap;
93
148
  exportMapOwned = false;
149
+ onDemand = fragment.onDemand;
94
150
  } else {
95
151
  if (!exportMapOwned) {
96
152
  exportMap = new Map(exportMap);
@@ -98,6 +154,7 @@ class HarmonyExportInitFragment extends InitFragment {
98
154
  }
99
155
  for (const [key, value] of fragment.exportMap) {
100
156
  if (!exportMap.has(key)) exportMap.set(key, value);
157
+ onDemand = onDemand || fragment.onDemand;
101
158
  }
102
159
  }
103
160
  }
@@ -120,7 +177,7 @@ class HarmonyExportInitFragment extends InitFragment {
120
177
  this.exportsArgument,
121
178
  exportMap,
122
179
  unusedExports,
123
- this.onDemand
180
+ onDemand
124
181
  );
125
182
  }
126
183
 
@@ -167,7 +224,10 @@ class HarmonyExportInitFragment extends InitFragment {
167
224
  * @param {GenerateContext} context context
168
225
  * @returns {string | Source | undefined} the source code that will be included as initialization code
169
226
  */
170
- getContent({ runtimeTemplate, runtimeRequirements }) {
227
+ getContent(context) {
228
+ this._generate(context);
229
+
230
+ const { runtimeRequirements } = context;
171
231
  const unusedPart =
172
232
  this.unusedExports.size > 1
173
233
  ? `/* unused harmony exports ${joinIterableWithComma(
@@ -177,35 +237,55 @@ class HarmonyExportInitFragment extends InitFragment {
177
237
  ? `/* unused harmony export ${first(this.unusedExports)} */\n`
178
238
  : "";
179
239
  let definePart = "";
180
- if (this.exportMap.size > 0) {
181
- /** @type {string[]} */
182
- const definitions = [];
183
- const orderedExportMap =
184
- this.exportMap.size > 1
185
- ? [...this.exportMap].sort(([a], [b]) => (a < b ? -1 : 1))
186
- : this.exportMap;
187
- for (const [key, value] of orderedExportMap) {
188
- definitions.push(
189
- `\n/* harmony export */ ${propertyName(
190
- /** @type {string} */ (key)
191
- )}: ${runtimeTemplate.returningFunction(value)}`
192
- );
193
- }
240
+
241
+ if (this._defsGetter && this._defsGetter.length) {
194
242
  // Requested even when the call is taken over below: whoever took it may still
195
243
  // emit it, and by then the requirement set is closed.
196
244
  runtimeRequirements.add(RuntimeGlobals.exports);
197
245
  runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
198
246
  definePart = `/* harmony export */ ${
199
247
  RuntimeGlobals.definePropertyGetters
200
- }(${this.exportsArgument}, {${definitions.join(
248
+ }(${this.exportsArgument}, {${this._defsGetter.join(
201
249
  ","
202
250
  )}\n/* harmony export */ });\n`;
203
251
  if (this.onDemand !== undefined && this.onDemand(definePart, false)) {
204
252
  definePart = "";
205
253
  }
206
254
  }
255
+
207
256
  return `${definePart}${unusedPart}`;
208
257
  }
258
+
259
+ /**
260
+ * Returns the source code that will be included at the end of the module.
261
+ * @param {GenerateContext} context context
262
+ * @returns {string | Source | undefined} the source code that will be included at the end of the module
263
+ */
264
+ getEndContent({ runtimeRequirements }) {
265
+ let definePart = "";
266
+
267
+ if (this._defsValue && this._defsValue.length) {
268
+ // Requested even when the call is taken over below: whoever took it may still
269
+ // emit it, and by then the requirement set is closed.
270
+ runtimeRequirements.add(RuntimeGlobals.exports);
271
+ runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
272
+ // Only this fragment emits the array form, so the runtime helper drops the
273
+ // branch reading it unless this asks for it.
274
+ runtimeRequirements.add(RuntimeGlobals.definePropertyGettersFromArray);
275
+ const definition = `/* harmony export */ ${
276
+ RuntimeGlobals.definePropertyGetters
277
+ }(${this.exportsArgument}, [${this._defsValue.join(",")}\n/* harmony export */ ]);\n`;
278
+
279
+ definePart =
280
+ this.onDemand !== undefined && this.onDemand(definition, true)
281
+ ? definePart
282
+ : `\n${definition}`;
283
+ }
284
+
285
+ return definePart;
286
+ }
209
287
  }
210
288
 
211
289
  module.exports = HarmonyExportInitFragment;
290
+
291
+ HarmonyExportInitFragment.ExportBindingType = ExportBindingType;
@@ -9,8 +9,10 @@ const Dependency = require("../Dependency");
9
9
  const { InlinedUsedName } = require("../optimize/InlineExports");
10
10
  const makeSerializable = require("../util/makeSerializable");
11
11
  const memoize = require("../util/memoize");
12
- const ExportBindingInitFragment = require("./ExportBindingInitFragment");
13
12
  const HarmonyExportInitFragment = require("./HarmonyExportInitFragment");
13
+
14
+ const { ExportBindingType } = HarmonyExportInitFragment;
15
+
14
16
  const NullDependency = require("./NullDependency");
15
17
 
16
18
  /** @import { ReplaceSource } from "webpack-sources" */
@@ -180,7 +182,7 @@ HarmonyExportSpecifierDependency.Template = class HarmonyExportSpecifierDependen
180
182
  return;
181
183
  }
182
184
 
183
- const canUseValueBinding =
185
+ const valueFormat =
184
186
  dep.constValue !== undefined &&
185
187
  /** @type {import("../Module").BuildInfo} */ (module.buildInfo)
186
188
  .isCircular === false;
@@ -200,34 +202,20 @@ HarmonyExportSpecifierDependency.Template = class HarmonyExportSpecifierDependen
200
202
  ) === true
201
203
  : undefined;
202
204
 
203
- if (canUseValueBinding) {
204
- initFragments.push(
205
- new ExportBindingInitFragment(
206
- module.exportsArgument,
207
- [
208
- {
209
- name: used,
210
- value: `/* binding */ ${dep.id}`,
211
- bindingType: "value"
212
- }
213
- ],
214
- true,
215
- onDemand
216
- )
217
- );
218
- } else {
219
- /** @type {ExportMap} */
220
- const map = new Map();
221
- map.set(used, `/* binding */ ${dep.id}`);
222
- initFragments.push(
223
- new HarmonyExportInitFragment(
224
- module.exportsArgument,
225
- map,
226
- undefined,
227
- onDemand
228
- )
229
- );
230
- }
205
+ /** @type {ExportMap} */
206
+ const map = new Map();
207
+ map.set(used, {
208
+ value: `/* binding */ ${dep.id}`,
209
+ type: valueFormat ? ExportBindingType.Value : ExportBindingType.Getter
210
+ });
211
+ initFragments.push(
212
+ new HarmonyExportInitFragment(
213
+ module.exportsArgument,
214
+ map,
215
+ undefined,
216
+ onDemand
217
+ )
218
+ );
231
219
  }
232
220
  };
233
221
 
@@ -0,0 +1,59 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Alexander Akait @alexander-akait
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const { ASSET_TYPE } = require("../ModuleSourceTypeConstants");
9
+ const makeSerializable = require("../util/makeSerializable");
10
+ const HarmonyImportSideEffectDependency = require("./HarmonyImportSideEffectDependency");
11
+
12
+ /** @import Module from "../Module" */
13
+ /** @import ModuleGraph from "../ModuleGraph" */
14
+ /** @import { GetConditionFn } from "../Dependency" */
15
+
16
+ /**
17
+ * Whether a module is emitted as a file of its own, asked of the module so a
18
+ * plugin emitting the same way is treated alike. `buildInfo.filename` cannot
19
+ * serve here: generation sets it long after a connection has to know whether
20
+ * it is active.
21
+ * @param {Module} module the module to look up
22
+ * @returns {boolean} true when it emits a file
23
+ */
24
+ const emitsOwnFile = (module) => module.getSourceTypes().has(ASSET_TYPE);
25
+
26
+ /**
27
+ * An `import "..."` that declares no binding. It is a separate class rather
28
+ * than a flag so it costs nothing per instance, and the bound form — much the
29
+ * more common one — keeps the base class and its inline caches untouched.
30
+ */
31
+ class HarmonyImportBareSideEffectDependency extends HarmonyImportSideEffectDependency {
32
+ /**
33
+ * Returns function to determine if the connection is active.
34
+ * @param {ModuleGraph} moduleGraph module graph
35
+ * @returns {null | false | GetConditionFn} function to determine if the connection is active
36
+ */
37
+ getCondition(moduleGraph) {
38
+ return (connection) => {
39
+ const refModule = connection.resolvedModule;
40
+
41
+ if (!refModule) return true;
42
+ // Nothing reads the module, so emitting its file is the only thing the
43
+ // import can have been written for.
44
+ if (emitsOwnFile(refModule)) return true;
45
+
46
+ return refModule.getSideEffectsConnectionState(moduleGraph);
47
+ };
48
+ }
49
+ }
50
+
51
+ makeSerializable(
52
+ HarmonyImportBareSideEffectDependency,
53
+ "webpack/lib/dependencies/HarmonyImportBareSideEffectDependency"
54
+ );
55
+
56
+ HarmonyImportBareSideEffectDependency.Template =
57
+ HarmonyImportSideEffectDependency.Template;
58
+
59
+ module.exports = HarmonyImportBareSideEffectDependency;