Skip to content

Commit d957aac

Browse files
authoredNov 21, 2022
refactor(binding/wasm): Use binding_macro (#6487)
1 parent 0e67eaf commit d957aac

File tree

2 files changed

+23
-241
lines changed

2 files changed

+23
-241
lines changed
 

‎bindings/binding_core_wasm/src/lib.rs

+12-235
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,10 @@
1-
use anyhow::Error;
2-
use serde::Serialize;
3-
use serde_wasm_bindgen::Serializer;
4-
use swc_core::{
5-
base::HandlerOpts,
6-
binding_macros::wasm::{
7-
compiler, convert_err, future_to_promise,
8-
js_sys::{JsString, Promise},
9-
noop, Options, ParseOptions, SourceMapsConfig,
10-
},
11-
common::{
12-
comments::{self, SingleThreadedComments},
13-
errors::Handler,
14-
sync::Lrc,
15-
FileName, Mark, SourceMap, GLOBALS,
16-
},
17-
ecma::{
18-
ast::{EsVersion, Program},
19-
transforms::base::resolver,
20-
visit::VisitMutWith,
21-
},
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,
224
};
23-
use wasm_bindgen::{prelude::*, JsCast};
5+
use wasm_bindgen::prelude::*;
246
mod types;
257

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-
328
/// Custom interface definitions for the @swc/wasm's public interface instead of
339
/// auto generated one, which is not reflecting most of types in detail.
3410
#[wasm_bindgen(typescript_custom_section)]
@@ -68,210 +44,11 @@ export function transform(
6844
export function transformSync(code: string | Program, opts?: Options, experimental_plugin_bytes_resolver?: any): Output;
6945
"#;
7046

71-
fn try_with_handler<F, Ret>(cm: Lrc<SourceMap>, config: HandlerOpts, op: F) -> Result<Ret, Error>
72-
where
73-
F: FnOnce(&Handler) -> Result<Ret, Error>,
74-
{
75-
GLOBALS.set(&Default::default(), || {
76-
swc_core::base::try_with_handler(cm, config, op)
77-
})
78-
}
79-
80-
#[wasm_bindgen(
81-
js_name = "minifySync",
82-
typescript_type = "minifySync",
83-
skip_typescript
84-
)]
85-
pub fn minify_sync(s: JsString, opts: JsValue) -> Result<JsValue, JsValue> {
86-
let c = compiler();
87-
try_with_handler(c.cm.clone(), Default::default(), |handler| {
88-
c.run(|| {
89-
let opts = if opts.is_null() || opts.is_undefined() {
90-
Default::default()
91-
} else {
92-
serde_wasm_bindgen::from_value(opts)
93-
.map_err(|e| anyhow::anyhow!("failed to parse options: {}", e))?
94-
};
95-
let fm = c.cm.new_source_file(FileName::Anon, s.into());
96-
let program =
97-
anyhow::Context::context(c.minify(fm, handler, &opts), "failed to minify file")?;
98-
99-
program
100-
.serialize(&COMPAT_SERIALIZER)
101-
.map_err(|e| anyhow::anyhow!("failed to serialize program: {}", e))
102-
})
103-
})
104-
.map_err(|e| convert_err(e, None))
105-
}
106-
107-
#[wasm_bindgen(js_name = "minify", typescript_type = "minify", skip_typescript)]
108-
pub fn minify(s: JsString, opts: JsValue) -> Promise {
109-
future_to_promise(async { minify_sync(s, opts) })
110-
}
111-
112-
#[wasm_bindgen(js_name = "parseSync", typescript_type = "parseSync", skip_typescript)]
113-
pub fn parse_sync(s: JsString, opts: JsValue) -> Result<JsValue, JsValue> {
114-
let c = compiler();
115-
try_with_handler(c.cm.clone(), Default::default(), |handler| {
116-
c.run(|| {
117-
GLOBALS.set(&Default::default(), || {
118-
let opts: ParseOptions = if opts.is_null() || opts.is_undefined() {
119-
Default::default()
120-
} else {
121-
serde_wasm_bindgen::from_value(opts)
122-
.map_err(|e| anyhow::anyhow!("failed to parse options: {}", e))?
123-
};
124-
let fm = c.cm.new_source_file(FileName::Anon, s.into());
125-
let cmts = c.comments().clone();
126-
let comments = if opts.comments {
127-
Some(&cmts as &dyn comments::Comments)
128-
} else {
129-
None
130-
};
131-
let mut program = anyhow::Context::context(
132-
c.parse_js(
133-
fm,
134-
handler,
135-
opts.target,
136-
opts.syntax,
137-
opts.is_module,
138-
comments,
139-
),
140-
"failed to parse code",
141-
)?;
142-
143-
program.visit_mut_with(&mut resolver(
144-
Mark::new(),
145-
Mark::new(),
146-
opts.syntax.typescript(),
147-
));
148-
149-
program
150-
.serialize(&COMPAT_SERIALIZER)
151-
.map_err(|e| anyhow::anyhow!("failed to serialize program: {}", e))
152-
})
153-
})
154-
})
155-
.map_err(|e| convert_err(e, None))
156-
}
157-
158-
#[wasm_bindgen(js_name = "parse", typescript_type = "parse", skip_typescript)]
159-
pub fn parse(s: JsString, opts: JsValue) -> Promise {
160-
future_to_promise(async { parse_sync(s, opts) })
161-
}
162-
163-
#[wasm_bindgen(
164-
js_name = "transformSync",
165-
typescript_type = "transformSync",
166-
skip_typescript
167-
)]
168-
#[allow(unused_variables)]
169-
pub fn transform_sync(
170-
s: JsValue,
171-
opts: JsValue,
172-
experimental_plugin_bytes_resolver: JsValue,
173-
) -> Result<JsValue, JsValue> {
174-
let c = compiler();
175-
let opts: Options = if opts.is_null() || opts.is_undefined() {
176-
Default::default()
177-
} else {
178-
serde_wasm_bindgen::from_value(opts)?
179-
};
180-
181-
let error_format = opts.experimental.error_format.unwrap_or_default();
182-
try_with_handler(c.cm.clone(), Default::default(), |handler| {
183-
c.run(|| {
184-
let s = JsCast::dyn_into::<JsString>(s);
185-
let out = match s {
186-
Ok(s) => {
187-
let fm = c.cm.new_source_file(
188-
if opts.filename.is_empty() {
189-
FileName::Anon
190-
} else {
191-
FileName::Real(opts.filename.clone().into())
192-
},
193-
s.into(),
194-
);
195-
let cm = c.cm.clone();
196-
let file = fm.clone();
197-
let comments = SingleThreadedComments::default();
198-
anyhow::Context::context(
199-
c.process_js_with_custom_pass(
200-
fm,
201-
None,
202-
handler,
203-
&opts,
204-
comments,
205-
|_| noop(),
206-
|_| noop(),
207-
),
208-
"failed to process js file",
209-
)?
210-
}
211-
Err(v) => {
212-
c.process_js(handler, serde_wasm_bindgen::from_value(v).expect("Should able to deserialize into program"), &opts)?
213-
}
214-
};
215-
216-
out.serialize(&COMPAT_SERIALIZER)
217-
.map_err(|e| anyhow::anyhow!("failed to serialize transform result: {}", e))
218-
})
219-
})
220-
.map_err(|e| convert_err(e, Some(error_format)))
221-
}
222-
223-
#[wasm_bindgen(js_name = "transform", typescript_type = "transform", skip_typescript)]
224-
pub fn transform(
225-
s: JsValue,
226-
opts: JsValue,
227-
experimental_plugin_bytes_resolver: JsValue,
228-
) -> Promise {
229-
future_to_promise(async { transform_sync(s, opts, experimental_plugin_bytes_resolver) })
230-
}
231-
232-
#[wasm_bindgen(js_name = "printSync", typescript_type = "printSync", skip_typescript)]
233-
pub fn print_sync(s: JsValue, opts: JsValue) -> Result<JsValue, JsValue> {
234-
let c = compiler();
235-
try_with_handler(c.cm.clone(), Default::default(), |_handler| {
236-
c.run(|| {
237-
let opts: Options = if opts.is_null() || opts.is_undefined() {
238-
Default::default()
239-
} else {
240-
serde_wasm_bindgen::from_value(opts)
241-
.map_err(|e| anyhow::anyhow!("failed to parse options: {}", e))?
242-
};
243-
244-
let program: Program = serde_wasm_bindgen::from_value(s)
245-
.map_err(|e| anyhow::anyhow!("failed to deserialize program: {}", e))?;
246-
247-
let s = anyhow::Context::context(
248-
c.print(
249-
&program,
250-
None,
251-
None,
252-
true,
253-
opts.codegen_target().unwrap_or(EsVersion::Es2020),
254-
opts.source_maps
255-
.clone()
256-
.unwrap_or(SourceMapsConfig::Bool(false)),
257-
&Default::default(),
258-
None,
259-
opts.config.minify.into(),
260-
None,
261-
opts.config.emit_source_map_columns.into_bool(),
262-
false,
263-
),
264-
"failed to print code",
265-
)?;
266-
267-
serde_wasm_bindgen::to_value(&s)
268-
.map_err(|e| anyhow::anyhow!("failed to serialize json: {}", e))
269-
})
270-
})
271-
.map_err(|e| convert_err(e, None))
272-
}
273-
274-
#[wasm_bindgen(js_name = "print", typescript_type = "print", skip_typescript)]
275-
pub fn print(s: JsValue, opts: JsValue) -> Promise {
276-
future_to_promise(async { print_sync(s, opts) })
277-
}
47+
build_minify_sync!(#[wasm_bindgen(js_name = "minifySync", typescript_type = "minifySync",skip_typescript)]);
48+
build_minify!(#[wasm_bindgen(js_name = "minify", typescript_type = "minify",skip_typescript)]);
49+
build_parse_sync!(#[wasm_bindgen(js_name = "parseSync", typescript_type = "parseSync",skip_typescript)]);
50+
build_parse!(#[wasm_bindgen(js_name = "parse", typescript_type = "parse",skip_typescript)]);
51+
build_print_sync!(#[wasm_bindgen(js_name = "printSync", typescript_type = "printSync",skip_typescript)]);
52+
build_print!(#[wasm_bindgen(js_name = "print", typescript_type = "print",skip_typescript)]);
53+
build_transform_sync!(#[wasm_bindgen(js_name = "transformSync", typescript_type = "transformSync",skip_typescript)]);
54+
build_transform!(#[wasm_bindgen(js_name = "transform", typescript_type = "transform",skip_typescript)]);

‎bindings/binding_core_wasm/src/types.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -364,11 +364,11 @@ export interface TerserCompressOptions {
364364
export interface TerserMangleOptions {
365365
props?: TerserManglePropertiesOptions,
366366
367-
top_level?: boolean,
367+
toplevel?: boolean,
368368
369-
keep_class_names?: boolean,
369+
keep_classnames?: boolean,
370370
371-
keep_fn_names?: boolean,
371+
keep_fnames?: boolean,
372372
373373
keep_private_props?: boolean,
374374
@@ -678,7 +678,7 @@ export interface JscConfig {
678678
baseUrl?: string
679679
680680
paths?: {
681-
[from: string]: [string]
681+
[from: string]: string[]
682682
}
683683
684684
minify?: JsMinifyOptions;
@@ -907,7 +907,7 @@ export interface GlobalPassOption {
907907
envs?: string[];
908908
}
909909
910-
export type ModuleConfig = Es6Config | CommonJsConfig | UmdConfig | AmdConfig | NodeNextConfig;
910+
export type ModuleConfig = Es6Config | CommonJsConfig | UmdConfig | AmdConfig | NodeNextConfig | SystemjsConfig;
911911
912912
export interface BaseModuleConfig {
913913
/**
@@ -1068,6 +1068,8 @@ export interface BaseModuleConfig {
10681068
* If set to true, dynamic imports will be preserved.
10691069
*/
10701070
ignoreDynamic?: boolean;
1071+
allowTopLevelThis?: boolean;
1072+
preserveImportMeta?: boolean;
10711073
}
10721074
10731075
export interface Es6Config extends BaseModuleConfig {
@@ -1091,7 +1093,10 @@ export interface AmdConfig extends BaseModuleConfig {
10911093
type: "amd";
10921094
moduleId?: string;
10931095
}
1094-
1096+
export interface SystemjsConfig {
1097+
type: "systemjs";
1098+
allowTopLevelThis?: boolean;
1099+
}
10951100
export interface Output {
10961101
/**
10971102
* Transformed code

1 commit comments

Comments
 (1)

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

@github-actions[bot]

Benchmark

Benchmark suite Current: d957aac Previous: 7fe091a Ratio
es/full/bugs-1 355644 ns/iter (± 34972) 344071 ns/iter (± 18909) 1.03
es/full/minify/libraries/antd 1924375843 ns/iter (± 24700286) 1880752872 ns/iter (± 27724911) 1.02
es/full/minify/libraries/d3 418516624 ns/iter (± 29468176) 408872327 ns/iter (± 10337906) 1.02
es/full/minify/libraries/echarts 1661882174 ns/iter (± 72001162) 1592486577 ns/iter (± 20242840) 1.04
es/full/minify/libraries/jquery 121308547 ns/iter (± 8114923) 104174694 ns/iter (± 4100286) 1.16
es/full/minify/libraries/lodash 144805257 ns/iter (± 19088462) 125012183 ns/iter (± 5091035) 1.16
es/full/minify/libraries/moment 70734769 ns/iter (± 3944496) 61905334 ns/iter (± 1629693) 1.14
es/full/minify/libraries/react 25782656 ns/iter (± 880415) 20509429 ns/iter (± 489340) 1.26
es/full/minify/libraries/terser 389602971 ns/iter (± 32330111) 326336949 ns/iter (± 28413498) 1.19
es/full/minify/libraries/three 652272739 ns/iter (± 14458354) 588771349 ns/iter (± 27419191) 1.11
es/full/minify/libraries/typescript 3754961918 ns/iter (± 140474437) 3435441737 ns/iter (± 58333195) 1.09
es/full/minify/libraries/victory 894463918 ns/iter (± 20935420) 878820429 ns/iter (± 16515001) 1.02
es/full/minify/libraries/vue 176250640 ns/iter (± 11113458) 162345753 ns/iter (± 5096746) 1.09
es/full/codegen/es3 34452 ns/iter (± 1948) 47104 ns/iter (± 1433) 0.73
es/full/codegen/es5 34702 ns/iter (± 3535) 47553 ns/iter (± 1701) 0.73
es/full/codegen/es2015 33413 ns/iter (± 939) 47288 ns/iter (± 1977) 0.71
es/full/codegen/es2016 33736 ns/iter (± 3185) 47285 ns/iter (± 1383) 0.71
es/full/codegen/es2017 35426 ns/iter (± 4759) 47005 ns/iter (± 1926) 0.75
es/full/codegen/es2018 39407 ns/iter (± 46759) 47221 ns/iter (± 1908) 0.83
es/full/codegen/es2019 34982 ns/iter (± 3113) 46986 ns/iter (± 3751) 0.74
es/full/codegen/es2020 33830 ns/iter (± 2334) 47106 ns/iter (± 1651) 0.72
es/full/all/es3 227251443 ns/iter (± 28622846) 197072875 ns/iter (± 11055693) 1.15
es/full/all/es5 207132358 ns/iter (± 20417800) 183315489 ns/iter (± 8177463) 1.13
es/full/all/es2015 164477962 ns/iter (± 15605318) 145851549 ns/iter (± 3355968) 1.13
es/full/all/es2016 154922776 ns/iter (± 10742297) 146334431 ns/iter (± 5872326) 1.06
es/full/all/es2017 153141706 ns/iter (± 13307824) 146651074 ns/iter (± 6743015) 1.04
es/full/all/es2018 152004383 ns/iter (± 11550747) 144704247 ns/iter (± 6521531) 1.05
es/full/all/es2019 150753334 ns/iter (± 12385616) 143124257 ns/iter (± 3735106) 1.05
es/full/all/es2020 146794393 ns/iter (± 9968285) 137327945 ns/iter (± 4613344) 1.07
es/full/parser 746922 ns/iter (± 37924) 718033 ns/iter (± 42779) 1.04
es/full/base/fixer 26820 ns/iter (± 1093) 26196 ns/iter (± 1087) 1.02
es/full/base/resolver_and_hygiene 94866 ns/iter (± 5480) 90766 ns/iter (± 4614) 1.05
serialization of ast node 209 ns/iter (± 21) 206 ns/iter (± 19) 1.01
serialization of serde 214 ns/iter (± 6) 233 ns/iter (± 10) 0.92

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

Please sign in to comment.