-
-
Notifications
You must be signed in to change notification settings - Fork 491
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(napi/minify): implement napi (#8478)
- Loading branch information
Showing
11 changed files
with
291 additions
and
42 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,71 @@ | ||
/* auto-generated by NAPI-RS */ | ||
/* eslint-disable */ | ||
export declare function minify(filename: string, sourceText: string): string | ||
export interface CodegenOptions { | ||
/** | ||
* Remove whitespace. | ||
* | ||
* @default true | ||
*/ | ||
whitespace?: boolean | ||
} | ||
|
||
export interface CompressOptions { | ||
/** | ||
* Enables optional catch or nullish-coalescing operator if targeted higher. | ||
* | ||
* @default 'es2015' | ||
*/ | ||
target?: string | ||
/** | ||
* Pass true to discard calls to `console.*`. | ||
* | ||
* @default false | ||
*/ | ||
dropConsole?: boolean | ||
/** | ||
* Remove `debugger;` statements. | ||
* | ||
* @default true | ||
*/ | ||
dropDebugger?: boolean | ||
} | ||
|
||
export interface MangleOptions { | ||
/** Pass true to mangle names declared in the top level scope. */ | ||
toplevel?: boolean | ||
/** Debug mangled names. */ | ||
debug?: boolean | ||
} | ||
|
||
/** | ||
* Minify synchronously. | ||
* | ||
* # Errors | ||
* | ||
* * Fails to parse the options. | ||
*/ | ||
export declare function minify(filename: string, sourceText: string, options?: MinifyOptions | undefined | null): MinifyResult | ||
|
||
export interface MinifyOptions { | ||
compress?: boolean | CompressOptions | ||
mangle?: boolean | MangleOptions | ||
codegen?: boolean | CodegenOptions | ||
sourcemap?: boolean | ||
} | ||
|
||
export interface MinifyResult { | ||
code: string | ||
map?: SourceMap | ||
} | ||
|
||
export interface SourceMap { | ||
file?: string | ||
mappings: string | ||
names: Array<string> | ||
sourceRoot?: string | ||
sources: Array<string> | ||
sourcesContent?: Array<string> | ||
version: number | ||
x_google_ignoreList?: Array<number> | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,59 @@ | ||
#![allow(clippy::needless_pass_by_value)] | ||
|
||
mod options; | ||
|
||
use std::path::PathBuf; | ||
|
||
use napi::Either; | ||
use napi_derive::napi; | ||
|
||
use oxc_allocator::Allocator; | ||
use oxc_codegen::{Codegen, CodegenOptions}; | ||
use oxc_minifier::{CompressOptions, MangleOptions, Minifier, MinifierOptions}; | ||
use oxc_minifier::Minifier; | ||
use oxc_parser::Parser; | ||
use oxc_span::SourceType; | ||
|
||
#[allow(clippy::needless_pass_by_value)] | ||
use crate::options::{MinifyOptions, MinifyResult}; | ||
|
||
/// Minify synchronously. | ||
/// | ||
/// # Errors | ||
/// | ||
/// * Fails to parse the options. | ||
#[napi] | ||
pub fn minify(filename: String, source_text: String) -> String { | ||
pub fn minify( | ||
filename: String, | ||
source_text: String, | ||
options: Option<MinifyOptions>, | ||
) -> napi::Result<MinifyResult> { | ||
let options = options.unwrap_or_default(); | ||
|
||
let minifier_options = match oxc_minifier::MinifierOptions::try_from(&options) { | ||
Ok(options) => options, | ||
Err(error) => return Err(napi::Error::from_reason(&error)), | ||
}; | ||
|
||
let allocator = Allocator::default(); | ||
|
||
let source_type = SourceType::from_path(&filename).unwrap_or_default().with_typescript(true); | ||
|
||
let mut program = Parser::new(&allocator, &source_text, source_type).parse().program; | ||
|
||
let mangler = Minifier::new(MinifierOptions { | ||
mangle: Some(MangleOptions::default()), | ||
compress: CompressOptions::default(), | ||
}) | ||
.build(&allocator, &mut program) | ||
.mangler; | ||
|
||
Codegen::new() | ||
.with_options(CodegenOptions { minify: true, ..CodegenOptions::default() }) | ||
.with_mangler(mangler) | ||
.build(&program) | ||
.code | ||
let mangler = Minifier::new(minifier_options).build(&allocator, &mut program).mangler; | ||
|
||
let mut codegen_options = match &options.codegen { | ||
Some(Either::A(false)) => CodegenOptions { minify: false, ..CodegenOptions::default() }, | ||
None | Some(Either::A(true)) => { | ||
CodegenOptions { minify: true, ..CodegenOptions::default() } | ||
} | ||
Some(Either::B(o)) => CodegenOptions::from(o), | ||
}; | ||
|
||
if options.sourcemap == Some(true) { | ||
codegen_options.source_map_path = Some(PathBuf::from(filename)); | ||
} | ||
|
||
let ret = Codegen::new().with_options(codegen_options).with_mangler(mangler).build(&program); | ||
|
||
Ok(MinifyResult { code: ret.code, map: ret.map.map(oxc_sourcemap::napi::SourceMap::from) }) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
use std::str::FromStr; | ||
|
||
use napi::Either; | ||
use napi_derive::napi; | ||
|
||
use oxc_sourcemap::napi::SourceMap; | ||
use oxc_syntax::es_target::ESTarget; | ||
|
||
#[napi(object)] | ||
pub struct CompressOptions { | ||
/// Enables optional catch or nullish-coalescing operator if targeted higher. | ||
/// | ||
/// @default 'es2015' | ||
pub target: Option<String>, | ||
|
||
/// Pass true to discard calls to `console.*`. | ||
/// | ||
/// @default false | ||
pub drop_console: Option<bool>, | ||
|
||
/// Remove `debugger;` statements. | ||
/// | ||
/// @default true | ||
pub drop_debugger: Option<bool>, | ||
} | ||
|
||
impl Default for CompressOptions { | ||
fn default() -> Self { | ||
Self { target: None, drop_console: None, drop_debugger: Some(true) } | ||
} | ||
} | ||
|
||
impl TryFrom<&CompressOptions> for oxc_minifier::CompressOptions { | ||
type Error = String; | ||
fn try_from(o: &CompressOptions) -> Result<Self, Self::Error> { | ||
Ok(oxc_minifier::CompressOptions { | ||
target: o | ||
.target | ||
.as_ref() | ||
.map(|s| ESTarget::from_str(s)) | ||
.transpose()? | ||
.unwrap_or(ESTarget::ES2015), | ||
drop_debugger: o.drop_debugger.unwrap_or(false), | ||
drop_console: o.drop_console.unwrap_or(true), | ||
}) | ||
} | ||
} | ||
|
||
#[napi(object)] | ||
#[derive(Default)] | ||
pub struct MangleOptions { | ||
/// Pass true to mangle names declared in the top level scope. | ||
pub toplevel: Option<bool>, | ||
|
||
/// Debug mangled names. | ||
pub debug: Option<bool>, | ||
} | ||
|
||
impl From<&MangleOptions> for oxc_minifier::MangleOptions { | ||
fn from(o: &MangleOptions) -> Self { | ||
Self { top_level: o.toplevel.unwrap_or(false), debug: o.debug.unwrap_or(false) } | ||
} | ||
} | ||
|
||
#[napi(object)] | ||
pub struct CodegenOptions { | ||
/// Remove whitespace. | ||
/// | ||
/// @default true | ||
pub whitespace: Option<bool>, | ||
} | ||
|
||
impl Default for CodegenOptions { | ||
fn default() -> Self { | ||
Self { whitespace: Some(true) } | ||
} | ||
} | ||
|
||
impl From<&CodegenOptions> for oxc_codegen::CodegenOptions { | ||
fn from(o: &CodegenOptions) -> Self { | ||
oxc_codegen::CodegenOptions { | ||
minify: o.whitespace.unwrap_or(true), | ||
..oxc_codegen::CodegenOptions::default() | ||
} | ||
} | ||
} | ||
|
||
#[napi(object)] | ||
#[derive(Default)] | ||
pub struct MinifyOptions { | ||
pub compress: Option<Either<bool, CompressOptions>>, | ||
|
||
pub mangle: Option<Either<bool, MangleOptions>>, | ||
|
||
pub codegen: Option<Either<bool, CodegenOptions>>, | ||
|
||
pub sourcemap: Option<bool>, | ||
} | ||
|
||
impl TryFrom<&MinifyOptions> for oxc_minifier::MinifierOptions { | ||
type Error = String; | ||
|
||
fn try_from(o: &MinifyOptions) -> Result<Self, Self::Error> { | ||
let compress = match &o.compress { | ||
Some(Either::A(false)) => None, | ||
None | Some(Either::A(true)) => Some(oxc_minifier::CompressOptions::default()), | ||
Some(Either::B(o)) => Some(oxc_minifier::CompressOptions::try_from(o)?), | ||
}; | ||
let mangle = match &o.mangle { | ||
Some(Either::A(false)) => None, | ||
None | Some(Either::A(true)) => Some(oxc_minifier::MangleOptions::default()), | ||
Some(Either::B(o)) => Some(oxc_minifier::MangleOptions::from(o)), | ||
}; | ||
Ok(oxc_minifier::MinifierOptions { compress, mangle }) | ||
} | ||
} | ||
|
||
#[napi(object)] | ||
pub struct MinifyResult { | ||
pub code: String, | ||
|
||
pub map: Option<SourceMap>, | ||
} |
Oops, something went wrong.