webpack 5.102.1 → 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 (118) hide show
  1. package/README.md +121 -134
  2. package/lib/CompatibilityPlugin.js +25 -2
  3. package/lib/Compilation.js +25 -2
  4. package/lib/ConcatenationScope.js +0 -15
  5. package/lib/CssModule.js +6 -1
  6. package/lib/DefinePlugin.js +11 -11
  7. package/lib/Dependency.js +8 -1
  8. package/lib/DependencyTemplate.js +1 -0
  9. package/lib/DotenvPlugin.js +457 -0
  10. package/lib/EnvironmentPlugin.js +19 -16
  11. package/lib/EvalSourceMapDevToolPlugin.js +16 -0
  12. package/lib/ExportsInfo.js +6 -2
  13. package/lib/ExternalModule.js +20 -28
  14. package/lib/ExternalModuleFactoryPlugin.js +10 -8
  15. package/lib/ExternalsPlugin.js +2 -1
  16. package/lib/ManifestPlugin.js +235 -0
  17. package/lib/Module.js +3 -0
  18. package/lib/ModuleGraph.js +2 -1
  19. package/lib/ModuleSourceTypesConstants.js +0 -6
  20. package/lib/MultiCompiler.js +1 -1
  21. package/lib/NodeStuffPlugin.js +419 -121
  22. package/lib/NormalModule.js +17 -16
  23. package/lib/RuntimeGlobals.js +22 -4
  24. package/lib/RuntimePlugin.js +27 -6
  25. package/lib/RuntimeTemplate.js +115 -56
  26. package/lib/SourceMapDevToolPlugin.js +20 -0
  27. package/lib/WebpackOptionsApply.js +33 -9
  28. package/lib/asset/AssetBytesGenerator.js +1 -1
  29. package/lib/asset/AssetGenerator.js +1 -2
  30. package/lib/asset/AssetSourceGenerator.js +1 -1
  31. package/lib/config/browserslistTargetHandler.js +5 -0
  32. package/lib/config/defaults.js +98 -18
  33. package/lib/config/normalization.js +2 -1
  34. package/lib/config/target.js +6 -0
  35. package/lib/css/CssGenerator.js +283 -57
  36. package/lib/css/CssLoadingRuntimeModule.js +2 -0
  37. package/lib/css/CssMergeStyleSheetsRuntimeModule.js +56 -0
  38. package/lib/css/CssModulesPlugin.js +84 -34
  39. package/lib/css/CssParser.js +1174 -667
  40. package/lib/css/walkCssTokens.js +97 -0
  41. package/lib/dependencies/CommonJsImportsParserPlugin.js +0 -9
  42. package/lib/dependencies/CommonJsPlugin.js +12 -0
  43. package/lib/dependencies/CssIcssExportDependency.js +247 -8
  44. package/lib/dependencies/CssIcssFromIdentifierDependency.js +124 -0
  45. package/lib/dependencies/CssIcssGlobalIdentifierDependency.js +48 -0
  46. package/lib/dependencies/CssIcssImportDependency.js +60 -54
  47. package/lib/dependencies/CssIcssLocalIdentifierDependency.js +61 -0
  48. package/lib/dependencies/{CssSelfLocalIdentifierDependency.js → CssIcssSelfLocalIdentifierDependency.js} +88 -10
  49. package/lib/dependencies/CssIcssSymbolDependency.js +31 -29
  50. package/lib/dependencies/CssImportDependency.js +15 -5
  51. package/lib/dependencies/ExternalModuleInitFragment.js +1 -1
  52. package/lib/dependencies/ExternalModuleInitFragmentDependency.js +95 -0
  53. package/lib/dependencies/HarmonyAcceptDependency.js +6 -1
  54. package/lib/dependencies/HarmonyAcceptImportDependency.js +2 -1
  55. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +12 -1
  56. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +32 -21
  57. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +12 -8
  58. package/lib/dependencies/HarmonyImportDependency.js +23 -27
  59. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +28 -69
  60. package/lib/dependencies/HarmonyImportSideEffectDependency.js +4 -3
  61. package/lib/dependencies/HarmonyImportSpecifierDependency.js +10 -8
  62. package/lib/dependencies/ImportDependency.js +8 -2
  63. package/lib/dependencies/ImportEagerDependency.js +6 -3
  64. package/lib/dependencies/ImportMetaPlugin.js +97 -9
  65. package/lib/dependencies/ImportParserPlugin.js +19 -21
  66. package/lib/dependencies/ImportPhase.js +121 -0
  67. package/lib/dependencies/ImportWeakDependency.js +6 -3
  68. package/lib/dependencies/ModuleDependency.js +5 -1
  69. package/lib/dependencies/ModuleHotAcceptDependency.js +1 -1
  70. package/lib/esm/ExportWebpackRequireRuntimeModule.js +1 -8
  71. package/lib/hmr/LazyCompilationPlugin.js +1 -0
  72. package/lib/ids/IdHelpers.js +4 -1
  73. package/lib/index.js +6 -0
  74. package/lib/javascript/ChunkHelpers.js +16 -5
  75. package/lib/javascript/JavascriptGenerator.js +101 -101
  76. package/lib/javascript/JavascriptModulesPlugin.js +23 -13
  77. package/lib/javascript/JavascriptParser.js +142 -38
  78. package/lib/json/JsonParser.js +7 -1
  79. package/lib/library/ModuleLibraryPlugin.js +0 -10
  80. package/lib/library/SystemLibraryPlugin.js +4 -0
  81. package/lib/library/UmdLibraryPlugin.js +1 -1
  82. package/lib/node/NodeTargetPlugin.js +9 -1
  83. package/lib/node/ReadFileCompileWasmPlugin.js +0 -2
  84. package/lib/optimize/ConcatenatedModule.js +161 -135
  85. package/lib/runtime/AsyncModuleRuntimeModule.js +28 -18
  86. package/lib/runtime/AutoPublicPathRuntimeModule.js +8 -3
  87. package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +89 -55
  88. package/lib/util/comparators.js +4 -3
  89. package/lib/util/internalSerializables.js +4 -4
  90. package/lib/util/jsonParseEvenBetterErrors.js +10 -0
  91. package/lib/wasm/EnableWasmLoadingPlugin.js +10 -4
  92. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +8 -5
  93. package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +8 -4
  94. package/lib/web/FetchCompileWasmPlugin.js +0 -2
  95. package/lib/webpack.js +85 -82
  96. package/module.d.ts +5 -0
  97. package/package.json +16 -14
  98. package/schemas/WebpackOptions.check.js +1 -1
  99. package/schemas/WebpackOptions.json +109 -27
  100. package/schemas/plugins/ManifestPlugin.check.d.ts +7 -0
  101. package/schemas/plugins/ManifestPlugin.check.js +6 -0
  102. package/schemas/plugins/ManifestPlugin.json +98 -0
  103. package/schemas/plugins/SourceMapDevToolPlugin.check.js +1 -1
  104. package/schemas/plugins/SourceMapDevToolPlugin.json +16 -3
  105. package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
  106. package/schemas/plugins/container/ContainerReferencePlugin.json +4 -1
  107. package/schemas/plugins/container/ExternalsType.check.js +1 -1
  108. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  109. package/schemas/plugins/container/ModuleFederationPlugin.json +4 -1
  110. package/schemas/plugins/css/CssAutoParserOptions.check.js +1 -1
  111. package/schemas/plugins/css/CssGlobalGeneratorOptions.check.js +1 -1
  112. package/schemas/plugins/css/CssGlobalParserOptions.check.js +1 -1
  113. package/schemas/plugins/css/CssModuleGeneratorOptions.check.js +1 -1
  114. package/schemas/plugins/css/CssModuleParserOptions.check.js +1 -1
  115. package/schemas/plugins/css/CssParserOptions.check.js +1 -1
  116. package/schemas/plugins/json/JsonModulesPluginParser.check.js +1 -1
  117. package/types.d.ts +560 -293
  118. package/lib/dependencies/CssLocalIdentifierDependency.js +0 -250
@@ -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
 
@@ -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
@@ -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
  }
@@ -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
 
@@ -257,6 +257,7 @@ class LazyCompilationProxyModule extends Module {
257
257
  block,
258
258
  module,
259
259
  request: this.request,
260
+ dependency: dep,
260
261
  strict: false, // TODO this should be inherited from the original module
261
262
  message: "import()",
262
263
  runtimeRequirements
@@ -15,6 +15,7 @@ const numberHash = require("../util/numberHash");
15
15
  /** @typedef {import("../Module")} Module */
16
16
  /** @typedef {typeof import("../util/Hash")} Hash */
17
17
  /** @typedef {import("../util/identifier").AssociatedObjectForCache} AssociatedObjectForCache */
18
+ /** @typedef {import("../Module").BuildMeta} BuildMeta */
18
19
 
19
20
  /**
20
21
  * @param {string} str string to hash
@@ -246,7 +247,9 @@ const getUsedModuleIdsAndModules = (compilation, filter) => {
246
247
  usedIds.add(String(moduleId));
247
248
  } else if (
248
249
  (!filter || filter(module)) &&
249
- chunkGraph.getNumberOfModuleChunks(module) !== 0
250
+ (chunkGraph.getNumberOfModuleChunks(module) !== 0 ||
251
+ // CSS modules need IDs even when not in chunks, for generating CSS class names(i.e. [id]-[local])
252
+ /** @type {BuildMeta} */ (module.buildMeta).isCSSModule)
250
253
  ) {
251
254
  modules.push(module);
252
255
  }
package/lib/index.js CHANGED
@@ -232,6 +232,9 @@ module.exports = mergeExports(fn, {
232
232
  get DynamicEntryPlugin() {
233
233
  return require("./DynamicEntryPlugin");
234
234
  },
235
+ get DotenvPlugin() {
236
+ return require("./DotenvPlugin");
237
+ },
235
238
  get EntryOptionPlugin() {
236
239
  return require("./EntryOptionPlugin");
237
240
  },
@@ -355,6 +358,9 @@ module.exports = mergeExports(fn, {
355
358
  get Stats() {
356
359
  return require("./Stats");
357
360
  },
361
+ get ManifestPlugin() {
362
+ return require("./ManifestPlugin");
363
+ },
358
364
  get Template() {
359
365
  return require("./Template");
360
366
  },