webpack 5.78.0 → 5.80.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 (35) hide show
  1. package/README.md +3 -0
  2. package/lib/CompatibilityPlugin.js +27 -10
  3. package/lib/Compiler.js +7 -4
  4. package/lib/DefinePlugin.js +18 -6
  5. package/lib/LibManifestPlugin.js +2 -1
  6. package/lib/NormalModuleFactory.js +11 -1
  7. package/lib/NormalModuleReplacementPlugin.js +1 -1
  8. package/lib/WarnCaseSensitiveModulesPlugin.js +12 -0
  9. package/lib/asset/AssetGenerator.js +11 -3
  10. package/lib/css/CssLoadingRuntimeModule.js +1 -1
  11. package/lib/css/CssParser.js +113 -18
  12. package/lib/css/walkCssTokens.js +134 -74
  13. package/lib/dependencies/CssUrlDependency.js +30 -18
  14. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +4 -0
  15. package/lib/dependencies/HarmonyImportSpecifierDependency.js +28 -3
  16. package/lib/dependencies/ImportMetaPlugin.js +56 -26
  17. package/lib/dependencies/ImportParserPlugin.js +17 -1
  18. package/lib/ids/OccurrenceModuleIdsPlugin.js +1 -1
  19. package/lib/index.js +5 -0
  20. package/lib/javascript/JavascriptParser.js +99 -1
  21. package/lib/schemes/DataUriPlugin.js +12 -3
  22. package/lib/stats/DefaultStatsFactoryPlugin.js +98 -25
  23. package/lib/stats/DefaultStatsPresetPlugin.js +9 -0
  24. package/lib/stats/DefaultStatsPrinterPlugin.js +18 -0
  25. package/lib/util/hash/md4.js +2 -2
  26. package/lib/util/hash/xxhash64.js +1 -1
  27. package/lib/webpack.js +1 -1
  28. package/package.json +54 -51
  29. package/schemas/WebpackOptions.check.js +1 -1
  30. package/schemas/WebpackOptions.json +8 -0
  31. package/schemas/plugins/ProgressPlugin.check.js +1 -1
  32. package/schemas/plugins/SourceMapDevToolPlugin.check.js +1 -1
  33. package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
  34. package/schemas/plugins/sharing/SharePlugin.check.js +1 -1
  35. package/types.d.ts +195 -139
@@ -36,14 +36,16 @@ const CC_FORM_FEED = "\f".charCodeAt(0);
36
36
  const CC_TAB = "\t".charCodeAt(0);
37
37
  const CC_SPACE = " ".charCodeAt(0);
38
38
 
39
- const CC_SLASH = "/".charCodeAt(0);
40
- const CC_BACK_SLASH = "\\".charCodeAt(0);
39
+ const CC_SOLIDUS = "/".charCodeAt(0);
40
+ const CC_REVERSE_SOLIDUS = "\\".charCodeAt(0);
41
41
  const CC_ASTERISK = "*".charCodeAt(0);
42
42
 
43
43
  const CC_LEFT_PARENTHESIS = "(".charCodeAt(0);
44
44
  const CC_RIGHT_PARENTHESIS = ")".charCodeAt(0);
45
45
  const CC_LEFT_CURLY = "{".charCodeAt(0);
46
46
  const CC_RIGHT_CURLY = "}".charCodeAt(0);
47
+ const CC_LEFT_SQUARE = "[".charCodeAt(0);
48
+ const CC_RIGHT_SQUARE = "]".charCodeAt(0);
47
49
 
48
50
  const CC_QUOTATION_MARK = '"'.charCodeAt(0);
49
51
  const CC_APOSTROPHE = "'".charCodeAt(0);
@@ -62,6 +64,7 @@ const CC_LOWER_E = "e".charCodeAt(0);
62
64
  const CC_LOWER_Z = "z".charCodeAt(0);
63
65
  const CC_UPPER_A = "A".charCodeAt(0);
64
66
  const CC_UPPER_E = "E".charCodeAt(0);
67
+ const CC_UPPER_U = "U".charCodeAt(0);
65
68
  const CC_UPPER_Z = "Z".charCodeAt(0);
66
69
  const CC_0 = "0".charCodeAt(0);
67
70
  const CC_9 = "9".charCodeAt(0);
@@ -99,28 +102,46 @@ const _isWhiteSpace = cc => {
99
102
  );
100
103
  };
101
104
 
105
+ const _isIdentStartCodePoint = cc => {
106
+ return (
107
+ (cc >= CC_LOWER_A && cc <= CC_LOWER_Z) ||
108
+ (cc >= CC_UPPER_A && cc <= CC_UPPER_Z) ||
109
+ cc === CC_LOW_LINE ||
110
+ cc >= 0x80
111
+ );
112
+ };
113
+
102
114
  /** @type {CharHandler} */
103
- const consumeSingleCharToken = (input, pos, callbacks) => {
115
+ const consumeDelimToken = (input, pos, callbacks) => {
104
116
  return pos + 1;
105
117
  };
106
118
 
107
119
  /** @type {CharHandler} */
108
- const consumePotentialComment = (input, pos, callbacks) => {
109
- pos++;
110
- if (pos === input.length) return pos;
111
- let cc = input.charCodeAt(pos);
112
- if (cc !== CC_ASTERISK) return pos;
113
- for (;;) {
114
- pos++;
115
- if (pos === input.length) return pos;
116
- cc = input.charCodeAt(pos);
117
- while (cc === CC_ASTERISK) {
120
+ const consumeComments = (input, pos, callbacks) => {
121
+ // If the next two input code point are U+002F SOLIDUS (/) followed by a U+002A
122
+ // ASTERISK (*), consume them and all following code points up to and including
123
+ // the first U+002A ASTERISK (*) followed by a U+002F SOLIDUS (/), or up to an
124
+ // EOF code point. Return to the start of this step.
125
+ //
126
+ // If the preceding paragraph ended by consuming an EOF code point, this is a parse error.
127
+ // But we are silent on errors.
128
+ if (
129
+ input.charCodeAt(pos) === CC_SOLIDUS &&
130
+ input.charCodeAt(pos + 1) === CC_ASTERISK
131
+ ) {
132
+ pos += 1;
133
+ while (pos < input.length) {
134
+ if (
135
+ input.charCodeAt(pos) === CC_ASTERISK &&
136
+ input.charCodeAt(pos + 1) === CC_SOLIDUS
137
+ ) {
138
+ pos += 2;
139
+ break;
140
+ }
118
141
  pos++;
119
- if (pos === input.length) return pos;
120
- cc = input.charCodeAt(pos);
121
- if (cc === CC_SLASH) return pos + 1;
122
142
  }
123
143
  }
144
+ return pos;
124
145
  };
125
146
 
126
147
  /** @type {function(number): CharHandler} */
@@ -143,7 +164,7 @@ const _consumeString = (input, pos, end) => {
143
164
  // bad string
144
165
  return pos;
145
166
  }
146
- if (cc === CC_BACK_SLASH) {
167
+ if (cc === CC_REVERSE_SOLIDUS) {
147
168
  // we don't need to fully parse the escaped code point
148
169
  // just skip over a potential new line
149
170
  pos++;
@@ -164,6 +185,12 @@ const _isIdentifierStartCode = cc => {
164
185
  );
165
186
  };
166
187
 
188
+ const _isTwoCodePointsAreValidEscape = (first, second) => {
189
+ if (first !== CC_REVERSE_SOLIDUS) return false;
190
+ if (_isNewLine(second)) return false;
191
+ return true;
192
+ };
193
+
167
194
  const _isDigit = cc => {
168
195
  return cc >= CC_0 && cc <= CC_9;
169
196
  };
@@ -174,13 +201,13 @@ const _startsIdentifier = (input, pos) => {
174
201
  if (pos === input.length) return false;
175
202
  const cc = input.charCodeAt(pos + 1);
176
203
  if (cc === CC_HYPHEN_MINUS) return true;
177
- if (cc === CC_BACK_SLASH) {
204
+ if (cc === CC_REVERSE_SOLIDUS) {
178
205
  const cc = input.charCodeAt(pos + 2);
179
206
  return !_isNewLine(cc);
180
207
  }
181
208
  return _isIdentifierStartCode(cc);
182
209
  }
183
- if (cc === CC_BACK_SLASH) {
210
+ if (cc === CC_REVERSE_SOLIDUS) {
184
211
  const cc = input.charCodeAt(pos + 1);
185
212
  return !_isNewLine(cc);
186
213
  }
@@ -207,6 +234,7 @@ const consumeMinus = (input, pos, callbacks) => {
207
234
  pos++;
208
235
  if (pos === input.length) return pos;
209
236
  const cc = input.charCodeAt(pos);
237
+ // If the input stream starts with a number, reconsume the current input code point, consume a numeric token, and return it.
210
238
  if (cc === CC_FULL_STOP || _isDigit(cc)) {
211
239
  return consumeNumericToken(input, pos, callbacks);
212
240
  } else if (cc === CC_HYPHEN_MINUS) {
@@ -221,7 +249,7 @@ const consumeMinus = (input, pos, callbacks) => {
221
249
  return callbacks.identifier(input, start, pos);
222
250
  }
223
251
  }
224
- } else if (cc === CC_BACK_SLASH) {
252
+ } else if (cc === CC_REVERSE_SOLIDUS) {
225
253
  if (pos + 1 === input.length) return pos;
226
254
  const cc = input.charCodeAt(pos + 1);
227
255
  if (_isNewLine(cc)) return pos;
@@ -230,11 +258,7 @@ const consumeMinus = (input, pos, callbacks) => {
230
258
  return callbacks.identifier(input, start, pos);
231
259
  }
232
260
  } else if (_isIdentifierStartCode(cc)) {
233
- pos++;
234
- pos = _consumeIdentifier(input, pos);
235
- if (callbacks.identifier !== undefined) {
236
- return callbacks.identifier(input, start, pos);
237
- }
261
+ pos = consumeOtherIdentifier(input, pos - 1, callbacks);
238
262
  }
239
263
  return pos;
240
264
  };
@@ -288,7 +312,11 @@ const consumeOtherIdentifier = (input, pos, callbacks) => {
288
312
  const consumePotentialUrl = (input, pos, callbacks) => {
289
313
  const start = pos;
290
314
  pos = _consumeIdentifier(input, pos);
291
- if (pos === start + 3 && input.slice(start, pos + 1) === "url(") {
315
+ const nextPos = pos + 1;
316
+ if (
317
+ pos === start + 3 &&
318
+ input.slice(start, nextPos).toLowerCase() === "url("
319
+ ) {
292
320
  pos++;
293
321
  let cc = input.charCodeAt(pos);
294
322
  while (_isWhiteSpace(cc)) {
@@ -297,26 +325,15 @@ const consumePotentialUrl = (input, pos, callbacks) => {
297
325
  cc = input.charCodeAt(pos);
298
326
  }
299
327
  if (cc === CC_QUOTATION_MARK || cc === CC_APOSTROPHE) {
300
- pos++;
301
- const contentStart = pos;
302
- pos = _consumeString(input, pos, cc);
303
- const contentEnd = pos - 1;
304
- cc = input.charCodeAt(pos);
305
- while (_isWhiteSpace(cc)) {
306
- pos++;
307
- if (pos === input.length) return pos;
308
- cc = input.charCodeAt(pos);
328
+ if (callbacks.function !== undefined) {
329
+ return callbacks.function(input, start, nextPos);
309
330
  }
310
- if (cc !== CC_RIGHT_PARENTHESIS) return pos;
311
- pos++;
312
- if (callbacks.url !== undefined)
313
- return callbacks.url(input, start, pos, contentStart, contentEnd);
314
- return pos;
331
+ return nextPos;
315
332
  } else {
316
333
  const contentStart = pos;
317
334
  let contentEnd;
318
335
  for (;;) {
319
- if (cc === CC_BACK_SLASH) {
336
+ if (cc === CC_REVERSE_SOLIDUS) {
320
337
  pos++;
321
338
  if (pos === input.length) return pos;
322
339
  pos++;
@@ -435,7 +452,7 @@ const consumeComma = (input, pos, callbacks) => {
435
452
  const _consumeIdentifier = (input, pos) => {
436
453
  for (;;) {
437
454
  const cc = input.charCodeAt(pos);
438
- if (cc === CC_BACK_SLASH) {
455
+ if (cc === CC_REVERSE_SOLIDUS) {
439
456
  pos++;
440
457
  if (pos === input.length) return pos;
441
458
  pos++;
@@ -509,7 +526,6 @@ const consumeLessThan = (input, pos, callbacks) => {
509
526
  return pos + 1;
510
527
  };
511
528
 
512
- /** @type {CharHandler} */
513
529
  const consumeAt = (input, pos, callbacks) => {
514
530
  const start = pos;
515
531
  pos++;
@@ -523,64 +539,102 @@ const consumeAt = (input, pos, callbacks) => {
523
539
  return pos;
524
540
  };
525
541
 
542
+ /** @type {CharHandler} */
543
+ const consumeReverseSolidus = (input, pos, callbacks) => {
544
+ const start = pos;
545
+ pos++;
546
+ if (pos === input.length) return pos;
547
+ // If the input stream starts with a valid escape, reconsume the current input code point, consume an ident-like token, and return it.
548
+ if (
549
+ _isTwoCodePointsAreValidEscape(
550
+ input.charCodeAt(start),
551
+ input.charCodeAt(pos)
552
+ )
553
+ ) {
554
+ return consumeOtherIdentifier(input, pos - 1, callbacks);
555
+ }
556
+ // Otherwise, this is a parse error. Return a <delim-token> with its value set to the current input code point.
557
+ return pos;
558
+ };
559
+
526
560
  const CHAR_MAP = Array.from({ length: 0x80 }, (_, cc) => {
527
561
  // https://drafts.csswg.org/css-syntax/#consume-token
528
562
  switch (cc) {
563
+ // whitespace
529
564
  case CC_LINE_FEED:
530
565
  case CC_CARRIAGE_RETURN:
531
566
  case CC_FORM_FEED:
532
567
  case CC_TAB:
533
568
  case CC_SPACE:
534
569
  return consumeSpace;
570
+ // U+0022 QUOTATION MARK (")
535
571
  case CC_QUOTATION_MARK:
536
- case CC_APOSTROPHE:
537
572
  return consumeString(cc);
573
+ // U+0023 NUMBER SIGN (#)
538
574
  case CC_NUMBER_SIGN:
539
575
  return consumeNumberSign;
540
- case CC_SLASH:
541
- return consumePotentialComment;
542
- // case CC_LEFT_SQUARE:
543
- // case CC_RIGHT_SQUARE:
544
- // case CC_COMMA:
545
- // case CC_COLON:
546
- // return consumeSingleCharToken;
547
- case CC_COMMA:
548
- return consumeComma;
549
- case CC_SEMICOLON:
550
- return consumeSemicolon;
576
+ // U+0027 APOSTROPHE (')
577
+ case CC_APOSTROPHE:
578
+ return consumeString(cc);
579
+ // U+0028 LEFT PARENTHESIS (()
551
580
  case CC_LEFT_PARENTHESIS:
552
581
  return consumeLeftParenthesis;
582
+ // U+0029 RIGHT PARENTHESIS ())
553
583
  case CC_RIGHT_PARENTHESIS:
554
584
  return consumeRightParenthesis;
555
- case CC_LEFT_CURLY:
556
- return consumeLeftCurlyBracket;
557
- case CC_RIGHT_CURLY:
558
- return consumeRightCurlyBracket;
559
- case CC_COLON:
560
- return consumePotentialPseudo;
585
+ // U+002B PLUS SIGN (+)
561
586
  case CC_PLUS_SIGN:
562
587
  return consumeNumericToken;
563
- case CC_FULL_STOP:
564
- return consumeDot;
588
+ // U+002C COMMA (,)
589
+ case CC_COMMA:
590
+ return consumeComma;
591
+ // U+002D HYPHEN-MINUS (-)
565
592
  case CC_HYPHEN_MINUS:
566
593
  return consumeMinus;
594
+ // U+002E FULL STOP (.)
595
+ case CC_FULL_STOP:
596
+ return consumeDot;
597
+ // U+003A COLON (:)
598
+ case CC_COLON:
599
+ return consumePotentialPseudo;
600
+ // U+003B SEMICOLON (;)
601
+ case CC_SEMICOLON:
602
+ return consumeSemicolon;
603
+ // U+003C LESS-THAN SIGN (<)
567
604
  case CC_LESS_THAN_SIGN:
568
605
  return consumeLessThan;
606
+ // U+0040 COMMERCIAL AT (@)
569
607
  case CC_AT_SIGN:
570
608
  return consumeAt;
609
+ // U+005B LEFT SQUARE BRACKET ([)
610
+ case CC_LEFT_SQUARE:
611
+ return consumeDelimToken;
612
+ // U+005C REVERSE SOLIDUS (\)
613
+ case CC_REVERSE_SOLIDUS:
614
+ return consumeReverseSolidus;
615
+ // U+005D RIGHT SQUARE BRACKET (])
616
+ case CC_RIGHT_SQUARE:
617
+ return consumeDelimToken;
618
+ // U+007B LEFT CURLY BRACKET ({)
619
+ case CC_LEFT_CURLY:
620
+ return consumeLeftCurlyBracket;
621
+ // U+007D RIGHT CURLY BRACKET (})
622
+ case CC_RIGHT_CURLY:
623
+ return consumeRightCurlyBracket;
624
+ // Optimization
571
625
  case CC_LOWER_U:
626
+ case CC_UPPER_U:
572
627
  return consumePotentialUrl;
573
- case CC_LOW_LINE:
574
- return consumeOtherIdentifier;
575
628
  default:
629
+ // digit
576
630
  if (_isDigit(cc)) return consumeNumericToken;
577
- if (
578
- (cc >= CC_LOWER_A && cc <= CC_LOWER_Z) ||
579
- (cc >= CC_UPPER_A && cc <= CC_UPPER_Z)
580
- ) {
631
+ // ident-start code point
632
+ if (_isIdentStartCodePoint(cc)) {
581
633
  return consumeOtherIdentifier;
582
634
  }
583
- return consumeSingleCharToken;
635
+ // EOF, but we don't have it
636
+ // anything else
637
+ return consumeDelimToken;
584
638
  }
585
639
  });
586
640
 
@@ -590,9 +644,15 @@ const CHAR_MAP = Array.from({ length: 0x80 }, (_, cc) => {
590
644
  * @returns {void}
591
645
  */
592
646
  module.exports = (input, callbacks) => {
647
+ // This section describes how to consume a token from a stream of code points. It will return a single token of any type.
593
648
  let pos = 0;
594
649
  while (pos < input.length) {
650
+ // Consume comments.
651
+ pos = consumeComments(input, pos, callbacks);
652
+
595
653
  const cc = input.charCodeAt(pos);
654
+
655
+ // Consume the next input code point.
596
656
  if (cc < 0x80) {
597
657
  pos = CHAR_MAP[cc](input, pos, callbacks);
598
658
  } else {
@@ -604,7 +664,7 @@ module.exports = (input, callbacks) => {
604
664
  module.exports.eatComments = (input, pos) => {
605
665
  loop: for (;;) {
606
666
  const cc = input.charCodeAt(pos);
607
- if (cc === CC_SLASH) {
667
+ if (cc === CC_SOLIDUS) {
608
668
  if (pos === input.length) return pos;
609
669
  let cc = input.charCodeAt(pos + 1);
610
670
  if (cc !== CC_ASTERISK) return pos;
@@ -617,7 +677,7 @@ module.exports.eatComments = (input, pos) => {
617
677
  pos++;
618
678
  if (pos === input.length) return pos;
619
679
  cc = input.charCodeAt(pos);
620
- if (cc === CC_SLASH) {
680
+ if (cc === CC_SOLIDUS) {
621
681
  pos++;
622
682
  continue loop;
623
683
  }
@@ -631,7 +691,7 @@ module.exports.eatComments = (input, pos) => {
631
691
  module.exports.eatWhitespaceAndComments = (input, pos) => {
632
692
  loop: for (;;) {
633
693
  const cc = input.charCodeAt(pos);
634
- if (cc === CC_SLASH) {
694
+ if (cc === CC_SOLIDUS) {
635
695
  if (pos === input.length) return pos;
636
696
  let cc = input.charCodeAt(pos + 1);
637
697
  if (cc !== CC_ASTERISK) return pos;
@@ -644,7 +704,7 @@ module.exports.eatWhitespaceAndComments = (input, pos) => {
644
704
  pos++;
645
705
  if (pos === input.length) return pos;
646
706
  cc = input.charCodeAt(pos);
647
- if (cc === CC_SLASH) {
707
+ if (cc === CC_SOLIDUS) {
648
708
  pos++;
649
709
  continue loop;
650
710
  }
@@ -27,12 +27,12 @@ class CssUrlDependency extends ModuleDependency {
27
27
  /**
28
28
  * @param {string} request request
29
29
  * @param {[number, number]} range range of the argument
30
- * @param {string} cssFunctionKind kind of css function, e. g. url(), image()
30
+ * @param {"string" | "url"} urlType dependency type e.g. url() or string
31
31
  */
32
- constructor(request, range, cssFunctionKind) {
32
+ constructor(request, range, urlType) {
33
33
  super(request);
34
34
  this.range = range;
35
- this.cssFunctionKind = cssFunctionKind;
35
+ this.urlType = urlType;
36
36
  }
37
37
 
38
38
  get type() {
@@ -54,13 +54,13 @@ class CssUrlDependency extends ModuleDependency {
54
54
 
55
55
  serialize(context) {
56
56
  const { write } = context;
57
- write(this.cssFunctionKind);
57
+ write(this.urlType);
58
58
  super.serialize(context);
59
59
  }
60
60
 
61
61
  deserialize(context) {
62
62
  const { read } = context;
63
- this.cssFunctionKind = read();
63
+ this.urlType = read();
64
64
  super.deserialize(context);
65
65
  }
66
66
  }
@@ -108,22 +108,34 @@ CssUrlDependency.Template = class CssUrlDependencyTemplate extends (
108
108
  apply(
109
109
  dependency,
110
110
  source,
111
- { runtime, moduleGraph, runtimeTemplate, codeGenerationResults }
111
+ { moduleGraph, runtimeTemplate, codeGenerationResults }
112
112
  ) {
113
113
  const dep = /** @type {CssUrlDependency} */ (dependency);
114
114
 
115
- source.replace(
116
- dep.range[0],
117
- dep.range[1] - 1,
118
- `${dep.cssFunctionKind}(${cssEscapeString(
119
- runtimeTemplate.assetUrl({
120
- publicPath: "",
121
- runtime,
122
- module: moduleGraph.getModule(dep),
123
- codeGenerationResults
124
- })
125
- )})`
126
- );
115
+ let newValue;
116
+
117
+ switch (dep.urlType) {
118
+ case "string":
119
+ newValue = cssEscapeString(
120
+ runtimeTemplate.assetUrl({
121
+ publicPath: "",
122
+ module: moduleGraph.getModule(dep),
123
+ codeGenerationResults
124
+ })
125
+ );
126
+ break;
127
+ case "url":
128
+ newValue = `url(${cssEscapeString(
129
+ runtimeTemplate.assetUrl({
130
+ publicPath: "",
131
+ module: moduleGraph.getModule(dep),
132
+ codeGenerationResults
133
+ })
134
+ )})`;
135
+ break;
136
+ }
137
+
138
+ source.replace(dep.range[0], dep.range[1] - 1, newValue);
127
139
  }
128
140
  };
129
141
 
@@ -196,6 +196,8 @@ module.exports = class HarmonyImportDependencyParserPlugin {
196
196
  exportPresenceMode,
197
197
  settings.assertions
198
198
  );
199
+ dep.referencedPropertiesInDestructuring =
200
+ parser.destructuringAssignmentPropertiesFor(expr);
199
201
  dep.shorthand = parser.scope.inShorthand;
200
202
  dep.directImport = true;
201
203
  dep.asiSafe = !parser.isAsiPosition(expr.range[0]);
@@ -233,6 +235,8 @@ module.exports = class HarmonyImportDependencyParserPlugin {
233
235
  exportPresenceMode,
234
236
  settings.assertions
235
237
  );
238
+ dep.referencedPropertiesInDestructuring =
239
+ parser.destructuringAssignmentPropertiesFor(expr);
236
240
  dep.asiSafe = !parser.isAsiPosition(expr.range[0]);
237
241
  dep.loc = expr.loc;
238
242
  parser.state.module.addDependency(dep);
@@ -52,6 +52,8 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
52
52
  this.asiSafe = undefined;
53
53
  /** @type {Set<string> | boolean} */
54
54
  this.usedByExports = undefined;
55
+ /** @type {Set<string>} */
56
+ this.referencedPropertiesInDestructuring = undefined;
55
57
  }
56
58
 
57
59
  // TODO webpack 6 remove
@@ -121,7 +123,7 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
121
123
  */
122
124
  getReferencedExports(moduleGraph, runtime) {
123
125
  let ids = this.getIds(moduleGraph);
124
- if (ids.length === 0) return Dependency.EXPORTS_OBJECT_REFERENCED;
126
+ if (ids.length === 0) return this._getReferencedExportsInDestructuring();
125
127
  let namespaceObjectAsContext = this.namespaceObjectAsContext;
126
128
  if (ids[0] === "default") {
127
129
  const selfModule = moduleGraph.getParentModule(this);
@@ -134,7 +136,8 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
134
136
  ) {
135
137
  case "default-only":
136
138
  case "default-with-named":
137
- if (ids.length === 1) return Dependency.EXPORTS_OBJECT_REFERENCED;
139
+ if (ids.length === 1)
140
+ return this._getReferencedExportsInDestructuring();
138
141
  ids = ids.slice(1);
139
142
  namespaceObjectAsContext = true;
140
143
  break;
@@ -152,7 +155,27 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
152
155
  ids = ids.slice(0, -1);
153
156
  }
154
157
 
155
- return [ids];
158
+ return this._getReferencedExportsInDestructuring(ids);
159
+ }
160
+
161
+ /**
162
+ * @param {string[]=} ids ids
163
+ * @returns {(string[] | ReferencedExport)[]} referenced exports
164
+ */
165
+ _getReferencedExportsInDestructuring(ids) {
166
+ if (this.referencedPropertiesInDestructuring) {
167
+ /** @type {ReferencedExport[]} */
168
+ const refs = [];
169
+ for (const key of this.referencedPropertiesInDestructuring) {
170
+ refs.push({
171
+ name: ids ? ids.concat([key]) : [key],
172
+ canMangle: false
173
+ });
174
+ }
175
+ return refs;
176
+ } else {
177
+ return ids ? [ids] : Dependency.EXPORTS_OBJECT_REFERENCED;
178
+ }
156
179
  }
157
180
 
158
181
  /**
@@ -226,6 +249,7 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
226
249
  write(this.shorthand);
227
250
  write(this.asiSafe);
228
251
  write(this.usedByExports);
252
+ write(this.referencedPropertiesInDestructuring);
229
253
  super.serialize(context);
230
254
  }
231
255
 
@@ -241,6 +265,7 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
241
265
  this.shorthand = read();
242
266
  this.asiSafe = read();
243
267
  this.usedByExports = read();
268
+ this.referencedPropertiesInDestructuring = read();
244
269
  super.deserialize(context);
245
270
  }
246
271
  }
@@ -75,6 +75,17 @@ class ImportMetaPlugin {
75
75
  }
76
76
 
77
77
  /// import.meta direct ///
78
+ const webpackVersion = parseInt(
79
+ require("../../package.json").version,
80
+ 10
81
+ );
82
+ const importMetaUrl = () =>
83
+ JSON.stringify(getUrl(parser.state.module));
84
+ const importMetaWebpackVersion = () => JSON.stringify(webpackVersion);
85
+ const importMetaUnknownProperty = members =>
86
+ `${Template.toNormalComment(
87
+ "unsupported import.meta." + members.join(".")
88
+ )} undefined${propertyAccess(members, 1)}`;
78
89
  parser.hooks.typeof
79
90
  .for("import.meta")
80
91
  .tap(
@@ -84,20 +95,48 @@ class ImportMetaPlugin {
84
95
  parser.hooks.expression
85
96
  .for("import.meta")
86
97
  .tap(PLUGIN_NAME, metaProperty => {
87
- const CriticalDependencyWarning = getCriticalDependencyWarning();
88
- parser.state.module.addWarning(
89
- new ModuleDependencyWarning(
90
- parser.state.module,
91
- new CriticalDependencyWarning(
92
- "Accessing import.meta directly is unsupported (only property access is supported)"
93
- ),
94
- metaProperty.loc
95
- )
96
- );
97
- const dep = new ConstDependency(
98
- `${parser.isAsiPosition(metaProperty.range[0]) ? ";" : ""}({})`,
99
- metaProperty.range
100
- );
98
+ const referencedPropertiesInDestructuring =
99
+ parser.destructuringAssignmentPropertiesFor(metaProperty);
100
+ if (!referencedPropertiesInDestructuring) {
101
+ const CriticalDependencyWarning =
102
+ getCriticalDependencyWarning();
103
+ parser.state.module.addWarning(
104
+ new ModuleDependencyWarning(
105
+ parser.state.module,
106
+ new CriticalDependencyWarning(
107
+ "Accessing import.meta directly is unsupported (only property access or destructuring is supported)"
108
+ ),
109
+ metaProperty.loc
110
+ )
111
+ );
112
+ const dep = new ConstDependency(
113
+ `${
114
+ parser.isAsiPosition(metaProperty.range[0]) ? ";" : ""
115
+ }({})`,
116
+ metaProperty.range
117
+ );
118
+ dep.loc = metaProperty.loc;
119
+ parser.state.module.addPresentationalDependency(dep);
120
+ return true;
121
+ }
122
+
123
+ let str = "";
124
+ for (const prop of referencedPropertiesInDestructuring) {
125
+ switch (prop) {
126
+ case "url":
127
+ str += `url: ${importMetaUrl()},`;
128
+ break;
129
+ case "webpack":
130
+ str += `webpack: ${importMetaWebpackVersion()},`;
131
+ break;
132
+ default:
133
+ str += `[${JSON.stringify(
134
+ prop
135
+ )}]: ${importMetaUnknownProperty([prop])},`;
136
+ break;
137
+ }
138
+ }
139
+ const dep = new ConstDependency(`({${str}})`, metaProperty.range);
101
140
  dep.loc = metaProperty.loc;
102
141
  parser.state.module.addPresentationalDependency(dep);
103
142
  return true;
@@ -120,10 +159,7 @@ class ImportMetaPlugin {
120
159
  parser.hooks.expression
121
160
  .for("import.meta.url")
122
161
  .tap(PLUGIN_NAME, expr => {
123
- const dep = new ConstDependency(
124
- JSON.stringify(getUrl(parser.state.module)),
125
- expr.range
126
- );
162
+ const dep = new ConstDependency(importMetaUrl(), expr.range);
127
163
  dep.loc = expr.loc;
128
164
  parser.state.module.addPresentationalDependency(dep);
129
165
  return true;
@@ -140,10 +176,6 @@ class ImportMetaPlugin {
140
176
  });
141
177
 
142
178
  /// import.meta.webpack ///
143
- const webpackVersion = parseInt(
144
- require("../../package.json").version,
145
- 10
146
- );
147
179
  parser.hooks.typeof
148
180
  .for("import.meta.webpack")
149
181
  .tap(
@@ -154,7 +186,7 @@ class ImportMetaPlugin {
154
186
  .for("import.meta.webpack")
155
187
  .tap(
156
188
  PLUGIN_NAME,
157
- toConstantDependency(parser, JSON.stringify(webpackVersion))
189
+ toConstantDependency(parser, importMetaWebpackVersion())
158
190
  );
159
191
  parser.hooks.evaluateTypeof
160
192
  .for("import.meta.webpack")
@@ -168,9 +200,7 @@ class ImportMetaPlugin {
168
200
  .for("import.meta")
169
201
  .tap(PLUGIN_NAME, (expr, members) => {
170
202
  const dep = new ConstDependency(
171
- `${Template.toNormalComment(
172
- "unsupported import.meta." + members.join(".")
173
- )} undefined${propertyAccess(members, 1)}`,
203
+ importMetaUnknownProperty(members),
174
204
  expr.range
175
205
  );
176
206
  dep.loc = expr.loc;