Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Next.js v15.2 creates a lot of fake scripts for server components with the same source map which breaks JS debuggers #77733

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

Open
Soarex16 opened this issue Apr 2, 2025 · 9 comments
Labels
linear: next Confirmed issue that is tracked by the Next.js team.

Comments

@Soarex16
Copy link

Soarex16 commented Apr 2, 2025

Link to the code that reproduces this issue

https://github.com/Soarex16/next-15-server-components-reproduction-app

To Reproduce

  1. Start the application in dev mode (either next dev or next dev --turbopack)
  2. Set a breakpoint on app/page.tsx:3 (on the console.log)
  3. Start debugging in a browser

Current vs. Expected behavior

Expected behavior

The debugger will stop in app/page.tsx only once (at the breakpoint on line 3).
After resuming the code, the debugger will not stop.

Actual behavior

The debugger stops at app/page.tsx:3, but after resume it stops at random locations in the same file.

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 24.3.0: Thu Jan  2 20:24:23 PST 2025; root:xnu-11215.81.4~3/RELEASE_ARM64_T6020
  Available memory (MB): 65536
  Available CPU cores: 12
Binaries:
  Node: 20.9.0
  npm: 10.1.0
  Yarn: 1.22.21
  pnpm: 8.10.5
Relevant Packages:
  next: 15.3.0-canary.29 // Latest available version is detected (15.3.0-canary.29).
  eslint-config-next: N/A
  react: 19.1.0
  react-dom: 19.1.0
  typescript: 5.8.2
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Not sure

Which stage(s) are affected? (Select all that apply)

next dev (local)

Additional context

TLDR

  • React Server components machinery creates fake scripts with the same source map as a real user code to preserve source mapped traces in the browser.
    This confuses js debuggers because they think that this piece of code was bundled in different places multiple times.
    So when the user put a breakpoint, the debugger put breakpoints in all these scripts causing redundant breaks.
  • This issue affects server components debugging both Webpack and Turbopack
  • This bug was introduced somewhere between 15.1.7 and 15.2. Sorry, I didn't have enough time to bisect it.
  • Reproducible with all JS popular debuggers (Chrome DevTools, WebStorm, VS Code). What's interesting is, in Firefox it works as expected.
  • Video with debugging in Chrome DevTools:
Screen.Recording.2025-03-31.at.16.34.39.1.mov

Detailed investigation

I discovered this issue working on turbopack support in WebStorm.

First I thought that is another bug in our JS debugger, but after checking CDP logs
I noticed that Next.js creates a lot of scripts with url like rsc://React/Server/webpack-internal:///(rsc)/./app/page.tsx?SOME_NUMBER.
Here is an example of one of the scripts:

/* This module was rendered by a Server Component. Turn on Source Maps to see the server source. */






({"Home":_=>
        _()})
//# sourceURL=rsc://React/Server/webpack-internal:///(rsc)/./app/page.tsx?0
//# sourceMappingURL=http://localhost:3000/__nextjs_source-map?filename=webpack-internal%3A%2F%2F%2F%28rsc%29%2F.%2Fapp%2Fpage.tsx

All these scripts created at react-server-dom-webpack-client.browser.development.js.
Here is one of the creation traces of such fake scripts

page.tsx:5 <<< This stack frame was source mapped from the fake scripts
createFakeFunction(), react-server-dom-webpack-client.browser.development.js:1954
buildFakeCallStack(), react-server-dom-webpack-client.browser.development.js:1976
react-stack-bottom-frame(), react-server-dom-webpack-client.browser.development.js:2595
anonymous(), react-server-dom-webpack-client.browser.development.js:2331
initializeModelChunk(), react-server-dom-webpack-client.browser.development.js:1054
getOutlinedModel(), react-server-dom-webpack-client.browser.development.js:1327
parseModelString(), react-server-dom-webpack-client.browser.development.js:1540
anonymous(), react-server-dom-webpack-client.browser.development.js:2294
initializeModelChunk(), react-server-dom-webpack-client.browser.development.js:1054
resolveModelChunk(), react-server-dom-webpack-client.browser.development.js:1031
resolveModel(), react-server-dom-webpack-client.browser.development.js:1599
processFullStringRow(), react-server-dom-webpack-client.browser.development.js:2288
processFullBinaryRow(), react-server-dom-webpack-client.browser.development.js:2233
progress(), react-server-dom-webpack-client.browser.development.js:2479
Async call from Promise.then
progress(), react-server-dom-webpack-client.browser.development.js:2499
Async call from Promise.then
progress(), react-server-dom-webpack-client.browser.development.js:2499
Async call from Promise.then
progress(), react-server-dom-webpack-client.browser.development.js:2499
Async call from Promise.then
startReadingFromStream(), react-server-dom-webpack-client.browser.development.js:2506
exports.createFromReadableStream(), react-server-dom-webpack-client.browser.development.js:2718
createFromReadableStream(), app-index.tsx:157
(app-pages-browser)/./node_modules/next/dist/client/app-index.js(), main-app.js:160
options.factory(), webpack.js:700
__webpack_require__(), webpack.js:37
fn(), webpack.js:357
require(), app-next-dev.ts:9
hydrate(), app-bootstrap.ts:78
hydrate(), app-bootstrap.ts:20
loadScriptsInSequence(), app-bootstrap.ts:60
appBootstrap(), app-next-dev.ts:8
(app-pages-browser)/./node_modules/next/dist/client/app-next-dev.js(), main-app.js:182
options.factory(), webpack.js:700
__webpack_require__(), webpack.js:37
__webpack_exec__(), main-app.js:2824
anonymous(), main-app.js:2825
webpackJsonpCallback(), webpack.js:1376
anonymous(), main-app.js:9

And since all these scripts point to the same source map, this causes JS Debuggers to set redundant breakpoints.

I made some research and that's probably caused by React Server components implementation.
Since part of a component is executed on server, React is trying to recreate stack traces for some operations in a browser. One of the examples is console.log replay:

Image

Here, to show a correct source location in the console during replay on the client, React use these techniques with fake scripts and source maps.

@github-actions github-actions bot added the linear: next Confirmed issue that is tracked by the Next.js team. label Apr 7, 2025
@Soarex16
Copy link
Author

Hello, @samcx
It looks like this issue is caused by React internals. Maybe it is worth to label it somehow and maybe report it to the React team?

@samcx
Copy link
Member

samcx commented Apr 16, 2025

@Soarex16 Is this happening on the latest canary as well?

@Soarex16
Copy link
Author

@samcx I checked now on the canary version (15.3.1-canary.11) and behaviour is exactly the same as I reported.

@m-salman-afzal
Copy link

It is not an issue if you run it with webpack. It is only doing for turbopack for me. I think how turbopack and webpack manages their chucks and source maps is causing the problem?

@Soarex16
Copy link
Author

Could you please explain why it is not an issue with webpack?
I checked again on the latest canary (next: 15.4.0-canary.9) both webpack and turbopack and the issue reproducible with both of them.

@rehanvdm
Copy link

Also facing this issue, is there any temporary workaround? Downgrade to an earlier version? What would be the latest version before this bug was introduced?

@rehanvdm
Copy link

Seems that it only works as expected in the v14 😢

@m-salman-afzal
Copy link

Could you please explain why it is not an issue with webpack? I checked again on the latest canary (next: 15.4.0-canary.9) both webpack and turbopack and the issue reproducible with both of them.

Yeah, I think it was combination of webpack and v14

@Soarex16
Copy link
Author

Also facing this issue, is there any temporary workaround? Downgrade to an earlier version? What would be the latest version before this bug was introduced?

If I'm not mistaken, it's 15.1.7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
linear: next Confirmed issue that is tracked by the Next.js team.
Projects
None yet
Development

No branches or pull requests

4 participants