Implement support for WASM and Deno
This commit is contained in:
parent
cc0d78b9da
commit
3e20d50eeb
|
@ -6,7 +6,6 @@ This folder contains various GitHub Actions that are run upon every new version
|
|||
|
||||
GitHub currently doesn't provide ARM64 macOS and Linux runners, so we run self-hosted versions. Jobs run on self-hosted machines aren't isolated (e.g. files created during a job run persist on the real filesystem), and most @actions/* don't have ARM64 builds yet, so self-hosted machines should have tools preinstalled before starting the GitHub Actions runner. These include:
|
||||
|
||||
- Go
|
||||
- Rust
|
||||
- Node.js
|
||||
- Python/pyenv
|
||||
|
|
|
@ -24,11 +24,6 @@ jobs:
|
|||
profile: minimal
|
||||
default: true
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: '^1.14.0'
|
||||
|
||||
- name: Run prebuild steps
|
||||
shell: bash
|
||||
run: bash ./prebuild.sh
|
||||
|
|
|
@ -54,16 +54,6 @@ jobs:
|
|||
profile: minimal
|
||||
default: true
|
||||
|
||||
- name: Set up GCC (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
run: .\.github\workflows\gcc.ps1
|
||||
|
||||
- name: Set up Go
|
||||
if: runner.name != 'macos-arm64'
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: '^1.14.0'
|
||||
|
||||
- name: Run prebuild steps
|
||||
shell: bash
|
||||
run: bash ./prebuild.sh
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
name: Build and publish Deno package
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-18.04
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
||||
- name: Get version
|
||||
id: version
|
||||
shell: bash
|
||||
run: echo ::set-output name=VERSION::"$([[ "$GITHUB_REF" == refs/tags/v* ]] && echo ${GITHUB_REF#refs/tags/v} || echo '0.0.0')"
|
||||
|
||||
- name: Set up Rust
|
||||
if: runner.name != 'macos-arm64'
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
profile: minimal
|
||||
default: true
|
||||
|
||||
- name: Run prebuild steps
|
||||
shell: bash
|
||||
run: bash ./prebuild.sh
|
||||
|
||||
- name: Install wasm-pack
|
||||
working-directory: ./wasm
|
||||
shell: bash
|
||||
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||
|
||||
- name: Build native module
|
||||
working-directory: ./wasm
|
||||
shell: bash
|
||||
run: TARGET=web ./build
|
||||
|
||||
- name: Install B2 CLI
|
||||
run: |
|
||||
wget -O b2 https://github.com/Backblaze/B2_Command_Line_Tool/releases/latest/download/b2-linux
|
||||
chmod +x b2
|
||||
|
||||
- name: Upload to B2
|
||||
run: |
|
||||
./b2 authorize-account ${{ secrets.CICD_CLI_B2_KEY_ID }} ${{ secrets.CICD_CLI_B2_APPLICATION_KEY }}
|
||||
./b2 sync --compareVersions size --delete wasm/pkg/ b2://${{ secrets.CICD_CLI_B2_BUCKET_NAME }}/minify-html/deno/${{ steps.version.outputs.VERSION }}/
|
|
@ -16,11 +16,6 @@ jobs:
|
|||
profile: minimal
|
||||
default: true
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: '^1.14.0'
|
||||
|
||||
- name: Run prebuild steps
|
||||
shell: bash
|
||||
run: bash ./prebuild.sh
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
Invoke-WebRequest 'https://wilsonl.in/TDM-GCC-64.7z' -OutFile C:\gcc.7z
|
||||
7z x C:\gcc.7z -oC:\
|
||||
$oldpath = (Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH).Path
|
||||
Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH -Value "C:\TDM-GCC-64\bin;$oldpath"
|
|
@ -32,15 +32,6 @@ jobs:
|
|||
profile: minimal
|
||||
default: true
|
||||
|
||||
- name: Set up GCC (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
run: .\.github\workflows\gcc.ps1
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: '^1.14.0'
|
||||
|
||||
- name: Run prebuild steps
|
||||
shell: bash
|
||||
run: bash ./prebuild.sh
|
||||
|
@ -54,7 +45,7 @@ jobs:
|
|||
with:
|
||||
name: ${{ matrix.ARCH }}
|
||||
path: ./java/target/rust/release/${{ matrix.FILE }}
|
||||
|
||||
|
||||
package:
|
||||
runs-on: ubuntu-18.04
|
||||
needs: build
|
||||
|
|
|
@ -34,16 +34,6 @@ jobs:
|
|||
profile: minimal
|
||||
default: true
|
||||
|
||||
- name: Set up GCC (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
run: .\.github\workflows\gcc.ps1
|
||||
|
||||
- name: Set up Go
|
||||
if: runner.name != 'macos-arm64'
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: '^1.14.0'
|
||||
|
||||
- name: Run prebuild steps
|
||||
shell: bash
|
||||
run: bash ./prebuild.sh
|
||||
|
|
|
@ -44,16 +44,6 @@ jobs:
|
|||
profile: minimal
|
||||
default: true
|
||||
|
||||
- name: Set up GCC (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
run: .\.github\workflows\gcc.ps1
|
||||
|
||||
- name: Set up Go
|
||||
if: runner.name != 'macos-arm64'
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: '^1.14.0'
|
||||
|
||||
- name: Run prebuild steps
|
||||
shell: bash
|
||||
run: bash ./prebuild.sh
|
||||
|
|
|
@ -65,15 +65,6 @@ jobs:
|
|||
profile: minimal
|
||||
default: true
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: '^1.14.0'
|
||||
|
||||
- name: Set up GCC (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
run: .\.github\workflows\gcc.ps1
|
||||
|
||||
- name: Run prebuild steps
|
||||
shell: bash
|
||||
run: bash ./prebuild.sh
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
name: Build and publish WASM package
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-18.04
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
||||
- name: Get version
|
||||
id: version
|
||||
shell: bash
|
||||
run: echo ::set-output name=VERSION::"$([[ "$GITHUB_REF" == refs/tags/v* ]] && echo ${GITHUB_REF#refs/tags/v} || echo '0.0.0')"
|
||||
|
||||
- name: Set up Rust
|
||||
if: runner.name != 'macos-arm64'
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
profile: minimal
|
||||
default: true
|
||||
|
||||
- name: Run prebuild steps
|
||||
shell: bash
|
||||
run: bash ./prebuild.sh
|
||||
|
||||
- name: Install wasm-pack
|
||||
working-directory: ./wasm
|
||||
shell: bash
|
||||
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||
|
||||
- name: Build native module
|
||||
working-directory: ./wasm
|
||||
shell: bash
|
||||
run: TARGET=bundle ./build
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@master
|
||||
with:
|
||||
node-version: 17.x
|
||||
|
||||
- name: Pack and publish package
|
||||
working-directory: ./wasm/pkg
|
||||
run: |
|
||||
cat << 'EOF' > .npmrc
|
||||
package-lock=false
|
||||
//registry.npmjs.org/:_authToken=${{ secrets.NPM_AUTH_TOKEN }}
|
||||
EOF
|
||||
# npm refuses to work with symlinks.
|
||||
cp ../../README.md .
|
||||
if [[ "${{ steps.version.outputs.VERSION }}" != "0.0.0" ]]; then
|
||||
npm publish --access public
|
||||
fi
|
52
README.md
52
README.md
|
@ -1,11 +1,13 @@
|
|||
<h1>
|
||||
minify-html
|
||||
<img width="24" src="https://wilsonl.in/minify-html/icon/cli.png">
|
||||
<img width="24" src="https://wilsonl.in/minify-html/icon/deno.png">
|
||||
<img width="24" src="https://wilsonl.in/minify-html/icon/java.png">
|
||||
<img width="24" src="https://wilsonl.in/minify-html/icon/nodejs.png">
|
||||
<img width="24" src="https://wilsonl.in/minify-html/icon/python.png">
|
||||
<img width="24" src="https://wilsonl.in/minify-html/icon/ruby.png">
|
||||
<img width="24" src="https://wilsonl.in/minify-html/icon/rust.png">
|
||||
<img width="24" src="https://wilsonl.in/minify-html/icon/wasm.png">
|
||||
</h1>
|
||||
|
||||
A Rust HTML minifier meticulously optimised for speed and effectiveness, with bindings for other languages.
|
||||
|
@ -64,6 +66,30 @@ Check out the [docs](https://docs.rs/minify-html) for API and usage examples.
|
|||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><img width="24" src="https://wilsonl.in/minify-html/icon/deno.png"> <strong>Deno</strong></summary>
|
||||
|
||||
- Package: [https://wilsonl.in/minify-html/deno/0.8.1/index.js]
|
||||
- Binding: [WASM](https://webassembly.org/)
|
||||
- Platforms: All
|
||||
|
||||
### Use
|
||||
|
||||
```ts
|
||||
import init, {minify} from "https://wilsonl.in/minify-html/deno/0.8.1/index.js";
|
||||
|
||||
const encoder = new TextEncoder();
|
||||
const decoder = new TextDecoder();
|
||||
|
||||
await init();
|
||||
|
||||
const minified = decoder.decode(minify(encoder.encode("<p> Hello, world! </p>"), { keep_spaces_between_attributes: true, keep_comments: true }));
|
||||
```
|
||||
|
||||
All [`Cfg` fields](https://docs.rs/minify-html/latest/minify_html/struct.Cfg.html) are available as snake_case properties on the object provided as the second argument; if any are not set, they default to `false`.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><img width="24" src="https://wilsonl.in/minify-html/icon/nodejs.png"> <strong>Node.js</strong></summary>
|
||||
|
||||
|
@ -183,6 +209,32 @@ All [`Cfg` fields](https://docs.rs/minify-html/latest/minify_html/struct.Cfg.htm
|
|||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><img width="24" src="https://wilsonl.in/minify-html/icon/wasm.png"> <strong>WASM</strong></summary>
|
||||
|
||||
- Package: [@minify-html/wasm](https://npmjs.org/package/@minify-html/wasm)
|
||||
- Binding: [WASM](https://webassembly.org/)
|
||||
- Platforms: All
|
||||
|
||||
A bundler may be required to use the WebAssembly module, see [this](https://rustwasm.github.io/wasm-bindgen/reference/deployment.html#bundlers) for more details.
|
||||
|
||||
### Use
|
||||
|
||||
```ts
|
||||
import init, {minify} from "https://wilsonl.in/minify-html/deno/0.8.1/index.js";
|
||||
|
||||
const encoder = new TextEncoder();
|
||||
const decoder = new TextDecoder();
|
||||
|
||||
await init();
|
||||
|
||||
const minified = decoder.decode(minify(encoder.encode("<p> Hello, world! </p>"), { keep_spaces_between_attributes: true, keep_comments: true }));
|
||||
```
|
||||
|
||||
All [`Cfg` fields](https://docs.rs/minify-html/latest/minify_html/struct.Cfg.html) are available as snake_case properties on the object provided as the second argument; if any are not set, they default to `false`.
|
||||
|
||||
</details>
|
||||
|
||||
## Minification
|
||||
|
||||
Note that some of the minification done can result in HTML that will not pass validation, but remain interpreted and rendered correctly by the browser; essentially, the laxness of the browser is taken advantage of for better minification. To prevent this, refer to these configuration options:
|
||||
|
|
1
format
1
format
|
@ -20,6 +20,7 @@ for dir in \
|
|||
ruby \
|
||||
rust/main \
|
||||
rust/onepass \
|
||||
wasm \
|
||||
; do
|
||||
pushd "$dir" >/dev/null
|
||||
cargo fmt
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
3
version
3
version
|
@ -105,6 +105,7 @@ for (const f of [
|
|||
"java/Cargo.toml",
|
||||
"python/Cargo.toml",
|
||||
"ruby/Cargo.toml",
|
||||
"wasm/Cargo.toml",
|
||||
]) {
|
||||
replaceInFile(
|
||||
f,
|
||||
|
@ -124,7 +125,7 @@ for (const f of ["README.md"]) {
|
|||
for (const f of ["README.md"]) {
|
||||
replaceInFile(
|
||||
f,
|
||||
/(wilsonl\.in\/minify-html\/bin\/)\d+\.\d+\.\d+/g,
|
||||
/(wilsonl\.in\/minify-html\/(?:bin|deno)\/)\d+\.\d+\.\d+/g,
|
||||
`$1${NEW_VERSION}`
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
/target
|
||||
**/*.rs.bk
|
||||
Cargo.lock
|
||||
bin/
|
||||
pkg/
|
||||
wasm-pack.log
|
|
@ -0,0 +1,37 @@
|
|||
[package]
|
||||
name = "index"
|
||||
publish = false
|
||||
version = "0.8.1"
|
||||
authors = ["Wilson Lin <code@wilsonl.in>"]
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[features]
|
||||
default = ["console_error_panic_hook"]
|
||||
|
||||
[dependencies]
|
||||
js-sys = "0.3.58"
|
||||
minify-html = { path = "../rust/main" }
|
||||
wasm-bindgen = "0.2.63"
|
||||
|
||||
# The `console_error_panic_hook` crate provides better debugging of panics by
|
||||
# logging them with `console.error`. This is great for development, but requires
|
||||
# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
|
||||
# code size when deploying.
|
||||
console_error_panic_hook = { version = "0.1.6", optional = true }
|
||||
|
||||
# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size
|
||||
# compared to the default allocator's ~10K. It is slower than the default
|
||||
# allocator, however.
|
||||
#
|
||||
# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now.
|
||||
wee_alloc = { version = "0.4.5", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
wasm-bindgen-test = "0.3.13"
|
||||
|
||||
[profile.release]
|
||||
# Tell `rustc` to optimize for small code size.
|
||||
opt-level = "s"
|
|
@ -0,0 +1,22 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -Eeuxo pipefail
|
||||
|
||||
pushd "$(dirname "$0")" >/dev/null
|
||||
|
||||
target="${TARGET:-bundler}"
|
||||
|
||||
rm -rf pkg
|
||||
wasm-pack build --target "$target"
|
||||
pushd pkg
|
||||
# `bundler` is for WASM/npm, `web` is for Deno.
|
||||
if [[ "$target" = "bundler" ]]; then
|
||||
# Use -i.tmp to support macOS and Linux.
|
||||
sed -i.tmp -E 's%"name": "index"%"name": "@minify-html/'$pkg_suffix'"%' package.json
|
||||
rm package.json.tmp .gitignore
|
||||
elif [[ "$target" = "web" ]]; then
|
||||
rm package.json .gitignore
|
||||
fi
|
||||
popd
|
||||
|
||||
popd >/dev/null
|
|
@ -0,0 +1,39 @@
|
|||
mod utils;
|
||||
|
||||
use js_sys::Reflect;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
|
||||
// allocator.
|
||||
#[cfg(feature = "wee_alloc")]
|
||||
#[global_allocator]
|
||||
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
||||
|
||||
macro_rules! get_prop {
|
||||
($cfg:expr, $x:literal) => {
|
||||
Reflect::get($cfg, &JsValue::from_str($x))
|
||||
.ok()
|
||||
.and_then(|p| p.as_bool())
|
||||
.unwrap_or(false)
|
||||
};
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn minify(code: &[u8], cfg: &JsValue) -> Vec<u8> {
|
||||
let cfg = minify_html::Cfg {
|
||||
do_not_minify_doctype: get_prop!(cfg, "do_not_minify_doctype"),
|
||||
ensure_spec_compliant_unquoted_attribute_values: get_prop!(
|
||||
cfg,
|
||||
"ensure_spec_compliant_unquoted_attribute_values"
|
||||
),
|
||||
keep_closing_tags: get_prop!(cfg, "keep_closing_tags"),
|
||||
keep_html_and_head_opening_tags: get_prop!(cfg, "keep_html_and_head_opening_tags"),
|
||||
keep_spaces_between_attributes: get_prop!(cfg, "keep_spaces_between_attributes"),
|
||||
keep_comments: get_prop!(cfg, "keep_comments"),
|
||||
minify_css: get_prop!(cfg, "minify_css"),
|
||||
minify_js: get_prop!(cfg, "minify_js"),
|
||||
remove_bangs: get_prop!(cfg, "remove_bangs"),
|
||||
remove_processing_instructions: get_prop!(cfg, "remove_processing_instructions"),
|
||||
};
|
||||
minify_html::minify(code, &cfg)
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
pub fn set_panic_hook() {
|
||||
// When the `console_error_panic_hook` feature is enabled, we can call the
|
||||
// `set_panic_hook` function at least once during initialization, and then
|
||||
// we will get better error messages if our code ever panics.
|
||||
//
|
||||
// For more details see
|
||||
// https://github.com/rustwasm/console_error_panic_hook#readme
|
||||
#[cfg(feature = "console_error_panic_hook")]
|
||||
console_error_panic_hook::set_once();
|
||||
}
|
Loading…
Reference in New Issue