Commit Graph

28 Commits

Author SHA1 Message Date
Niklas Mischkulnig bdbf63aef7 fix(next-custom-transforms): never place generated imports before directives (#98717)
## Summary

**What?** Fixes the error reported for a module that has a top-level
`"use client"` directive and an inline `"use server"` function
directive, e.g. `<form action={async () => { "use server" }} />` in a
client page.

**Why?** Under Turbopack this reported a bogus error — `The "use client"
directive must be placed before other expressions` — even though the
directive was already at the top of the file. The actual mistake (an
inline server action inside a Client Component) was never surfaced.

**How?** On Turbopack's RSC layer the server actions transform runs
*before* the React Server Components assert. When it hoists an inline
action it prepended its generated imports (`registerServerReference`,
action encryption, cache runtime) at index 0 of the module — *above* the
`"use client"` directive, which the transform does not consume. The RSC
assert then saw an import before the directive and reported it as
misplaced.

Co-authored-by: vercel-fleet-prod[bot] <318278635+vercel-fleet-prod[bot]@users.noreply.github.com>
2026-09-16 17:09:32 +02:00
Hendrik Liebau cdf5c37d84 Scope app-entry export validation to files inside the app directory (#97350)
Adopts #97150. Closes #97150.

Fixes #96859

### What?

Since 16.3.0, builds fail for pages-router files named `sitemap` or
`robots` that export `getStaticProps`/`getServerSideProps`:

```
Error: "getStaticProps" is not supported in app/.
```

This is a regression from #94962, which added the metadata conventions
(`sitemap`, `robots`, `manifest`, `icon`, …) to the app-entry filename
regex in `ReactServerComponentValidator::assert_invalid_api`. The regex
only looks at the filename, so a file like `pages/sitemap.js` is now
mistaken for an app entry and rejected for exporting `getStaticProps`.

### How?

A file is only treated as an app entry when it's inside `appDir`,
reusing the gate `assert_server_filename` already applies to `error.js`.
The pages compilation context has no `appDir`, so pages-router files are
never validated as app entries.

On the test side:

- The fixtures that exercise the app-entry checks moved under
`app-dir/`, since the test harness derives `appDir` from the fixture
path. Their contents are unchanged.
- A new fixture (plus a `sitemap.js` fixture glob) asserts that a
pages-style `sitemap.js` compiles without errors.
- A new e2e suite, `test/e2e/pages-metadata-filenames`, covers
`pages/sitemap.js` with `getStaticProps` and `pages/robots.js` with
`getServerSideProps`. It fails without the fix under Turbopack (build
and dev) and passes with it under both Turbopack and webpack.

Supersedes #96873 (same approach, closed by its author) and closes
#96967.

---------

Co-authored-by: Rodrigo Arias <rodrigo@arias.me>
2026-08-14 11:53:24 +02:00
Sebastian "Sebbie" Silbermann cb44b43cdf Use page extensions in next-swc transforms applying to pages (#90650)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com>
Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
2026-03-04 16:13:36 +00:00
Luke Sandberg f93a867d77 Update wasm and next-custom-transforms crates to Rust edition 2024 (#90350)
The `wasm` and `next-custom-transforms` crates were still on Rust edition 2018 while the rest of the crates in this repo use edition 2024. This caused a pre-commit hook conflict:

- `cargo fmt` passes the crate's own edition (2018) to `rustfmt`, which uses **case-insensitive** import sorting
- The lint-staged pre-commit hook runs `rustfmt --edition 2024 --`, which uses **ASCII order** import sorting (uppercase before lowercase)

These two sort orders disagree on items like `{custom_before_pass, TransformOptions}` vs `{TransformOptions, custom_before_pass}`, causing an infinite flip-flop: every commit would reorder imports, and the next `cargo fmt` would reorder them back.

## Changes

- Bump `crates/wasm` and `crates/next-custom-transforms` from edition 2018 to 2024
- Add `+ use<C>` precise capturing to `server_actions()` return type to satisfy edition 2024's stricter `impl Trait` lifetime capture rules
- Add `style_edition = "2024"` to `.rustfmt.toml` as a safety net so `cargo fmt` uses 2024-style formatting regardless of individual crate editions
- Reformat all affected files with `cargo fmt`
- Apply new clippy rules
2026-02-23 01:48:12 -08:00
Janka Uryga c0d6a5d81e Guard against Object/Array shadowing in 'use cache' transform (#88229)
The transform output for 'use cache' uses `Object.defineProperty` and
`Array.prototype.slice`. In theory, it's possible for a module to shadow
those names and break it:
```ts
// i want to suffer!
const Array = {}
const Object = {}

async function cached() {
  "use cache"
  ...
}
```

We should defensively make sure that our transform's output refers to
the actual Object/Array builtins, not whatever's in scope for that name.
We can do this by using an unresolved syntax context for the
identifiers. This is what we do for `require()` elsewhere:
https://github.com/vercel/next.js/blob/6805af48baf1128e6b2a9e8f1752ee5982f02c60/crates/next-custom-transforms/src/transforms/track_dynamic_imports.rs#L119-L122
Using `quote_ident!(unresolved_ctxt, "Array")` will cause SWC to rename
any local redefinitions of `Array` to something that doesn't clash
(which can be seen in the added snapshots).
2026-01-07 19:04:15 +01:00
Zack Tanner b1ce6042be add compilation error for taint when not enabled (#88173)
Using `taint` APIs from React without enabling `experimental.taint` will
error at runtime because it needs to bundle experimental React, making
it hard to catch and potentially leading to downtime. This updates our
transform to throw an error if we detect that it's imported but `taint`
isn't enabled.

Fixes NAR-690
2026-01-06 11:57:46 -08:00
Niklas Mischkulnig 33e1764252 Bump swc to 48 (#86240)
Upgrade swc from 45 to 48

Based on #85540

- In the AST, strings now contain a `Wtf8Atom` (= not utf8), while `Ident`s keep using the utf8 `Atom`.
- swc's comment printing logic also changed slighted, moving some comments around
- ~~Some comments are getting lost along the way and/or attached to the wrong line. This also broke server actions which rely on a `__next_internal_client_entry_do_not_use__` at the very top~~
2025-11-21 12:47:13 +01:00
Hendrik Liebau ba20a5e8f2 Fix false-positive build error for cacheLife & cacheTag (#85875)
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
2025-11-11 17:30:41 +01:00
Hendrik Liebau 5bd7c6fec0 [test] Add missing test fixtures for cacheLife & cacheTag in client (#85872)
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.
2025-11-11 14:37:43 +01:00
Luke Sandberg 2289975541 [turbopack] Adopt rcstr! more consistently (#80552)
Replace construction of `RcStr` instances on constant strings with the `rcstr!` macro which can shift construction costs to compile time and eliminate reference counting.

Performance impacts from all the dropped ref counts are minor but do exist

![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/AwJ29EfoPcPdLSwCZxAz/e82b0e64-5803-4883-a89f-3090f1e937ce.png)

There is also a small progression in max heap which makes sense, laying out the static rcstrs should be a somewhat easier job compared to mimalloc.
2025-07-31 23:12:45 -07:00
Wyatt Johnson 8abbb3dc2e refactor: rename experimental.dynamicIO to experimental.cacheComponents (#81562)
## What?

Rename `experimental.dynamicIO` to `experimental.cacheComponents` across
the Next.js codebase.

## Why?

We're going to be merging the functionality of the `ppr`, `dynamicIO`
and `useCache` experimental flags into the singular `cacheComponents`
flag to reduce complexity of the codebase and simplify adoption for
users wanting to experiment with experimental features.

## How?

- Renamed the configuration option from `experimental.dynamicIO` to
`experimental.cacheComponents`
- Added deprecation handling with automatic migration for the old option
name
- Updated all documentation, tests, and internal references
- Updated Rust code in SWC transforms and Turbopack
- Maintained backward compatibility with deprecation warnings

NAR-158
2025-07-17 19:30:28 -06:00
Niklas Mischkulnig 2af3d065e7 Turbopack: split up server actions modules for better treeshaking (#76877)
Closes PACK-4074

We really need to look into getting e2e tests for correct sourcemaps: PACK-4142

Fix Turbopack server action tree shaking by explicitly splitting up that module

```js
/* __next_internal_action_entry_do_not_use__ {"00c18c215a6b7cdc64bf709f3a714ffdef1bf9651d":"default","70e10665baac148856374b2789aceb970f66fec33e":"myAction"} */ import { createServerReference, callServer, findSourceMapURL } from "private-next-rsc-action-client-wrapper";
export var foo = /*#__PURE__*/ createServerReference("70e10665baac148856374b2789aceb970f66fec33e", callServer, void 0, findSourceMapURL, "myAction");
export var bar = /*#__PURE__*/ createServerReference("00c18c215a6b7cdc64bf709f3a714ffdef1bf9651d", callServer, void 0, findSourceMapURL, "default");
```
->
```js
"use turbopack no side effects";
export { foo } from "data:text/javascript,%2F%2A%20__next_internal_action_entry_do_not_use__%20%7B%2200ab21efdafbe611287bc25c0462b1e0510d13e48b%22%3A%22foo%22%7D%20%2A%2F%22use%20turbopack%20no%20side%20effects%22%3Bimport%7BcreateServerReference%2CcallServer%2CfindSourceMapURL%7Dfrom%22private-next-rsc-action-client-wrapper%22%3Bexport%20var%20foo%3D%2F%2A%23__PURE__%2A%2FcreateServerReference%28%2200ab21efdafbe611287bc25c0462b1e0510d13e48b%22%2CcallServer%2Cvoid%200%2CfindSourceMapURL%2C%22foo%22%29%3B";
export { bar } from "data:text/javascript,%2F%2A%20__next_internal_action_entry_do_not_use__%20%7B%2200ac840dcaf5e8197cb02b7f3a43c119b7a770b272%22%3A%22bar%22%7D%20%2A%2F%22use%20turbopack%20no%20side%20effects%22%3Bimport%7BcreateServerReference%2CcallServer%2CfindSourceMapURL%7Dfrom%22private-next-rsc-action-client-wrapper%22%3Bexport%20var%20bar%3D%2F%2A%23__PURE__%2A%2FcreateServerReference%28%2200ac840dcaf5e8197cb02b7f3a43c119b7a770b272%22%2CcallServer%2Cvoid%200%2CfindSourceMapURL%2C%22bar%22%29%3B";
````

- [x] Keep [sourcemaps](https://github.com/vercel/next.js/blob/canary/test/development/app-dir/source-mapping/README.md#server-actions)
2025-03-17 15:52:17 +01:00
Tim Neutkens 9d1c6fddf0 Turbopack: Ensure server actions sourcemaps tests pass (#76157)
## What?

Follow-up to #76129. Fixes the sourcemap, ensures the mappings are not
carried over when compiling for the client. For the server these
mappings are preserved.

<!-- 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 #

-->
2025-02-27 10:59:12 +01:00
Hendrik Liebau 7aa61377fb Emit build error when useCache is enabled and Edge runtime is used (#75279)
The `"use cache"` directive is not compatible with the Edge runtime.

When the `experimental.useCache` flag is enabled, we now emit a build
error for pages with `export const runtime = 'edge'`. This is analogous
to using the `experimental.dynamicIO` flag.

The other route segment configs that are forbidden when `dynamicIO` is
enabled, are currently still allowed for `useCache`:

- `dynamicParams`
- `dynamic`
- `fetchCache`
- `revalidate`
2025-01-24 17:33:24 +00:00
Hendrik Liebau 958b9669fb Add test fixtures demonstrating export statement validation bugs (#75277)
The issues with the current export statement validation for app router
pages are documented in the added fixtures, see also the inline comments
in the diff.
2025-01-24 17:24:02 +01:00
Hendrik Liebau bf726d3c21 Introduce standalone experimental.useCache flag (#75240) 2025-01-24 00:28:05 +01:00
Jude Gao 07d2820645 Track use cache usage (#75007)
We’re updating the SWC transform to
[track](https://nextjs.org/telemetry) how the "use cache" directive is
used during builds. Each use of "use cache" is counted based on the
handler it’s linked to.

By default, "use cache" counts toward a feature called
"useCache/default". If a custom handler is defined in the Next.js config
(e.g., "custom"), then "use cache: custom" will count toward
"useCache/custom".

The build process will collect these counts and combine them across all
source files and workers. This data is reported under the
NEXT_BUILD_FEATURE_USAGE event, allowing us to filter by "useCache/*" to
see how often each cache handler is used.

*Only support webpack prod build for now.

Closes NDX-683
2025-01-22 11:41:04 -05:00
Hendrik Liebau d54122a712 Emit build error for unknown cache kinds (#72832)
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>
2024-11-17 17:03:16 +01:00
Hendrik Liebau 2c6b09d57d Emit build error when "use cache" is used without dynamicIO enabled (#72781)
Using a build error instead of a runtime error allows us to fail early,
and show a proper error source in the terminal and in the dev overlay.

<img width="777" alt="Screenshot 2024-11-13 at 22 19 45"
src="https://github.com/user-attachments/assets/d0ee3c69-71f5-4aa6-8c0a-879217f66930">
2024-11-13 21:43:58 +00:00
Hendrik Liebau c3467c7f5f Remove unused enabled config from server actions transforms (#72755)
The option was always set to `true` so we can safely remove it. The
experimental `serverActions` flag was removed a long time ago in #57145.
2024-11-13 11:55:34 +00:00
Donny/강동윤 4373f96f24 build: Update swc_core to v5.0.1 (#71683)
### What?

ChangeLog:
https://github.com/swc-project/swc/compare/swc_core%40v1.0.6...swc_core%40v5.0.1

### Why?

To keep in sync.

### How?

 - Closes SWC-612

 - Depends on https://github.com/wooorm/mdxjs-rs/pull/55
2024-11-06 22:00:26 +09:00
Zack Tanner e1e25e16ae use server component transform for segment validation (#72051)
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>

![CleanShot 2024-10-29 at 17 03
46@2x](https://github.com/user-attachments/assets/a68c060a-6ae7-4c6c-8243-6c48c2703f66)



</details>
2024-10-30 11:30:37 -07:00
Shu Ding 1face6e6e0 Improve SWC transform ID generation (#69183)
This adds an extra `hash_salt` option to the Server Actions transform's
`generate_action_id` method which defaults to empty for now (so no
actual behavior changes). When set, the salt will be used to prefix the
payload.
2024-08-22 23:07:05 +02:00
Donny/강동윤 0a3fa759a9 build: Update swc_core to v0.101.3 (#69039)
This reverts commit 4c33361f4c.


### What?

 - Reverts https://github.com/vercel/next.js/pull/68978
 - Re-apply https://github.com/vercel/next.js/pull/68560

### Why?

The bug of `Evaluator` is fixed.

### How?
2024-08-20 22:44:27 +02:00
Donny/강동윤 4c33361f4c Revert "Update swc_core to v0.100.6 (#68560)" (#68978)
### What?

Revert swc_core upgrade, as it has a bug related to `styled_jsx`
transform.

Wasm plugin version runs after the TypeScript pass so it works, but
custom transform (next-swc) runs before the typescript pass so it
breaks.

### Why?

It broke some apps.

### How?
2024-08-16 13:17:14 +00:00
Donny/강동윤 c823dd09c7 Update swc_core to v0.100.6 (#68560)
### What?

Update SWC crates to
https://github.com/swc-project/swc/commit/ed635ce91086f2eb00644bbca036ca686f035dbe

### Why?

To keep in sync.

### How?
2024-08-16 16:17:59 +09:00
hrmny 9dc685edea chore: remove turbopack-binding and other unused crates (#68456)
### What?

Removes the `turbopack-binding` crate which is unnecessary now that we
have everything in one repo.
This should improve compile times a bit.

Closes PACK-3162
2024-08-05 16:50:45 +00:00
hrmny cad3a51049 refactor: move rust crates to the repo root directory (#67780)
### Why?
In preparation for moving all turbopack crates

Also makes them easier to work with in general.

Closes PACK-3164
2024-07-22 18:41:27 +02:00