Skip to content

Commit

Permalink
Trace output's source maps through input's source map (#6494)
Browse files Browse the repository at this point in the history
### Description

This preserves an input file's original source map so that the
transformed output source map can be traced through it.

### Testing Instructions

<!--
  Give a quick description of steps to test your changes.
-->


Closes PACK-1980
Closes PACK-537

---------

Co-authored-by: Tobias Koppers <tobias.koppers@googlemail.com>
Co-authored-by: Will Binns-Smith <wbinnssmith@gmail.com>
  • Loading branch information
3 people committed Dec 14, 2023
1 parent 7d458ce commit 000d264
Show file tree
Hide file tree
Showing 15 changed files with 245 additions and 407 deletions.
30 changes: 8 additions & 22 deletions crates/turbopack-build/src/ecmascript/minify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,29 +29,14 @@ use turbopack_ecmascript::ParseResultSourceMap;

#[turbo_tasks::function]
pub async fn minify(path: Vc<FileSystemPath>, code: Vc<Code>) -> Result<Vc<Code>> {
let original_map = *code.generate_source_map().await?;
let minified_code = perform_minify(path, code);
let path = path.await?;
let original_map = code.generate_source_map().await?.clone_value();
let code = code.await?;

let merged = match (original_map, *minified_code.generate_source_map().await?) {
(Some(original_map), Some(minify_map)) => Some(Vc::upcast(original_map.trace(minify_map))),
_ => None,
};

let mut builder = CodeBuilder::default();
builder.push_source(minified_code.await?.source_code(), merged);
let path = &*path.await?;
let filename = path.file_name();
write!(builder, "\n\n//# sourceMappingURL={}.map", filename)?;
Ok(builder.build().cell())
}

#[turbo_tasks::function]
async fn perform_minify(path: Vc<FileSystemPath>, code_vc: Vc<Code>) -> Result<Vc<Code>> {
let code = &*code_vc.await?;
let cm = Arc::new(SwcSourceMap::new(FilePathMapping::empty()));
let compiler = Arc::new(Compiler::new(cm.clone()));
let fm = compiler.cm.new_source_file(
FileName::Custom((*path.await?.path).to_string()),
FileName::Custom(path.path.to_string()),
code.source_code().to_str()?.to_string(),
);

Expand Down Expand Up @@ -112,11 +97,12 @@ async fn perform_minify(path: Vc<FileSystemPath>, code_vc: Vc<Code>) -> Result<V
let mut builder = CodeBuilder::default();
builder.push_source(
&src.into(),
Some(*Box::new(Vc::upcast(
ParseResultSourceMap::new(cm, src_map_buf).cell(),
))),
Some(Vc::upcast(
ParseResultSourceMap::new(cm, src_map_buf, original_map).cell(),
)),
);

write!(builder, "\n\n//# sourceMappingURL={}.map", path.file_name())?;
Ok(builder.build().cell())
}

Expand Down
44 changes: 35 additions & 9 deletions crates/turbopack-core/src/reference/source_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ use turbo_tasks::{ValueToString, Vc};
use turbo_tasks_fs::{FileSystemEntryType, FileSystemPath};

use super::ModuleReference;
use crate::{file_source::FileSource, raw_module::RawModule, resolve::ModuleResolveResult};
use crate::{
file_source::FileSource,
raw_module::RawModule,
resolve::ModuleResolveResult,
source_map::{GenerateSourceMap, OptionSourceMap, SourceMap},
};

#[turbo_tasks::value]
pub struct SourceMapReference {
Expand All @@ -19,23 +24,44 @@ impl SourceMapReference {
}
}

#[turbo_tasks::value_impl]
impl ModuleReference for SourceMapReference {
#[turbo_tasks::function]
async fn resolve_reference(&self) -> Vc<ModuleResolveResult> {
impl SourceMapReference {
async fn get_file(&self) -> Option<Vc<FileSystemPath>> {
let file_type = self.file.get_type().await;
if let Ok(file_type_result) = file_type.as_ref() {
if let FileSystemEntryType::File = &**file_type_result {
return ModuleResolveResult::module(Vc::upcast(RawModule::new(Vc::upcast(
FileSource::new(self.file),
))))
.cell();
return Some(self.file);
}
}
None
}
}

#[turbo_tasks::value_impl]
impl ModuleReference for SourceMapReference {
#[turbo_tasks::function]
async fn resolve_reference(&self) -> Vc<ModuleResolveResult> {
if let Some(file) = self.get_file().await {
return ModuleResolveResult::module(Vc::upcast(RawModule::new(Vc::upcast(
FileSource::new(file),
))))
.cell();
}
ModuleResolveResult::unresolveable().into()
}
}

#[turbo_tasks::value_impl]
impl GenerateSourceMap for SourceMapReference {
#[turbo_tasks::function]
async fn generate_source_map(&self) -> Result<Vc<OptionSourceMap>> {
let Some(file) = self.get_file().await else {
return Ok(Vc::cell(None));
};
let source_map = SourceMap::new_from_file(file).await?;
Ok(Vc::cell(source_map.map(|m| m.cell())))
}
}

#[turbo_tasks::value_impl]
impl ValueToString for SourceMapReference {
#[turbo_tasks::function]
Expand Down
Loading

0 comments on commit 000d264

Please sign in to comment.