Search code examples
angularvisual-studio-codewebpackvscode-debuggersource-maps

How can I bind break points in both my Angular application and library in VSCode, I can only get working in one or the other, not both


I am attempting to get debugging in vscode working for both my application and my lib for Angular 16 at the same time. The structure is as follows:

./root
./root/my-app/src
./root/lib/projects/my-lib

I have added my lib to the app's project.json and have been able to successfully install, build, watch and update both the app and the lib and have it hot reload, however I can only get the breakpoints working in one or the other, but not both at the same time. I have set webRoot in the launch.json file to the ./root folder and have tried path overrides like below. (I realize I can't have two enties for "webpack:/*", I'm just showing what I'm successful with when I change between the two.)

"webRoot": "C:\\path\\to\\root",
"sourceMapPathOverrides": {
  "webpack:/*": "${webRoot}/my-app/*", // works for app, but not lib
  "webpack:/*": "${webRoot}/lib/*", // works for lib, but not app
}

When I use vscode's Debug Diagnotics and see why the source wasn't loaded, I get a message like this when I use the "lib" entry from above:

We couldn't find a corresponding source location, but found some other files with the same name:

  c:\path\to\root\lib**my-app**\src\app\features\component\component.ts

In the above, **my-app** is red and strike though and lib is green.

Is there a way to make this work? I was thinking all I needed to do was create an entries like "webpack:/my-app/*" and/or "webpack:/lib/*" but neither of those work for either one.

Any help would be greatly appreciated!


Solution

  • If anyone runs into this, it took me way too long to even think I know how it works, because I still don't really understand it but I'll attempt to provide an explanation of what I did in order to fix my scenario.

    TLDR;

    "webRoot": "${workspaceFolder}/../",   // need to jump out of ./root/my-app to ./root
    "sourceMaps": true,
    "sourceMapPathOverrides": {
    
      // map ./projects/* to ./root/lib/projects
      "webpack:///./projects/*":  "${webRoot}/lib/projects/*",
    
      // map ./src/* to ./root/my-app/src/*
      "webpack:///./src/*":       "${webRoot}/my-app/src/*"
    
    }
    

    NTLDR;

    (Not too long, did read.) :)

    webRoot

    My app source is essentially a sibling of my lib source (they both live in the ./root folder) and the vscode ${workspaceFolder} variable points to the root of it's project so in my case the value of ${workspaceFolder} is ./root/my-app because it is located at ./root/my-app/.vscode/launch.json. I needed the value of ${webRoot} to be the parent directory of my-app (./root), so: "webRoot": "${workspaceFolder}/../" It might be possible to leave that alone and only make the change to the actual path override, but I didn't try.

    sourceMapPathOverrides

    The source maps are loaded into a special webpack:/// path that you can view in vscode or chrome.

    vscode
    • Start a debugging session
    • In vscode's debug console (not terminal), type ".scripts" to open the Debug Diagnostics window
    • Click "What scripts and sourcemaps are loaded"
    • Search/filter at the top of that window for the resource you want to find. (I searched "projects" for my lib and "src/app.component" for my app.)

    chrome

    • Start a debugging session or just "ng serve"
    • Open dev tools
    • View the "Sources" tab
    • Expand "webpack://" in the list on the left

    Both of those pointed to these paths I needed to override:

    • "../webpack:/projects/" in vscode or in chrome "webpack://projects"
    • "../webpack:/src/" in vscode or in chrome "webpack://src"

    solution

    Even after I had the paths, it seemed like nothing I tried in was taking effect so I started second guessing those were the correct paths which turned into a vicious cycle of bad guesses, paths and patterns that would never work.

    As it turns out, I needed to use "webpack:///./" as the prefix for my override entries/pattern and boom! break points hit in both app and lib when debugging using the my-app launch config.

    According to my new best friend, ChatGPT, here is an explanation of "webpack:///./":

    • webpack:///: This part indicates the protocol used for the source map URL, which is commonly used in source map URLs generated by Webpack.

    • ./: This part represents the relative path within the project where the source map is located.

    Hope this helps someone else down the road, it took me waaaay to long to figure this out...for some reason I just couldn't wrap my head around the obvious.

    Here is my launch.json and tasks.json file:

    {
      "version": "0.2.0",
      "configurations": [
        {
          "name": "Debug MyApp",
          "type": "chrome",
          "request": "launch",
          "preLaunchTask": "Serve MyApp",
          "url": "http://localhost:4200/#",
          "webRoot": "${workspaceFolder}/../",
          "sourceMaps": true,
          "sourceMapPathOverrides": {
            "webpack:///./projects/*":  "${webRoot}/lib/projects/*",
            "webpack:///./src/*":       "${webRoot}/my-app/src/*"
          },
          "trace": true
        }
      ]
    }
    
    {
      "version": "2.0.0",
      "tasks": [
        {
          "label": "Serve MyApp",
          "type": "npm",
          "script": "start",
          "isBackground": true,
          "presentation": {
            "focus": true,
            "panel": "dedicated"
          },
          "group": {
            "kind": "build",
            "isDefault": true
          },
          "problemMatcher": {
            "owner": "typescript",
            "source": "ts",
            "applyTo": "closedDocuments",
            "fileLocation": ["relative", "${cwd}"],
            "pattern": "$tsc",
            "background": {
              "activeOnStart": true,
              "beginsPattern": {
                "regexp": "(.*?)"
              },
              "endsPattern": {
                "regexp": "Compiled |Failed to compile."
              }
            }
          }
        }
      ]
    }