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
@@ -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;
@@ -35,6 +35,19 @@ class ImportContextDependency extends ContextDependency {
35
35
  return "esm";
36
36
  }
37
37
 
38
+ /**
39
+ * @returns {string | null} an identifier to merge equal requests
40
+ */
41
+ getResourceIdentifier() {
42
+ let str = super.getResourceIdentifier();
43
+
44
+ if (this.options.attributes) {
45
+ str += `|importAttributes${JSON.stringify(this.options.attributes)}`;
46
+ }
47
+
48
+ return str;
49
+ }
50
+
38
51
  /**
39
52
  * @param {ObjectSerializerContext} context context
40
53
  */
@@ -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
 
@@ -50,8 +53,8 @@ class ImportDependency extends ModuleDependency {
50
53
  */
51
54
  getResourceIdentifier() {
52
55
  let str = super.getResourceIdentifier();
53
- if (this.attributes !== undefined) {
54
- str += JSON.stringify(this.attributes);
56
+ if (this.attributes) {
57
+ str += `|importAttributes${JSON.stringify(this.attributes)}`;
55
58
  }
56
59
  return str;
57
60
  }
@@ -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
 
@@ -6,11 +6,14 @@
6
6
  "use strict";
7
7
 
8
8
  const { pathToFileURL } = require("url");
9
+ const { SyncBailHook } = require("tapable");
10
+ const Compilation = require("../Compilation");
9
11
  const ModuleDependencyWarning = require("../ModuleDependencyWarning");
10
12
  const {
11
13
  JAVASCRIPT_MODULE_TYPE_AUTO,
12
14
  JAVASCRIPT_MODULE_TYPE_ESM
13
15
  } = require("../ModuleTypeConstants");
16
+ const RuntimeGlobals = require("../RuntimeGlobals");
14
17
  const Template = require("../Template");
15
18
  const BasicEvaluatedExpression = require("../javascript/BasicEvaluatedExpression");
16
19
  const {
@@ -31,6 +34,8 @@ const ConstDependency = require("./ConstDependency");
31
34
  /** @typedef {import("../javascript/JavascriptParser")} Parser */
32
35
  /** @typedef {import("../javascript/JavascriptParser").Range} Range */
33
36
  /** @typedef {import("../javascript/JavascriptParser").Members} Members */
37
+ /** @typedef {import("../javascript/JavascriptParser").DestructuringAssignmentProperty} DestructuringAssignmentProperty */
38
+ /** @typedef {import("./ConstDependency").RawRuntimeRequirements} RawRuntimeRequirements */
34
39
 
35
40
  const getCriticalDependencyWarning = memoize(() =>
36
41
  require("./CriticalDependencyWarning")
@@ -38,7 +43,35 @@ const getCriticalDependencyWarning = memoize(() =>
38
43
 
39
44
  const PLUGIN_NAME = "ImportMetaPlugin";
40
45
 
46
+ /**
47
+ * @typedef {object} ImportMetaPluginHooks
48
+ * @property {SyncBailHook<[DestructuringAssignmentProperty], string | void>} propertyInDestructuring
49
+ */
50
+
51
+ /** @type {WeakMap<Compilation, ImportMetaPluginHooks>} */
52
+ const compilationHooksMap = new WeakMap();
53
+
41
54
  class ImportMetaPlugin {
55
+ /**
56
+ * @param {Compilation} compilation the compilation
57
+ * @returns {ImportMetaPluginHooks} the attached hooks
58
+ */
59
+ static getCompilationHooks(compilation) {
60
+ if (!(compilation instanceof Compilation)) {
61
+ throw new TypeError(
62
+ "The 'compilation' argument must be an instance of Compilation"
63
+ );
64
+ }
65
+ let hooks = compilationHooksMap.get(compilation);
66
+ if (hooks === undefined) {
67
+ hooks = {
68
+ propertyInDestructuring: new SyncBailHook(["property"])
69
+ };
70
+ compilationHooksMap.set(compilation, hooks);
71
+ }
72
+ return hooks;
73
+ }
74
+
42
75
  /**
43
76
  * @param {Compiler} compiler compiler
44
77
  */
@@ -46,6 +79,8 @@ class ImportMetaPlugin {
46
79
  compiler.hooks.compilation.tap(
47
80
  PLUGIN_NAME,
48
81
  (compilation, { normalModuleFactory }) => {
82
+ const hooks = ImportMetaPlugin.getCompilationHooks(compilation);
83
+
49
84
  /**
50
85
  * @param {NormalModule} module module
51
86
  * @returns {string} file url
@@ -115,7 +150,7 @@ class ImportMetaPlugin {
115
150
  new ModuleDependencyWarning(
116
151
  parser.state.module,
117
152
  new CriticalDependencyWarning(
118
- "Accessing import.meta directly is unsupported (only property access or destructuring is supported)"
153
+ "'import.meta' cannot be used as a standalone expression. For static analysis, its properties must be accessed directly (e.g., 'import.meta.url') or through destructuring."
119
154
  ),
120
155
  /** @type {DependencyLocation} */ (metaProperty.loc)
121
156
  )
@@ -135,25 +170,44 @@ class ImportMetaPlugin {
135
170
  return true;
136
171
  }
137
172
 
173
+ /** @type {RawRuntimeRequirements} */
174
+ const runtimeRequirements = [];
175
+
138
176
  let str = "";
139
- for (const { id: prop } of referencedPropertiesInDestructuring) {
140
- switch (prop) {
177
+ for (const prop of referencedPropertiesInDestructuring) {
178
+ const value = hooks.propertyInDestructuring.call(prop);
179
+
180
+ if (value) {
181
+ str += value;
182
+ continue;
183
+ }
184
+
185
+ switch (prop.id) {
141
186
  case "url":
142
187
  str += `url: ${importMetaUrl()},`;
143
188
  break;
144
189
  case "webpack":
145
190
  str += `webpack: ${importMetaWebpackVersion()},`;
146
191
  break;
192
+ case "main":
193
+ str += `main: ${RuntimeGlobals.moduleCache}[${RuntimeGlobals.entryModuleId}] === ${RuntimeGlobals.module},`;
194
+ runtimeRequirements.push(
195
+ RuntimeGlobals.moduleCache,
196
+ RuntimeGlobals.entryModuleId,
197
+ RuntimeGlobals.module
198
+ );
199
+ break;
147
200
  default:
148
201
  str += `[${JSON.stringify(
149
- prop
150
- )}]: ${importMetaUnknownProperty([prop])},`;
202
+ prop.id
203
+ )}]: ${importMetaUnknownProperty([prop.id])},`;
151
204
  break;
152
205
  }
153
206
  }
154
207
  const dep = new ConstDependency(
155
208
  `({${str}})`,
156
- /** @type {Range} */ (metaProperty.range)
209
+ /** @type {Range} */ (metaProperty.range),
210
+ runtimeRequirements
157
211
  );
158
212
  dep.loc = /** @type {DependencyLocation} */ (metaProperty.loc);
159
213
  parser.state.module.addPresentationalDependency(dep);
@@ -197,17 +251,17 @@ class ImportMetaPlugin {
197
251
  );
198
252
 
199
253
  // import.meta.webpack
200
- parser.hooks.typeof
254
+ parser.hooks.expression
201
255
  .for("import.meta.webpack")
202
256
  .tap(
203
257
  PLUGIN_NAME,
204
- toConstantDependency(parser, JSON.stringify("number"))
258
+ toConstantDependency(parser, importMetaWebpackVersion())
205
259
  );
206
- parser.hooks.expression
260
+ parser.hooks.typeof
207
261
  .for("import.meta.webpack")
208
262
  .tap(
209
263
  PLUGIN_NAME,
210
- toConstantDependency(parser, importMetaWebpackVersion())
264
+ toConstantDependency(parser, JSON.stringify("number"))
211
265
  );
212
266
  parser.hooks.evaluateTypeof
213
267
  .for("import.meta.webpack")
@@ -216,10 +270,44 @@ class ImportMetaPlugin {
216
270
  .for("import.meta.webpack")
217
271
  .tap(PLUGIN_NAME, evaluateToNumber(webpackVersion));
218
272
 
273
+ parser.hooks.expression
274
+ .for("import.meta.main")
275
+ .tap(
276
+ PLUGIN_NAME,
277
+ toConstantDependency(
278
+ parser,
279
+ `${RuntimeGlobals.moduleCache}[${RuntimeGlobals.entryModuleId}] === ${RuntimeGlobals.module}`,
280
+ [
281
+ RuntimeGlobals.moduleCache,
282
+ RuntimeGlobals.entryModuleId,
283
+ RuntimeGlobals.module
284
+ ]
285
+ )
286
+ );
287
+ parser.hooks.typeof
288
+ .for("import.meta.main")
289
+ .tap(
290
+ PLUGIN_NAME,
291
+ toConstantDependency(parser, JSON.stringify("boolean"))
292
+ );
293
+ parser.hooks.evaluateTypeof
294
+ .for("import.meta.main")
295
+ .tap(PLUGIN_NAME, evaluateToString("boolean"));
296
+
219
297
  // Unknown properties
220
298
  parser.hooks.unhandledExpressionMemberChain
221
299
  .for("import.meta")
222
300
  .tap(PLUGIN_NAME, (expr, members) => {
301
+ // keep import.meta.env unknown property
302
+ // don't evaluate import.meta.env.UNKNOWN_PROPERTY -> undefined.UNKNOWN_PROPERTY
303
+ // `dirname` and `filename` logic in NodeStuffPlugin
304
+ if (
305
+ members[0] === "env" ||
306
+ members[0] === "dirname" ||
307
+ members[0] === "filename"
308
+ ) {
309
+ return true;
310
+ }
223
311
  const dep = new ConstDependency(
224
312
  importMetaUnknownProperty(members),
225
313
  /** @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 */
@@ -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
 
@@ -18,11 +18,13 @@ const DependencyTemplate = require("../DependencyTemplate");
18
18
  class ModuleDependency extends Dependency {
19
19
  /**
20
20
  * @param {string} request request path which needs resolving
21
+ * @param {number=} sourceOrder source order
21
22
  */
22
- constructor(request) {
23
+ constructor(request, sourceOrder) {
23
24
  super();
24
25
  this.request = request;
25
26
  this.userRequest = request;
27
+ this.sourceOrder = sourceOrder;
26
28
  /** @type {Range | undefined} */
27
29
  this.range = undefined;
28
30
  this._context = undefined;
@@ -74,6 +76,7 @@ class ModuleDependency extends Dependency {
74
76
  write(this.userRequest);
75
77
  write(this._context);
76
78
  write(this.range);
79
+ write(this.sourceOrder);
77
80
  super.serialize(context);
78
81
  }
79
82
 
@@ -86,6 +89,7 @@ class ModuleDependency extends Dependency {
86
89
  this.userRequest = read();
87
90
  this._context = read();
88
91
  this.range = read();
92
+ this.sourceOrder = read();
89
93
  super.deserialize(context);
90
94
  }
91
95
  }
@@ -17,7 +17,7 @@ class ModuleHotAcceptDependency extends ModuleDependency {
17
17
  * @param {Range} range location in source code
18
18
  */
19
19
  constructor(request, range) {
20
- super(request);
20
+ super(request, Infinity);
21
21
  this.range = range;
22
22
  this.weak = true;
23
23
  }
@@ -378,9 +378,7 @@ class WorkerPlugin {
378
378
  )}|${i}`;
379
379
  const hash = createHash(compilation.outputOptions.hashFunction);
380
380
  hash.update(name);
381
- const digest =
382
- /** @type {string} */
383
- (hash.digest(compilation.outputOptions.hashDigest));
381
+ const digest = hash.digest(compilation.outputOptions.hashDigest);
384
382
  entryOptions.runtime = digest.slice(
385
383
  0,
386
384
  compilation.outputOptions.hashDigestLength
@@ -6,10 +6,6 @@
6
6
 
7
7
  const RuntimeGlobals = require("../RuntimeGlobals");
8
8
  const RuntimeModule = require("../RuntimeModule");
9
- const Template = require("../Template");
10
-
11
- // CompatibilityPlugin renames `__webpack_require__` but doesn’t account for `export { __webpack_require__ }`, so we create a temporary variable to handle it.
12
- const EXPORT_TEMP_NAME = "__webpack_require_temp__";
13
9
 
14
10
  class ExportWebpackRequireRuntimeModule extends RuntimeModule {
15
11
  constructor() {
@@ -27,10 +23,7 @@ class ExportWebpackRequireRuntimeModule extends RuntimeModule {
27
23
  * @returns {string | null} runtime code
28
24
  */
29
25
  generate() {
30
- return Template.asString([
31
- `var ${EXPORT_TEMP_NAME} = ${RuntimeGlobals.require};`,
32
- `export { ${EXPORT_TEMP_NAME} as ${RuntimeGlobals.require} };`
33
- ]);
26
+ return `export { ${RuntimeGlobals.require} };`;
34
27
  }
35
28
  }
36
29