From 406fa3fc780eea0e26aa3f636643e6db7ee32b04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Santos?= Date: Mon, 20 Sep 2021 07:25:51 +0100 Subject: [PATCH] feat(es/minifier): Add CLI for debugging (#2273) swc_ecma_minifier: - Add a binary to help development. --- ecmascript/minifier/Cargo.toml | 4 ++ ecmascript/minifier/src/cli/bin.rs | 79 ++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 ecmascript/minifier/src/cli/bin.rs diff --git a/ecmascript/minifier/Cargo.toml b/ecmascript/minifier/Cargo.toml index 7a6a80c4e92..c292ed71361 100644 --- a/ecmascript/minifier/Cargo.toml +++ b/ecmascript/minifier/Cargo.toml @@ -9,6 +9,10 @@ name = "swc_ecma_minifier" repository = "https://github.com/swc-project/swc.git" version = "0.27.3" +[[bin]] +name = "cli" +path = "./src/cli/bin.rs" + [features] debug = [] diff --git a/ecmascript/minifier/src/cli/bin.rs b/ecmascript/minifier/src/cli/bin.rs new file mode 100644 index 00000000000..c983a0dbc99 --- /dev/null +++ b/ecmascript/minifier/src/cli/bin.rs @@ -0,0 +1,79 @@ +use std::{env::args, io, path::Path}; +use swc_common::{input::SourceFileInput, sync::Lrc, FilePathMapping, Mark, SourceMap}; +use swc_ecma_ast::Module; +use swc_ecma_codegen::text_writer::JsWriter; +use swc_ecma_minifier::{ + optimize, + option::{ExtraOptions, MinifyOptions}, +}; +use swc_ecma_parser::{error::Error as ParseError, lexer::Lexer, Parser}; +use swc_ecma_transforms::{fixer, hygiene::hygiene_with_config, resolver_with_mark}; +use swc_ecma_visit::FoldWith; + +fn parse_js(cm: &Lrc, filename: String) -> Result { + let fm = cm + .load_file(Path::new(&filename)) + .expect("Failed to load file"); + + let lexer = Lexer::new( + Default::default(), + Default::default(), + SourceFileInput::from(&*fm), + None, + ); + let mut parser = Parser::new_from(lexer); + + parser.parse_module() +} + +fn print_js(cm: Lrc, module: &Module) { + let stdout = io::stdout(); + + let mut emitter = swc_ecma_codegen::Emitter { + cfg: swc_ecma_codegen::Config { minify: true }, + cm: cm.clone(), + comments: None, + wr: Box::new(JsWriter::new(cm.clone(), "\n", &stdout, None)), + }; + emitter.emit_module(module).unwrap(); + + print!("\n"); +} + +fn run_cli(filename: String) -> Result<(), ParseError> { + swc_common::GLOBALS.set(&swc_common::Globals::new(), || { + let cm = Lrc::new(SourceMap::new(FilePathMapping::empty())); + + let top_level_mark = Mark::fresh(Mark::root()); + let program = parse_js(&cm, filename)?.fold_with(&mut resolver_with_mark(top_level_mark)); + + let output = optimize( + program, + cm.clone(), + None, + None, + &MinifyOptions { + compress: Some(Default::default()), + mangle: Some(Default::default()), + ..Default::default() + }, + &ExtraOptions { top_level_mark }, + ); + + let output = output + .fold_with(&mut hygiene_with_config(Default::default())) + .fold_with(&mut fixer(None)); + + print_js(cm.clone(), &output); + + Ok(()) + }) +} + +fn main() { + let filename = args().nth(1).expect("Usage: cargo run [filename.js]"); + + if let Err(error) = run_cli(filename) { + println!("{:?}", error); + } +}