Skip to content

Commit dd4b9e8

Browse files
authoredNov 18, 2022
refactor(bindings): Deprecate jsvalue::*_serde (#6462)
1 parent 44b0790 commit dd4b9e8

File tree

14 files changed

+388
-58
lines changed

14 files changed

+388
-58
lines changed
 

‎.github/workflows/CI.yml

+1
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,7 @@ jobs:
641641
- name: Run cargo test (core)
642642
if: matrix.settings.crate == 'swc_core'
643643
run: |
644+
rustup target add wasm32-unknown-unknown
644645
cargo test -p swc_core --features ecma_quote --features common --features ecma_utils
645646
646647
- name: Run cargo test (binding_core_wasm)

‎Cargo.lock

+18-14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎bindings/binding_core_wasm/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ swc_core = { version = "0.43.15", features = [
3131
] }
3232
tracing = { version = "0.1.37", features = ["max_level_off"] }
3333
wasm-bindgen = { version = "0.2.82", features = [
34-
"serde-serialize",
3534
"enable-interning",
3635
] }
3736

‎bindings/binding_core_wasm/src/lib.rs

+36-12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
use anyhow::Error;
2+
use serde::Serialize;
3+
use serde_wasm_bindgen::Serializer;
24
use swc_core::{
35
base::HandlerOpts,
46
binding_macros::wasm::{
@@ -21,6 +23,12 @@ use swc_core::{
2123
use wasm_bindgen::{prelude::*, JsCast};
2224
mod types;
2325

26+
// A serializer with options to provide backward compat for the input / output
27+
// from the bindgen generated swc interfaces.
28+
const COMPAT_SERIALIZER: Serializer = Serializer::new()
29+
.serialize_maps_as_objects(true)
30+
.serialize_missing_as_null(true);
31+
2432
/// Custom interface definitions for the @swc/wasm's public interface instead of
2533
/// auto generated one, which is not reflecting most of types in detail.
2634
#[wasm_bindgen(typescript_custom_section)]
@@ -81,12 +89,16 @@ pub fn minify_sync(s: JsString, opts: JsValue) -> Result<JsValue, JsValue> {
8189
let opts = if opts.is_null() || opts.is_undefined() {
8290
Default::default()
8391
} else {
84-
anyhow::Context::context(opts.into_serde(), "failed to parse options")?
92+
serde_wasm_bindgen::from_value(opts)
93+
.map_err(|e| anyhow::anyhow!("failed to parse options: {}", e))?
8594
};
8695
let fm = c.cm.new_source_file(FileName::Anon, s.into());
8796
let program =
8897
anyhow::Context::context(c.minify(fm, handler, &opts), "failed to minify file")?;
89-
anyhow::Context::context(JsValue::from_serde(&program), "failed to serialize json")
98+
99+
program
100+
.serialize(&COMPAT_SERIALIZER)
101+
.map_err(|e| anyhow::anyhow!("failed to serialize program: {}", e))
90102
})
91103
})
92104
.map_err(|e| convert_err(e, None))
@@ -106,7 +118,8 @@ pub fn parse_sync(s: JsString, opts: JsValue) -> Result<JsValue, JsValue> {
106118
let opts: ParseOptions = if opts.is_null() || opts.is_undefined() {
107119
Default::default()
108120
} else {
109-
anyhow::Context::context(opts.into_serde(), "failed to parse options")?
121+
serde_wasm_bindgen::from_value(opts)
122+
.map_err(|e| anyhow::anyhow!("failed to parse options: {}", e))?
110123
};
111124
let fm = c.cm.new_source_file(FileName::Anon, s.into());
112125
let cmts = c.comments().clone();
@@ -133,7 +146,9 @@ pub fn parse_sync(s: JsString, opts: JsValue) -> Result<JsValue, JsValue> {
133146
opts.syntax.typescript(),
134147
));
135148

136-
anyhow::Context::context(JsValue::from_serde(&program), "failed to serialize json")
149+
program
150+
.serialize(&COMPAT_SERIALIZER)
151+
.map_err(|e| anyhow::anyhow!("failed to serialize program: {}", e))
137152
})
138153
})
139154
})
@@ -160,9 +175,9 @@ pub fn transform_sync(
160175
let opts: Options = if opts.is_null() || opts.is_undefined() {
161176
Default::default()
162177
} else {
163-
anyhow::Context::context(opts.into_serde(), "failed to parse options")
164-
.map_err(|e| convert_err(e, None))?
178+
serde_wasm_bindgen::from_value(opts)?
165179
};
180+
166181
let error_format = opts.experimental.error_format.unwrap_or_default();
167182
try_with_handler(c.cm.clone(), Default::default(), |handler| {
168183
c.run(|| {
@@ -193,9 +208,13 @@ pub fn transform_sync(
193208
"failed to process js file",
194209
)?
195210
}
196-
Err(v) => unsafe { c.process_js(handler, v.into_serde().expect(""), &opts)? },
211+
Err(v) => {
212+
c.process_js(handler, serde_wasm_bindgen::from_value(v).expect("Should able to deserialize into program"), &opts)?
213+
}
197214
};
198-
anyhow::Context::context(JsValue::from_serde(&out), "failed to serialize json")
215+
216+
out.serialize(&COMPAT_SERIALIZER)
217+
.map_err(|e| anyhow::anyhow!("failed to serialize transform result: {}", e))
199218
})
200219
})
201220
.map_err(|e| convert_err(e, Some(error_format)))
@@ -218,10 +237,13 @@ pub fn print_sync(s: JsValue, opts: JsValue) -> Result<JsValue, JsValue> {
218237
let opts: Options = if opts.is_null() || opts.is_undefined() {
219238
Default::default()
220239
} else {
221-
anyhow::Context::context(opts.into_serde(), "failed to parse options")?
240+
serde_wasm_bindgen::from_value(opts)
241+
.map_err(|e| anyhow::anyhow!("failed to parse options: {}", e))?
222242
};
223-
let program: Program =
224-
anyhow::Context::context(s.into_serde(), "failed to deserialize program")?;
243+
244+
let program: Program = serde_wasm_bindgen::from_value(s)
245+
.map_err(|e| anyhow::anyhow!("failed to deserialize program: {}", e))?;
246+
225247
let s = anyhow::Context::context(
226248
c.print(
227249
&program,
@@ -241,7 +263,9 @@ pub fn print_sync(s: JsValue, opts: JsValue) -> Result<JsValue, JsValue> {
241263
),
242264
"failed to print code",
243265
)?;
244-
anyhow::Context::context(JsValue::from_serde(&s), "failed to serialize json")
266+
267+
serde_wasm_bindgen::to_value(&s)
268+
.map_err(|e| anyhow::anyhow!("failed to serialize json: {}", e))
245269
})
246270
})
247271
.map_err(|e| convert_err(e, None))

‎crates/binding_macros/Cargo.toml

+6-1
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,15 @@ binding_wasm = [
1818
"swc_common",
1919
"swc_ecma_transforms",
2020
"swc_ecma_ast",
21+
"swc_ecma_visit",
2122

2223
# Optional packages
2324
"once_cell",
2425
"wasm-bindgen",
2526
"wasm-bindgen-futures",
2627
"js-sys",
28+
"serde",
29+
"serde-wasm-bindgen",
2730
"anyhow",
2831
"console_error_panic_hook",
2932
]
@@ -34,14 +37,16 @@ swc = { optional = true, version = "0.232.99", path = "../swc" }
3437
swc_common = { optional = true, version = "0.29.14", path = "../swc_common" }
3538
swc_ecma_ast = { optional = true, version = "0.94.19", path = "../swc_ecma_ast" }
3639
swc_ecma_transforms = { optional = true, version = "0.198.52", path = "../swc_ecma_transforms" }
40+
swc_ecma_visit = { optional = true, version = "0.80.19", path = "../swc_ecma_visit" }
3741

3842
# Optional deps for the wasm binding macro
3943
anyhow = { optional = true, version = "1.0.58" }
4044
console_error_panic_hook = { optional = true, version = "0.1.7" }
4145
js-sys = { optional = true, version = "0.3.59" }
4246
once_cell = { optional = true, version = "1.13.0" }
47+
serde = { optional = true, version = "1", features = ["derive"] }
48+
serde-wasm-bindgen = { optional = true, version = "0.4.5" }
4349
wasm-bindgen = { optional = true, version = "0.2.82", features = [
44-
"serde-serialize",
4550
"enable-interning",
4651
] }
4752
wasm-bindgen-futures = { optional = true, version = "0.4.32" }

‎crates/binding_macros/src/wasm.rs

+85-30
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,61 @@ use anyhow::Error;
66
#[doc(hidden)]
77
pub use js_sys;
88
use once_cell::sync::Lazy;
9-
use swc::{config::ErrorFormat, Compiler};
9+
#[doc(hidden)]
10+
pub use serde_wasm_bindgen;
11+
use serde_wasm_bindgen::Serializer;
12+
use swc::{config::ErrorFormat, Compiler, HandlerOpts};
1013
#[doc(hidden)]
1114
pub use swc::{
1215
config::{Options, ParseOptions, SourceMapsConfig},
1316
try_with_handler,
1417
};
1518
#[doc(hidden)]
16-
pub use swc_common::{comments, FileName};
17-
use swc_common::{FilePathMapping, SourceMap};
19+
pub use swc_common::{
20+
comments::{self, SingleThreadedComments},
21+
errors::Handler,
22+
FileName, Mark, GLOBALS,
23+
};
24+
use swc_common::{sync::Lrc, FilePathMapping, SourceMap};
1825
#[doc(hidden)]
1926
pub use swc_ecma_ast::{EsVersion, Program};
2027
#[doc(hidden)]
21-
pub use swc_ecma_transforms::pass::noop;
28+
pub use swc_ecma_transforms::{pass::noop, resolver};
29+
#[doc(hidden)]
30+
pub use swc_ecma_visit::VisitMutWith;
2231
#[doc(hidden)]
2332
pub use wasm_bindgen::{JsCast, JsValue};
2433
#[doc(hidden)]
2534
pub use wasm_bindgen_futures::future_to_promise;
2635

36+
// A serializer with options to provide backward compat for the input / output
37+
// from the bindgen generated swc interfaces.
38+
#[doc(hidden)]
39+
pub fn compat_serializer() -> Arc<Serializer> {
40+
static V: Lazy<Arc<Serializer>> = Lazy::new(|| {
41+
let s = Serializer::new()
42+
.serialize_maps_as_objects(true)
43+
.serialize_missing_as_null(true);
44+
Arc::new(s)
45+
});
46+
47+
V.clone()
48+
}
49+
50+
#[doc(hidden)]
51+
pub fn try_with_handler_globals<F, Ret>(
52+
cm: Lrc<SourceMap>,
53+
config: HandlerOpts,
54+
op: F,
55+
) -> Result<Ret, Error>
56+
where
57+
F: FnOnce(&Handler) -> Result<Ret, Error>,
58+
{
59+
GLOBALS.set(&Default::default(), || {
60+
swc::try_with_handler(cm, config, op)
61+
})
62+
}
63+
2764
/// Get global sourcemap
2865
pub fn compiler() -> Arc<Compiler> {
2966
console_error_panic_hook::set_once();
@@ -56,23 +93,28 @@ macro_rules! build_minify_sync {
5693
($(#[$m:meta])*, $opt: expr) => {
5794
$(#[$m])*
5895
pub fn minify_sync(s: $crate::wasm::js_sys::JsString, opts: $crate::wasm::JsValue) -> Result<$crate::wasm::JsValue, $crate::wasm::JsValue> {
96+
use serde::Serialize;
97+
5998
let c = $crate::wasm::compiler();
6099

61-
$crate::wasm::try_with_handler(
100+
$crate::wasm::try_with_handler_globals(
62101
c.cm.clone(),
63102
$opt,
64103
|handler| {
65104
c.run(|| {
66105
let opts = if opts.is_null() || opts.is_undefined() {
67106
Default::default()
68107
} else {
69-
$crate::wasm::anyhow::Context::context(opts.into_serde(), "failed to parse options")?
108+
$crate::wasm::serde_wasm_bindgen::from_value(opts)
109+
.map_err(|e| $crate::wasm::anyhow::anyhow!("failed to parse options: {}", e))?
70110
};
71111

72112
let fm = c.cm.new_source_file($crate::wasm::FileName::Anon, s.into());
73113
let program = $crate::wasm::anyhow::Context::context(c.minify(fm, handler, &opts), "failed to minify file")?;
74114

75-
$crate::wasm::anyhow::Context::context($crate::wasm::JsValue::from_serde(&program), "failed to serialize json")
115+
program
116+
.serialize($crate::wasm::compat_serializer().as_ref())
117+
.map_err(|e| $crate::wasm::anyhow::anyhow!("failed to serialize program: {}", e))
76118
})
77119
},
78120
)
@@ -105,17 +147,21 @@ macro_rules! build_parse_sync {
105147
($(#[$m:meta])*, $opt: expr) => {
106148
$(#[$m])*
107149
pub fn parse_sync(s: $crate::wasm::js_sys::JsString, opts: $crate::wasm::JsValue) -> Result<$crate::wasm::JsValue, $crate::wasm::JsValue> {
150+
use serde::Serialize;
151+
use $crate::wasm::VisitMutWith;
152+
108153
let c = $crate::wasm::compiler();
109154

110-
$crate::wasm::try_with_handler(
155+
$crate::wasm::try_with_handler_globals(
111156
c.cm.clone(),
112157
$opt,
113158
|handler| {
114159
c.run(|| {
115160
let opts: $crate::wasm::ParseOptions = if opts.is_null() || opts.is_undefined() {
116161
Default::default()
117162
} else {
118-
$crate::wasm::anyhow::Context::context(opts.into_serde(), "failed to parse options")?
163+
$crate::wasm::serde_wasm_bindgen::from_value(opts)
164+
.map_err(|e| $crate::wasm::anyhow::anyhow!("failed to parse options: {}", e))?
119165
};
120166

121167
let fm = c.cm.new_source_file($crate::wasm::FileName::Anon, s.into());
@@ -127,9 +173,8 @@ macro_rules! build_parse_sync {
127173
None
128174
};
129175

130-
let program = $crate::wasm::anyhow::Context::context(
131-
c
132-
.parse_js(
176+
let mut program = $crate::wasm::anyhow::Context::context(
177+
c.parse_js(
133178
fm,
134179
handler,
135180
opts.target,
@@ -140,7 +185,15 @@ macro_rules! build_parse_sync {
140185
"failed to parse code"
141186
)?;
142187

143-
$crate::wasm::anyhow::Context::context($crate::wasm::JsValue::from_serde(&program), "failed to serialize json")
188+
program.visit_mut_with(&mut $crate::wasm::resolver(
189+
$crate::wasm::Mark::new(),
190+
$crate::wasm::Mark::new(),
191+
opts.syntax.typescript(),
192+
));
193+
194+
program
195+
.serialize($crate::wasm::compat_serializer().as_ref())
196+
.map_err(|e| $crate::wasm::anyhow::anyhow!("failed to serialize program: {}", e))
144197
})
145198
},
146199
)
@@ -175,18 +228,20 @@ macro_rules! build_print_sync {
175228
pub fn print_sync(s: $crate::wasm::JsValue, opts: $crate::wasm::JsValue) -> Result<$crate::wasm::JsValue, $crate::wasm::JsValue> {
176229
let c = $crate::wasm::compiler();
177230

178-
$crate::wasm::try_with_handler(
231+
$crate::wasm::try_with_handler_globals(
179232
c.cm.clone(),
180233
$opt,
181234
|_handler| {
182235
c.run(|| {
183236
let opts: $crate::wasm::Options = if opts.is_null() || opts.is_undefined() {
184237
Default::default()
185238
} else {
186-
$crate::wasm::anyhow::Context::context(opts.into_serde(), "failed to parse options")?
239+
$crate::wasm::serde_wasm_bindgen::from_value(opts)
240+
.map_err(|e| $crate::wasm::anyhow::anyhow!("failed to parse options: {}", e))?
187241
};
188242

189-
let program: $crate::wasm::Program = $crate::wasm::anyhow::Context::context(s.into_serde(), "failed to deserialize program")?;
243+
let program: $crate::wasm::Program = $crate::wasm::serde_wasm_bindgen::from_value(s)
244+
.map_err(|e| $crate::wasm::anyhow::anyhow!("failed to deserialize program: {}", e))?;
190245
let s = $crate::wasm::anyhow::Context::context(c
191246
.print(
192247
&program,
@@ -205,7 +260,8 @@ macro_rules! build_print_sync {
205260
false,
206261
),"failed to print code")?;
207262

208-
$crate::wasm::anyhow::Context::context(JsValue::from_serde(&s), "failed to serialize json")
263+
serde_wasm_bindgen::to_value(&s)
264+
.map_err(|e| anyhow::anyhow!("failed to serialize json: {}", e))
209265
})
210266
},
211267
)
@@ -234,7 +290,7 @@ macro_rules! build_print {
234290
#[macro_export]
235291
macro_rules! build_transform_sync {
236292
($(#[$m:meta])*) => {
237-
build_transform_sync!($(#[$m])*, |_, _| $crate::wasm::noop(), |_, _| $crate::wasm::noop(), Default::default());
293+
build_transform_sync!($(#[$m])*, |_| $crate::wasm::noop(), |_| $crate::wasm::noop(), Default::default());
238294
};
239295
($(#[$m:meta])*, $before_pass: expr, $after_pass: expr) => {
240296
build_transform_sync!($(#[$m])*, $before_pass, $after_pass, Default::default());
@@ -247,6 +303,8 @@ macro_rules! build_transform_sync {
247303
opts: $crate::wasm::JsValue,
248304
experimental_plugin_bytes_resolver: $crate::wasm::JsValue,
249305
) -> Result<$crate::wasm::JsValue, $crate::wasm::JsValue> {
306+
use serde::Serialize;
307+
250308
let c = $crate::wasm::compiler();
251309

252310
#[cfg(feature = "plugin")]
@@ -281,9 +339,7 @@ macro_rules! build_transform_sync {
281339
buffer
282340
};
283341

284-
let bytes: Vec<u8> = data
285-
.into_serde()
286-
.expect("Could not read byte from plugin resolver");
342+
let bytes: Vec<u8> = $crate::wasm::serde_wasm_bindgen::from_value(data).expect("Could not read byte from plugin resolver");
287343

288344
// In here we 'inject' externally loaded bytes into the cache, so
289345
// remaining plugin_runner execution path works as much as
@@ -296,13 +352,11 @@ macro_rules! build_transform_sync {
296352
let opts: $crate::wasm::Options = if opts.is_null() || opts.is_undefined() {
297353
Default::default()
298354
} else {
299-
$crate::wasm::anyhow::Context::context(opts.into_serde(), "failed to parse options")
300-
.map_err(|e| $crate::wasm::convert_err(e, None))?
355+
$crate::wasm::serde_wasm_bindgen::from_value(opts)?
301356
};
302357

303358
let error_format = opts.experimental.error_format.unwrap_or_default();
304-
305-
$crate::wasm::try_with_handler(
359+
$crate::wasm::try_with_handler_globals(
306360
c.cm.clone(),
307361
$opt,
308362
|handler| {
@@ -320,24 +374,25 @@ macro_rules! build_transform_sync {
320374
);
321375
let cm = c.cm.clone();
322376
let file = fm.clone();
323-
377+
let comments = $crate::wasm::SingleThreadedComments::default();
324378
$crate::wasm::anyhow::Context::context(
325379
c.process_js_with_custom_pass(
326380
fm,
327381
None,
328382
handler,
329383
&opts,
330-
Default::default(),
384+
comments,
331385
$before_pass,
332386
$after_pass,
333387
), "failed to process js file"
334388
)?
335389
}
336-
Err(v) => unsafe { c.process_js(handler, v.into_serde().expect(""), &opts)? },
390+
Err(v) => unsafe { c.process_js(handler, $crate::wasm::serde_wasm_bindgen::from_value(v).expect(""), &opts)? },
337391
};
338392

339-
$crate::wasm::anyhow::Context::context($crate::wasm::JsValue::from_serde(&out),
340-
"failed to serialize json")
393+
out
394+
.serialize($crate::wasm::compat_serializer().as_ref())
395+
.map_err(|e| $crate::wasm::anyhow::anyhow!("failed to serialize transform result: {}", e))
341396
})
342397
},
343398
)

‎crates/swc_core/.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
tests/**/Cargo.lock
2+
tests/**/target/

‎crates/swc_core/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -362,3 +362,6 @@ swc_plugin_runner = { optional = true, version = "0.77.33", path = "../swc_plugi
362362

363363
[build-dependencies]
364364
vergen = { version = "7.3.2", default-features = false, features = ["cargo"] }
365+
366+
[dev-dependencies]
367+
anyhow = "1.0.66"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
[workspace]
2+
3+
[package]
4+
edition = "2021"
5+
name = "stub_napi"
6+
publish = false
7+
version = "0.1.0"
8+
9+
[lib]
10+
crate-type = ["cdylib"]
11+
12+
[features]
13+
default = ["swc_v1", "plugin"]
14+
plugin = ["swc_core/plugin_transform_host_native"]
15+
swc_v1 = ["swc_core/bundler_node_v1"]
16+
swc_v2 = ["swc_core/bundler_node_v2"]
17+
18+
# Experiemntal bytechecked plugin serialization / deserialization.
19+
plugin_bytecheck = [
20+
# "swc_core/__plugin_transform_host_bytecheck",
21+
"swc_core/__plugin_transform_host_schema_v1",
22+
"swc_core/__plugin_transform_env_native",
23+
]
24+
25+
# Internal flag for testing purpose only.
26+
__plugin_transform_vtest = [
27+
"swc_core/__plugin_transform_host",
28+
"swc_core/__plugin_transform_host_schema_vtest",
29+
"swc_core/__plugin_transform_env_native",
30+
]
31+
32+
[build-dependencies]
33+
napi-build = { version = "2" }
34+
35+
[dependencies]
36+
anyhow = "1.0.66"
37+
backtrace = "0.3"
38+
napi = { version = "2", default-features = false, features = [
39+
"napi3",
40+
"serde-json",
41+
] }
42+
napi-derive = { version = "2", default-features = false, features = [
43+
"type-def",
44+
] }
45+
path-clean = "0.1"
46+
serde = { version = "1", features = ["derive"] }
47+
serde_json = { version = "1", features = ["unbounded_depth"] }
48+
tracing = { version = "0.1.37", features = ["release_max_level_info"] }
49+
tracing-chrome = "0.5.0"
50+
tracing-futures = "0.2.5"
51+
tracing-subscriber = { version = "0.3.9", features = ["env-filter"] }
52+
53+
swc_core = { path = "../../../../swc_core", features = [
54+
"ecma_ast",
55+
"common_concurrent",
56+
"bundler",
57+
"ecma_loader",
58+
"ecma_transforms",
59+
"ecma_visit",
60+
"base_node",
61+
"base_concurrent",
62+
] }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
use std::{
2+
env,
3+
fs::File,
4+
io::{BufWriter, Write},
5+
path::Path,
6+
};
7+
8+
extern crate napi_build;
9+
10+
#[cfg(all(not(feature = "swc_v1"), not(feature = "swc_v2")))]
11+
compile_error!("Please enable swc_v1 or swc_v2 feature");
12+
13+
#[cfg(all(feature = "swc_v1", feature = "swc_v2"))]
14+
compile_error!("Features swc_v1 and swc_v2 are incompatible");
15+
16+
fn main() {
17+
let out_dir = env::var("OUT_DIR").expect("Outdir should exist");
18+
let dest_path = Path::new(&out_dir).join("triple.txt");
19+
let mut f =
20+
BufWriter::new(File::create(&dest_path).expect("Failed to create target triple text"));
21+
write!(
22+
f,
23+
"{}",
24+
env::var("TARGET").expect("Target should be specified")
25+
)
26+
.expect("Failed to write target triple text");
27+
28+
napi_build::setup();
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#![recursion_limit = "2048"]
2+
#![allow(dead_code)]
3+
4+
#[macro_use]
5+
extern crate napi_derive;
6+
7+
use std::{env, panic::set_hook, sync::Arc};
8+
9+
use backtrace::Backtrace;
10+
use swc_core::{
11+
base::Compiler,
12+
common::{sync::Lazy, FilePathMapping, SourceMap},
13+
};
14+
15+
static COMPILER: Lazy<Arc<Compiler>> = Lazy::new(|| {
16+
let cm = Arc::new(SourceMap::new(FilePathMapping::empty()));
17+
18+
Arc::new(Compiler::new(cm))
19+
});
20+
21+
#[napi::module_init]
22+
fn init() {
23+
if cfg!(debug_assertions) || env::var("SWC_DEBUG").unwrap_or_default() == "1" {
24+
set_hook(Box::new(|panic_info| {
25+
let backtrace = Backtrace::new();
26+
println!("Panic: {:?}\nBacktrace: {:?}", panic_info, backtrace);
27+
}));
28+
}
29+
}
30+
31+
fn get_compiler() -> Arc<Compiler> {
32+
COMPILER.clone()
33+
}
34+
35+
#[napi(js_name = "Compiler")]
36+
pub struct JsCompiler {
37+
_compiler: Arc<Compiler>,
38+
}
39+
40+
#[napi]
41+
impl JsCompiler {
42+
#[napi(constructor)]
43+
#[allow(clippy::new_without_default)]
44+
#[tracing::instrument(level = "info", skip_all)]
45+
pub fn new() -> Self {
46+
Self {
47+
_compiler: COMPILER.clone(),
48+
}
49+
}
50+
}
51+
52+
pub type ArcCompiler = Arc<Compiler>;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
[workspace]
2+
3+
[package]
4+
edition = "2021"
5+
name = "stub_wasm"
6+
publish = false
7+
version = "0.1.0"
8+
9+
[lib]
10+
crate-type = ["cdylib"]
11+
12+
[features]
13+
default = ["swc_v1"]
14+
plugin = []
15+
swc_v1 = []
16+
17+
[dependencies]
18+
anyhow = "1.0.66"
19+
serde = { version = "1", features = ["derive"] }
20+
serde-wasm-bindgen = "0.4.5"
21+
swc_core = { path = "../../../../swc_core", features = [
22+
"common_perf",
23+
"binding_macro_wasm",
24+
"ecma_transforms",
25+
"ecma_visit",
26+
"plugin_transform_host_js",
27+
] }
28+
tracing = { version = "0.1.37", features = ["max_level_off"] }
29+
wasm-bindgen = { version = "0.2.82", features = ["enable-interning"] }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
use swc_core::binding_macros::{
2+
build_minify, build_minify_sync, build_parse, build_parse_sync, build_print, build_print_sync,
3+
build_transform, build_transform_sync,
4+
};
5+
use wasm_bindgen::prelude::*;
6+
7+
build_minify_sync!(#[wasm_bindgen(js_name = "minifySync")]);
8+
build_minify!(#[wasm_bindgen(js_name = "minify")]);
9+
build_parse_sync!(#[wasm_bindgen(js_name = "parseSync")]);
10+
build_parse!(#[wasm_bindgen(js_name = "parse")]);
11+
build_print_sync!(#[wasm_bindgen(js_name = "printSync")]);
12+
build_print!(#[wasm_bindgen(js_name = "print")]);
13+
build_transform_sync!(#[wasm_bindgen(js_name = "transformSync")]);
14+
build_transform!(#[wasm_bindgen(js_name = "transform")]);

‎crates/swc_core/tests/integration.rs

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
use std::{
2+
env,
3+
path::{Path, PathBuf},
4+
process::{Command, Stdio},
5+
};
6+
7+
use anyhow::{anyhow, Error};
8+
9+
fn build_fixture_binary(dir: &Path, target: Option<&str>) -> Result<(), Error> {
10+
let mut args = vec!["build".to_string()];
11+
if let Some(target) = target {
12+
args.push(format!("--target={}", target));
13+
};
14+
15+
let mut cmd = Command::new("cargo");
16+
cmd.current_dir(dir);
17+
cmd.args(args).stderr(Stdio::inherit());
18+
cmd.output()?;
19+
20+
if !cmd
21+
.status()
22+
.expect("Exit code should be available")
23+
.success()
24+
{
25+
return Err(anyhow!("Failed to build binary"));
26+
}
27+
28+
Ok(())
29+
}
30+
31+
#[test]
32+
fn swc_core_napi_integartion_build() -> Result<(), Error> {
33+
build_fixture_binary(
34+
&PathBuf::from(env::var("CARGO_MANIFEST_DIR")?)
35+
.join("tests")
36+
.join("fixture")
37+
.join("stub_napi"),
38+
None,
39+
)
40+
}
41+
42+
#[test]
43+
fn swc_core_wasm_integartion_build() -> Result<(), Error> {
44+
build_fixture_binary(
45+
&PathBuf::from(env::var("CARGO_MANIFEST_DIR")?)
46+
.join("tests")
47+
.join("fixture")
48+
.join("stub_wasm"),
49+
Some("wasm32-unknown-unknown"),
50+
)
51+
}

1 commit comments

Comments
 (1)

github-actions[bot] commented on Nov 18, 2022

@github-actions[bot]

Benchmark

Benchmark suite Current: dd4b9e8 Previous: 4d7b920 Ratio
es/full/bugs-1 333261 ns/iter (± 24615) 366800 ns/iter (± 31418) 0.91
es/full/minify/libraries/antd 1807198979 ns/iter (± 32721704) 2055494042 ns/iter (± 78757627) 0.88
es/full/minify/libraries/d3 419103916 ns/iter (± 12419303) 477783305 ns/iter (± 18919141) 0.88
es/full/minify/libraries/echarts 1566847566 ns/iter (± 49474633) 1779525769 ns/iter (± 46840644) 0.88
es/full/minify/libraries/jquery 99481084 ns/iter (± 2778702) 118346314 ns/iter (± 7646826) 0.84
es/full/minify/libraries/lodash 127093735 ns/iter (± 10497244) 137623358 ns/iter (± 6206468) 0.92
es/full/minify/libraries/moment 66319902 ns/iter (± 6021505) 69789977 ns/iter (± 1720809) 0.95
es/full/minify/libraries/react 22117838 ns/iter (± 1405033) 23433969 ns/iter (± 1581414) 0.94
es/full/minify/libraries/terser 325721497 ns/iter (± 6132262) 372333562 ns/iter (± 12267596) 0.87
es/full/minify/libraries/three 585693790 ns/iter (± 5794116) 649739339 ns/iter (± 19737265) 0.90
es/full/minify/libraries/typescript 3471689839 ns/iter (± 78001210) 3799607078 ns/iter (± 61154067) 0.91
es/full/minify/libraries/victory 860902587 ns/iter (± 21743934) 934895778 ns/iter (± 30254734) 0.92
es/full/minify/libraries/vue 168050579 ns/iter (± 11482018) 182105144 ns/iter (± 11566172) 0.92
es/full/codegen/es3 33755 ns/iter (± 937) 34522 ns/iter (± 3486) 0.98
es/full/codegen/es5 33929 ns/iter (± 604) 34487 ns/iter (± 5155) 0.98
es/full/codegen/es2015 34413 ns/iter (± 6277) 35078 ns/iter (± 3853) 0.98
es/full/codegen/es2016 33957 ns/iter (± 979) 34826 ns/iter (± 2698) 0.98
es/full/codegen/es2017 34391 ns/iter (± 1993) 34187 ns/iter (± 2043) 1.01
es/full/codegen/es2018 34562 ns/iter (± 13329) 34358 ns/iter (± 2770) 1.01
es/full/codegen/es2019 35699 ns/iter (± 5306) 34475 ns/iter (± 3493) 1.04
es/full/codegen/es2020 34602 ns/iter (± 4503) 35314 ns/iter (± 3217) 0.98
es/full/all/es3 219672312 ns/iter (± 33052956) 223676981 ns/iter (± 15577815) 0.98
es/full/all/es5 183535112 ns/iter (± 14564518) 205150591 ns/iter (± 12701799) 0.89
es/full/all/es2015 146592478 ns/iter (± 12870827) 159631999 ns/iter (± 10881445) 0.92
es/full/all/es2016 146346454 ns/iter (± 12561533) 161724721 ns/iter (± 11560641) 0.90
es/full/all/es2017 147970126 ns/iter (± 15861961) 159447439 ns/iter (± 14104711) 0.93
es/full/all/es2018 146178569 ns/iter (± 11174568) 159974078 ns/iter (± 12840273) 0.91
es/full/all/es2019 144069288 ns/iter (± 12461896) 159551306 ns/iter (± 13664315) 0.90
es/full/all/es2020 139428674 ns/iter (± 8948386) 154461090 ns/iter (± 10076296) 0.90
es/full/parser 725785 ns/iter (± 32380) 772838 ns/iter (± 66860) 0.94
es/full/base/fixer 26742 ns/iter (± 897) 28855 ns/iter (± 3848) 0.93
es/full/base/resolver_and_hygiene 92772 ns/iter (± 2698) 99021 ns/iter (± 16403) 0.94
serialization of ast node 219 ns/iter (± 4) 220 ns/iter (± 26) 1.00
serialization of serde 222 ns/iter (± 7) 251 ns/iter (± 36) 0.88

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.