microsoft/vscode-chrome-debug-core

sourceRoot override config

Toxicable opened this issue · 10 comments

I have a case where our source maps require using the sourceRoot property to get back to the actual source file for a NodeJS program.
However, we can't compute the sourceRoot at build time, it's only known at runtime.

Would it make sense for vscode-chrome-debug-core to add a config that allows for overriding sourceRoot when reading source files. We'd then need mozilla/source-map#414 to handle actually setting the setting the sourceRoot, but this would be how you'd configure it through vscode.

For our specific use case we'd always set it to ${workspaceRoot}

Related issue: bazel-contrib/rules_nodejs#823 (comment)
#44 looks and old request for this feature

I'm sort of confused about your use case, why can't your build process set it correctly? Does sourceMapPathOverrides help here?

I don't believe that sourceMapPathOverrides would help here, the relative paths are fine, it's just needs a sourceRoot to be set to point to the workspace.

The use case is for building and running JS/TS under a build tool called Bazel https://bazel.build/ https://github.com/bazelbuild/rules_nodejs
The main feature from Bazel relevent here is it's caching mechanism.
For caching to work effectively, two artifacts build in two hosts must be equal, therefore we cannot include any absolute paths in the artifacts, this includes the source maps, since that would produce different hashes.

We don't distinguish between sourceRoot and the other part of the source, you can use sourceMapPathOverrides to overwrite it anyway. You can either use that or just rely on relative paths which will be resolved relative to the sourcemap location. The paths in the sourcemap don't need to be absolute, it's fairly common for them to just be relative paths.

Oh right, ok sourceMapPathOverrides might work with some thing like "./*": "${workspaceRoot}/*".

I forgot to mention one extra part about how those relative paths work; the .js artifacts are also executed in a dir differrent from your workspace and because of that their relative paths actually point to symlinked readonly versions of your actual source .ts files.
So currently if you hit breakpoint in VSCode it will take you do this read only version, not the file in your workspace. That's why I've been looking at sourceRoot to point it at our workspace instead of the dir where it the artifacts are placed.

Anyway, will try out sourceMapPathOverrides with the above config and see how we go

We currently do set the sourceRoot at build time, with the understanding that we miss out on all caching features, the goal would be to disable that so we and utilize those caches.

I did some more debugging and found this:
When sourceRoot is set our source maps look like:

sourceRoot: "/home/f.wiles/wksp/"
sources: ["apps/some/path/to/a/file.ts"]

when it's not set we get a source map like this:

sourceRoot: ""
sources: ["../../../../../../../../apps/some/path/to/a/file.ts"]

Meaning that sourceMapPathOverrides does work for the second one, but the issue is that I had to set it to "../../../../../../../../": "${workspaceRoot}/*"
Ideas on how we could apply this across all levels?

I guess what I'm imagining is that you could set the sourceRoot then use an override like

"/some/fake/path/*": "${workspaceRoot}/*" and that placeholder would not change, so you would get the benefit of caching.

you could also use something like

...
"../../../../../../../../*": "${workspaceRoot}/*",
"../../../../../../../*": "${workspaceRoot}/*",
"../../../../../../*": "${workspaceRoot}/*",
"../../../../../*": "${workspaceRoot}/*",

although that doesn't look very nice

Ah right, yeah doing it on multiple levels should work fine for us.

However, is there a way to set sourceMapPathOverrides globally? we usually use the auto attach feature and not the launch.json since our devs get annoyed at it opening up a new console window.

No, since with auto attach you don't know "what" you're attaching to. But with a launch config you should be able to set it up to not open a new console window.

Ah right, ok well the found some setting which stops the other console from being opened.
I think this is what we'll go with for now.
Thank you so much for your help, this will make it a lot easier for us.
We could consider this closed now

{
      "type": "node",
      "request": "launch",
      "name": "Launch Program",
      "autoAttachChildProcesses": true,
      "internalConsoleOptions": "neverOpen",
      "console": "internalConsole",
      "sourceMapPathOverrides": {
        "../*": "${workspaceRoot}/*",
        "../../*": "${workspaceRoot}/*",
        "../../../*": "${workspaceRoot}/*",
        "../../../../*": "${workspaceRoot}/*",
        "../../../../../*": "${workspaceRoot}/*",
        "../../../../../../*": "${workspaceRoot}/*",
        "../../../../../../../*": "${workspaceRoot}/*",
        "../../../../../../../../*": "${workspaceRoot}/*",
        "../../../../../../../../../*": "${workspaceRoot}/*",
        "../../../../../../../../../../*": "${workspaceRoot}/*",
        "../../../../../../../../../../../*": "${workspaceRoot}/*",
        "../../../../../../../../../../../../../*": "${workspaceRoot}/*",
      }

Great! Sorry for that ugly sourceMapPathOverrides but I'm glad it works!