feat(es): Add an option to omit columns from sourcemaps (#4646)

This commit is contained in:
Hana 2022-05-13 16:49:31 +08:00 committed by GitHub
parent 0e631eeab9
commit b6f904b8f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 130 additions and 0 deletions

View File

@ -130,6 +130,7 @@ impl Task for BundleTask {
None,
minify,
None,
true,
)?;
Ok((k, output))

View File

@ -45,6 +45,7 @@ impl Task for PrintTask {
None,
options.config.minify.into_bool(),
None,
options.config.emit_source_map_columns.into_bool(),
)
.convert_err()
}
@ -102,6 +103,7 @@ pub fn print_sync(program: String, options: Buffer) -> napi::Result<TransformOut
None,
options.config.minify.into_bool(),
None,
options.config.emit_source_map_columns.into_bool(),
)
.convert_err()
}

View File

@ -116,6 +116,7 @@ pub fn print_sync(s: JsValue, opts: JsValue) -> Result<JsValue, JsValue> {
None,
opts.config.minify.into(),
None,
opts.config.emit_source_map_columns.into_bool(),
)
.context("failed to print code")?;

View File

@ -47,6 +47,7 @@ fn bench_minify(b: &mut Bencher, filename: &str) {
source_map: Default::default(),
output_path: Default::default(),
inline_sources_content: true,
emit_source_map_columns: true,
},
)
})

View File

@ -115,6 +115,7 @@ fn bench_codegen(b: &mut Bencher, _target: EsVersion) {
None,
false,
None,
false,
)
.unwrap(),
);

View File

@ -35,6 +35,7 @@ fn main() {
source_map: Default::default(),
output_path: Default::default(),
inline_sources_content: Default::default(),
emit_source_map_columns: Default::default(),
},
)
.context("failed to minify")

View File

@ -626,6 +626,7 @@ impl Options {
source_file_name,
comments: comments.cloned(),
preserve_comments,
emit_source_map_columns: cfg.emit_source_map_columns.into_bool(),
})
}
}
@ -794,6 +795,9 @@ pub struct Config {
#[serde(default)]
pub inline_sources_content: BoolConfig<true>,
#[serde(default)]
pub emit_source_map_columns: BoolConfig<true>,
#[serde(default)]
pub error: ErrorConfig,
@ -840,6 +844,9 @@ pub struct JsMinifyOptions {
#[serde(default = "true_by_default")]
pub inline_sources_content: bool,
#[serde(default = "true_by_default")]
pub emit_source_map_columns: bool,
}
fn true_by_default() -> bool {
@ -1073,6 +1080,7 @@ pub struct BuiltInput<P: swc_ecma_visit::Fold> {
pub preserve_comments: BoolOr<JsMinifyCommentOption>,
pub inline_sources_content: bool,
pub emit_source_map_columns: bool,
}
/// `jsc` in `.swcrc`.

View File

@ -428,6 +428,7 @@ impl Compiler {
orig: Option<&sourcemap::SourceMap>,
minify: bool,
comments: Option<&dyn Comments>,
emit_source_map_columns: bool,
) -> Result<TransformOutput, Error>
where
T: Node + VisitWith<IdentCollector>,
@ -493,6 +494,7 @@ impl Compiler {
output_path: output_path.as_deref(),
names: source_map_names,
inline_sources_content,
emit_columns: emit_source_map_columns,
},
)
.to_writer(&mut buf)
@ -517,6 +519,7 @@ impl Compiler {
output_path: output_path.as_deref(),
names: source_map_names,
inline_sources_content,
emit_columns: emit_source_map_columns,
},
)
.to_writer(&mut buf)
@ -546,6 +549,8 @@ struct SwcSourceMapConfig<'a> {
names: &'a AHashMap<BytePos, JsWord>,
inline_sources_content: bool,
emit_columns: bool,
}
impl SourceMapGenConfig for SwcSourceMapConfig<'_> {
@ -584,6 +589,10 @@ impl SourceMapGenConfig for SwcSourceMapConfig<'_> {
fn inline_sources_content(&self, _: &FileName) -> bool {
self.inline_sources_content
}
fn emit_columns(&self, _f: &FileName) -> bool {
self.emit_columns
}
}
pub(crate) fn minify_file_comments(
@ -869,6 +878,7 @@ impl Compiler {
preserve_comments: config.preserve_comments,
inline_sources_content: config.inline_sources_content,
comments: config.comments,
emit_source_map_columns: config.emit_source_map_columns,
};
let orig = if config.source_maps.enabled() {
@ -1040,6 +1050,7 @@ impl Compiler {
orig.as_ref(),
true,
Some(&comments),
opts.emit_source_map_columns,
)
})
}
@ -1111,6 +1122,7 @@ impl Compiler {
orig,
config.minify,
config.comments.as_ref().map(|v| v as _),
config.emit_source_map_columns,
)
})
}

View File

@ -100,6 +100,7 @@ fn create_matrix(entry: &Path) -> Vec<Options> {
source_map: Default::default(),
output_path: Default::default(),
inline_sources_content: Default::default(),
emit_source_map_columns: Default::default(),
})
} else {
None

View File

@ -754,6 +754,7 @@ fn should_visit() {
preserve_comments: config.preserve_comments,
inline_sources_content: config.inline_sources_content,
comments: config.comments,
emit_source_map_columns: config.emit_source_map_columns,
};
if config.minify {
@ -785,6 +786,7 @@ fn should_visit() {
// TODO: figure out sourcemaps
config.minify,
Some(&comments),
config.emit_source_map_columns,
)
.unwrap()
.code)

View File

@ -279,6 +279,7 @@ fn issue_4112() {
&Options {
config: Config {
module: Some(ModuleConfig::CommonJs(Default::default())),
emit_source_map_columns: true.into(),
..Default::default()
},
source_maps: Some(SourceMapsConfig::Bool(true)),
@ -299,3 +300,88 @@ fn issue_4112() {
})
.unwrap()
}
#[test]
fn should_work_with_emit_source_map_columns() {
Tester::new().print_errors(|cm, handler| {
let c = Compiler::new(cm.clone());
let fm = cm.new_source_file(
swc_common::FileName::Real("./app.js".into()),
r#"import { createElement } from "react";
createElement('div', null, {});"#
.to_string(),
);
let result = c.process_js_file(
fm.clone(),
&handler,
&Options {
swcrc: false,
is_module: IsModule::Bool(true),
source_maps: Some(SourceMapsConfig::Bool(true)),
config: Config {
inline_sources_content: true.into(),
emit_source_map_columns: true.into(),
..Default::default()
},
..Default::default()
},
);
match result {
Ok(result) => {
assert!(result.map.is_some());
let map = result.map.unwrap();
let source_map = sourcemap::SourceMap::from_slice(map.as_bytes())
.expect("failed to deserialize sourcemap");
let token = source_map
.lookup_token(1, 14)
.expect("failed to find token");
assert_eq!(token.get_dst_line(), 1);
assert_eq!(token.get_dst_col(), 14);
assert_eq!(token.get_src_line(), 2);
assert_eq!(token.get_src_col(), 16);
}
Err(err) => {
panic!("Error: {:#?}", err);
}
}
let result2 = c.process_js_file(
fm,
&handler,
&Options {
swcrc: false,
is_module: IsModule::Bool(true),
source_maps: Some(SourceMapsConfig::Bool(true)),
config: Config {
inline_sources_content: true.into(),
emit_source_map_columns: false.into(),
..Default::default()
},
..Default::default()
},
);
match result2 {
Ok(result) => {
assert!(result.map.is_some());
let map = result.map.unwrap();
let source_map = sourcemap::SourceMap::from_slice(map.as_bytes())
.expect("failed to deserialize sourcemap");
let token = source_map
.lookup_token(1, 14)
.expect("failed to find token");
assert_eq!(token.get_dst_line(), 1);
assert_eq!(token.get_dst_col(), 0);
assert_eq!(token.get_src_line(), 2);
assert_eq!(token.get_src_col(), 2);
}
Err(err) => {
panic!("Error: {:#?}", err);
}
}
Ok(())
});
}

View File

@ -1166,6 +1166,7 @@ impl SourceMap {
let mut ch_start = 0;
let mut line_ch_start = 0;
let mut prev_dst_line = u32::MAX;
for (pos, lc) in mappings.iter() {
let pos = *pos;
@ -1205,6 +1206,12 @@ impl SourceMap {
}
};
let emit_columns = config.emit_columns(&f.name);
if !emit_columns && lc.line == prev_dst_line {
continue;
}
let a = match f.lookup_line(pos) {
Some(line) => line as u32,
None => continue,
@ -1242,6 +1249,7 @@ impl SourceMap {
}
builder.add_raw(lc.line, lc.col, line - 1, col, Some(src_id), name_idx);
prev_dst_line = lc.line;
}
builder.into_sourcemap()
@ -1329,6 +1337,11 @@ pub trait SourceMapGenConfig {
FileName::Real(..) | FileName::Custom(..) | FileName::Url(..)
)
}
/// You can define whether to emit sourcemap with columns or not
fn emit_columns(&self, _f: &FileName) -> bool {
true
}
}
#[derive(Debug, Clone)]

View File

@ -95,6 +95,7 @@ fn pass(input_dir: PathBuf) {
None,
false,
Some(&comments),
false,
)
.expect("failed to print?")
.code;