Skip to content

Add an "apply source map" button to the profile info panel - #6200

Merged
canova merged 4 commits into
firefox-devtools:mainfrom
canova:sourcemap-button
Jul 28, 2026
Merged

Add an "apply source map" button to the profile info panel#6200
canova merged 4 commits into
firefox-devtools:mainfrom
canova:sourcemap-button

Conversation

@canova

@canova canova commented Jul 20, 2026

Copy link
Copy Markdown
Member

Main | Deploy preview

Fixes #6195.

This PR adds a "Apply source map…" button to the Profile info panel, which can be used to apply any source map from the disk.

This is the new button:
Screenshot 2026-07-20 at 11 07 32

When you select a source map, it looks at the file name of the .map file, and tries to match to any sourceMapURL fields in the source table. If there is a match, it automatically uses that source and applies the source map.

If it can't find any source that matches the name, or if it finds multiple sources that matches the name, then we prompt the user a select input to pick one. Once the source is picked, then we apply the source map at that point to the selected source.

This is the select when it can't match:

Screenshot 2026-07-20 at 11 02 27 Screenshot 2026-07-20 at 11 02 31

We also try to give some feedback to the user:
Screenshot 2026-07-20 at 11 02 43


Here's an example profile to test:
This is a profile of profiler.firefox.com without the source map applied: Production / Deploy preview
And this is the source map for our main bundle: index-XVVABR7J.js.map.zip
(note you have to unzip it before using, apparently github doesn't allow uploading .map file extensions, so I had to zip it)
You can open this profile link, then click on the button and select this source map. You should see the applied source map function names as well as JS source contents.

@canova
canova requested a review from mstange July 20, 2026 09:08
@canova
canova requested a review from a team as a code owner July 20, 2026 09:08
@codecov

codecov Bot commented Jul 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.56701% with 28 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.65%. Comparing base (6d734d2) to head (342d130).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...omponents/app/MenuButtons/ApplySourceMapButton.tsx 80.45% 17 Missing ⚠️
src/actions/source-map-symbolication.ts 73.80% 11 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6200      +/-   ##
==========================================
+ Coverage   83.63%   83.65%   +0.02%     
==========================================
  Files         346      348       +2     
  Lines       37153    37339     +186     
  Branches    10315    10376      +61     
==========================================
+ Hits        31073    31237     +164     
- Misses       5652     5674      +22     
  Partials      428      428              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

* text (fetched alongside the source maps). Used for scope-tree-based function
* name resolution.
*/
export type SourceMapSymbolicationResult = 'applied' | 'no-match' | 'error';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use TS enum classes these days, but this is fine too

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yeah, I always forget that we support them now.

@mstange mstange left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems fine. The UI can probably be improved but it also doesn't cause any harm. Thanks!

Comment on lines +54 to +55
* mappings / sources), and for index maps (which carry a `sections` field and
* are not supported here).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's an index map? Can you link to a spec or to MDN docs?

@canova canova Jul 28, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An index map is an alternative format to source maps actually, which is also part of the source map spec: https://tc39.es/ecma426/#sec-index-source-map If I understand correctly, they have sections array as a top level field instead of mappings.

But we currently don't support it because it's not supported by any web bundlers. And I'm not so sure about others, but I think it's safe to say that it's not used that much at all. We can consider adding that support if we notice that there are some important bundlers/compilers that output it. I looked at the source-map package and it looks like it supports it, so it's mostly glue work to make that happen.

(also updated the code comment there to explain it)

canova added 4 commits July 28, 2026 13:18
Change the return type from `Promise<void>` to a `Promise<'applied' |
'no-match' | 'error'>` so callers can tell a valid-but-unmatched run
apart from a worker failure. The existing load-time caller in
receive-profile ignores the value, so this is behavior-neutral.

The following file based symbolication path will use the result to show
proper errors in its UI
Pure helpers for the upcoming "apply a .map file from disk" flow:

- getSourcesWithSourceMapURL lists the profile sources that carry a
  sourceMapURL and are therefore eligible targets for a source map.
- parseSourceMapFileContents parses and validates a .map file, rejecting
  index maps.
- matchSourceMapToSource auto-matches a user-supplied map to a source by
  filename/sourceMapURL basename, returning an 'ambiguous' result (with
  candidates) when more than one source could match. Handles ?query,
  backslash paths, and the ".map"/".json" suffixes browsers append when
  saving a map served as JSON.
Add a thunk that takes a .map file the user selected from disk, parses
and auto-matches it to an eligible bundle source (or reports the match
as ambiguous so the UI can prompt), then runs it through the existing
doSourceMapSymbolication pipeline.

Unlike the WebChannel path, eligibility only requires a sourceMapURL (no
UUID id), since the map contents are supplied directly rather than
fetched.
The profiler already has a full JS source-map symbolication pipeline,
but it only runs at load time when the browser provides source maps over
the WebChannel. Profiles loaded from a file (or whose maps the browser
couldn't fetch) had no way to symbolicate JS stacks. This adds a button
in the Profile Info panel that accepts a .map file from disk and feeds
it into the applySourceMapFile pipeline.

The button is shown whenever the profile has at least one source with a
sourceMapURL. It reads the file, runs the apply action, and reports
which source was resolved, prompting with a picker when the match is
ambiguous and showing an error otherwise.
@canova
canova force-pushed the sourcemap-button branch from 6de4d0f to 342d130 Compare July 28, 2026 11:18
@canova
canova merged commit 31576f7 into firefox-devtools:main Jul 28, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add an "apply source maps" button to the UI for applying them later or from disk

3 participants