You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			185 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Rust
		
	
			
		
		
	
	
			185 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Rust
		
	
// From https://github.com/swc-project/swc/blob/main/crates/binding_core_wasm/src/lib.rs
 | 
						|
 | 
						|
use anyhow::{Context, Error};
 | 
						|
use once_cell::sync::Lazy;
 | 
						|
use std::sync::Arc;
 | 
						|
use swc::{
 | 
						|
  config::{
 | 
						|
    ErrorFormat, JsMinifyOptions, Options, ParseOptions, SourceMapsConfig,
 | 
						|
  },
 | 
						|
  try_with_handler, Compiler,
 | 
						|
};
 | 
						|
use swc_common::{comments::Comments, FileName, FilePathMapping, SourceMap};
 | 
						|
use swc_ecmascript::ast::{EsVersion, Program};
 | 
						|
use wasm_bindgen::prelude::*;
 | 
						|
 | 
						|
fn convert_err(err: Error, error_format: ErrorFormat) -> JsValue {
 | 
						|
  error_format.format(&err).into()
 | 
						|
}
 | 
						|
 | 
						|
#[wasm_bindgen(js_name = "minifySync")]
 | 
						|
pub fn minify_sync(s: &str, opts: JsValue) -> Result<JsValue, JsValue> {
 | 
						|
  console_error_panic_hook::set_once();
 | 
						|
 | 
						|
  let c = compiler();
 | 
						|
 | 
						|
  try_with_handler(
 | 
						|
    c.cm.clone(),
 | 
						|
    swc::HandlerOpts {
 | 
						|
      ..Default::default()
 | 
						|
    },
 | 
						|
    |handler| {
 | 
						|
      c.run(|| {
 | 
						|
        let opts: JsMinifyOptions =
 | 
						|
          opts.into_serde().context("failed to parse options")?;
 | 
						|
 | 
						|
        let fm = c.cm.new_source_file(FileName::Anon, s.into());
 | 
						|
        let program = c
 | 
						|
          .minify(fm, handler, &opts)
 | 
						|
          .context("failed to minify file")?;
 | 
						|
 | 
						|
        JsValue::from_serde(&program).context("failed to serialize json")
 | 
						|
      })
 | 
						|
    },
 | 
						|
  )
 | 
						|
  .map_err(|e| convert_err(e, ErrorFormat::Normal))
 | 
						|
}
 | 
						|
 | 
						|
#[wasm_bindgen(js_name = "parseSync")]
 | 
						|
pub fn parse_sync(s: &str, opts: JsValue) -> Result<JsValue, JsValue> {
 | 
						|
  console_error_panic_hook::set_once();
 | 
						|
 | 
						|
  let c = compiler();
 | 
						|
 | 
						|
  try_with_handler(
 | 
						|
    c.cm.clone(),
 | 
						|
    swc::HandlerOpts {
 | 
						|
      ..Default::default()
 | 
						|
    },
 | 
						|
    |handler| {
 | 
						|
      c.run(|| {
 | 
						|
        let opts: ParseOptions =
 | 
						|
          opts.into_serde().context("failed to parse options")?;
 | 
						|
 | 
						|
        let fm = c.cm.new_source_file(FileName::Anon, s.into());
 | 
						|
 | 
						|
        let cmts = c.comments().clone();
 | 
						|
        let comments = if opts.comments {
 | 
						|
          Some(&cmts as &dyn Comments)
 | 
						|
        } else {
 | 
						|
          None
 | 
						|
        };
 | 
						|
 | 
						|
        let program = c
 | 
						|
          .parse_js(
 | 
						|
            fm,
 | 
						|
            handler,
 | 
						|
            opts.target,
 | 
						|
            opts.syntax,
 | 
						|
            opts.is_module,
 | 
						|
            comments,
 | 
						|
          )
 | 
						|
          .context("failed to parse code")?;
 | 
						|
 | 
						|
        JsValue::from_serde(&program).context("failed to serialize json")
 | 
						|
      })
 | 
						|
    },
 | 
						|
  )
 | 
						|
  .map_err(|e| convert_err(e, ErrorFormat::Normal))
 | 
						|
}
 | 
						|
 | 
						|
#[wasm_bindgen(js_name = "printSync")]
 | 
						|
pub fn print_sync(s: JsValue, opts: JsValue) -> Result<JsValue, JsValue> {
 | 
						|
  console_error_panic_hook::set_once();
 | 
						|
 | 
						|
  let c = compiler();
 | 
						|
 | 
						|
  try_with_handler(
 | 
						|
    c.cm.clone(),
 | 
						|
    swc::HandlerOpts {
 | 
						|
      ..Default::default()
 | 
						|
    },
 | 
						|
    |_handler| {
 | 
						|
      c.run(|| {
 | 
						|
        let opts: Options =
 | 
						|
          opts.into_serde().context("failed to parse options")?;
 | 
						|
 | 
						|
        let program: Program =
 | 
						|
          s.into_serde().context("failed to deserialize program")?;
 | 
						|
 | 
						|
        let s = c
 | 
						|
          .print(
 | 
						|
            &program,
 | 
						|
            None,
 | 
						|
            None,
 | 
						|
            true,
 | 
						|
            opts.codegen_target().unwrap_or(EsVersion::Es2020),
 | 
						|
            opts
 | 
						|
              .source_maps
 | 
						|
              .clone()
 | 
						|
              .unwrap_or(SourceMapsConfig::Bool(false)),
 | 
						|
            &Default::default(),
 | 
						|
            None,
 | 
						|
            opts.config.minify.into(),
 | 
						|
            None,
 | 
						|
            opts.config.emit_source_map_columns.into_bool(),
 | 
						|
            false,
 | 
						|
          )
 | 
						|
          .context("failed to print code")?;
 | 
						|
 | 
						|
        JsValue::from_serde(&s).context("failed to serialize json")
 | 
						|
      })
 | 
						|
    },
 | 
						|
  )
 | 
						|
  .map_err(|e| convert_err(e, ErrorFormat::Normal))
 | 
						|
}
 | 
						|
 | 
						|
#[wasm_bindgen(js_name = "transformSync")]
 | 
						|
pub fn transform_sync(s: &str, opts: JsValue) -> Result<JsValue, JsValue> {
 | 
						|
  console_error_panic_hook::set_once();
 | 
						|
 | 
						|
  let c = compiler();
 | 
						|
  let opts: Options = opts
 | 
						|
    .into_serde()
 | 
						|
    .context("failed to parse options")
 | 
						|
    .map_err(|e| convert_err(e, ErrorFormat::Normal))?;
 | 
						|
 | 
						|
  let error_format = opts.experimental.error_format.unwrap_or_default();
 | 
						|
 | 
						|
  try_with_handler(
 | 
						|
    c.cm.clone(),
 | 
						|
    swc::HandlerOpts {
 | 
						|
      ..Default::default()
 | 
						|
    },
 | 
						|
    |handler| {
 | 
						|
      c.run(|| {
 | 
						|
        let fm = c.cm.new_source_file(
 | 
						|
          if opts.filename.is_empty() {
 | 
						|
            FileName::Anon
 | 
						|
          } else {
 | 
						|
            FileName::Real(opts.filename.clone().into())
 | 
						|
          },
 | 
						|
          s.into(),
 | 
						|
        );
 | 
						|
        let out = c
 | 
						|
          .process_js_file(fm, handler, &opts)
 | 
						|
          .context("failed to process input file")?;
 | 
						|
 | 
						|
        JsValue::from_serde(&out).context("failed to serialize json")
 | 
						|
      })
 | 
						|
    },
 | 
						|
  )
 | 
						|
  .map_err(|e| convert_err(e, error_format))
 | 
						|
}
 | 
						|
 | 
						|
/// Get global sourcemap
 | 
						|
fn compiler() -> Arc<Compiler> {
 | 
						|
  static C: Lazy<Arc<Compiler>> = Lazy::new(|| {
 | 
						|
    let cm = Arc::new(SourceMap::new(FilePathMapping::empty()));
 | 
						|
 | 
						|
    Arc::new(Compiler::new(cm))
 | 
						|
  });
 | 
						|
 | 
						|
  C.clone()
 | 
						|
}
 |