terser 5.47.1 → 5.48.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## v5.48.0
4
+
5
+ - Support `import source ...` and `import defer ...` (#1682)
6
+
3
7
  ## v5.47.1
4
8
 
5
9
  - Fix crash when using `mangle.keep_fnames` with destructuring
@@ -2578,7 +2578,7 @@ function parse($TEXT, options) {
2578
2578
  return new_(allow_calls);
2579
2579
  }
2580
2580
  if (is("name", "import") && is_token(peek(), "punc", ".")) {
2581
- return import_meta(allow_calls);
2581
+ return parse_import_expr(allow_calls);
2582
2582
  }
2583
2583
  var start = S.token;
2584
2584
  var peeked;
@@ -3018,6 +3018,17 @@ function parse($TEXT, options) {
3018
3018
  function import_statement() {
3019
3019
  var start = prev();
3020
3020
 
3021
+ // import source x from "..."
3022
+ // import defer * as x from "..."
3023
+ var phase = null;
3024
+ if (is("name", "source") || is("name", "defer")) {
3025
+ var peeked = peek();
3026
+ if (!is_token(peeked, "name", "from") && !is_token(peeked, "punc", ",")) {
3027
+ phase = S.token.value;
3028
+ next();
3029
+ }
3030
+ }
3031
+
3021
3032
  var imported_name;
3022
3033
  var imported_names;
3023
3034
  if (is("name")) {
@@ -3052,14 +3063,33 @@ function parse($TEXT, options) {
3052
3063
  end: mod_str,
3053
3064
  }),
3054
3065
  attributes,
3066
+ phase,
3055
3067
  end: S.token,
3056
3068
  });
3057
3069
  }
3058
3070
 
3059
- function import_meta(allow_calls) {
3071
+ // import.meta
3072
+ // import.source("module")
3073
+ // import.defer("module")
3074
+ function parse_import_expr(allow_calls) {
3060
3075
  var start = S.token;
3061
3076
  expect_token("name", "import");
3062
3077
  expect_token("punc", ".");
3078
+ if (is("name", "source") || is("name", "defer")) {
3079
+ var phase = S.token.value;
3080
+ next();
3081
+ if (!is("punc", "(")) {
3082
+ croak("'import." + phase + "' can only be used in a dynamic import");
3083
+ }
3084
+ next();
3085
+ var args = expr_list(")");
3086
+ return subscripts(new AST_DynamicImport({
3087
+ start: start,
3088
+ phase: phase,
3089
+ args: args,
3090
+ end: prev()
3091
+ }), allow_calls);
3092
+ }
3063
3093
  expect_token("name", "meta");
3064
3094
  return subscripts(new AST_ImportMeta({
3065
3095
  start: start,
@@ -5292,9 +5322,10 @@ var AST_NameMapping = DEFNODE("NameMapping", "foreign_name name", function AST_N
5292
5322
 
5293
5323
  var AST_Import = DEFNODE(
5294
5324
  "Import",
5295
- "imported_name imported_names module_name attributes",
5325
+ "phase imported_name imported_names module_name attributes",
5296
5326
  function AST_Import(props) {
5297
5327
  if (props) {
5328
+ this.phase = props.phase;
5298
5329
  this.imported_name = props.imported_name;
5299
5330
  this.imported_names = props.imported_names;
5300
5331
  this.module_name = props.module_name;
@@ -5308,6 +5339,7 @@ var AST_Import = DEFNODE(
5308
5339
  {
5309
5340
  $documentation: "An `import` statement",
5310
5341
  $propdoc: {
5342
+ phase: "[string?] Phase keyword: 'source', 'defer', or null.",
5311
5343
  imported_name: "[AST_SymbolImport] The name of the variable holding the module's default export.",
5312
5344
  imported_names: "[AST_NameMapping*] The names of non-default imported variables",
5313
5345
  module_name: "[AST_String] String literal describing where this module came from",
@@ -5348,6 +5380,40 @@ var AST_ImportMeta = DEFNODE("ImportMeta", null, function AST_ImportMeta(props)
5348
5380
  $documentation: "A reference to import.meta",
5349
5381
  });
5350
5382
 
5383
+ var AST_DynamicImport = DEFNODE(
5384
+ "DynamicImport",
5385
+ "phase args",
5386
+ function AST_DynamicImport(props) {
5387
+ if (props) {
5388
+ this.phase = props.phase;
5389
+ this.args = props.args;
5390
+ this.start = props.start;
5391
+ this.end = props.end;
5392
+ }
5393
+
5394
+ this.flags = 0;
5395
+ },
5396
+ {
5397
+ $documentation: "A phased dynamic import expression: `import.source(specifier [, options])` or `import.defer(specifier [, options])`. Plain `import(x)` continues to be parsed as an AST_Call with a synthetic `import` SymbolRef callee.",
5398
+ $propdoc: {
5399
+ phase: "[string] Phase keyword ('source' or 'defer').",
5400
+ args: "[AST_Node*] specifier followed by optional options argument"
5401
+ },
5402
+ _walk: function(visitor) {
5403
+ return visitor._visit(this, function() {
5404
+ var args = this.args;
5405
+ for (var i = 0, len = args.length; i < len; i++) {
5406
+ args[i]._walk(visitor);
5407
+ }
5408
+ });
5409
+ },
5410
+ _children_backwards(push) {
5411
+ let i = this.args.length;
5412
+ while (i--) push(this.args[i]);
5413
+ },
5414
+ }
5415
+ );
5416
+
5351
5417
  var AST_Export = DEFNODE(
5352
5418
  "Export",
5353
5419
  "exported_definition exported_value is_default exported_names module_name attributes",
@@ -7811,7 +7877,8 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
7811
7877
  imported_name: imported_name,
7812
7878
  imported_names : imported_names,
7813
7879
  module_name : from_moz(M.source),
7814
- attributes: import_attributes_from_moz(M.attributes || M.assertions)
7880
+ attributes: import_attributes_from_moz(M.attributes || M.assertions),
7881
+ phase: M.phase || null
7815
7882
  });
7816
7883
  },
7817
7884
 
@@ -7842,6 +7909,14 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
7842
7909
  if (M.options) {
7843
7910
  args.push(from_moz(M.options));
7844
7911
  }
7912
+ if (M.phase) {
7913
+ return new AST_DynamicImport({
7914
+ start: my_start_token(M),
7915
+ end: my_end_token(M),
7916
+ phase: M.phase,
7917
+ args: args
7918
+ });
7919
+ }
7845
7920
  return new AST_Call({
7846
7921
  start: my_start_token(M),
7847
7922
  end: my_end_token(M),
@@ -8441,6 +8516,16 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
8441
8516
  };
8442
8517
  });
8443
8518
 
8519
+ def_to_moz(AST_DynamicImport, function To_Moz_ImportExpression(M) {
8520
+ const [source, options] = M.args.map(to_moz);
8521
+ return {
8522
+ type: "ImportExpression",
8523
+ source,
8524
+ options: options || null,
8525
+ phase: M.phase
8526
+ };
8527
+ });
8528
+
8444
8529
  def_to_moz(AST_Toplevel, function To_Moz_Program(M) {
8445
8530
  return to_moz_scope("Program", M);
8446
8531
  });
@@ -8705,12 +8790,14 @@ def_transform(AST_PrefixedTemplateString, function(self, tw) {
8705
8790
  });
8706
8791
  }
8707
8792
  }
8708
- return {
8793
+ var moz = {
8709
8794
  type: "ImportDeclaration",
8710
8795
  specifiers: specifiers,
8711
8796
  source: to_moz(M.module_name),
8712
8797
  attributes: import_attributes_to_moz(M.attributes)
8713
8798
  };
8799
+ if (M.phase) moz.phase = M.phase;
8800
+ return moz;
8714
8801
  });
8715
8802
 
8716
8803
  def_to_moz(AST_ImportMeta, function To_Moz_MetaProperty() {
@@ -11003,6 +11090,10 @@ function OutputStream(options) {
11003
11090
  DEFPRINT(AST_Import, function(self, output) {
11004
11091
  output.print("import");
11005
11092
  output.space();
11093
+ if (self.phase) {
11094
+ output.print(self.phase);
11095
+ output.space();
11096
+ }
11006
11097
  if (self.imported_name) {
11007
11098
  self.imported_name.print(output);
11008
11099
  }
@@ -11043,6 +11134,15 @@ function OutputStream(options) {
11043
11134
  DEFPRINT(AST_ImportMeta, function(self, output) {
11044
11135
  output.print("import.meta");
11045
11136
  });
11137
+ DEFPRINT(AST_DynamicImport, function(self, output) {
11138
+ output.print("import." + self.phase);
11139
+ output.with_parens(function() {
11140
+ self.args.forEach(function(arg, i) {
11141
+ if (i) output.comma();
11142
+ arg.print(output);
11143
+ });
11144
+ });
11145
+ });
11046
11146
 
11047
11147
  DEFPRINT(AST_NameMapping, function(self, output) {
11048
11148
  var is_import = output.parent() instanceof AST_Import;
@@ -11895,11 +11995,18 @@ AST_VarDefLike.prototype.shallow_cmp = function(other) {
11895
11995
  AST_NameMapping.prototype.shallow_cmp = pass_through;
11896
11996
 
11897
11997
  AST_Import.prototype.shallow_cmp = function(other) {
11898
- return (this.imported_name == null ? other.imported_name == null : this.imported_name === other.imported_name) && (this.imported_names == null ? other.imported_names == null : this.imported_names === other.imported_names) && (this.attributes == null ? other.attributes == null : this.attributes === other.attributes);
11998
+ return (this.imported_name || null) === (other.imported_name || null)
11999
+ && (this.imported_names || null) === (other.imported_names || null)
12000
+ && (this.attributes || null) === (other.attributes || null)
12001
+ && (this.phase || null) === (other.phase || null);
11899
12002
  };
11900
12003
 
11901
12004
  AST_ImportMeta.prototype.shallow_cmp = pass_through;
11902
12005
 
12006
+ AST_DynamicImport.prototype.shallow_cmp = function(other) {
12007
+ return (this.phase || null) === (other.phase || null) && this.args.length === other.args.length;
12008
+ };
12009
+
11903
12010
  AST_Export.prototype.shallow_cmp = function(other) {
11904
12011
  return (this.exported_definition == null ? other.exported_definition == null : this.exported_definition === other.exported_definition) && (this.exported_value == null ? other.exported_value == null : this.exported_value === other.exported_value) && (this.exported_names == null ? other.exported_names == null : this.exported_names === other.exported_names) && (this.attributes == null ? other.attributes == null : this.attributes === other.attributes) && this.module_name === other.module_name && this.is_default === other.is_default;
11905
12012
  };
@@ -13188,6 +13295,11 @@ AST_Import.prototype._size = function () {
13188
13295
 
13189
13296
  AST_ImportMeta.prototype._size = () => 11;
13190
13297
 
13298
+ AST_DynamicImport.prototype._size = function () {
13299
+ // `import.` + phase + `()` + arg overhead
13300
+ return 9 + this.phase.length + list_overhead(this.args);
13301
+ };
13302
+
13191
13303
  AST_Export.prototype._size = function () {
13192
13304
  let size = 7 + (this.is_default ? 8 : 0);
13193
13305
 
@@ -14656,6 +14768,10 @@ function is_nullish(node, compressor) {
14656
14768
  || this.alternative && this.alternative.has_side_effects(compressor);
14657
14769
  });
14658
14770
  def_has_side_effects(AST_ImportMeta, return_false);
14771
+ def_has_side_effects(AST_DynamicImport, function() {
14772
+ // `import.source(x)` only compiles the module, which is side-effect free
14773
+ return this.phase !== "source";
14774
+ });
14659
14775
  def_has_side_effects(AST_LabeledStatement, function(compressor) {
14660
14776
  return this.body.has_side_effects(compressor);
14661
14777
  });
@@ -15979,6 +16095,12 @@ def_drop_side_effect_free(AST_Call, function (compressor, first_in_statement) {
15979
16095
  return args && make_sequence(this, args);
15980
16096
  });
15981
16097
 
16098
+ def_drop_side_effect_free(AST_DynamicImport, function (compressor, first_in_statement) {
16099
+ if (this.phase !== "source") return this;
16100
+ var args = trim(this.args, compressor, first_in_statement);
16101
+ return args && make_sequence(this, args);
16102
+ });
16103
+
15982
16104
  def_drop_side_effect_free(AST_Accessor, return_null);
15983
16105
 
15984
16106
  def_drop_side_effect_free(AST_Function, return_null);
package/lib/ast.js CHANGED
@@ -1535,9 +1535,10 @@ var AST_NameMapping = DEFNODE("NameMapping", "foreign_name name", function AST_N
1535
1535
 
1536
1536
  var AST_Import = DEFNODE(
1537
1537
  "Import",
1538
- "imported_name imported_names module_name attributes",
1538
+ "phase imported_name imported_names module_name attributes",
1539
1539
  function AST_Import(props) {
1540
1540
  if (props) {
1541
+ this.phase = props.phase;
1541
1542
  this.imported_name = props.imported_name;
1542
1543
  this.imported_names = props.imported_names;
1543
1544
  this.module_name = props.module_name;
@@ -1551,6 +1552,7 @@ var AST_Import = DEFNODE(
1551
1552
  {
1552
1553
  $documentation: "An `import` statement",
1553
1554
  $propdoc: {
1555
+ phase: "[string?] Phase keyword: 'source', 'defer', or null.",
1554
1556
  imported_name: "[AST_SymbolImport] The name of the variable holding the module's default export.",
1555
1557
  imported_names: "[AST_NameMapping*] The names of non-default imported variables",
1556
1558
  module_name: "[AST_String] String literal describing where this module came from",
@@ -1591,6 +1593,40 @@ var AST_ImportMeta = DEFNODE("ImportMeta", null, function AST_ImportMeta(props)
1591
1593
  $documentation: "A reference to import.meta",
1592
1594
  });
1593
1595
 
1596
+ var AST_DynamicImport = DEFNODE(
1597
+ "DynamicImport",
1598
+ "phase args",
1599
+ function AST_DynamicImport(props) {
1600
+ if (props) {
1601
+ this.phase = props.phase;
1602
+ this.args = props.args;
1603
+ this.start = props.start;
1604
+ this.end = props.end;
1605
+ }
1606
+
1607
+ this.flags = 0;
1608
+ },
1609
+ {
1610
+ $documentation: "A phased dynamic import expression: `import.source(specifier [, options])` or `import.defer(specifier [, options])`. Plain `import(x)` continues to be parsed as an AST_Call with a synthetic `import` SymbolRef callee.",
1611
+ $propdoc: {
1612
+ phase: "[string] Phase keyword ('source' or 'defer').",
1613
+ args: "[AST_Node*] specifier followed by optional options argument"
1614
+ },
1615
+ _walk: function(visitor) {
1616
+ return visitor._visit(this, function() {
1617
+ var args = this.args;
1618
+ for (var i = 0, len = args.length; i < len; i++) {
1619
+ args[i]._walk(visitor);
1620
+ }
1621
+ });
1622
+ },
1623
+ _children_backwards(push) {
1624
+ let i = this.args.length;
1625
+ while (i--) push(this.args[i]);
1626
+ },
1627
+ }
1628
+ );
1629
+
1594
1630
  var AST_Export = DEFNODE(
1595
1631
  "Export",
1596
1632
  "exported_definition exported_value is_default exported_names module_name attributes",
@@ -3375,6 +3411,7 @@ export {
3375
3411
  AST_Function,
3376
3412
  AST_Hole,
3377
3413
  AST_If,
3414
+ AST_DynamicImport,
3378
3415
  AST_Import,
3379
3416
  AST_ImportMeta,
3380
3417
  AST_Infinity,
@@ -58,6 +58,7 @@ import {
58
58
  AST_Constant,
59
59
  AST_DefClass,
60
60
  AST_Dot,
61
+ AST_DynamicImport,
61
62
  AST_Expansion,
62
63
  AST_Function,
63
64
  AST_Node,
@@ -152,6 +153,12 @@ def_drop_side_effect_free(AST_Call, function (compressor, first_in_statement) {
152
153
  return args && make_sequence(this, args);
153
154
  });
154
155
 
156
+ def_drop_side_effect_free(AST_DynamicImport, function (compressor, first_in_statement) {
157
+ if (this.phase !== "source") return this;
158
+ var args = trim(this.args, compressor, first_in_statement);
159
+ return args && make_sequence(this, args);
160
+ });
161
+
155
162
  def_drop_side_effect_free(AST_Accessor, return_null);
156
163
 
157
164
  def_drop_side_effect_free(AST_Function, return_null);
@@ -69,6 +69,7 @@ import {
69
69
  AST_Function,
70
70
  AST_If,
71
71
  AST_Import,
72
+ AST_DynamicImport,
72
73
  AST_ImportMeta,
73
74
  AST_Jump,
74
75
  AST_LabeledStatement,
@@ -403,6 +404,10 @@ export function is_nullish(node, compressor) {
403
404
  || this.alternative && this.alternative.has_side_effects(compressor);
404
405
  });
405
406
  def_has_side_effects(AST_ImportMeta, return_false);
407
+ def_has_side_effects(AST_DynamicImport, function() {
408
+ // `import.source(x)` only compiles the module, which is side-effect free
409
+ return this.phase !== "source";
410
+ });
406
411
  def_has_side_effects(AST_LabeledStatement, function(compressor) {
407
412
  return this.body.has_side_effects(compressor);
408
413
  });
@@ -29,6 +29,7 @@ import {
29
29
  AST_ForOf,
30
30
  AST_If,
31
31
  AST_Import,
32
+ AST_DynamicImport,
32
33
  AST_ImportMeta,
33
34
  AST_Jump,
34
35
  AST_LabeledStatement,
@@ -193,11 +194,18 @@ AST_VarDefLike.prototype.shallow_cmp = function(other) {
193
194
  AST_NameMapping.prototype.shallow_cmp = pass_through;
194
195
 
195
196
  AST_Import.prototype.shallow_cmp = function(other) {
196
- return (this.imported_name == null ? other.imported_name == null : this.imported_name === other.imported_name) && (this.imported_names == null ? other.imported_names == null : this.imported_names === other.imported_names) && (this.attributes == null ? other.attributes == null : this.attributes === other.attributes);
197
+ return (this.imported_name || null) === (other.imported_name || null)
198
+ && (this.imported_names || null) === (other.imported_names || null)
199
+ && (this.attributes || null) === (other.attributes || null)
200
+ && (this.phase || null) === (other.phase || null);
197
201
  };
198
202
 
199
203
  AST_ImportMeta.prototype.shallow_cmp = pass_through;
200
204
 
205
+ AST_DynamicImport.prototype.shallow_cmp = function(other) {
206
+ return (this.phase || null) === (other.phase || null) && this.args.length === other.args.length;
207
+ };
208
+
201
209
  AST_Export.prototype.shallow_cmp = function(other) {
202
210
  return (this.exported_definition == null ? other.exported_definition == null : this.exported_definition === other.exported_definition) && (this.exported_value == null ? other.exported_value == null : this.exported_value === other.exported_value) && (this.exported_names == null ? other.exported_names == null : this.exported_names === other.exported_names) && (this.attributes == null ? other.attributes == null : this.attributes === other.attributes) && this.module_name === other.module_name && this.is_default === other.is_default;
203
211
  };
@@ -91,6 +91,7 @@ import {
91
91
  AST_Function,
92
92
  AST_Hole,
93
93
  AST_If,
94
+ AST_DynamicImport,
94
95
  AST_Import,
95
96
  AST_ImportMeta,
96
97
  AST_Label,
@@ -585,7 +586,8 @@ import { is_basic_identifier_string } from "./parse.js";
585
586
  imported_name: imported_name,
586
587
  imported_names : imported_names,
587
588
  module_name : from_moz(M.source),
588
- attributes: import_attributes_from_moz(M.attributes || M.assertions)
589
+ attributes: import_attributes_from_moz(M.attributes || M.assertions),
590
+ phase: M.phase || null
589
591
  });
590
592
  },
591
593
 
@@ -616,6 +618,14 @@ import { is_basic_identifier_string } from "./parse.js";
616
618
  if (M.options) {
617
619
  args.push(from_moz(M.options));
618
620
  }
621
+ if (M.phase) {
622
+ return new AST_DynamicImport({
623
+ start: my_start_token(M),
624
+ end: my_end_token(M),
625
+ phase: M.phase,
626
+ args: args
627
+ });
628
+ }
619
629
  return new AST_Call({
620
630
  start: my_start_token(M),
621
631
  end: my_end_token(M),
@@ -1215,6 +1225,16 @@ import { is_basic_identifier_string } from "./parse.js";
1215
1225
  };
1216
1226
  });
1217
1227
 
1228
+ def_to_moz(AST_DynamicImport, function To_Moz_ImportExpression(M) {
1229
+ const [source, options] = M.args.map(to_moz);
1230
+ return {
1231
+ type: "ImportExpression",
1232
+ source,
1233
+ options: options || null,
1234
+ phase: M.phase
1235
+ };
1236
+ });
1237
+
1218
1238
  def_to_moz(AST_Toplevel, function To_Moz_Program(M) {
1219
1239
  return to_moz_scope("Program", M);
1220
1240
  });
@@ -1479,12 +1499,14 @@ import { is_basic_identifier_string } from "./parse.js";
1479
1499
  });
1480
1500
  }
1481
1501
  }
1482
- return {
1502
+ var moz = {
1483
1503
  type: "ImportDeclaration",
1484
1504
  specifiers: specifiers,
1485
1505
  source: to_moz(M.module_name),
1486
1506
  attributes: import_attributes_to_moz(M.attributes)
1487
1507
  };
1508
+ if (M.phase) moz.phase = M.phase;
1509
+ return moz;
1488
1510
  });
1489
1511
 
1490
1512
  def_to_moz(AST_ImportMeta, function To_Moz_MetaProperty() {
package/lib/output.js CHANGED
@@ -103,6 +103,7 @@ import {
103
103
  AST_Function,
104
104
  AST_Hole,
105
105
  AST_If,
106
+ AST_DynamicImport,
106
107
  AST_Import,
107
108
  AST_ImportMeta,
108
109
  AST_Jump,
@@ -1766,6 +1767,10 @@ function OutputStream(options) {
1766
1767
  DEFPRINT(AST_Import, function(self, output) {
1767
1768
  output.print("import");
1768
1769
  output.space();
1770
+ if (self.phase) {
1771
+ output.print(self.phase);
1772
+ output.space();
1773
+ }
1769
1774
  if (self.imported_name) {
1770
1775
  self.imported_name.print(output);
1771
1776
  }
@@ -1806,6 +1811,15 @@ function OutputStream(options) {
1806
1811
  DEFPRINT(AST_ImportMeta, function(self, output) {
1807
1812
  output.print("import.meta");
1808
1813
  });
1814
+ DEFPRINT(AST_DynamicImport, function(self, output) {
1815
+ output.print("import." + self.phase);
1816
+ output.with_parens(function() {
1817
+ self.args.forEach(function(arg, i) {
1818
+ if (i) output.comma();
1819
+ arg.print(output);
1820
+ });
1821
+ });
1822
+ });
1809
1823
 
1810
1824
  DEFPRINT(AST_NameMapping, function(self, output) {
1811
1825
  var is_import = output.parent() instanceof AST_Import;
package/lib/parse.js CHANGED
@@ -99,6 +99,7 @@ import {
99
99
  AST_Function,
100
100
  AST_Hole,
101
101
  AST_If,
102
+ AST_DynamicImport,
102
103
  AST_Import,
103
104
  AST_ImportMeta,
104
105
  AST_Infinity,
@@ -2428,7 +2429,7 @@ function parse($TEXT, options) {
2428
2429
  return new_(allow_calls);
2429
2430
  }
2430
2431
  if (is("name", "import") && is_token(peek(), "punc", ".")) {
2431
- return import_meta(allow_calls);
2432
+ return parse_import_expr(allow_calls);
2432
2433
  }
2433
2434
  var start = S.token;
2434
2435
  var peeked;
@@ -2868,6 +2869,17 @@ function parse($TEXT, options) {
2868
2869
  function import_statement() {
2869
2870
  var start = prev();
2870
2871
 
2872
+ // import source x from "..."
2873
+ // import defer * as x from "..."
2874
+ var phase = null;
2875
+ if (is("name", "source") || is("name", "defer")) {
2876
+ var peeked = peek();
2877
+ if (!is_token(peeked, "name", "from") && !is_token(peeked, "punc", ",")) {
2878
+ phase = S.token.value;
2879
+ next();
2880
+ }
2881
+ }
2882
+
2871
2883
  var imported_name;
2872
2884
  var imported_names;
2873
2885
  if (is("name")) {
@@ -2902,14 +2914,33 @@ function parse($TEXT, options) {
2902
2914
  end: mod_str,
2903
2915
  }),
2904
2916
  attributes,
2917
+ phase,
2905
2918
  end: S.token,
2906
2919
  });
2907
2920
  }
2908
2921
 
2909
- function import_meta(allow_calls) {
2922
+ // import.meta
2923
+ // import.source("module")
2924
+ // import.defer("module")
2925
+ function parse_import_expr(allow_calls) {
2910
2926
  var start = S.token;
2911
2927
  expect_token("name", "import");
2912
2928
  expect_token("punc", ".");
2929
+ if (is("name", "source") || is("name", "defer")) {
2930
+ var phase = S.token.value;
2931
+ next();
2932
+ if (!is("punc", "(")) {
2933
+ croak("'import." + phase + "' can only be used in a dynamic import");
2934
+ }
2935
+ next();
2936
+ var args = expr_list(")");
2937
+ return subscripts(new AST_DynamicImport({
2938
+ start: start,
2939
+ phase: phase,
2940
+ args: args,
2941
+ end: prev()
2942
+ }), allow_calls);
2943
+ }
2913
2944
  expect_token("name", "meta");
2914
2945
  return subscripts(new AST_ImportMeta({
2915
2946
  start: start,
package/lib/size.js CHANGED
@@ -35,6 +35,7 @@ import {
35
35
  AST_Hole,
36
36
  AST_If,
37
37
  AST_Import,
38
+ AST_DynamicImport,
38
39
  AST_ImportMeta,
39
40
  AST_Infinity,
40
41
  AST_LabeledStatement,
@@ -276,6 +277,11 @@ AST_Import.prototype._size = function () {
276
277
 
277
278
  AST_ImportMeta.prototype._size = () => 11;
278
279
 
280
+ AST_DynamicImport.prototype._size = function () {
281
+ // `import.` + phase + `()` + arg overhead
282
+ return 9 + this.phase.length + list_overhead(this.args);
283
+ };
284
+
279
285
  AST_Export.prototype._size = function () {
280
286
  let size = 7 + (this.is_default ? 8 : 0);
281
287
 
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "homepage": "https://terser.org",
5
5
  "author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
6
6
  "license": "BSD-2-Clause",
7
- "version": "5.47.1",
7
+ "version": "5.48.0",
8
8
  "engines": {
9
9
  "node": ">=10"
10
10
  },