When functions exported from a module with a top-level `'use cache'`
directive are imported into client modules, the compiler should allow
`cacheLife` and `cacheTag` usage within those functions.
This PR updates the `react_server_components` transform to properly
track module directives (`'use client'`, `'use server'`, `'use cache'`)
and skip client graph validation for modules with `'use cache'`,
identical to how modules with `'use server'` are already handled. Those
modules are transformed anyway for the client graph by the
`server_actions` transform, which is applied after the
`react_server_components` transform, in which their implementation is
replaced by server function references.
closes NAR-498
Importing `cacheLife` and `cacheTag` in Client Components yields build errors. This adds test fixtures to cover these scenarios.
In addition, we're duplicating the test fixtures that have different error messages between `app/` and `pages/` directories to ensure both cases are covered.
This PR fixes a slight performance regression introduced in #85519 where
inline async function expressions were created for each unique set of
arguments passed to a `'use cache'` function.
For a function like this:
```js
export async function getCachedData(id) {
'use cache';
return fetch(`/api/data/${id}`);
}
```
we were previously generating (simplified):
```js
export var $$RSC_SERVER_CACHE_0 = cache("default", "0815", 0, async function(id) {
return fetch(`/api/data/${id}`);
});
```
In #85519, we restructured this to ensure proper stack frames in error
messages (simplified):
```js
export var $$RSC_SERVER_CACHE_0 = React.cache(function getCachedData() {
return cache("default", "0815", 0, async function(id) {
return fetch(`/api/data/${id}`);
}, arguments);
});
```
However, this introduced a small performance issue: the inner async
function expression was passed inline to the cache wrapper. While
`React.cache` memoizes the outer function, each unique set of arguments
would cause a new inner function object to be allocated.
Now we're generating (simplified):
```js
const $$RSC_SERVER_CACHE_0_INNER = async function getCachedData(id) {
return fetch(`/api/data/${id}`);
};
export var $$RSC_SERVER_CACHE_0 = React.cache(function getCachedData() {
return cache("default", "0815", 0, $$RSC_SERVER_CACHE_0_INNER, arguments);
});
```
The cache implementation is now hoisted to module scope with an `_INNER`
suffix as a const declaration with a named function expression. The
function name is preserved to ensure proper stack traces in dev. This
eliminates the repeated function allocations while preserving the
improvements from #85519.
### What?
Remove the hack we use for streaming in turbo-tasks.
We don't use the stream capability and the streaming hack causes some problems.
fixes `Item already exists` error
Closes https://github.com/vercel/next.js/issues/85833
This feature exists because we have some tests that aren't using the proper `OperationVc` APIs yet. It's documented that it should not be used in new code: https://github.com/search?q=repo%3Avercel%2Fnext.js%20non_operation_vc_strongly_consistent&type=code
This feature usage was added for some HMR benchmarks which were later removed. I added a comment to that PR here: https://github.com/vercel/next.js/pull/80219#discussion_r2143787319 (but it was after the PR merged)
The feature lets you strongly-consistently read or resolve a normal `Vc`. This API predates the `OperationVc` type, and is a footgun because if the `Vc` is already resolved, there's no meaningful way to read or resolve it with strong consistency.
- `experimental.ppr` was replaced with `cacheComponents`.
- It's still in the zod and TS type schemas, I think for our error messages on the Next.js side, but Turbopack only needs to know about the fields that Turbopack cares about. Serde silently ignores unknown fields by default.
- Nothing was reading this field from this struct.
- This unit test coverage is very overkill.
This implements a portion of the first iteration of a bundle analyzer for Turbopack in Next.js by writing data files to disk. A separate visualization and explorer tool will follow.
This data is written when builds are run with `next build --experimental-analyze`. An upcoming PR will implement a dedicated `next analyze` command that will write the data files without writing a complete build.
The data is derived from Turbopack’s module and chunk graphs, and precise module sizes are reversed from the source map data of each chunk. Importantly, this requires that source maps are generated within Turbopack and the project is recomputed with them -- however, no source maps are written as part of the build artifacts if the user did not configure their Next.js config that way.
The binary format written in these files is subject to change, so the feature is experimental for the time being. Until it stabilizes, no guarantees will be provided between it and the visualizer tool.
Test Plan:
In a test app:
- do not configure `productionBrowserSourceMaps`
- run `next build` and confirm **no files are written** to `.next/diagnostics/analyze`
- run `next build --analyze` and confirm files **are** written to `.next/diagnostics/analyze`
- Open the data with the yet-to-be-published visualization tool and confirm data is visible
Turns out this is all dead code, so delete it!
It looks like this was added back in https://github.com/vercel/turborepo/pull/3448, probably when Turbopack was trying to rewrite larger parts of Next.js than ended up happening.
### What
Add an option to turbopack to render sourcemap relative file paths in source maps
For now this is unused since it requires some support in next to be added in #85576
### Why
This will be useful for server source maps because it enables node and other runtimes to automatically format file paths to be working directory relative when printing errors to the console which many terminal emulators support to make clickable.
### TIL
My initial approach for this was to set the `sourceRoot` option to avoid prepending the same string onto nearly every source uri. However, the spec on this sourcemap feature is garbage. Intuitively i thought it worked like `<base href=...>` where relative uris would 'resolve' against it, but no, it is just a string concatenation feature. sigh.
### What?
Get rid of `impl Into` for value types. It's kind of legacy and we want cell creation to be kind of explicit instead of hidden in `into()` calls.
Also reduces the generated code size of the macro, potentially reducing rust build time and binary size.
The `.contains("/node_modules/")` condition didn't work for npm, where the path might be `"node_modules/.prisma/client"`
This fixes cases of the following error with Prisma and npm
```
Prisma Client could not locate the Query Engine for runtime "rhel-openssl-3.0.x".
We detected that you are using Next.js, learn how to fix this: https://pris.ly/d/engine-not-found-nextjs.
This is likely caused by tooling that has not copied "libquery_engine-rhel-openssl-3.0.x.so.node" to the deployment folder.
Ensure that you ran `prisma generate` and that "libquery_engine-rhel-openssl-3.0.x.so.node" has been copied to "node_modules/.prisma/client".
We would appreciate if you could take the time to share some information with us.
Please help us by answering a few questions: https://pris.ly/engine-not-found-tooling-investigation
The following locations have been searched:
/var/task/node_modules/.prisma/client
/var/task/node_modules/@prisma/client
/vercel/path0/node_modules/@prisma/client
/tmp/prisma-engines
```
These scopes aren't fully Next.js environments and can't access many
Next.js APIs. In the future this might change but for now we will
exclude the `next-js` condition when bundling for these entrypoints so
that 3rd parties that target Next.js can do so with the expectation that
regardless of what environment they are running in the full suite of
Next.js libraries they support will work.
This PR is the initiative of deprecating the edge runtime. Proxy will
default to Node.js runtime, and will not allow runtime config. If the
users want to use the edge runtime, they should stay on the Middleware,
though we recommend starting the migration.
---------
Co-authored-by: devjiwonchoi <devjiwonchoi@gmail.com>
Co-authored-by: JJ Kasper <jj@jjsweb.site>
Improve invalid Proxy/Middleware export error message to:
```
> Build error occurred
Error: The file "./proxy.ts" must export a function, either as a default export or as a named "proxy" export.
This function is what Next.js runs for every request handled by this proxy (previously called middleware).
Why this happens:
- You are migrating from `middleware` to `proxy`, but haven't updated the exported function.
- The file exists but doesn't export a function.
- The export is not a function (e.g., an object or constant).
- There's a syntax error preventing the export from being recognized.
To fix it:
- Ensure this file has either a default or "proxy" function export.
Learn more: https://nextjs.org/docs/messages/middleware-to-proxy
```
Turbopack:
```
Error: Turbopack build failed with 1 errors:
./proxy.ts
Proxy is missing expected function export name
This function is what Next.js runs for every request handled by this proxy (previously called middleware).
Why this happens:
- You are migrating from `middleware` to `proxy`, but haven't updated the exported function.
- The file exists but doesn't export a function.
- The export is not a function (e.g., an object or constant).
- There's a syntax error preventing the export from being recognized.
To fix it:
- Ensure this file has either a default or "proxy" function export.
Learn more: https://nextjs.org/docs/messages/middleware-to-proxy
```
Closes NEXT-4741
This PR fixes a critical issue with the `experimental.inlineCss` feature
where CSS `url()` references to fonts and other assets would break when
CSS was inlined into `<style>` tags instead of being loaded via external
`<link>` tags. The problem occurred because relative URLs in CSS are
resolved relative to the CSS file's location when loaded externally, but
when the CSS is inlined directly into the HTML document, those same
relative URLs resolve relative to the HTML document instead, causing 404
errors for fonts and images. We fixed this by detecting when CSS is
being prepared for inlining and switching from relative URLs (like
`../_next/static/media/font.woff2`) to absolute URLs (like
`/_next/static/media/font.woff2`) in both the Webpack and Turbopack
bundlers. This ensures that asset references work correctly regardless
of whether the CSS is inlined or external, while maintaining the
existing optimization of using relative URLs for the default case where
CSS is loaded via external stylesheets. The fix is transparent to users
and requires no changes to application code—simply enabling
`experimental.inlineCss: true` will now work correctly with all CSS
asset references.
Fixes https://github.com/vercel/next.js/issues/83674
---------
Co-authored-by: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com>
This removes the `routerBfCache` and enables it automatically when
`cacheComponents` is enabled. This leverages `React.Activity` on layout
segments to support restoring previously visited UI segments while
preserving state.
We don't really want to document this flag because 99% of developers won't need it, but we can detect this situation and suggest the flag.
Based on this user getting stuck: https://x.com/_bgwoodruff/status/1978493219068371330
Cache Components previously relied upon experimental only features in
React however now that partial prerendering in React is stabilized we
can now use the canary channel. There are still some features that
require experimental such as taint but for Cache Components by default
we should use canary.
This moves `experimental.cacheComponents` to a top level config. As part
of this, I disabled some tests in `build-output-prerender` that assert
on `cacheComponents` appearing in the experimental list. In a separate
PR, I'm going to show that Cache Components is enabled next to the
bundler info.
This also updates some docs pages to remove "experimental" language.
Certain patterns in source code cause turbopack to scan the project directories for resources. This can go wrong when one of those patterns can traverse into .next (oroborous!).
There is no usecase for turbopack to read files from the distDir during analysis and we can prevent that with a simple filter at the FileSystem layer which is what this PR does. Given the recent `build/dev` split this is a little subtle, so i added a new property to `NextConfigComplete` so we always pass the original `distDir` down even when we are performing the `dev` split.
The semantics of this are implemented at the filesystem layer which means:
* writing into a 'denied_path' is an error
* reading a denied path is 'not found'
* reading the parent directory of a denied path filters it.
Closes PACK-5593
### Why?
When Proxy/Middleware had invalid exports (valid: named function `proxy`
for `proxy.js`, named function `middleware` for `middleware.js`, or
default function), it errored during runtime but not during build.
This error can sneak into production as it only throws during runtime.
### How?
Walk AST of the Proxy/Middleware file, and if a valid export is not
found, throw during build.
---------
Co-authored-by: Benjamin Woodruff <benjamin.woodruff@vercel.com>
These are now stable but to allow for graceful upgrading we still export
unstable versions. The unstable version includes a once-warning that
indicates you should upgrade to the stable name.
### What?
Relaxes the overly strict `default.tsx` validation for parallel routes
to only require the file when it's actually needed (non-leaf segments
with routable children).
### Why?
The initial validation for parallel routes required `default.tsx` files
for all parallel route slots to prevent a specific issue: when
navigating to child routes, missing `default.tsx` files could cause
silent 404s in slot content, creating a confusing user experience.
However, this validation was **too strict** - it required `default.tsx`
even in cases where it wasn't actually necessary:
1. **Leaf segments** (routes with no child routes) - There are no child
routes to navigate to, so the 404 issue cannot occur
2. **Route groups** - These are organizational folders and aren't
routable themselves
3. **Catch-all parameters** - The matched segments are dynamic parameter
values, not actual child route segments
This caused false positive build errors for valid parallel route
configurations that don't have the underlying navigational issue.
NAR-448
At first, we performed one naive traversal per page to collect all client references. That had the problem that references used by multiple layout segments were attributed only to the first layout segment (e.g. only on `not-found` and not on `page`). Because the traversal doesn't revisit nodes.
That particular problem was fixed by https://github.com/vercel/next.js/pull/81704. But it didn't consider the fact that the order of client references isn't correctly modelled by having a `client reference -> vec<server components>` mapping to fixup whatever the graph traversal missed.
In this particular case, layout segment B had a unique client reference and one shared with layout segment A. So the fixup from above would then make B have `unique reference, shared reference` (because they were just added at the end), even though the real order (according to the graph is the reverse).
Instead, traverse once per layout segment, which doesn't have this problem.
### What?
Removes the deprecated `experimental_ppr` route-level configuration
option from Next.js.
### Why?
The PPR configuration feature has been deprecated in favor of the cache
components feature flag. The `experimental_ppr` route-level option no
longer has any effect since incremental PPR is not supported with cache
components.
Rather than silently ignoring this configuration, this change ensures
that users receive an explicit error when they attempt to export
`experimental_ppr` from their routes. This provides clear feedback that
the configuration needs to be removed when migrating to the cache
components approach.
### How?
- Removed `experimental_ppr` from the segment config schema and types
(both Rust and TypeScript)
- Updated `checkIsRoutePPREnabled` to no longer accept the `appConfig`
parameter since route-level config is removed
- Added `experimental_ppr` to the list of possibly invalid exports when
cache components are enabled, ensuring users get an error instead of
silent failure
- Removed unused `reduceAppConfig` import that was no longer needed
after these changes
This is about whether `new URL("logo.png", import.meta.url)` and `import logo from "./logo.png"` return a client or a server asset:
- a server asset is a file that will be read by the server during rendering, for example a Wasm or font file (if you think about vercel/og image generation). It's stored on the server next to the JS chunks
- a client asset is a file that will be used by the browser, e.g. for an `<img src={logo}/>` usecase. It will be stored on the CDN and have the `_next/` prefix.
For
- client contexts, it's easy: all imports are client assets (unsurprisingly)
- SSR contexts, we emulate the client (to prevent hydration mismatches)
- API/metadata context, it's less clear cut what should happen, but we arbitrarily do the following: `new URL` returns server assets and `import logo` returns client assets.
That very last case of having client assets for imports, and server assets for `new URL` wasn't implemented in Turbopack.
Turbopack doesn't change anything here fundamentally, but Webpack appears to have some bugs where this is less consistent (across nodejs/edge and api/metadata routes for example). See tests added in https://github.com/vercel/next.js/pull/84636
Closes PACK-4874
Closes PACK-5649
Closes#80577
Libraries that want to support Next.js without specific public adaptors
must use dynamic requires and other non-standard tricks to conditionally
load Next.js specific behavior. To simplify this we are adding a
condition to Next.js so that package authors can load Next.js specific
versions of code publicly (through export maps) and privately (through
import maps).
The condition is added when cacheComponents is enabled. This will allow
libraries to target modern Next.js conditionally without publishing new
majors with a new floor version for optional peer dependencies on
Next.js. In the future this will be the only mode for Next.js and the
condition will always be present
The condition is currently only implemented for bundled code. We want to
support this for externals too but it is tricky because determining the
right condition requires running Node.js first and I want to be careful
about adding any process indirection that slows down cold start. This
will be addressed in a future update.
---------
Co-authored-by: Sebastian Sebbie Silbermann <sebastian.silbermann@vercel.com>
TaskInputs should have deterministic serialization and that isn't really possible with `AutoSet`
This was only used as part of the `CapturedIssues` api, so that is modified to wrap the autoset in a `cell` instead of an `Arc`. Originally the `Arc` was used to make it possible to call `peek_issues` from top level `run_once` tasks. So to fix that, I audited callsites and moved one call of `peek_issues` from `handle_issues` into the `IssueReporter`.
As part of the audit, I changed the API of `take_issues` to `drop_issues` since that is the only usecase for this function.
When using `proxy`, the `Compiled X in ...` message in Turbopack had
hardcoded `middleware`. Therefore, modify to display `proxy` if using a
proxy. Also, Webpack displayed with a leading slash `/proxy`, which
could be misinterpreted as a route, so I removed the leading slash.