webpack 5.69.0 → 5.71.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (73) hide show
  1. package/hot/poll.js +1 -1
  2. package/hot/signal.js +1 -1
  3. package/lib/BannerPlugin.js +10 -4
  4. package/lib/Chunk.js +1 -1
  5. package/lib/ChunkGroup.js +1 -1
  6. package/lib/CleanPlugin.js +64 -18
  7. package/lib/Compilation.js +51 -25
  8. package/lib/Compiler.js +16 -3
  9. package/lib/ConstPlugin.js +2 -2
  10. package/lib/ContextModule.js +54 -22
  11. package/lib/ContextModuleFactory.js +13 -12
  12. package/lib/DelegatedModuleFactoryPlugin.js +1 -1
  13. package/lib/Dependency.js +7 -0
  14. package/lib/EntryOptionPlugin.js +1 -0
  15. package/lib/ErrorHelpers.js +2 -2
  16. package/lib/ExternalModuleFactoryPlugin.js +4 -4
  17. package/lib/FileSystemInfo.js +8 -0
  18. package/lib/Generator.js +1 -0
  19. package/lib/LoaderOptionsPlugin.js +1 -1
  20. package/lib/Module.js +2 -0
  21. package/lib/ModuleFilenameHelpers.js +3 -3
  22. package/lib/ModuleHashingError.js +29 -0
  23. package/lib/NodeStuffPlugin.js +10 -0
  24. package/lib/NormalModule.js +23 -18
  25. package/lib/NormalModuleFactory.js +17 -10
  26. package/lib/ProgressPlugin.js +3 -4
  27. package/lib/RuntimePlugin.js +18 -0
  28. package/lib/RuntimeTemplate.js +1 -0
  29. package/lib/WebpackOptionsApply.js +2 -0
  30. package/lib/asset/AssetGenerator.js +119 -31
  31. package/lib/cache/ResolverCachePlugin.js +15 -6
  32. package/lib/config/browserslistTargetHandler.js +3 -5
  33. package/lib/config/defaults.js +9 -1
  34. package/lib/config/normalization.js +1 -0
  35. package/lib/dependencies/CommonJsExportsParserPlugin.js +1 -2
  36. package/lib/dependencies/ContextDependencyHelpers.js +3 -3
  37. package/lib/dependencies/ContextElementDependency.js +33 -1
  38. package/lib/dependencies/HarmonyAcceptImportDependency.js +5 -3
  39. package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +95 -0
  40. package/lib/dependencies/HarmonyExportInitFragment.js +4 -1
  41. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +127 -43
  42. package/lib/dependencies/HarmonyImportSpecifierDependency.js +22 -8
  43. package/lib/dependencies/HarmonyModulesPlugin.js +10 -0
  44. package/lib/dependencies/ImportContextDependency.js +0 -2
  45. package/lib/dependencies/ImportMetaContextDependency.js +35 -0
  46. package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +252 -0
  47. package/lib/dependencies/ImportMetaContextPlugin.js +59 -0
  48. package/lib/dependencies/LoaderPlugin.js +2 -0
  49. package/lib/dependencies/RequireContextDependency.js +0 -16
  50. package/lib/esm/ModuleChunkLoadingPlugin.js +3 -1
  51. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +24 -8
  52. package/lib/hmr/HotModuleReplacement.runtime.js +29 -14
  53. package/lib/hmr/JavascriptHotModuleReplacement.runtime.js +4 -3
  54. package/lib/ids/HashedModuleIdsPlugin.js +2 -2
  55. package/lib/ids/IdHelpers.js +1 -1
  56. package/lib/javascript/BasicEvaluatedExpression.js +5 -2
  57. package/lib/javascript/JavascriptParser.js +66 -40
  58. package/lib/library/UmdLibraryPlugin.js +5 -3
  59. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +22 -7
  60. package/lib/node/RequireChunkLoadingRuntimeModule.js +22 -7
  61. package/lib/runtime/BaseUriRuntimeModule.js +31 -0
  62. package/lib/schemes/HttpUriPlugin.js +44 -3
  63. package/lib/stats/DefaultStatsFactoryPlugin.js +1 -1
  64. package/lib/util/internalSerializables.js +4 -0
  65. package/lib/web/JsonpChunkLoadingRuntimeModule.js +17 -6
  66. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +30 -20
  67. package/module.d.ts +15 -0
  68. package/package.json +2 -2
  69. package/schemas/WebpackOptions.check.js +1 -1
  70. package/schemas/WebpackOptions.json +17 -1
  71. package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
  72. package/schemas/plugins/schemes/HttpUriPlugin.json +4 -0
  73. package/types.d.ts +179 -83
@@ -10,6 +10,7 @@ const InnerGraph = require("../optimize/InnerGraph");
10
10
  const ConstDependency = require("./ConstDependency");
11
11
  const HarmonyAcceptDependency = require("./HarmonyAcceptDependency");
12
12
  const HarmonyAcceptImportDependency = require("./HarmonyAcceptImportDependency");
13
+ const HarmonyEvaluatedImportSpecifierDependency = require("./HarmonyEvaluatedImportSpecifierDependency");
13
14
  const HarmonyExports = require("./HarmonyExports");
14
15
  const { ExportPresenceModes } = require("./HarmonyImportDependency");
15
16
  const HarmonyImportSideEffectDependency = require("./HarmonyImportSideEffectDependency");
@@ -83,6 +84,18 @@ module.exports = class HarmonyImportDependencyParserPlugin {
83
84
  */
84
85
  apply(parser) {
85
86
  const { exportPresenceMode } = this;
87
+
88
+ function getNonOptionalPart(members, membersOptionals) {
89
+ let i = 0;
90
+ while (i < members.length && membersOptionals[i] === false) i++;
91
+ return i !== members.length ? members.slice(0, i) : members;
92
+ }
93
+
94
+ function getNonOptionalMemberChain(node, count) {
95
+ while (count--) node = node.object;
96
+ return node;
97
+ }
98
+
86
99
  parser.hooks.isPure
87
100
  .for("Identifier")
88
101
  .tap("HarmonyImportDependencyParserPlugin", expression => {
@@ -131,74 +144,145 @@ module.exports = class HarmonyImportDependencyParserPlugin {
131
144
  return true;
132
145
  }
133
146
  );
134
- parser.hooks.expression
135
- .for(harmonySpecifierTag)
136
- .tap("HarmonyImportDependencyParserPlugin", expr => {
137
- const settings = /** @type {HarmonySettings} */ (parser.currentTagData);
138
- const dep = new HarmonyImportSpecifierDependency(
147
+ parser.hooks.binaryExpression.tap(
148
+ "HarmonyImportDependencyParserPlugin",
149
+ expression => {
150
+ if (expression.operator !== "in") return;
151
+
152
+ const leftPartEvaluated = parser.evaluateExpression(expression.left);
153
+ if (leftPartEvaluated.couldHaveSideEffects()) return;
154
+ const leftPart = leftPartEvaluated.asString();
155
+ if (!leftPart) return;
156
+
157
+ const rightPart = parser.evaluateExpression(expression.right);
158
+ if (!rightPart.isIdentifier()) return;
159
+
160
+ const rootInfo = rightPart.rootInfo;
161
+ if (
162
+ !rootInfo ||
163
+ !rootInfo.tagInfo ||
164
+ rootInfo.tagInfo.tag !== harmonySpecifierTag
165
+ )
166
+ return;
167
+ const settings = rootInfo.tagInfo.data;
168
+ const members = rightPart.getMembers();
169
+ const dep = new HarmonyEvaluatedImportSpecifierDependency(
139
170
  settings.source,
140
171
  settings.sourceOrder,
141
- settings.ids,
172
+ settings.ids.concat(members).concat([leftPart]),
142
173
  settings.name,
143
- expr.range,
144
- exportPresenceMode,
145
- settings.assertions
174
+ expression.range,
175
+ settings.assertions,
176
+ "in"
146
177
  );
147
- dep.shorthand = parser.scope.inShorthand;
148
- dep.directImport = true;
149
- dep.asiSafe = !parser.isAsiPosition(expr.range[0]);
150
- dep.loc = expr.loc;
178
+ dep.directImport = members.length === 0;
179
+ dep.asiSafe = !parser.isAsiPosition(expression.range[0]);
180
+ dep.loc = expression.loc;
151
181
  parser.state.module.addDependency(dep);
152
182
  InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e));
153
183
  return true;
154
- });
155
- parser.hooks.expressionMemberChain
184
+ }
185
+ );
186
+ parser.hooks.expression
156
187
  .for(harmonySpecifierTag)
157
- .tap("HarmonyImportDependencyParserPlugin", (expr, members) => {
188
+ .tap("HarmonyImportDependencyParserPlugin", expr => {
158
189
  const settings = /** @type {HarmonySettings} */ (parser.currentTagData);
159
- const ids = settings.ids.concat(members);
160
190
  const dep = new HarmonyImportSpecifierDependency(
161
191
  settings.source,
162
192
  settings.sourceOrder,
163
- ids,
193
+ settings.ids,
164
194
  settings.name,
165
195
  expr.range,
166
196
  exportPresenceMode,
167
197
  settings.assertions
168
198
  );
199
+ dep.shorthand = parser.scope.inShorthand;
200
+ dep.directImport = true;
169
201
  dep.asiSafe = !parser.isAsiPosition(expr.range[0]);
170
202
  dep.loc = expr.loc;
171
203
  parser.state.module.addDependency(dep);
172
204
  InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e));
173
205
  return true;
174
206
  });
207
+ parser.hooks.expressionMemberChain
208
+ .for(harmonySpecifierTag)
209
+ .tap(
210
+ "HarmonyImportDependencyParserPlugin",
211
+ (expression, members, membersOptionals) => {
212
+ const settings = /** @type {HarmonySettings} */ (
213
+ parser.currentTagData
214
+ );
215
+ const nonOptionalMembers = getNonOptionalPart(
216
+ members,
217
+ membersOptionals
218
+ );
219
+ const expr =
220
+ nonOptionalMembers !== members
221
+ ? getNonOptionalMemberChain(
222
+ expression,
223
+ members.length - nonOptionalMembers.length
224
+ )
225
+ : expression;
226
+ const ids = settings.ids.concat(nonOptionalMembers);
227
+ const dep = new HarmonyImportSpecifierDependency(
228
+ settings.source,
229
+ settings.sourceOrder,
230
+ ids,
231
+ settings.name,
232
+ expr.range,
233
+ exportPresenceMode,
234
+ settings.assertions
235
+ );
236
+ dep.asiSafe = !parser.isAsiPosition(expr.range[0]);
237
+ dep.loc = expr.loc;
238
+ parser.state.module.addDependency(dep);
239
+ InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e));
240
+ return true;
241
+ }
242
+ );
175
243
  parser.hooks.callMemberChain
176
244
  .for(harmonySpecifierTag)
177
- .tap("HarmonyImportDependencyParserPlugin", (expr, members) => {
178
- const { arguments: args, callee } = expr;
179
- const settings = /** @type {HarmonySettings} */ (parser.currentTagData);
180
- const ids = settings.ids.concat(members);
181
- const dep = new HarmonyImportSpecifierDependency(
182
- settings.source,
183
- settings.sourceOrder,
184
- ids,
185
- settings.name,
186
- callee.range,
187
- exportPresenceMode,
188
- settings.assertions
189
- );
190
- dep.directImport = members.length === 0;
191
- dep.call = true;
192
- dep.asiSafe = !parser.isAsiPosition(callee.range[0]);
193
- // only in case when we strictly follow the spec we need a special case here
194
- dep.namespaceObjectAsContext =
195
- members.length > 0 && this.strictThisContextOnImports;
196
- dep.loc = callee.loc;
197
- parser.state.module.addDependency(dep);
198
- if (args) parser.walkExpressions(args);
199
- InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e));
200
- return true;
201
- });
245
+ .tap(
246
+ "HarmonyImportDependencyParserPlugin",
247
+ (expression, members, membersOptionals) => {
248
+ const { arguments: args, callee } = expression;
249
+ const settings = /** @type {HarmonySettings} */ (
250
+ parser.currentTagData
251
+ );
252
+ const nonOptionalMembers = getNonOptionalPart(
253
+ members,
254
+ membersOptionals
255
+ );
256
+ const expr =
257
+ nonOptionalMembers !== members
258
+ ? getNonOptionalMemberChain(
259
+ callee,
260
+ members.length - nonOptionalMembers.length
261
+ )
262
+ : callee;
263
+ const ids = settings.ids.concat(nonOptionalMembers);
264
+ const dep = new HarmonyImportSpecifierDependency(
265
+ settings.source,
266
+ settings.sourceOrder,
267
+ ids,
268
+ settings.name,
269
+ expr.range,
270
+ exportPresenceMode,
271
+ settings.assertions
272
+ );
273
+ dep.directImport = members.length === 0;
274
+ dep.call = true;
275
+ dep.asiSafe = !parser.isAsiPosition(expr.range[0]);
276
+ // only in case when we strictly follow the spec we need a special case here
277
+ dep.namespaceObjectAsContext =
278
+ members.length > 0 && this.strictThisContextOnImports;
279
+ dep.loc = expr.loc;
280
+ parser.state.module.addDependency(dep);
281
+ if (args) parser.walkExpressions(args);
282
+ InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e));
283
+ return true;
284
+ }
285
+ );
202
286
  const { hotAcceptCallback, hotAcceptWithoutCallback } =
203
287
  HotModuleReplacementPlugin.getParserHooks(parser);
204
288
  hotAcceptCallback.tap(
@@ -261,14 +261,32 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen
261
261
  */
262
262
  apply(dependency, source, templateContext) {
263
263
  const dep = /** @type {HarmonyImportSpecifierDependency} */ (dependency);
264
- const { moduleGraph, module, runtime, concatenationScope } =
265
- templateContext;
264
+ const { moduleGraph, runtime } = templateContext;
266
265
  const connection = moduleGraph.getConnection(dep);
267
266
  // Skip rendering depending when dependency is conditional
268
267
  if (connection && !connection.isTargetActive(runtime)) return;
269
268
 
270
269
  const ids = dep.getIds(moduleGraph);
270
+ const exportExpr = this._getCodeForIds(dep, source, templateContext, ids);
271
+ const range = dep.range;
272
+ if (dep.shorthand) {
273
+ source.insert(range[1], `: ${exportExpr}`);
274
+ } else {
275
+ source.replace(range[0], range[1] - 1, exportExpr);
276
+ }
277
+ }
271
278
 
279
+ /**
280
+ * @param {HarmonyImportSpecifierDependency} dep dependency
281
+ * @param {ReplaceSource} source source
282
+ * @param {DependencyTemplateContext} templateContext context
283
+ * @param {string[]} ids ids
284
+ * @returns {string} generated code
285
+ */
286
+ _getCodeForIds(dep, source, templateContext, ids) {
287
+ const { moduleGraph, module, runtime, concatenationScope } =
288
+ templateContext;
289
+ const connection = moduleGraph.getConnection(dep);
272
290
  let exportExpr;
273
291
  if (
274
292
  connection &&
@@ -299,7 +317,7 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen
299
317
  );
300
318
  }
301
319
  } else {
302
- super.apply(dependency, source, templateContext);
320
+ super.apply(dep, source, templateContext);
303
321
 
304
322
  const { runtimeTemplate, initFragments, runtimeRequirements } =
305
323
  templateContext;
@@ -320,11 +338,7 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen
320
338
  runtimeRequirements
321
339
  });
322
340
  }
323
- if (dep.shorthand) {
324
- source.insert(dep.range[1], `: ${exportExpr}`);
325
- } else {
326
- source.replace(dep.range[0], dep.range[1] - 1, exportExpr);
327
- }
341
+ return exportExpr;
328
342
  }
329
343
  };
330
344
 
@@ -8,6 +8,7 @@
8
8
  const HarmonyAcceptDependency = require("./HarmonyAcceptDependency");
9
9
  const HarmonyAcceptImportDependency = require("./HarmonyAcceptImportDependency");
10
10
  const HarmonyCompatibilityDependency = require("./HarmonyCompatibilityDependency");
11
+ const HarmonyEvaluatedImportSpecifierDependency = require("./HarmonyEvaluatedImportSpecifierDependency");
11
12
  const HarmonyExportExpressionDependency = require("./HarmonyExportExpressionDependency");
12
13
  const HarmonyExportHeaderDependency = require("./HarmonyExportHeaderDependency");
13
14
  const HarmonyExportImportedSpecifierDependency = require("./HarmonyExportImportedSpecifierDependency");
@@ -59,6 +60,15 @@ class HarmonyModulesPlugin {
59
60
  new HarmonyImportSpecifierDependency.Template()
60
61
  );
61
62
 
63
+ compilation.dependencyFactories.set(
64
+ HarmonyEvaluatedImportSpecifierDependency,
65
+ normalModuleFactory
66
+ );
67
+ compilation.dependencyTemplates.set(
68
+ HarmonyEvaluatedImportSpecifierDependency,
69
+ new HarmonyEvaluatedImportSpecifierDependency.Template()
70
+ );
71
+
62
72
  compilation.dependencyTemplates.set(
63
73
  HarmonyExportHeaderDependency,
64
74
  new HarmonyExportHeaderDependency.Template()
@@ -28,7 +28,6 @@ class ImportContextDependency extends ContextDependency {
28
28
  serialize(context) {
29
29
  const { write } = context;
30
30
 
31
- write(this.range);
32
31
  write(this.valueRange);
33
32
 
34
33
  super.serialize(context);
@@ -37,7 +36,6 @@ class ImportContextDependency extends ContextDependency {
37
36
  deserialize(context) {
38
37
  const { read } = context;
39
38
 
40
- this.range = read();
41
39
  this.valueRange = read();
42
40
 
43
41
  super.deserialize(context);
@@ -0,0 +1,35 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Ivan Kopeykin @vankop
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const makeSerializable = require("../util/makeSerializable");
9
+ const ContextDependency = require("./ContextDependency");
10
+ const ModuleDependencyTemplateAsRequireId = require("./ModuleDependencyTemplateAsRequireId");
11
+
12
+ class ImportMetaContextDependency extends ContextDependency {
13
+ constructor(options, range) {
14
+ super(options);
15
+
16
+ this.range = range;
17
+ }
18
+
19
+ get category() {
20
+ return "esm";
21
+ }
22
+
23
+ get type() {
24
+ return `import.meta.webpackContext ${this.options.mode}`;
25
+ }
26
+ }
27
+
28
+ makeSerializable(
29
+ ImportMetaContextDependency,
30
+ "webpack/lib/dependencies/ImportMetaContextDependency"
31
+ );
32
+
33
+ ImportMetaContextDependency.Template = ModuleDependencyTemplateAsRequireId;
34
+
35
+ module.exports = ImportMetaContextDependency;
@@ -0,0 +1,252 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Ivan Kopeykin @vankop
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const WebpackError = require("../WebpackError");
9
+ const {
10
+ evaluateToIdentifier
11
+ } = require("../javascript/JavascriptParserHelpers");
12
+ const ImportMetaContextDependency = require("./ImportMetaContextDependency");
13
+
14
+ /** @typedef {import("estree").Expression} ExpressionNode */
15
+ /** @typedef {import("estree").ObjectExpression} ObjectExpressionNode */
16
+ /** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
17
+ /** @typedef {import("../ContextModule").ContextModuleOptions} ContextModuleOptions */
18
+ /** @typedef {import("../ChunkGroup").RawChunkGroupOptions} RawChunkGroupOptions */
19
+ /** @typedef {Pick<ContextModuleOptions, 'mode'|'recursive'|'regExp'|'include'|'exclude'|'chunkName'>&{groupOptions: RawChunkGroupOptions, exports?: ContextModuleOptions["referencedExports"]}} ImportMetaContextOptions */
20
+
21
+ function createPropertyParseError(prop, expect) {
22
+ return createError(
23
+ `Parsing import.meta.webpackContext options failed. Unknown value for property ${JSON.stringify(
24
+ prop.key.name
25
+ )}, expected type ${expect}.`,
26
+ prop.value.loc
27
+ );
28
+ }
29
+
30
+ function createError(msg, loc) {
31
+ const error = new WebpackError(msg);
32
+ error.name = "ImportMetaContextError";
33
+ error.loc = loc;
34
+ return error;
35
+ }
36
+
37
+ module.exports = class ImportMetaContextDependencyParserPlugin {
38
+ apply(parser) {
39
+ parser.hooks.evaluateIdentifier
40
+ .for("import.meta.webpackContext")
41
+ .tap("HotModuleReplacementPlugin", expr => {
42
+ return evaluateToIdentifier(
43
+ "import.meta.webpackContext",
44
+ "import.meta",
45
+ () => ["webpackContext"],
46
+ true
47
+ )(expr);
48
+ });
49
+ parser.hooks.call
50
+ .for("import.meta.webpackContext")
51
+ .tap("ImportMetaContextDependencyParserPlugin", expr => {
52
+ if (expr.arguments.length < 1 || expr.arguments.length > 2) return;
53
+ const [directoryNode, optionsNode] = expr.arguments;
54
+ if (optionsNode && optionsNode.type !== "ObjectExpression") return;
55
+ const requestExpr = parser.evaluateExpression(directoryNode);
56
+ if (!requestExpr.isString()) return;
57
+ const request = requestExpr.string;
58
+ const errors = [];
59
+ let regExp = /^\.\/.*$/;
60
+ let recursive = true;
61
+ /** @type {ContextModuleOptions["mode"]} */
62
+ let mode = "sync";
63
+ /** @type {ContextModuleOptions["include"]} */
64
+ let include;
65
+ /** @type {ContextModuleOptions["exclude"]} */
66
+ let exclude;
67
+ /** @type {RawChunkGroupOptions} */
68
+ const groupOptions = {};
69
+ /** @type {ContextModuleOptions["chunkName"]} */
70
+ let chunkName;
71
+ /** @type {ContextModuleOptions["referencedExports"]} */
72
+ let exports;
73
+ if (optionsNode) {
74
+ for (const prop of optionsNode.properties) {
75
+ if (prop.type !== "Property" || prop.key.type !== "Identifier") {
76
+ errors.push(
77
+ createError(
78
+ "Parsing import.meta.webpackContext options failed.",
79
+ optionsNode.loc
80
+ )
81
+ );
82
+ break;
83
+ }
84
+ switch (prop.key.name) {
85
+ case "regExp": {
86
+ const regExpExpr = parser.evaluateExpression(
87
+ /** @type {ExpressionNode} */ (prop.value)
88
+ );
89
+ if (!regExpExpr.isRegExp()) {
90
+ errors.push(createPropertyParseError(prop, "RegExp"));
91
+ } else {
92
+ regExp = regExpExpr.regExp;
93
+ }
94
+ break;
95
+ }
96
+ case "include": {
97
+ const regExpExpr = parser.evaluateExpression(
98
+ /** @type {ExpressionNode} */ (prop.value)
99
+ );
100
+ if (!regExpExpr.isRegExp()) {
101
+ errors.push(createPropertyParseError(prop, "RegExp"));
102
+ } else {
103
+ include = regExpExpr.regExp;
104
+ }
105
+ break;
106
+ }
107
+ case "exclude": {
108
+ const regExpExpr = parser.evaluateExpression(
109
+ /** @type {ExpressionNode} */ (prop.value)
110
+ );
111
+ if (!regExpExpr.isRegExp()) {
112
+ errors.push(createPropertyParseError(prop, "RegExp"));
113
+ } else {
114
+ exclude = regExpExpr.regExp;
115
+ }
116
+ break;
117
+ }
118
+ case "mode": {
119
+ const modeExpr = parser.evaluateExpression(
120
+ /** @type {ExpressionNode} */ (prop.value)
121
+ );
122
+ if (!modeExpr.isString()) {
123
+ errors.push(createPropertyParseError(prop, "string"));
124
+ } else {
125
+ mode = /** @type {ContextModuleOptions["mode"]} */ (
126
+ modeExpr.string
127
+ );
128
+ }
129
+ break;
130
+ }
131
+ case "chunkName": {
132
+ const expr = parser.evaluateExpression(
133
+ /** @type {ExpressionNode} */ (prop.value)
134
+ );
135
+ if (!expr.isString()) {
136
+ errors.push(createPropertyParseError(prop, "string"));
137
+ } else {
138
+ chunkName = expr.string;
139
+ }
140
+ break;
141
+ }
142
+ case "exports": {
143
+ const expr = parser.evaluateExpression(
144
+ /** @type {ExpressionNode} */ (prop.value)
145
+ );
146
+ if (expr.isString()) {
147
+ exports = [[expr.string]];
148
+ } else if (expr.isArray()) {
149
+ const items = expr.items;
150
+ if (
151
+ items.every(i => {
152
+ if (!i.isArray()) return false;
153
+ const innerItems = i.items;
154
+ return innerItems.every(i => i.isString());
155
+ })
156
+ ) {
157
+ exports = [];
158
+ for (const i1 of items) {
159
+ const export_ = [];
160
+ for (const i2 of i1.items) {
161
+ export_.push(i2.string);
162
+ }
163
+ exports.push(export_);
164
+ }
165
+ } else {
166
+ errors.push(
167
+ createPropertyParseError(prop, "string|string[][]")
168
+ );
169
+ }
170
+ } else {
171
+ errors.push(
172
+ createPropertyParseError(prop, "string|string[][]")
173
+ );
174
+ }
175
+ break;
176
+ }
177
+ case "prefetch": {
178
+ const expr = parser.evaluateExpression(
179
+ /** @type {ExpressionNode} */ (prop.value)
180
+ );
181
+ if (expr.isBoolean()) {
182
+ groupOptions.prefetchOrder = 0;
183
+ } else if (expr.isNumber()) {
184
+ groupOptions.prefetchOrder = expr.number;
185
+ } else {
186
+ errors.push(createPropertyParseError(prop, "boolean|number"));
187
+ }
188
+ break;
189
+ }
190
+ case "preload": {
191
+ const expr = parser.evaluateExpression(
192
+ /** @type {ExpressionNode} */ (prop.value)
193
+ );
194
+ if (expr.isBoolean()) {
195
+ groupOptions.preloadOrder = 0;
196
+ } else if (expr.isNumber()) {
197
+ groupOptions.preloadOrder = expr.number;
198
+ } else {
199
+ errors.push(createPropertyParseError(prop, "boolean|number"));
200
+ }
201
+ break;
202
+ }
203
+ case "recursive": {
204
+ const recursiveExpr = parser.evaluateExpression(
205
+ /** @type {ExpressionNode} */ (prop.value)
206
+ );
207
+ if (!recursiveExpr.isBoolean()) {
208
+ errors.push(createPropertyParseError(prop, "boolean"));
209
+ } else {
210
+ recursive = recursiveExpr.bool;
211
+ }
212
+ break;
213
+ }
214
+ default:
215
+ errors.push(
216
+ createError(
217
+ `Parsing import.meta.webpackContext options failed. Unknown property ${JSON.stringify(
218
+ prop.key.name
219
+ )}.`,
220
+ optionsNode.loc
221
+ )
222
+ );
223
+ }
224
+ }
225
+ }
226
+ if (errors.length) {
227
+ for (const error of errors) parser.state.current.addError(error);
228
+ return;
229
+ }
230
+
231
+ const dep = new ImportMetaContextDependency(
232
+ {
233
+ request,
234
+ include,
235
+ exclude,
236
+ recursive,
237
+ regExp,
238
+ groupOptions,
239
+ chunkName,
240
+ referencedExports: exports,
241
+ mode,
242
+ category: "esm"
243
+ },
244
+ expr.range
245
+ );
246
+ dep.loc = expr.loc;
247
+ dep.optional = !!parser.scope.inTry;
248
+ parser.state.current.addDependency(dep);
249
+ return true;
250
+ });
251
+ }
252
+ };
@@ -0,0 +1,59 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Ivan Kopeykin @vankop
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const ContextElementDependency = require("./ContextElementDependency");
9
+ const ImportMetaContextDependency = require("./ImportMetaContextDependency");
10
+ const ImportMetaContextDependencyParserPlugin = require("./ImportMetaContextDependencyParserPlugin");
11
+
12
+ /** @typedef {import("../../declarations/WebpackOptions").ResolveOptions} ResolveOptions */
13
+ /** @typedef {import("../Compiler")} Compiler */
14
+
15
+ class ImportMetaContextPlugin {
16
+ /**
17
+ * Apply the plugin
18
+ * @param {Compiler} compiler the compiler instance
19
+ * @returns {void}
20
+ */
21
+ apply(compiler) {
22
+ compiler.hooks.compilation.tap(
23
+ "RequireContextPlugin",
24
+ (compilation, { contextModuleFactory, normalModuleFactory }) => {
25
+ compilation.dependencyFactories.set(
26
+ ImportMetaContextDependency,
27
+ contextModuleFactory
28
+ );
29
+ compilation.dependencyTemplates.set(
30
+ ImportMetaContextDependency,
31
+ new ImportMetaContextDependency.Template()
32
+ );
33
+ compilation.dependencyFactories.set(
34
+ ContextElementDependency,
35
+ normalModuleFactory
36
+ );
37
+
38
+ const handler = (parser, parserOptions) => {
39
+ if (
40
+ parserOptions.importMetaContext !== undefined &&
41
+ !parserOptions.importMetaContext
42
+ )
43
+ return;
44
+
45
+ new ImportMetaContextDependencyParserPlugin().apply(parser);
46
+ };
47
+
48
+ normalModuleFactory.hooks.parser
49
+ .for("javascript/auto")
50
+ .tap("ImportMetaContextPlugin", handler);
51
+ normalModuleFactory.hooks.parser
52
+ .for("javascript/esm")
53
+ .tap("ImportMetaContextPlugin", handler);
54
+ }
55
+ );
56
+ }
57
+ }
58
+
59
+ module.exports = ImportMetaContextPlugin;
@@ -32,6 +32,7 @@ const LoaderImportDependency = require("./LoaderImportDependency");
32
32
  * @typedef {Object} ImportModuleOptions
33
33
  * @property {string=} layer the target layer
34
34
  * @property {string=} publicPath the target public path
35
+ * @property {string=} baseUri target base uri
35
36
  */
36
37
 
37
38
  class LoaderPlugin {
@@ -199,6 +200,7 @@ class LoaderPlugin {
199
200
  referencedModule,
200
201
  {
201
202
  entryOptions: {
203
+ baseUri: options.baseUri,
202
204
  publicPath: options.publicPath
203
205
  }
204
206
  },