webpack 5.102.1 → 5.104.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 (220) hide show
  1. package/README.md +121 -134
  2. package/hot/dev-server.js +18 -3
  3. package/hot/emitter-event-target.js +7 -0
  4. package/hot/lazy-compilation-node.js +45 -29
  5. package/hot/lazy-compilation-universal.js +18 -0
  6. package/hot/lazy-compilation-web.js +15 -5
  7. package/hot/load-http.js +7 -0
  8. package/hot/only-dev-server.js +19 -4
  9. package/lib/APIPlugin.js +6 -0
  10. package/lib/Chunk.js +1 -1
  11. package/lib/ChunkGraph.js +9 -7
  12. package/lib/ChunkGroup.js +8 -5
  13. package/lib/CleanPlugin.js +6 -3
  14. package/lib/CodeGenerationResults.js +2 -1
  15. package/lib/CompatibilityPlugin.js +28 -2
  16. package/lib/Compilation.js +58 -21
  17. package/lib/Compiler.js +3 -3
  18. package/lib/ConcatenationScope.js +0 -15
  19. package/lib/ContextModule.js +6 -3
  20. package/lib/ContextModuleFactory.js +6 -4
  21. package/lib/CssModule.js +6 -1
  22. package/lib/DefinePlugin.js +45 -14
  23. package/lib/DelegatedModule.js +7 -4
  24. package/lib/Dependency.js +8 -1
  25. package/lib/DependencyTemplate.js +1 -0
  26. package/lib/DllModule.js +6 -3
  27. package/lib/DotenvPlugin.js +462 -0
  28. package/lib/EnvironmentPlugin.js +19 -16
  29. package/lib/EvalSourceMapDevToolPlugin.js +16 -0
  30. package/lib/ExportsInfo.js +6 -2
  31. package/lib/ExternalModule.js +28 -35
  32. package/lib/ExternalModuleFactoryPlugin.js +11 -9
  33. package/lib/ExternalsPlugin.js +2 -1
  34. package/lib/FileSystemInfo.js +1 -1
  35. package/lib/Generator.js +10 -7
  36. package/lib/HookWebpackError.js +33 -4
  37. package/lib/HotModuleReplacementPlugin.js +22 -0
  38. package/lib/ManifestPlugin.js +235 -0
  39. package/lib/Module.js +27 -15
  40. package/lib/ModuleBuildError.js +1 -1
  41. package/lib/ModuleError.js +1 -1
  42. package/lib/ModuleFilenameHelpers.js +1 -1
  43. package/lib/ModuleGraph.js +29 -13
  44. package/lib/ModuleGraphConnection.js +2 -2
  45. package/lib/ModuleSourceTypeConstants.js +189 -0
  46. package/lib/ModuleTypeConstants.js +1 -4
  47. package/lib/ModuleWarning.js +1 -1
  48. package/lib/MultiCompiler.js +1 -1
  49. package/lib/NodeStuffPlugin.js +424 -116
  50. package/lib/NormalModule.js +23 -20
  51. package/lib/NormalModuleFactory.js +7 -10
  52. package/lib/Parser.js +1 -1
  53. package/lib/RawModule.js +7 -4
  54. package/lib/RuntimeGlobals.js +22 -4
  55. package/lib/RuntimeModule.js +1 -1
  56. package/lib/RuntimePlugin.js +27 -6
  57. package/lib/RuntimeTemplate.js +120 -57
  58. package/lib/SourceMapDevToolPlugin.js +26 -1
  59. package/lib/Template.js +17 -6
  60. package/lib/TemplatedPathPlugin.js +5 -6
  61. package/lib/WebpackError.js +0 -1
  62. package/lib/WebpackOptionsApply.js +67 -15
  63. package/lib/asset/AssetBytesGenerator.js +16 -12
  64. package/lib/asset/AssetGenerator.js +31 -26
  65. package/lib/asset/AssetSourceGenerator.js +16 -12
  66. package/lib/asset/RawDataUrlModule.js +6 -3
  67. package/lib/buildChunkGraph.js +4 -2
  68. package/lib/cache/PackFileCacheStrategy.js +6 -5
  69. package/lib/cli.js +2 -43
  70. package/lib/config/browserslistTargetHandler.js +24 -0
  71. package/lib/config/defaults.js +226 -61
  72. package/lib/config/normalization.js +4 -3
  73. package/lib/config/target.js +11 -0
  74. package/lib/container/ContainerEntryModule.js +6 -3
  75. package/lib/container/FallbackModule.js +6 -3
  76. package/lib/container/RemoteModule.js +1 -3
  77. package/lib/css/CssGenerator.js +304 -76
  78. package/lib/css/CssLoadingRuntimeModule.js +14 -4
  79. package/lib/css/CssMergeStyleSheetsRuntimeModule.js +56 -0
  80. package/lib/css/CssModulesPlugin.js +72 -67
  81. package/lib/css/CssParser.js +1726 -732
  82. package/lib/css/walkCssTokens.js +128 -11
  83. package/lib/dependencies/CachedConstDependency.js +24 -10
  84. package/lib/dependencies/CommonJsImportsParserPlugin.js +0 -9
  85. package/lib/dependencies/CommonJsPlugin.js +12 -0
  86. package/lib/dependencies/CommonJsRequireContextDependency.js +1 -1
  87. package/lib/dependencies/ContextDependencyHelpers.js +2 -2
  88. package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +3 -1
  89. package/lib/dependencies/CssIcssExportDependency.js +389 -12
  90. package/lib/dependencies/CssIcssImportDependency.js +114 -51
  91. package/lib/dependencies/CssIcssSymbolDependency.js +31 -33
  92. package/lib/dependencies/CssImportDependency.js +17 -6
  93. package/lib/dependencies/CssUrlDependency.js +3 -2
  94. package/lib/dependencies/DynamicExports.js +7 -7
  95. package/lib/dependencies/ExternalModuleDependency.js +7 -4
  96. package/lib/dependencies/ExternalModuleInitFragment.js +3 -2
  97. package/lib/dependencies/ExternalModuleInitFragmentDependency.js +96 -0
  98. package/lib/dependencies/HarmonyAcceptDependency.js +6 -1
  99. package/lib/dependencies/HarmonyAcceptImportDependency.js +2 -1
  100. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +12 -1
  101. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +35 -23
  102. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +13 -9
  103. package/lib/dependencies/HarmonyExports.js +4 -4
  104. package/lib/dependencies/HarmonyImportDependency.js +28 -27
  105. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +28 -69
  106. package/lib/dependencies/HarmonyImportSideEffectDependency.js +4 -3
  107. package/lib/dependencies/HarmonyImportSpecifierDependency.js +10 -8
  108. package/lib/dependencies/ImportDependency.js +8 -2
  109. package/lib/dependencies/ImportEagerDependency.js +6 -3
  110. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +1 -1
  111. package/lib/dependencies/ImportMetaPlugin.js +154 -9
  112. package/lib/dependencies/ImportParserPlugin.js +21 -23
  113. package/lib/dependencies/ImportPhase.js +121 -0
  114. package/lib/dependencies/ImportWeakDependency.js +6 -3
  115. package/lib/dependencies/LocalModulesHelpers.js +3 -3
  116. package/lib/dependencies/ModuleDependency.js +5 -1
  117. package/lib/dependencies/ModuleHotAcceptDependency.js +1 -1
  118. package/lib/dependencies/WorkerPlugin.js +2 -2
  119. package/lib/dependencies/getFunctionExpression.js +1 -1
  120. package/lib/esm/ExportWebpackRequireRuntimeModule.js +1 -8
  121. package/lib/esm/ModuleChunkFormatPlugin.js +5 -4
  122. package/lib/hmr/HotModuleReplacement.runtime.js +2 -1
  123. package/lib/hmr/LazyCompilationPlugin.js +5 -3
  124. package/lib/ids/IdHelpers.js +20 -8
  125. package/lib/index.js +6 -0
  126. package/lib/javascript/ChunkHelpers.js +16 -5
  127. package/lib/javascript/JavascriptGenerator.js +105 -104
  128. package/lib/javascript/JavascriptModulesPlugin.js +80 -37
  129. package/lib/javascript/JavascriptParser.js +161 -44
  130. package/lib/json/JsonGenerator.js +5 -4
  131. package/lib/json/JsonParser.js +9 -2
  132. package/lib/library/AbstractLibraryPlugin.js +1 -1
  133. package/lib/library/AmdLibraryPlugin.js +4 -1
  134. package/lib/library/ExportPropertyLibraryPlugin.js +4 -1
  135. package/lib/library/ModuleLibraryPlugin.js +41 -23
  136. package/lib/library/SystemLibraryPlugin.js +8 -1
  137. package/lib/library/UmdLibraryPlugin.js +2 -2
  138. package/lib/logging/Logger.js +5 -4
  139. package/lib/logging/createConsoleLogger.js +2 -2
  140. package/lib/node/NodeTargetPlugin.js +9 -1
  141. package/lib/node/ReadFileCompileWasmPlugin.js +0 -2
  142. package/lib/optimize/ConcatenatedModule.js +208 -167
  143. package/lib/optimize/ModuleConcatenationPlugin.js +5 -4
  144. package/lib/optimize/SideEffectsFlagPlugin.js +3 -2
  145. package/lib/optimize/SplitChunksPlugin.js +60 -46
  146. package/lib/rules/RuleSetCompiler.js +1 -1
  147. package/lib/runtime/AsyncModuleRuntimeModule.js +28 -18
  148. package/lib/runtime/AutoPublicPathRuntimeModule.js +8 -3
  149. package/lib/runtime/GetChunkFilenameRuntimeModule.js +3 -2
  150. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +89 -55
  151. package/lib/schemes/HttpUriPlugin.js +78 -7
  152. package/lib/serialization/AggregateErrorSerializer.js +1 -2
  153. package/lib/serialization/ObjectMiddleware.js +0 -2
  154. package/lib/serialization/SingleItemMiddleware.js +1 -1
  155. package/lib/sharing/ConsumeSharedModule.js +1 -1
  156. package/lib/sharing/ConsumeSharedPlugin.js +5 -3
  157. package/lib/sharing/ProvideSharedModule.js +1 -1
  158. package/lib/sharing/resolveMatchedConfigs.js +15 -9
  159. package/lib/sharing/utils.js +1 -1
  160. package/lib/stats/DefaultStatsFactoryPlugin.js +8 -5
  161. package/lib/stats/DefaultStatsPresetPlugin.js +1 -1
  162. package/lib/stats/DefaultStatsPrinterPlugin.js +1 -1
  163. package/lib/util/StringXor.js +1 -1
  164. package/lib/util/URLAbsoluteSpecifier.js +2 -2
  165. package/lib/util/binarySearchBounds.js +2 -2
  166. package/lib/util/comparators.js +54 -76
  167. package/lib/util/compileBooleanMatcher.js +78 -6
  168. package/lib/util/createHash.js +20 -199
  169. package/lib/util/deprecation.js +1 -1
  170. package/lib/util/deterministicGrouping.js +6 -3
  171. package/lib/util/fs.js +75 -75
  172. package/lib/util/hash/BatchedHash.js +10 -9
  173. package/lib/util/hash/BulkUpdateHash.js +138 -0
  174. package/lib/util/hash/DebugHash.js +75 -0
  175. package/lib/util/hash/hash-digest.js +216 -0
  176. package/lib/util/identifier.js +82 -17
  177. package/lib/util/internalSerializables.js +2 -6
  178. package/lib/util/runtime.js +3 -3
  179. package/lib/util/source.js +2 -2
  180. package/lib/wasm/EnableWasmLoadingPlugin.js +10 -4
  181. package/lib/wasm-async/AsyncWebAssemblyGenerator.js +3 -2
  182. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +11 -7
  183. package/lib/wasm-sync/WebAssemblyGenerator.js +9 -6
  184. package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +11 -6
  185. package/lib/wasm-sync/WebAssemblyModulesPlugin.js +6 -2
  186. package/lib/web/FetchCompileWasmPlugin.js +0 -2
  187. package/lib/webpack.js +85 -82
  188. package/module.d.ts +5 -0
  189. package/package.json +34 -28
  190. package/schemas/WebpackOptions.check.js +1 -1
  191. package/schemas/WebpackOptions.json +160 -101
  192. package/schemas/plugins/{css/CssAutoParserOptions.check.d.ts → ManifestPlugin.check.d.ts} +1 -1
  193. package/schemas/plugins/ManifestPlugin.check.js +6 -0
  194. package/schemas/plugins/ManifestPlugin.json +98 -0
  195. package/schemas/plugins/SourceMapDevToolPlugin.check.js +1 -1
  196. package/schemas/plugins/SourceMapDevToolPlugin.json +16 -3
  197. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  198. package/schemas/plugins/container/ContainerReferencePlugin.json +4 -1
  199. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  200. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  201. package/schemas/plugins/container/ModuleFederationPlugin.json +4 -1
  202. package/schemas/plugins/css/CssModuleGeneratorOptions.check.js +1 -1
  203. package/schemas/plugins/css/CssModuleParserOptions.check.js +1 -1
  204. package/schemas/plugins/css/CssParserOptions.check.js +1 -1
  205. package/schemas/plugins/json/JsonModulesPluginParser.check.js +1 -1
  206. package/types.d.ts +771 -436
  207. package/lib/ModuleSourceTypesConstants.js +0 -123
  208. package/lib/dependencies/CssLocalIdentifierDependency.js +0 -250
  209. package/lib/dependencies/CssSelfLocalIdentifierDependency.js +0 -112
  210. package/schemas/plugins/css/CssAutoGeneratorOptions.check.d.ts +0 -7
  211. package/schemas/plugins/css/CssAutoGeneratorOptions.check.js +0 -6
  212. package/schemas/plugins/css/CssAutoGeneratorOptions.json +0 -3
  213. package/schemas/plugins/css/CssAutoParserOptions.check.js +0 -6
  214. package/schemas/plugins/css/CssAutoParserOptions.json +0 -3
  215. package/schemas/plugins/css/CssGlobalGeneratorOptions.check.d.ts +0 -7
  216. package/schemas/plugins/css/CssGlobalGeneratorOptions.check.js +0 -6
  217. package/schemas/plugins/css/CssGlobalGeneratorOptions.json +0 -3
  218. package/schemas/plugins/css/CssGlobalParserOptions.check.d.ts +0 -7
  219. package/schemas/plugins/css/CssGlobalParserOptions.check.js +0 -6
  220. package/schemas/plugins/css/CssGlobalParserOptions.json +0 -3
@@ -15,6 +15,7 @@ const makeSerializable = require("../util/makeSerializable");
15
15
  const propertyAccess = require("../util/propertyAccess");
16
16
  const traverseDestructuringAssignmentProperties = require("../util/traverseDestructuringAssignmentProperties");
17
17
  const HarmonyImportDependency = require("./HarmonyImportDependency");
18
+ const { ImportPhaseUtils } = require("./ImportPhase");
18
19
 
19
20
  /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
20
21
  /** @typedef {import("../Dependency").GetConditionFn} GetConditionFn */
@@ -36,6 +37,7 @@ const HarmonyImportDependency = require("./HarmonyImportDependency");
36
37
  /** @typedef {import("../util/chainedImports").IdRanges} IdRanges */
37
38
  /** @typedef {import("./HarmonyImportDependency").ExportPresenceMode} ExportPresenceMode */
38
39
  /** @typedef {HarmonyImportDependency.Ids} Ids */
40
+ /** @typedef {import("./ImportPhase").ImportPhaseType} ImportPhaseType */
39
41
 
40
42
  const idsSymbol = Symbol("HarmonyImportSpecifierDependency.ids");
41
43
 
@@ -49,9 +51,9 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
49
51
  * @param {string} name name
50
52
  * @param {Range} range range
51
53
  * @param {ExportPresenceMode} exportPresenceMode export presence mode
54
+ * @param {ImportPhaseType} phase import phase
52
55
  * @param {ImportAttributes | undefined} attributes import attributes
53
56
  * @param {IdRanges | undefined} idRanges ranges for members of ids; the two arrays are right-aligned
54
- * @param {boolean=} defer is defer phase
55
57
  */
56
58
  constructor(
57
59
  request,
@@ -60,11 +62,11 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
60
62
  name,
61
63
  range,
62
64
  exportPresenceMode,
65
+ phase,
63
66
  attributes,
64
- idRanges, // TODO webpack 6 make this non-optional. It must always be set to properly trim ids.
65
- defer
67
+ idRanges // TODO webpack 6 make this non-optional. It must always be set to properly trim ids.
66
68
  ) {
67
- super(request, sourceOrder, attributes, defer);
69
+ super(request, sourceOrder, phase, attributes);
68
70
  this.ids = ids;
69
71
  this.name = name;
70
72
  this.range = range;
@@ -440,14 +442,14 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen
440
442
  connection.module,
441
443
  {
442
444
  asiSafe: dep.asiSafe,
443
- deferredImport: dep.defer
445
+ deferredImport: ImportPhaseUtils.isDefer(dep.phase)
444
446
  }
445
447
  );
446
448
  } else if (dep.namespaceObjectAsContext && ids.length === 1) {
447
449
  exportExpr =
448
450
  concatenationScope.createModuleReference(connection.module, {
449
451
  asiSafe: dep.asiSafe,
450
- deferredImport: dep.defer
452
+ deferredImport: ImportPhaseUtils.isDefer(dep.phase)
451
453
  }) + propertyAccess(ids);
452
454
  } else {
453
455
  exportExpr = concatenationScope.createModuleReference(
@@ -457,7 +459,7 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen
457
459
  call: dep.call,
458
460
  directImport: dep.directImport,
459
461
  asiSafe: dep.asiSafe,
460
- deferredImport: dep.defer
462
+ deferredImport: ImportPhaseUtils.isDefer(dep.phase)
461
463
  }
462
464
  );
463
465
  }
@@ -482,7 +484,7 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen
482
484
  initFragments,
483
485
  runtime,
484
486
  runtimeRequirements,
485
- defer: dep.defer
487
+ dependency: dep
486
488
  });
487
489
  }
488
490
  return exportExpr;
@@ -22,18 +22,21 @@ const ModuleDependency = require("./ModuleDependency");
22
22
  /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
23
23
  /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
24
24
  /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
25
+ /** @typedef {import("./ImportPhase").ImportPhaseType} ImportPhaseType */
25
26
 
26
27
  class ImportDependency extends ModuleDependency {
27
28
  /**
28
29
  * @param {string} request the request
29
30
  * @param {Range} range expression range
30
- * @param {RawReferencedExports | null=} referencedExports list of referenced exports
31
+ * @param {RawReferencedExports | null} referencedExports list of referenced exports
32
+ * @param {ImportPhaseType} phase import phase
31
33
  * @param {ImportAttributes=} attributes import attributes
32
34
  */
33
- constructor(request, range, referencedExports, attributes) {
35
+ constructor(request, range, referencedExports, phase, attributes) {
34
36
  super(request);
35
37
  this.range = range;
36
38
  this.referencedExports = referencedExports;
39
+ this.phase = phase;
37
40
  this.attributes = attributes;
38
41
  }
39
42
 
@@ -99,6 +102,7 @@ class ImportDependency extends ModuleDependency {
99
102
  serialize(context) {
100
103
  context.write(this.range);
101
104
  context.write(this.referencedExports);
105
+ context.write(this.phase);
102
106
  context.write(this.attributes);
103
107
  super.serialize(context);
104
108
  }
@@ -109,6 +113,7 @@ class ImportDependency extends ModuleDependency {
109
113
  deserialize(context) {
110
114
  this.range = context.read();
111
115
  this.referencedExports = context.read();
116
+ this.phase = context.read();
112
117
  this.attributes = context.read();
113
118
  super.deserialize(context);
114
119
  }
@@ -140,6 +145,7 @@ ImportDependency.Template = class ImportDependencyTemplate extends (
140
145
  module: /** @type {Module} */ (moduleGraph.getModule(dep)),
141
146
  request: dep.request,
142
147
  strict: /** @type {BuildMeta} */ (module.buildMeta).strictHarmonyModule,
148
+ dependency: dep,
143
149
  message: "import()",
144
150
  runtimeRequirements
145
151
  });
@@ -16,16 +16,18 @@ const ImportDependency = require("./ImportDependency");
16
16
  /** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */
17
17
  /** @typedef {import("../javascript/JavascriptParser").Range} Range */
18
18
  /** @typedef {ImportDependency.RawReferencedExports} RawReferencedExports */
19
+ /** @typedef {import("./ImportPhase").ImportPhaseType} ImportPhaseType */
19
20
 
20
21
  class ImportEagerDependency extends ImportDependency {
21
22
  /**
22
23
  * @param {string} request the request
23
24
  * @param {Range} range expression range
24
- * @param {RawReferencedExports | null=} referencedExports list of referenced exports
25
+ * @param {RawReferencedExports | null} referencedExports list of referenced exports
26
+ * @param {ImportPhaseType} phase import phase
25
27
  * @param {ImportAttributes=} attributes import attributes
26
28
  */
27
- constructor(request, range, referencedExports, attributes) {
28
- super(request, range, referencedExports, attributes);
29
+ constructor(request, range, referencedExports, phase, attributes) {
30
+ super(request, range, referencedExports, phase, attributes);
29
31
  }
30
32
 
31
33
  get type() {
@@ -63,6 +65,7 @@ ImportEagerDependency.Template = class ImportEagerDependencyTemplate extends (
63
65
  request: dep.request,
64
66
  strict: /** @type {BuildMeta} */ (module.buildMeta).strictHarmonyModule,
65
67
  message: "import() eager",
68
+ dependency: dep,
66
69
  runtimeRequirements
67
70
  });
68
71
 
@@ -25,7 +25,7 @@ const ImportMetaContextDependency = require("./ImportMetaContextDependency");
25
25
  /** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
26
26
  /** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */
27
27
 
28
- /** @typedef {Pick<ContextModuleOptions, 'mode' | 'recursive' | 'regExp' | 'include' | 'exclude' | 'chunkName'> & { groupOptions: RawChunkGroupOptions, exports?: RawReferencedExports }} ImportMetaContextOptions */
28
+ /** @typedef {Pick<ContextModuleOptions, "mode" | "recursive" | "regExp" | "include" | "exclude" | "chunkName"> & { groupOptions: RawChunkGroupOptions, exports?: RawReferencedExports }} ImportMetaContextOptions */
29
29
 
30
30
  /**
31
31
  * @param {Property} prop property
@@ -6,11 +6,15 @@
6
6
  "use strict";
7
7
 
8
8
  const { pathToFileURL } = require("url");
9
+ const { SyncBailHook } = require("tapable");
10
+ const Compilation = require("../Compilation");
11
+ const DefinePlugin = require("../DefinePlugin");
9
12
  const ModuleDependencyWarning = require("../ModuleDependencyWarning");
10
13
  const {
11
14
  JAVASCRIPT_MODULE_TYPE_AUTO,
12
15
  JAVASCRIPT_MODULE_TYPE_ESM
13
16
  } = require("../ModuleTypeConstants");
17
+ const RuntimeGlobals = require("../RuntimeGlobals");
14
18
  const Template = require("../Template");
15
19
  const BasicEvaluatedExpression = require("../javascript/BasicEvaluatedExpression");
16
20
  const {
@@ -31,6 +35,8 @@ const ConstDependency = require("./ConstDependency");
31
35
  /** @typedef {import("../javascript/JavascriptParser")} Parser */
32
36
  /** @typedef {import("../javascript/JavascriptParser").Range} Range */
33
37
  /** @typedef {import("../javascript/JavascriptParser").Members} Members */
38
+ /** @typedef {import("../javascript/JavascriptParser").DestructuringAssignmentProperty} DestructuringAssignmentProperty */
39
+ /** @typedef {import("./ConstDependency").RawRuntimeRequirements} RawRuntimeRequirements */
34
40
 
35
41
  const getCriticalDependencyWarning = memoize(() =>
36
42
  require("./CriticalDependencyWarning")
@@ -38,7 +44,60 @@ const getCriticalDependencyWarning = memoize(() =>
38
44
 
39
45
  const PLUGIN_NAME = "ImportMetaPlugin";
40
46
 
47
+ /**
48
+ * Collect import.meta.env definitions from DefinePlugin and build JSON string
49
+ * @param {Compilation} compilation the compilation
50
+ * @returns {string} env object as JSON string
51
+ */
52
+ const collectImportMetaEnvDefinitions = (compilation) => {
53
+ const definePluginHooks = DefinePlugin.getCompilationHooks(compilation);
54
+ const definitions = definePluginHooks.definitions.call({});
55
+ if (!definitions) {
56
+ return "{}";
57
+ }
58
+
59
+ /** @type {string[]} */
60
+ const pairs = [];
61
+ for (const key of Object.keys(definitions)) {
62
+ if (key.startsWith("import.meta.env.")) {
63
+ const envKey = key.slice("import.meta.env.".length);
64
+ const value = definitions[key];
65
+ pairs.push(`${JSON.stringify(envKey)}:${value}`);
66
+ }
67
+ }
68
+
69
+ return `{${pairs.join(",")}}`;
70
+ };
71
+
72
+ /**
73
+ * @typedef {object} ImportMetaPluginHooks
74
+ * @property {SyncBailHook<[DestructuringAssignmentProperty], string | void>} propertyInDestructuring
75
+ */
76
+
77
+ /** @type {WeakMap<Compilation, ImportMetaPluginHooks>} */
78
+ const compilationHooksMap = new WeakMap();
79
+
41
80
  class ImportMetaPlugin {
81
+ /**
82
+ * @param {Compilation} compilation the compilation
83
+ * @returns {ImportMetaPluginHooks} the attached hooks
84
+ */
85
+ static getCompilationHooks(compilation) {
86
+ if (!(compilation instanceof Compilation)) {
87
+ throw new TypeError(
88
+ "The 'compilation' argument must be an instance of Compilation"
89
+ );
90
+ }
91
+ let hooks = compilationHooksMap.get(compilation);
92
+ if (hooks === undefined) {
93
+ hooks = {
94
+ propertyInDestructuring: new SyncBailHook(["property"])
95
+ };
96
+ compilationHooksMap.set(compilation, hooks);
97
+ }
98
+ return hooks;
99
+ }
100
+
42
101
  /**
43
102
  * @param {Compiler} compiler compiler
44
103
  */
@@ -46,6 +105,8 @@ class ImportMetaPlugin {
46
105
  compiler.hooks.compilation.tap(
47
106
  PLUGIN_NAME,
48
107
  (compilation, { normalModuleFactory }) => {
108
+ const hooks = ImportMetaPlugin.getCompilationHooks(compilation);
109
+
49
110
  /**
50
111
  * @param {NormalModule} module module
51
112
  * @returns {string} file url
@@ -135,25 +196,44 @@ class ImportMetaPlugin {
135
196
  return true;
136
197
  }
137
198
 
199
+ /** @type {RawRuntimeRequirements} */
200
+ const runtimeRequirements = [];
201
+
138
202
  let str = "";
139
- for (const { id: prop } of referencedPropertiesInDestructuring) {
140
- switch (prop) {
203
+ for (const prop of referencedPropertiesInDestructuring) {
204
+ const value = hooks.propertyInDestructuring.call(prop);
205
+
206
+ if (value) {
207
+ str += value;
208
+ continue;
209
+ }
210
+
211
+ switch (prop.id) {
141
212
  case "url":
142
213
  str += `url: ${importMetaUrl()},`;
143
214
  break;
144
215
  case "webpack":
145
216
  str += `webpack: ${importMetaWebpackVersion()},`;
146
217
  break;
218
+ case "main":
219
+ str += `main: ${RuntimeGlobals.moduleCache}[${RuntimeGlobals.entryModuleId}] === ${RuntimeGlobals.module},`;
220
+ runtimeRequirements.push(
221
+ RuntimeGlobals.moduleCache,
222
+ RuntimeGlobals.entryModuleId,
223
+ RuntimeGlobals.module
224
+ );
225
+ break;
147
226
  default:
148
227
  str += `[${JSON.stringify(
149
- prop
150
- )}]: ${importMetaUnknownProperty([prop])},`;
228
+ prop.id
229
+ )}]: ${importMetaUnknownProperty([prop.id])},`;
151
230
  break;
152
231
  }
153
232
  }
154
233
  const dep = new ConstDependency(
155
234
  `({${str}})`,
156
- /** @type {Range} */ (metaProperty.range)
235
+ /** @type {Range} */ (metaProperty.range),
236
+ runtimeRequirements
157
237
  );
158
238
  dep.loc = /** @type {DependencyLocation} */ (metaProperty.loc);
159
239
  parser.state.module.addPresentationalDependency(dep);
@@ -197,17 +277,17 @@ class ImportMetaPlugin {
197
277
  );
198
278
 
199
279
  // import.meta.webpack
200
- parser.hooks.typeof
280
+ parser.hooks.expression
201
281
  .for("import.meta.webpack")
202
282
  .tap(
203
283
  PLUGIN_NAME,
204
- toConstantDependency(parser, JSON.stringify("number"))
284
+ toConstantDependency(parser, importMetaWebpackVersion())
205
285
  );
206
- parser.hooks.expression
286
+ parser.hooks.typeof
207
287
  .for("import.meta.webpack")
208
288
  .tap(
209
289
  PLUGIN_NAME,
210
- toConstantDependency(parser, importMetaWebpackVersion())
290
+ toConstantDependency(parser, JSON.stringify("number"))
211
291
  );
212
292
  parser.hooks.evaluateTypeof
213
293
  .for("import.meta.webpack")
@@ -216,10 +296,75 @@ class ImportMetaPlugin {
216
296
  .for("import.meta.webpack")
217
297
  .tap(PLUGIN_NAME, evaluateToNumber(webpackVersion));
218
298
 
299
+ parser.hooks.expression
300
+ .for("import.meta.main")
301
+ .tap(
302
+ PLUGIN_NAME,
303
+ toConstantDependency(
304
+ parser,
305
+ `${RuntimeGlobals.moduleCache}[${RuntimeGlobals.entryModuleId}] === ${RuntimeGlobals.module}`,
306
+ [
307
+ RuntimeGlobals.moduleCache,
308
+ RuntimeGlobals.entryModuleId,
309
+ RuntimeGlobals.module
310
+ ]
311
+ )
312
+ );
313
+ parser.hooks.typeof
314
+ .for("import.meta.main")
315
+ .tap(
316
+ PLUGIN_NAME,
317
+ toConstantDependency(parser, JSON.stringify("boolean"))
318
+ );
319
+ parser.hooks.evaluateTypeof
320
+ .for("import.meta.main")
321
+ .tap(PLUGIN_NAME, evaluateToString("boolean"));
322
+
323
+ // import.meta.env
324
+ parser.hooks.typeof
325
+ .for("import.meta.env")
326
+ .tap(
327
+ PLUGIN_NAME,
328
+ toConstantDependency(parser, JSON.stringify("object"))
329
+ );
330
+ parser.hooks.expression
331
+ .for("import.meta.env")
332
+ .tap(PLUGIN_NAME, (expr) => {
333
+ const envCode = collectImportMetaEnvDefinitions(compilation);
334
+ const dep = new ConstDependency(
335
+ envCode,
336
+ /** @type {Range} */ (expr.range)
337
+ );
338
+ dep.loc = /** @type {DependencyLocation} */ (expr.loc);
339
+ parser.state.module.addPresentationalDependency(dep);
340
+ return true;
341
+ });
342
+ parser.hooks.evaluateTypeof
343
+ .for("import.meta.env")
344
+ .tap(PLUGIN_NAME, evaluateToString("object"));
345
+ parser.hooks.evaluateIdentifier
346
+ .for("import.meta.env")
347
+ .tap(PLUGIN_NAME, (expr) =>
348
+ new BasicEvaluatedExpression()
349
+ .setTruthy()
350
+ .setSideEffects(false)
351
+ .setRange(/** @type {Range} */ (expr.range))
352
+ );
353
+
219
354
  // Unknown properties
220
355
  parser.hooks.unhandledExpressionMemberChain
221
356
  .for("import.meta")
222
357
  .tap(PLUGIN_NAME, (expr, members) => {
358
+ // keep import.meta.env unknown property
359
+ // don't evaluate import.meta.env.UNKNOWN_PROPERTY -> undefined.UNKNOWN_PROPERTY
360
+ // `dirname` and `filename` logic in NodeStuffPlugin
361
+ if (
362
+ members[0] === "env" ||
363
+ members[0] === "dirname" ||
364
+ members[0] === "filename"
365
+ ) {
366
+ return true;
367
+ }
223
368
  const dep = new ConstDependency(
224
369
  importMetaUnknownProperty(members),
225
370
  /** @type {Range} */ (expr.range)
@@ -17,6 +17,7 @@ const ContextDependencyHelpers = require("./ContextDependencyHelpers");
17
17
  const ImportContextDependency = require("./ImportContextDependency");
18
18
  const ImportDependency = require("./ImportDependency");
19
19
  const ImportEagerDependency = require("./ImportEagerDependency");
20
+ const { ImportPhaseUtils, createGetImportPhase } = require("./ImportPhase");
20
21
  const ImportWeakDependency = require("./ImportWeakDependency");
21
22
 
22
23
  /** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
@@ -28,7 +29,7 @@ const ImportWeakDependency = require("./ImportWeakDependency");
28
29
  /** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
29
30
  /** @typedef {import("../javascript/JavascriptParser").ImportExpression} ImportExpression */
30
31
  /** @typedef {import("../javascript/JavascriptParser").Range} Range */
31
- /** @typedef {import("../javascript/JavascriptParser").ParserState} ParserState */
32
+ /** @typedef {import("../javascript/JavascriptParser").JavascriptParserState} JavascriptParserState */
32
33
  /** @typedef {import("../javascript/JavascriptParser").Members} Members */
33
34
  /** @typedef {import("../javascript/JavascriptParser").MembersOptionals} MembersOptionals */
34
35
  /** @typedef {import("../javascript/JavascriptParser").ArrowFunctionExpression} ArrowFunctionExpression */
@@ -40,7 +41,7 @@ const ImportWeakDependency = require("./ImportWeakDependency");
40
41
  /** @typedef {{ references: RawReferencedExports, expression: ImportExpression }} ImportSettings */
41
42
  /** @typedef {WeakMap<ImportExpression, RawReferencedExports>} State */
42
43
 
43
- /** @type {WeakMap<ParserState, State>} */
44
+ /** @type {WeakMap<JavascriptParserState, State>} */
44
45
  const parserStateMap = new WeakMap();
45
46
  const dynamicImportTag = Symbol("import()");
46
47
 
@@ -311,27 +312,11 @@ class ImportParserPlugin {
311
312
  }
312
313
  }
313
314
 
314
- let phase = expr.phase;
315
- if (!phase && importOptions && importOptions.webpackDefer !== undefined) {
316
- if (typeof importOptions.webpackDefer !== "boolean") {
317
- parser.state.module.addWarning(
318
- new UnsupportedFeatureWarning(
319
- `\`webpackDefer\` expected a boolean, but received: ${importOptions.webpackDefer}.`,
320
- /** @type {DependencyLocation} */ (expr.loc)
321
- )
322
- );
323
- } else if (importOptions.webpackDefer) {
324
- phase = "defer";
325
- }
326
- }
327
- if (phase === "defer") {
328
- parser.state.module.addWarning(
329
- new UnsupportedFeatureWarning(
330
- "import.defer() is not implemented yet.",
331
- /** @type {DependencyLocation} */ (expr.loc)
332
- )
333
- );
334
- }
315
+ const phase = createGetImportPhase(this.options.deferImport)(
316
+ parser,
317
+ expr,
318
+ () => importOptions
319
+ );
335
320
 
336
321
  if (importOptions) {
337
322
  if (importOptions.webpackIgnore !== undefined) {
@@ -533,6 +518,7 @@ class ImportParserPlugin {
533
518
  /** @type {string} */ (param.string),
534
519
  /** @type {Range} */ (expr.range),
535
520
  exports,
521
+ phase,
536
522
  attributes
537
523
  );
538
524
  parser.state.current.addDependency(dep);
@@ -541,6 +527,7 @@ class ImportParserPlugin {
541
527
  /** @type {string} */ (param.string),
542
528
  /** @type {Range} */ (expr.range),
543
529
  exports,
530
+ phase,
544
531
  attributes
545
532
  );
546
533
  parser.state.current.addDependency(dep);
@@ -557,6 +544,7 @@ class ImportParserPlugin {
557
544
  /** @type {string} */ (param.string),
558
545
  /** @type {Range} */ (expr.range),
559
546
  exports,
547
+ phase,
560
548
  attributes
561
549
  );
562
550
  dep.loc = /** @type {DependencyLocation} */ (expr.loc);
@@ -568,6 +556,16 @@ class ImportParserPlugin {
568
556
  if (mode === "weak") {
569
557
  mode = "async-weak";
570
558
  }
559
+
560
+ if (ImportPhaseUtils.isDefer(phase)) {
561
+ parser.state.module.addWarning(
562
+ new UnsupportedFeatureWarning(
563
+ "import.defer() is not yet supported for ContextModule (the import path is a dynamic expression).",
564
+ /** @type {DependencyLocation} */ (expr.loc)
565
+ )
566
+ );
567
+ }
568
+
571
569
  const dep = ContextDependencyHelpers.create(
572
570
  ImportContextDependency,
573
571
  /** @type {Range} */ (expr.range),
@@ -0,0 +1,121 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Haijie Xie @hai-x
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const memoize = require("../util/memoize");
9
+
10
+ const getCommentCompilationWarning = memoize(() =>
11
+ require("../CommentCompilationWarning")
12
+ );
13
+
14
+ /** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
15
+ /** @typedef {import("../javascript/JavascriptParser").ExportAllDeclaration} ExportAllDeclaration */
16
+ /** @typedef {import("../javascript/JavascriptParser").ExportNamedDeclaration} ExportNamedDeclaration */
17
+ /** @typedef {import("../javascript/JavascriptParser").ImportDeclaration} ImportDeclaration */
18
+ /** @typedef {import("../javascript/JavascriptParser").ImportExpression} ImportExpression */
19
+
20
+ /** @typedef {typeof ImportPhase.Evaluation | typeof ImportPhase.Defer | typeof ImportPhase.Source} ImportPhaseType */
21
+
22
+ const ImportPhase = Object.freeze({
23
+ Evaluation: 0b00,
24
+ Defer: 0b01,
25
+ Source: 0b10
26
+ });
27
+
28
+ /**
29
+ * @typedef {object} ImportPhaseUtils
30
+ * @property {(phase: ImportPhaseType) => boolean} isDefer true if phase is defer
31
+ * @property {(phase: ImportPhaseType) => boolean} isSource true if phase is source
32
+ */
33
+
34
+ /** @type {ImportPhaseUtils} */
35
+ const ImportPhaseUtils = {
36
+ isDefer(phase) {
37
+ return phase === ImportPhase.Defer;
38
+ },
39
+ isSource(phase) {
40
+ return phase === ImportPhase.Source;
41
+ }
42
+ };
43
+
44
+ /**
45
+ * @typedef {() => Record<string, EXPECTED_ANY> | null} GetCommentOptions
46
+ */
47
+
48
+ /**
49
+ * @callback GetImportPhase
50
+ * @param {JavascriptParser} parser parser
51
+ * @param {ExportNamedDeclaration | ExportAllDeclaration | ImportDeclaration | ImportExpression} node node
52
+ * @param {GetCommentOptions=} getCommentOptions optional function that returns the comment options object.
53
+ * @returns {ImportPhaseType} import phase
54
+ */
55
+
56
+ /**
57
+ * @param {boolean=} enableImportPhase enable import phase detection
58
+ * @returns {GetImportPhase} evaluates the import phase for ast node
59
+ */
60
+ function createGetImportPhase(enableImportPhase) {
61
+ return (parser, node, getCommentOptions) => {
62
+ if (!enableImportPhase) return ImportPhase.Evaluation;
63
+
64
+ // We now only support `defer import`
65
+ const phaseBySyntax =
66
+ "phase" in node && node.phase === "defer"
67
+ ? ImportPhase.Defer
68
+ : ImportPhase.Evaluation;
69
+
70
+ if (!node.range) {
71
+ return phaseBySyntax;
72
+ }
73
+
74
+ getCommentOptions =
75
+ getCommentOptions ||
76
+ (() => {
77
+ if (!node.range) return null;
78
+ const { options, errors } = parser.parseCommentOptions(node.range);
79
+ if (errors) {
80
+ for (const e of errors) {
81
+ const { comment } = e;
82
+ if (!comment.loc) continue;
83
+
84
+ const CommentCompilationWarning = getCommentCompilationWarning();
85
+ parser.state.module.addWarning(
86
+ new CommentCompilationWarning(
87
+ `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
88
+ comment.loc
89
+ )
90
+ );
91
+ }
92
+ }
93
+ return options;
94
+ });
95
+
96
+ const options = getCommentOptions();
97
+
98
+ if (!options || !options.webpackDefer) return phaseBySyntax;
99
+
100
+ const { webpackDefer } = options;
101
+ if (typeof webpackDefer === "boolean") {
102
+ return webpackDefer ? ImportPhase.Defer : phaseBySyntax;
103
+ } else if (node.loc) {
104
+ const CommentCompilationWarning = getCommentCompilationWarning();
105
+ parser.state.module.addWarning(
106
+ new CommentCompilationWarning(
107
+ "webpackDefer magic comment expected a boolean value.",
108
+ node.loc
109
+ )
110
+ );
111
+ }
112
+
113
+ return phaseBySyntax;
114
+ };
115
+ }
116
+
117
+ module.exports = {
118
+ ImportPhase,
119
+ ImportPhaseUtils,
120
+ createGetImportPhase
121
+ };
@@ -16,16 +16,18 @@ const ImportDependency = require("./ImportDependency");
16
16
  /** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */
17
17
  /** @typedef {import("../javascript/JavascriptParser").Range} Range */
18
18
  /** @typedef {ImportDependency.RawReferencedExports} RawReferencedExports */
19
+ /** @typedef {import("./ImportPhase").ImportPhaseType} ImportPhaseType */
19
20
 
20
21
  class ImportWeakDependency extends ImportDependency {
21
22
  /**
22
23
  * @param {string} request the request
23
24
  * @param {Range} range expression range
24
- * @param {RawReferencedExports | null=} referencedExports list of referenced exports
25
+ * @param {RawReferencedExports | null} referencedExports list of referenced exports
26
+ * @param {ImportPhaseType} phase import phase
25
27
  * @param {ImportAttributes=} attributes import attributes
26
28
  */
27
- constructor(request, range, referencedExports, attributes) {
28
- super(request, range, referencedExports, attributes);
29
+ constructor(request, range, referencedExports, phase, attributes) {
30
+ super(request, range, referencedExports, phase, attributes);
29
31
  this.weak = true;
30
32
  }
31
33
 
@@ -61,6 +63,7 @@ ImportWeakDependency.Template = class ImportDependencyTemplate extends (
61
63
  strict: /** @type {BuildMeta} */ (module.buildMeta).strictHarmonyModule,
62
64
  message: "import() weak",
63
65
  weak: true,
66
+ dependency: dep,
64
67
  runtimeRequirements
65
68
  });
66
69
 
@@ -7,7 +7,7 @@
7
7
 
8
8
  const LocalModule = require("./LocalModule");
9
9
 
10
- /** @typedef {import("../javascript/JavascriptParser").ParserState} ParserState */
10
+ /** @typedef {import("../javascript/JavascriptParser").JavascriptParserState} JavascriptParserState */
11
11
 
12
12
  /**
13
13
  * @param {string} parent parent module
@@ -34,7 +34,7 @@ const lookup = (parent, mod) => {
34
34
  };
35
35
 
36
36
  /**
37
- * @param {ParserState} state parser state
37
+ * @param {JavascriptParserState} state parser state
38
38
  * @param {string} name name
39
39
  * @returns {LocalModule} local module
40
40
  */
@@ -48,7 +48,7 @@ module.exports.addLocalModule = (state, name) => {
48
48
  };
49
49
 
50
50
  /**
51
- * @param {ParserState} state parser state
51
+ * @param {JavascriptParserState} state parser state
52
52
  * @param {string} name name
53
53
  * @param {string=} namedModule named module
54
54
  * @returns {LocalModule | null} local module or null