Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SSR transformed named imported functions don't work with debuggers "step-into" #18325

Open
7 tasks done
AriPerkkio opened this issue Oct 10, 2024 · 2 comments
Open
7 tasks done

Comments

@AriPerkkio
Copy link
Contributor

AriPerkkio commented Oct 10, 2024

Describe the bug

Originally reported at vitest-dev/vitest#5569. I think I've seen 2-3 similar reports in the past too.

When a file is SSR transformed in Vite, debuggers like Chrome Dev tools and VSCode are unable to "step into" functions that are imported via named imports. In practice this means stopping debugger in line 3 and pressing "step into" button of debuggers in the example below.

1 | import { add } from "./math.ts";
2 |
3 | add(1, 2);

Debugger should stop at line 1 or 2, but instead it stops at 7.

1 | export function add(a: number, b: number): number {
2 |   if (a === 1) {
3 |     return 1;
4 |   }
5 | 
6 |   return a + b;
7 | }
8 |

Source map of the math.ts in reproduction: https://evanw.github.io/source-map-visualization/#NDI2AGZ1bmN0....

Video demonstrating step-into issue with Vite SSR
vite-step-into.webm

I think this has something to do with the way Vite SSR transforms import into import() and saves the results into single variable. In the reproduction setup I've created "Vite simulation", where SSR transformed file is loaded directly into Node.

In this example "step into" works correctly on lines 11 and 15. If Vite was able to destructure the named imports of __vite_ssr_exports__ into separate variables, I think debuggers would work just fine. But this would break ESM live bindings.

 1 | globalThis.__vite_ssr_exports__ = {};
 2 | debugger;
 3 | 
 4 | await import("./transpiled.js");
 5 | const { add, multiply } = globalThis.__vite_ssr_exports__;
 6 | 
 7 | // Incorrect position when "step into"
 8 | globalThis.__vite_ssr_exports__.add(1, 2);
 9 | 
10 | // Correct position when "stepinto"
11 | add(1, 2);
12 | 
13 | // Same here
14 | globalThis.__vite_ssr_exports__.multiply(1, 2);
15 | multiply(1, 2);
16 |
Video showing how lines 11 and 15 work correctly
node-step-into.webm

Reproduction

https://github.com/AriPerkkio/vite-ssr-transform-sourcemaps-issue

Steps to reproduce

See README https://github.com/AriPerkkio/vite-ssr-transform-sourcemaps-issue/blob/main/README.md.

System Info

System:
    OS: macOS 15.0.1
    CPU: (8) arm64 Apple M2
    Memory: 471.58 MB / 16.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 20.17.0 - ~/.nvm/versions/node/v20.17.0/bin/node
    Yarn: 1.22.22 - ~/.nvm/versions/node/v20.17.0/bin/yarn
    npm: 10.8.2 - ~/.nvm/versions/node/v20.17.0/bin/npm
    pnpm: 8.15.9 - ~/.nvm/versions/node/v20.17.0/bin/pnpm
  Browsers:
    Chrome: 129.0.6668.91
    Safari: 18.0.1

Used Package Manager

pnpm

Logs

No response

Validations

@AriPerkkio
Copy link
Contributor Author

In the source map there is a weird mapping into the position where debugger stops. I tested if removing this with magic-string + @ampproject/remapping helps, but debugger is still working the same.

@sapphi-red
Copy link
Member

sapphi-red commented Oct 11, 2024

I guess we need to tell the debugger that the property access of __vite_ssr_exports__.add should be ignored when stepping. But I'm not sure if there's a way to do that.

One idea would be to avoid the property access with a helper function and map that helper function to somewhere and set that in x_google_ignoreList.

const access = (obj, key) => obj[key] // the helper function

access(__vite_ssr_exports__, 'add')(1, 2)

I'm not sure if that would work though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants