diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml
index e593bc1..0dec6f9 100644
--- a/.github/workflows/nodejs.yml
+++ b/.github/workflows/nodejs.yml
@@ -54,18 +54,17 @@ jobs:
shell: bash
run: |
npm install
- npm run build
- node compress.js
+ npm run build-release
echo ::set-output name=BINARY_NAME::"$(node -e 'console.log([process.platform, process.arch].join("__"))')"
- name: Upload to B2
uses: wilsonzlin/b2-upload-action@v1.0.0
with:
bucket: ${{ secrets.CICD_CLI_B2_BUCKET_NAME }}
- uploadKey: minify-html/bin/nodejs/${{ steps.version.outputs.VERSION }}/${{ matrix.feature }}/${{ steps.module.outputs.BINARY_NAME }}.node.gz
+ uploadKey: minify-html/bin/nodejs/${{ steps.version.outputs.VERSION }}/${{ steps.module.outputs.BINARY_NAME }}.node
keyId: ${{ secrets.CICD_CLI_B2_KEY_ID }}
applicationKey: ${{ secrets.CICD_CLI_B2_APPLICATION_KEY }}
- file: ./nodejs/index.node.gz
+ file: ./nodejs/index.node
package:
runs-on: ubuntu-18.04
@@ -87,6 +86,7 @@ jobs:
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
diff --git a/README.md b/README.md
index 7c32147..852afe8 100644
--- a/README.md
+++ b/README.md
@@ -68,7 +68,7 @@ Check out the [docs](https://docs.rs/minify-html) for API and usage examples.
Hello, world!
", cfg); +const minified = minifyHtml.minify("Hello, world!
", { 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 to `createConfiguration`; if any are not set, they default to `false`. +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`. diff --git a/format b/format index eb60258..ba980de 100755 --- a/format +++ b/format @@ -15,7 +15,7 @@ for dir in \ fuzz \ fuzz/process \ java \ - nodejs/native \ + nodejs \ python \ ruby \ rust/main \ diff --git a/nodejs/.cargo/config b/nodejs/.cargo/config deleted file mode 100644 index dcd4c4a..0000000 --- a/nodejs/.cargo/config +++ /dev/null @@ -1,4 +0,0 @@ -[target.x86_64-pc-windows-msvc] -rustflags = ["--print=native-static-libs"] -[target.i686-pc-windows-msvc] -rustflags = ["--print=native-static-libs"] diff --git a/nodejs/.gitignore b/nodejs/.gitignore index 03c3b23..ae4d859 100644 --- a/nodejs/.gitignore +++ b/nodejs/.gitignore @@ -1,6 +1,6 @@ -/build/ +/Cargo.lock /index.node -/native/Cargo.lock -/native/target /package-lock.json +/target/ node_modules/ +npm-debug.log* diff --git a/nodejs/Cargo.toml b/nodejs/Cargo.toml new file mode 100644 index 0000000..af0ade8 --- /dev/null +++ b/nodejs/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "minify-html-node" +publish = false +version = "0.8.1" +description = "Node.js bindings for minify-html" +authors = ["Wilson Lin"]
-license = "MIT"
-edition = "2018"
-
-[lib]
-name = "minify_html_ffi"
-crate-type = ["staticlib"]
-
-[build-dependencies]
-cbindgen = "0.14"
-
-[dependencies]
-libc = "0.2"
-minify-html = { path = "../../rust/main" }
diff --git a/nodejs/native/build.rs b/nodejs/native/build.rs
deleted file mode 100644
index 4c76180..0000000
--- a/nodejs/native/build.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-use std::env;
-
-fn main() {
- let crate_dir = env!("CARGO_MANIFEST_DIR");
- let profile = env::var("PROFILE").unwrap();
-
- cbindgen::Builder::new()
- .with_language(cbindgen::Language::C)
- .with_crate(crate_dir)
- .generate()
- .expect("generate C bindings")
- .write_to_file(format!("target/{}/minify_html_ffi.h", profile));
-}
diff --git a/nodejs/native/src/lib.rs b/nodejs/native/src/lib.rs
deleted file mode 100644
index 89c556b..0000000
--- a/nodejs/native/src/lib.rs
+++ /dev/null
@@ -1,69 +0,0 @@
-use minify_html::{minify, Cfg};
-use std::{mem, slice};
-
-#[no_mangle]
-pub extern "C" fn ffi_create_cfg(
- do_not_minify_doctype: bool,
- ensure_spec_compliant_unquoted_attribute_values: bool,
- keep_closing_tags: bool,
- keep_comments: bool,
- keep_html_and_head_opening_tags: bool,
- keep_spaces_between_attributes: bool,
- minify_css: bool,
- minify_js: bool,
- remove_bangs: bool,
- remove_processing_instructions: bool,
-) -> *const Cfg {
- Box::into_raw(Box::new(Cfg {
- do_not_minify_doctype,
- ensure_spec_compliant_unquoted_attribute_values,
- keep_closing_tags,
- keep_comments,
- keep_html_and_head_opening_tags,
- keep_spaces_between_attributes,
- minify_css,
- minify_js,
- remove_bangs,
- remove_processing_instructions,
- }))
-}
-
-#[no_mangle]
-pub extern "C" fn ffi_drop_cfg(cfg: *const Cfg) -> () {
- unsafe {
- Box::from_raw(cfg as *mut Cfg);
- };
-}
-
-#[repr(C)]
-pub struct ffi_output {
- data: *mut u8,
- len: usize,
- cap: usize,
-}
-
-#[no_mangle]
-pub extern "C" fn ffi_drop_output(ptr: *const ffi_output) -> () {
- unsafe {
- let out = Box::from_raw(ptr as *mut ffi_output);
- Vec::from_raw_parts(out.data, out.len, out.cap);
- };
-}
-
-#[no_mangle]
-// TODO Return result memory (let Node.js manage GC) instead of overwriting source.
-pub extern "C" fn ffi_minify(
- code: *const u8,
- code_len: usize,
- cfg: *const Cfg,
-) -> *const ffi_output {
- let code_slice = unsafe { slice::from_raw_parts(code, code_len) };
- let mut out_code = minify(code_slice, unsafe { &*cfg });
- let res = Box::into_raw(Box::new(ffi_output {
- data: out_code.as_mut_ptr(),
- len: out_code.len(),
- cap: out_code.capacity(),
- }));
- mem::forget(out_code);
- res
-}
diff --git a/nodejs/package.json b/nodejs/package.json
index cf85f29..7503d0b 100644
--- a/nodejs/package.json
+++ b/nodejs/package.json
@@ -4,18 +4,15 @@
"bin": {
"minify-html": "./cli.js"
},
- "version": "0.8.1",
"main": "index.js",
+ "files": ["src/**", "Cargo.toml", "cli.js", "index.d.ts", "index.js", "README.md", "postinstall.js"],
+ "version": "0.8.1",
"types": "index.d.ts",
- "files": [
- "cli.js",
- "postinstall.js",
- "index.d.ts",
- "index.js"
- ],
"scripts": {
- "build": "node-gyp build && shx mv build/Release/index.node index.node",
- "clean": "cd native && cargo clean && cd .. && node-gyp clean && node-gyp configure && shx rm -f index.node",
+ "build": "npm_package_name=minify-html-node cargo-cp-artifact -nc index.node -- cargo build --message-format=json-render-diagnostics",
+ "build-debug": "npm run build --",
+ "build-release": "npm run build -- --release",
+ "clean": "shx rm -rf target index.node",
"postinstall": "node postinstall.js"
},
"repository": {
@@ -37,8 +34,8 @@
"homepage": "https://github.com/wilsonzlin/minify-html#readme",
"devDependencies": {
"@types/node": "^14.6.0",
- "node-gyp": "^7.0.0",
- "shx": "^0.3.2"
+ "cargo-cp-artifact": "^0.1",
+ "shx": "^0.3.4"
},
"keywords": [
"compress",
diff --git a/nodejs/postinstall.js b/nodejs/postinstall.js
index 4f87dec..b83fb22 100644
--- a/nodejs/postinstall.js
+++ b/nodejs/postinstall.js
@@ -1,8 +1,8 @@
const fs = require("fs");
const https = require("https");
const path = require("path");
-const zlib = require("zlib");
const pkg = require("./package.json");
+const cp = require("child_process");
const MAX_DOWNLOAD_ATTEMPTS = 4;
@@ -36,12 +36,10 @@ const downloadNativeBinary = async () => {
let binary;
try {
binary = await fetch(
- `https://wilsonl.in/minify-html/bin/nodejs/${pkg.version}/${
- pkg.name.split("/")[1]
- }/${binaryName}.node.gz`
+ `https://wilsonl.in/minify-html/bin/nodejs/${pkg.version}/${binaryName}.node`
);
} catch (e) {
- if (e instanceof StatusError && attempt < MAX_DOWNLOAD_ATTEMPTS) {
+ if (e instanceof StatusError && e.status !== 404 && attempt < MAX_DOWNLOAD_ATTEMPTS) {
await wait(Math.random() * 2500 + 500);
continue;
}
@@ -60,8 +58,15 @@ if (
downloadNativeBinary().then(
() => console.log(`Downloaded ${pkg.name}`),
(err) => {
- console.error(`Failed to download ${pkg.name}: ${err}`);
- process.exit(1);
+ console.error(`Failed to download ${pkg.name}, will build from source: ${err}`);
+ const out = cp.spawnSync("npm", ["run", "build-release"], {
+ cwd: __dirname,
+ stdio: ["ignore", "inherit", "inherit"],
+ });
+ process.exitCode = out.exitCode;
+ if (out.error) {
+ throw out.error;
+ }
}
);
}
diff --git a/nodejs/src/lib.rs b/nodejs/src/lib.rs
new file mode 100644
index 0000000..c330ca5
--- /dev/null
+++ b/nodejs/src/lib.rs
@@ -0,0 +1,57 @@
+use neon::prelude::*;
+use neon::types::buffer::TypedArray;
+
+fn minify(mut cx: FunctionContext) -> JsResult {
+ let src = cx.argument::(0)?;
+ let opt = cx.argument::(1)?;
+ let cfg = minify_html::Cfg {
+ do_not_minify_doctype: opt
+ .get_opt::(&mut cx, "do_not_minify_doctype")?
+ .map(|v| v.value(&mut cx))
+ .unwrap_or(false),
+ ensure_spec_compliant_unquoted_attribute_values: opt
+ .get_opt::(&mut cx, "ensure_spec_compliant_unquoted_attribute_values")?
+ .map(|v| v.value(&mut cx))
+ .unwrap_or(false),
+ keep_closing_tags: opt
+ .get_opt::(&mut cx, "keep_closing_tags")?
+ .map(|v| v.value(&mut cx))
+ .unwrap_or(false),
+ keep_html_and_head_opening_tags: opt
+ .get_opt::(&mut cx, "keep_html_and_head_opening_tags")?
+ .map(|v| v.value(&mut cx))
+ .unwrap_or(false),
+ keep_spaces_between_attributes: opt
+ .get_opt::(&mut cx, "keep_spaces_between_attributes")?
+ .map(|v| v.value(&mut cx))
+ .unwrap_or(false),
+ keep_comments: opt
+ .get_opt::(&mut cx, "keep_comments")?
+ .map(|v| v.value(&mut cx))
+ .unwrap_or(false),
+ minify_css: opt
+ .get_opt::(&mut cx, "minify_css")?
+ .map(|v| v.value(&mut cx))
+ .unwrap_or(false),
+ minify_js: opt
+ .get_opt::(&mut cx, "minify_js")?
+ .map(|v| v.value(&mut cx))
+ .unwrap_or(false),
+ remove_bangs: opt
+ .get_opt::(&mut cx, "remove_bangs")?
+ .map(|v| v.value(&mut cx))
+ .unwrap_or(false),
+ remove_processing_instructions: opt
+ .get_opt::(&mut cx, "remove_processing_instructions")?
+ .map(|v| v.value(&mut cx))
+ .unwrap_or(false),
+ };
+ let out = minify_html::minify(src.as_slice(&mut cx), &cfg);
+ Ok(JsBuffer::external(&mut cx, out))
+}
+
+#[neon::main]
+fn main(mut cx: ModuleContext) -> NeonResult<()> {
+ cx.export_function("minify", minify)?;
+ Ok(())
+}
diff --git a/version b/version
index aebf9f9..dbd1959 100755
--- a/version
+++ b/version
@@ -101,10 +101,9 @@ for (const f of [
`${RUST_MAIN_DIR}/Cargo.toml`,
`${RUST_ONEPASS_DIR}/Cargo.toml`,
"cli/Cargo.toml",
- "nodejs/native/Cargo.toml",
+ "nodejs/Cargo.toml",
"java/Cargo.toml",
"python/Cargo.toml",
- "python/Cargo.js.toml",
"ruby/Cargo.toml",
]) {
replaceInFile(