Skip to content

Commit f650fee

Browse files
committed
Add support for inline source maps in input
Closes parcel-bundler#219
1 parent d1cee40 commit f650fee

File tree

7 files changed

+122
-44
lines changed

7 files changed

+122
-44
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,12 @@ parcel_selectors = { version = "0.24.4", path = "./selectors" }
3131
itertools = "0.10.1"
3232
smallvec = { version = "1.7.0", features = ["union"] }
3333
bitflags = "1.3.2"
34-
parcel_sourcemap = "2.0.2"
34+
parcel_sourcemap = { version = "2.1.0", features = ["json"] }
3535
data-encoding = "2.3.2"
3636
lazy_static = "1.4.0"
3737
const-str = "0.3.1"
3838
# CLI deps
3939
clap = { version = "3.0.6", features = ["derive"], optional = true }
40-
serde_json = { version = "1.0.78", optional = true }
4140
pathdiff = { version = "0.2.1", optional = true }
4241
browserslist-rs = { version = "0.7.0", optional = true }
4342
rayon = "1.5.1"
@@ -51,11 +50,11 @@ indoc = "1.0.3"
5150
assert_cmd = "2.0"
5251
assert_fs = "1.0"
5352
predicates = "2.1"
54-
serde_json = "1.0.78"
53+
serde_json = "1"
5554

5655
[features]
5756
default = ["grid"]
58-
cli = ["clap", "serde_json", "pathdiff", "browserslist-rs", "jemallocator"]
57+
cli = ["clap", "pathdiff", "browserslist-rs", "jemallocator"]
5958
grid = []
6059
serde = ["smallvec/serde", "cssparser/serde"]
6160

node/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@ crate-type = ["cdylib"]
1111
[dependencies]
1212
serde = { version = "1.0.123", features = ["derive"] }
1313
serde_bytes = "0.11.5"
14-
serde_json = "*"
1514
cssparser = "0.29.1"
1615
parcel_css = { path = "../" }
17-
parcel_sourcemap = "2.0.2"
16+
parcel_sourcemap = { version = "2.1.0", features = ["json"] }
1817

1918
[target.'cfg(target_os = "macos")'.dependencies]
2019
jemallocator = { version = "0.3.2", features = ["disable_initial_exec_tls"] }

node/src/lib.rs

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,6 @@ use napi::{CallContext, JsObject, JsUnknown};
4949
#[cfg(not(target_arch = "wasm32"))]
5050
use napi_derive::{js_function, module_exports};
5151

52-
#[derive(Serialize)]
53-
#[serde(rename_all = "camelCase")]
54-
struct SourceMapJson<'a> {
55-
version: u8,
56-
mappings: String,
57-
sources: &'a Vec<String>,
58-
sources_content: &'a Vec<String>,
59-
names: &'a Vec<String>,
60-
}
61-
6252
#[derive(Serialize)]
6353
#[serde(rename_all = "camelCase")]
6454
struct TransformResult {
@@ -299,7 +289,7 @@ fn compile<'i>(code: &'i str, config: &Config) -> Result<TransformResult, Compil
299289
})?;
300290

301291
let map = if let Some(mut source_map) = source_map {
302-
Some(source_map_to_json(&mut source_map)?)
292+
source_map.to_json(None).ok()
303293
} else {
304294
None
305295
};
@@ -363,7 +353,7 @@ fn compile_bundle<'i>(fs: &'i FileProvider, config: &BundleConfig) -> Result<Tra
363353
})?;
364354

365355
let map = if let Some(source_map) = &mut source_map {
366-
Some(source_map_to_json(source_map)?)
356+
source_map.to_json(None).ok()
367357
} else {
368358
None
369359
};
@@ -377,22 +367,6 @@ fn compile_bundle<'i>(fs: &'i FileProvider, config: &BundleConfig) -> Result<Tra
377367
})
378368
}
379369

380-
#[inline]
381-
fn source_map_to_json<'i>(source_map: &mut SourceMap) -> Result<Vec<u8>, CompileError<'i>> {
382-
let mut vlq_output: Vec<u8> = Vec::new();
383-
source_map.write_vlq(&mut vlq_output)?;
384-
385-
let sm = SourceMapJson {
386-
version: 3,
387-
mappings: unsafe { String::from_utf8_unchecked(vlq_output) },
388-
sources: source_map.get_sources(),
389-
sources_content: source_map.get_sources_content(),
390-
names: source_map.get_names(),
391-
};
392-
393-
Ok(serde_json::to_vec(&sm).unwrap())
394-
}
395-
396370
#[derive(Serialize, Debug, Deserialize)]
397371
#[serde(rename_all = "camelCase")]
398372
struct AttrConfig {

src/lib.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19012,4 +19012,33 @@ mod tests {
1901219012
minify_test(".foo { z-index: 9999999 }", ".foo{z-index:9999999}");
1901319013
minify_test(".foo { z-index: -9999999 }", ".foo{z-index:-9999999}");
1901419014
}
19015+
19016+
#[test]
19017+
fn test_input_source_map() {
19018+
let source = r#".imported {
19019+
content: "yay, file support!";
19020+
}
19021+
19022+
.selector {
19023+
margin: 1em;
19024+
background-color: #f60;
19025+
}
19026+
19027+
.selector .nested {
19028+
margin: 0.5em;
19029+
}
19030+
19031+
/*# sourceMappingURL=data:application/json;base64,ewoJInZlcnNpb24iOiAzLAoJInNvdXJjZVJvb3QiOiAicm9vdCIsCgkiZmlsZSI6ICJzdGRvdXQiLAoJInNvdXJjZXMiOiBbCgkJInN0ZGluIiwKCQkic2Fzcy9fdmFyaWFibGVzLnNjc3MiLAoJCSJzYXNzL19kZW1vLnNjc3MiCgldLAoJInNvdXJjZXNDb250ZW50IjogWwoJCSJAaW1wb3J0IFwiX3ZhcmlhYmxlc1wiO1xuQGltcG9ydCBcIl9kZW1vXCI7XG5cbi5zZWxlY3RvciB7XG4gIG1hcmdpbjogJHNpemU7XG4gIGJhY2tncm91bmQtY29sb3I6ICRicmFuZENvbG9yO1xuXG4gIC5uZXN0ZWQge1xuICAgIG1hcmdpbjogJHNpemUgLyAyO1xuICB9XG59IiwKCQkiJGJyYW5kQ29sb3I6ICNmNjA7XG4kc2l6ZTogMWVtOyIsCgkJIi5pbXBvcnRlZCB7XG4gIGNvbnRlbnQ6IFwieWF5LCBmaWxlIHN1cHBvcnQhXCI7XG59IgoJXSwKCSJtYXBwaW5ncyI6ICJBRUFBLFNBQVMsQ0FBQztFQUNSLE9BQU8sRUFBRSxvQkFBcUI7Q0FDL0I7O0FGQ0QsU0FBUyxDQUFDO0VBQ1IsTUFBTSxFQ0hELEdBQUc7RURJUixnQkFBZ0IsRUNMTCxJQUFJO0NEVWhCOztBQVBELFNBQVMsQ0FJUCxPQUFPLENBQUM7RUFDTixNQUFNLEVDUEgsS0FBRztDRFFQIiwKCSJuYW1lcyI6IFtdCn0= */"#;
19032+
19033+
let mut stylesheet = StyleSheet::parse("test.css", &source, ParserOptions::default()).unwrap();
19034+
stylesheet.minify(MinifyOptions::default()).unwrap();
19035+
let mut sm = parcel_sourcemap::SourceMap::new("/");
19036+
stylesheet.to_css(PrinterOptions {
19037+
source_map: Some(&mut sm),
19038+
minify: true,
19039+
..PrinterOptions::default()
19040+
}).unwrap();
19041+
let map = sm.to_json(None).unwrap();
19042+
assert_eq!(map, r#"{"version":3,"sourceRoot":null,"mappings":"AEAA,uCFGA,2CAAA","sources":["stdin","sass/_variables.scss","sass/_demo.scss"],"sourcesContent":["@import \"_variables\";\n@import \"_demo\";\n\n.selector {\n margin: $size;\n background-color: $brandColor;\n\n .nested {\n margin: $size / 2;\n }\n}","$brandColor: #f60;\n$size: 1em;",".imported {\n content: \"yay, file support!\";\n}"],"names":[]}"#);
19043+
}
1901519044
}

src/printer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub struct PseudoClasses<'a> {
6060
pub struct Printer<'a, 'b, 'c, W> {
6161
pub(crate) sources: Option<&'c Vec<String>>,
6262
dest: &'a mut W,
63-
source_map: Option<&'a mut SourceMap>,
63+
pub(crate) source_map: Option<&'a mut SourceMap>,
6464
pub(crate) loc: Location,
6565
indent: u8,
6666
line: u32,

src/stylesheet.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::rules::{CssRule, CssRuleList, MinifyContext};
1515
use crate::targets::Browsers;
1616
use crate::traits::ToCss;
1717
use cssparser::{Parser, ParserInput, RuleListParser};
18+
use parcel_sourcemap::SourceMap;
1819
use std::collections::{HashMap, HashSet};
1920

2021
pub use crate::parser::ParserOptions;
@@ -65,6 +66,8 @@ pub struct StyleSheet<'i, 'o> {
6566
/// A list of file names for all source files included within the style sheet.
6667
/// Sources are referenced by index in the `loc` property of each rule.
6768
pub sources: Vec<String>,
69+
/// The source map URL extracted from the original style sheet.
70+
pub source_map_url: Option<String>,
6871
#[cfg_attr(feature = "serde", serde(skip))]
6972
/// The options the style sheet was originally parsed with.
7073
options: ParserOptions<'o>,
@@ -103,6 +106,7 @@ impl<'i, 'o> StyleSheet<'i, 'o> {
103106
pub fn new(sources: Vec<String>, rules: CssRuleList<'i>, options: ParserOptions<'o>) -> StyleSheet<'i, 'o> {
104107
StyleSheet {
105108
sources,
109+
source_map_url: None,
106110
rules,
107111
options,
108112
}
@@ -128,11 +132,18 @@ impl<'i, 'o> StyleSheet<'i, 'o> {
128132

129133
Ok(StyleSheet {
130134
sources: vec![filename],
135+
source_map_url: parser.current_source_map_url().map(|s| s.to_owned()),
131136
rules: CssRuleList(rules),
132137
options,
133138
})
134139
}
135140

141+
/// Returns the inline source map associated with the style sheet.
142+
pub fn source_map(&self) -> Option<SourceMap> {
143+
let source_map_url = self.source_map_url.as_ref()?;
144+
SourceMap::from_data_url("/", source_map_url).ok()
145+
}
146+
136147
/// Minify and transform the style sheet for the provided browser targets.
137148
pub fn minify(&mut self, options: MinifyOptions) -> Result<(), Error<MinifyErrorKind>> {
138149
let mut context = PropertyHandlerContext::new(options.targets, &options.unused_symbols);
@@ -206,6 +217,13 @@ impl<'i, 'o> StyleSheet<'i, 'o> {
206217
} else {
207218
self.rules.to_css(&mut printer)?;
208219
printer.newline()?;
220+
221+
if let Some(sm) = printer.source_map {
222+
if let Some(mut input_sm) = self.source_map() {
223+
let _ = sm.extends(&mut input_sm);
224+
}
225+
}
226+
209227
Ok(ToCssResult {
210228
dependencies: printer.dependencies,
211229
code: dest,

0 commit comments

Comments
 (0)