question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Proposal: Source maps v4

See original GitHub issue

Feature request

What is the expected behavior? Analyzing JS stack traces is complex. Source maps provide a reasonable debugging experience at runtime, but when analyzing an exception, it’s difficult to reconstruct an unminified stack trace, even with V3 source maps available. The best case of this often is that the token at the point of the error can be discovered, so a language parser will need to walk backward from that token to try to find a function declaration to get the name.

Consider a tiny example such as this:

function causeError() {
  throw new Error('Expected failure.');
}
causeError();

Upon minification, this might become:

(()=>{throw new Error('Expected failure.')})();

A plain rendering of this in an error stack might look like:

Error: Expected failure.
    at example.js:1:13
    at example.js:1:45

With source maps, we can get a pretty reasonable output:

Error: Expected failure.
    at example-src.js:2:3
    at example-src.js:4:1

However, the token at 2:3 is throw. That isn’t terribly useful. If I reconstructed that stack by hand, I would expect:

Error: Expected failure.
    at causeError (example-src.js:2:3)
    at Global code (example-src.js:4:1)

To that end, the Edge DevTools team are proposing a v4 of Source Maps that will support this by encoding a notion of “scopes” – source text ranges that correspond to a given runtime name. This is at MicrosoftEdge/MSEdgeExplainers#538.

What is motivation or use case for adding/changing the behavior? We’ve seen other tools that do this – https://github.com/bloomberg/pasta-sourcemaps as an example – but if we can standardize this, we can incorporate that functionality into our everyday developer tools.

How should this be implemented in your opinion? The spec proposes that the scopes field would be comprised of a list 6 VLQs for each scope name mapping:

  • Source index
  • Start line
  • Start column
  • End line
  • End column
  • Scope name index

Given an input source map from a tool like TypeScript already producing these values, the only thing a tool like Webpack would need to do is combine all of them, in this case, combining and de-duping the scopeNames field, and providing a small amount of modification (updating the source index and scope name index) when combining all of the various scopes values from each of the input source maps.

Are you willing to work on this yourself? Yes. And, I’ve been working on producing this in TypeScript as well – microsoft/typescript#47152

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:9 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
robpalmecommented, Dec 17, 2021

Hey all, glad to see interest and energy on this proposal. Here’s some background from the previous work we did on this that may address @sokra’s questions.

Background

In pasta at least, the reason for expressing the named scope as a range (two coordinates) rather than a single point (one coordinate) is consequence of two key design decisions:

  1. Scope name decoding is based on source location
    • As usual, you first take the generated location and decode a source location. The new step is to then map that source location to a source scope name
    • The alternative (as @sokra says) would be to key scope name decoding off the generated location, which may well be more direct. This would work, but it offers less information and involves some repetition of the source name index each time you return to a previous scope. Almost all use-cases require computing source location anyway, so it is easily at hand to perform the subsequent name lookup.
  2. Scope declarations are per-function - meaning nested instead of linear
// *nested*                            // *linear*
| "<top-level>"                        | "<top-level>"
|                                      |
|  |  "causeError"         vs            |  "causeError"
|  |                                     |
|                                      | "<top-level>"

The nested approach means it only needs one VLQ entry per-function. Whereas with the linear approach, a function that has many inner functions needs to repeatedly reference the same name as you go into and out of the children.

The nested approach has a semantic benefit - it truly expresses the logical structure of the source code, i.e. there is a 1:1 correspondence of VLQ entries and functions. So you can easily disambiguate edge cases such as two contiguous functions with the same name, or a function within a function of the same name. Additionally, taking @sokra’s suggestion that we might want future extensions, it seems more likely for that to become useful if we keep the data associated with a semantic per-function datastructure, e.g. you could imagine adding more per-function metadata such as isExported, isAsync, isDeprecated, listOfDecorators.

Discussion

The above is core spec discussion rather than anything specific to webpack, so maybe we should talk about this in the proposal repo? This also highlights the need for us to build recorded rationale for each key design decision so we can get more buy-in and avoid explaining these same things across repos. I think @ldarbi can help with that.

Maybe it would also be good to chat about this in the TC39 Tooling Group run by @romulocintra. That brings together the kind of folk who would be interested in this. I think the next meeting will be mid-January (the github is a little out of date).

0reactions
webpack-botcommented, Aug 14, 2022

Issue was closed because of inactivity.

If you think this is still a valid issue, please file a new issue with additional information.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Proposal: Source Maps v4 (or v3.1): Improved post-hoc ...
Proposal : Source Maps v4 (or v3.1): Improved post-hoc debuggability #12. Open. robpaveza opened this issue on Jan 19 · 21 comments.
Read more >
Source Map Revision 3 Proposal
Add “sourcesContent” line to support self contained source maps. ... Line 4: An optional source root, useful for relocating source files on a...
Read more >
Source Maps - SurviveJS
If you are using webpack 4 or newer and the mode option, the tool will generate source maps automatically for you in development...
Read more >
Source Maps - APM Real User Monitoring JavaScript Agent
Elastic Docs› APM Real User Monitoring JavaScript Agent Reference [4.x] ... Additional information on the source map endpoint is available in the APM ......
Read more >
Patrick on Twitter: "Source Map lovers! Here's an explainer from the ...
Here's an explainer from the Edge DevTools team to enhance the Source Maps ... Source Maps v4 Proposal by robpaveza · Pull Request...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found