Skip to content

Commit

Permalink
feat(node-swc): Add experimental trace support in @swc/core (#3731)
Browse files Browse the repository at this point in the history
  • Loading branch information
kwonoj authored Feb 25, 2022
1 parent f87a2fe commit a454996
Show file tree
Hide file tree
Showing 32 changed files with 459 additions and 354 deletions.
72 changes: 64 additions & 8 deletions Cargo.lock

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

6 changes: 4 additions & 2 deletions crates/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,7 @@ swc_ecma_loader = {path = "../swc_ecma_loader"}
swc_ecma_parser = {path = "../swc_ecma_parser"}
swc_node_base = {path = "../swc_node_base"}
swc_node_bundler = {path = "../swc_node_bundler"}
tracing = {version = "0.1.28", features = ["release_max_level_info"]}
tracing-subscriber = {version = "0.3.4", features = ["env-filter"]}
tracing = { version = "0.1.31", features = ["release_max_level_info"] }
tracing-chrome = "0.4.0"
tracing-futures = "0.2.5"
tracing-subscriber = { version = "0.3.9", features = ["env-filter"] }
2 changes: 2 additions & 0 deletions crates/node/src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ pub(crate) fn bundle(
conf_items: Buffer,
signal: Option<AbortSignal>,
) -> napi::Result<AsyncTask<BundleTask>> {
crate::util::init_trace_once(false, None)?;

let c: Arc<Compiler> = get_compiler();

let static_items: StaticConfigItem = get_deserialized(&conf_items)?;
Expand Down
9 changes: 1 addition & 8 deletions crates/node/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use std::{env, panic::set_hook, sync::Arc};
use backtrace::Backtrace;
use swc::Compiler;
use swc_common::{self, sync::Lazy, FilePathMapping, SourceMap};
use tracing_subscriber::EnvFilter;

mod bundle;
mod minify;
Expand All @@ -34,13 +33,6 @@ fn init() {
println!("Panic: {:?}\nBacktrace: {:?}", panic_info, backtrace);
}));
}

let _ = tracing_subscriber::FmtSubscriber::builder()
.without_time()
.with_target(false)
.with_ansi(true)
.with_env_filter(EnvFilter::from_env("SWC_LOG"))
.try_init();
}

fn get_compiler() -> Arc<Compiler> {
Expand All @@ -56,6 +48,7 @@ pub struct JsCompiler {
impl JsCompiler {
#[napi(constructor)]
#[allow(clippy::new_without_default)]
#[tracing::instrument(level = "trace", skip_all)]
pub fn new() -> Self {
Self {
_compiler: COMPILER.clone(),
Expand Down
2 changes: 2 additions & 0 deletions crates/node/src/minify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ impl Task for MinifyTask {

#[napi]
fn minify(code: Buffer, opts: Buffer, signal: Option<AbortSignal>) -> AsyncTask<MinifyTask> {
crate::util::init_trace_once(false, None).expect("Should able to init trace");
let code = String::from_utf8_lossy(code.as_ref()).to_string();
let options = String::from_utf8_lossy(opts.as_ref()).to_string();

Expand All @@ -83,6 +84,7 @@ fn minify(code: Buffer, opts: Buffer, signal: Option<AbortSignal>) -> AsyncTask<

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

Expand Down
6 changes: 6 additions & 0 deletions crates/node/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ pub fn parse(
filename: Option<String>,
signal: Option<AbortSignal>,
) -> AsyncTask<ParseTask> {
crate::util::init_trace_once(false, None).expect("Should able to init trace");

let c = get_compiler();
let options = String::from_utf8_lossy(options.as_ref()).to_string();
let filename = if let Some(value) = filename {
Expand All @@ -131,6 +133,7 @@ pub fn parse(

#[napi]
pub fn parse_sync(src: String, opts: Buffer, filename: Option<String>) -> napi::Result<String> {
crate::util::init_trace_once(false, None)?;
let c = get_compiler();

let options: ParseOptions = get_deserialized(&opts)?;
Expand Down Expand Up @@ -160,6 +163,7 @@ pub fn parse_sync(src: String, opts: Buffer, filename: Option<String>) -> napi::

#[napi]
pub fn parse_file_sync(path: String, opts: Buffer) -> napi::Result<String> {
crate::util::init_trace_once(false, None)?;
let c = get_compiler();
let options: ParseOptions = get_deserialized(&opts)?;

Expand Down Expand Up @@ -190,6 +194,8 @@ pub fn parse_file(
options: Buffer,
signal: Option<AbortSignal>,
) -> AsyncTask<ParseFileTask> {
crate::util::init_trace_once(false, None).expect("Should able to init trace");

let c = get_compiler();
let path = PathBuf::from(&path);
let options = String::from_utf8_lossy(options.as_ref()).to_string();
Expand Down
4 changes: 4 additions & 0 deletions crates/node/src/print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ pub fn print(
options: Buffer,
signal: Option<AbortSignal>,
) -> napi::Result<AsyncTask<PrintTask>> {
crate::util::init_trace_once(false, None)?;

let c = get_compiler();
let options = String::from_utf8_lossy(&options).to_string();

Expand All @@ -77,6 +79,8 @@ pub fn print(

#[napi]
pub fn print_sync(program: String, options: Buffer) -> napi::Result<TransformOutput> {
crate::util::init_trace_once(false, None)?;

let c = get_compiler();

let program: Program = deserialize_json(program.as_str())?;
Expand Down
13 changes: 13 additions & 0 deletions crates/node/src/transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use path_clean::clean;
use swc::{config::Options, Compiler, TransformOutput};
use swc_common::FileName;
use swc_ecma_ast::Program;
use tracing::instrument;

use crate::{
get_compiler,
Expand Down Expand Up @@ -40,6 +41,7 @@ impl Task for TransformTask {
type JsValue = TransformOutput;
type Output = TransformOutput;

#[instrument(level = "trace", skip_all)]
fn compute(&mut self) -> napi::Result<Self::Output> {
let mut options: Options = serde_json::from_slice(self.options.as_ref())?;
if !options.filename.is_empty() {
Expand Down Expand Up @@ -92,12 +94,15 @@ impl Task for TransformTask {
}

#[napi]
#[instrument(level = "trace", skip_all)]
pub fn transform(
src: String,
is_module: bool,
options: JsBuffer,
signal: Option<AbortSignal>,
) -> napi::Result<AsyncTask<TransformTask>> {
crate::util::init_trace_once(false, None)?;

let c = get_compiler();

let input = if is_module {
Expand All @@ -115,7 +120,10 @@ pub fn transform(
}

#[napi]
#[instrument(level = "trace", skip_all)]
pub fn transform_sync(s: String, is_module: bool, opts: Buffer) -> napi::Result<TransformOutput> {
crate::util::init_trace_once(false, None)?;

let c = get_compiler();

let mut options: Options = get_deserialized(&opts)?;
Expand Down Expand Up @@ -147,12 +155,15 @@ pub fn transform_sync(s: String, is_module: bool, opts: Buffer) -> napi::Result<
}

#[napi]
#[instrument(level = "trace", skip_all)]
pub fn transform_file(
src: String,
_is_module: bool,
options: JsBuffer,
signal: Option<AbortSignal>,
) -> napi::Result<AsyncTask<TransformTask>> {
crate::util::init_trace_once(false, None)?;

let c = get_compiler();

let path = clean(&src);
Expand All @@ -170,6 +181,8 @@ pub fn transform_file_sync(
is_module: bool,
opts: Buffer,
) -> napi::Result<TransformOutput> {
crate::util::init_trace_once(false, None)?;

let c = get_compiler();

let mut options: Options = get_deserialized(&opts)?;
Expand Down
56 changes: 55 additions & 1 deletion crates/node/src/util.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,68 @@
use std::{
any::type_name,
panic::{catch_unwind, AssertUnwindSafe},
sync::Mutex,
};

use anyhow::{anyhow, Context, Error};
use napi::Status;
use serde::de::DeserializeOwned;
use swc::try_with_handler;
use swc_common::{errors::Handler, sync::Lrc, SourceMap};
use swc_common::{
errors::Handler,
sync::{Lrc, OnceCell},
SourceMap,
};
use tracing::instrument;
use tracing_chrome::{ChromeLayerBuilder, FlushGuard};
use tracing_subscriber::{
prelude::__tracing_subscriber_SubscriberExt, util::SubscriberInitExt, EnvFilter,
};

// Hold FlushGuard for the trace until it flushes out completely.
#[derive(Default)]
struct TraceFlushGuard {
inner: Option<FlushGuard>,
}
static FLUSH_GUARD: OnceCell<Mutex<TraceFlushGuard>> = OnceCell::new();

#[napi]
pub fn init_trace_once(
enable_chrome_trace: bool,
trace_out_file: Option<String>,
) -> napi::Result<()> {
FLUSH_GUARD.get_or_init(|| {
if enable_chrome_trace {
let layer = if let Some(trace_out_file) = trace_out_file {
ChromeLayerBuilder::new().file(trace_out_file)
} else {
ChromeLayerBuilder::new()
};

let (chrome_layer, guard) = layer.build();
tracing_subscriber::registry()
.with(chrome_layer)
.try_init()
.expect("Should able to register trace");

Mutex::new(TraceFlushGuard { inner: Some(guard) })
} else {
tracing_subscriber::FmtSubscriber::builder()
.without_time()
.with_target(false)
.with_ansi(true)
.with_env_filter(EnvFilter::from_env("SWC_LOG"))
.try_init()
.expect("Should able to register trace");

Mutex::new(TraceFlushGuard { inner: None })
}
});

Ok(())
}

#[instrument(level = "trace", skip_all)]
pub fn try_with<F, Ret>(cm: Lrc<SourceMap>, skip_filename: bool, op: F) -> Result<Ret, Error>
where
F: FnOnce(&Handler) -> Result<Ret, Error>,
Expand Down
2 changes: 1 addition & 1 deletion crates/swc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ swc_ecmascript = {version = "0.119.0", path = "../swc_ecmascript"}
swc_node_comments = {version = "0.4.0", path = "../swc_node_comments"}
swc_plugin_runner = {version = "0.38.0", path = "../swc_plugin_runner", optional = true}
swc_visit = {version = "0.3.0", path = "../swc_visit"}
tracing = "0.1.28"
tracing = "0.1.31"

[dependencies.napi-derive]
default-features = false
Expand Down
Loading

1 comment on commit a454996

@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: a454996 Previous: f87a2fe Ratio
full_es2015 171589643 ns/iter (± 5234678) 191879220 ns/iter (± 9545550) 0.89
full_es2016 177857517 ns/iter (± 7655490) 196695590 ns/iter (± 10746558) 0.90
full_es2017 178860552 ns/iter (± 6851580) 195361133 ns/iter (± 13442045) 0.92
full_es2018 177360351 ns/iter (± 9283980) 194507319 ns/iter (± 8981323) 0.91
full_es2019 177198691 ns/iter (± 6974183) 193950702 ns/iter (± 8698079) 0.91
full_es2020 159168190 ns/iter (± 5692184) 175079973 ns/iter (± 10226555) 0.91
full_es3 219283413 ns/iter (± 6719745) 244185329 ns/iter (± 11688138) 0.90
full_es5 219847903 ns/iter (± 13846057) 240740384 ns/iter (± 11363513) 0.91
parser 703454 ns/iter (± 23351) 771237 ns/iter (± 70416) 0.91

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

Please sign in to comment.