Create structure for Node.js node-gyp native module

This commit is contained in:
Wilson Lin 2020-07-24 14:20:24 +10:00
parent e21d663856
commit 6143b852e1
7 changed files with 104 additions and 29 deletions

9
nodejs/.gitignore vendored
View File

@ -1,7 +1,6 @@
/dist/*
/native/target
/native/index.node
/native/artifacts.json
/build/
/index.node
/native/Cargo.lock
/native/target
node_modules/
package-lock.json
/package-lock.json

8
nodejs/binding.c Normal file
View File

@ -0,0 +1,8 @@
#include <stdlib.h>
#define NAPI_VERSION 4
#include <node_api.h>
typedef struct Cfg Cfg;
#include <minify_html_ffi.h>

24
nodejs/binding.gyp Normal file
View File

@ -0,0 +1,24 @@
{
"targets": [
{
"target_name": "index",
"sources": [
"binding.c"
],
"include_dirs": [
"native/target/release/",
],
"actions": [
{
"action_name": "build minify-html-ffi static library",
"inputs": ["native/src/lib.rs"],
"outputs": ["native/target/release/libminify_html_ffi.a", "native/target/release/minify_html_ffi.h"],
"action": ["cargo", "build", "--manifest-path", "native/Cargo.toml", "--release"],
},
],
"libraries": [
"../native/target/release/libminify_html_ffi.a",
],
},
],
}

View File

@ -1,20 +1,18 @@
[package]
publish = false
name = "minify-html-nodejs"
name = "minify-html-ffi"
version = "0.2.6"
authors = ["Wilson Lin <code@wilsonl.in>"]
license = "MIT"
build = "build.rs"
exclude = ["artifacts.json", "index.node"]
edition = "2018"
[lib]
name = "minify_html_nodejs_lib"
crate-type = ["cdylib"]
name = "minify_html_ffi"
crate-type = ["staticlib"]
[build-dependencies]
neon-build = "0.4.0"
cbindgen = "0.14"
[dependencies]
libc = "0.2"
minify-html = { path = "../..", features = ["js-esbuild"] }
neon = "0.4.0"

View File

@ -1,3 +1,13 @@
use std::env;
fn main() {
neon_build::setup();
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));
}

View File

@ -1,18 +1,54 @@
use neon::prelude::*;
use std::{mem, ptr, slice};
use minify_html::{Cfg, Error, in_place};
fn minify(mut cx: FunctionContext) -> JsResult<JsNumber> {
let mut buffer = cx.argument::<JsBuffer>(0)?;
let cfg_obj = cx.argument::<JsObject>(1)?;
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| in_place(code.as_mut_slice::<u8>(), &cfg)) {
Ok(out_len) => Ok(cx.number(out_len as f64)),
Err(Error { error_type, position }) => cx.throw_error(format!("{} [Character {}]", error_type.message(), position)),
}
#[no_mangle]
pub extern "C" fn ffi_create_cfg(minify_js: bool) -> *mut Cfg {
Box::into_raw(Box::new(Cfg {
minify_js,
}))
}
register_module!(mut cx, {
cx.export_function("minify", minify)
});
#[no_mangle]
pub extern "C" fn ffi_drop_cfg(cfg: *mut Cfg) -> () {
unsafe {
Box::from_raw(cfg);
};
}
#[repr(C)]
pub struct ffi_error {
message: *mut u8,
message_len: usize,
position: usize,
}
#[no_mangle]
pub extern "C" fn ffi_drop_ffi_error(ffi_error_ptr: *mut ffi_error) -> () {
unsafe {
let ffi_error = Box::from_raw(ffi_error_ptr);
let _ = String::from_raw_parts(ffi_error.message, ffi_error.message_len, ffi_error.message_len);
};
}
#[no_mangle]
pub extern "C" fn ffi_in_place(code: *mut u8, code_len: usize, cfg: *const Cfg, out_min_len: *mut usize) -> *const ffi_error {
let code_slice = unsafe { slice::from_raw_parts_mut(code, code_len) };
match in_place(code_slice, unsafe { &*cfg }) {
Ok(min_len) => unsafe {
*out_min_len = min_len;
ptr::null()
}
Err(Error { error_type, position }) => {
let mut msg = error_type.message();
msg.shrink_to_fit();
let msg_ptr = msg.as_mut_ptr();
let msg_len = msg.len();
mem::forget(msg);
Box::into_raw(Box::new(ffi_error {
message: msg_ptr,
message_len: msg_len,
position,
}))
}
}
}

View File

@ -7,7 +7,7 @@
"postinstall.js"
],
"scripts": {
"build": "neon build --release && mv native/index.node index.node",
"build": "node-gyp build && mv build/Release/index.node index.node",
"postinstall": "node postinstall.js"
},
"repository": {
@ -25,7 +25,7 @@
},
"homepage": "https://github.com/wilsonzlin/minify-html#readme",
"devDependencies": {
"neon-cli": "^0.4.0"
"node-gyp": "^7.0.0"
},
"keywords": [
"build",