"]
6 | edition = "2018"
7 |
8 | [dependencies]
9 | minify-html-onepass = { path = "../../../minify-html-onepass" }
10 | serde = { version = "1.0.104", features = ["derive"] }
11 | serde_json = "1.0.44"
12 |
--------------------------------------------------------------------------------
/bench/runners/minify-html-onepass/build:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -Eeuxo pipefail
4 |
5 | cargo build --release
6 |
--------------------------------------------------------------------------------
/bench/runners/minify-html-onepass/run:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -Eeuxo pipefail
4 |
5 | ../../../target/release/minify-html-onepass-bench
6 |
--------------------------------------------------------------------------------
/bench/runners/minify-html-onepass/src/main.rs:
--------------------------------------------------------------------------------
1 | use minify_html_onepass::in_place;
2 | use minify_html_onepass::Cfg;
3 | use std::env;
4 | use std::fs;
5 | use std::io::stdout;
6 | use std::time::Instant;
7 |
8 | fn main() {
9 | let iterations = env::var("MHB_ITERATIONS")
10 | .unwrap()
11 | .parse::()
12 | .unwrap();
13 | let input_dir = env::var("MHB_INPUT_DIR").unwrap();
14 | let html_only = env::var("MHB_HTML_ONLY")
15 | .ok()
16 | .filter(|v| v == "1")
17 | .is_some();
18 | let output_dir = env::var("MHB_OUTPUT_DIR").ok();
19 |
20 | let mut results: Vec<(String, usize, usize, f64)> = Vec::new();
21 | let cfg = Cfg {
22 | minify_css: !html_only,
23 | minify_js: !html_only,
24 | };
25 |
26 | for t in fs::read_dir(input_dir).unwrap().map(|d| d.unwrap()) {
27 | let source = fs::read(t.path()).unwrap();
28 | let input_name = t.file_name().into_string().unwrap();
29 |
30 | let mut output = source.to_vec();
31 | let len = in_place(&mut output, &cfg).expect("failed to minify");
32 | output.truncate(len);
33 | if let Some(output_dir) = &output_dir {
34 | fs::write(format!("{}/{}", output_dir, input_name), output).unwrap();
35 | };
36 |
37 | let start = Instant::now();
38 | for _ in 0..iterations {
39 | let mut data = source.to_vec();
40 | let _ = in_place(&mut data, &cfg).expect("failed to minify");
41 | }
42 | let elapsed = start.elapsed().as_secs_f64();
43 |
44 | results.push((input_name, len, iterations, elapsed));
45 | }
46 |
47 | serde_json::to_writer(stdout(), &results).unwrap();
48 | }
49 |
--------------------------------------------------------------------------------
/bench/runners/minify-html/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "minify-html-bench"
3 | publish = false
4 | version = "0.0.1"
5 | authors = ["Wilson Lin "]
6 | edition = "2018"
7 |
8 | [dependencies]
9 | minify-html = { path = "../../../minify-html" }
10 | serde = { version = "1.0.104", features = ["derive"] }
11 | serde_json = "1.0.44"
12 |
--------------------------------------------------------------------------------
/bench/runners/minify-html/build:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -Eeuxo pipefail
4 |
5 | cargo build --release
6 |
--------------------------------------------------------------------------------
/bench/runners/minify-html/run:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -Eeuxo pipefail
4 |
5 | ../../../target/release/minify-html-bench
6 |
--------------------------------------------------------------------------------
/bench/runners/minify-html/src/main.rs:
--------------------------------------------------------------------------------
1 | use minify_html::minify;
2 | use minify_html::Cfg;
3 | use std::env;
4 | use std::fs;
5 | use std::io::stdout;
6 | use std::time::Instant;
7 |
8 | fn main() {
9 | let iterations = env::var("MHB_ITERATIONS")
10 | .unwrap()
11 | .parse::()
12 | .unwrap();
13 | let input_dir = env::var("MHB_INPUT_DIR").unwrap();
14 | let html_only = env::var("MHB_HTML_ONLY")
15 | .ok()
16 | .filter(|v| v == "1")
17 | .is_some();
18 | let output_dir = env::var("MHB_OUTPUT_DIR").ok();
19 |
20 | let mut results: Vec<(String, usize, usize, f64)> = Vec::new();
21 | let mut cfg = Cfg::new();
22 | cfg.enable_possibly_noncompliant();
23 | if !html_only {
24 | cfg.minify_css = true;
25 | cfg.minify_js = true;
26 | };
27 |
28 | for t in fs::read_dir(input_dir).unwrap().map(|d| d.unwrap()) {
29 | let source = fs::read(t.path()).unwrap();
30 | let input_name = t.file_name().into_string().unwrap();
31 |
32 | let output = minify(&source, &cfg);
33 | let len = output.len();
34 | if let Some(output_dir) = &output_dir {
35 | fs::write(format!("{}/{}", output_dir, input_name), output).unwrap();
36 | };
37 |
38 | let start = Instant::now();
39 | for _ in 0..iterations {
40 | let _ = minify(&source, &cfg);
41 | }
42 | let elapsed = start.elapsed().as_secs_f64();
43 |
44 | results.push((input_name, len, iterations, elapsed));
45 | }
46 |
47 | serde_json::to_writer(stdout(), &results).unwrap();
48 | }
49 |
--------------------------------------------------------------------------------
/bench/runners/minimize/build:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -Eeuxo pipefail
4 |
5 | npm i
6 |
--------------------------------------------------------------------------------
/bench/runners/minimize/index.js:
--------------------------------------------------------------------------------
1 | const minimize = require("minimize");
2 | const { htmlOnly, esbuildCss, esbuildJs, run } = require("../common");
3 |
4 | const jsMime = new Set([
5 | undefined,
6 | "application/ecmascript",
7 | "application/javascript",
8 | "application/x-ecmascript",
9 | "application/x-javascript",
10 | "text/ecmascript",
11 | "text/javascript",
12 | "text/javascript1.0",
13 | "text/javascript1.1",
14 | "text/javascript1.2",
15 | "text/javascript1.3",
16 | "text/javascript1.4",
17 | "text/javascript1.5",
18 | "text/jscript",
19 | "text/livescript",
20 | "text/x-ecmascript",
21 | "text/x-javascript",
22 | ]);
23 |
24 | const jsCssPlugin = {
25 | id: "esbuild",
26 | element: (node, next) => {
27 | if (node.type === "text" && node.parent) {
28 | if (
29 | node.parent.type === "script" &&
30 | jsMime.has(node.parent.attribs.type)
31 | ) {
32 | node.data = esbuildJs(node.data);
33 | } else if (node.parent.type === "style") {
34 | node.data = esbuildCss(node.data);
35 | }
36 | }
37 | next();
38 | },
39 | };
40 |
41 | const plugins = htmlOnly ? [] : [jsCssPlugin];
42 |
43 | const minifier = new minimize({ plugins });
44 |
45 | run((src) => minifier.parse(src.toString()));
46 |
--------------------------------------------------------------------------------
/bench/runners/minimize/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "dependencies": {
4 | "minimize": "2.2.0"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/bench/runners/minimize/run:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -Eeuxo pipefail
4 |
5 | node index.js
6 |
--------------------------------------------------------------------------------
/bench/runners/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "dependencies": {
4 | "esbuild": "0.12.19"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/debug/diff/README.md:
--------------------------------------------------------------------------------
1 | [compare](./compare) is a useful script for viewing a character-by-character diff between the minified outputs of minify-html and html-minifier for a specific input. Pass the input's file name as the first argument.
2 |
--------------------------------------------------------------------------------
/debug/diff/c14n/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | publish = false
3 | name = "c14n"
4 | version = "0.0.1"
5 | edition = "2018"
6 |
7 | [dependencies]
8 | minify-html = { path = "../../../minify-html" }
9 |
--------------------------------------------------------------------------------
/debug/diff/c14n/README.md:
--------------------------------------------------------------------------------
1 | # c14n
2 |
3 | Parse HTML from stdin and write a canonical HTML document to stdout. Useful to preprocess documents for diffing:
4 |
5 | - Sort attributes by name.
6 | - Decode all entities, then re-encode only special characters consistently.
7 | - Make tag and attribute names lowercase.
8 |
--------------------------------------------------------------------------------
/debug/diff/c14n/src/main.rs:
--------------------------------------------------------------------------------
1 | use minify_html::canonicalise;
2 | use std::io::stdin;
3 | use std::io::stdout;
4 | use std::io::Read;
5 |
6 | fn main() {
7 | let mut src = Vec::new();
8 | stdin().read_to_end(&mut src).unwrap();
9 | canonicalise(&mut stdout(), &src).unwrap();
10 | }
11 |
--------------------------------------------------------------------------------
/debug/diff/canonicalise:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -Eeo pipefail
4 |
5 | pushd "$(dirname "$0")" >/dev/null
6 |
7 | cargo build --manifest-path c14n/Cargo.toml --release
8 | cargo build --manifest-path charlines/Cargo.toml --release
9 |
10 | for f in outputs/*/*; do
11 | out=$(../../target/release/c14n < "$f")
12 | if [[ "$CHARLINES" == "1" ]]; then
13 | out=$(../../target/release/charlines <<< "$out")
14 | fi
15 | cat <<< "$out" > "$f"
16 | done
17 |
18 | popd >/dev/null
19 |
--------------------------------------------------------------------------------
/debug/diff/charlines/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | publish = false
3 | name = "charlines"
4 | version = "0.0.1"
5 | edition = "2018"
6 |
--------------------------------------------------------------------------------
/debug/diff/charlines/README.md:
--------------------------------------------------------------------------------
1 | # charlines
2 |
3 | Output each character from stdin onto its own stdout line. Useful for subsequence diffing when text does not naturally have a lot of line breaks (e.g. minified HTML).
4 |
--------------------------------------------------------------------------------
/debug/diff/charlines/src/main.rs:
--------------------------------------------------------------------------------
1 | use std::io::stdin;
2 | use std::io::stdout;
3 | use std::io::Read;
4 | use std::io::Write;
5 |
6 | fn main() {
7 | let mut src = Vec::new();
8 | stdin().read_to_end(&mut src).unwrap();
9 | let mut out = stdout();
10 | for c in src {
11 | out.write_all(&[c, b'\n']).unwrap();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/debug/diff/compare:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -Eeuxo pipefail
4 |
5 | pushd "$(dirname "$0")" >/dev/null
6 |
7 | git --no-pager diff --no-index --word-diff=color --word-diff-regex=. "outputs/html-minifier/$1" "outputs/minify-html/$1" | less
8 |
9 | popd >/dev/null
10 |
--------------------------------------------------------------------------------
/debug/diff/run:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -Eeuo pipefail
4 |
5 | shopt -s nullglob
6 |
7 | pushd "$(dirname "$0")" >/dev/null
8 |
9 | input_dir="$PWD/../../bench/inputs"
10 | output_dir="$PWD/outputs"
11 |
12 | rm -rf "$output_dir"
13 | mkdir -p "$output_dir"
14 |
15 | pushd "../../bench/runners" >/dev/null
16 | for r in *; do
17 | if [[ ! -d "$r" ]] || [[ "$r" == "node_modules" ]]; then
18 | continue
19 | fi
20 | mkdir -p "$output_dir/$r"
21 | echo "Running $r..."
22 | pushd "$r" >/dev/null
23 | MHB_ITERATIONS=1 MHB_INPUT_DIR="$input_dir" MHB_OUTPUT_DIR="$output_dir/$r" RUST_BACKTRACE=1 ./run >/dev/null
24 | popd >/dev/null
25 | done
26 | popd >/dev/null
27 |
28 | echo "All done!"
29 |
30 | popd >/dev/null
31 |
--------------------------------------------------------------------------------
/debug/prof/README.md:
--------------------------------------------------------------------------------
1 | Profiling minify-html can be done on Linux by using [profile.sh](./profile.sh), which uses `perf`. The generated report can be used using `perf report`.
2 |
--------------------------------------------------------------------------------
/debug/prof/profile.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 | shopt -s nullglob
5 |
6 | for i in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do
7 | echo performance | sudo dd status=none of="$i"
8 | done
9 |
10 | rm -f perf.data
11 | sudo perf record -g nice -n -20 taskset -c 1 target/release/minify-html-bench --tests tests --iterations 512
12 | sudo chown "$USER:$USER" perf.data
13 |
--------------------------------------------------------------------------------
/format:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -Eeuxo pipefail
4 |
5 | pushd "$(dirname "$0")" >/dev/null
6 |
7 | npx prettier@2.3.2 -w \
8 | 'bench/*.{js,json}' \
9 | 'bench/runners/*.{js,json}' \
10 | 'bench/runners/*/*.{js,json}' \
11 | 'minify-html-nodejs/*.{js,json,ts}' \
12 | 'version'
13 |
14 | cargo +nightly fmt
15 |
--------------------------------------------------------------------------------
/icon/cli.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wilsonzlin/minify-html/2301223773dadce30a33b4c407d8b2524adeb5e2/icon/cli.png
--------------------------------------------------------------------------------
/icon/deno.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wilsonzlin/minify-html/2301223773dadce30a33b4c407d8b2524adeb5e2/icon/deno.png
--------------------------------------------------------------------------------
/icon/java.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wilsonzlin/minify-html/2301223773dadce30a33b4c407d8b2524adeb5e2/icon/java.png
--------------------------------------------------------------------------------
/icon/nodejs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wilsonzlin/minify-html/2301223773dadce30a33b4c407d8b2524adeb5e2/icon/nodejs.png
--------------------------------------------------------------------------------
/icon/python.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wilsonzlin/minify-html/2301223773dadce30a33b4c407d8b2524adeb5e2/icon/python.png
--------------------------------------------------------------------------------
/icon/ruby.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wilsonzlin/minify-html/2301223773dadce30a33b4c407d8b2524adeb5e2/icon/ruby.png
--------------------------------------------------------------------------------
/icon/rust.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wilsonzlin/minify-html/2301223773dadce30a33b4c407d8b2524adeb5e2/icon/rust.png
--------------------------------------------------------------------------------
/icon/wasm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wilsonzlin/minify-html/2301223773dadce30a33b4c407d8b2524adeb5e2/icon/wasm.png
--------------------------------------------------------------------------------
/minhtml/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "minhtml"
3 | description = "[CLI] Extremely fast and smart HTML + JS + CSS minifier"
4 | version = "0.16.4"
5 | authors = ["Wilson Lin "]
6 | edition = "2018"
7 | license = "MIT"
8 | homepage = "https://github.com/wilsonzlin/minify-html"
9 | readme = "README.md"
10 | keywords = ["html", "compress", "minifier", "js", "css"]
11 | categories = ["compression", "command-line-utilities", "development-tools::build-utils", "web-programming"]
12 | repository = "https://github.com/wilsonzlin/minify-html.git"
13 |
14 | [dependencies]
15 | minify-html = { version = "0.16.4", path = "../minify-html" }
16 | rayon = "1.5"
17 | structopt = "0.3"
18 |
--------------------------------------------------------------------------------
/minhtml/README.md:
--------------------------------------------------------------------------------
1 | # minhtml
2 |
3 | CLI for [minify-html](https://github.com/wilsonzlin/minify-html).
4 |
5 | ## Usage
6 |
7 | ```
8 | minhtml [FLAGS] [OPTIONS] [inputs]...
9 | ```
10 |
11 | - **-o, --output \