Skip to content

Commit

Permalink
feat: Add support for debug IDs
Browse files Browse the repository at this point in the history
  • Loading branch information
timfish committed Jan 6, 2025
1 parent 649c656 commit 7bee3ee
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 10 deletions.
1 change: 1 addition & 0 deletions crates/node_binding/binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1975,6 +1975,7 @@ export interface RawSourceMapDevToolPluginOptions {
test?: string | RegExp | (string | RegExp)[]
include?: string | RegExp | (string | RegExp)[]
exclude?: string | RegExp | (string | RegExp)[]
debugIds?: boolean
}

export interface RawSplitChunkSizes {
Expand Down
2 changes: 2 additions & 0 deletions crates/rspack_binding_values/src/raw_options/raw_devtool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ pub struct RawSourceMapDevToolPluginOptions {
pub include: Option<RawAssetConditions>,
#[napi(ts_type = "string | RegExp | (string | RegExp)[]")]
pub exclude: Option<RawAssetConditions>,
pub debug_ids: Option<bool>,
}

impl From<RawSourceMapDevToolPluginOptions> for SourceMapDevToolPluginOptions {
Expand Down Expand Up @@ -153,6 +154,7 @@ impl From<RawSourceMapDevToolPluginOptions> for SourceMapDevToolPluginOptions {
test: opts.test.map(into_asset_conditions),
include: opts.include.map(into_asset_conditions),
exclude: opts.exclude.map(into_asset_conditions),
debug_ids: opts.debug_ids.unwrap_or(false),
}
}
}
Expand Down
62 changes: 53 additions & 9 deletions crates/rspack_plugin_devtool/src/source_map_dev_tool_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,36 @@ pub struct SourceMapDevToolPluginOptions {
pub test: Option<AssetConditions>,
pub include: Option<AssetConditions>,
pub exclude: Option<AssetConditions>,
pub debug_ids: bool,
}

fn create_debug_id(filename: &str, source: &[u8]) -> String {
// We need two 64 bit hashes to give us the 128 bits required for a uuid
// The first 64 bit hash is built from the source
let mut hasher = RspackHash::new(&rspack_hash::HashFunction::Xxhash64);
hasher.write(source);
let hash1 = hasher.finish().to_le_bytes();

// The second 64 bit hash is built from the filename and the source hash
let mut hasher = RspackHash::new(&rspack_hash::HashFunction::Xxhash64);
hasher.write(filename.as_bytes());
hasher.write(&hash1);
let hash2 = hasher.finish().to_le_bytes();

let mut bytes = [hash1, hash2].concat();

// Build the uuid from the 16 bytes
let mut uuid = String::with_capacity(36);
bytes[6] = (bytes[6] & 0x0f) | 0x40;
bytes[8] = (bytes[8] & 0x3f) | 0x80;

for (i, byte) in bytes.iter().enumerate() {
if i == 4 || i == 6 || i == 8 || i == 10 {
uuid.push('-');
}
uuid.push_str(&format!("{byte:02x}"));
}
uuid
}

enum SourceMappingUrlComment {
Expand Down Expand Up @@ -119,6 +149,7 @@ pub struct SourceMapDevToolPlugin {
test: Option<AssetConditions>,
include: Option<AssetConditions>,
exclude: Option<AssetConditions>,
debug_ids: bool,
mapped_assets_cache: MappedAssetsCache,
}

Expand Down Expand Up @@ -183,6 +214,7 @@ impl SourceMapDevToolPlugin {
options.test,
options.include,
options.exclude,
options.debug_ids,
MappedAssetsCache::new(),
)
}
Expand Down Expand Up @@ -369,9 +401,17 @@ impl SourceMapDevToolPlugin {
.into_iter()
.map(|(source_filename, source, source_map)| {
async {
let source_map_json = match source_map {
Some(map) => Some(map.to_json().into_diagnostic()?),
None => None,
let (source_map_json, debug_id) = match source_map {
Some(mut map) => {
let debug_id = self.debug_ids.then(|| {
let debug_id = create_debug_id(&source_filename, &source.buffer());
map.set_debug_id(Some(debug_id.clone()));
debug_id
});

(Some(map.to_json().into_diagnostic()?), debug_id)
}
None => (None, None),
};

let mut asset = compilation
Expand Down Expand Up @@ -473,15 +513,19 @@ impl SourceMapDevToolPlugin {
.always_ok()
}
};
let current_source_mapping_url_comment = current_source_mapping_url_comment
.cow_replace("[url]", &source_map_url)
.into_owned();

let debug_id_comment = debug_id
.map(|id| format!("\n//# debugId={id}"))
.unwrap_or_default();

asset.source = Some(
ConcatSource::new([
source.clone(),
RawStringSource::from(
current_source_mapping_url_comment
.cow_replace("[url]", &source_map_url)
.into_owned(),
)
.boxed(),
RawStringSource::from(debug_id_comment).boxed(),
RawStringSource::from(current_source_mapping_url_comment).boxed(),
])
.boxed(),
);
Expand Down
4 changes: 3 additions & 1 deletion packages/rspack/src/rspackOptionsApply.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ export class RspackOptionsApply {
const cheap = options.devtool.includes("cheap");
const moduleMaps = options.devtool.includes("module");
const noSources = options.devtool.includes("nosources");
const debug_ids = options.devtool.includes("debugids");
const Plugin = evalWrapped
? EvalSourceMapDevToolPlugin
: SourceMapDevToolPlugin;
Expand All @@ -200,7 +201,8 @@ export class RspackOptionsApply {
module: moduleMaps ? true : !cheap,
columns: !cheap,
noSources: noSources,
namespace: options.output.devtoolNamespace
namespace: options.output.devtoolNamespace,
debugIds: debug_ids,
}).apply(compiler);
} else if (options.devtool.includes("eval")) {
new EvalDevToolModulePlugin({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const fs = require("fs");

it("source should include debug id that matches debugId key in sourcemap", function() {
const source = fs.readFileSync(__filename, "utf-8");
const sourceMap = fs.readFileSync(__filename + ".map", "utf-8");
const map = JSON.parse(sourceMap);
expect(map.debugId).toBeDefined();
expect(
/[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/i.test(map.debugId)
).toBe(true);
expect(source).toContain(`//# debugId=${map.debugId}`);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/** @type {import("../../../../").Configuration} */
module.exports = {
devtool: "source-map-debugids"
};

0 comments on commit 7bee3ee

Please sign in to comment.