fix(xtask): restore stripped sourcesContent when building the wasm module
This commit is contained in:
parent
da61d7cac5
commit
f2e71ec95c
3 changed files with 83 additions and 4 deletions
|
|
@ -3,7 +3,7 @@ use std::{
|
|||
ffi::{OsStr, OsString},
|
||||
fmt::Write,
|
||||
fs,
|
||||
path::PathBuf,
|
||||
path::{Path, PathBuf},
|
||||
process::Command,
|
||||
time::Duration,
|
||||
};
|
||||
|
|
@ -16,7 +16,9 @@ use notify::{
|
|||
};
|
||||
use notify_debouncer_full::new_debouncer;
|
||||
|
||||
use crate::{bail_on_err, watch_wasm, BuildWasm, EMSCRIPTEN_TAG};
|
||||
use crate::{
|
||||
bail_on_err, embed_sources::embed_sources_in_map, watch_wasm, BuildWasm, EMSCRIPTEN_TAG,
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
enum EmccSource {
|
||||
|
|
@ -48,10 +50,14 @@ const EXPORTED_RUNTIME_METHODS: [&str; 19] = [
|
|||
];
|
||||
|
||||
pub fn run_wasm(args: &BuildWasm) -> Result<()> {
|
||||
let mut emscripten_flags = vec!["-O3", "--minify", "0"];
|
||||
let mut emscripten_flags = if args.debug {
|
||||
vec!["-O0", "--minify", "0"]
|
||||
} else {
|
||||
vec!["-O3", "--minify", "0"]
|
||||
};
|
||||
|
||||
if args.debug {
|
||||
emscripten_flags.extend(["-s", "ASSERTIONS=1", "-s", "SAFE_HEAP=1", "-O0", "-g"]);
|
||||
emscripten_flags.extend(["-s", "ASSERTIONS=1", "-s", "SAFE_HEAP=1", "-g"]);
|
||||
}
|
||||
|
||||
if args.verbose {
|
||||
|
|
@ -287,6 +293,17 @@ fn build_wasm(cmd: &mut Command, edit_tsd: bool) -> Result<()> {
|
|||
fs::write(file, content)?;
|
||||
}
|
||||
|
||||
// Post-process the source map to embed source content for optimized builds
|
||||
let map_path = Path::new("lib")
|
||||
.join("binding_web")
|
||||
.join("lib")
|
||||
.join("web-tree-sitter.wasm.map");
|
||||
if map_path.exists() {
|
||||
if let Err(e) = embed_sources_in_map(&map_path) {
|
||||
eprintln!("Warning: Failed to embed sources in source map: {e}");
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
61
crates/xtask/src/embed_sources.rs
Normal file
61
crates/xtask/src/embed_sources.rs
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
use anyhow::Result;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
/// Restores sourcesContent if it was stripped by Binaryen.
|
||||
///
|
||||
/// This is a workaround for Binaryen where `wasm-opt -O2` and higher
|
||||
/// optimization levels strip the `sourcesContent` field from source maps,
|
||||
/// even when the source map was generated with `--sources` flag.
|
||||
///
|
||||
/// This is fixed upstream in Binaryen as of Apr 9, 2025, but there hasn't been a release with the fix yet.
|
||||
/// See: <https://github.com/WebAssembly/binaryen/issues/6805>
|
||||
///
|
||||
/// This reads the original source files and embeds them in the
|
||||
/// source map's `sourcesContent` field, making debugging possible even
|
||||
/// with optimized builds.
|
||||
///
|
||||
/// TODO: Once Binaryen releases a version with the fix, and emscripten updates to that
|
||||
/// version, and we update our emscripten version, this function can be removed.
|
||||
pub fn embed_sources_in_map(map_path: &Path) -> Result<()> {
|
||||
let map_content = fs::read_to_string(map_path)?;
|
||||
let mut map: serde_json::Value = serde_json::from_str(&map_content)?;
|
||||
|
||||
if let Some(sources_content) = map.get("sourcesContent") {
|
||||
if let Some(arr) = sources_content.as_array() {
|
||||
if !arr.is_empty() && arr.iter().any(|v| !v.is_null()) {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let sources = map["sources"]
|
||||
.as_array()
|
||||
.ok_or_else(|| anyhow::anyhow!("No sources array in source map"))?;
|
||||
|
||||
let map_dir = map_path.parent().unwrap_or(Path::new("."));
|
||||
let mut sources_content = Vec::new();
|
||||
|
||||
for source in sources {
|
||||
let source_path = source.as_str().unwrap_or("");
|
||||
let full_path = map_dir.join(source_path);
|
||||
|
||||
let content = if full_path.exists() {
|
||||
match fs::read_to_string(&full_path) {
|
||||
Ok(content) => serde_json::Value::String(content),
|
||||
Err(_) => serde_json::Value::Null,
|
||||
}
|
||||
} else {
|
||||
serde_json::Value::Null
|
||||
};
|
||||
|
||||
sources_content.push(content);
|
||||
}
|
||||
|
||||
map["sourcesContent"] = serde_json::Value::Array(sources_content);
|
||||
|
||||
let output = serde_json::to_string(&map)?;
|
||||
fs::write(map_path, output)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ mod build_wasm;
|
|||
mod bump;
|
||||
mod check_wasm_exports;
|
||||
mod clippy;
|
||||
mod embed_sources;
|
||||
mod fetch;
|
||||
mod generate;
|
||||
mod test;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue