Skip to content

Commit

Permalink
feat(bindings): Create a minifier-only package (#7993)
Browse files Browse the repository at this point in the history
  • Loading branch information
kdy1 committed Sep 29, 2023
1 parent 632a63a commit 64d8f4b
Show file tree
Hide file tree
Showing 42 changed files with 7,501 additions and 5 deletions.
13 changes: 12 additions & 1 deletion .github/workflows/publish-node.yml
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,17 @@ jobs:
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: bindings-${{ matrix.settings.target }}
name: |
bindings-${{ matrix.settings.target }}
path: |
swc*
if-no-files-found: error
# Separate step for fail-fast
- name: Upload minifier artifacts
uses: actions/upload-artifact@v3
with:
name: |
minifier-${{ matrix.settings.target }}
path: |
swc*
if-no-files-found: error
Expand Down Expand Up @@ -459,6 +469,7 @@ jobs:
npm config set provenance true
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc
npm publish --access public
(cd ./packages/minifier && npm publish --access public)
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
Expand Down
35 changes: 35 additions & 0 deletions bindings/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion bindings/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
[workspace]
members = ["binding_core_node", "binding_core_wasm", "swc_cli"]
members = [
"binding_core_node",
"binding_core_wasm",
"binding_minifier_node",
"binding_minifier_wasm",
"swc_cli",
]

[profile.release]
# lto = true
Expand Down
44 changes: 44 additions & 0 deletions bindings/binding_minifier_node/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
[package]
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
build = "build.rs"
edition = "2021"
exclude = ["artifacts.json", "index.node"]
license = "Apache-2.0"
name = "binding_minifier_node"
publish = false
version = "0.1.0"

[lib]
bench = false
crate-type = ["cdylib"]

[build-dependencies]
napi-build = { version = "2" }

[dependencies]
anyhow = "1.0.66"
backtrace = "0.3"
napi = { version = "2", default-features = false, features = [
"napi3",
"serde-json",
] }
napi-derive = { version = "2", default-features = false, features = [
"type-def",
] }
node_macro_deps = { path = "../node_macro_deps" }
path-clean = "0.1"
serde = { version = "1", features = ["derive"] }
serde_json = { version = "1", features = ["unbounded_depth"] }
tracing = { version = "0.1.37", features = ["release_max_level_info"] }
tracing-chrome = "0.5.0"
tracing-futures = "0.2.5"
tracing-subscriber = { version = "0.3.9", features = ["env-filter"] }

swc_core = { version = "0.83.18", features = [
"allocator_node",
"ecma_ast",
"ecma_codegen",
"common_concurrent",
"ecma_minifier",
] }
swc_node_base = "0.5.8"
23 changes: 23 additions & 0 deletions bindings/binding_minifier_node/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use std::{
env,
fs::File,
io::{BufWriter, Write},
path::Path,
};

extern crate napi_build;

fn main() {
let out_dir = env::var("OUT_DIR").expect("Outdir should exist");
let dest_path = Path::new(&out_dir).join("triple.txt");
let mut f =
BufWriter::new(File::create(&dest_path).expect("Failed to create target triple text"));
write!(
f,
"{}",
env::var("TARGET").expect("Target should be specified")
)
.expect("Failed to write target triple text");

napi_build::setup();
}
64 changes: 64 additions & 0 deletions bindings/binding_minifier_node/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#![recursion_limit = "2048"]
#![allow(dead_code)]

#[macro_use]
extern crate napi_derive;

extern crate swc_node_base;

use std::{env, panic::set_hook, sync::Arc};

use backtrace::Backtrace;
use swc_core::{
base::Compiler,
common::{sync::Lazy, FilePathMapping, SourceMap},
};

mod minify;
mod util;

static COMPILER: Lazy<Arc<Compiler>> = Lazy::new(|| {
let cm = Arc::new(SourceMap::new(FilePathMapping::empty()));

Arc::new(Compiler::new(cm))
});

#[napi::module_init]
fn init() {
if cfg!(debug_assertions) || env::var("SWC_DEBUG").unwrap_or_default() == "1" {
set_hook(Box::new(|panic_info| {
let backtrace = Backtrace::new();
println!("Panic: {:?}\nBacktrace: {:?}", panic_info, backtrace);
}));
}
}

fn get_compiler() -> Arc<Compiler> {
COMPILER.clone()
}

#[napi(js_name = "Compiler")]
pub struct JsCompiler {
_compiler: Arc<Compiler>,
}

#[napi]
impl JsCompiler {
#[napi(constructor)]
#[allow(clippy::new_without_default)]
#[tracing::instrument(level = "info", skip_all)]
pub fn new() -> Self {
Self {
_compiler: COMPILER.clone(),
}
}
}

pub type ArcCompiler = Arc<Compiler>;

/// Hack for `Type Generation`
#[napi(object)]
pub struct TransformOutput {
pub code: String,
pub map: Option<String>,
}
106 changes: 106 additions & 0 deletions bindings/binding_minifier_node/src/minify.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
use std::sync::Arc;

use napi::{
bindgen_prelude::{AbortSignal, AsyncTask, Buffer},
Task,
};
use serde::Deserialize;
use swc_core::{
base::{
config::{ErrorFormat, JsMinifyOptions},
TransformOutput,
},
common::{collections::AHashMap, sync::Lrc, FileName, SourceFile, SourceMap},
node::{deserialize_json, get_deserialized, MapErr},
};

use crate::{get_compiler, util::try_with};

struct MinifyTask {
c: Arc<swc_core::base::Compiler>,
code: String,
options: String,
}

#[derive(Deserialize)]
#[serde(untagged)]
enum MinifyTarget {
/// Code to minify.
Single(String),
/// `{ filename: code }`
Map(AHashMap<String, String>),
}

impl MinifyTarget {
fn to_file(&self, cm: Lrc<SourceMap>) -> Lrc<SourceFile> {
match self {
MinifyTarget::Single(code) => cm.new_source_file(FileName::Anon, code.clone()),
MinifyTarget::Map(codes) => {
assert_eq!(
codes.len(),
1,
"swc.minify does not support concatting multiple files yet"
);

let (filename, code) = codes.iter().next().unwrap();

cm.new_source_file(FileName::Real(filename.clone().into()), code.clone())
}
}
}
}

#[napi]
impl Task for MinifyTask {
type JsValue = TransformOutput;
type Output = TransformOutput;

fn compute(&mut self) -> napi::Result<Self::Output> {
let input: MinifyTarget = deserialize_json(&self.code)?;
let options: JsMinifyOptions = deserialize_json(&self.options)?;

try_with(self.c.cm.clone(), false, ErrorFormat::Normal, |handler| {
let fm = input.to_file(self.c.cm.clone());

self.c.minify(fm, handler, &options)
})
.convert_err()
}

fn resolve(&mut self, _env: napi::Env, output: Self::Output) -> napi::Result<Self::JsValue> {
Ok(output)
}
}

#[napi]
fn minify(code: Buffer, opts: Buffer, signal: Option<AbortSignal>) -> AsyncTask<MinifyTask> {
crate::util::init_default_trace_subscriber();
let code = String::from_utf8_lossy(code.as_ref()).to_string();
let options = String::from_utf8_lossy(opts.as_ref()).to_string();

let c = get_compiler();

let task = MinifyTask { c, code, options };

AsyncTask::with_optional_signal(task, signal)
}

#[napi]
pub fn minify_sync(code: Buffer, opts: Buffer) -> napi::Result<TransformOutput> {
crate::util::init_default_trace_subscriber();
let code: MinifyTarget = get_deserialized(code)?;
let opts = get_deserialized(opts)?;

let c = get_compiler();

let fm = code.to_file(c.cm.clone());

try_with(
c.cm.clone(),
false,
// TODO(kdy1): Maybe make this configurable?
ErrorFormat::Normal,
|handler| c.minify(fm, handler, &opts),
)
.convert_err()
}

1 comment on commit 64d8f4b

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: 64d8f4b Previous: 38bc710 Ratio
es/full/bugs-1 277965 ns/iter (± 2591) 292835 ns/iter (± 10082) 0.95
es/full/minify/libraries/antd 1322034511 ns/iter (± 10614227) 1315995624 ns/iter (± 18473083) 1.00
es/full/minify/libraries/d3 275937559 ns/iter (± 5390115) 277406238 ns/iter (± 3393749) 0.99
es/full/minify/libraries/echarts 1071279483 ns/iter (± 30424959) 1062448946 ns/iter (± 20500512) 1.01
es/full/minify/libraries/jquery 84715555 ns/iter (± 468616) 83558813 ns/iter (± 176392) 1.01
es/full/minify/libraries/lodash 97809227 ns/iter (± 399303) 97253814 ns/iter (± 248356) 1.01
es/full/minify/libraries/moment 49943312 ns/iter (± 110891) 49495554 ns/iter (± 104500) 1.01
es/full/minify/libraries/react 18061096 ns/iter (± 74567) 17900940 ns/iter (± 62713) 1.01
es/full/minify/libraries/terser 218785964 ns/iter (± 718455) 217602082 ns/iter (± 458473) 1.01
es/full/minify/libraries/three 388554065 ns/iter (± 2173441) 385690773 ns/iter (± 2303723) 1.01
es/full/minify/libraries/typescript 2669766156 ns/iter (± 7608831) 2655033055 ns/iter (± 12817397) 1.01
es/full/minify/libraries/victory 571119477 ns/iter (± 4596651) 564255625 ns/iter (± 3079118) 1.01
es/full/minify/libraries/vue 119849269 ns/iter (± 505057) 119122326 ns/iter (± 383014) 1.01
es/full/codegen/es3 33925 ns/iter (± 107) 34990 ns/iter (± 120) 0.97
es/full/codegen/es5 33709 ns/iter (± 105) 34846 ns/iter (± 143) 0.97
es/full/codegen/es2015 33788 ns/iter (± 92) 34862 ns/iter (± 92) 0.97
es/full/codegen/es2016 33727 ns/iter (± 72) 34817 ns/iter (± 122) 0.97
es/full/codegen/es2017 33786 ns/iter (± 91) 34859 ns/iter (± 97) 0.97
es/full/codegen/es2018 33828 ns/iter (± 130) 34799 ns/iter (± 107) 0.97
es/full/codegen/es2019 33757 ns/iter (± 90) 34949 ns/iter (± 104) 0.97
es/full/codegen/es2020 33765 ns/iter (± 146) 34857 ns/iter (± 163) 0.97
es/full/all/es3 164834626 ns/iter (± 1375225) 164104993 ns/iter (± 931894) 1.00
es/full/all/es5 158014243 ns/iter (± 942665) 157456785 ns/iter (± 1625657) 1.00
es/full/all/es2015 116652014 ns/iter (± 410134) 117387903 ns/iter (± 1102040) 0.99
es/full/all/es2016 116181520 ns/iter (± 936650) 115623727 ns/iter (± 1550286) 1.00
es/full/all/es2017 115654292 ns/iter (± 1187599) 114660643 ns/iter (± 1107395) 1.01
es/full/all/es2018 112705244 ns/iter (± 659836) 113788337 ns/iter (± 787702) 0.99
es/full/all/es2019 112325492 ns/iter (± 553576) 112911948 ns/iter (± 623637) 0.99
es/full/all/es2020 108655632 ns/iter (± 597400) 107690003 ns/iter (± 799645) 1.01
es/full/parser 494362 ns/iter (± 54671) 491421 ns/iter (± 5446) 1.01
es/full/base/fixer 17721 ns/iter (± 98) 20901 ns/iter (± 156) 0.85
es/full/base/resolver_and_hygiene 81115 ns/iter (± 215) 82757 ns/iter (± 835) 0.98
serialization of serde 293 ns/iter (± 0) 292 ns/iter (± 0) 1.00
css/minify/libraries/bootstrap 28641836 ns/iter (± 91697) 29100192 ns/iter (± 51642) 0.98
css/visitor/compare/clone 1655996 ns/iter (± 6365) 1653686 ns/iter (± 13382) 1.00
css/visitor/compare/visit_mut_span 1789973 ns/iter (± 8765) 1776330 ns/iter (± 5688) 1.01
css/visitor/compare/visit_mut_span_panic 1862855 ns/iter (± 4695) 1841336 ns/iter (± 3087) 1.01
css/visitor/compare/fold_span 2582662 ns/iter (± 5936) 2581196 ns/iter (± 4931) 1.00
css/visitor/compare/fold_span_panic 2770013 ns/iter (± 11236) 2785907 ns/iter (± 11518) 0.99
css/lexer/bootstrap_5_1_3 4662661 ns/iter (± 11807) 4483800 ns/iter (± 7895) 1.04
css/lexer/foundation_6_7_4 3918160 ns/iter (± 8720) 3733794 ns/iter (± 10694) 1.05
css/lexer/tailwind_3_1_1 743044 ns/iter (± 475) 708523 ns/iter (± 1849) 1.05
css/parser/bootstrap_5_1_3 18833284 ns/iter (± 41291) 19686475 ns/iter (± 35403) 0.96
css/parser/foundation_6_7_4 15059542 ns/iter (± 101337) 15803629 ns/iter (± 22217) 0.95
css/parser/tailwind_3_1_1 2912249 ns/iter (± 133440) 3007980 ns/iter (± 2756) 0.97
es/codegen/colors 739077 ns/iter (± 403811) 738013 ns/iter (± 403277) 1.00
es/codegen/large 3159415 ns/iter (± 1686575) 3153538 ns/iter (± 1682367) 1.00
es/codegen/with-parser/colors 45700 ns/iter (± 218) 45889 ns/iter (± 292) 1.00
es/codegen/with-parser/large 492122 ns/iter (± 1297) 493632 ns/iter (± 728) 1.00
es/minify/libraries/antd 1152714727 ns/iter (± 7455423) 1127096429 ns/iter (± 14796159) 1.02
es/minify/libraries/d3 239404305 ns/iter (± 794529) 238395514 ns/iter (± 1057147) 1.00
es/minify/libraries/echarts 926142975 ns/iter (± 12133145) 902028020 ns/iter (± 7719329) 1.03
es/minify/libraries/jquery 73231336 ns/iter (± 140245) 72735647 ns/iter (± 146273) 1.01
es/minify/libraries/lodash 87209747 ns/iter (± 171395) 86700647 ns/iter (± 147885) 1.01
es/minify/libraries/moment 43364683 ns/iter (± 81467) 43148038 ns/iter (± 137398) 1.01
es/minify/libraries/react 15911038 ns/iter (± 63846) 15921644 ns/iter (± 43882) 1.00
es/minify/libraries/terser 186214406 ns/iter (± 520703) 184797150 ns/iter (± 1041819) 1.01
es/minify/libraries/three 322524889 ns/iter (± 1994476) 319705400 ns/iter (± 1413069) 1.01
es/minify/libraries/typescript 2261937867 ns/iter (± 5672028) 2235946281 ns/iter (± 10811418) 1.01
es/minify/libraries/victory 482649568 ns/iter (± 5379957) 471230031 ns/iter (± 2508820) 1.02
es/minify/libraries/vue 105536567 ns/iter (± 122125) 105852882 ns/iter (± 499387) 1.00
es/visitor/compare/clone 1942088 ns/iter (± 3828) 1926409 ns/iter (± 2539) 1.01
es/visitor/compare/visit_mut_span 2283519 ns/iter (± 1880) 2268965 ns/iter (± 8120) 1.01
es/visitor/compare/visit_mut_span_panic 2311753 ns/iter (± 3154) 2308680 ns/iter (± 9130) 1.00
es/visitor/compare/fold_span 3364940 ns/iter (± 8739) 3369069 ns/iter (± 6949) 1.00
es/visitor/compare/fold_span_panic 3508388 ns/iter (± 6028) 3499131 ns/iter (± 86460) 1.00
es/lexer/colors 13058 ns/iter (± 15) 13076 ns/iter (± 81) 1.00
es/lexer/angular 6128894 ns/iter (± 3803) 6133242 ns/iter (± 15912) 1.00
es/lexer/backbone 794251 ns/iter (± 2142) 799803 ns/iter (± 1513) 0.99
es/lexer/jquery 4522780 ns/iter (± 6587) 4505032 ns/iter (± 5057) 1.00
es/lexer/jquery mobile 6878664 ns/iter (± 11014) 7009813 ns/iter (± 44472) 0.98
es/lexer/mootools 3577931 ns/iter (± 2018) 3578978 ns/iter (± 18672) 1.00
es/lexer/underscore 662520 ns/iter (± 926) 675818 ns/iter (± 3880) 0.98
es/lexer/three 21535333 ns/iter (± 23616) 21474930 ns/iter (± 28892) 1.00
es/lexer/yui 3820229 ns/iter (± 3913) 3849243 ns/iter (± 4608) 0.99
es/parser/colors 27534 ns/iter (± 86) 27594 ns/iter (± 59) 1.00
es/parser/angular 13590211 ns/iter (± 79112) 13460736 ns/iter (± 51416) 1.01
es/parser/backbone 1980882 ns/iter (± 13417) 1975922 ns/iter (± 9268) 1.00
es/parser/jquery 10805614 ns/iter (± 41127) 10778757 ns/iter (± 47808) 1.00
es/parser/jquery mobile 16664305 ns/iter (± 157354) 16497780 ns/iter (± 44531) 1.01
es/parser/mootools 8351324 ns/iter (± 20184) 8315216 ns/iter (± 17873) 1.00
es/parser/underscore 1704377 ns/iter (± 12987) 1693482 ns/iter (± 10383) 1.01
es/parser/three 46634729 ns/iter (± 201055) 46328445 ns/iter (± 144509) 1.01
es/parser/yui 8228378 ns/iter (± 33076) 8265364 ns/iter (± 26062) 1.00
es/preset-env/usage/builtin_type 138805 ns/iter (± 32511) 134662 ns/iter (± 31536) 1.03
es/preset-env/usage/property 17255 ns/iter (± 88) 16106 ns/iter (± 47) 1.07
es/resolver/typescript 91948300 ns/iter (± 961271) 90659864 ns/iter (± 1050734) 1.01
es/fixer/typescript 63414764 ns/iter (± 975692) 63762441 ns/iter (± 260394) 0.99
es/hygiene/typescript 129357559 ns/iter (± 576070) 127984463 ns/iter (± 389366) 1.01
es/resolver_with_hygiene/typescript 242872518 ns/iter (± 843896) 243106672 ns/iter (± 1645986) 1.00
es/visitor/base-perf/module_clone 59458 ns/iter (± 411) 59101 ns/iter (± 271) 1.01
es/visitor/base-perf/fold_empty 63475 ns/iter (± 376) 62983 ns/iter (± 345) 1.01
es/visitor/base-perf/fold_noop_impl_all 63615 ns/iter (± 212) 63843 ns/iter (± 435) 1.00
es/visitor/base-perf/fold_noop_impl_vec 63784 ns/iter (± 184) 64048 ns/iter (± 225) 1.00
es/visitor/base-perf/boxing_boxed_clone 57 ns/iter (± 0) 58 ns/iter (± 0) 0.98
es/visitor/base-perf/boxing_unboxed_clone 40 ns/iter (± 0) 41 ns/iter (± 0) 0.98
es/visitor/base-perf/boxing_boxed 106 ns/iter (± 0) 110 ns/iter (± 0) 0.96
es/visitor/base-perf/boxing_unboxed 75 ns/iter (± 0) 78 ns/iter (± 0) 0.96
es/visitor/base-perf/visit_empty 0 ns/iter (± 0) 0 ns/iter (± 0) NaN
es/visitor/base-perf/visit_contains_this 2525 ns/iter (± 58) 2484 ns/iter (± 11) 1.02
es/base/parallel/resolver/typescript 4362508319 ns/iter (± 273838380) 3684072591 ns/iter (± 270947608) 1.18
es/base/parallel/hygiene/typescript 1449805672 ns/iter (± 11360519) 1426606180 ns/iter (± 16524256) 1.02
misc/visitors/time-complexity/time 5 135 ns/iter (± 1) 135 ns/iter (± 1) 1
misc/visitors/time-complexity/time 10 392 ns/iter (± 7) 388 ns/iter (± 10) 1.01
misc/visitors/time-complexity/time 15 522 ns/iter (± 2) 679 ns/iter (± 5) 0.77
misc/visitors/time-complexity/time 20 1071 ns/iter (± 18) 1068 ns/iter (± 52) 1.00
misc/visitors/time-complexity/time 40 4227 ns/iter (± 10) 3517 ns/iter (± 24) 1.20
misc/visitors/time-complexity/time 60 7769 ns/iter (± 9) 7354 ns/iter (± 616) 1.06

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.