webpack 5.59.0 → 5.76.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.

Potentially problematic release.


This version of webpack might be problematic. Click here for more details.

Files changed (236) hide show
  1. package/README.md +22 -24
  2. package/bin/webpack.js +0 -0
  3. package/hot/dev-server.js +17 -4
  4. package/hot/lazy-compilation-node.js +3 -1
  5. package/hot/poll.js +1 -1
  6. package/hot/signal.js +1 -1
  7. package/lib/APIPlugin.js +33 -0
  8. package/lib/BannerPlugin.js +13 -5
  9. package/lib/Cache.js +1 -1
  10. package/lib/CacheFacade.js +4 -11
  11. package/lib/Chunk.js +6 -3
  12. package/lib/ChunkGraph.js +94 -8
  13. package/lib/ChunkGroup.js +1 -1
  14. package/lib/CleanPlugin.js +81 -20
  15. package/lib/Compilation.js +188 -93
  16. package/lib/Compiler.js +87 -18
  17. package/lib/ConstPlugin.js +2 -2
  18. package/lib/ContextModule.js +142 -51
  19. package/lib/ContextModuleFactory.js +65 -25
  20. package/lib/DelegatedModule.js +1 -1
  21. package/lib/DelegatedModuleFactoryPlugin.js +1 -1
  22. package/lib/Dependency.js +17 -0
  23. package/lib/DependencyTemplate.js +9 -0
  24. package/lib/DependencyTemplates.js +1 -1
  25. package/lib/DllModule.js +1 -1
  26. package/lib/DllReferencePlugin.js +1 -1
  27. package/lib/EntryOptionPlugin.js +2 -0
  28. package/lib/ErrorHelpers.js +2 -2
  29. package/lib/EvalDevToolModulePlugin.js +16 -1
  30. package/lib/EvalSourceMapDevToolPlugin.js +25 -4
  31. package/lib/ExportsInfo.js +5 -5
  32. package/lib/ExternalModule.js +94 -54
  33. package/lib/ExternalModuleFactoryPlugin.js +5 -5
  34. package/lib/FileSystemInfo.js +124 -58
  35. package/lib/Generator.js +3 -0
  36. package/lib/HookWebpackError.js +1 -1
  37. package/lib/HotModuleReplacementPlugin.js +3 -1
  38. package/lib/LoaderOptionsPlugin.js +1 -1
  39. package/lib/Module.js +28 -4
  40. package/lib/ModuleFilenameHelpers.js +8 -4
  41. package/lib/ModuleHashingError.js +29 -0
  42. package/lib/MultiCompiler.js +1 -1
  43. package/lib/MultiWatching.js +1 -1
  44. package/lib/NodeStuffPlugin.js +13 -3
  45. package/lib/NormalModule.js +51 -33
  46. package/lib/NormalModuleFactory.js +42 -37
  47. package/lib/ProgressPlugin.js +4 -5
  48. package/lib/RawModule.js +1 -1
  49. package/lib/RuntimeGlobals.js +29 -1
  50. package/lib/RuntimeModule.js +1 -1
  51. package/lib/RuntimePlugin.js +84 -1
  52. package/lib/RuntimeTemplate.js +114 -2
  53. package/lib/Template.js +3 -2
  54. package/lib/TemplatedPathPlugin.js +48 -23
  55. package/lib/WatchIgnorePlugin.js +19 -7
  56. package/lib/Watching.js +33 -19
  57. package/lib/WebpackOptionsApply.js +79 -11
  58. package/lib/asset/AssetGenerator.js +228 -71
  59. package/lib/asset/AssetModulesPlugin.js +3 -0
  60. package/lib/asset/AssetParser.js +1 -0
  61. package/lib/asset/AssetSourceGenerator.js +31 -6
  62. package/lib/asset/AssetSourceParser.js +1 -0
  63. package/lib/asset/RawDataUrlModule.js +148 -0
  64. package/lib/async-modules/AwaitDependenciesInitFragment.js +4 -4
  65. package/lib/buildChunkGraph.js +38 -7
  66. package/lib/cache/PackFileCacheStrategy.js +15 -8
  67. package/lib/cache/ResolverCachePlugin.js +90 -29
  68. package/lib/cli.js +44 -3
  69. package/lib/config/browserslistTargetHandler.js +41 -6
  70. package/lib/config/defaults.js +123 -19
  71. package/lib/config/normalization.js +10 -2
  72. package/lib/config/target.js +10 -0
  73. package/lib/container/ContainerEntryModule.js +8 -5
  74. package/lib/container/FallbackModule.js +4 -4
  75. package/lib/container/ModuleFederationPlugin.js +2 -0
  76. package/lib/container/RemoteModule.js +4 -2
  77. package/lib/container/RemoteRuntimeModule.js +8 -7
  78. package/lib/css/CssExportsGenerator.js +139 -0
  79. package/lib/css/CssGenerator.js +109 -0
  80. package/lib/css/CssLoadingRuntimeModule.js +442 -0
  81. package/lib/css/CssModulesPlugin.js +462 -0
  82. package/lib/css/CssParser.js +618 -0
  83. package/lib/css/walkCssTokens.js +659 -0
  84. package/lib/debug/ProfilingPlugin.js +24 -21
  85. package/lib/dependencies/AMDRequireDependency.js +6 -6
  86. package/lib/dependencies/CommonJsExportsParserPlugin.js +1 -2
  87. package/lib/dependencies/CommonJsFullRequireDependency.js +5 -1
  88. package/lib/dependencies/CommonJsImportsParserPlugin.js +344 -61
  89. package/lib/dependencies/CommonJsRequireContextDependency.js +6 -2
  90. package/lib/dependencies/CommonJsRequireDependency.js +2 -1
  91. package/lib/dependencies/ContextDependency.js +16 -2
  92. package/lib/dependencies/ContextDependencyHelpers.js +21 -8
  93. package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +4 -1
  94. package/lib/dependencies/ContextElementDependency.js +25 -3
  95. package/lib/dependencies/CreateScriptUrlDependency.js +12 -0
  96. package/lib/dependencies/CssExportDependency.js +85 -0
  97. package/lib/dependencies/CssImportDependency.js +75 -0
  98. package/lib/dependencies/CssLocalIdentifierDependency.js +119 -0
  99. package/lib/dependencies/CssSelfLocalIdentifierDependency.js +101 -0
  100. package/lib/dependencies/CssUrlDependency.js +132 -0
  101. package/lib/dependencies/ExportsInfoDependency.js +6 -0
  102. package/lib/dependencies/HarmonyAcceptImportDependency.js +5 -3
  103. package/lib/dependencies/HarmonyCompatibilityDependency.js +5 -5
  104. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +127 -0
  105. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +12 -3
  106. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +25 -17
  107. package/lib/dependencies/HarmonyExportInitFragment.js +4 -1
  108. package/lib/dependencies/HarmonyImportDependency.js +23 -0
  109. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +142 -45
  110. package/lib/dependencies/HarmonyImportSpecifierDependency.js +46 -22
  111. package/lib/dependencies/HarmonyModulesPlugin.js +10 -0
  112. package/lib/dependencies/ImportContextDependency.js +0 -2
  113. package/lib/dependencies/ImportMetaContextDependency.js +35 -0
  114. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +252 -0
  115. package/lib/dependencies/ImportMetaContextPlugin.js +59 -0
  116. package/lib/dependencies/ImportMetaPlugin.js +22 -3
  117. package/lib/dependencies/ImportParserPlugin.js +35 -29
  118. package/lib/dependencies/JsonExportsDependency.js +17 -21
  119. package/lib/dependencies/LoaderDependency.js +13 -0
  120. package/lib/dependencies/LoaderImportDependency.js +13 -0
  121. package/lib/dependencies/LoaderPlugin.js +4 -2
  122. package/lib/dependencies/ModuleDependency.js +11 -1
  123. package/lib/dependencies/ProvidedDependency.js +31 -8
  124. package/lib/dependencies/RequireContextDependency.js +0 -16
  125. package/lib/dependencies/RequireEnsureDependency.js +2 -2
  126. package/lib/dependencies/RequireResolveContextDependency.js +2 -2
  127. package/lib/dependencies/RequireResolveDependency.js +2 -1
  128. package/lib/dependencies/URLDependency.js +3 -8
  129. package/lib/dependencies/URLPlugin.js +22 -1
  130. package/lib/dependencies/WorkerPlugin.js +2 -0
  131. package/lib/esm/ModuleChunkFormatPlugin.js +74 -49
  132. package/lib/esm/ModuleChunkLoadingPlugin.js +3 -1
  133. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +25 -9
  134. package/lib/hmr/HotModuleReplacement.runtime.js +29 -14
  135. package/lib/hmr/JavascriptHotModuleReplacement.runtime.js +4 -3
  136. package/lib/hmr/LazyCompilationPlugin.js +54 -26
  137. package/lib/hmr/lazyCompilationBackend.js +51 -12
  138. package/lib/ids/DeterministicModuleIdsPlugin.js +55 -35
  139. package/lib/ids/HashedModuleIdsPlugin.js +11 -14
  140. package/lib/ids/IdHelpers.js +26 -12
  141. package/lib/ids/NamedModuleIdsPlugin.js +6 -9
  142. package/lib/ids/NaturalModuleIdsPlugin.js +10 -13
  143. package/lib/ids/OccurrenceModuleIdsPlugin.js +13 -10
  144. package/lib/ids/SyncModuleIdsPlugin.js +140 -0
  145. package/lib/index.js +20 -0
  146. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +2 -2
  147. package/lib/javascript/BasicEvaluatedExpression.js +5 -2
  148. package/lib/javascript/ChunkHelpers.js +33 -0
  149. package/lib/javascript/JavascriptGenerator.js +1 -0
  150. package/lib/javascript/JavascriptModulesPlugin.js +27 -2
  151. package/lib/javascript/JavascriptParser.js +143 -73
  152. package/lib/javascript/StartupHelpers.js +7 -30
  153. package/lib/json/JsonData.js +8 -0
  154. package/lib/json/JsonParser.js +4 -6
  155. package/lib/library/AssignLibraryPlugin.js +39 -15
  156. package/lib/library/EnableLibraryPlugin.js +11 -0
  157. package/lib/library/UmdLibraryPlugin.js +5 -3
  158. package/lib/node/NodeTargetPlugin.js +3 -0
  159. package/lib/node/NodeWatchFileSystem.js +85 -31
  160. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +23 -8
  161. package/lib/node/RequireChunkLoadingRuntimeModule.js +24 -9
  162. package/lib/optimize/ConcatenatedModule.js +62 -26
  163. package/lib/optimize/ModuleConcatenationPlugin.js +26 -4
  164. package/lib/optimize/RealContentHashPlugin.js +45 -15
  165. package/lib/optimize/SplitChunksPlugin.js +8 -1
  166. package/lib/runtime/AsyncModuleRuntimeModule.js +50 -66
  167. package/lib/runtime/BaseUriRuntimeModule.js +31 -0
  168. package/lib/runtime/CreateScriptRuntimeModule.js +36 -0
  169. package/lib/runtime/CreateScriptUrlRuntimeModule.js +9 -34
  170. package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +76 -0
  171. package/lib/runtime/LoadScriptRuntimeModule.js +11 -9
  172. package/lib/runtime/NonceRuntimeModule.js +24 -0
  173. package/lib/schemes/HttpUriPlugin.js +77 -14
  174. package/lib/serialization/FileMiddleware.js +44 -9
  175. package/lib/sharing/ConsumeSharedModule.js +8 -2
  176. package/lib/sharing/ConsumeSharedRuntimeModule.js +26 -5
  177. package/lib/sharing/ProvideSharedModule.js +4 -2
  178. package/lib/sharing/ProvideSharedPlugin.js +1 -2
  179. package/lib/sharing/ShareRuntimeModule.js +1 -1
  180. package/lib/sharing/utils.js +1 -1
  181. package/lib/stats/DefaultStatsFactoryPlugin.js +113 -68
  182. package/lib/stats/DefaultStatsPrinterPlugin.js +90 -25
  183. package/lib/util/ArrayHelpers.js +30 -0
  184. package/lib/util/AsyncQueue.js +1 -1
  185. package/lib/util/compileBooleanMatcher.js +1 -1
  186. package/lib/util/create-schema-validation.js +9 -2
  187. package/lib/util/createHash.js +12 -0
  188. package/lib/util/deprecation.js +10 -2
  189. package/lib/util/deterministicGrouping.js +1 -1
  190. package/lib/util/extractUrlAndGlobal.js +3 -0
  191. package/lib/util/fs.js +11 -0
  192. package/lib/util/hash/BatchedHash.js +7 -4
  193. package/lib/util/hash/md4.js +20 -0
  194. package/lib/util/hash/wasm-hash.js +163 -0
  195. package/lib/util/hash/xxhash64.js +5 -139
  196. package/lib/util/identifier.js +65 -44
  197. package/lib/util/internalSerializables.js +15 -0
  198. package/lib/util/nonNumericOnlyHash.js +22 -0
  199. package/lib/util/semver.js +17 -10
  200. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +9 -3
  201. package/lib/wasm-sync/WebAssemblyParser.js +1 -1
  202. package/lib/web/JsonpChunkLoadingRuntimeModule.js +31 -18
  203. package/lib/webpack.js +10 -3
  204. package/lib/webworker/ImportScriptsChunkLoadingPlugin.js +3 -11
  205. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +33 -22
  206. package/module.d.ts +215 -0
  207. package/package.json +28 -32
  208. package/schemas/WebpackOptions.check.js +1 -1
  209. package/schemas/WebpackOptions.json +321 -30
  210. package/schemas/plugins/BannerPlugin.check.js +1 -1
  211. package/schemas/plugins/BannerPlugin.json +4 -0
  212. package/schemas/plugins/DllReferencePlugin.check.js +1 -1
  213. package/schemas/plugins/HashedModuleIdsPlugin.check.js +1 -1
  214. package/schemas/plugins/ProgressPlugin.check.js +1 -1
  215. package/schemas/plugins/asset/AssetGeneratorOptions.check.js +1 -1
  216. package/schemas/plugins/asset/AssetParserOptions.check.js +1 -1
  217. package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js +1 -1
  218. package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
  219. package/schemas/plugins/container/ContainerPlugin.json +2 -1
  220. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  221. package/schemas/plugins/container/ContainerReferencePlugin.json +1 -0
  222. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  223. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  224. package/schemas/plugins/container/ModuleFederationPlugin.json +3 -1
  225. package/schemas/plugins/css/CssGeneratorOptions.check.d.ts +7 -0
  226. package/schemas/plugins/css/CssGeneratorOptions.check.js +6 -0
  227. package/schemas/plugins/css/CssGeneratorOptions.json +3 -0
  228. package/schemas/plugins/css/CssParserOptions.check.d.ts +7 -0
  229. package/schemas/plugins/css/CssParserOptions.check.js +6 -0
  230. package/schemas/plugins/css/CssParserOptions.json +3 -0
  231. package/schemas/plugins/optimize/AggressiveSplittingPlugin.check.js +1 -1
  232. package/schemas/plugins/optimize/LimitChunkCountPlugin.check.js +1 -1
  233. package/schemas/plugins/optimize/MinChunkSizePlugin.check.js +1 -1
  234. package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
  235. package/schemas/plugins/schemes/HttpUriPlugin.json +4 -0
  236. package/types.d.ts +869 -296
@@ -7,6 +7,7 @@
7
7
 
8
8
  const makeSerializable = require("../util/makeSerializable");
9
9
  const HarmonyImportDependency = require("./HarmonyImportDependency");
10
+ const NullDependency = require("./NullDependency");
10
11
 
11
12
  /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
12
13
  /** @typedef {import("../Dependency")} Dependency */
@@ -28,8 +29,9 @@ makeSerializable(
28
29
  "webpack/lib/dependencies/HarmonyAcceptImportDependency"
29
30
  );
30
31
 
31
- HarmonyAcceptImportDependency.Template = class HarmonyAcceptImportDependencyTemplate extends (
32
- HarmonyImportDependency.Template
33
- ) {};
32
+ HarmonyAcceptImportDependency.Template =
33
+ /** @type {typeof HarmonyImportDependency.Template} */ (
34
+ NullDependency.Template
35
+ );
34
36
 
35
37
  module.exports = HarmonyAcceptImportDependency;
@@ -74,14 +74,14 @@ HarmonyCompatibilityDependency.Template = class HarmonyExportDependencyTemplate
74
74
  initFragments.push(
75
75
  new InitFragment(
76
76
  runtimeTemplate.supportsArrowFunction()
77
- ? `${RuntimeGlobals.asyncModule}(${module.moduleArgument}, async (__webpack_handle_async_dependencies__) => {\n`
78
- : `${RuntimeGlobals.asyncModule}(${module.moduleArgument}, async function (__webpack_handle_async_dependencies__) {\n`,
77
+ ? `${RuntimeGlobals.asyncModule}(${module.moduleArgument}, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {\n`
78
+ : `${RuntimeGlobals.asyncModule}(${module.moduleArgument}, async function (__webpack_handle_async_dependencies__, __webpack_async_result__) { try {\n`,
79
79
  InitFragment.STAGE_ASYNC_BOUNDARY,
80
80
  0,
81
81
  undefined,
82
- module.buildMeta.async
83
- ? `\n__webpack_handle_async_dependencies__();\n}, 1);`
84
- : "\n});"
82
+ `\n__webpack_async_result__();\n} catch(e) { __webpack_async_result__(e); } }${
83
+ module.buildMeta.async ? ", 1" : ""
84
+ });`
85
85
  )
86
86
  );
87
87
  }
@@ -0,0 +1,127 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Ivan Kopeykin @vankop
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const makeSerializable = require("../util/makeSerializable");
9
+ const HarmonyImportSpecifierDependency = require("./HarmonyImportSpecifierDependency");
10
+
11
+ /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
12
+ /** @typedef {import("../ChunkGraph")} ChunkGraph */
13
+ /** @typedef {import("../Dependency")} Dependency */
14
+ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
15
+
16
+ /**
17
+ * Dependency for static evaluating import specifier. e.g.
18
+ * @example
19
+ * import a from "a";
20
+ * "x" in a;
21
+ * a.x !== undefined; // if x value statically analyzable
22
+ */
23
+ class HarmonyEvaluatedImportSpecifierDependency extends HarmonyImportSpecifierDependency {
24
+ constructor(request, sourceOrder, ids, name, range, assertions, operator) {
25
+ super(request, sourceOrder, ids, name, range, false, assertions);
26
+ this.operator = operator;
27
+ }
28
+
29
+ get type() {
30
+ return `evaluated X ${this.operator} harmony import specifier`;
31
+ }
32
+
33
+ serialize(context) {
34
+ super.serialize(context);
35
+ const { write } = context;
36
+ write(this.operator);
37
+ }
38
+
39
+ deserialize(context) {
40
+ super.deserialize(context);
41
+ const { read } = context;
42
+ this.operator = read();
43
+ }
44
+ }
45
+
46
+ makeSerializable(
47
+ HarmonyEvaluatedImportSpecifierDependency,
48
+ "webpack/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency"
49
+ );
50
+
51
+ HarmonyEvaluatedImportSpecifierDependency.Template = class HarmonyEvaluatedImportSpecifierDependencyTemplate extends (
52
+ HarmonyImportSpecifierDependency.Template
53
+ ) {
54
+ /**
55
+ * @param {Dependency} dependency the dependency for which the template should be applied
56
+ * @param {ReplaceSource} source the current replace source which can be modified
57
+ * @param {DependencyTemplateContext} templateContext the context object
58
+ * @returns {void}
59
+ */
60
+ apply(dependency, source, templateContext) {
61
+ const dep = /** @type {HarmonyEvaluatedImportSpecifierDependency} */ (
62
+ dependency
63
+ );
64
+ const { module, moduleGraph, runtime } = templateContext;
65
+ const connection = moduleGraph.getConnection(dep);
66
+ // Skip rendering depending when dependency is conditional
67
+ if (connection && !connection.isTargetActive(runtime)) return;
68
+
69
+ const exportsInfo = moduleGraph.getExportsInfo(connection.module);
70
+ const ids = dep.getIds(moduleGraph);
71
+
72
+ let value;
73
+
74
+ const exportsType = connection.module.getExportsType(
75
+ moduleGraph,
76
+ module.buildMeta.strictHarmonyModule
77
+ );
78
+ switch (exportsType) {
79
+ case "default-with-named": {
80
+ if (ids[0] === "default") {
81
+ value =
82
+ ids.length === 1 || exportsInfo.isExportProvided(ids.slice(1));
83
+ } else {
84
+ value = exportsInfo.isExportProvided(ids);
85
+ }
86
+ break;
87
+ }
88
+ case "namespace": {
89
+ if (ids[0] === "__esModule") {
90
+ value = ids.length === 1 || undefined;
91
+ } else {
92
+ value = exportsInfo.isExportProvided(ids);
93
+ }
94
+ break;
95
+ }
96
+ case "dynamic": {
97
+ if (ids[0] !== "default") {
98
+ value = exportsInfo.isExportProvided(ids);
99
+ }
100
+ break;
101
+ }
102
+ // default-only could lead to runtime error, when default value is primitive
103
+ }
104
+
105
+ if (typeof value === "boolean") {
106
+ source.replace(dep.range[0], dep.range[1] - 1, ` ${value}`);
107
+ } else {
108
+ const usedName = exportsInfo.getUsedName(ids, runtime);
109
+
110
+ const code = this._getCodeForIds(
111
+ dep,
112
+ source,
113
+ templateContext,
114
+ ids.slice(0, -1)
115
+ );
116
+ source.replace(
117
+ dep.range[0],
118
+ dep.range[1] - 1,
119
+ `${
120
+ usedName ? JSON.stringify(usedName[usedName.length - 1]) : '""'
121
+ } in ${code}`
122
+ );
123
+ }
124
+ }
125
+ };
126
+
127
+ module.exports = HarmonyEvaluatedImportSpecifierDependency;
@@ -11,6 +11,7 @@ const HarmonyExportExpressionDependency = require("./HarmonyExportExpressionDepe
11
11
  const HarmonyExportHeaderDependency = require("./HarmonyExportHeaderDependency");
12
12
  const HarmonyExportImportedSpecifierDependency = require("./HarmonyExportImportedSpecifierDependency");
13
13
  const HarmonyExportSpecifierDependency = require("./HarmonyExportSpecifierDependency");
14
+ const { ExportPresenceModes } = require("./HarmonyImportDependency");
14
15
  const {
15
16
  harmonySpecifierTag,
16
17
  getAssertions
@@ -21,10 +22,18 @@ const { HarmonyStarExportsList } = HarmonyExportImportedSpecifierDependency;
21
22
 
22
23
  module.exports = class HarmonyExportDependencyParserPlugin {
23
24
  constructor(options) {
24
- this.strictExportPresence = options.strictExportPresence;
25
+ this.exportPresenceMode =
26
+ options.reexportExportsPresence !== undefined
27
+ ? ExportPresenceModes.fromUserOption(options.reexportExportsPresence)
28
+ : options.exportsPresence !== undefined
29
+ ? ExportPresenceModes.fromUserOption(options.exportsPresence)
30
+ : options.strictExportPresence
31
+ ? ExportPresenceModes.ERROR
32
+ : ExportPresenceModes.AUTO;
25
33
  }
26
34
 
27
35
  apply(parser) {
36
+ const { exportPresenceMode } = this;
28
37
  parser.hooks.export.tap(
29
38
  "HarmonyExportDependencyParserPlugin",
30
39
  statement => {
@@ -128,7 +137,7 @@ module.exports = class HarmonyExportDependencyParserPlugin {
128
137
  name,
129
138
  harmonyNamedExports,
130
139
  null,
131
- this.strictExportPresence,
140
+ exportPresenceMode,
132
141
  null,
133
142
  settings.assertions
134
143
  );
@@ -160,7 +169,7 @@ module.exports = class HarmonyExportDependencyParserPlugin {
160
169
  name,
161
170
  harmonyNamedExports,
162
171
  harmonyStarExports && harmonyStarExports.slice(),
163
- this.strictExportPresence,
172
+ exportPresenceMode,
164
173
  harmonyStarExports
165
174
  );
166
175
  if (harmonyStarExports) {
@@ -40,6 +40,8 @@ const processExportInfo = require("./processExportInfo");
40
40
 
41
41
  /** @typedef {"missing"|"unused"|"empty-star"|"reexport-dynamic-default"|"reexport-named-default"|"reexport-namespace-object"|"reexport-fake-namespace-object"|"reexport-undefined"|"normal-reexport"|"dynamic-reexport"} ExportModeType */
42
42
 
43
+ const { ExportPresenceModes } = HarmonyImportDependency;
44
+
43
45
  const idsSymbol = Symbol("HarmonyExportImportedSpecifierDependency.ids");
44
46
 
45
47
  class NormalReexportItem {
@@ -325,7 +327,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
325
327
  * @param {string | null} name the export name of for this module
326
328
  * @param {Set<string>} activeExports other named exports in the module
327
329
  * @param {ReadonlyArray<HarmonyExportImportedSpecifierDependency> | Iterable<HarmonyExportImportedSpecifierDependency>} otherStarExports other star exports in the module before this import
328
- * @param {boolean} strictExportPresence when true, missing exports in the imported module lead to errors instead of warnings
330
+ * @param {number} exportPresenceMode mode of checking export names
329
331
  * @param {HarmonyStarExportsList} allStarExports all star exports in the module
330
332
  * @param {Record<string, any>=} assertions import assertions
331
333
  */
@@ -336,7 +338,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
336
338
  name,
337
339
  activeExports,
338
340
  otherStarExports,
339
- strictExportPresence,
341
+ exportPresenceMode,
340
342
  allStarExports,
341
343
  assertions
342
344
  ) {
@@ -346,7 +348,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
346
348
  this.name = name;
347
349
  this.activeExports = activeExports;
348
350
  this.otherStarExports = otherStarExports;
349
- this.strictExportPresence = strictExportPresence;
351
+ this.exportPresenceMode = exportPresenceMode;
350
352
  this.allStarExports = allStarExports;
351
353
  }
352
354
 
@@ -735,20 +737,29 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
735
737
  }
736
738
  }
737
739
 
740
+ /**
741
+ * @param {ModuleGraph} moduleGraph module graph
742
+ * @returns {number} effective mode
743
+ */
744
+ _getEffectiveExportPresenceLevel(moduleGraph) {
745
+ if (this.exportPresenceMode !== ExportPresenceModes.AUTO)
746
+ return this.exportPresenceMode;
747
+ return moduleGraph.getParentModule(this).buildMeta.strictHarmonyModule
748
+ ? ExportPresenceModes.ERROR
749
+ : ExportPresenceModes.WARN;
750
+ }
751
+
738
752
  /**
739
753
  * Returns warnings
740
754
  * @param {ModuleGraph} moduleGraph module graph
741
755
  * @returns {WebpackError[]} warnings
742
756
  */
743
757
  getWarnings(moduleGraph) {
744
- if (
745
- this.strictExportPresence ||
746
- moduleGraph.getParentModule(this).buildMeta.strictHarmonyModule
747
- ) {
748
- return null;
758
+ const exportsPresence = this._getEffectiveExportPresenceLevel(moduleGraph);
759
+ if (exportsPresence === ExportPresenceModes.WARN) {
760
+ return this._getErrors(moduleGraph);
749
761
  }
750
-
751
- return this._getErrors(moduleGraph);
762
+ return null;
752
763
  }
753
764
 
754
765
  /**
@@ -757,13 +768,10 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
757
768
  * @returns {WebpackError[]} errors
758
769
  */
759
770
  getErrors(moduleGraph) {
760
- if (
761
- this.strictExportPresence ||
762
- moduleGraph.getParentModule(this).buildMeta.strictHarmonyModule
763
- ) {
771
+ const exportsPresence = this._getEffectiveExportPresenceLevel(moduleGraph);
772
+ if (exportsPresence === ExportPresenceModes.ERROR) {
764
773
  return this._getErrors(moduleGraph);
765
774
  }
766
-
767
775
  return null;
768
776
  }
769
777
 
@@ -856,7 +864,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
856
864
  write(this.name);
857
865
  write(this.activeExports);
858
866
  write(this.otherStarExports);
859
- write(this.strictExportPresence);
867
+ write(this.exportPresenceMode);
860
868
  write(this.allStarExports);
861
869
 
862
870
  super.serialize(context);
@@ -870,7 +878,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
870
878
  this.name = read();
871
879
  this.activeExports = read();
872
880
  this.otherStarExports = read();
873
- this.strictExportPresence = read();
881
+ this.exportPresenceMode = read();
874
882
  this.allStarExports = read();
875
883
 
876
884
  super.deserialize(context);
@@ -145,7 +145,10 @@ class HarmonyExportInitFragment extends InitFragment {
145
145
  ? `/* unused harmony export ${first(this.unusedExports)} */\n`
146
146
  : "";
147
147
  const definitions = [];
148
- for (const [key, value] of this.exportMap) {
148
+ const orderedExportMap = Array.from(this.exportMap).sort(([a], [b]) =>
149
+ a < b ? -1 : 1
150
+ );
151
+ for (const [key, value] of orderedExportMap) {
149
152
  definitions.push(
150
153
  `\n/* harmony export */ ${JSON.stringify(
151
154
  key
@@ -27,6 +27,27 @@ const ModuleDependency = require("./ModuleDependency");
27
27
  /** @typedef {import("../util/Hash")} Hash */
28
28
  /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
29
29
 
30
+ const ExportPresenceModes = {
31
+ NONE: /** @type {0} */ (0),
32
+ WARN: /** @type {1} */ (1),
33
+ AUTO: /** @type {2} */ (2),
34
+ ERROR: /** @type {3} */ (3),
35
+ fromUserOption(str) {
36
+ switch (str) {
37
+ case "error":
38
+ return ExportPresenceModes.ERROR;
39
+ case "warn":
40
+ return ExportPresenceModes.WARN;
41
+ case "auto":
42
+ return ExportPresenceModes.AUTO;
43
+ case false:
44
+ return ExportPresenceModes.NONE;
45
+ default:
46
+ throw new Error(`Invalid export presence value ${str}`);
47
+ }
48
+ }
49
+ };
50
+
30
51
  class HarmonyImportDependency extends ModuleDependency {
31
52
  /**
32
53
  *
@@ -334,3 +355,5 @@ HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate extends
334
355
  return emittedModules.get(referencedModule) || false;
335
356
  }
336
357
  };
358
+
359
+ module.exports.ExportPresenceModes = ExportPresenceModes;
@@ -10,7 +10,9 @@ const InnerGraph = require("../optimize/InnerGraph");
10
10
  const ConstDependency = require("./ConstDependency");
11
11
  const HarmonyAcceptDependency = require("./HarmonyAcceptDependency");
12
12
  const HarmonyAcceptImportDependency = require("./HarmonyAcceptImportDependency");
13
+ const HarmonyEvaluatedImportSpecifierDependency = require("./HarmonyEvaluatedImportSpecifierDependency");
13
14
  const HarmonyExports = require("./HarmonyExports");
15
+ const { ExportPresenceModes } = require("./HarmonyImportDependency");
14
16
  const HarmonyImportSideEffectDependency = require("./HarmonyImportSideEffectDependency");
15
17
  const HarmonyImportSpecifierDependency = require("./HarmonyImportSpecifierDependency");
16
18
 
@@ -19,6 +21,7 @@ const HarmonyImportSpecifierDependency = require("./HarmonyImportSpecifierDepend
19
21
  /** @typedef {import("estree").Identifier} Identifier */
20
22
  /** @typedef {import("estree").ImportDeclaration} ImportDeclaration */
21
23
  /** @typedef {import("estree").ImportExpression} ImportExpression */
24
+ /** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
22
25
  /** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
23
26
  /** @typedef {import("../optimize/InnerGraph").InnerGraph} InnerGraph */
24
27
  /** @typedef {import("../optimize/InnerGraph").TopLevelSymbol} TopLevelSymbol */
@@ -60,8 +63,18 @@ function getAssertions(node) {
60
63
  }
61
64
 
62
65
  module.exports = class HarmonyImportDependencyParserPlugin {
66
+ /**
67
+ * @param {JavascriptParserOptions} options options
68
+ */
63
69
  constructor(options) {
64
- this.strictExportPresence = options.strictExportPresence;
70
+ this.exportPresenceMode =
71
+ options.importExportsPresence !== undefined
72
+ ? ExportPresenceModes.fromUserOption(options.importExportsPresence)
73
+ : options.exportsPresence !== undefined
74
+ ? ExportPresenceModes.fromUserOption(options.exportsPresence)
75
+ : options.strictExportPresence
76
+ ? ExportPresenceModes.ERROR
77
+ : ExportPresenceModes.AUTO;
65
78
  this.strictThisContextOnImports = options.strictThisContextOnImports;
66
79
  }
67
80
 
@@ -70,6 +83,19 @@ module.exports = class HarmonyImportDependencyParserPlugin {
70
83
  * @returns {void}
71
84
  */
72
85
  apply(parser) {
86
+ const { exportPresenceMode } = this;
87
+
88
+ function getNonOptionalPart(members, membersOptionals) {
89
+ let i = 0;
90
+ while (i < members.length && membersOptionals[i] === false) i++;
91
+ return i !== members.length ? members.slice(0, i) : members;
92
+ }
93
+
94
+ function getNonOptionalMemberChain(node, count) {
95
+ while (count--) node = node.object;
96
+ return node;
97
+ }
98
+
73
99
  parser.hooks.isPure
74
100
  .for("Identifier")
75
101
  .tap("HarmonyImportDependencyParserPlugin", expression => {
@@ -118,74 +144,145 @@ module.exports = class HarmonyImportDependencyParserPlugin {
118
144
  return true;
119
145
  }
120
146
  );
121
- parser.hooks.expression
122
- .for(harmonySpecifierTag)
123
- .tap("HarmonyImportDependencyParserPlugin", expr => {
124
- const settings = /** @type {HarmonySettings} */ (parser.currentTagData);
125
- const dep = new HarmonyImportSpecifierDependency(
147
+ parser.hooks.binaryExpression.tap(
148
+ "HarmonyImportDependencyParserPlugin",
149
+ expression => {
150
+ if (expression.operator !== "in") return;
151
+
152
+ const leftPartEvaluated = parser.evaluateExpression(expression.left);
153
+ if (leftPartEvaluated.couldHaveSideEffects()) return;
154
+ const leftPart = leftPartEvaluated.asString();
155
+ if (!leftPart) return;
156
+
157
+ const rightPart = parser.evaluateExpression(expression.right);
158
+ if (!rightPart.isIdentifier()) return;
159
+
160
+ const rootInfo = rightPart.rootInfo;
161
+ if (
162
+ !rootInfo ||
163
+ !rootInfo.tagInfo ||
164
+ rootInfo.tagInfo.tag !== harmonySpecifierTag
165
+ )
166
+ return;
167
+ const settings = rootInfo.tagInfo.data;
168
+ const members = rightPart.getMembers();
169
+ const dep = new HarmonyEvaluatedImportSpecifierDependency(
126
170
  settings.source,
127
171
  settings.sourceOrder,
128
- settings.ids,
172
+ settings.ids.concat(members).concat([leftPart]),
129
173
  settings.name,
130
- expr.range,
131
- this.strictExportPresence,
132
- settings.assertions
174
+ expression.range,
175
+ settings.assertions,
176
+ "in"
133
177
  );
134
- dep.shorthand = parser.scope.inShorthand;
135
- dep.directImport = true;
136
- dep.asiSafe = !parser.isAsiPosition(expr.range[0]);
137
- dep.loc = expr.loc;
178
+ dep.directImport = members.length === 0;
179
+ dep.asiSafe = !parser.isAsiPosition(expression.range[0]);
180
+ dep.loc = expression.loc;
138
181
  parser.state.module.addDependency(dep);
139
182
  InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e));
140
183
  return true;
141
- });
142
- parser.hooks.expressionMemberChain
184
+ }
185
+ );
186
+ parser.hooks.expression
143
187
  .for(harmonySpecifierTag)
144
- .tap("HarmonyImportDependencyParserPlugin", (expr, members) => {
188
+ .tap("HarmonyImportDependencyParserPlugin", expr => {
145
189
  const settings = /** @type {HarmonySettings} */ (parser.currentTagData);
146
- const ids = settings.ids.concat(members);
147
190
  const dep = new HarmonyImportSpecifierDependency(
148
191
  settings.source,
149
192
  settings.sourceOrder,
150
- ids,
193
+ settings.ids,
151
194
  settings.name,
152
195
  expr.range,
153
- this.strictExportPresence,
196
+ exportPresenceMode,
154
197
  settings.assertions
155
198
  );
199
+ dep.shorthand = parser.scope.inShorthand;
200
+ dep.directImport = true;
156
201
  dep.asiSafe = !parser.isAsiPosition(expr.range[0]);
157
202
  dep.loc = expr.loc;
158
203
  parser.state.module.addDependency(dep);
159
204
  InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e));
160
205
  return true;
161
206
  });
207
+ parser.hooks.expressionMemberChain
208
+ .for(harmonySpecifierTag)
209
+ .tap(
210
+ "HarmonyImportDependencyParserPlugin",
211
+ (expression, members, membersOptionals) => {
212
+ const settings = /** @type {HarmonySettings} */ (
213
+ parser.currentTagData
214
+ );
215
+ const nonOptionalMembers = getNonOptionalPart(
216
+ members,
217
+ membersOptionals
218
+ );
219
+ const expr =
220
+ nonOptionalMembers !== members
221
+ ? getNonOptionalMemberChain(
222
+ expression,
223
+ members.length - nonOptionalMembers.length
224
+ )
225
+ : expression;
226
+ const ids = settings.ids.concat(nonOptionalMembers);
227
+ const dep = new HarmonyImportSpecifierDependency(
228
+ settings.source,
229
+ settings.sourceOrder,
230
+ ids,
231
+ settings.name,
232
+ expr.range,
233
+ exportPresenceMode,
234
+ settings.assertions
235
+ );
236
+ dep.asiSafe = !parser.isAsiPosition(expr.range[0]);
237
+ dep.loc = expr.loc;
238
+ parser.state.module.addDependency(dep);
239
+ InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e));
240
+ return true;
241
+ }
242
+ );
162
243
  parser.hooks.callMemberChain
163
244
  .for(harmonySpecifierTag)
164
- .tap("HarmonyImportDependencyParserPlugin", (expr, members) => {
165
- const { arguments: args, callee } = expr;
166
- const settings = /** @type {HarmonySettings} */ (parser.currentTagData);
167
- const ids = settings.ids.concat(members);
168
- const dep = new HarmonyImportSpecifierDependency(
169
- settings.source,
170
- settings.sourceOrder,
171
- ids,
172
- settings.name,
173
- callee.range,
174
- this.strictExportPresence,
175
- settings.assertions
176
- );
177
- dep.directImport = members.length === 0;
178
- dep.call = true;
179
- dep.asiSafe = !parser.isAsiPosition(callee.range[0]);
180
- // only in case when we strictly follow the spec we need a special case here
181
- dep.namespaceObjectAsContext =
182
- members.length > 0 && this.strictThisContextOnImports;
183
- dep.loc = callee.loc;
184
- parser.state.module.addDependency(dep);
185
- if (args) parser.walkExpressions(args);
186
- InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e));
187
- return true;
188
- });
245
+ .tap(
246
+ "HarmonyImportDependencyParserPlugin",
247
+ (expression, members, membersOptionals) => {
248
+ const { arguments: args, callee } = expression;
249
+ const settings = /** @type {HarmonySettings} */ (
250
+ parser.currentTagData
251
+ );
252
+ const nonOptionalMembers = getNonOptionalPart(
253
+ members,
254
+ membersOptionals
255
+ );
256
+ const expr =
257
+ nonOptionalMembers !== members
258
+ ? getNonOptionalMemberChain(
259
+ callee,
260
+ members.length - nonOptionalMembers.length
261
+ )
262
+ : callee;
263
+ const ids = settings.ids.concat(nonOptionalMembers);
264
+ const dep = new HarmonyImportSpecifierDependency(
265
+ settings.source,
266
+ settings.sourceOrder,
267
+ ids,
268
+ settings.name,
269
+ expr.range,
270
+ exportPresenceMode,
271
+ settings.assertions
272
+ );
273
+ dep.directImport = members.length === 0;
274
+ dep.call = true;
275
+ dep.asiSafe = !parser.isAsiPosition(expr.range[0]);
276
+ // only in case when we strictly follow the spec we need a special case here
277
+ dep.namespaceObjectAsContext =
278
+ members.length > 0 && this.strictThisContextOnImports;
279
+ dep.loc = expr.loc;
280
+ parser.state.module.addDependency(dep);
281
+ if (args) parser.walkExpressions(args);
282
+ InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e));
283
+ return true;
284
+ }
285
+ );
189
286
  const { hotAcceptCallback, hotAcceptWithoutCallback } =
190
287
  HotModuleReplacementPlugin.getParserHooks(parser);
191
288
  hotAcceptCallback.tap(