This enables DevTools (e.g. Chrome debugger) to collapse stackframes from 3rd party dependencies.
Webpack only. Turbopack added support in https://github.com/vercel/next.js/pull/71770. Replays from RSC will follow.
Had to fork `EvalSourceMapDevToolPlugin` (with blessing from @sokra) to be able to inject `ignoreList`.
For `source-map`, we can use https://github.com/mondaychen/devtools-ignore-webpack-plugin/ instead since we can operate on the assets on disk. I inlined it to iterate on it faster. Though it'd be faster for bundling to also fork `SourceMapDevToolPlugin` since `DevToolsIgnorePlugin` adds another parse/serialize roundtrip.
## test plan
We'll start leveraging `ignoreList` in the terminal as well which will allow us to write automated tests. I haven't found a way to automatically test this ignore-listing in browsers.
Note that this is on Chrome Beta. Chrome Stable does not ignore-list logged stacks yet. Only stacks of the actual `console` call or in the debugger.
(the frame from our console instrumentation is a bug that may be fixed once we populate our own sourcemaps)
`pnpm debug dev test/e2e/app-dir/server-source-maps/fixtures/default/`
`/ssr-error-log` shows
browser:


Node.js debugger doesn't seem to work. Will look at that in a follow-up
We already create server source maps in dev by default,
so we should make use of them.
To opt-out, run `next dev --disable-source-maps` instead.
Our internal `next-no-sourcemaps` script is now defunct.
Updates the heuristic to scoping prerender caches during dev. A cache
scope will be created for every request if one does not already exist.
If the request is a server action we create a new one. existing caches
already expire after 30 seconds (unchanged)
This updates the prefetch cache purge to be 5 seconds since so we don't
mask short lifetime caches
This also adds cache tracking to the first RSC render of the validation
render. This means we now need to always do a second render regardless
of whether there is a sync abort.
Since `console.error` is intercepted, this can be frustrating when a 3p
library that hasn't updated to use the async APIs triggers a warning.
This keeps the error behavior when `dynamicIO` is enabled and warns in
other cases.
Changes `--turbo` -> `--turbopack` to avoid confusion.
- Updated docs
- Updates create-next-app -- For create-next-app it's a rename as
otherwise there is an ordering problem with the prompts
- For the CLI `next dev --turbo` is still supported, will eventually be
a warning in a future version to swap with `--turbopack` but is not a
requirement today, can be handled automatically by the upgrade codemod
- New CLI flag: `next dev --turbopack`
<!-- Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible we request that
you follow the checklist sections below.
Choose the right checklist for the change(s) that you're making:
## For Contributors
### Improving Documentation
- Run `pnpm prettier-fix` to fix formatting issues before opening the
PR.
- Read the Docs Contribution Guide to ensure your contribution follows
the docs guidelines:
https://nextjs.org/docs/community/contribution-guide
### Adding or Updating Examples
- The "examples guidelines" are followed from our contributing doc
https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md
- Make sure the linting passes by running `pnpm build && pnpm lint`. See
https://github.com/vercel/next.js/blob/canary/contributing/repository/linting.md
### Fixing a bug
- Related issues linked using `fixes #number`
- Tests added. See:
https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md
### Adding a feature
- Implements an existing feature request or RFC. Make sure the feature
request has been accepted for implementation before opening a PR. (A
discussion must be opened, see
https://github.com/vercel/next.js/discussions/new?category=ideas)
- Related issues/discussions are linked using `fixes #number`
- e2e tests added
(https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs)
- Documentation added
- Telemetry added. In case of a feature if it's used or not.
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md
## For Maintainers
- Minimal description (aim for explaining to someone not on the team to
understand the PR)
- When linking to a Slack thread, you might want to share details of the
conclusion
- Link both the Linear (Fixes NEXT-xxx) and the GitHub issues
- Add review comments if necessary to explain to the reviewer the logic
behind a change
### What?
### Why?
### How?
Closes NEXT-
Fixes #
-->
---------
Co-authored-by: Will Binns-Smith <wbinnssmith@gmail.com>
Our patched `console.error` tries to skip internal router errors by
checking `isNextRouterError(error)`. however, if one of those happened
on the server and got replayed on the client, it gets logged differently
-- it's prefixed with the `[ Server ]` badge. this changes the position
where the actual error object is in `args` and thus messes up our
detection, so we end up printing it out (instead of hiding it like we
should)
This PR adds a check that attempts to match replayed server errors
(following [similar logic from react
devtools](https://github.com/facebook/react/blob/65a56d0e99261481c721334a3ec4561d173594cd/packages/react-devtools-shared/src/backend/flight/renderer.js#L88-L93))
and thus also filter out router errors that originated on the server
Closes#71555
This applies similar handling from #71567 to show dynamic IO errors
during client navigations. This also adds a redbox test case for the
initial SSR render.
Previously our rules for allowed dynamic were only enforced in builds.
This is not tenable for serious adoption because you can't spend all day
working on your site and then find out its broken when you build /
deploy.
To address this I've added a simulated prerendering during dev that
should enforce the same rules for rendered routes in dev that would
apply during a build. There is no way to avoid doing additional work to
implement this feature because we need the abort mechanism of SSR to
actually find the dynamic holes that should be disallowed. I was able to
avoid completely duplicating the RSC render however by capturing the
stream chunks available before the first task completes and stashing
them away as a simulated halted RSC payload.
I did have to introduce prospective renders to the RSC render and the
validating SSR render however to work around issues of lazy module
initialization where functions like Math.random and new Date() in module
scope would incorrectly trigger dynamic validation when you would not
expect them to.
This PR adjusts the server action transforms to assign proper function names for the generated server reference proxies.
- If the original function has a name, this name is used.
- If a function expression is assigned to a variable, the variable's name is used.
- If an anonymous function expression is assigned to a prop, the prop's name is used.
In addition, this PR simplifies the output for exported functions, avoiding unnecessary `registerServerReference` calls.
It also fixes the source mapping of default exported server actions.
**Before:**
<img width="890" alt="before" src="https://github.com/user-attachments/assets/a3d6a5f8-d48e-474d-8f03-b49306fb704f">
**After:**
<img width="890" alt="after" src="https://github.com/user-attachments/assets/8f332690-6c26-46f1-9eef-7680f47ea578">
Next up, we will do the same for `'use cache'` functions.
Temporarily removing the dev warnings. I've moved these to be errors in
the build side. In a follow up PR I will use prerendering during dev to
trigger these errors and report them as dev errors as well.
This also updates how we track sync dynamic errors. The main goal is to
have a stack trace of the sync function and separately report all the
component stacks that might contain this function call. It's not
fool-proof b/c the sync api may be called in a way that is not observed
by SSR. The whole debugging story here will improve dramatically with
owner stacks but that is currently experimental only in React.
The plan for future updates is to add a prospective render for SSR so we
can flush out module scope issues like calling Math.random while lazy
initializing a module. This is asserted for RSC in this change (see new
tests) but won't wouldn't pass for SSR b/c we only do single pass
prerendering at the moment.
After that I will add in the prerender-while-render in dev and utilize
the prerender errors to power dev as well.
stacked on #71345
When dynamicIO is enabled certain platform APIs that provide access to
outside state like randomness and current time are augmented to bail out
of prerendering. When running in Dev there is no true Prerender but we
still want to communicate to the developer when they are using APIs that
might not work as they intend in Production. This change adds warnings
when you use these platform APIs during the Prerender portion of the dev
render.
To seed caches in dev mode we implemented a prefetch if one had not been
done in the recent past. The implementation isn't quite working b/c it
doesn't match the prefetch header properly but the mechanics are there.
One problem however is the prefetch streams so we end up starting the
regular render before the prefetch render is complete.
The ideal cache warmup is to only render until there are no more caches
to fill in the prefetch. Additionally we can disable certain things like
dynamic Request apis and fetches so they stall forever too. This
suggests that there is enough of a difference in the needs of the
prefetch for cache warming that we ought to implement it as it's own
request type. This change implements the mechanics of triggering the
warmup prefetch but does not yet implement the changes to things like
the request or fetch apis behavior. I will follow up with further
changes on top of this commit.
# Changes
### 1. `unstable_after()` is no longer dynamic
`after()` can now run at build time and in ISR/revalidations.
the principle is "if it ran, then the callback runs too". i.e. if we
encountered an `after()` call during some render task (build / request /
revalidation), then the callback should run at the end of that task.
note that errors thrown inside `after` during a prerender will fail the
build. this is, amongst other things, intended to support the next
section
### 2. calling dynamic APIs inside `unstable_after()` is banned
before:
```ts
after(() => {
const cookieStore = await cookies();
doStuff(cookieStore)
})
```
after:
```ts
const cookieStore = await cookies();
after(() => {
doStuff(cookieStore)
})
```
tracking dynamic things inside `after` is difficult (can't throw at the
callsite, because we're executing after the callsite is finished, so it
doesn't mesh well with `dynamicIO`). it's simpler if we make the user
hoist the dynamic call outside of `after()`, because then it slots right
into the existing mechanisms/docs/metal models we have for this.
# Notes
one notable limitation is that `tags` and `revalidate` written inside
`after` have no effect. this means that if we do
```ts
after(async () => {
await fetch('...', { next: { tags: ['my-cool-tag']} })
})
```
and try to call `revalidateTag('my-cool-tag')`, nothing will happen,
because the route is not associated with the tag. same applies to
`revalidate`.
i believe this is acceptable for now, because we expect `after` to be
mostly used to perform side effects, and thus not do a lot of
{cached,tagged,revalidatable} data-fetching. it will be addressed in a
follow up.
As we've learned in #70467, compilation times can be quite high in CI,
when testing HMR behaviour. The fetch logging HMR tests are frequently
failing. Increasing the `retry` timeout should mitigate the flakiness.
This PR adds support for showing the original server sources of server
components and server actions in the browser's developer tools.
To accomplish that, we're building on top of #69190, #70563, and #70564,
in which we prepared the proper generation of the source maps.
This PR completes the feature, by wiring up `findSourceMapURL` (see
https://github.com/facebook/react/pull/30741) with a new dev server
middleware that serves those source map files to the browser.
Another change we had to make is disabling the dead-code elimination of
server actions in client bundles (see #70103), but only in development
mode. This optimization is primarily intended for production bundles, so
the change should not pose a problem.
With that, it's now possible to jump directly into the server sources
from the browser's dev tools, e.g. for component stacks of server logs
that are replayed in the browser, or when inspecting server action props
in the React DevTools.
Closes PACK-3270
- Retains sourcemaps for the generated `__turbopack_import__`
statements. At least in dev
- Refactoring to allow simply returning statements to hoist
<br>
- [x] ~~Prevent duplicate `__turbopack_import__` calls when importing
the same module multiple times~~
- [x] ~~The order is slightly different now~~
### What?
Add a new turbo-tasks backend that stores data normalized and is
prepared for persistent caching.
No longer keeps state in task locals, but all state is stored
immediately. This is required for persistent caching since it could
store and resume at any point and we always need to be in a valid state.
Tasks stay dirty until recomputed. (Previously dirty was changed to
scheduled)
### Why?
* Reduced memory usage
* preparation for persistent caching
When `dynamicIO` is enabled it is important that you can reason about
what parts of component tree are allowed to be dynamic and which must be
static.
The heuristic we're going with is to require that anything dynamic must
be rendered inside a Suspense boundary. The rationale here is that if
you have a static component then you don't need to define a fallback UI
for it because it will never render. Conversely to have a useful dynamic
site having a well defined fallback UI to show when the dynamic part is
not ready yet is helpful.
If PPR is turned off the Suspense boundaries won't actually define a
static UI during prerendering but we want the upgrade path to PPR to be
as unblocked as possible so we require that you follow this semantic
when `dynamicIO` is enabled even if PPR is not.
There are some special considerations we need to make for
`generateMetadata`, `generateViewport`, and use of synchronosuly dynamic
APIs like `(cookies() as unknown as UnsafeUnwrappedCookies).get(...)`.
Metadata & Viewport can't be wrapped in a Suspense boundary. So if
something else in your application is dynamic we don't error for dynamic
metadata/viewport. If dynamic metadata/viewport is the only thing that
is dynamic in your application we consider this an error. Your recourse
is to make these functions only read static/cached data or alternatively
you can make the application itself dynamic by introducing something
dynamic inside a Suspense boundary.
If you use a Synchronously dynamic API like the one mentioned above you
will likely get incomplete parts of your component tree identified as
dynamic b/c the synchronous dynamic API immediately terminates the
prerender. We provide component stacks in these cases but the correct
fix is to find the synchronous dynamic API and make it async.