Skip to content

Commit

Permalink
w
Browse files Browse the repository at this point in the history
  • Loading branch information
Boshen committed Jan 1, 2025
1 parent 72fe245 commit f8e94af
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 24 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/oxc_minifier/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ oxc_syntax = { workspace = true }
oxc_traverse = { workspace = true }

cow-utils = { workspace = true }
rustc-hash = { workspace = true }

[dev-dependencies]
oxc_parser = { workspace = true }
Expand Down
38 changes: 33 additions & 5 deletions crates/oxc_minifier/src/ast_passes/remove_unused_code.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use oxc_allocator::Vec;
use oxc_ast::ast::*;
use oxc_ecmascript::side_effects::MayHaveSideEffects;
use oxc_span::SPAN;
use oxc_syntax::symbol::SymbolId;
use oxc_traverse::{traverse_mut_with_ctx, ReusableTraverseCtx, Traverse, TraverseCtx};
use rustc_hash::FxHashSet;

use crate::CompressorPass;

Expand All @@ -11,6 +10,8 @@ use crate::CompressorPass;
/// <https://github.com/google/closure-compiler/blob/v20240609/src/com/google/javascript/jscomp/RemoveUnusedCode.java>
pub struct RemoveUnusedCode {
pub(crate) changed: bool,

symbol_ids_to_remove: FxHashSet<SymbolId>,
}

impl<'a> CompressorPass<'a> for RemoveUnusedCode {
Expand All @@ -20,11 +21,38 @@ impl<'a> CompressorPass<'a> for RemoveUnusedCode {
}
}

impl<'a> Traverse<'a> for RemoveUnusedCode {}
impl<'a> Traverse<'a> for RemoveUnusedCode {
fn enter_program(&mut self, _node: &mut Program<'a>, ctx: &mut TraverseCtx<'a>) {
let symbols = ctx.symbols();
for symbol_id in symbols.symbol_ids() {
if symbols.get_resolved_references(symbol_id).count() == 0 {
self.symbol_ids_to_remove.insert(symbol_id);
}
}
}

fn exit_statement(&mut self, stmt: &mut Statement<'a>, ctx: &mut TraverseCtx<'a>) {
if let Statement::VariableDeclaration(decl) = stmt {
decl.declarations.retain(|d| {
if let BindingPatternKind::BindingIdentifier(ident) = &d.id.kind {
if d.init.is_none() {
if self.symbol_ids_to_remove.contains(&ident.symbol_id()) {
return false;
}
}
}
true
});
if decl.declarations.is_empty() {
*stmt = ctx.ast.statement_empty(decl.span);
}
}
}
}

impl<'a> RemoveUnusedCode {
pub fn new() -> Self {
Self { changed: false }
Self { changed: false, symbol_ids_to_remove: FxHashSet::default() }
}
}

Expand Down
2 changes: 1 addition & 1 deletion tasks/minsize/minsize.snap
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Original | minified | minified | gzip | gzip | Fixture

3.20 MB | 1.01 MB | 1.01 MB | 332.14 kB | 331.56 kB | echarts.js

6.69 MB | 2.32 MB | 2.31 MB | 493.00 kB | 488.28 kB | antd.js
6.69 MB | 2.32 MB | 2.31 MB | 493.01 kB | 488.28 kB | antd.js

10.95 MB | 3.51 MB | 3.49 MB | 910.09 kB | 915.50 kB | typescript.js

28 changes: 10 additions & 18 deletions tasks/minsize/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use flate2::{write::GzEncoder, Compression};
use humansize::{format_size, DECIMAL};
use oxc_allocator::Allocator;
use oxc_codegen::{CodeGenerator, CodegenOptions};
use oxc_minifier::{CompressOptions, MangleOptions, Minifier, MinifierOptions};
use oxc_minifier::{Minifier, MinifierOptions};
use oxc_parser::Parser;
use oxc_semantic::SemanticBuilder;
use oxc_span::SourceType;
Expand Down Expand Up @@ -126,17 +126,13 @@ pub fn run() -> Result<(), io::Error> {

fn minify_twice(file: &TestFile) -> String {
let source_type = SourceType::from_path(&file.file_name).unwrap();
let options = MinifierOptions {
mangle: Some(MangleOptions::default()),
compress: CompressOptions::default(),
};
let source_text1 = minify(&file.source_text, source_type, options);
let source_text2 = minify(&source_text1, source_type, options);
assert_eq_minified_code(&source_text1, &source_text2, &file.file_name);
source_text2
let code1 = minify(&file.source_text, source_type);
let code2 = minify(&code1, source_type);
assert_eq_minified_code(&code1, &code2, &file.file_name);
code2
}

fn minify(source_text: &str, source_type: SourceType, options: MinifierOptions) -> String {
fn minify(source_text: &str, source_type: SourceType) -> String {
let allocator = Allocator::default();
let ret = Parser::new(&allocator, source_text, source_type).parse();
let mut program = ret.program;
Expand All @@ -147,7 +143,7 @@ fn minify(source_text: &str, source_type: SourceType, options: MinifierOptions)
ReplaceGlobalDefinesConfig::new(&[("process.env.NODE_ENV", "'development'")]).unwrap(),
)
.build(symbols, scopes, &mut program);
let ret = Minifier::new(options).build(&allocator, &mut program);
let ret = Minifier::new(MinifierOptions::default()).build(&allocator, &mut program);
CodeGenerator::new()
.with_options(CodegenOptions { minify: true, ..CodegenOptions::default() })
.with_mangler(ret.mangler)
Expand All @@ -164,13 +160,9 @@ fn gzip_size(s: &str) -> usize {

fn assert_eq_minified_code(s1: &str, s2: &str, filename: &str) {
if s1 != s2 {
let normalized_left = normalize_minified_code(s1);
let normalized_right = normalize_minified_code(s2);
similar_asserts::assert_eq!(
normalized_left,
normalized_right,
"Minification failed for {filename}"
);
let left = normalize_minified_code(s1);
let right = normalize_minified_code(s2);
similar_asserts::assert_eq!(left, right, "Minification failed for {filename}");
}
}

Expand Down

0 comments on commit f8e94af

Please sign in to comment.