Skip to content

Commit 395aa5e

Browse files
committed
feat(napi/minify): return parse errors (#12112)
closes #12101
1 parent 92af759 commit 395aa5e

File tree

9 files changed

+77
-18
lines changed

9 files changed

+77
-18
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

napi/minify/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ doctest = false
2424
[dependencies]
2525
oxc_allocator = { workspace = true }
2626
oxc_codegen = { workspace = true }
27+
oxc_diagnostics = { workspace = true }
2728
oxc_minifier = { workspace = true }
29+
oxc_napi = { workspace = true }
2830
oxc_parser = { workspace = true }
2931
oxc_sourcemap = { workspace = true, features = ["napi", "rayon"] }
3032
oxc_span = { workspace = true }

napi/minify/index.d.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,33 @@ export interface MinifyOptions {
103103
export interface MinifyResult {
104104
code: string
105105
map?: SourceMap
106+
errors: Array<OxcError>
107+
}
108+
export interface Comment {
109+
type: 'Line' | 'Block'
110+
value: string
111+
start: number
112+
end: number
113+
}
114+
115+
export interface ErrorLabel {
116+
message?: string
117+
start: number
118+
end: number
119+
}
120+
121+
export interface OxcError {
122+
severity: Severity
123+
message: string
124+
labels: Array<ErrorLabel>
125+
helpMessage?: string
126+
codeframe?: string
127+
}
128+
129+
export declare const enum Severity {
130+
Error = 'Error',
131+
Warning = 'Warning',
132+
Advice = 'Advice'
106133
}
107134
export interface SourceMap {
108135
file?: string

napi/minify/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,3 +384,4 @@ if (!nativeBinding) {
384384

385385
module.exports = nativeBinding
386386
module.exports.minify = nativeBinding.minify
387+
module.exports.Severity = nativeBinding.Severity

napi/minify/minify.wasi-browser.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,4 @@ const {
5555
})
5656
export default __napiModule.exports
5757
export const minify = __napiModule.exports.minify
58+
export const Severity = __napiModule.exports.Severity

napi/minify/minify.wasi.cjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,4 @@ const { instance: __napiInstance, module: __wasiModule, napiModule: __napiModule
8686
})
8787
module.exports = __napiModule.exports
8888
module.exports.minify = __napiModule.exports.minify
89+
module.exports.Severity = __napiModule.exports.Severity

napi/minify/src/lib.rs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![expect(clippy::needless_pass_by_value, clippy::missing_errors_doc)]
1+
#![expect(clippy::needless_pass_by_value)]
22

33
#[cfg(all(
44
feature = "allocator",
@@ -16,31 +16,52 @@ use napi_derive::napi;
1616

1717
use oxc_allocator::Allocator;
1818
use oxc_codegen::{Codegen, CodegenOptions};
19+
use oxc_diagnostics::OxcDiagnostic;
1920
use oxc_minifier::Minifier;
21+
use oxc_napi::OxcError;
2022
use oxc_parser::Parser;
23+
use oxc_sourcemap::napi::SourceMap;
2124
use oxc_span::SourceType;
2225

23-
use crate::options::{MinifyOptions, MinifyResult};
26+
use crate::options::MinifyOptions;
27+
28+
#[derive(Default)]
29+
#[napi(object)]
30+
pub struct MinifyResult {
31+
pub code: String,
32+
pub map: Option<SourceMap>,
33+
pub errors: Vec<OxcError>,
34+
}
2435

2536
/// Minify synchronously.
2637
#[napi]
2738
pub fn minify(
2839
filename: String,
2940
source_text: String,
3041
options: Option<MinifyOptions>,
31-
) -> napi::Result<MinifyResult> {
42+
) -> MinifyResult {
3243
let options = options.unwrap_or_default();
3344

3445
let minifier_options = match oxc_minifier::MinifierOptions::try_from(&options) {
3546
Ok(options) => options,
36-
Err(error) => return Err(napi::Error::from_reason(&error)),
47+
Err(error) => {
48+
return MinifyResult {
49+
errors: OxcError::from_diagnostics(
50+
&filename,
51+
&source_text,
52+
vec![OxcDiagnostic::error(error)],
53+
),
54+
..MinifyResult::default()
55+
};
56+
}
3757
};
3858

3959
let allocator = Allocator::default();
4060

4161
let source_type = SourceType::from_path(&filename).unwrap_or_default();
4262

43-
let mut program = Parser::new(&allocator, &source_text, source_type).parse().program;
63+
let parser_ret = Parser::new(&allocator, &source_text, source_type).parse();
64+
let mut program = parser_ret.program;
4465

4566
let scoping = Minifier::new(minifier_options).build(&allocator, &mut program).scoping;
4667

@@ -52,10 +73,14 @@ pub fn minify(
5273
};
5374

5475
if options.sourcemap == Some(true) {
55-
codegen_options.source_map_path = Some(PathBuf::from(filename));
76+
codegen_options.source_map_path = Some(PathBuf::from(&filename));
5677
}
5778

5879
let ret = Codegen::new().with_options(codegen_options).with_scoping(scoping).build(&program);
5980

60-
Ok(MinifyResult { code: ret.code, map: ret.map.map(oxc_sourcemap::napi::SourceMap::from) })
81+
MinifyResult {
82+
code: ret.code,
83+
map: ret.map.map(oxc_sourcemap::napi::SourceMap::from),
84+
errors: OxcError::from_diagnostics(&filename, &source_text, parser_ret.errors),
85+
}
6186
}

napi/minify/src/options.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use napi::Either;
44
use napi_derive::napi;
55

66
use oxc_minifier::TreeShakeOptions;
7-
use oxc_sourcemap::napi::SourceMap;
87
use oxc_syntax::es_target::ESTarget;
98

109
#[napi(object)]
@@ -192,10 +191,3 @@ impl TryFrom<&MinifyOptions> for oxc_minifier::MinifierOptions {
192191
Ok(oxc_minifier::MinifierOptions { compress, mangle })
193192
}
194193
}
195-
196-
#[napi(object)]
197-
pub struct MinifyResult {
198-
pub code: String,
199-
200-
pub map: Option<SourceMap>,
201-
}

napi/minify/test/minify.test.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,29 @@ describe('simple', () => {
2323
],
2424
'version': 3,
2525
},
26+
'errors': [],
2627
});
2728
});
2829

2930
it('can turn off everything', () => {
3031
const ret = minify('test.js', code, { compress: false, mangle: false, codegen: { removeWhitespace: false } });
31-
expect(ret).toStrictEqual({
32-
'code': 'function foo() {\n\tvar bar;\n\tbar(undefined);\n}\nfoo();\n',
33-
});
32+
expect(ret.code).toBe(
33+
'function foo() {\n\tvar bar;\n\tbar(undefined);\n}\nfoo();\n',
34+
);
3435
});
3536

3637
it('defaults to esnext', () => {
3738
const code = 'try { foo } catch (e) {}';
3839
const ret = minify('test.js', code);
3940
expect(ret.code).toBe('try{foo}catch{}');
4041
});
42+
43+
it('returns parser error', () => {
44+
const code = 'const';
45+
const ret = minify('test.js', code);
46+
expect(ret.code).toBe('');
47+
expect(ret.errors.length).toBe(1);
48+
});
4149
});
4250

4351
describe('worker', () => {

0 commit comments

Comments
 (0)