From 2e29d7828164493ec6e8e3c043325ebcd2d935e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Fri, 4 Dec 2020 05:03:26 +0900 Subject: [PATCH] fix: Decorator metadata (#1248) swc_ecma_transforms: - Emit proper typename for `design:type` used with enum. (#1160) --- benches/typescript.rs | 10 ++- .../tests/fixture/deno-8574/output/entry.ts | 2 +- ecmascript/Cargo.toml | 2 +- ecmascript/codegen/Cargo.toml | 4 +- ecmascript/codegen/src/lib.rs | 17 +++- ecmascript/codegen/src/text_writer.rs | 12 +++ .../src/proposals/decorators/legacy.rs | 59 +++++++++++++- .../proposals/decorators/legacy/metadata.rs | 36 ++++++++- .../transforms/tests/proposal_decorators.rs | 51 ++++++++++++ native/src/bundle.rs | 18 ++++- native/src/print.rs | 11 +++ spack/src/config/mod.rs | 10 +++ spack/tests/fixture.rs | 2 + src/codegen.rs | 80 +++++++++++++++++++ src/config.rs | 9 +++ src/lib.rs | 33 +++++--- tests/fixture/issue-1160/input/.swcrc | 17 ++++ tests/fixture/issue-1160/input/entry.ts | 13 +++ tests/fixture/issue-1160/output/entry.ts | 62 ++++++++++++++ wasm/src/lib.rs | 3 +- 20 files changed, 426 insertions(+), 25 deletions(-) create mode 100644 src/codegen.rs create mode 100644 tests/fixture/issue-1160/input/.swcrc create mode 100644 tests/fixture/issue-1160/input/entry.ts create mode 100644 tests/fixture/issue-1160/output/entry.ts diff --git a/benches/typescript.rs b/benches/typescript.rs index 46bfa21dcb81..ccd224254010 100644 --- a/benches/typescript.rs +++ b/benches/typescript.rs @@ -116,8 +116,14 @@ fn bench_codegen(b: &mut Bencher, _target: JscTarget) { b.iter(|| { black_box( - c.print(&module, SourceMapsConfig::Bool(false), None, false) - .unwrap(), + c.print( + &module, + JscTarget::Es2020, + SourceMapsConfig::Bool(false), + None, + false, + ) + .unwrap(), ); }) } diff --git a/bundler/tests/fixture/deno-8574/output/entry.ts b/bundler/tests/fixture/deno-8574/output/entry.ts index 3788f835140d..baf6caccb78f 100644 --- a/bundler/tests/fixture/deno-8574/output/entry.ts +++ b/bundler/tests/fixture/deno-8574/output/entry.ts @@ -372,7 +372,7 @@ function onceStrict(fn) { f.called = false; return f; } -const VERSION1 = "5.4.11"; +const VERSION1 = "5.4.12"; function getBufferResponse(response) { return response.arrayBuffer(); } diff --git a/ecmascript/Cargo.toml b/ecmascript/Cargo.toml index 74a05b5390ea..1393ca67a034 100644 --- a/ecmascript/Cargo.toml +++ b/ecmascript/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "Apache-2.0/MIT" name = "swc_ecmascript" repository = "https://github.com/swc-project/swc.git" -version = "0.14.4" +version = "0.14.5" [features] codegen = ["swc_ecma_codegen"] diff --git a/ecmascript/codegen/Cargo.toml b/ecmascript/codegen/Cargo.toml index 4d9059121c8b..844526990a66 100644 --- a/ecmascript/codegen/Cargo.toml +++ b/ecmascript/codegen/Cargo.toml @@ -7,7 +7,7 @@ include = ["Cargo.toml", "src/**/*.rs"] license = "Apache-2.0/MIT" name = "swc_ecma_codegen" repository = "https://github.com/swc-project/swc.git" -version = "0.41.3" +version = "0.41.4" [dependencies] bitflags = "1" @@ -17,8 +17,8 @@ swc_atoms = {version = "0.2", path = "../../atoms"} swc_common = {version = "0.10.0", path = "../../common"} swc_ecma_ast = {version = "0.35.0", path = "../ast"} swc_ecma_codegen_macros = {version = "0.5", path = "./macros"} +swc_ecma_parser = {version = "0.43.0", path = "../parser"} [dev-dependencies] swc_common = {version = "0.10.0", path = "../../common", features = ["sourcemap"]} -swc_ecma_parser = {version = "0.43.0", path = "../parser"} testing = {version = "0.10.0", path = "../../testing"} diff --git a/ecmascript/codegen/src/lib.rs b/ecmascript/codegen/src/lib.rs index 47e9a1c85833..f746a1d22852 100644 --- a/ecmascript/codegen/src/lib.rs +++ b/ecmascript/codegen/src/lib.rs @@ -14,6 +14,7 @@ use swc_common::{ }; use swc_ecma_ast::*; use swc_ecma_codegen_macros::emitter; +use swc_ecma_parser::JscTarget; #[macro_use] pub mod macros; @@ -388,7 +389,13 @@ impl<'a> Emitter<'a> { // self.wr.write_str_lit(node.span, &s)?; // return Ok(()); // } - let value = escape(&self.cm, node.span, &node.value, single_quote); + let value = escape( + &self.cm, + self.wr.target(), + node.span, + &node.value, + single_quote, + ); // let value = node.value.replace("\n", "\\n"); let single_quote = single_quote.unwrap_or(false); @@ -2412,7 +2419,13 @@ fn unescape(s: &str) -> String { result } -fn escape<'s>(cm: &SourceMap, span: Span, s: &'s str, single_quote: Option) -> Cow<'s, str> { +fn escape<'s>( + cm: &SourceMap, + target: JscTarget, + span: Span, + s: &'s str, + single_quote: Option, +) -> Cow<'s, str> { if span.is_dummy() { return Cow::Owned(s.escape_default().to_string()); } diff --git a/ecmascript/codegen/src/text_writer.rs b/ecmascript/codegen/src/text_writer.rs index 410e19ec485e..67e5ef4c4e55 100644 --- a/ecmascript/codegen/src/text_writer.rs +++ b/ecmascript/codegen/src/text_writer.rs @@ -1,6 +1,7 @@ pub use self::{basic_impl::JsWriter, semicolon::omit_trailing_semi}; use super::*; use swc_common::Span; +use swc_ecma_parser::JscTarget; mod basic_impl; mod semicolon; @@ -12,6 +13,17 @@ pub type Symbol = Str; /// /// Ported from `EmitWriteJs`. pub trait WriteJs { + /// Returns javascript target which should be used while generating code. + /// + /// This defaults to [JscTarget::Es2020] because it preserves input as much + /// as possible. + /// + /// Implementor **should return same value** regardless how much time it is + /// called. + fn target(&self) -> JscTarget { + JscTarget::Es2020 + } + fn increase_indent(&mut self) -> Result; fn decrease_indent(&mut self) -> Result; diff --git a/ecmascript/transforms/src/proposals/decorators/legacy.rs b/ecmascript/transforms/src/proposals/decorators/legacy.rs index d166ae668d41..b8621d78aed6 100644 --- a/ecmascript/transforms/src/proposals/decorators/legacy.rs +++ b/ecmascript/transforms/src/proposals/decorators/legacy.rs @@ -4,20 +4,30 @@ use crate::util::{ alias_if_required, default_constructor, prepend, prop_name_to_expr_value, undefined, ExprFactory, ModuleItemLike, StmtLike, }; +use fxhash::FxHashMap; use smallvec::SmallVec; use std::mem::replace; use swc_common::{util::move_map::MoveMap, DUMMY_SP}; use swc_ecma_ast::*; -use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, VisitWith}; +use swc_ecma_utils::{ident::IdentLike, Id}; +use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, Node, Visit, VisitWith}; mod metadata; +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum EnumKind { + Mixed, + Str, + Num, +} + #[derive(Debug)] pub(super) struct Legacy { metadata: bool, uninitialized_vars: Vec, initialized_vars: Vec, exports: Vec, + enums: FxHashMap, } pub(super) fn new(metadata: bool) -> Legacy { @@ -26,6 +36,48 @@ pub(super) fn new(metadata: bool) -> Legacy { uninitialized_vars: Default::default(), initialized_vars: Default::default(), exports: Default::default(), + enums: Default::default(), + } +} + +impl Visit for Legacy { + fn visit_ts_enum_decl(&mut self, e: &TsEnumDecl, _: &dyn Node) { + let enum_kind = e + .members + .iter() + .map(|member| member.init.as_ref()) + .map(|init| match init { + Some(e) => match &**e { + Expr::Lit(lit) => match lit { + Lit::Str(_) => EnumKind::Str, + Lit::Num(_) => EnumKind::Num, + _ => EnumKind::Mixed, + }, + _ => EnumKind::Mixed, + }, + None => EnumKind::Num, + }) + .fold(None, |opt: Option, item| { + // + let a = match item { + EnumKind::Mixed => return Some(EnumKind::Mixed), + _ => item, + }; + + let b = match opt { + Some(EnumKind::Mixed) => return Some(EnumKind::Mixed), + Some(v) => v, + None => return Some(item), + }; + if a == b { + return Some(a); + } else { + return Some(EnumKind::Mixed); + } + }); + if let Some(kind) = enum_kind { + self.enums.insert(e.id.to_id(), kind); + } } } @@ -78,6 +130,10 @@ impl Fold for Legacy { } fn fold_module(&mut self, m: Module) -> Module { + // Collect required information. + // For example, value type of enum affects codegen + m.visit_with(&Invalid { span: DUMMY_SP }, self); + let mut m = m.fold_children_with(self); if !self.uninitialized_vars.is_empty() { @@ -214,6 +270,7 @@ impl Legacy { let i = c.ident.clone(); c = c.fold_with(&mut ParamMetadata).fold_with(&mut Metadata { + enums: &self.enums, class_name: i.as_ref(), }); } diff --git a/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs b/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs index d521ece9bbdb..99beb7583586 100644 --- a/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs +++ b/ecmascript/transforms/src/proposals/decorators/legacy/metadata.rs @@ -1,8 +1,11 @@ +use fxhash::FxHashMap; use swc_common::{util::move_map::MoveMap, Spanned, DUMMY_SP}; use swc_ecma_ast::*; -use swc_ecma_utils::{undefined, ExprFactory}; +use swc_ecma_utils::{ident::IdentLike, undefined, ExprFactory, Id}; use swc_ecma_visit::{noop_fold_type, Fold, FoldWith}; +use super::EnumKind; + /// https://github.com/leonardfactory/babel-plugin-transform-typescript-metadata/blob/master/src/parameter/parameterVisitor.ts pub(super) struct ParamMetadata; @@ -118,6 +121,8 @@ impl ParamMetadata { /// https://github.com/leonardfactory/babel-plugin-transform-typescript-metadata/blob/master/src/metadata/metadataVisitor.ts pub(super) struct Metadata<'a> { + pub(super) enums: &'a FxHashMap, + pub(super) class_name: Option<&'a Ident>, } @@ -219,6 +224,35 @@ impl Fold for Metadata<'_> { return p; } + if let Some(name) = p + .type_ann + .as_ref() + .map(|ty| &ty.type_ann) + .map(|type_ann| match &**type_ann { + TsType::TsTypeRef(r) => Some(r), + _ => None, + }) + .flatten() + .map(|r| match &r.type_name { + TsEntityName::TsQualifiedName(_) => None, + TsEntityName::Ident(i) => Some(i), + }) + .flatten() + { + if let Some(kind) = self.enums.get(&name.to_id()) { + let dec = self.create_metadata_design_decorator( + "design:type", + match kind { + EnumKind::Mixed => quote_ident!("Object").as_arg(), + EnumKind::Str => quote_ident!("String").as_arg(), + EnumKind::Num => quote_ident!("Number").as_arg(), + }, + ); + p.decorators.push(dec); + return p; + } + } + let dec = self.create_metadata_design_decorator( "design:type", serialize_type(self.class_name, p.type_ann.as_ref()).as_arg(), diff --git a/ecmascript/transforms/tests/proposal_decorators.rs b/ecmascript/transforms/tests/proposal_decorators.rs index 721905398af4..09b91a373244 100644 --- a/ecmascript/transforms/tests/proposal_decorators.rs +++ b/ecmascript/transforms/tests/proposal_decorators.rs @@ -5129,3 +5129,54 @@ let Sample = _class = _dec11(_class = _dec10(_class = _dec9(((_class = class Sam ], Object.getOwnPropertyDescriptor(_class.prototype, "assignments"), _class.prototype), _class)) || _class) || _class) || _class;"##, ok_if_code_eq ); + +test!( + ts(), + |_| decorators(Config { + legacy: true, + emit_metadata: true, + }), + issue_1160_1, + " + enum MyEnum { + x = \"xxx\", + y = \"yyy\" + } + + class Xpto { + @Decorator() + value!: MyEnum; + } + + function Decorator() { + return function (...args) {}; + } + ", + " + var _class, _descriptor; +enum MyEnum { + x = \"xxx\", + y = \"yyy\" +} +var _dec = Decorator(), _dec1 = typeof Reflect !== \"undefined\" && typeof Reflect.metadata === \ + \"function\" && Reflect.metadata(\"design:type\", String); +let Xpto = ((_class = class Xpto { + constructor(){ + _initializerDefineProperty(this, \"value\", _descriptor, this); + } +}) || _class, _descriptor = _applyDecoratedDescriptor(_class.prototype, \"value\", [ + _dec, + _dec1 +], { + configurable: true, + enumerable: true, + writable: true, + initializer: void 0 +}), _class); +function Decorator() { + return function(...args) { + }; +} +", + ok_if_code_eq +); diff --git a/native/src/bundle.rs b/native/src/bundle.rs index 40b75ec940ae..dcfb22a4d4f2 100644 --- a/native/src/bundle.rs +++ b/native/src/bundle.rs @@ -44,6 +44,14 @@ impl Task for BundleTask { type JsValue = JsObject; fn compute(&mut self) -> napi::Result { + // Defaults to es3 + let codegen_target = self + .config + .static_items + .config + .codegen_target() + .unwrap_or_default(); + let res = catch_unwind(AssertUnwindSafe(|| { let bundler = Bundler::new( self.swc.globals(), @@ -125,9 +133,13 @@ impl Task for BundleTask { }) .unwrap_or(false); - let output = - self.swc - .print(&m, SourceMapsConfig::Bool(true), None, minify)?; + let output = self.swc.print( + &m, + codegen_target, + SourceMapsConfig::Bool(true), + None, + minify, + )?; Ok((k, output)) }) diff --git a/native/src/print.rs b/native/src/print.rs index 9f564f396b5d..92f2883af72c 100644 --- a/native/src/print.rs +++ b/native/src/print.rs @@ -9,6 +9,7 @@ use swc::{ Compiler, TransformOutput, }; use swc_ecma_ast::Program; +use swc_ecma_parser::JscTarget; // ----- Printing ----- @@ -26,6 +27,12 @@ impl Task for PrintTask { self.c .print( &self.program, + self.options + .config + .as_ref() + .map(|config| &config.jsc) + .map(|jsc| jsc.target) + .unwrap_or(JscTarget::Es2020), self.options .source_maps .clone() @@ -72,9 +79,13 @@ pub fn print_sync(cx: CallContext) -> napi::Result { let options: Options = cx.get_deserialized(1)?; + // Defaults to es3 + let codegen_target = options.codegen_target().unwrap_or_default(); + let result = { c.print( &program, + codegen_target, options .source_maps .clone() diff --git a/spack/src/config/mod.rs b/spack/src/config/mod.rs index 7bcf1675d772..b123b780771b 100644 --- a/spack/src/config/mod.rs +++ b/spack/src/config/mod.rs @@ -8,6 +8,7 @@ use serde::Deserialize; use std::{collections::HashMap, fmt, marker::PhantomData, path::PathBuf}; use string_enum::StringEnum; use swc_common::FileName; +use swc_ecma_parser::JscTarget; mod module; mod optimization; @@ -40,6 +41,15 @@ pub struct Config { pub options: Option, } +impl Config { + pub fn codegen_target(&self) -> Option { + self.options + .as_ref() + .map(|options| options.codegen_target()) + .flatten() + } +} + #[derive(StringEnum)] pub enum Mode { /// `production` diff --git a/spack/tests/fixture.rs b/spack/tests/fixture.rs index 4537645fcb2f..d6c4c50d5f07 100644 --- a/spack/tests/fixture.rs +++ b/spack/tests/fixture.rs @@ -19,6 +19,7 @@ use swc_common::{FileName, Span, GLOBALS}; use swc_ecma_ast::{ Bool, Expr, ExprOrSuper, Ident, KeyValueProp, Lit, MemberExpr, MetaPropExpr, PropName, Str, }; +use swc_ecma_parser::JscTarget; use swc_ecma_transforms::fixer; use swc_ecma_visit::FoldWith; use test::{ @@ -196,6 +197,7 @@ fn reference_tests(tests: &mut Vec, errors: bool) -> Result<(), i let code = compiler .print( &bundled.module.fold_with(&mut fixer(None)), + JscTarget::Es2020, SourceMapsConfig::Bool(false), None, false, diff --git a/src/codegen.rs b/src/codegen.rs new file mode 100644 index 000000000000..d8d43abbe78e --- /dev/null +++ b/src/codegen.rs @@ -0,0 +1,80 @@ +use swc_common::Span; +use swc_ecma_codegen::{text_writer::WriteJs, Result}; +use swc_ecma_parser::JscTarget; + +pub(crate) struct WriterWapper +where + W: WriteJs, +{ + pub target: JscTarget, + pub inner: W, +} + +impl WriteJs for WriterWapper +where + W: WriteJs, +{ + fn increase_indent(&mut self) -> Result { + self.inner.increase_indent() + } + + fn decrease_indent(&mut self) -> Result { + self.inner.decrease_indent() + } + + fn write_semi(&mut self) -> Result { + self.inner.write_semi() + } + + fn write_space(&mut self) -> Result { + self.inner.write_space() + } + + fn write_keyword(&mut self, span: Option, s: &'static str) -> Result { + self.inner.write_keyword(span, s) + } + + fn write_operator(&mut self, s: &str) -> Result { + self.inner.write_operator(s) + } + + fn write_param(&mut self, s: &str) -> Result { + self.inner.write_param(s) + } + + fn write_property(&mut self, s: &str) -> Result { + self.inner.write_property(s) + } + + fn write_line(&mut self) -> Result { + self.inner.write_line() + } + + fn write_lit(&mut self, span: Span, s: &str) -> Result { + self.inner.write_lit(span, s) + } + + fn write_comment(&mut self, span: Span, s: &str) -> Result { + self.inner.write_comment(span, s) + } + + fn write_str_lit(&mut self, span: Span, s: &str) -> Result { + self.inner.write_str_lit(span, s) + } + + fn write_str(&mut self, s: &str) -> Result { + self.inner.write_str(s) + } + + fn write_symbol(&mut self, span: Span, s: &str) -> Result { + self.inner.write_symbol(span, s) + } + + fn write_punct(&mut self, s: &'static str) -> Result { + self.inner.write_punct(s) + } + + fn target(&self) -> JscTarget { + self.target + } +} diff --git a/src/config.rs b/src/config.rs index f8e6bb10d3ff..6b8432de254b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -120,6 +120,15 @@ pub struct Options { pub is_module: bool, } +impl Options { + pub fn codegen_target(&self) -> Option { + self.config + .as_ref() + .map(|config| &config.jsc) + .map(|jsc| jsc.target) + } +} + fn default_is_module() -> bool { true } diff --git a/src/lib.rs b/src/lib.rs index 4bf6e0923c85..d94d3bbec66e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,6 +34,7 @@ use swc_ecma_transforms::{ use swc_ecma_visit::FoldWith; mod builder; +mod codegen; pub mod config; pub struct Compiler { @@ -189,6 +190,7 @@ impl Compiler { pub fn print( &self, node: &T, + target: JscTarget, source_map: SourceMapsConfig, orig: Option<&sourcemap::SourceMap>, minify: bool, @@ -206,16 +208,19 @@ impl Compiler { cfg: swc_ecma_codegen::Config { minify }, comments: if minify { None } else { Some(&self.comments) }, cm: self.cm.clone(), - wr: Box::new(swc_ecma_codegen::text_writer::JsWriter::new( - self.cm.clone(), - "\n", - &mut buf, - if source_map.enabled() { - Some(&mut src_map_buf) - } else { - None - }, - )), + wr: Box::new(self::codegen::WriterWapper { + target, + inner: swc_ecma_codegen::text_writer::JsWriter::new( + self.cm.clone(), + "\n", + &mut buf, + if source_map.enabled() { + Some(&mut src_map_buf) + } else { + None + }, + ), + }), }; node.emit_with(&mut emitter) @@ -471,7 +476,13 @@ impl Compiler { }) }); - self.print(&program, config.source_maps, orig, config.minify) + self.print( + &program, + config.target, + config.source_maps, + orig, + config.minify, + ) }) } } diff --git a/tests/fixture/issue-1160/input/.swcrc b/tests/fixture/issue-1160/input/.swcrc new file mode 100644 index 000000000000..f106ce8a0a12 --- /dev/null +++ b/tests/fixture/issue-1160/input/.swcrc @@ -0,0 +1,17 @@ +{ + "module": { + "type": "commonjs" + }, + "jsc": { + "target": "es2018", + "parser": { + "syntax": "typescript", + "decorators": true, + "dynamicImport": false + }, + "transform": { + "legacyDecorator": false, + "decoratorMetadata": true + } + } +} diff --git a/tests/fixture/issue-1160/input/entry.ts b/tests/fixture/issue-1160/input/entry.ts new file mode 100644 index 000000000000..574df7af6b87 --- /dev/null +++ b/tests/fixture/issue-1160/input/entry.ts @@ -0,0 +1,13 @@ +enum MyEnum { + x = "xxx", + y = "yyy" +} + +class Xpto { + @Decorator() + value!: MyEnum; +} + +function Decorator() { + return function (...args) { }; +} diff --git a/tests/fixture/issue-1160/output/entry.ts b/tests/fixture/issue-1160/output/entry.ts new file mode 100644 index 000000000000..9105cf736bf6 --- /dev/null +++ b/tests/fixture/issue-1160/output/entry.ts @@ -0,0 +1,62 @@ +"use strict"; +function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) { + var desc = { + }; + Object.keys(descriptor).forEach(function(key) { + desc[key] = descriptor[key]; + }); + desc.enumerable = !!desc.enumerable; + desc.configurable = !!desc.configurable; + if ("value" in desc || desc.initializer) { + desc.writable = true; + } + desc = decorators.slice().reverse().reduce(function(desc, decorator) { + return decorator(target, property, desc) || desc; + }, desc); + if (context && desc.initializer !== void 0) { + desc.value = desc.initializer ? desc.initializer.call(context) : void 0; + desc.initializer = undefined; + } + if (desc.initializer === void 0) { + Object.defineProperty(target, property, desc); + desc = null; + } + return desc; +} +function _initializerDefineProperty(target, property, descriptor, context) { + if (!descriptor) return; + Object.defineProperty(target, property, { + enumerable: descriptor.enumerable, + configurable: descriptor.configurable, + writable: descriptor.writable, + value: descriptor.initializer ? descriptor.initializer.call(context) : void 0 + }); +} +var _class, _descriptor; +var MyEnum; +(function(MyEnum1) { + MyEnum1["x"] = "xxx"; + MyEnum1["y"] = "yyy"; +})(MyEnum || (MyEnum = { +})); +var _dec = Decorator(), _dec1 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:type", String); +let Xpto = ((_class = function() { + class Xpto1 { + constructor(){ + _initializerDefineProperty(this, "value", _descriptor, this); + } + } + return Xpto1; +}()) || _class, _descriptor = _applyDecoratedDescriptor(_class.prototype, "value", [ + _dec, + _dec1 +], { + configurable: true, + enumerable: true, + writable: true, + initializer: void 0 +}), _class); +function Decorator() { + return function(...args) { + }; +} diff --git a/wasm/src/lib.rs b/wasm/src/lib.rs index c27536a438d7..d5b3e43cd9ff 100644 --- a/wasm/src/lib.rs +++ b/wasm/src/lib.rs @@ -5,7 +5,7 @@ use std::{ sync::{Arc, RwLock}, }; use swc::{ - config::{Options, ParseOptions, SourceMapsConfig}, + config::{JscTarget, Options, ParseOptions, SourceMapsConfig}, Compiler, }; use swc_common::{ @@ -50,6 +50,7 @@ pub fn print_sync(s: JsValue, opts: JsValue) -> Result { let s = c .print( &program, + opts.codegen_target().unwrap_or(JscTarget::Es2020), opts.source_maps .clone() .unwrap_or(SourceMapsConfig::Bool(false)),