Rename to minify-html
This commit is contained in:
parent
d35e881bb7
commit
dc376d7c7f
|
@ -56,4 +56,4 @@ jobs:
|
|||
- name: Upload to B2
|
||||
run: |
|
||||
b2 authorize-account ${{ secrets.CICD_CLI_B2_KEY_ID }} ${{ secrets.CICD_CLI_B2_APPLICATION_KEY }}
|
||||
b2 sync ./bench/results/ b2://${{ secrets.CICD_CLI_B2_BUCKET_NAME }}/hyperbuild/bench/${{ steps.version.outputs.VERSION }}/
|
||||
b2 sync ./bench/results/ b2://${{ secrets.CICD_CLI_B2_BUCKET_NAME }}/minify-html/bench/${{ steps.version.outputs.VERSION }}/
|
||||
|
|
|
@ -71,4 +71,4 @@ jobs:
|
|||
- name: Upload to B2
|
||||
run: |
|
||||
b2 authorize-account ${{ secrets.CICD_CLI_B2_KEY_ID }} ${{ secrets.CICD_CLI_B2_APPLICATION_KEY }}
|
||||
b2 upload-file --contentType ${{ matrix.MIME }} ${{ secrets.CICD_CLI_B2_BUCKET_NAME }} ./cli/target/release/hyperbuild-cli${{ matrix.EXT }} hyperbuild/bin/${{ steps.file.outputs.FILE }}
|
||||
b2 upload-file --contentType ${{ matrix.MIME }} ${{ secrets.CICD_CLI_B2_BUCKET_NAME }} ./cli/target/release/minify-html-cli${{ matrix.EXT }} minify-html/bin/${{ steps.file.outputs.FILE }}
|
||||
|
|
|
@ -16,10 +16,10 @@ jobs:
|
|||
include:
|
||||
- os: ubuntu-latest
|
||||
ARCH: linux-x86_64
|
||||
FILE: 'libhyperbuild_java.so'
|
||||
FILE: 'libminify_html_java.so'
|
||||
- os: macos-latest
|
||||
ARCH: macos-x86_64
|
||||
FILE: 'libhyperbuild_java.dylib'
|
||||
FILE: 'libminify_html_java.dylib'
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Set up Rust (macOS, Linux)
|
||||
|
|
|
@ -73,7 +73,7 @@ jobs:
|
|||
run: |
|
||||
binary_name="$(node -e 'console.log([process.platform, process.arch, process.versions.modules].join("__"))')"
|
||||
b2 authorize-account ${{ secrets.CICD_CLI_B2_KEY_ID }} ${{ secrets.CICD_CLI_B2_APPLICATION_KEY }}
|
||||
b2 upload-file ${{ secrets.CICD_CLI_B2_BUCKET_NAME }} ./nodejs/dist/native.node "hyperbuild/bin/nodejs/${{ steps.version.outputs.VERSION }}/$binary_name.node"
|
||||
b2 upload-file ${{ secrets.CICD_CLI_B2_BUCKET_NAME }} ./nodejs/dist/native.node "minify-html/bin/nodejs/${{ steps.version.outputs.VERSION }}/$binary_name.node"
|
||||
package:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
|
|
|
@ -14,15 +14,6 @@ jobs:
|
|||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
python: [3.5, 3.6, 3.7, 3.8]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
ARCH: linux-x86_64
|
||||
LIBFILE: 'libhyperbuild_python_lib.so'
|
||||
PYEXT: 'so'
|
||||
- os: macos-latest
|
||||
ARCH: macos-x86_64
|
||||
LIBFILE: 'libhyperbuild_python_lib.dylib'
|
||||
PYEXT: 'so'
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Set up Python
|
||||
|
|
|
@ -17,10 +17,10 @@ jobs:
|
|||
include:
|
||||
- os: ubuntu-latest
|
||||
NAME: linux
|
||||
FILE: 'libhyperbuild_ruby_lib.so'
|
||||
FILE: 'libminify_html_ruby_lib.so'
|
||||
- os: macos-latest
|
||||
NAME: macos
|
||||
FILE: 'libhyperbuild_ruby_lib.dylib'
|
||||
FILE: 'libminify_html_ruby_lib.dylib'
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Get version
|
||||
|
@ -102,7 +102,7 @@ jobs:
|
|||
- name: Upload to B2
|
||||
run: |
|
||||
b2 authorize-account ${{ secrets.CICD_CLI_B2_KEY_ID }} ${{ secrets.CICD_CLI_B2_APPLICATION_KEY }}
|
||||
b2 upload-file ${{ secrets.CICD_CLI_B2_BUCKET_NAME }} ./ruby/target/release/${{ matrix.FILE }} hyperbuild/bin/ruby/${{ steps.version.outputs.VERSION }}/${{ steps.native_file.outputs.NAME }}
|
||||
b2 upload-file ${{ secrets.CICD_CLI_B2_BUCKET_NAME }} ./ruby/target/release/${{ matrix.FILE }} minify-html/bin/ruby/${{ steps.version.outputs.VERSION }}/${{ steps.native_file.outputs.NAME }}
|
||||
package:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
|
@ -125,8 +125,8 @@ jobs:
|
|||
run: |
|
||||
cp ../README.md .
|
||||
b2 authorize-account ${{ secrets.CICD_CLI_B2_KEY_ID }} ${{ secrets.CICD_CLI_B2_APPLICATION_KEY }}
|
||||
b2 sync b2://${{ secrets.CICD_CLI_B2_BUCKET_NAME }}/hyperbuild/bin/ruby/${{ steps.version.outputs.VERSION }}/ ./lib/.
|
||||
gem build hyperbuild.gemspec
|
||||
b2 sync b2://${{ secrets.CICD_CLI_B2_BUCKET_NAME }}/minify-html/bin/ruby/${{ steps.version.outputs.VERSION }}/ ./lib/.
|
||||
gem build minify_html.gemspec
|
||||
mkdir -p "$HOME/.gem"
|
||||
cat << 'EOF' > "$HOME/.gem/credentials"
|
||||
---
|
||||
|
@ -134,5 +134,5 @@ jobs:
|
|||
EOF
|
||||
chmod 0600 "$HOME/.gem/credentials"
|
||||
if [[ "${{ steps.version.outputs.VERSION }}" != "0.0.0" ]]; then
|
||||
gem push hyperbuild-${{ steps.version.outputs.VERSION }}.gem
|
||||
gem push minify_html-${{ steps.version.outputs.VERSION }}.gem
|
||||
fi
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
[package]
|
||||
name = "hyperbuild"
|
||||
name = "minify-html"
|
||||
description = "Fast allocation-less HTML minifier with smart whitespace handling"
|
||||
license = "MIT"
|
||||
homepage = "https://github.com/wilsonzlin/hyperbuild"
|
||||
homepage = "https://github.com/wilsonzlin/minify-html"
|
||||
readme = "README.md"
|
||||
keywords = ["html", "compress", "minifier", "minify", "minification"]
|
||||
categories = ["compression", "command-line-utilities", "development-tools::build-utils", "web-programming"]
|
||||
repository = "https://github.com/wilsonzlin/hyperbuild.git"
|
||||
repository = "https://github.com/wilsonzlin/minify-html.git"
|
||||
version = "0.2.4"
|
||||
authors = ["Wilson Lin <code@wilsonl.in>"]
|
||||
edition = "2018"
|
||||
|
|
92
README.md
92
README.md
|
@ -1,4 +1,4 @@
|
|||
# hyperbuild
|
||||
# minify-html
|
||||
|
||||
A fast one-pass in-place HTML minifier written in Rust with context-aware whitespace handling.
|
||||
|
||||
|
@ -20,7 +20,7 @@ Available as:
|
|||
|
||||
Speed and effectiveness of Node.js version compared to [html-minfier](https://github.com/kangax/html-minifier) and [minimize](https://github.com/Swaagie/minimize), run on popular already-minified web pages. See [bench](./bench) folder for more details.
|
||||
|
||||
<img width="435" alt="Chart showing speed of HTML minifiers" src="https://wilsonl.in/hyperbuild/bench/0.2.4/average-speeds.png"> <img width="435" alt="Chart showing effectiveness of HTML minifiers" src="https://wilsonl.in/hyperbuild/bench/0.2.4/average-sizes.png">
|
||||
<img width="435" alt="Chart showing speed of HTML minifiers" src="https://wilsonl.in/minify-html/bench/0.2.4/average-speeds.png"> <img width="435" alt="Chart showing effectiveness of HTML minifiers" src="https://wilsonl.in/minify-html/bench/0.2.4/average-sizes.png">
|
||||
|
||||
## Usage
|
||||
|
||||
|
@ -30,15 +30,15 @@ Precompiled binaries are available for x86-64 macOS and Linux.
|
|||
|
||||
##### Get
|
||||
|
||||
[macOS](https://wilsonl.in/hyperbuild/bin/0.2.4-macos-x86_64) |
|
||||
[Linux](https://wilsonl.in/hyperbuild/bin/0.2.4-linux-x86_64)
|
||||
[macOS](https://wilsonl.in/minify-html/bin/0.2.4-macos-x86_64) |
|
||||
[Linux](https://wilsonl.in/minify-html/bin/0.2.4-linux-x86_64)
|
||||
|
||||
##### Use
|
||||
|
||||
Use the `--help` argument for more details.
|
||||
|
||||
```bash
|
||||
hyperbuild --src /path/to/src.html --out /path/to/output.min.html
|
||||
minify-html --src /path/to/src.html --out /path/to/output.min.html
|
||||
```
|
||||
|
||||
### API
|
||||
|
@ -50,7 +50,7 @@ hyperbuild --src /path/to/src.html --out /path/to/output.min.html
|
|||
|
||||
```toml
|
||||
[dependencies]
|
||||
hyperbuild = { version = "0.2.4", features = ["js-esbuild"] }
|
||||
minify-html = { version = "0.2.4", features = ["js-esbuild"] }
|
||||
```
|
||||
|
||||
Building with the `js-esbuild` feature requires the Go compiler to be installed as well, to build the [JS minifier](https://github.com/evanw/esbuild).
|
||||
|
@ -60,7 +60,7 @@ If the `js-esbuild` feature is not enabled, `cfg.minify_js` will have no effect.
|
|||
##### Use
|
||||
|
||||
```rust
|
||||
use hyperbuild::{Cfg, FriendlyError, hyperbuild, hyperbuild_copy, hyperbuild_friendly_error, hyperbuild_truncate};
|
||||
use minify_html::{Cfg, FriendlyError, in_place, copy, with_friendly_error, truncate};
|
||||
|
||||
fn main() {
|
||||
let mut code = b"<p> Hello, world! </p>".to_vec();
|
||||
|
@ -70,29 +70,29 @@ fn main() {
|
|||
|
||||
// Minifies a slice in-place and returns the new minified length,
|
||||
// but leaves any original code after the minified code intact.
|
||||
match hyperbuild(&mut code, cfg) {
|
||||
match in_place(&mut code, cfg) {
|
||||
Ok(minified_len) => {}
|
||||
Err((error_type, error_position)) => {}
|
||||
};
|
||||
|
||||
// Creates a vector copy containing only minified code
|
||||
// instead of minifying in-place.
|
||||
match hyperbuild_copy(&code, cfg) {
|
||||
match copy(&code, cfg) {
|
||||
Ok(minified) => {}
|
||||
Err((error_type, error_position)) => {}
|
||||
};
|
||||
|
||||
// Minifies a vector in-place, and then truncates the
|
||||
// vector to the new minified length.
|
||||
match hyperbuild_truncate(&mut code, cfg) {
|
||||
match truncate(&mut code, cfg) {
|
||||
Ok(()) => {}
|
||||
Err((error_type, error_position)) => {}
|
||||
};
|
||||
|
||||
// Identical to `hyperbuild` except with FriendlyError instead.
|
||||
// Identical to `in_place` except with FriendlyError instead.
|
||||
// `code_context` is a string of a visual representation of the source,
|
||||
// with line numbers and position markers to aid in debugging syntax.
|
||||
match hyperbuild_friendly_error(&mut code, cfg) {
|
||||
match with_friendly_error(&mut code, cfg) {
|
||||
Ok(minified_len) => {}
|
||||
Err(FriendlyError { position, message, code_context }) => {
|
||||
eprintln!("Failed at character {}:", position);
|
||||
|
@ -108,44 +108,46 @@ fn main() {
|
|||
<details>
|
||||
<summary><strong>Node.js</strong></summary>
|
||||
|
||||
hyperbuild is [on npm](https://www.npmjs.com/package/hyperbuild), available as a [Node.js native module](https://neon-bindings.com/), and supports Node.js versions 8 and higher.
|
||||
Package: [@minify-html/js-esbuild](https://www.npmjs.com/package/@minify-html/js-esbuild),
|
||||
Binding: [Neon](https://neon-bindings.com/)
|
||||
Platforms: macOS, Linux; Node.js 8 and higher
|
||||
|
||||
##### Get
|
||||
|
||||
Using npm:
|
||||
|
||||
```bash
|
||||
npm i hyperbuild
|
||||
npm i @minify-html/js-esbuild
|
||||
```
|
||||
|
||||
Using Yarn:
|
||||
|
||||
```bash
|
||||
yarn add hyperbuild
|
||||
yarn add @minify-html/js-esbuild
|
||||
```
|
||||
|
||||
##### Use
|
||||
|
||||
```js
|
||||
const hyperbuild = require("hyperbuild");
|
||||
const minifyHtml = require("@minify-html/js-esbuild");
|
||||
|
||||
const cfg = { minifyJs: false };
|
||||
const minified = hyperbuild.minify("<p> Hello, world! </p>", cfg);
|
||||
const minified = minifyHtml.minify("<p> Hello, world! </p>", cfg);
|
||||
|
||||
// Alternatively, minify in place to avoid copying.
|
||||
const source = Buffer.from("<p> Hello, world! </p>", cfg);
|
||||
hyperbuild.minifyInPlace(source);
|
||||
minifyHtml.minifyInPlace(source);
|
||||
```
|
||||
|
||||
hyperbuild is also available for TypeScript:
|
||||
minify-html is also available for TypeScript:
|
||||
|
||||
```ts
|
||||
import * as hyperbuild from "hyperbuild";
|
||||
import * as minifyHtml from "@minify-html/js-esbuild";
|
||||
import * as fs from "fs";
|
||||
|
||||
const cfg = { minifyJs: false };
|
||||
const minified = hyperbuild.minify("<p> Hello, world! </p>", cfg);
|
||||
hyperbuild.minifyInPlace(fs.readFileSync("source.html"), cfg);
|
||||
const minified = minifyHtml.minify("<p> Hello, world! </p>", cfg);
|
||||
minifyHtml.minifyInPlace(fs.readFileSync("source.html"), cfg);
|
||||
```
|
||||
|
||||
</details>
|
||||
|
@ -153,7 +155,9 @@ hyperbuild.minifyInPlace(fs.readFileSync("source.html"), cfg);
|
|||
<details>
|
||||
<summary><strong>Java</strong></summary>
|
||||
|
||||
hyperbuild is available via [JNI](https://github.com/jni-rs/jni-rs), and supports Java versions 7 and higher.
|
||||
Package: [in.wilsonl.minify_html](https://search.maven.org/artifact/in.wilsonl.minify_html/minify-html)
|
||||
Binding: [JNI](https://github.com/jni-rs/jni-rs)
|
||||
Platforms: macOS, Linux; Java 7 and higher
|
||||
|
||||
##### Get
|
||||
|
||||
|
@ -161,8 +165,8 @@ Add as a Maven dependency:
|
|||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>in.wilsonl.hyperbuild</groupId>
|
||||
<artifactId>hyperbuild</artifactId>
|
||||
<groupId>in.wilsonl.minify_html</groupId>
|
||||
<artifactId>minify-html</artifactId>
|
||||
<version>0.2.4</version>
|
||||
</dependency>
|
||||
```
|
||||
|
@ -170,20 +174,20 @@ Add as a Maven dependency:
|
|||
##### Use
|
||||
|
||||
```java
|
||||
import in.wilsonl.hyperbuild.Hyperbuild;
|
||||
import in.wilsonl.minify_html.MinifyHtml;
|
||||
|
||||
Hyperbuild.Configuration cfg = new Hyperbuild.Configuration.Builder()
|
||||
MinifyHtml.Configuration cfg = new MinifyHtml.Configuration.Builder()
|
||||
.setMinifyJs(false)
|
||||
.build();
|
||||
try {
|
||||
String minified = Hyperbuild.minify("<p> Hello, world! </p>", cfg);
|
||||
} catch (Hyperbuild.SyntaxException e) {
|
||||
String minified = MinifyHtml.minify("<p> Hello, world! </p>", cfg);
|
||||
} catch (MinifyHtml.SyntaxException e) {
|
||||
System.err.println(e.getMessage());
|
||||
}
|
||||
|
||||
// Alternatively, minify in place:
|
||||
assert source instanceof ByteBuffer && source.isDirect();
|
||||
Hyperbuild.minifyInPlace(source, cfg);
|
||||
MinifyHtml.minifyInPlace(source, cfg);
|
||||
```
|
||||
|
||||
</details>
|
||||
|
@ -191,7 +195,9 @@ Hyperbuild.minifyInPlace(source, cfg);
|
|||
<details>
|
||||
<summary><strong>Python</strong></summary>
|
||||
|
||||
hyperbuild is [on PyPI](https://pypi.org/project/hyperbuild), available as a [native module](https://github.com/PyO3/pyo3), and supports CPython (the default Python interpreter) versions 3.5 and higher.
|
||||
Package: [minify_html](https://pypi.org/project/minify_html)
|
||||
Binding: [PyO3](https://github.com/PyO3/pyo3)
|
||||
Platforms: macOS, Linux; CPython 3.5 and higher
|
||||
|
||||
##### Get
|
||||
|
||||
|
@ -200,10 +206,10 @@ Add the PyPI project as a dependency and install it using `pip` or `pipenv`.
|
|||
##### Use
|
||||
|
||||
```python
|
||||
import hyperbuild
|
||||
import minify_html
|
||||
|
||||
try:
|
||||
minified = hyperbuild.minify("<p> Hello, world! </p>", minify_js=False)
|
||||
minified = minify_html.minify("<p> Hello, world! </p>", minify_js=False)
|
||||
except SyntaxError as e:
|
||||
print(e)
|
||||
```
|
||||
|
@ -213,7 +219,9 @@ except SyntaxError as e:
|
|||
<details>
|
||||
<summary><strong>Ruby</strong></summary>
|
||||
|
||||
hyperbuild is published on [RubyGems](https://rubygems.org/gems/hyperbuild), available as a [native module](https://github.com/danielpclark/rutie) for macOS and Linux, and supports Ruby versions 2.5 and higher.
|
||||
Package: [minify_html](https://rubygems.org/gems/minify_html)
|
||||
Binding: [Rutie](https://github.com/danielpclark/rutie)
|
||||
Platforms: macOS, Linux; Ruby 2.5 and higher
|
||||
|
||||
##### Get
|
||||
|
||||
|
@ -222,9 +230,9 @@ Add the library as a dependency to `Gemfile` or `*.gemspec`.
|
|||
##### Use
|
||||
|
||||
```ruby
|
||||
require 'hyperbuild'
|
||||
require 'minify_html'
|
||||
|
||||
print Hyperbuild.minify("<p> Hello, world! </p>", { :minify_js => false })
|
||||
print MinifyHtml.minify("<p> Hello, world! </p>", { :minify_js => false })
|
||||
```
|
||||
|
||||
</details>
|
||||
|
@ -233,7 +241,7 @@ print Hyperbuild.minify("<p> Hello, world! </p>", { :minify_js => false })
|
|||
|
||||
### Whitespace
|
||||
|
||||
hyperbuild has advanced context-aware whitespace minification that does things such as:
|
||||
minify-html has advanced context-aware whitespace minification that does things such as:
|
||||
|
||||
- Leave whitespace untouched in `pre` and `code`, which are whitespace sensitive.
|
||||
- Trim and collapse whitespace in content tags, as whitespace is collapsed anyway when rendered.
|
||||
|
@ -241,7 +249,7 @@ hyperbuild has advanced context-aware whitespace minification that does things s
|
|||
|
||||
#### Methods
|
||||
|
||||
There are three whitespace minification methods. When processing text content, hyperbuild chooses which ones to use depending on the containing element.
|
||||
There are three whitespace minification methods. When processing text content, minify-html chooses which ones to use depending on the containing element.
|
||||
|
||||
<details>
|
||||
<summary><strong>Collapse whitespace</strong></summary>
|
||||
|
@ -327,7 +335,7 @@ Remove any leading/trailing whitespace from any leading/trailing text nodes of a
|
|||
|
||||
#### Element types
|
||||
|
||||
hyperbuild recognises elements based on one of a few ways it assumes they are used. By making these assumptions, it can apply optimal whitespace minification strategies.
|
||||
minify-html recognises elements based on one of a few ways it assumes they are used. By making these assumptions, it can apply optimal whitespace minification strategies.
|
||||
|
||||
|Group|Elements|Expected children|
|
||||
|---|---|---|
|
||||
|
@ -468,7 +476,7 @@ Bangs, [processing instructions](https://en.wikipedia.org/wiki/Processing_Instru
|
|||
|
||||
Only UTF-8/ASCII-encoded HTML code is supported.
|
||||
|
||||
hyperbuild does no syntax checking or standards enforcement for performance and code complexity reasons.
|
||||
minify-html does no syntax checking or standards enforcement for performance and code complexity reasons.
|
||||
|
||||
For example, this means that it's not an error to have self-closing tags, declare multiple `<body>` elements, use incorrect attribute names and values, or write something like `<br>alert('');</br>`
|
||||
|
||||
|
@ -503,10 +511,10 @@ Special handling of some attributes require case sensitive names and values. For
|
|||
|
||||
`script` and `style` tags must be closed with `</script>` and `</style>` respectively (case sensitive).
|
||||
|
||||
hyperbuild does **not** handle [escaped and double-escaped](./notes/Script%20data.md) script content.
|
||||
minify-html does **not** handle [escaped and double-escaped](./notes/Script%20data.md) script content.
|
||||
|
||||
## Issues and contributions
|
||||
|
||||
Pull requests and any contributions welcome!
|
||||
|
||||
If hyperbuild did something unexpected, misunderstood some syntax, or incorrectly kept/removed some code, [raise an issue](https://github.com/wilsonzlin/hyperbuild/issues) with some relevant code that can be used to reproduce and investigate the issue.
|
||||
If minify-html did something unexpected, misunderstood some syntax, or incorrectly kept/removed some code, [raise an issue](https://github.com/wilsonzlin/minify-html/issues) with some relevant code that can be used to reproduce and investigate the issue.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/hyperbuild-bench/Cargo.lock
|
||||
/hyperbuild-bench/target/
|
||||
/minify-html-bench/Cargo.lock
|
||||
/minify-html-bench/target/
|
||||
/min/
|
||||
/results*/
|
||||
node_modules/
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# Benchmarking
|
||||
|
||||
This folder contains scripts used to test the performance and effectiveness of hyperbuild, for guided optimisation and/or comparisons.
|
||||
This folder contains scripts used to test the performance and effectiveness of minify-html, for guided optimisation and/or comparisons.
|
||||
|
||||
It also contains a set of common web pages as tests for benchmarking.
|
||||
|
||||
## Comparison
|
||||
|
||||
The [Node.js version of hyperbuild](../nodejs) is tested against [html-minfier](https://github.com/kangax/html-minifier) and [minimize](https://github.com/Swaagie/minimize) in two dimensions:
|
||||
The [Node.js version of minify-html](../nodejs) is tested against [html-minfier](https://github.com/kangax/html-minifier) and [minimize](https://github.com/Swaagie/minimize) in two dimensions:
|
||||
|
||||
- Speed as operations per second.
|
||||
- Minified file size compared to the original.
|
||||
|
@ -35,32 +35,32 @@ For more information on how the tests are fetched, see [fetch.js](./fetch.js).
|
|||
|
||||
On this [project's README](../README.md), average graphs are shown. Graphs showing per-test results are shown below:
|
||||
|
||||
<img width="435" alt="Chart showing speed of HTML minifiers per test" src="https://wilsonl.in/hyperbuild/bench/0.2.4/speeds.png"> <img width="435" alt="Chart showing effectiveness of HTML minifiers per test" src="https://wilsonl.in/hyperbuild/bench/0.2.4/sizes.png">
|
||||
<img width="435" alt="Chart showing speed of HTML minifiers per test" src="https://wilsonl.in/minify-html/bench/0.2.4/speeds.png"> <img width="435" alt="Chart showing effectiveness of HTML minifiers per test" src="https://wilsonl.in/minify-html/bench/0.2.4/sizes.png">
|
||||
|
||||
Since speed depends on the input, speed charts show performance relative to hyperbuild-nodejs as a percentage.
|
||||
Since speed depends on the input, speed charts show performance relative to the Node.js minify-html as a percentage.
|
||||
|
||||
The settings used for each minifier can be found in [minifiers.js](./minifiers.js). Some settings to note:
|
||||
|
||||
- JS and CSS minification is disabled for all, as hyperbuild is an HTML minifier and there are existing separate tools for [such](https://github.com/terser/terser) [tasks](https://github.com/jakubpawlowicz/clean-css).
|
||||
- `conservativeCollapse` is enabled for html-minifier as otherwise some whitespace would be unsafely removed with side affects. hyperbuild can safely remove whitespace with context if configured properly.
|
||||
- JS and CSS minification is disabled for all, as minify-html is an HTML minifier and there are existing separate tools for [such](https://github.com/terser/terser) [tasks](https://github.com/jakubpawlowicz/clean-css).
|
||||
- `conservativeCollapse` is enabled for html-minifier as otherwise some whitespace would be unsafely removed with side affects. minify-html can safely remove whitespace with context if configured properly.
|
||||
|
||||
## Running
|
||||
|
||||
Make sure to install the dependencies listed in [package.json](./package.json) by running `npm i` or `yarn`. Node.js 10 is required, and system dependencies for building [canvas](https://www.npmjs.com/package/canvas), used for rendering graphs, may need to be installed. See the [npm package](https://www.npmjs.com/package/canvas) for more details.
|
||||
|
||||
Run [build.sh](./build.sh) to build hyperbuild-nodejs with the local hyperbuild.
|
||||
Run [build.sh](./build.sh) to build minify-html-nodejs with the local minify-html.
|
||||
|
||||
Run [sizes.js](sizes.js) to run each HTML minifier against each test and record the minified size results. This will also output the minified files in `min` if inspection of minified outputs is necessary. [compare.sh](./compare.sh) is a useful script for viewing a character-by-character diff between the minified outputs of hyperbuild and html-minifier for a specific test. Pass the test's file name as the first argument.
|
||||
Run [sizes.js](sizes.js) to run each HTML minifier against each test and record the minified size results. This will also output the minified files in `min` if inspection of minified outputs is necessary. [compare.sh](./compare.sh) is a useful script for viewing a character-by-character diff between the minified outputs of minify-html and html-minifier for a specific test. Pass the test's file name as the first argument.
|
||||
|
||||
Run [speeds.js](./speeds.js) to benchmark the performance of each HTML minifier against each test and record the op/s results.
|
||||
|
||||
Run [graph.js](./graph.js) to render graphs from recorded speed and size results in the `results` folder.
|
||||
|
||||
## hyperbuild-bench
|
||||
## minify-html-bench
|
||||
|
||||
The [hyperbuild-bench](./hyperbuild-bench) folder contains a Rust executable subproject that runs the local hyperbuild on all tests for many iterations to calculate speed as operations per second.
|
||||
The [minify-html-bench](./minify-html-bench) folder contains a Rust executable subproject that runs the local minify-html on all tests for many iterations to calculate speed as operations per second.
|
||||
|
||||
This can be useful for profiling the core code or checking the performance of hyperbuild in other languages with native bindings.
|
||||
This can be useful for profiling the core code or checking the performance of minify-html in other languages with native bindings.
|
||||
|
||||
It takes two arguments:
|
||||
|
||||
|
@ -69,4 +69,4 @@ It takes two arguments:
|
|||
|
||||
The results will be written to stdout as a JSON object, where properties are the test file names and values are the operations per second.
|
||||
|
||||
Profiling hyperbuild can be done on Linux by using [profile.sh](./profile.sh), which uses `perf`. The generated report can be used using `perf report`.
|
||||
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`.
|
||||
|
|
|
@ -9,7 +9,7 @@ npm run build
|
|||
npm run build-binary
|
||||
popd
|
||||
|
||||
pushd hyperbuild-bench
|
||||
pushd minify-html-bench
|
||||
cargo build --release
|
||||
popd
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
git --no-pager diff --no-index --word-diff=color --word-diff-regex=. "min/html-minifier/$1.html" "min/hyperbuild-nodejs/$1.html" | less
|
||||
git --no-pager diff --no-index --word-diff=color --word-diff-regex=. "min/html-minifier/$1.html" "min/minify-html-nodejs/$1.html" | less
|
||||
|
|
|
@ -2,8 +2,8 @@ const chartjs = require('chartjs-node');
|
|||
const results = require('./results');
|
||||
|
||||
const colours = {
|
||||
'hyperbuild': '#041f60',
|
||||
'hyperbuild-nodejs': '#1f77b4',
|
||||
'minify-html': '#041f60',
|
||||
'minify-html-nodejs': '#1f77b4',
|
||||
'minimize': '#ff7f0e',
|
||||
'html-minifier': '#2ca02c',
|
||||
};
|
||||
|
@ -56,7 +56,7 @@ const renderChart = async (cfg) => {
|
|||
};
|
||||
|
||||
(async () => {
|
||||
const averageSpeeds = results.getSpeedResults().getAverageRelativeSpeedPerMinifier('hyperbuild-nodejs');
|
||||
const averageSpeeds = results.getSpeedResults().getAverageRelativeSpeedPerMinifier('minify-html-nodejs');
|
||||
results.writeAverageSpeedsGraph(await renderChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
|
@ -70,7 +70,7 @@ const renderChart = async (cfg) => {
|
|||
...chartOptions('Average operations per second (higher is better)', false, percentageTick),
|
||||
}));
|
||||
|
||||
const speeds = results.getSpeedResults().getRelativeFileSpeedsPerMinifier('hyperbuild-nodejs');
|
||||
const speeds = results.getSpeedResults().getRelativeFileSpeedsPerMinifier('minify-html-nodejs');
|
||||
results.writeSpeedsGraph(await renderChart({
|
||||
type: 'bar',
|
||||
data: {
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
const htmlMinifier = require("html-minifier");
|
||||
const hyperbuild = require("hyperbuild");
|
||||
const minifyHtml = require("@minify-html/js-esbuild");
|
||||
const minimize = require("minimize");
|
||||
|
||||
module.exports = {
|
||||
'hyperbuild-nodejs': (_, buffer) => hyperbuild.minifyInPlace(Buffer.from(buffer), {minifyJs: false}),
|
||||
'minify-html-nodejs': (_, buffer) => minifyHtml.minifyInPlace(Buffer.from(buffer), {minifyJs: false}),
|
||||
'html-minifier': content => htmlMinifier.minify(content, {
|
||||
collapseBooleanAttributes: true,
|
||||
collapseInlineTagWhitespace: true,
|
||||
collapseWhitespace: true,
|
||||
// hyperbuild can do context-aware whitespace removal, which is safe when configured correctly to match how whitespace is used in the document.
|
||||
// minify-html can do context-aware whitespace removal, which is safe when configured correctly to match how whitespace is used in the document.
|
||||
// html-minifier cannot, so whitespace must be collapsed conservatively.
|
||||
// Alternatively, hyperbuild can also be made to remove whitespace regardless of context.
|
||||
// Alternatively, minify-html can also be made to remove whitespace regardless of context.
|
||||
conservativeCollapse: true,
|
||||
customEventAttributes: [],
|
||||
decodeEntities: true,
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
[package]
|
||||
name = "hyperbuild-bench"
|
||||
name = "minify-html-bench"
|
||||
publish = false
|
||||
version = "0.0.1"
|
||||
authors = ["Wilson Lin <code@wilsonl.in>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
hyperbuild = { path = "../.." }
|
||||
minify-html = { path = "../.." }
|
||||
structopt = "0.3.5"
|
||||
serde = { version = "1.0.104", features = ["derive"] }
|
||||
serde_json = "1.0.44"
|
|
@ -1,4 +1,4 @@
|
|||
use hyperbuild::{Cfg, hyperbuild};
|
||||
use minify_html::{Cfg, in_place};
|
||||
use std::fs;
|
||||
use std::io::{stdout};
|
||||
use std::time::Instant;
|
||||
|
@ -23,7 +23,7 @@ fn main() {
|
|||
let start = Instant::now();
|
||||
for _ in 0..args.iterations {
|
||||
let mut data = source.to_vec();
|
||||
hyperbuild(&mut data, &Cfg {
|
||||
in_place(&mut data, &Cfg {
|
||||
minify_js: false,
|
||||
}).unwrap();
|
||||
};
|
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@minify-html/js-esbuild": "file:../nodejs",
|
||||
"benchmark": "2.1.4",
|
||||
"chart.js": "^2.9.3",
|
||||
"chartjs-node": "^1.7.1",
|
||||
"html-minifier": "4.0.0",
|
||||
"hyperbuild": "file:../nodejs",
|
||||
"minimize": "2.2.0",
|
||||
"minimist": "^1.2.0",
|
||||
"mkdirp": "^0.5.1",
|
||||
|
|
|
@ -8,5 +8,5 @@ for i in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do
|
|||
done
|
||||
|
||||
rm -f perf.data
|
||||
sudo perf record -g nice -n -20 taskset -c 1 hyperbuild-bench/target/release/hyperbuild-bench --tests tests --iterations 512
|
||||
sudo perf record -g nice -n -20 taskset -c 1 minify-html-bench/target/release/minify-html-bench --tests tests --iterations 512
|
||||
sudo chown "$USER:$USER" perf.data
|
||||
|
|
|
@ -61,11 +61,11 @@ const runTest = test => new Promise((resolve, reject) => {
|
|||
// Run Rust library.
|
||||
if (shouldRunRust) {
|
||||
for (const [testName, testOps] of JSON.parse(cmd(
|
||||
path.join(__dirname, 'hyperbuild-bench', 'target', 'release', 'hyperbuild-bench'),
|
||||
path.join(__dirname, 'minify-html-bench', 'target', 'release', 'minify-html-bench'),
|
||||
'--iterations', 512,
|
||||
'--tests', path.join(__dirname, 'tests'),
|
||||
))) {
|
||||
Object.assign(speeds[testName], {hyperbuild: testOps});
|
||||
Object.assign(speeds[testName], {['minify-html']: testOps});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
[package]
|
||||
name = "hyperbuild-cli"
|
||||
publish = false
|
||||
name = "minify-html-cli"
|
||||
version = "0.2.4"
|
||||
authors = ["Wilson Lin <code@wilsonl.in>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
hyperbuild = { path = "..", features = ["js-esbuild"] }
|
||||
minify-html = { path = "..", features = ["js-esbuild"] }
|
||||
structopt = "0.3.5"
|
||||
|
|
|
@ -3,7 +3,7 @@ use std::io::{Read, stdin, stdout, Write};
|
|||
|
||||
use structopt::StructOpt;
|
||||
|
||||
use hyperbuild::{Cfg, FriendlyError, hyperbuild_friendly_error};
|
||||
use minify_html::{Cfg, FriendlyError, with_friendly_error};
|
||||
|
||||
#[derive(StructOpt)]
|
||||
struct Cli {
|
||||
|
@ -36,7 +36,7 @@ fn main() {
|
|||
None => Box::new(stdin()),
|
||||
};
|
||||
io_expect!(src_file.read_to_end(&mut code), "could not load source code");
|
||||
match hyperbuild_friendly_error(&mut code, &Cfg {
|
||||
match with_friendly_error(&mut code, &Cfg {
|
||||
minify_js: args.js,
|
||||
}) {
|
||||
Ok(out_len) => {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
[package]
|
||||
name = "hyperbuild-fuzz-target"
|
||||
publish = false
|
||||
name = "minify-html-fuzz-target"
|
||||
version = "0.0.1"
|
||||
authors = ["Wilson Lin <code@wilsonl.in>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
afl = "0.5.2"
|
||||
hyperbuild = { path = ".." }
|
||||
minify-html = { path = ".." }
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Fuzzing
|
||||
|
||||
This folder contains a Cargo package for a fuzz target that can be used for fuzzing with [american fuzzy lop](https://github.com/google/AFL). Fuzzing has found many rare bugs and unhandled edge cases that cause crashes and is invaluable for improving the reliability of hyperbuild.
|
||||
This folder contains a Cargo package for a fuzz target that can be used for fuzzing with [american fuzzy lop](https://github.com/google/AFL). Fuzzing has found many rare bugs and unhandled edge cases that cause crashes and is invaluable for improving the reliability of minify-html.
|
||||
|
||||
## Inputs
|
||||
|
||||
|
@ -15,7 +15,7 @@ cargo afl build
|
|||
## Running
|
||||
|
||||
```bash
|
||||
cargo afl fuzz -i in -o out target/debug/hyperbuild-fuzz-target
|
||||
cargo afl fuzz -i in -o out target/debug/minify-html-fuzz-target
|
||||
```
|
||||
|
||||
## Results
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
[package]
|
||||
name = "hyperbuild-fuzz-process"
|
||||
name = "minify-html-fuzz-process"
|
||||
version = "0.0.1"
|
||||
authors = ["Wilson Lin <code@wilsonl.in>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
hyperbuild = { path = "../.." }
|
||||
minify-html = { path = "../.." }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::fs;
|
||||
use std::io::{self, Write};
|
||||
use std::panic;
|
||||
use hyperbuild;
|
||||
use minify_html;
|
||||
|
||||
fn main() {
|
||||
for dirent in fs::read_dir("../out/crashes").unwrap() {
|
||||
|
@ -9,7 +9,7 @@ fn main() {
|
|||
let path_in_catch = path.clone();
|
||||
let res = panic::catch_unwind(|| {
|
||||
let mut contents = fs::read(path_in_catch).unwrap();
|
||||
let _ = hyperbuild::hyperbuild(&mut contents, &hyperbuild::Cfg {
|
||||
let _ = minify_html::in_place(&mut contents, &minify_html::Cfg {
|
||||
minify_js: false,
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use afl::fuzz;
|
||||
use hyperbuild::{Cfg, hyperbuild};
|
||||
use minify_html::{Cfg, in_place};
|
||||
|
||||
fn main() {
|
||||
fuzz!(|data: &[u8]| {
|
||||
let mut mut_data: Vec<u8> = data.iter().map(|x| *x).collect();
|
||||
let _ = hyperbuild(&mut mut_data, &Cfg {
|
||||
let _ = in_place(&mut mut_data, &Cfg {
|
||||
minify_js: false,
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
[package]
|
||||
name = "hyperbuild-java"
|
||||
publish = false
|
||||
name = "minify-html-java"
|
||||
version = "0.2.4"
|
||||
authors = ["Wilson Lin <code@wilsonl.in>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
hyperbuild = { path = "..", features = ["js-esbuild"] }
|
||||
minify-html = { path = "..", features = ["js-esbuild"] }
|
||||
jni = "0.14.0"
|
||||
|
||||
[lib]
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
|
||||
set -e
|
||||
|
||||
# Builds hyperbuild-java with native module for local testing.
|
||||
# Built JAR will only run current platform.
|
||||
# Build JAR with native module for current platform.
|
||||
|
||||
pushd "$(dirname "$0")"
|
||||
|
||||
|
@ -35,17 +34,9 @@ else
|
|||
exit 1
|
||||
fi
|
||||
|
||||
if [ -f Cargo.toml.orig ]; then
|
||||
echo 'Not altering Java Cargo.toml file'
|
||||
else
|
||||
cp Cargo.toml Cargo.toml.orig
|
||||
# Don't use -i as macOS requires '' argument but then Ubuntu will treat as pattern.
|
||||
sed 's%^hyperbuild = .*$%hyperbuild = { path = ".." }%' Cargo.toml.orig > Cargo.toml
|
||||
fi
|
||||
cargo build $rust_build_arg
|
||||
mv Cargo.toml.orig Cargo.toml
|
||||
mkdir -p src/main/resources/
|
||||
cp target/rust/$rust_build_dir/libhyperbuild_java.$ext src/main/resources/$os_name-x86_64.nativelib
|
||||
cp target/rust/$rust_build_dir/libminify_html_java.$ext src/main/resources/$os_name-x86_64.nativelib
|
||||
|
||||
mvn clean package
|
||||
|
||||
|
|
14
java/pom.xml
14
java/pom.xml
|
@ -4,13 +4,13 @@
|
|||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>in.wilsonl.hyperbuild</groupId>
|
||||
<artifactId>hyperbuild</artifactId>
|
||||
<groupId>in.wilsonl.minify_html</groupId>
|
||||
<artifactId>minify-html</artifactId>
|
||||
<version>0.2.4</version>
|
||||
|
||||
<name>hyperbuild</name>
|
||||
<name>minify-html</name>
|
||||
<description>Fast allocation-less HTML minifier with smart whitespace handling</description>
|
||||
<url>https://github.com/wilsonzlin/hyperbuild</url>
|
||||
<url>https://github.com/wilsonzlin/minify-html</url>
|
||||
<developers>
|
||||
<developer>
|
||||
<name>Wilson Lin</name>
|
||||
|
@ -28,9 +28,9 @@
|
|||
</licenses>
|
||||
|
||||
<scm>
|
||||
<url>https://github.com/wilsonzlin/hyperbuild</url>
|
||||
<connection>scm:git:git@github.com:wilsonzlin/hyperbuild.git</connection>
|
||||
<developerConnection>scm:git:git@github.com:wilsonzlin/hyperbuild.git</developerConnection>
|
||||
<url>https://github.com/wilsonzlin/minify-html</url>
|
||||
<connection>scm:git:git@github.com:wilsonzlin/minify-html.git</connection>
|
||||
<developerConnection>scm:git:git@github.com:wilsonzlin/minify-html.git</developerConnection>
|
||||
</scm>
|
||||
|
||||
<distributionManagement>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package in.wilsonl.hyperbuild;
|
||||
package in.wilsonl.minify_html;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
|
@ -13,7 +13,7 @@ import static java.lang.String.format;
|
|||
* Methods call to native compiled Rust code using JNI.
|
||||
* When this class is loaded, a static initialiser will attempt to load a prebuilt native library for the running operating system and architecture from the JAR. If it cannot, a {@link RuntimeException} will be thrown.
|
||||
*/
|
||||
public class Hyperbuild {
|
||||
public class MinifyHtml {
|
||||
static {
|
||||
String osName = System.getProperty("os.name").toLowerCase();
|
||||
String osArch = System.getProperty("os.arch").toLowerCase();
|
||||
|
@ -33,8 +33,8 @@ public class Hyperbuild {
|
|||
|
||||
String nativeLibFile = format("/%s-%s.nativelib", nativeLibNameOs, nativeLibNameArch);
|
||||
|
||||
try (InputStream is = Hyperbuild.class.getResourceAsStream(nativeLibFile)) {
|
||||
File temp = File.createTempFile("hyperbuild-java-nativelib", nativeLibFile.substring(1));
|
||||
try (InputStream is = MinifyHtml.class.getResourceAsStream(nativeLibFile)) {
|
||||
File temp = File.createTempFile("minify-html-java-nativelib", nativeLibFile.substring(1));
|
||||
temp.deleteOnExit();
|
||||
Files.copy(is, temp.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
System.load(temp.getAbsolutePath());
|
||||
|
@ -43,7 +43,7 @@ public class Hyperbuild {
|
|||
}
|
||||
}
|
||||
|
||||
private Hyperbuild() {
|
||||
private MinifyHtml() {
|
||||
}
|
||||
|
||||
/**
|
|
@ -1,4 +1,4 @@
|
|||
use hyperbuild::{hyperbuild, Cfg};
|
||||
use minify_html::{in_place as minify_html_native, Cfg};
|
||||
use jni::JNIEnv;
|
||||
use jni::objects::{JByteBuffer, JClass, JObject, JString};
|
||||
use jni::sys::{jint, jstring};
|
||||
|
@ -14,7 +14,7 @@ fn build_cfg(
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_in_wilsonl_hyperbuild_Hyperbuild_minifyInPlace(
|
||||
pub extern "system" fn Java_in_wilsonl_minify_1html_MinifyHtml_minifyInPlace(
|
||||
env: JNIEnv,
|
||||
_class: JClass,
|
||||
input: JByteBuffer,
|
||||
|
@ -29,11 +29,11 @@ pub extern "system" fn Java_in_wilsonl_hyperbuild_Hyperbuild_minifyInPlace(
|
|||
}
|
||||
};
|
||||
|
||||
(match hyperbuild(source, &build_cfg(&env, &cfg)) {
|
||||
(match minify_html_native(source, &build_cfg(&env, &cfg)) {
|
||||
Ok(out_len) => out_len,
|
||||
Err((err, pos)) => {
|
||||
env.throw_new(
|
||||
"in/wilsonl/hyperbuild/HyperbuildException",
|
||||
"in/wilsonl/minify_html/MinifyHtml$SyntaxException",
|
||||
format!("{} [Character {}]", err.message(), pos),
|
||||
).unwrap();
|
||||
0
|
||||
|
@ -42,7 +42,7 @@ pub extern "system" fn Java_in_wilsonl_hyperbuild_Hyperbuild_minifyInPlace(
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_in_wilsonl_hyperbuild_Hyperbuild_minify(
|
||||
pub extern "system" fn Java_in_wilsonl_minify_1html_MinifyHtml_minify(
|
||||
env: JNIEnv,
|
||||
_class: JClass,
|
||||
input: JString,
|
||||
|
@ -52,11 +52,11 @@ pub extern "system" fn Java_in_wilsonl_hyperbuild_Hyperbuild_minify(
|
|||
let source: String = env.get_string(input).unwrap().into();
|
||||
let mut code = source.into_bytes();
|
||||
|
||||
match hyperbuild(&mut code, &build_cfg(&env, &cfg)) {
|
||||
match minify_html_native(&mut code, &build_cfg(&env, &cfg)) {
|
||||
Ok(out_len) => env.new_string(unsafe { from_utf8_unchecked(&code[0..out_len]) }).unwrap().into_inner(),
|
||||
Err((err, pos)) => {
|
||||
env.throw_new(
|
||||
"in/wilsonl/hyperbuild/Hyperbuild$SyntaxException",
|
||||
"in/wilsonl/minify_html/MinifyHtml$SyntaxException",
|
||||
format!("{} [Character {}]", err.message(), pos),
|
||||
).unwrap();
|
||||
JObject::null().into_inner()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "hyperbuild-nodejs"
|
||||
publish = false
|
||||
name = "minify-html-nodejs"
|
||||
version = "0.2.4"
|
||||
authors = ["Wilson Lin <code@wilsonl.in>"]
|
||||
license = "MIT"
|
||||
|
@ -9,12 +9,12 @@ exclude = ["artifacts.json", "index.node"]
|
|||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
name = "hyperbuild_nodejs_lib"
|
||||
name = "minify_html_nodejs_lib"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[build-dependencies]
|
||||
neon-build = "0.4.0"
|
||||
|
||||
[dependencies]
|
||||
hyperbuild = { path = "../..", features = ["js-esbuild"] }
|
||||
minify-html = { path = "../..", features = ["js-esbuild"] }
|
||||
neon = "0.4.0"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use neon::prelude::*;
|
||||
use hyperbuild::{Cfg, hyperbuild};
|
||||
use minify_html::{Cfg, in_place};
|
||||
|
||||
fn minify(mut cx: FunctionContext) -> JsResult<JsNumber> {
|
||||
let mut buffer = cx.argument::<JsBuffer>(0)?;
|
||||
|
@ -7,7 +7,7 @@ fn minify(mut cx: FunctionContext) -> JsResult<JsNumber> {
|
|||
let cfg = Cfg {
|
||||
minify_js: cfg_obj.get(&mut cx, "minifyJs")?.downcast::<JsBoolean>().or_throw(&mut cx)?.value(),
|
||||
};
|
||||
match cx.borrow_mut(&mut buffer, |code| hyperbuild(code.as_mut_slice::<u8>(), &cfg)) {
|
||||
match cx.borrow_mut(&mut buffer, |code| in_place(code.as_mut_slice::<u8>(), &cfg)) {
|
||||
Ok(out_len) => Ok(cx.number(out_len as f64)),
|
||||
Err((err, pos)) => cx.throw_error(format!("{} [Character {}]", err.message(), pos)),
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "hyperbuild",
|
||||
"name": "@minify-html/js-esbuild",
|
||||
"version": "0.2.4",
|
||||
"description": "Fast allocation-less HTML minifier with smart whitespace handling",
|
||||
"main": "dist/index.js",
|
||||
|
@ -15,7 +15,7 @@
|
|||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/wilsonzlin/hyperbuild.git"
|
||||
"url": "git+https://github.com/wilsonzlin/minify-html.git"
|
||||
},
|
||||
"author": {
|
||||
"email": "npm@wilsonl.in",
|
||||
|
@ -24,9 +24,9 @@
|
|||
},
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/wilsonzlin/hyperbuild/issues"
|
||||
"url": "https://github.com/wilsonzlin/minify-html/issues"
|
||||
},
|
||||
"homepage": "https://github.com/wilsonzlin/hyperbuild#readme",
|
||||
"homepage": "https://github.com/wilsonzlin/minify-html#readme",
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.0.22",
|
||||
"neon-cli": "^0.4.0",
|
||||
|
|
|
@ -33,7 +33,7 @@ const downloadNativeBinary = async () => {
|
|||
for (let attempt = 0; ; attempt++) {
|
||||
let binary;
|
||||
try {
|
||||
binary = await fetch(`https://wilsonl.in/hyperbuild/bin/nodejs/${pkg.version}/${binaryName}.node`);
|
||||
binary = await fetch(`https://wilsonl.in/minify-html/bin/nodejs/${pkg.version}/${binaryName}.node`);
|
||||
} catch (e) {
|
||||
if (e instanceof StatusError && attempt < MAX_DOWNLOAD_ATTEMPTS) {
|
||||
await wait(Math.random() * 2500 + 500);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const hyperbuild = require(`./native.node`);
|
||||
const native = require(`./native.node`);
|
||||
|
||||
export type Configuration = {
|
||||
minifyJs: boolean;
|
||||
|
@ -6,12 +6,12 @@ export type Configuration = {
|
|||
|
||||
export const minify = (code: string, cfg: Configuration): string => {
|
||||
const buf = Buffer.from(code);
|
||||
const len = hyperbuild.minify(buf, cfg);
|
||||
const len = native.minify(buf, cfg);
|
||||
return buf.slice(0, len).toString();
|
||||
};
|
||||
|
||||
export const minifyInPlace = (buf: Buffer, cfg: Configuration): Buffer => {
|
||||
const len = hyperbuild.minify(buf, cfg);
|
||||
const len = native.minify(buf, cfg);
|
||||
// This does not do a copy.
|
||||
return buf.slice(0, len);
|
||||
};
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
|
||||
For legacy reasons, HTML comments can appear within a script tag, and if there is a `<script` in it, the first following `</script>` within the comment does **not** close the main script tag.
|
||||
|
||||
hyperbuild does **not** do this special handling, as it adds complexity and slows down performance dramatically, for a legacy feature that is not recommended to be (and almost never) used.
|
||||
minify-html does **not** do this special handling, as it adds complexity and slows down performance dramatically, for a legacy feature that is not recommended to be (and almost never) used.
|
||||
|
||||
See https://www.w3.org/TR/html52/syntax.html#script-data-state for more details.
|
||||
|
||||
Commit [20c59769](https://github.com/wilsonzlin/hyperbuild/commit/20c59769fea6bfb8a9d5ecea47d979dc9b1dcda5) removed support.
|
||||
Commit [20c59769](https://github.com/wilsonzlin/minify-html/commit/20c59769fea6bfb8a9d5ecea47d979dc9b1dcda5) removed support.
|
||||
|
||||
## States and transitions
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
[package]
|
||||
publish = false
|
||||
name = "minify-html"
|
||||
name = "minify_html"
|
||||
description = "Fast allocation-less HTML minifier with smart whitespace handling"
|
||||
license = "MIT"
|
||||
homepage = "https://github.com/wilsonzlin/hyperbuild"
|
||||
homepage = "https://github.com/wilsonzlin/minify-html"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/wilsonzlin/hyperbuild.git"
|
||||
repository = "https://github.com/wilsonzlin/minify-html.git"
|
||||
version = "0.2.4"
|
||||
authors = ["Wilson Lin <code@wilsonl.in>"]
|
||||
edition = "2018"
|
||||
|
@ -15,7 +15,7 @@ name = "minify_html"
|
|||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
hyperbuild = { path = "..", features = ["js-esbuild"] }
|
||||
minify-html = { path = "..", features = ["js-esbuild"] }
|
||||
[dependencies.pyo3]
|
||||
version = "0.11.1"
|
||||
features = ["extension-module"]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use hyperbuild::{Cfg, hyperbuild as hyperbuild_native};
|
||||
use minify_html::{Cfg, in_place as minify_html_native};
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::exceptions::SyntaxError;
|
||||
use pyo3::wrap_pyfunction;
|
||||
|
@ -7,7 +7,7 @@ use std::str::from_utf8_unchecked;
|
|||
#[pyfunction(py_args="*", minify_js="false")]
|
||||
fn minify(code: String, minify_js: bool) -> PyResult<String> {
|
||||
let mut code = code.into_bytes();
|
||||
match hyperbuild_native(&mut code, &Cfg {
|
||||
match minify_html_native(&mut code, &Cfg {
|
||||
minify_js,
|
||||
}) {
|
||||
Ok(out_len) => Ok(unsafe { from_utf8_unchecked(&code[0..out_len]).to_string() }),
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
[package]
|
||||
name = "hyperbuild-ruby"
|
||||
publish = false
|
||||
name = "minify-html-ruby"
|
||||
version = "0.2.4"
|
||||
authors = ["Wilson Lin <code@wilsonl.in>"]
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
name = "hyperbuild_ruby_lib"
|
||||
name = "minify_html_ruby_lib"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
hyperbuild = { path = "..", features = ["js-esbuild"] }
|
||||
minify-html = { path = "..", features = ["js-esbuild"] }
|
||||
rutie = "0.7.0"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
require 'fiddle'
|
||||
|
||||
class HyperbuildLoader
|
||||
class MinifyHtmlLoader
|
||||
def self.operating_system
|
||||
case RbConfig::CONFIG['host_os'].downcase
|
||||
when /linux|bsd|solaris/ then 'linux'
|
||||
|
@ -15,4 +15,4 @@ class HyperbuildLoader
|
|||
end
|
||||
end
|
||||
|
||||
Fiddle::Function.new(Fiddle.dlopen(HyperbuildLoader.lib_path)['Init_hyperbuild'], [], Fiddle::TYPE_VOIDP).call
|
||||
Fiddle::Function.new(Fiddle.dlopen(MinifyHtmlLoader.lib_path)['Init_minify_html'], [], Fiddle::TYPE_VOIDP).call
|
|
@ -1,14 +1,14 @@
|
|||
require 'rake'
|
||||
|
||||
Gem::Specification.new do |spec|
|
||||
spec.name = "hyperbuild"
|
||||
spec.name = "minify_html"
|
||||
spec.version = "0.2.4"
|
||||
spec.authors = ["Wilson Lin"]
|
||||
spec.email = ["code@wilsonl.in"]
|
||||
spec.license = "MIT"
|
||||
spec.files = FileList["lib/*", "README.md"].to_a
|
||||
spec.summary = "Fast allocation-less HTML minifier with smart whitespace handling"
|
||||
spec.homepage = "https://github.com/wilsonzlin/hyperbuild"
|
||||
spec.homepage = "https://github.com/wilsonzlin/minify_html"
|
||||
|
||||
spec.require_paths = ["lib"]
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
use hyperbuild::{Cfg, hyperbuild as hyperbuild_native};
|
||||
use minify_html::{Cfg, in_place as minify_html_native};
|
||||
use rutie::{Boolean, Class, class, Hash, methods, Object, RString, Symbol, VM};
|
||||
use std::str::from_utf8_unchecked;
|
||||
|
||||
class!(Hyperbuild);
|
||||
class!(MinifyHtml);
|
||||
|
||||
methods! {
|
||||
Hyperbuild,
|
||||
MinifyHtml,
|
||||
_itself,
|
||||
|
||||
fn minify(source: RString, cfg_hash: Hash) -> RString {
|
||||
|
@ -22,7 +22,7 @@ methods! {
|
|||
.map_or(false, |v| v.to_bool()),
|
||||
};
|
||||
|
||||
hyperbuild_native(&mut code, cfg)
|
||||
minify_html_native(&mut code, cfg)
|
||||
.map_err(|(err, pos)| VM::raise(Class::from_existing("SyntaxError"), format!("{} [Character {}]", err.message(), pos).as_str()))
|
||||
.map(|out_len| RString::new_utf8(unsafe { from_utf8_unchecked(&code[0..out_len]) }))
|
||||
.unwrap()
|
||||
|
@ -31,8 +31,8 @@ methods! {
|
|||
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Init_hyperbuild() {
|
||||
Class::new("Hyperbuild", None).define(|itself| {
|
||||
pub extern "C" fn Init_minify_html() {
|
||||
Class::new("MinifyHtml", None).define(|itself| {
|
||||
itself.def_self("minify", minify);
|
||||
});
|
||||
}
|
||||
|
|
12
src/lib.rs
12
src/lib.rs
|
@ -14,7 +14,7 @@ mod spec;
|
|||
mod tests;
|
||||
mod unit;
|
||||
|
||||
pub fn hyperbuild(code: &mut [u8], cfg: &Cfg) -> Result<usize, (ErrorType, usize)> {
|
||||
pub fn in_place(code: &mut [u8], cfg: &Cfg) -> Result<usize, (ErrorType, usize)> {
|
||||
let mut proc = Processor::new(code);
|
||||
match process_content(&mut proc, cfg, Namespace::Html, None) {
|
||||
Ok(()) => Ok(proc.written_len()),
|
||||
|
@ -22,8 +22,8 @@ pub fn hyperbuild(code: &mut [u8], cfg: &Cfg) -> Result<usize, (ErrorType, usize
|
|||
}
|
||||
}
|
||||
|
||||
pub fn hyperbuild_truncate(code: &mut Vec<u8>, cfg: &Cfg) -> Result<(), (ErrorType, usize)> {
|
||||
match hyperbuild(code, cfg) {
|
||||
pub fn truncate(code: &mut Vec<u8>, cfg: &Cfg) -> Result<(), (ErrorType, usize)> {
|
||||
match in_place(code, cfg) {
|
||||
Ok(written_len) => {
|
||||
code.truncate(written_len);
|
||||
Ok(())
|
||||
|
@ -32,9 +32,9 @@ pub fn hyperbuild_truncate(code: &mut Vec<u8>, cfg: &Cfg) -> Result<(), (ErrorTy
|
|||
}
|
||||
}
|
||||
|
||||
pub fn hyperbuild_copy(code: &[u8], cfg: &Cfg) -> Result<Vec<u8>, (ErrorType, usize)> {
|
||||
pub fn copy(code: &[u8], cfg: &Cfg) -> Result<Vec<u8>, (ErrorType, usize)> {
|
||||
let mut copy = code.to_vec();
|
||||
match hyperbuild_truncate(&mut copy, cfg) {
|
||||
match truncate(&mut copy, cfg) {
|
||||
Ok(()) => Ok(copy),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ pub struct FriendlyError {
|
|||
pub code_context: String,
|
||||
}
|
||||
|
||||
pub fn hyperbuild_friendly_error(code: &mut [u8], cfg: &Cfg) -> Result<usize, FriendlyError> {
|
||||
pub fn with_friendly_error(code: &mut [u8], cfg: &Cfg) -> Result<usize, FriendlyError> {
|
||||
let mut proc = Processor::new(code);
|
||||
match process_content(&mut proc, cfg, Namespace::Html, None) {
|
||||
Ok(()) => Ok(proc.written_len()),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#[cfg(test)]
|
||||
fn _eval(src: &'static [u8], expected: &'static [u8], cfg: &super::Cfg) -> () {
|
||||
let mut code = src.to_vec();
|
||||
match super::hyperbuild_friendly_error(&mut code, cfg) {
|
||||
match super::with_friendly_error(&mut code, cfg) {
|
||||
Ok(len) => {
|
||||
assert_eq!(std::str::from_utf8(&code[..len]).unwrap(), std::str::from_utf8(expected).unwrap());
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ fn eval(src: &'static [u8], expected: &'static [u8]) -> () {
|
|||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(feature = "js-esbuild")]
|
||||
fn eval_with_js_min(src: &'static [u8], expected: &'static [u8]) -> () {
|
||||
_eval(src, expected, &super::Cfg {
|
||||
minify_js: true,
|
||||
|
|
|
@ -88,7 +88,7 @@ struct Metrics {
|
|||
|
||||
impl Metrics {
|
||||
fn unquoted_len(&self, raw_val: &[u8]) -> usize {
|
||||
// TODO VERIFY (including control characters and Unicode noncharacters) Browsers seem to simply consider any characters until whitespace part of an unquoted attribute value, despite the spec (and hyperbuild) having more restrictions on allowed characters.
|
||||
// TODO VERIFY (including control characters and Unicode noncharacters) Browsers seem to simply consider any characters until whitespace part of an unquoted attribute value, despite the spec (and minify-html) having more restrictions on allowed characters.
|
||||
// Costs for encoding first and last characters if going with unquoted attribute value.
|
||||
// NOTE: Don't need to consider whitespace for either as all whitespace will be encoded and counts as part of `total_whitespace_encoded_length`.
|
||||
// Need to consider semicolon in any encoded entity in case first char is followed by semicolon or digit.
|
||||
|
@ -326,7 +326,7 @@ pub fn process_attr_value(proc: &mut Processor, should_collapse_and_trim_ws: boo
|
|||
// Numeric entities simply need to check if the following character is a base 10 digit.
|
||||
// The last character encoded as an entity never needs a semicolon:
|
||||
// - For quoted values, it's always a quote and will never be encoded.
|
||||
// - Unquoted attribute values are only ever followed by a space (written by hyperbuild) or the opening tag delimiter ('>').
|
||||
// - Unquoted attribute values are only ever followed by a space (written by minify-html) or the opening tag delimiter ('>').
|
||||
// '>' is always safe as it's only used for any '>' as the last character of an unquoted value.
|
||||
let should_add_semicolon = !is_last && entity_requires_semicolon(optimal_slice[write + 1]);
|
||||
let encoded = ENCODED[&c];
|
||||
|
|
10
version
10
version
|
@ -75,19 +75,19 @@ for (const f of ['Cargo.toml', 'cli/Cargo.toml', 'nodejs/native/Cargo.toml', 'ja
|
|||
}
|
||||
|
||||
for (const f of ['README.md']) {
|
||||
replaceInFile(f, /^(hyperbuild = \{ version = )"\d+\.\d+\.\d+"/m, `$1"${NEW_VERSION}"`);
|
||||
replaceInFile(f, /^(minify-html = \{ version = )"\d+\.\d+\.\d+"/m, `$1"${NEW_VERSION}"`);
|
||||
}
|
||||
|
||||
for (const f of ['README.md']) {
|
||||
replaceInFile(f, /(wilsonl\.in\/hyperbuild\/bin\/)\d+\.\d+\.\d+/g, `$1${NEW_VERSION}`);
|
||||
replaceInFile(f, /(wilsonl\.in\/minify-html\/bin\/)\d+\.\d+\.\d+/g, `$1${NEW_VERSION}`);
|
||||
}
|
||||
|
||||
for (const f of ['README.md', 'bench/README.md']) {
|
||||
replaceInFile(f, /(wilsonl\.in\/hyperbuild\/bench\/)\d+\.\d+\.\d+/g, `$1${NEW_VERSION}`);
|
||||
replaceInFile(f, /(wilsonl\.in\/minify-html\/bench\/)\d+\.\d+\.\d+/g, `$1${NEW_VERSION}`);
|
||||
}
|
||||
|
||||
for (const f of ['java/pom.xml', 'README.md']) {
|
||||
replaceInFile(f, /(<artifactId>hyperbuild<\/artifactId>\s*<version>)\d+\.\d+\.\d+(<\/version>)/, `$1${NEW_VERSION}$2`);
|
||||
replaceInFile(f, /(<artifactId>minify_html<\/artifactId>\s*<version>)\d+\.\d+\.\d+(<\/version>)/, `$1${NEW_VERSION}$2`);
|
||||
}
|
||||
|
||||
for (const f of ['nodejs/package.json']) {
|
||||
|
@ -98,7 +98,7 @@ for (const f of ['python/setup.py']) {
|
|||
replaceInFile(f, /^(\s*version=)"\d+\.\d+\.\d+",\s*$/m, `$1"${NEW_VERSION}",`);
|
||||
}
|
||||
|
||||
for (const f of ['ruby/hyperbuild.gemspec']) {
|
||||
for (const f of ['ruby/minify_html.gemspec']) {
|
||||
replaceInFile(f, /^(\s*spec\.version\s*=\s*)"\d+\.\d+\.\d+"\s*$/m, `$1"${NEW_VERSION}"`);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue