As discussed we are removing the deprecated field from `revalidateTag`
and `revalidatePath` as they aren't going away anytime soon and the new
`expire` APIs will have slightly different semantics so not a 1-1 rename
with no arguments change anymore. We are also adding the `unstable_`
prefix for `expireTag`/`expirePath` while we iterate on them so it's
clear they will change.
---------
Co-authored-by: Zack Tanner <1939140+ztanner@users.noreply.github.com>
### Why?
This PR added an indication of where the env was loaded from when
`experimental.typedEnv` was enabled. Also, it allows the user to set
`NODE_ENV=production` to enable the `typedEnv` feature for
`.env.production*` files.

### How?
Modified `@next/env` to pass parsed envs along with the `loadedEnvFiles`
value and used the location to indicate via JSDoc.
We now look through each section for the source and
use that section to determine if a frame is ignore-listed.
Previously, stacks from Turbopack sourcemaps were
not ignore-listed since they were index maps.
Works around https://github.com/nodejs/node/issues/52102
Webpack will be harder to patch and I don't know yet where the Webpack runtime is using `vm.runInThisContext`.
Best way to observe change is in https://github.com/vercel/next.js/pull/71909 and `pnpm test-dev-turbo test/development/app-dir/dynamic-io-dev-errors/ -t "should display error when component accessed data without suspense boundary"`.
Before:
```
Error: [...]
at Page [Server] (<anonymous>)
at InnerLayoutRouter (.next/server/chunks/ssr/[root of the server]__088b8c._.js)
```
After:
```
Error: [...]
at Page [Server] (<anonymous>)
at InnerLayoutRouter (node_modules/.pnpm/file+..+next-repo-2186278d37ae48e2b1397aa86060054592669ed9909b91e96c5af049d12c04c3+packages+n_vk62popbath6ofshgazcbhzdoe/node_modules/next/dist/src/client/components/layout-router.tsx:324:2)
```
Next step is figuring out why the now sourcemapped frames aren't ignore-listed.
Migrated every instance of `sandbox` to use the `using` keyword so that
the `cleanup` will be automatically performed when the execution leaves
the scope.
A multi-zone Next.js app might have complex rewrites for its client
assets. For these apps, resolving a source map through the
`/__nextjs_source-map` dev middleware might fail because the asset might
belong to a different app.
Instead of trying to resolve those rewrites (i.e. using `fetch` instead
of `fs`), we can just bypass the source map dev middleware for client
chunks. Because we control how those source maps are generated, we can
safely assume that the `sourceMappingURL` is relative to the filename,
with an added `.map` extension. The browser can just request this file,
and it gets served through the normal dev server, without the need to
route this through the source map dev middleware.
reverts #72258
This adds `expireTag()` and `expirePath` APIs which are replacing
`revalidateTag` and `revalidatePath`. As such this also marks
`revalidatePath` and `revalidateTag` as deprecated and marked for
removal.
The arguments passed to these methods match `revalidateTag` and
`revalidatePath` with the exception that `expireTag` can receive
multiple tags now as separate arguments which matches our new
`unstable_cacheTag()` API.
We are wanting to update these APIs as `revalidateTag` naming has caused
some confusion as to when the affected items will be updated. The
underlying behavior of `expireTag` is to mark an entry as out of date
and for it to no longer be used so we are expiring it.
If you call `expirePath('/blog/first'`) the next time that item is
requested it is considered expired so the cache will not be used for it
and a fresh entry will be generated. Similarly for `expireTag('posts',
'blog')` the next time any cache with that tag is requested it's
respective cache will not be leveraged and new cache will be populated.
---------
Co-authored-by: Zack Tanner <1939140+ztanner@users.noreply.github.com>
Co-authored-by: Delba de Oliveira <32464864+delbaoliveira@users.noreply.github.com>
When using Turbopack, and importing a server action into a client
component, the source map for the client chunk will be requested if
devtools are open. The filename for this source map request might be
`/_next/static/chunks/[project]__800ed2._.js`, for example. This
scenario was already handled by the dev middleware.
However, it didn't consider that there might also be an `assetPrefix`
defined in the `next.config.js`. In this case, the filename would be
`/some-asset-prefix/_next/static/chunks/[project]__800ed2._.js`. When
resolving the external source map for this file, we need to strip the
asset prefix.
Again, this can only be tested manually.
After adding validation that fixing invalid segment configs (when DIO is
enabled), it revealed that errors weren't being displayed in Turbopack,
because `setHMRServerError` wasn't implemented.
This refactors the implementation to use the existing server component
transform when validating if the segments are valid. This has the
benefit of highlighting precisely where the segment is coming, making it
easier to remove. The test that was skipped in Turbopack is also
re-enabled.
<details>
<summary>Screenshot</summary>

</details>
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.
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.