microsoft / vscode-js-debug

A DAP-compatible JavaScript debugger. Used in VS Code, VS, + more
MIT License
1.67k stars 283 forks source link

[vite+svelte] breakpoints in svelte files are created in transpiled sources #2029

Closed fnicastri closed 4 months ago

fnicastri commented 4 months ago

Describe the bug Breakpoints in Svelte files are created in the transpiled file and not in the source file.

breakpoints in ts files are ok.

Crome debugger works, sourcemaps seems ok.

When debugging from code neither VSCode debugger nor Chrome debugger are working.

I've tried many pathMapping/resolveSourceMapLocations/sourceMapPathOverrides and options in launch.json, nothing worked.

To Reproduce Steps to reproduce the behavior:

  1. clone the repo, it is a standard vite+svelte project
  2. npm install
  3. npm run dev
  4. Try to debug from vscode and see error

vscode-debugadapter-17f94c80.json.gz

Version: 1.90.2
Commit: 5437499feb04f7a586f677b155b039bc2b3669eb
Date: 2024-06-18T22:54:35.075Z (1 wk ago)
Electron: 29.4.0
ElectronBuildId: 9728852
Chromium: 122.0.6261.156
Node.js: 20.9.0
V8: 12.2.281.27-electron.0
OS: Darwin arm64 23.5.0
Chrome is up to date
Version 126.0.6478.127 (Official Build) (arm64)
fnicastri commented 4 months ago

some screenshots:

ts file:

Screenshot 2024-06-29 at 6 45 52 PM

svelte file:

Screenshot 2024-06-29 at 6 44 58 PM

breakpoints info:

Screenshot 2024-06-29 at 6 45 28 PM

Screenshot 2024-06-29 at 6 45 10 PM

connor4312 commented 4 months ago

This is an issue with how Svelte transforms code / generates its sourcemaps, and how that interacts with V8. Here is the mapping it creates:

image

When you set a breakpoint on counter += 1, that maps it to the binary expression being passed as an argument, as you would expect. However V8 cannot set a breakpoint here, so it moves it to the next available location, which is after the statement and before the closing brace. However, there are no sourcemap mappings on this line, so the debugger doesn't know where (or if) it has a location in the source file, and so it shows you the generated location it mapped to.

You can see the effects of the poor breakpoint placement in chrome devtools too: notice the count has already been incremented by the time you hit a breakpoint that should happen before it's executed. They just don't show you where the breakpoint actually ended up being placed, so the issue is hidden a bit 🙂 In this debugger I prefer to make such failures more obvious so a developer can figure out what's going wrong. There's nothing more frustrating that your debugger lying to you!

It would be better if Svelte kept the increment as its own expression statement and then added an unmapped $$invalidate statement afterwards, like

count += 1;
$$invalidate(0, count);
connor4312 commented 4 months ago

I'll go ahead and open an issue with these details for them

fnicastri commented 4 months ago

@connor4312 Thank you!