### What?
Use `ResolvedVc<T>` instead of `Vc<T>` for struct fields in `next-api`, but split into multiple PRs.
### Why?
To reduce scope of changes of each PRs so I can debug HMR failures.
### How?
### What?
Use `ResolvedVc<T>` instead of `Vc<T>` for struct fields in `next-api`, but split into multiple PRs.
### Why?
To reduce scope of changes of each PRs so I can debug HMR failures.
### How?
### What?
Use `ResolvedVc<T>` instead of `Vc<T>` for struct fields in `next-api`, but split into multiple PRs.
### Why?
To reduce scope of changes of each PRs so I can debug HMR failures.
### How?
### What?
Use `ResolvedVc<T>` instead of `Vc<T>` for struct fields in `next-api`, but split into multiple PRs.
### Why?
To reduce scope of changes of each PRs so I can debug HMR failures.
### How?
aka "one graph"
- Make client references actual references (non-chunkable, so chunking
ignores them right now. We can change that later and move more chunking
into Turbopack itself as opposed to the manual stuff in `AppEndpoint`)
- `find server actions` now just walks the rsc_entry and discovery
client references itself
- `collecting next/dynamic` still walks the RSC graph which is wrong (as
before). I left this to make this PR a noop that shouldn't change any
behavior. We'll fix this in the coming reimplementation (and add tests
for what is apparently currently not asserted 😐)
**View without whitespace changes**
Closes PACK-3532
Depends on https://github.com/vercel/next.js/pull/73010
A very small speedup, mostly noticeable in cpu time, not really in wall
time
```
before:
504.86s user 73.31s system 792% cpu 1:12.93 total
522.09s user 76.70s system 778% cpu 1:16.94 total
503.73s user 68.78s system 818% cpu 1:09.92 total
after:
471.20s user 61.73s system 757% cpu 1:10.33 total
481.69s user 69.05s system 805% cpu 1:08.33 total
```
With this PR, we are allowing _static_ class methods to be annotated with `"use cache"` or `"use server"`.
Class _instance_ methods on the other hand are not allowed as server functions.
- adds per-module tracing for `find server actions` (it's implemented in
the same way for next/dynamic and client references). Now, `find server
actions` isn't just a single blob anymore.
- add a tracing span for `all_server_paths`
Accessing `this` or `arguments` in server functions is not allowed. With
this PR, we are now emitting build errors in this case.
---------
Co-authored-by: Janka Uryga <lolzatu2@gmail.com>
This is a follow-up fix for #72969. Method or function properties of exported objects in `"use cache"` or `"use server"` files must not be compiled into server functions, unless they have an inline server directive.
This PR has two main goals:
- **Consolidate the detection of server directives in modules and function bodies.** Previously, these were two separate implementations with significant overlap, but also some [questionable discrepancies](https://github.com/vercel/next.js/pull/72811#discussion_r1843660381).
- **Model the current directive (in a file or function) using an enum instead of two separate booleans.** This change prevents any confusion that both directives might be present simultaneously. Additionally, we're now emitting an error if multiple directives (`"use server"` and `"use cache"`) are defined in the same location (at the top of a file or function body).
A mixed usage of `"use server"` and `"use cache"` _across different locations_ is still allowed, e.g. `"use cache"` at the top of a file, and `"use server"` in a function.
> [!NOTE]
> The diff may be tricky to review because chunks from two different functions are combined into a single function. Fortunately, we have comprehensive test coverage for the transforms, which instills high confidence that these changes are correct.
There's significant drift between how Link is implemented in pages vs app dir, and we're planning to make even more changes. (For example, we want to change the intersection observer prefetch behavior, but only in app router)
To simplify this drift in behavior, this will alias `next/link` to `client/app-dir/link.tsx` in app dir bundles.
There is no change in behavior to the `link` component in this PR. The next PR in the stack will remove the current forked handling to remove things that are irrelevant to the router it's rendered in.
### What?
Enable single-incoming-edge optimization for module fragments with `ModulePart::Export`.
### Why?
It will reduce the number of modules greatly.
### How?
Closes PACK-3481
The edge runtime does `await
self._ENTRIES["middleware_..."].default.call(...)`, so instead export a
Proxy that hides that the module object itself is a promise.
Partial revert of https://github.com/vercel/next.js/pull/62141
With this PR, we are now allowing `"use server"` and `"use cache"` to be
used in method properties, e.g.:
```js
export const obj = {
async foo() {
'use cache'
return Math.random()
},
async bar() {
'use server'
console.log(42)
},
}
```
Or, more realistically, something like this:
```js
export const api = {
product: {
async fetch() {
'use cache'
return fetch('https://example.com').then((res) => res.json())
},
},
}
```
Supporting this pattern is mostly done for convenience; it allows users
to group server functions into a common object, using method properties.
Notably, we will not support the usage of `this` and `super`, for which
we will add build errors in a follow-up PR.
By adding `visit_mut_function` we can deduplicate the code that's common between `visit_mut_fn_expr` and `visit_mut_fn_decl`. And more importantly, this prepares us for handling the transform of method props, which will also use `visit_mut_function`.
As a positive side effect this brings two small improvements with it:
- always highlight the whole function when `async` is missing, not only the identifier
- assign a function name to an anonymous arrow function expression in a variable declaration
Closes PACK-3421
Address PR feedback from https://github.com/vercel/next.js/pull/72305
When working on this, I uncovered another bug which will be handled in a
different PR.
Changes:
- Don't rely on `DiskFileSystem` but only via file paths and
`is_inside()`
- Put the `RebasedAsset` for externals on the `[project]/` fs (this way,
they aren't emitted either), i.e. don't perform any rebasing at all and
just reference the files where they are
---------
Co-authored-by: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com>
- Change the Next manifest output assets to also track references to output assets there. That way, `page.js.nft.json` lists the referenced output assets of `page.js` and e.g. `page_client-reference-manifest.js` and all the chunks references in the manifest as well.
- For `ResolveResultItem::External`, continue resolving with a fresh `ModuleAssetContext` that doesn't have any of the build-time settings (because the Node environment when running the server won't have these settings either).
Closes PACK-3380
The bread and butter of NFT. The next two PRs split the work into two halves, one half plumbs as far as ResolveResultItem, and the next one fills in the remaining (and fixes some bugs).
Closes PACK-3379
### Why?
Before we just wrote the files in `FileSystem::write()`, but that caused some issues when two `FileSystem::write()` tasks are active (or even temporarily active) at the same time. They invalidate each other and basically caused a loop of writes.
For a long time we wanted to have a better solution for that, since that problem causes compilation to hang with 100% cpu load, which is quite annoying.
Also the eventual consistency can cause some unexpected writes to be done when the content or filename are on a temporary value that has not stabilised yet.
The problem applies to every side effect in tasks.
### What?
To solve that this refactoring changes the way side effects in tasks are handled.
Side effects in tasks should not be directly executed anymore. Instead one should emit an "effect" (`effect(async { ... })` helper method) to declare a side effect that should be executed. Top level execution is usually wrapped in a strongly consistent read of the top level task. Here one need to apply the "effects" (`apply_effects(operation).await?` helper method). Since this happens after the strongly consistent read, only effects that have been stabilised are executed.
It's also possible to call `apply_effects` somewhere nested in the execution (after a strongly consistent read) if side effects are necessary for further execution. e. g. we do that to emit the files for the node.js pool before executing the pool.
Internally effects are collectibles that are propagated through the call graph. Each effect can only be executed once, so updates to the graph will only apply new effects while existing effects are skipped as they were already executed.
The actual change is pretty simple, but `FileSystem::write` no longer returns a `Vc<Completion>` but nothing instead. This makes the change needed a bit bigger.
Good news: To emit a whole (potential circular) graph we could use recursion now instead of needing to walk the graph while avoiding cycles. This might allow some performance improvements for incremental builds.
When a `"use cache"` directive with a custom cache kind is used, e.g.
`"use cache: custom"`, a cache handler with the same name must be
specified in the Next.js config:
```js
/**
* @type {import('next').NextConfig}
*/
const nextConfig = {
experimental: {
dynamicIO: true,
cacheHandlers: {
custom: require.resolve('path/to/custom/cache/handler'),
},
},
}
module.exports = nextConfig
```
If this is not the case, we emit a build error with an error message
that explains this requirement.
<img width="795" alt="Screenshot 2024-11-14 at 23 30 01"
src="https://github.com/user-attachments/assets/bd138c97-608f-42ce-abb2-edb3e44edc3f">
When we'll get a docs page for this experimental config, we will add the
usual "Read more: ..." hint as well.
---------
Co-authored-by: Benjamin Woodruff <benjamin.woodruff@vercel.com>
Co-authored-by: Janka Uryga <lolzatu2@gmail.com>
The `RcStr` type doesn't use anything in `turbo-tasks`, so there's no reason it can't be a separate crate that doesn't depend on `turbo-tasks`.
This will let it be used in wasm swc plugins, where turbo-tasks does not currently compile.
Imports were automatically rewritten with:
```
# Fix imports:
sg run --lang rust --pattern 'use $CRATE::{$$$PRE, RcStr};' --rewrite 'use $CRATE::{$$$PRE}; use turbo_rcstr::RcStr;' --update-all
sg run --lang rust --pattern 'use $CRATE::{RcStr, $$$POST};' --rewrite 'use $CRATE::{$$$POST}; use turbo_rcstr::RcStr;' --update-all
sg run --lang rust --pattern 'use $CRATE::{$$$PRE, RcStr, $$$POST};' --rewrite 'use $CRATE::{$$$PRE, $$$POST}; use turbo_rcstr::RcStr;' --update-all
sg run --lang rust --pattern 'use $CRATE::RcStr;' --rewrite 'use turbo_rcstr::RcStr;' --update-all
cargo fmt
# Fix strings in comments:
fastmod crate::RcStr turbo_rcstr::RcStr
fastmod turbo_tasks::RcStr turbo_rcstr::RcStr
```
I had to manually fix the `Cargo.toml` files based on the compilation errors.
This improves maintainability and readability by decluttering the server actions transforms implementation, dedupes a few error messages, and consistently uses periods and trailing newlines for all error messages.
The same approach is already used for the React Server Components transforms.
### What?
The `data` variant for pages and the `rsc` variant for app router (for change notification purposes) causes some conflicting writes in the next-rs test case. This causes some instability since we are invalidating in a loop.
Noticed this mess while working with @samcx on #72442 where we had to run:
```
cargo nextest r --features next-core/native-tls -p next-core
```
This PR makes `turbo-tasks-fetch` responsible for setting the `reqwest` TLS features, rather than trying to pass that feature flag down.
After this PR, running tests on `next-core` works with just:
```
cargo nextest r -p next-core
```
## Why?
- The feature flag logic was getting duplicated in multiple top-level targets.
- Packages that depended on `turbo-tasks-fetch` (directly *or transitively*) had to specify a default feature and make sure that default feature was disabled in the workspace's dependency list so that `cargo test -p package-name` would work
- ... or you had to specify a flag when compiling, like `--features next-core/native-tls`.
Technically this change gives us less flexibility. We can't produce multiple binaries for the same platform target with different TLS stacks. But I don't think we would've ever used that flexibility anyways.
### What?
Add options for the new backend to disable certain features.
* Storage can be disabled to avoid capturing change log data.
* Dependency tracking can be disabled when no changes are expected and no persistence is used
* Children tracking can be disabled for testing purposes.
Closes PACK-3405
Considering the bound args param in the server reference information byte is required for a client-side optimization of omitting unused arguments to work properly when a server action or `"use cache"` function uses closed-over variables.
The server reference information byte is not used yet, so this PR should not change any observable behavior.
This is a pure refactoring without any behavioral changes. It will allow us to more easily incorporate the presence of the bound args param into the server reference information byte.
Early returns should use `anyhow::bail!()`.
Ran ast-grep with
```bash
sg run --lang rust --pattern 'return Err(anyhow!($$$ARGS));' --rewrite 'anyhow::bail!($$$ARGS)' --update-all && sg run --lang rust --pattern 'return Err(anyhow::anyhow!($$$ARGS));' --rewrite 'anyhow::bail!($$$ARGS)' --update-all && cargo fmt
```
Manually cleaned up unused import warnings (second commit) because `cargo fix` hangs (idle, no CPU usage) about halfway through our build, and I'm not sure why. I tested the latest nightly, and it hangs too.
Adds tracing settings to the various contexts that are used for nft
There are cases where we need to know whether tracing is useful, this PR sets up that state ahead of the next one(s) which actually take advantage of them.
Closes PACK-3377