diff --git a/packages/next-swc/Cargo.lock b/packages/next-swc/Cargo.lock index db4a56a3ea49..73033e3bdd84 100644 --- a/packages/next-swc/Cargo.lock +++ b/packages/next-swc/Cargo.lock @@ -1149,9 +1149,9 @@ checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" [[package]] name = "js-sys" -version = "0.3.57" +version = "0.3.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" +checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" dependencies = [ "wasm-bindgen", ] @@ -4447,6 +4447,7 @@ dependencies = [ "anyhow", "console_error_panic_hook", "getrandom", + "js-sys", "next-swc", "once_cell", "parking_lot_core 0.8.0", @@ -4466,9 +4467,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.80" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" +checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" dependencies = [ "cfg-if 1.0.0", "serde", @@ -4478,13 +4479,13 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.80" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" +checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" dependencies = [ "bumpalo", - "lazy_static", "log", + "once_cell", "proc-macro2", "quote", "syn", @@ -4505,9 +4506,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.80" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" +checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4515,9 +4516,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.80" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" +checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" dependencies = [ "proc-macro2", "quote", @@ -4528,9 +4529,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.80" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" +checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" [[package]] name = "wasmer" diff --git a/packages/next-swc/crates/wasm/Cargo.toml b/packages/next-swc/crates/wasm/Cargo.toml index 4a4f0d2a7b56..650b3464450a 100644 --- a/packages/next-swc/crates/wasm/Cargo.toml +++ b/packages/next-swc/crates/wasm/Cargo.toml @@ -30,8 +30,9 @@ swc_common = { version = "0.26.0", features = ["concurrent", "sourcemap"] } swc_ecmascript = { version = "0.186.0", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] } swc_plugin_runner = { version = "0.70.0", default-features = false, optional = true } tracing = { version = "0.1.32", features = ["release_max_level_off"] } -wasm-bindgen = {version = "0.2", features = ["serde-serialize"]} +wasm-bindgen = {version = "0.2", features = ["serde-serialize", "enable-interning"]} wasm-bindgen-futures = "0.4.8" wasmer = { version = "2.3.0", optional = true, default-features = false } wasmer-wasi = { version = "2.3.0", optional = true, default-features = false } getrandom = { version = "0.2.5", optional = true, default-features = false } +js-sys = "0.3.59" diff --git a/packages/next-swc/crates/wasm/src/lib.rs b/packages/next-swc/crates/wasm/src/lib.rs index 17392a0a6817..e6b0c7331418 100644 --- a/packages/next-swc/crates/wasm/src/lib.rs +++ b/packages/next-swc/crates/wasm/src/lib.rs @@ -1,18 +1,20 @@ use anyhow::{Context, Error}; +use js_sys::JsString; use next_swc::{custom_before_pass, TransformOptions}; use once_cell::sync::Lazy; use std::sync::Arc; use swc::{config::JsMinifyOptions, config::ParseOptions, try_with_handler, Compiler}; use swc_common::{comments::Comments, errors::ColorConfig, FileName, FilePathMapping, SourceMap}; use swc_ecmascript::transforms::pass::noop; -use wasm_bindgen::prelude::*; +use wasm_bindgen::{prelude::*, JsCast}; +use wasm_bindgen_futures::future_to_promise; fn convert_err(err: Error) -> JsValue { format!("{:?}", err).into() } #[wasm_bindgen(js_name = "minifySync")] -pub fn minify_sync(s: &str, opts: JsValue) -> Result { +pub fn minify_sync(s: JsString, opts: JsValue) -> Result { console_error_panic_hook::set_once(); let c = compiler(); @@ -37,8 +39,15 @@ pub fn minify_sync(s: &str, opts: JsValue) -> Result { .map_err(convert_err) } +#[wasm_bindgen(js_name = "minify")] +pub fn minify(s: JsString, opts: JsValue) -> js_sys::Promise { + // TODO: This'll be properly scheduled once wasm have standard backed thread + // support. + future_to_promise(async { minify_sync(s, opts) }) +} + #[wasm_bindgen(js_name = "transformSync")] -pub fn transform_sync(s: &str, opts: JsValue) -> Result { +pub fn transform_sync(s: JsValue, opts: JsValue) -> Result { console_error_panic_hook::set_once(); let c = compiler(); @@ -52,28 +61,39 @@ pub fn transform_sync(s: &str, opts: JsValue) -> Result { |handler| { let opts: TransformOptions = opts.into_serde().context("failed to parse options")?; - let fm = c.cm.new_source_file( - if opts.swc.filename.is_empty() { - FileName::Anon - } else { - FileName::Real(opts.swc.filename.clone().into()) - }, - s.into(), - ); - let cm = c.cm.clone(); - let file = fm.clone(); - let out = c - .process_js_with_custom_pass( - fm, - None, - handler, - &opts.swc, - |_, comments| { - custom_before_pass(cm, file, &opts, comments.clone(), Default::default()) - }, - |_, _| noop(), - ) - .context("failed to process js file")?; + let s = s.dyn_into::(); + let out = match s { + Ok(s) => { + let fm = c.cm.new_source_file( + if opts.swc.filename.is_empty() { + FileName::Anon + } else { + FileName::Real(opts.swc.filename.clone().into()) + }, + s.into(), + ); + let cm = c.cm.clone(); + let file = fm.clone(); + c.process_js_with_custom_pass( + fm, + None, + handler, + &opts.swc, + |_, comments| { + custom_before_pass( + cm, + file, + &opts, + comments.clone(), + Default::default(), + ) + }, + |_, _| noop(), + ) + .context("failed to process js file")? + } + Err(v) => c.process_js(handler, v.into_serde().expect(""), &opts.swc)?, + }; JsValue::from_serde(&out).context("failed to serialize json") }, @@ -81,8 +101,15 @@ pub fn transform_sync(s: &str, opts: JsValue) -> Result { .map_err(convert_err) } +#[wasm_bindgen(js_name = "transform")] +pub fn transform(s: JsValue, opts: JsValue) -> js_sys::Promise { + // TODO: This'll be properly scheduled once wasm have standard backed thread + // support. + future_to_promise(async { transform_sync(s, opts) }) +} + #[wasm_bindgen(js_name = "parseSync")] -pub fn parse_sync(s: &str, opts: JsValue) -> Result { +pub fn parse_sync(s: JsString, opts: JsValue) -> Result { console_error_panic_hook::set_once(); let c = swc::Compiler::new(Arc::new(SourceMap::new(FilePathMapping::empty()))); @@ -124,6 +151,13 @@ pub fn parse_sync(s: &str, opts: JsValue) -> Result { .map_err(convert_err) } +#[wasm_bindgen(js_name = "parse")] +pub fn parse(s: JsString, opts: JsValue) -> js_sys::Promise { + // TODO: This'll be properly scheduled once wasm have standard backed thread + // support. + future_to_promise(async { parse_sync(s, opts) }) +} + /// Get global sourcemap fn compiler() -> Arc { static C: Lazy> = Lazy::new(|| { diff --git a/packages/next/build/swc/index.js b/packages/next/build/swc/index.js index 89c078e6b5ae..054f42d961d8 100644 --- a/packages/next/build/swc/index.js +++ b/packages/next/build/swc/index.js @@ -143,22 +143,26 @@ async function loadWasm(importPath = '') { wasmBindings = { isWasm: true, transform(src, options) { - return Promise.resolve( - bindings.transformSync(src.toString(), options) - ) + // TODO: we can remove fallback to sync interface once new stable version of next-swc gets published (current v12.2) + return bindings?.transform + ? bindings.transform(src.toString(), options) + : Promise.resolve(bindings.transformSync(src.toString(), options)) }, transformSync(src, options) { return bindings.transformSync(src.toString(), options) }, minify(src, options) { - return Promise.resolve(bindings.minifySync(src.toString(), options)) + return bindings?.minify + ? bindings.minify(src.toString(), options) + : Promise.resolve(bindings.minifySync(src.toString(), options)) }, minifySync(src, options) { return bindings.minifySync(src.toString(), options) }, parse(src, options) { - const astStr = bindings.parseSync(src.toString(), options) - return Promise.resolve(astStr) + return bindings?.parse + ? bindings.parse(src.toString(), options) + : Promise.resolve(bindings.parseSync(src.toString(), options)) }, parseSync(src, options) { const astStr = bindings.parseSync(src.toString(), options)