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

Monorepo build tools incompatible with breakpoints #1893

Closed
AaronFriel opened this issue Nov 29, 2023 · 6 comments
Closed

Monorepo build tools incompatible with breakpoints #1893

AaronFriel opened this issue Nov 29, 2023 · 6 comments
Assignees
Labels
info-needed Issue requires more information from poster

Comments

@AaronFriel
Copy link

Describe the bug

Many monorepo tools are "oblivious" to the fact that they are in a monorepo, including most Node.js build tools. In my case, using any arbitrary tool (even a shell script) which runs next dev in multiple projects. The Next.js build tool produces source map paths that are relative to each package they are in, and source mapping fails.

Expected behavior

In preference order:

  1. That source mapped files in a monorepo "just work".

  2. That the "Debug Diagnostics" menu helps me change my launch config to handle scenarios (possible feature request?) by adding the mapping for me. It clearly found a "file with the same name", why is there not an option to help me add that mapping?

  3. That there is clear documentation on how to handle this scenario.

Actual behavior

Given a repo with the structure:

root/
├─ projects/
│  ├─ foo/
│  │  ├─ src/
│  │  ├─ package.json
│  ├─ bar/
│  │  ├─ src/
│  │  ├─ package.json

That is, a repository with projects/foo and projects/bar, the source maps for each are typically relative paths like webpack://./src/index.ts. When using a tool like nx, turbo, lerna, et al., to launch processes in multiple projects simultaneously, these relative paths result in a failure to "find a corresponding source location", as described by Debug Diagnostics:

./projects/foo/src/index.ts

  • ✅ This breakpoint was initially set in:

    [absolute-path-redacted]/projects/foo/src/index.ts line 13 column 1

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

    [absolute-path-redacted]/projects/foo/src/index.ts

    If this is the same file, you may need to adjust your build tool to correct the paths.

Where, confusingly, the path it found "with the same name" will have the monorepo path highlighted in red. I can't reproduce that here in text or show a screenshot, but it looks to me like it finds a "piecewise diff" (Levenshtein edit distance?) with the location in the sourcemap, likely webpack://./src/index.ts.

What makes this particularly frustrating is that it found the file. But it is very, very unclear from the documentation how to configure the launch.json to use it.

When changing the launch config to run the sub-project directly and viewing debug diagnostics on a successfully hit breakpoint, I see:

./projects/foo/src/index.ts

  • ✅ This breakpoint was initially set in:

    [absolute-path-redacted]/projects/foo/src/index.ts line 13 column 1

  • ✅ In the runtime, the breakpoint was set in:

    webpack-internal:///(rsc)/./src/index.ts line 25 column 5

  • ✅ The runtime acknowledged and adjusted the breakpoint, and it mapped back to the following locations:

    [absolute-path-redacted]/projects/foo/src/index.ts

Unfortunately this is not quite what I want. Using the same shell script, makefile, monorepo tool (turbo, lerna, etc.) or other tool to launch other pre-requisite processes in a single command is the desired state.

@AaronFriel AaronFriel added the bug Issue identified by VS Code Team member as probable bug label Nov 29, 2023
@connor4312
Copy link
Member

connor4312 commented Nov 29, 2023

I don't really know anything about your build setup without the log file that the bug template asks for, or a sample repo, but it sounds like you're bundling everything with webpack which will pave over the actual paths on disk. You will probably want to customize your sourceMapPathOverrides based on the webpack namespaces. Alternatively, you can tickle webpack into producing absolute file URIs that will work much more reliably. Depending on how dependencies are built, you may need the source-map-loader.

I don't provide guidance on how to debug with a monorepo as part of our official docs, because basically every monorepo builds and debugs things different. For example, are package dependencies built ahead of time? Are they compiled with something like tsc or do you use some bundler to package them and then import them? Or are the bundled dynamically with the top level package you're debugging? Are you using webpack/esbuild/tsc/vite/babel/... to do this? It's quickly into N^2 types of things to document. Things can 'just work' depending on what combination of decisions you make, but not all of them, and often the thing that needs fixing is tooling dropping a sourcemap at some point.

@connor4312 connor4312 added info-needed Issue requires more information from poster and removed bug Issue identified by VS Code Team member as probable bug labels Nov 29, 2023
@AaronFriel
Copy link
Author

AaronFriel commented Nov 29, 2023

I don't really know anything about your build setup without the log file that the bug template asks for, or a sample repo, but it sounds like you're bundling everything with webpack which will pave over the actual paths on disk.
...
Are you using webpack/esbuild/tsc/vite/babel/... to do this? It's quickly into N^2 types of things to document.

Totally understand the concern, but it looks like there is a pretty common theme when googling "monorepo" here that this is a poor interaction between Webpack and monorepos. Whether in this repo or in others (next.js, vite, etc.) folks find that source maps were relative to the package they were built in, not relative to the "repository root". And there are a lot of issues in this repo, questions on StackOverflow, in other open source repos with this issue, including:

I have a hunch there is a solution here that isn't overly complex that solves the problem for most of the users running into this. Most of these build tools make it deliberately difficult to change the Webpack or other settings, as they are prone to causing breaks, or remove control from the framework e.g.: Next.js migrating to turbopack. That makes it pretty challenging to wrangle all of the parties involved to "do the right thing".

But on the other hand, the "Debug Diagnostics" tool found the file! It just refused to use it for debugging. That seems fixable!

@connor4312
Copy link
Member

connor4312 commented Nov 29, 2023

Most of those things you mentioned are unique problems:

  • Webpack doesn't follow sourcemaps -- as I mentioned in the initial issue, this is fixed for certain configurations of webpack, depending on the devtools setting. But this is something webpack should really just do properly itself, and more modern tools like esbuild already do this.
  • Having to set resolveSourceMapLocations: null in the second issue: we have an issue for this! PR welcome if you're feeling ambitious 🙂 Using dependency graph to reduce file scanning #1730
  • The next.js issue seems like a dumping ground of various debug issues , and it was eventually closed with a fix on their side Fix NODE_OPTIONS='--inspect' not running expected vercel/next.js#51467

I haven't read through the search query you posted. If there is "a solution" to make life better in these cases, I'm all for it, but the issues you mention are different issues with different problems. Some general 'user setup issues' may be fixed with #1214

But on the other hand, the "Debug Diagnostics" tool found the file! It just refused to use it for debugging. That seems fixable!

Can you share a log file so I can see what's going on in your case? I agree that is rather strange 🤔

@davidfmatheson
Copy link

I face a similar problem debugging my projects in an nx monorepo. Generally I set cwd in my VS Code launch.json to the project I'm working on. When I'm working in NeoVim, I can do this programmatically so I don't have to make manual edits every time I switch project (I build an appropriate cwd here). It would be great if I didn't have to coax it to find source like this, though.

@connor4312
Copy link
Member

Please open a new issue with details about what you're trying to do.

@connor4312
Copy link
Member

Closing this issue as we haven't heard back from the reporter in the last month. The issues brought up seem to be generally captured elsewhere (#1893 (comment)), and log files are needed for the additional issue mentioned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
info-needed Issue requires more information from poster
Projects
None yet
Development

No branches or pull requests

3 participants