webpack 5.102.0 → 5.103.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 (146) hide show
  1. package/README.md +121 -134
  2. package/lib/ChunkGraph.js +2 -2
  3. package/lib/CodeGenerationResults.js +1 -1
  4. package/lib/CompatibilityPlugin.js +25 -2
  5. package/lib/Compilation.js +30 -13
  6. package/lib/ConcatenationScope.js +0 -15
  7. package/lib/ContextModule.js +3 -1
  8. package/lib/CssModule.js +6 -1
  9. package/lib/DefinePlugin.js +12 -12
  10. package/lib/Dependency.js +8 -1
  11. package/lib/DependencyTemplate.js +1 -0
  12. package/lib/DependencyTemplates.js +1 -1
  13. package/lib/DotenvPlugin.js +457 -0
  14. package/lib/EnvironmentPlugin.js +19 -16
  15. package/lib/EvalSourceMapDevToolPlugin.js +16 -0
  16. package/lib/ExportsInfo.js +6 -2
  17. package/lib/ExternalModule.js +20 -28
  18. package/lib/ExternalModuleFactoryPlugin.js +10 -8
  19. package/lib/ExternalsPlugin.js +2 -1
  20. package/lib/FileSystemInfo.js +9 -12
  21. package/lib/ManifestPlugin.js +235 -0
  22. package/lib/Module.js +3 -0
  23. package/lib/ModuleFilenameHelpers.js +1 -1
  24. package/lib/ModuleGraph.js +2 -1
  25. package/lib/ModuleSourceTypesConstants.js +0 -6
  26. package/lib/MultiCompiler.js +1 -1
  27. package/lib/NodeStuffPlugin.js +419 -121
  28. package/lib/NormalModule.js +18 -17
  29. package/lib/NormalModuleFactory.js +75 -4
  30. package/lib/RuntimeGlobals.js +22 -4
  31. package/lib/RuntimePlugin.js +27 -6
  32. package/lib/RuntimeTemplate.js +125 -57
  33. package/lib/SourceMapDevToolPlugin.js +26 -8
  34. package/lib/WebpackOptionsApply.js +33 -9
  35. package/lib/asset/AssetBytesGenerator.js +2 -1
  36. package/lib/asset/AssetGenerator.js +3 -5
  37. package/lib/asset/AssetSourceGenerator.js +1 -1
  38. package/lib/cache/getLazyHashedEtag.js +1 -1
  39. package/lib/config/browserslistTargetHandler.js +82 -76
  40. package/lib/config/defaults.js +105 -20
  41. package/lib/config/normalization.js +2 -1
  42. package/lib/config/target.js +7 -1
  43. package/lib/css/CssGenerator.js +283 -57
  44. package/lib/css/CssLoadingRuntimeModule.js +2 -0
  45. package/lib/css/CssMergeStyleSheetsRuntimeModule.js +56 -0
  46. package/lib/css/CssModulesPlugin.js +86 -40
  47. package/lib/css/CssParser.js +1174 -667
  48. package/lib/css/walkCssTokens.js +98 -1
  49. package/lib/dependencies/CommonJsImportsParserPlugin.js +0 -9
  50. package/lib/dependencies/CommonJsPlugin.js +12 -0
  51. package/lib/dependencies/ContextElementDependency.js +2 -2
  52. package/lib/dependencies/CssIcssExportDependency.js +247 -8
  53. package/lib/dependencies/CssIcssFromIdentifierDependency.js +124 -0
  54. package/lib/dependencies/CssIcssGlobalIdentifierDependency.js +48 -0
  55. package/lib/dependencies/CssIcssImportDependency.js +60 -54
  56. package/lib/dependencies/CssIcssLocalIdentifierDependency.js +61 -0
  57. package/lib/dependencies/{CssSelfLocalIdentifierDependency.js → CssIcssSelfLocalIdentifierDependency.js} +88 -10
  58. package/lib/dependencies/CssIcssSymbolDependency.js +31 -29
  59. package/lib/dependencies/CssImportDependency.js +15 -5
  60. package/lib/dependencies/ExternalModuleInitFragment.js +1 -1
  61. package/lib/dependencies/ExternalModuleInitFragmentDependency.js +95 -0
  62. package/lib/dependencies/HarmonyAcceptDependency.js +6 -1
  63. package/lib/dependencies/HarmonyAcceptImportDependency.js +2 -1
  64. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +12 -1
  65. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +32 -21
  66. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +12 -8
  67. package/lib/dependencies/HarmonyImportDependency.js +27 -28
  68. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +28 -69
  69. package/lib/dependencies/HarmonyImportSideEffectDependency.js +4 -3
  70. package/lib/dependencies/HarmonyImportSpecifierDependency.js +10 -8
  71. package/lib/dependencies/ImportContextDependency.js +13 -0
  72. package/lib/dependencies/ImportDependency.js +10 -4
  73. package/lib/dependencies/ImportEagerDependency.js +6 -3
  74. package/lib/dependencies/ImportMetaPlugin.js +98 -10
  75. package/lib/dependencies/ImportParserPlugin.js +19 -21
  76. package/lib/dependencies/ImportPhase.js +121 -0
  77. package/lib/dependencies/ImportWeakDependency.js +6 -3
  78. package/lib/dependencies/ModuleDependency.js +5 -1
  79. package/lib/dependencies/ModuleHotAcceptDependency.js +1 -1
  80. package/lib/dependencies/WorkerPlugin.js +1 -3
  81. package/lib/esm/ExportWebpackRequireRuntimeModule.js +1 -8
  82. package/lib/hmr/LazyCompilationPlugin.js +1 -0
  83. package/lib/ids/HashedModuleIdsPlugin.js +5 -7
  84. package/lib/ids/IdHelpers.js +5 -2
  85. package/lib/index.js +6 -0
  86. package/lib/javascript/ChunkHelpers.js +16 -5
  87. package/lib/javascript/JavascriptGenerator.js +101 -101
  88. package/lib/javascript/JavascriptModulesPlugin.js +25 -16
  89. package/lib/javascript/JavascriptParser.js +143 -39
  90. package/lib/json/JsonParser.js +7 -1
  91. package/lib/library/ModuleLibraryPlugin.js +0 -10
  92. package/lib/library/SystemLibraryPlugin.js +19 -5
  93. package/lib/library/UmdLibraryPlugin.js +1 -1
  94. package/lib/node/NodeTargetPlugin.js +9 -1
  95. package/lib/node/ReadFileCompileWasmPlugin.js +0 -2
  96. package/lib/optimize/ConcatenatedModule.js +161 -135
  97. package/lib/optimize/RealContentHashPlugin.js +5 -3
  98. package/lib/runtime/AsyncModuleRuntimeModule.js +28 -18
  99. package/lib/runtime/AutoPublicPathRuntimeModule.js +8 -3
  100. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +89 -55
  101. package/lib/serialization/FileMiddleware.js +1 -1
  102. package/lib/serialization/ObjectMiddleware.js +1 -1
  103. package/lib/stats/DefaultStatsFactoryPlugin.js +1 -1
  104. package/lib/util/Hash.js +35 -5
  105. package/lib/util/comparators.js +4 -3
  106. package/lib/util/create-schema-validation.js +1 -1
  107. package/lib/util/createHash.js +85 -15
  108. package/lib/util/hash/BatchedHash.js +47 -8
  109. package/lib/util/hash/wasm-hash.js +53 -13
  110. package/lib/util/internalSerializables.js +4 -4
  111. package/lib/util/jsonParseEvenBetterErrors.js +10 -0
  112. package/lib/wasm/EnableWasmLoadingPlugin.js +10 -4
  113. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +8 -5
  114. package/lib/wasm-async/AsyncWebAssemblyParser.js +0 -9
  115. package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +8 -4
  116. package/lib/wasm-sync/WebAssemblyParser.js +0 -9
  117. package/lib/web/FetchCompileWasmPlugin.js +0 -2
  118. package/lib/web/JsonpChunkLoadingRuntimeModule.js +1 -1
  119. package/lib/webpack.js +85 -82
  120. package/module.d.ts +5 -0
  121. package/package.json +28 -26
  122. package/schemas/WebpackOptions.check.js +1 -1
  123. package/schemas/WebpackOptions.json +110 -15
  124. package/schemas/plugins/{HashedModuleIdsPlugin.check.d.ts → ManifestPlugin.check.d.ts} +1 -1
  125. package/schemas/plugins/ManifestPlugin.check.js +6 -0
  126. package/schemas/plugins/ManifestPlugin.json +98 -0
  127. package/schemas/plugins/SourceMapDevToolPlugin.check.js +1 -1
  128. package/schemas/plugins/SourceMapDevToolPlugin.json +16 -3
  129. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  130. package/schemas/plugins/container/ContainerReferencePlugin.json +4 -1
  131. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  132. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  133. package/schemas/plugins/container/ModuleFederationPlugin.json +4 -1
  134. package/schemas/plugins/css/CssAutoParserOptions.check.js +1 -1
  135. package/schemas/plugins/css/CssGlobalGeneratorOptions.check.js +1 -1
  136. package/schemas/plugins/css/CssGlobalParserOptions.check.js +1 -1
  137. package/schemas/plugins/css/CssModuleGeneratorOptions.check.js +1 -1
  138. package/schemas/plugins/css/CssModuleParserOptions.check.js +1 -1
  139. package/schemas/plugins/css/CssParserOptions.check.js +1 -1
  140. package/schemas/plugins/ids/HashedModuleIdsPlugin.check.d.ts +7 -0
  141. package/schemas/plugins/ids/HashedModuleIdsPlugin.check.js +6 -0
  142. package/schemas/plugins/{HashedModuleIdsPlugin.json → ids/HashedModuleIdsPlugin.json} +15 -2
  143. package/schemas/plugins/json/JsonModulesPluginParser.check.js +1 -1
  144. package/types.d.ts +788 -127
  145. package/lib/dependencies/CssLocalIdentifierDependency.js +0 -252
  146. package/schemas/plugins/HashedModuleIdsPlugin.check.js +0 -6
@@ -9,6 +9,7 @@ const Template = require("../Template");
9
9
  const AwaitDependenciesInitFragment = require("../async-modules/AwaitDependenciesInitFragment");
10
10
  const makeSerializable = require("../util/makeSerializable");
11
11
  const HarmonyImportDependency = require("./HarmonyImportDependency");
12
+ const { ImportPhaseUtils } = require("./ImportPhase");
12
13
  const NullDependency = require("./NullDependency");
13
14
 
14
15
  /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
@@ -120,7 +121,11 @@ HarmonyAcceptDependency.Template = class HarmonyAcceptDependencyTemplate extends
120
121
  for (const d of module.dependencies) {
121
122
  if (deferDependency && noDeferredDependency) break;
122
123
  if (isRelatedHarmonyImportDependency(dependency, d)) {
123
- if (/** @type {HarmonyImportDependency} */ (d).defer) {
124
+ if (
125
+ ImportPhaseUtils.isDefer(
126
+ /** @type {HarmonyImportDependency} */ (d).phase
127
+ )
128
+ ) {
124
129
  deferDependency = /** @type {HarmonyImportDependency} */ (d);
125
130
  } else {
126
131
  noDeferredDependency = /** @type {HarmonyImportDependency} */ (d);
@@ -7,6 +7,7 @@
7
7
 
8
8
  const makeSerializable = require("../util/makeSerializable");
9
9
  const HarmonyImportDependency = require("./HarmonyImportDependency");
10
+ const { ImportPhase } = require("./ImportPhase");
10
11
  const NullDependency = require("./NullDependency");
11
12
 
12
13
  class HarmonyAcceptImportDependency extends HarmonyImportDependency {
@@ -14,7 +15,7 @@ class HarmonyAcceptImportDependency extends HarmonyImportDependency {
14
15
  * @param {string} request the request string
15
16
  */
16
17
  constructor(request) {
17
- super(request, Number.NaN);
18
+ super(request, Infinity, ImportPhase.Evaluation);
18
19
  this.weak = true;
19
20
  }
20
21
 
@@ -7,6 +7,7 @@
7
7
 
8
8
  const makeSerializable = require("../util/makeSerializable");
9
9
  const HarmonyImportSpecifierDependency = require("./HarmonyImportSpecifierDependency");
10
+ const { ImportPhase } = require("./ImportPhase");
10
11
 
11
12
  /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
12
13
  /** @typedef {import("../Dependency")} Dependency */
@@ -37,7 +38,17 @@ class HarmonyEvaluatedImportSpecifierDependency extends HarmonyImportSpecifierDe
37
38
  * @param {string} operator operator
38
39
  */
39
40
  constructor(request, sourceOrder, ids, name, range, attributes, operator) {
40
- super(request, sourceOrder, ids, name, range, false, attributes, []);
41
+ super(
42
+ request,
43
+ sourceOrder,
44
+ ids,
45
+ name,
46
+ range,
47
+ false,
48
+ ImportPhase.Evaluation,
49
+ attributes,
50
+ []
51
+ );
41
52
  this.operator = operator;
42
53
  }
43
54
 
@@ -5,6 +5,7 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ const CompatibilityPlugin = require("../CompatibilityPlugin");
8
9
  const WebpackError = require("../WebpackError");
9
10
  const { getImportAttributes } = require("../javascript/JavascriptParser");
10
11
  const InnerGraph = require("../optimize/InnerGraph");
@@ -15,10 +16,10 @@ const HarmonyExportImportedSpecifierDependency = require("./HarmonyExportImporte
15
16
  const HarmonyExportSpecifierDependency = require("./HarmonyExportSpecifierDependency");
16
17
  const { ExportPresenceModes } = require("./HarmonyImportDependency");
17
18
  const {
18
- getImportMode,
19
19
  harmonySpecifierTag
20
20
  } = require("./HarmonyImportDependencyParserPlugin");
21
21
  const HarmonyImportSideEffectDependency = require("./HarmonyImportSideEffectDependency");
22
+ const { ImportPhaseUtils, createGetImportPhase } = require("./ImportPhase");
22
23
 
23
24
  /** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
24
25
  /** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
@@ -26,6 +27,7 @@ const HarmonyImportSideEffectDependency = require("./HarmonyImportSideEffectDepe
26
27
  /** @typedef {import("../javascript/JavascriptParser").FunctionDeclaration} FunctionDeclaration */
27
28
  /** @typedef {import("../javascript/JavascriptParser").Range} Range */
28
29
  /** @typedef {import("./HarmonyImportDependencyParserPlugin").HarmonySettings} HarmonySettings */
30
+ /** @typedef {import("../CompatibilityPlugin").CompatibilitySettings} CompatibilitySettings */
29
31
 
30
32
  const { HarmonyStarExportsList } = HarmonyExportImportedSpecifierDependency;
31
33
 
@@ -36,6 +38,7 @@ module.exports = class HarmonyExportDependencyParserPlugin {
36
38
  * @param {import("../../declarations/WebpackOptions").JavascriptParserOptions} options options
37
39
  */
38
40
  constructor(options) {
41
+ this.options = options;
39
42
  this.exportPresenceMode =
40
43
  options.reexportExportsPresence !== undefined
41
44
  ? ExportPresenceModes.fromUserOption(options.reexportExportsPresence)
@@ -44,7 +47,6 @@ module.exports = class HarmonyExportDependencyParserPlugin {
44
47
  : options.strictExportPresence
45
48
  ? ExportPresenceModes.ERROR
46
49
  : ExportPresenceModes.AUTO;
47
- this.deferImport = options.deferImport;
48
50
  }
49
51
 
50
52
  /**
@@ -53,6 +55,8 @@ module.exports = class HarmonyExportDependencyParserPlugin {
53
55
  */
54
56
  apply(parser) {
55
57
  const { exportPresenceMode } = this;
58
+ const getImportPhase = createGetImportPhase(this.options.deferImport);
59
+
56
60
  parser.hooks.export.tap(PLUGIN_NAME, (statement) => {
57
61
  const dep = new HarmonyExportHeaderDependency(
58
62
  /** @type {Range | false} */ (
@@ -77,22 +81,20 @@ module.exports = class HarmonyExportDependencyParserPlugin {
77
81
  clearDep.loc = /** @type {DependencyLocation} */ (statement.loc);
78
82
  clearDep.loc.index = -1;
79
83
  parser.state.module.addPresentationalDependency(clearDep);
80
- let defer = false;
81
- if (this.deferImport) {
82
- ({ defer } = getImportMode(parser, statement));
83
- if (defer) {
84
- const error = new WebpackError(
85
- "Deferred re-export (`export defer * as namespace from '...'`) is not a part of the Import Defer proposal.\nUse the following code instead:\n import defer * as namespace from '...';\n export { namespace };"
86
- );
87
- error.loc = statement.loc || undefined;
88
- parser.state.current.addError(error);
89
- }
84
+
85
+ const phase = getImportPhase(parser, statement);
86
+ if (phase && ImportPhaseUtils.isDefer(phase)) {
87
+ const error = new WebpackError(
88
+ "Deferred re-export (`export defer * as namespace from '...'`) is not a part of the Import Defer proposal.\nUse the following code instead:\n import defer * as namespace from '...';\n export { namespace };"
89
+ );
90
+ error.loc = statement.loc || undefined;
91
+ parser.state.current.addError(error);
90
92
  }
91
93
  const sideEffectDep = new HarmonyImportSideEffectDependency(
92
94
  /** @type {string} */ (source),
93
95
  parser.state.lastHarmonyImportOrder,
94
- getImportAttributes(statement),
95
- defer
96
+ phase,
97
+ getImportAttributes(statement)
96
98
  );
97
99
  sideEffectDep.loc = Object.create(
98
100
  /** @type {DependencyLocation} */ (statement.loc)
@@ -157,6 +159,18 @@ module.exports = class HarmonyExportDependencyParserPlugin {
157
159
  parser.hooks.exportSpecifier.tap(
158
160
  PLUGIN_NAME,
159
161
  (statement, id, name, idx) => {
162
+ // CompatibilityPlugin may change exports name
163
+ // not handle re-export or import then export situation as current CompatibilityPlugin only
164
+ // rename symbol in declaration module, not change exported symbol
165
+ const variable = parser.getTagData(
166
+ id,
167
+ CompatibilityPlugin.nestedWebpackIdentifierTag
168
+ );
169
+ if (variable && /** @type {CompatibilitySettings} */ (variable).name) {
170
+ // CompatibilityPlugin changes exports to a new name, should updates exports name
171
+ id = /** @type {CompatibilitySettings} */ (variable).name;
172
+ }
173
+
160
174
  const settings =
161
175
  /** @type {HarmonySettings} */
162
176
  (parser.getTagData(id, harmonySpecifierTag));
@@ -174,8 +188,8 @@ module.exports = class HarmonyExportDependencyParserPlugin {
174
188
  null,
175
189
  exportPresenceMode,
176
190
  null,
177
- settings.attributes,
178
- settings.defer
191
+ settings.phase,
192
+ settings.attributes
179
193
  )
180
194
  : new HarmonyExportSpecifierDependency(id, name);
181
195
  dep.loc = Object.create(
@@ -207,9 +221,6 @@ module.exports = class HarmonyExportDependencyParserPlugin {
207
221
  parser.state.harmonyStarExports || new HarmonyStarExportsList();
208
222
  }
209
223
  const attributes = getImportAttributes(statement);
210
- const defer = this.deferImport
211
- ? getImportMode(parser, statement).defer
212
- : false;
213
224
  const dep = new HarmonyExportImportedSpecifierDependency(
214
225
  /** @type {string} */
215
226
  (source),
@@ -221,8 +232,8 @@ module.exports = class HarmonyExportDependencyParserPlugin {
221
232
  harmonyStarExports && harmonyStarExports.slice(),
222
233
  exportPresenceMode,
223
234
  harmonyStarExports,
224
- attributes,
225
- defer
235
+ getImportPhase(parser, statement),
236
+ attributes
226
237
  );
227
238
  if (harmonyStarExports) {
228
239
  harmonyStarExports.push(dep);
@@ -27,6 +27,7 @@ const {
27
27
  } = require("../util/runtime");
28
28
  const HarmonyExportInitFragment = require("./HarmonyExportInitFragment");
29
29
  const HarmonyImportDependency = require("./HarmonyImportDependency");
30
+ const { ImportPhaseUtils } = require("./ImportPhase");
30
31
  const processExportInfo = require("./processExportInfo");
31
32
 
32
33
  /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
@@ -57,6 +58,7 @@ const processExportInfo = require("./processExportInfo");
57
58
  /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
58
59
  /** @typedef {import("./HarmonyImportDependency").Ids} Ids */
59
60
  /** @typedef {import("./HarmonyImportDependency").ExportPresenceMode} ExportPresenceMode */
61
+ /** @typedef {import("../dependencies/ImportPhase").ImportPhaseType} ImportPhaseType */
60
62
 
61
63
  /** @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 */
62
64
 
@@ -376,8 +378,8 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
376
378
  * @param {ReadonlyArray<HarmonyExportImportedSpecifierDependency> | null} otherStarExports other star exports in the module before this import
377
379
  * @param {ExportPresenceMode} exportPresenceMode mode of checking export names
378
380
  * @param {HarmonyStarExportsList | null} allStarExports all star exports in the module
381
+ * @param {ImportPhaseType} phase import phase
379
382
  * @param {ImportAttributes=} attributes import attributes
380
- * @param {boolean=} defer is defer phase
381
383
  */
382
384
  constructor(
383
385
  request,
@@ -388,10 +390,10 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
388
390
  otherStarExports,
389
391
  exportPresenceMode,
390
392
  allStarExports,
391
- attributes,
392
- defer
393
+ phase,
394
+ attributes
393
395
  ) {
394
- super(request, sourceOrder, attributes, defer);
396
+ super(request, sourceOrder, phase, attributes);
395
397
 
396
398
  this.ids = ids;
397
399
  this.name = name;
@@ -1050,12 +1052,14 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS
1050
1052
  ) {
1051
1053
  const importedModule = /** @type {Module} */ (moduleGraph.getModule(dep));
1052
1054
  const importVar = dep.getImportVar(moduleGraph);
1055
+ const isDeferred =
1056
+ ImportPhaseUtils.isDefer(dep.phase) &&
1057
+ !(/** @type {BuildMeta} */ (importedModule.buildMeta).async);
1053
1058
 
1054
1059
  if (
1055
1060
  (mode.type === "reexport-namespace-object" ||
1056
1061
  mode.type === "reexport-fake-namespace-object") &&
1057
- dep.defer &&
1058
- !moduleGraph.isAsync(importedModule)
1062
+ isDeferred
1059
1063
  ) {
1060
1064
  initFragments.push(
1061
1065
  ...this.getReexportDeferredNamespaceObjectFragments(
@@ -1200,7 +1204,7 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS
1200
1204
  moduleGraph.isAsync(importedModule)
1201
1205
  ? InitFragment.STAGE_ASYNC_HARMONY_IMPORTS
1202
1206
  : InitFragment.STAGE_HARMONY_IMPORTS,
1203
- dep.sourceOrder,
1207
+ /** @type {number} */ (dep.sourceOrder),
1204
1208
  key,
1205
1209
  runtimeCondition
1206
1210
  )
@@ -1261,7 +1265,7 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS
1261
1265
  moduleGraph.isAsync(importedModule)
1262
1266
  ? InitFragment.STAGE_ASYNC_HARMONY_IMPORTS
1263
1267
  : InitFragment.STAGE_HARMONY_IMPORTS,
1264
- dep.sourceOrder
1268
+ /** @type {number} */ (dep.sourceOrder)
1265
1269
  )
1266
1270
  );
1267
1271
  break;
@@ -12,6 +12,7 @@ const InitFragment = require("../InitFragment");
12
12
  const Template = require("../Template");
13
13
  const AwaitDependenciesInitFragment = require("../async-modules/AwaitDependenciesInitFragment");
14
14
  const { filterRuntime, mergeRuntime } = require("../util/runtime");
15
+ const { ImportPhaseUtils } = require("./ImportPhase");
15
16
  const ModuleDependency = require("./ModuleDependency");
16
17
 
17
18
  /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
@@ -23,6 +24,7 @@ const ModuleDependency = require("./ModuleDependency");
23
24
  /** @typedef {import("../ModuleGraph")} ModuleGraph */
24
25
  /** @typedef {import("../WebpackError")} WebpackError */
25
26
  /** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */
27
+ /** @typedef {import("./ImportPhase").ImportPhaseType} ImportPhaseType */
26
28
  /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
27
29
  /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
28
30
  /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
@@ -60,14 +62,13 @@ class HarmonyImportDependency extends ModuleDependency {
60
62
  /**
61
63
  * @param {string} request request string
62
64
  * @param {number} sourceOrder source order
65
+ * @param {ImportPhaseType} phase import phase
63
66
  * @param {ImportAttributes=} attributes import attributes
64
- * @param {boolean=} defer import attributes
65
67
  */
66
- constructor(request, sourceOrder, attributes, defer) {
67
- super(request);
68
- this.sourceOrder = sourceOrder;
68
+ constructor(request, sourceOrder, phase, attributes) {
69
+ super(request, sourceOrder);
70
+ this.phase = phase;
69
71
  this.attributes = attributes;
70
- this.defer = defer;
71
72
  }
72
73
 
73
74
  get category() {
@@ -79,8 +80,11 @@ class HarmonyImportDependency extends ModuleDependency {
79
80
  */
80
81
  getResourceIdentifier() {
81
82
  let str = super.getResourceIdentifier();
82
- if (this.attributes !== undefined) {
83
- str += JSON.stringify(this.attributes);
83
+ if (ImportPhaseUtils.isDefer(this.phase)) {
84
+ str += "|defer";
85
+ }
86
+ if (this.attributes) {
87
+ str += `|importAttributes${JSON.stringify(this.attributes)}`;
84
88
  }
85
89
  return str;
86
90
  }
@@ -101,10 +105,14 @@ class HarmonyImportDependency extends ModuleDependency {
101
105
  */
102
106
  getImportVar(moduleGraph) {
103
107
  const module = /** @type {Module} */ (moduleGraph.getParentModule(this));
108
+ const importedModule = /** @type {Module} */ (moduleGraph.getModule(this));
104
109
  const meta = moduleGraph.getMeta(module);
105
- const defer = this.defer;
106
110
 
107
- const metaKey = defer ? "deferredImportVarMap" : "importVarMap";
111
+ const isDeferred =
112
+ ImportPhaseUtils.isDefer(this.phase) &&
113
+ !(/** @type {BuildMeta} */ (importedModule.buildMeta).async);
114
+
115
+ const metaKey = isDeferred ? "deferredImportVarMap" : "importVarMap";
108
116
  let importVarMap = meta[metaKey];
109
117
  if (!importVarMap) {
110
118
  meta[metaKey] = importVarMap =
@@ -112,19 +120,12 @@ class HarmonyImportDependency extends ModuleDependency {
112
120
  (new Map());
113
121
  }
114
122
 
115
- let importVar = importVarMap.get(
116
- /** @type {Module} */
117
- (moduleGraph.getModule(this))
118
- );
123
+ let importVar = importVarMap.get(importedModule);
119
124
  if (importVar) return importVar;
120
125
  importVar = `${Template.toIdentifier(
121
126
  `${this.userRequest}`
122
- )}__WEBPACK_${this.defer ? "DEFERRED_" : ""}IMPORTED_MODULE_${importVarMap.size}__`;
123
- importVarMap.set(
124
- /** @type {Module} */
125
- (moduleGraph.getModule(this)),
126
- importVar
127
- );
127
+ )}__WEBPACK_${isDeferred ? "DEFERRED_" : ""}IMPORTED_MODULE_${importVarMap.size}__`;
128
+ importVarMap.set(importedModule, importVar);
128
129
  return importVar;
129
130
  }
130
131
 
@@ -164,7 +165,7 @@ class HarmonyImportDependency extends ModuleDependency {
164
165
  request: this.request,
165
166
  originModule: module,
166
167
  runtimeRequirements,
167
- defer: this.defer
168
+ dependency: this
168
169
  });
169
170
  }
170
171
 
@@ -286,9 +287,8 @@ class HarmonyImportDependency extends ModuleDependency {
286
287
  */
287
288
  serialize(context) {
288
289
  const { write } = context;
289
- write(this.sourceOrder);
290
290
  write(this.attributes);
291
- write(this.defer);
291
+ write(this.phase);
292
292
  super.serialize(context);
293
293
  }
294
294
 
@@ -297,9 +297,8 @@ class HarmonyImportDependency extends ModuleDependency {
297
297
  */
298
298
  deserialize(context) {
299
299
  const { read } = context;
300
- this.sourceOrder = read();
301
300
  this.attributes = read();
302
- this.defer = read();
301
+ this.phase = read();
303
302
  super.deserialize(context);
304
303
  }
305
304
  }
@@ -341,7 +340,7 @@ HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate extends
341
340
  const moduleKey = referencedModule
342
341
  ? referencedModule.identifier()
343
342
  : dep.request;
344
- const key = `${dep.defer ? "deferred " : ""}harmony import ${moduleKey}`;
343
+ const key = `${ImportPhaseUtils.isDefer(dep.phase) ? "deferred " : ""}harmony import ${moduleKey}`;
345
344
 
346
345
  const runtimeCondition = dep.weak
347
346
  ? false
@@ -379,7 +378,7 @@ HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate extends
379
378
  new ConditionalInitFragment(
380
379
  importStatement[0],
381
380
  InitFragment.STAGE_HARMONY_IMPORTS,
382
- dep.sourceOrder,
381
+ /** @type {number} */ (dep.sourceOrder),
383
382
  key,
384
383
  runtimeCondition
385
384
  )
@@ -392,7 +391,7 @@ HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate extends
392
391
  new ConditionalInitFragment(
393
392
  importStatement[1],
394
393
  InitFragment.STAGE_ASYNC_HARMONY_IMPORTS,
395
- dep.sourceOrder,
394
+ /** @type {number} */ (dep.sourceOrder),
396
395
  `${key} compat`,
397
396
  runtimeCondition
398
397
  )
@@ -402,7 +401,7 @@ HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate extends
402
401
  new ConditionalInitFragment(
403
402
  importStatement[0] + importStatement[1],
404
403
  InitFragment.STAGE_HARMONY_IMPORTS,
405
- dep.sourceOrder,
404
+ /** @type {number} */ (dep.sourceOrder),
406
405
  key,
407
406
  runtimeCondition
408
407
  )
@@ -5,7 +5,6 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const CommentCompilationWarning = require("../CommentCompilationWarning");
9
8
  const HotModuleReplacementPlugin = require("../HotModuleReplacementPlugin");
10
9
  const WebpackError = require("../WebpackError");
11
10
  const {
@@ -21,6 +20,7 @@ const HarmonyExports = require("./HarmonyExports");
21
20
  const { ExportPresenceModes } = require("./HarmonyImportDependency");
22
21
  const HarmonyImportSideEffectDependency = require("./HarmonyImportSideEffectDependency");
23
22
  const HarmonyImportSpecifierDependency = require("./HarmonyImportSpecifierDependency");
23
+ const { ImportPhaseUtils, createGetImportPhase } = require("./ImportPhase");
24
24
 
25
25
  /** @typedef {import("estree").Expression} Expression */
26
26
  /** @typedef {import("estree").Identifier} Identifier */
@@ -36,6 +36,7 @@ const HarmonyImportSpecifierDependency = require("./HarmonyImportSpecifierDepend
36
36
  /** @typedef {import("../javascript/JavascriptParser").Members} Members */
37
37
  /** @typedef {import("../javascript/JavascriptParser").MembersOptionals} MembersOptionals */
38
38
  /** @typedef {import("./HarmonyImportDependency").Ids} Ids */
39
+ /** @typedef {import("./ImportPhase").ImportPhaseType} ImportPhaseType */
39
40
 
40
41
  const harmonySpecifierTag = Symbol("harmony import");
41
42
 
@@ -47,7 +48,7 @@ const harmonySpecifierTag = Symbol("harmony import");
47
48
  * @property {string} name
48
49
  * @property {boolean} await
49
50
  * @property {ImportAttributes=} attributes
50
- * @property {boolean | undefined} defer
51
+ * @property {ImportPhaseType} phase
51
52
  */
52
53
 
53
54
  const PLUGIN_NAME = "HarmonyImportDependencyParserPlugin";
@@ -57,6 +58,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
57
58
  * @param {JavascriptParserOptions} options options
58
59
  */
59
60
  constructor(options) {
61
+ this.options = options;
60
62
  this.exportPresenceMode =
61
63
  options.importExportsPresence !== undefined
62
64
  ? ExportPresenceModes.fromUserOption(options.importExportsPresence)
@@ -66,7 +68,6 @@ module.exports = class HarmonyImportDependencyParserPlugin {
66
68
  ? ExportPresenceModes.ERROR
67
69
  : ExportPresenceModes.AUTO;
68
70
  this.strictThisContextOnImports = options.strictThisContextOnImports;
69
- this.deferImport = options.deferImport;
70
71
  }
71
72
 
72
73
  /**
@@ -76,6 +77,8 @@ module.exports = class HarmonyImportDependencyParserPlugin {
76
77
  apply(parser) {
77
78
  const { exportPresenceMode } = this;
78
79
 
80
+ const getImportPhase = createGetImportPhase(this.options.deferImport);
81
+
79
82
  /**
80
83
  * @param {Members} members members
81
84
  * @param {MembersOptionals} membersOptionals members Optionals
@@ -119,26 +122,24 @@ module.exports = class HarmonyImportDependencyParserPlugin {
119
122
  parser.state.module.addPresentationalDependency(clearDep);
120
123
  parser.unsetAsiPosition(/** @type {Range} */ (statement.range)[1]);
121
124
  const attributes = getImportAttributes(statement);
122
- let defer = false;
123
- if (this.deferImport) {
124
- ({ defer } = getImportMode(parser, statement));
125
- if (
126
- defer &&
127
- (statement.specifiers.length !== 1 ||
128
- statement.specifiers[0].type !== "ImportNamespaceSpecifier")
129
- ) {
130
- const error = new WebpackError(
131
- "Deferred import can only be used with `import * as namespace from '...'` syntax."
132
- );
133
- error.loc = statement.loc || undefined;
134
- parser.state.current.addError(error);
135
- }
125
+ const phase = getImportPhase(parser, statement);
126
+ if (
127
+ ImportPhaseUtils.isDefer(phase) &&
128
+ (statement.specifiers.length !== 1 ||
129
+ statement.specifiers[0].type !== "ImportNamespaceSpecifier")
130
+ ) {
131
+ const error = new WebpackError(
132
+ "Deferred import can only be used with `import * as namespace from '...'` syntax."
133
+ );
134
+ error.loc = statement.loc || undefined;
135
+ parser.state.current.addError(error);
136
136
  }
137
+
137
138
  const sideEffectDep = new HarmonyImportSideEffectDependency(
138
139
  /** @type {string} */ (source),
139
140
  parser.state.lastHarmonyImportOrder,
140
- attributes,
141
- defer
141
+ phase,
142
+ attributes
142
143
  );
143
144
  sideEffectDep.loc = /** @type {DependencyLocation} */ (statement.loc);
144
145
  parser.state.module.addDependency(sideEffectDep);
@@ -148,9 +149,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
148
149
  PLUGIN_NAME,
149
150
  (statement, source, id, name) => {
150
151
  const ids = id === null ? [] : [id];
151
- const defer = this.deferImport
152
- ? getImportMode(parser, statement).defer
153
- : false;
152
+ const phase = getImportPhase(parser, statement);
154
153
  parser.tagVariable(
155
154
  name,
156
155
  harmonySpecifierTag,
@@ -160,7 +159,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
160
159
  ids,
161
160
  sourceOrder: parser.state.lastHarmonyImportOrder,
162
161
  attributes: getImportAttributes(statement),
163
- defer
162
+ phase
164
163
  })
165
164
  );
166
165
  return true;
@@ -237,9 +236,9 @@ module.exports = class HarmonyImportDependencyParserPlugin {
237
236
  /** @type {Range} */
238
237
  (expr.range),
239
238
  exportPresenceMode,
239
+ settings.phase,
240
240
  settings.attributes,
241
- [],
242
- settings.defer
241
+ []
243
242
  );
244
243
  dep.referencedPropertiesInDestructuring =
245
244
  parser.destructuringAssignmentPropertiesFor(expr);
@@ -287,9 +286,9 @@ module.exports = class HarmonyImportDependencyParserPlugin {
287
286
  /** @type {Range} */
288
287
  (expr.range),
289
288
  exportPresenceMode,
289
+ settings.phase,
290
290
  settings.attributes,
291
- ranges,
292
- settings.defer
291
+ ranges
293
292
  );
294
293
  dep.referencedPropertiesInDestructuring =
295
294
  parser.destructuringAssignmentPropertiesFor(expr);
@@ -337,9 +336,9 @@ module.exports = class HarmonyImportDependencyParserPlugin {
337
336
  settings.name,
338
337
  /** @type {Range} */ (expr.range),
339
338
  exportPresenceMode,
339
+ settings.phase,
340
340
  settings.attributes,
341
- ranges,
342
- settings.defer
341
+ ranges
343
342
  );
344
343
  dep.directImport = members.length === 0;
345
344
  dep.call = true;
@@ -406,44 +405,4 @@ module.exports = class HarmonyImportDependencyParserPlugin {
406
405
  }
407
406
  };
408
407
 
409
- /**
410
- * @param {JavascriptParser} parser parser
411
- * @param {ExportNamedDeclaration | ExportAllDeclaration | ImportDeclaration} node node
412
- * @returns {{ defer: boolean }} import attributes
413
- */
414
- function getImportMode(parser, node) {
415
- const result = { defer: "phase" in node && node.phase === "defer" };
416
- if (!node.range) {
417
- return result;
418
- }
419
- const { options, errors } = parser.parseCommentOptions(node.range);
420
- if (errors) {
421
- for (const e of errors) {
422
- const { comment } = e;
423
- if (!comment.loc) continue;
424
- parser.state.module.addWarning(
425
- new CommentCompilationWarning(
426
- `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
427
- comment.loc
428
- )
429
- );
430
- }
431
- }
432
- if (!options) return result;
433
- if (options.webpackDefer) {
434
- if (typeof options.webpackDefer === "boolean") {
435
- result.defer = options.webpackDefer;
436
- } else if (node.loc) {
437
- parser.state.module.addWarning(
438
- new CommentCompilationWarning(
439
- "webpackDefer magic comment expected a boolean value.",
440
- node.loc
441
- )
442
- );
443
- }
444
- }
445
- return result;
446
- }
447
-
448
- module.exports.getImportMode = getImportMode;
449
408
  module.exports.harmonySpecifierTag = harmonySpecifierTag;
@@ -16,16 +16,17 @@ const HarmonyImportDependency = require("./HarmonyImportDependency");
16
16
  /** @typedef {import("../ModuleGraph")} ModuleGraph */
17
17
  /** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */
18
18
  /** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */
19
+ /** @typedef {import("./ImportPhase").ImportPhaseType} ImportPhaseType */
19
20
 
20
21
  class HarmonyImportSideEffectDependency extends HarmonyImportDependency {
21
22
  /**
22
23
  * @param {string} request the request string
23
24
  * @param {number} sourceOrder source order
25
+ * @param {ImportPhaseType} phase import phase
24
26
  * @param {ImportAttributes=} attributes import attributes
25
- * @param {boolean=} defer is defer phase
26
27
  */
27
- constructor(request, sourceOrder, attributes, defer) {
28
- super(request, sourceOrder, attributes, defer);
28
+ constructor(request, sourceOrder, phase, attributes) {
29
+ super(request, sourceOrder, phase, attributes);
29
30
  }
30
31
 
31
32
  get type() {