diff --git a/bench/runners/minify-html-onepass/Cargo.toml b/bench/runners/minify-html-onepass/Cargo.toml
index 9c8ba4c..485dafc 100644
--- a/bench/runners/minify-html-onepass/Cargo.toml
+++ b/bench/runners/minify-html-onepass/Cargo.toml
@@ -6,6 +6,6 @@ authors = ["Wilson Lin "]
edition = "2018"
[dependencies]
-minify-html-onepass = { path = "../../../rust/onepass", features = ["js-esbuild"] }
+minify-html-onepass = { path = "../../../rust/onepass" }
serde = { version = "1.0.104", features = ["derive"] }
serde_json = "1.0.44"
diff --git a/rust/onepass/Cargo.toml b/rust/onepass/Cargo.toml
index 34a902e..8ef8567 100644
--- a/rust/onepass/Cargo.toml
+++ b/rust/onepass/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "minify-html-onepass"
-description = "Alternate version of minify-html"
+description = "Even faster version of minify-html"
license = "MIT"
homepage = "https://github.com/wilsonzlin/minify-html"
readme = "README.md"
@@ -15,13 +15,9 @@ include = ["/src/**/*", "/Cargo.toml", "/LICENSE", "/README.md"]
[badges]
maintenance = { status = "actively-developed" }
-[features]
-default = []
-js-esbuild = ["crossbeam", "esbuild-rs"]
-
[dependencies]
aho-corasick = "0.7"
-crossbeam = { version = "0.7", optional = true }
-esbuild-rs = { version = "0.13.8", optional = true }
+css-minify = "0.2.2"
lazy_static = "1.4"
memchr = "2"
+minify-js = "0.1.0"
diff --git a/rust/onepass/src/cfg/mod.rs b/rust/onepass/src/cfg/mod.rs
index 54a7f96..06a7017 100644
--- a/rust/onepass/src/cfg/mod.rs
+++ b/rust/onepass/src/cfg/mod.rs
@@ -2,17 +2,14 @@
/// minification approach.
pub struct Cfg {
/// If enabled, JavaScript in `
- // /*
- // Considerations:
- // - Need to parse strings (e.g. "", '', ``) so syntax within strings aren't mistakenly interpreted as code.
- // - Need to be able to parse regex literals to determine string delimiters aren't actually characters in the regex.
- // - Determining whether a slash is division or regex requires a full-blown JS parser to handle all cases (this is a well-known JS parsing problem).
- // - `/::new();
- // SCRIPT_END must be case insensitive.
- SCRIPT_END.replace_all_with_bytes(
- result.code.as_str().trim().as_bytes(),
- &mut escaped,
- |_, orig, dst| {
- dst.extend(b"<\\/");
- // Keep original case.
- dst.extend(&orig[2..]);
- true
- },
- );
- guard.push(EsbuildSection { src, escaped });
- // Drop Arc reference and Mutex guard before marking task as complete as it's possible proc::finish
- // waiting on WaitGroup will resume before Arc/Mutex is dropped after exiting this function.
- drop(guard);
- drop(results);
- drop(wg);
- },
- );
+ // TODO Write to `out` directly, but only if we can guarantee that the length will never exceed the input.
+ let mut output = Vec::new();
+ let result = minify_js::minify(proc[src].to_vec(), &mut output);
+ // TODO Collect error as warning.
+ if !result.is_err() && output.len() < src.len() {
+ proc.write_slice(output.as_slice());
+ } else {
+ proc.write_range(src);
};
+ } else {
+ proc.write_range(src);
};
Ok(())
diff --git a/rust/onepass/src/unit/style.rs b/rust/onepass/src/unit/style.rs
index ca2f671..c84d2a3 100644
--- a/rust/onepass/src/unit/style.rs
+++ b/rust/onepass/src/unit/style.rs
@@ -1,32 +1,16 @@
use aho_corasick::{AhoCorasick, AhoCorasickBuilder};
+use css_minify::optimizations::{Level, Minifier};
use lazy_static::lazy_static;
-#[cfg(feature = "js-esbuild")]
-use {
- crate::proc::checkpoint::WriteCheckpoint,
- crate::proc::EsbuildSection,
- esbuild_rs::{Loader, TransformOptions, TransformOptionsBuilder},
- std::sync::Arc,
-};
+use std::str::from_utf8_unchecked;
use crate::err::ProcessingResult;
+use crate::proc::checkpoint::WriteCheckpoint;
use crate::proc::MatchAction::*;
use crate::proc::MatchMode::*;
use crate::proc::Processor;
use crate::Cfg;
-#[cfg(feature = "js-esbuild")]
-lazy_static! {
- static ref TRANSFORM_OPTIONS: Arc = {
- let mut builder = TransformOptionsBuilder::new();
- builder.loader = Loader::CSS;
- builder.minify_identifiers = true;
- builder.minify_syntax = true;
- builder.minify_whitespace = true;
- builder.build()
- };
-}
-
lazy_static! {
static ref STYLE_END: AhoCorasick = AhoCorasickBuilder::new()
.ascii_case_insensitive(true)
@@ -35,45 +19,23 @@ lazy_static! {
#[inline(always)]
pub fn process_style(proc: &mut Processor, cfg: &Cfg) -> ProcessingResult<()> {
- #[cfg(feature = "js-esbuild")]
let start = WriteCheckpoint::new(proc);
proc.require_not_at_end()?;
- proc.m(WhileNotSeq(&STYLE_END), Keep);
+ let src = proc.m(WhileNotSeq(&STYLE_END), Discard);
// `process_tag` will require closing tag.
- // TODO This is copied from script.rs.
- #[cfg(feature = "js-esbuild")]
if cfg.minify_css {
- let (wg, results) = proc.new_esbuild_section();
- let src = start.written_range(proc);
- unsafe {
- esbuild_rs::transform_direct_unmanaged(
- &proc[src],
- &TRANSFORM_OPTIONS.clone(),
- move |result| {
- let mut guard = results.lock().unwrap();
- // TODO Are there other places that can have unintentional closing tags?
- let mut escaped = Vec::::new();
- // STYLE_END must be case insensitive.
- STYLE_END.replace_all_with_bytes(
- result.code.as_str().trim().as_bytes(),
- &mut escaped,
- |_, orig, dst| {
- dst.extend(b"<\\/");
- // Keep original case.
- dst.extend(&orig[2..]);
- true
- },
- );
- guard.push(EsbuildSection { src, escaped });
- // Drop Arc reference and Mutex guard before marking task as complete as it's possible proc::finish
- // waiting on WaitGroup will resume before Arc/Mutex is dropped after exiting this function.
- drop(guard);
- drop(results);
- drop(wg);
- },
- );
+ let result = Minifier::default()
+ .minify(unsafe { from_utf8_unchecked(&proc[src]) }, Level::Three)
+ .ok();
+ // TODO Collect error as warning.
+ if result.as_ref().filter(|r| r.len() < src.len()).is_some() {
+ proc.write_slice(result.unwrap().as_bytes());
+ } else {
+ proc.write_range(src);
};
+ } else {
+ proc.write_range(src);
};
Ok(())
diff --git a/version b/version
index 9f28f9d..a9e4637 100755
--- a/version
+++ b/version
@@ -93,9 +93,7 @@ if (
cmd("git", "pull");
cmd("bash", "./prebuild.sh");
cmd("cargo", "test", { workingDir: RUST_MAIN_DIR });
-cmd("cargo", "test", "--features", "js-esbuild", {
- workingDir: RUST_ONEPASS_DIR,
-});
+cmd("cargo", "test", { workingDir: RUST_ONEPASS_DIR });
for (const f of [
`${RUST_MAIN_DIR}/Cargo.toml`,