Skip to content

Commit e0f676b

Browse files
authored
Turbopack: sourcemaps for JSON modules (#84611)
Closes PACK-5637 Generate sourcemaps for JSON modules, which better attributes bundle sizes in tools such as source-map-explorer (These should never show up in stack traces) <img width="1509" height="502" alt="Bildschirmfoto 2025-10-07 um 17 03 00" src="https://github.com/user-attachments/assets/0c41bade-36cd-417a-b32d-f5cc3dfe3a7a" /> <img width="374" height="470" alt="Bildschirmfoto 2025-10-07 um 15 01 14" src="https://github.com/user-attachments/assets/a93d322e-cca2-4624-ba6c-d23febc3fa87" />
1 parent 642ae3e commit e0f676b

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

turbopack/crates/turbopack-json/src/lib.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use turbo_tasks_fs::{FileContent, FileJsonContent, glob::Glob};
1818
use turbopack_core::{
1919
asset::{Asset, AssetContent},
2020
chunk::{ChunkItem, ChunkType, ChunkableModule, ChunkingContext},
21+
code_builder::CodeBuilder,
2122
ident::AssetIdent,
2223
module::Module,
2324
module_graph::ModuleGraph,
@@ -130,16 +131,41 @@ impl EcmascriptChunkItem for JsonChunkItem {
130131
match &*data {
131132
FileJsonContent::Content(data) => {
132133
let data_str = data.to_string();
133-
let inner_code = if data_str.len() > 10_000 {
134+
135+
let mut code = CodeBuilder::default();
136+
137+
let source_code = if data_str.len() > 10_000 {
134138
// Only use JSON.parse if the content is larger than 10kb
135139
// https://v8.dev/blog/cost-of-javascript-2019#json
136140
let js_str_content = serde_json::to_string(&data_str)?;
137141
format!("{TURBOPACK_EXPORT_VALUE}(JSON.parse({js_str_content}));")
138142
} else {
139143
format!("{TURBOPACK_EXPORT_VALUE}({data_str});")
140144
};
145+
146+
let source_code = source_code.into();
147+
let source_map = serde_json::json!({
148+
"version": 3,
149+
// TODO: Encode using `urlencoding`, so that these
150+
// are valid URLs. However, `project_trace_source_operation` (and
151+
// `uri_from_file`) need to handle percent encoding correctly first.
152+
//
153+
// See turbopack/crates/turbopack-core/src/source_map/utils.rs as well
154+
"sources": [format!("turbopack:///{}", self.module.ident().path().to_string().await?)],
155+
"sourcesContent": [&data_str],
156+
"names": [],
157+
// Maps 0:0 in the output code to 0:0 in the `source_code`. Sufficient for
158+
// bundle analyzers to attribute the bytes in the output chunks
159+
"mappings": "AAAA",
160+
})
161+
.to_string()
162+
.into();
163+
code.push_source(&source_code, Some(source_map));
164+
165+
let code = code.build();
141166
Ok(EcmascriptChunkItemContent {
142-
inner_code: inner_code.into(),
167+
source_map: Some(code.generate_source_map_ref(None)),
168+
inner_code: code.into_source_code(),
143169
..Default::default()
144170
}
145171
.into())

turbopack/crates/turbopack-tests/tests/snapshot/imports/json/output/turbopack_crates_turbopack-tests_tests_snapshot_imports_json_input_fc5f1049._.js.map

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

0 commit comments

Comments
 (0)