From fe4e4d2c338ea1eceeb3d70abedd80d6069d2582 Mon Sep 17 00:00:00 2001 From: "Sebastian \"Sebbie\" Silbermann" Date: Tue, 22 Oct 2024 20:05:19 +0200 Subject: [PATCH 01/44] react-sync: Automatically update peer dependencies in libraries (#71636) --- scripts/sync-react.js | 48 ++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/scripts/sync-react.js b/scripts/sync-react.js index 915bc835f0dbb1..171434cff8dec7 100644 --- a/scripts/sync-react.js +++ b/scripts/sync-react.js @@ -20,8 +20,11 @@ const filesReferencingReactPeerDependencyVersion = [ 'packages/create-next-app/templates/index.ts', 'test/lib/next-modes/base.ts', ] -const appManifestsInstallingNextjsPeerDependencies = [ +const libraryManifestsSupportingNextjsReact = [ 'packages/third-parties/package.json', + 'packages/next/package.json', +] +const appManifestsInstallingNextjsPeerDependencies = [ 'examples/reproduction-template/package.json', 'test/.stats-app/package.json', // TODO: These should use the usual test helpers that automatically install the right React version @@ -322,25 +325,6 @@ Or, run this command with no arguments to use the most recently published versio } } - const nextjsPackageJsonPath = path.join( - process.cwd(), - 'packages', - 'next', - 'package.json' - ) - const nextjsPackageJson = JSON.parse( - await fsp.readFile(nextjsPackageJsonPath, 'utf-8') - ) - nextjsPackageJson.peerDependencies.react = `^18.2.0 || ${newVersionStr}` - nextjsPackageJson.peerDependencies['react-dom'] = - `^18.2.0 || ${newVersionStr}` - await fsp.writeFile( - nextjsPackageJsonPath, - JSON.stringify(nextjsPackageJson, null, 2) + - // Prettier would add a newline anyway so do it manually to skip the additional `pnpm prettier-write` - '\n' - ) - for (const fileName of appManifestsInstallingNextjsPeerDependencies) { const packageJsonPath = path.join(cwd, fileName) const packageJson = await fsp.readFile(packageJsonPath, 'utf-8') @@ -360,7 +344,29 @@ Or, run this command with no arguments to use the most recently published versio } if (commit) { - await commitEverything('Updated peer dependency references') + await commitEverything('Updated peer dependency references in apps') + } + + for (const fileName of libraryManifestsSupportingNextjsReact) { + const packageJsonPath = path.join(cwd, fileName) + const packageJson = await fsp.readFile(packageJsonPath, 'utf-8') + const manifest = JSON.parse(packageJson) + if (manifest.peerDependencies['react']) { + manifest.peerDependencies['react'] = `^18.2.0 || ${newVersionStr}` + } + if (manifest.peerDependencies['react-dom']) { + manifest.peerDependencies['react-dom'] = `^18.2.0 || ${newVersionStr}` + } + await fsp.writeFile( + packageJsonPath, + JSON.stringify(manifest, null, 2) + + // Prettier would add a newline anyway so do it manually to skip the additional `pnpm prettier-write` + '\n' + ) + } + + if (commit) { + await commitEverything('Updated peer dependency references in libraries') } // Install the updated dependencies and build the vendored React files. From 703d276ecbb6f3230f113dd00f5fa54862ac2dd5 Mon Sep 17 00:00:00 2001 From: Ivan Vasilov Date: Tue, 22 Oct 2024 20:10:04 +0200 Subject: [PATCH 02/44] examples: Update `with-supabase` to be compatible with Nextjs 15 (#71631) Co-authored-by: Lee Robinson --- .../app/(auth-pages)/forgot-password/page.tsx | 7 +++---- .../app/(auth-pages)/sign-in/page.tsx | 3 ++- .../app/(auth-pages)/sign-up/page.tsx | 5 ++++- examples/with-supabase/app/actions.ts | 14 +++++++------- examples/with-supabase/app/auth/callback/route.ts | 2 +- examples/with-supabase/app/protected/page.tsx | 2 +- .../app/protected/reset-password/page.tsx | 7 +++---- examples/with-supabase/components/header-auth.tsx | 4 +++- examples/with-supabase/utils/supabase/server.ts | 4 ++-- 9 files changed, 26 insertions(+), 22 deletions(-) diff --git a/examples/with-supabase/app/(auth-pages)/forgot-password/page.tsx b/examples/with-supabase/app/(auth-pages)/forgot-password/page.tsx index 203e37b8c1bff8..bcf972555a5079 100644 --- a/examples/with-supabase/app/(auth-pages)/forgot-password/page.tsx +++ b/examples/with-supabase/app/(auth-pages)/forgot-password/page.tsx @@ -6,11 +6,10 @@ import { Label } from "@/components/ui/label"; import Link from "next/link"; import { SmtpMessage } from "../smtp-message"; -export default function ForgotPassword({ - searchParams, -}: { - searchParams: Message; +export default async function ForgotPassword(props: { + searchParams: Promise; }) { + const searchParams = await props.searchParams; return ( <>
diff --git a/examples/with-supabase/app/(auth-pages)/sign-in/page.tsx b/examples/with-supabase/app/(auth-pages)/sign-in/page.tsx index dabdf8c5cdae5b..7628cc7a5f2d42 100644 --- a/examples/with-supabase/app/(auth-pages)/sign-in/page.tsx +++ b/examples/with-supabase/app/(auth-pages)/sign-in/page.tsx @@ -5,7 +5,8 @@ import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import Link from "next/link"; -export default function Login({ searchParams }: { searchParams: Message }) { +export default async function Login(props: { searchParams: Promise }) { + const searchParams = await props.searchParams; return (

Sign in

diff --git a/examples/with-supabase/app/(auth-pages)/sign-up/page.tsx b/examples/with-supabase/app/(auth-pages)/sign-up/page.tsx index 1abbd3b8abfb87..31b5a6d32354f2 100644 --- a/examples/with-supabase/app/(auth-pages)/sign-up/page.tsx +++ b/examples/with-supabase/app/(auth-pages)/sign-up/page.tsx @@ -6,7 +6,10 @@ import { Label } from "@/components/ui/label"; import Link from "next/link"; import { SmtpMessage } from "../smtp-message"; -export default function Signup({ searchParams }: { searchParams: Message }) { +export default async function Signup(props: { + searchParams: Promise; +}) { + const searchParams = await props.searchParams; if ("message" in searchParams) { return (
diff --git a/examples/with-supabase/app/actions.ts b/examples/with-supabase/app/actions.ts index 032715549c1c64..f16b94174f78e9 100644 --- a/examples/with-supabase/app/actions.ts +++ b/examples/with-supabase/app/actions.ts @@ -8,8 +8,8 @@ import { redirect } from "next/navigation"; export const signUpAction = async (formData: FormData) => { const email = formData.get("email")?.toString(); const password = formData.get("password")?.toString(); - const supabase = createClient(); - const origin = headers().get("origin"); + const supabase = await createClient(); + const origin = (await headers()).get("origin"); if (!email || !password) { return { error: "Email and password are required" }; @@ -38,7 +38,7 @@ export const signUpAction = async (formData: FormData) => { export const signInAction = async (formData: FormData) => { const email = formData.get("email") as string; const password = formData.get("password") as string; - const supabase = createClient(); + const supabase = await createClient(); const { error } = await supabase.auth.signInWithPassword({ email, @@ -54,8 +54,8 @@ export const signInAction = async (formData: FormData) => { export const forgotPasswordAction = async (formData: FormData) => { const email = formData.get("email")?.toString(); - const supabase = createClient(); - const origin = headers().get("origin"); + const supabase = await createClient(); + const origin = (await headers()).get("origin"); const callbackUrl = formData.get("callbackUrl")?.toString(); if (!email) { @@ -87,7 +87,7 @@ export const forgotPasswordAction = async (formData: FormData) => { }; export const resetPasswordAction = async (formData: FormData) => { - const supabase = createClient(); + const supabase = await createClient(); const password = formData.get("password") as string; const confirmPassword = formData.get("confirmPassword") as string; @@ -124,7 +124,7 @@ export const resetPasswordAction = async (formData: FormData) => { }; export const signOutAction = async () => { - const supabase = createClient(); + const supabase = await createClient(); await supabase.auth.signOut(); return redirect("/sign-in"); }; diff --git a/examples/with-supabase/app/auth/callback/route.ts b/examples/with-supabase/app/auth/callback/route.ts index 68035d1d385247..dd415a4834773b 100644 --- a/examples/with-supabase/app/auth/callback/route.ts +++ b/examples/with-supabase/app/auth/callback/route.ts @@ -11,7 +11,7 @@ export async function GET(request: Request) { const redirectTo = requestUrl.searchParams.get("redirect_to")?.toString(); if (code) { - const supabase = createClient(); + const supabase = await createClient(); await supabase.auth.exchangeCodeForSession(code); } diff --git a/examples/with-supabase/app/protected/page.tsx b/examples/with-supabase/app/protected/page.tsx index cbc4876f4312c3..5508abab311101 100644 --- a/examples/with-supabase/app/protected/page.tsx +++ b/examples/with-supabase/app/protected/page.tsx @@ -4,7 +4,7 @@ import { InfoIcon } from "lucide-react"; import { redirect } from "next/navigation"; export default async function ProtectedPage() { - const supabase = createClient(); + const supabase = await createClient(); const { data: { user }, diff --git a/examples/with-supabase/app/protected/reset-password/page.tsx b/examples/with-supabase/app/protected/reset-password/page.tsx index 7b7ab9516e97e6..9cd70846530f19 100644 --- a/examples/with-supabase/app/protected/reset-password/page.tsx +++ b/examples/with-supabase/app/protected/reset-password/page.tsx @@ -4,11 +4,10 @@ import { SubmitButton } from "@/components/submit-button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; -export default async function ResetPassword({ - searchParams, -}: { - searchParams: Message; +export default async function ResetPassword(props: { + searchParams: Promise; }) { + const searchParams = await props.searchParams; return (

Reset password

diff --git a/examples/with-supabase/components/header-auth.tsx b/examples/with-supabase/components/header-auth.tsx index 49072e9673cda4..eb9d65c1e7c037 100644 --- a/examples/with-supabase/components/header-auth.tsx +++ b/examples/with-supabase/components/header-auth.tsx @@ -6,9 +6,11 @@ import { Button } from "./ui/button"; import { createClient } from "@/utils/supabase/server"; export default async function AuthButton() { + const supabase = await createClient(); + const { data: { user }, - } = await createClient().auth.getUser(); + } = await supabase.auth.getUser(); if (!hasEnvVars) { return ( diff --git a/examples/with-supabase/utils/supabase/server.ts b/examples/with-supabase/utils/supabase/server.ts index e18626fe370c35..2c00bbc9636ebb 100644 --- a/examples/with-supabase/utils/supabase/server.ts +++ b/examples/with-supabase/utils/supabase/server.ts @@ -1,8 +1,8 @@ import { createServerClient } from "@supabase/ssr"; import { cookies } from "next/headers"; -export const createClient = () => { - const cookieStore = cookies(); +export const createClient = async () => { + const cookieStore = await cookies(); return createServerClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, From a8445ed46eda32c46ea33b0f2688805e2a775e66 Mon Sep 17 00:00:00 2001 From: Steven Date: Tue, 22 Oct 2024 14:34:04 -0400 Subject: [PATCH 03/44] chore(docs): fix typo in image.mdx docs (#71647) There was an extra backtick causing a format error. https://nextjs.org/docs/app/api-reference/components/image#src image --- docs/02-app/02-api-reference/01-components/image.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/02-app/02-api-reference/01-components/image.mdx b/docs/02-app/02-api-reference/01-components/image.mdx index 05ed6d23c4b23a..2a2c0bace7a5f5 100644 --- a/docs/02-app/02-api-reference/01-components/image.mdx +++ b/docs/02-app/02-api-reference/01-components/image.mdx @@ -93,7 +93,7 @@ When using the default [loader](#loader), also consider the following for source - When src is an external URL, you must also configure [remotePatterns](#remotepatterns) - When src is [animated](#animated-images) or not a known format (JPEG, PNG, WebP, AVIF, GIF, TIFF) the image will be served as-is -- When src is SVG format, it will be blocked unless [`unoptimized`](#unoptimized)` or [`dangerouslyAllowSVG`](#dangerouslyallowsvg) is enabled +- When src is SVG format, it will be blocked unless [`unoptimized`](#unoptimized) or [`dangerouslyAllowSVG`](#dangerouslyallowsvg) is enabled ### `width` From e06cd47449c2b358a013ec2a322c7ad9512dfb3a Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Tue, 22 Oct 2024 21:11:15 +0200 Subject: [PATCH 04/44] docs: remove the canary note on instrumentation (#71649) The note of `onRequestError` API is outdated, it's available on v15 stable now Fixes #71634 --- .../02-api-reference/02-file-conventions/instrumentation.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/02-app/02-api-reference/02-file-conventions/instrumentation.mdx b/docs/02-app/02-api-reference/02-file-conventions/instrumentation.mdx index 73a5659152f6af..a867354eed950d 100644 --- a/docs/02-app/02-api-reference/02-file-conventions/instrumentation.mdx +++ b/docs/02-app/02-api-reference/02-file-conventions/instrumentation.mdx @@ -35,8 +35,6 @@ export function register() { ### `onRequestError` (optional) -> This API is available in Next.js canary. - You can optionally export an `onRequestError` function to track **server** errors to any custom observability provider. - If you're running any async tasks in `onRequestError`, make sure they're awaited. `onRequestError` will be triggered when the Next.js server captures the error. From 95720f4cc18f4ce1dbc6c394fc194ff89b1462af Mon Sep 17 00:00:00 2001 From: Benjamin Woodruff Date: Tue, 22 Oct 2024 12:40:46 -0700 Subject: [PATCH 05/44] fix(turbo-tasks): Implement ValueDebugFormat for ResolvedVc (#71173) Caught this missing implementation when the codemod in #71172 tried to convert this test to use `ResolvedVc`. This implementation just forwards to the one on `Vc`. I don't think we need an explicit test case for `Vc` inside of a struct, because the plan is to codemod away virtually every instance of this. Co-authored-by: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> --- turbopack/crates/turbo-tasks-testing/tests/debug.rs | 8 ++++---- turbopack/crates/turbo-tasks/src/vc/resolved.rs | 11 +++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/turbopack/crates/turbo-tasks-testing/tests/debug.rs b/turbopack/crates/turbo-tasks-testing/tests/debug.rs index fc44f7c56e8c33..35d13c8d4e6f55 100644 --- a/turbopack/crates/turbo-tasks-testing/tests/debug.rs +++ b/turbopack/crates/turbo-tasks-testing/tests/debug.rs @@ -47,7 +47,7 @@ async fn enum_none_debug() { #[tokio::test] async fn enum_transparent_debug() { run(®ISTRATION, || async { - let a: Vc = Enum::Transparent(Transparent(42).cell()).cell(); + let a: Vc = Enum::Transparent(Transparent(42).resolved_cell()).cell(); assert_eq!( format!("{:?}", a.dbg().await?), r#"Enum :: Transparent( @@ -63,7 +63,7 @@ async fn enum_transparent_debug() { #[tokio::test] async fn enum_inner_vc_debug() { run(®ISTRATION, || async { - let a: Vc = Enum::Enum(Enum::None.cell()).cell(); + let a: Vc = Enum::Enum(Enum::None.resolved_cell()).cell(); assert_eq!( format!("{:?}", a.dbg().await?), r#"Enum :: Enum( @@ -163,8 +163,8 @@ struct Transparent(u32); #[turbo_tasks::value(shared)] enum Enum { None, - Transparent(Vc), - Enum(Vc), + Transparent(ResolvedVc), + Enum(ResolvedVc), } #[turbo_tasks::value(shared)] diff --git a/turbopack/crates/turbo-tasks/src/vc/resolved.rs b/turbopack/crates/turbo-tasks/src/vc/resolved.rs index 3b85ff4a6e584e..786f06b3d72302 100644 --- a/turbopack/crates/turbo-tasks/src/vc/resolved.rs +++ b/turbopack/crates/turbo-tasks/src/vc/resolved.rs @@ -22,6 +22,7 @@ use indexmap::{IndexMap, IndexSet}; use serde::{Deserialize, Serialize}; use crate::{ + debug::{ValueDebug, ValueDebugFormat, ValueDebugFormatString}, trace::{TraceRawVcs, TraceRawVcsContext}, vc::Vc, RcStr, ResolveTypeError, Upcast, VcRead, VcTransparentRead, VcValueTrait, VcValueType, @@ -215,6 +216,16 @@ where } } +impl ValueDebugFormat for ResolvedVc +where + T: ?Sized + Send, + T: Upcast>, +{ + fn value_debug_format(&self, depth: usize) -> ValueDebugFormatString { + self.node.value_debug_format(depth) + } +} + /// Indicates that a type does not contain any instances of [`Vc`]. It may /// contain [`ResolvedVc`]. /// From 82750786adcc1f7478e88bd9580ec561a70dd4f7 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Tue, 22 Oct 2024 22:05:29 +0200 Subject: [PATCH 06/44] test: fix async api tests (#71652) --- .../interception-middleware-rewrite/app/[lang]/layout.tsx | 6 +++++- .../navigation/app/not-found/clientcomponent/page.js | 4 ++-- .../app-dir/navigation/app/redirect/clientcomponent/page.js | 4 ++-- .../app/[artist]/[album]/page.tsx | 2 +- .../app/(mpa-navigation)/dynamic-catchall/[...slug]/page.js | 3 ++- .../app/(mpa-navigation)/dynamic/[first]/[second]/page.js | 3 ++- .../app/(mpa-navigation)/dynamic/[first]/page.js | 3 ++- .../(mpa-navigation)/static-mpa-navigation/[slug]/page.js | 3 ++- .../app/(required-tags)/static-missing-tags/[slug]/page.js | 2 +- test/e2e/app-dir/searchparams-reuse-loading/app/page.tsx | 3 ++- .../searchparams-reuse-loading/app/params-first/page.tsx | 3 ++- .../searchparams-reuse-loading/app/root-page-first/page.tsx | 3 ++- test/integration/app-dir-export/app/another/[slug]/page.js | 3 ++- 13 files changed, 27 insertions(+), 15 deletions(-) diff --git a/test/e2e/app-dir/interception-middleware-rewrite/app/[lang]/layout.tsx b/test/e2e/app-dir/interception-middleware-rewrite/app/[lang]/layout.tsx index 521cc03120ad5c..9c372385c7bd84 100644 --- a/test/e2e/app-dir/interception-middleware-rewrite/app/[lang]/layout.tsx +++ b/test/e2e/app-dir/interception-middleware-rewrite/app/[lang]/layout.tsx @@ -1,6 +1,10 @@ import Link from 'next/link' -export default function Layout({ children, modal, params }) { +export default async function Layout(props) { + const params = await props.params + + const { children, modal } = props + return ( <>
diff --git a/test/e2e/app-dir/navigation/app/not-found/clientcomponent/page.js b/test/e2e/app-dir/navigation/app/not-found/clientcomponent/page.js index 066490779210eb..4d28919b28e723 100644 --- a/test/e2e/app-dir/navigation/app/not-found/clientcomponent/page.js +++ b/test/e2e/app-dir/navigation/app/not-found/clientcomponent/page.js @@ -2,8 +2,8 @@ import ClientComp from './client-component' import { headers } from 'next/headers' -export default function Page() { +export default async function Page() { // Opt-in to SSR. - headers() + await headers() return } diff --git a/test/e2e/app-dir/navigation/app/redirect/clientcomponent/page.js b/test/e2e/app-dir/navigation/app/redirect/clientcomponent/page.js index 5b6bb43c2cc526..36a32fbfb40893 100644 --- a/test/e2e/app-dir/navigation/app/redirect/clientcomponent/page.js +++ b/test/e2e/app-dir/navigation/app/redirect/clientcomponent/page.js @@ -1,8 +1,8 @@ import ClientComp from './client-component' import { headers } from 'next/headers' -export default function Page() { +export default async function Page() { // Opt-in to SSR. - headers() + await headers() return } diff --git a/test/e2e/app-dir/parallel-routes-breadcrumbs/app/[artist]/[album]/page.tsx b/test/e2e/app-dir/parallel-routes-breadcrumbs/app/[artist]/[album]/page.tsx index bbff22e628317a..2d75682397c442 100644 --- a/test/e2e/app-dir/parallel-routes-breadcrumbs/app/[artist]/[album]/page.tsx +++ b/test/e2e/app-dir/parallel-routes-breadcrumbs/app/[artist]/[album]/page.tsx @@ -5,7 +5,7 @@ export default async function Page({ params }) { const { artist, album } = await params return (
-

Album: {params.album}

+

Album: {album}

    {tracks.map((track) => (
  • diff --git a/test/e2e/app-dir/root-layout/app/(mpa-navigation)/dynamic-catchall/[...slug]/page.js b/test/e2e/app-dir/root-layout/app/(mpa-navigation)/dynamic-catchall/[...slug]/page.js index 5dece6d1e3e8d3..ed46ba635ec120 100644 --- a/test/e2e/app-dir/root-layout/app/(mpa-navigation)/dynamic-catchall/[...slug]/page.js +++ b/test/e2e/app-dir/root-layout/app/(mpa-navigation)/dynamic-catchall/[...slug]/page.js @@ -1,6 +1,7 @@ import Link from 'next/link' -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params const nextUrl = [...params.slug, 'slug'] return ( <> diff --git a/test/e2e/app-dir/root-layout/app/(mpa-navigation)/dynamic/[first]/[second]/page.js b/test/e2e/app-dir/root-layout/app/(mpa-navigation)/dynamic/[first]/[second]/page.js index 2d1c41c94d19d6..620b774905cf1b 100644 --- a/test/e2e/app-dir/root-layout/app/(mpa-navigation)/dynamic/[first]/[second]/page.js +++ b/test/e2e/app-dir/root-layout/app/(mpa-navigation)/dynamic/[first]/[second]/page.js @@ -1,6 +1,7 @@ import Link from 'next/link' -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params return ( <> To basic inner diff --git a/test/e2e/app-dir/root-layout/app/(mpa-navigation)/dynamic/[first]/page.js b/test/e2e/app-dir/root-layout/app/(mpa-navigation)/dynamic/[first]/page.js index e2fb10ecf4863e..1e55ab8182e1d1 100644 --- a/test/e2e/app-dir/root-layout/app/(mpa-navigation)/dynamic/[first]/page.js +++ b/test/e2e/app-dir/root-layout/app/(mpa-navigation)/dynamic/[first]/page.js @@ -1,6 +1,7 @@ import Link from 'next/link' -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params return ( <> To inner dynamic diff --git a/test/e2e/app-dir/root-layout/app/(mpa-navigation)/static-mpa-navigation/[slug]/page.js b/test/e2e/app-dir/root-layout/app/(mpa-navigation)/static-mpa-navigation/[slug]/page.js index c039cd2120bf68..b451df17560eff 100644 --- a/test/e2e/app-dir/root-layout/app/(mpa-navigation)/static-mpa-navigation/[slug]/page.js +++ b/test/e2e/app-dir/root-layout/app/(mpa-navigation)/static-mpa-navigation/[slug]/page.js @@ -2,7 +2,8 @@ import Link from 'next/link' export const dynamicParams = false -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params return ( <> Static page

    } diff --git a/test/e2e/app-dir/searchparams-reuse-loading/app/page.tsx b/test/e2e/app-dir/searchparams-reuse-loading/app/page.tsx index 35638acf986517..5cc9a6f30ef542 100644 --- a/test/e2e/app-dir/searchparams-reuse-loading/app/page.tsx +++ b/test/e2e/app-dir/searchparams-reuse-loading/app/page.tsx @@ -1,6 +1,7 @@ import Link from 'next/link' -export default function Page({ searchParams }) { +export default async function Page(props) { + const searchParams = await props.searchParams return ( <>
    {JSON.stringify(searchParams)}
    diff --git a/test/e2e/app-dir/searchparams-reuse-loading/app/params-first/page.tsx b/test/e2e/app-dir/searchparams-reuse-loading/app/params-first/page.tsx index bf0d4bc715f81e..2ac9662385de35 100644 --- a/test/e2e/app-dir/searchparams-reuse-loading/app/params-first/page.tsx +++ b/test/e2e/app-dir/searchparams-reuse-loading/app/params-first/page.tsx @@ -1,6 +1,7 @@ import Link from 'next/link' -export default async function Home({ searchParams }) { +export default async function Home(props) { + const searchParams = await props.searchParams return (

    diff --git a/test/e2e/app-dir/searchparams-reuse-loading/app/root-page-first/page.tsx b/test/e2e/app-dir/searchparams-reuse-loading/app/root-page-first/page.tsx index 9277cd0537614f..59b79f6e695c21 100644 --- a/test/e2e/app-dir/searchparams-reuse-loading/app/root-page-first/page.tsx +++ b/test/e2e/app-dir/searchparams-reuse-loading/app/root-page-first/page.tsx @@ -1,6 +1,7 @@ import Link from 'next/link' -export default async function Home({ searchParams }) { +export default async function Home(props) { + const searchParams = await props.searchParams return (

    diff --git a/test/integration/app-dir-export/app/another/[slug]/page.js b/test/integration/app-dir-export/app/another/[slug]/page.js index 9c4a7e34f303ec..d8886cd11c8dc7 100644 --- a/test/integration/app-dir-export/app/another/[slug]/page.js +++ b/test/integration/app-dir-export/app/another/[slug]/page.js @@ -6,7 +6,8 @@ export function generateStaticParams() { return [{ slug: 'first' }, { slug: 'second' }] } -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params return (

    {params.slug}

    From ce41f6bc6f24f267dc87f5892bc40a690b8fc2af Mon Sep 17 00:00:00 2001 From: "Sebastian \"Sebbie\" Silbermann" Date: Tue, 22 Oct 2024 22:13:15 +0200 Subject: [PATCH 07/44] Enable source maps for `pnpm debug` (#71653) Now `pnpm debug` is like `pnpm next` with `NODE_OPTIONS=--inspect` --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b211149ac4e4e6..dc41e33e18feef 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "next": "cross-env NEXT_TELEMETRY_DISABLED=1 node --trace-deprecation --enable-source-maps packages/next/dist/bin/next", "next-no-sourcemaps": "cross-env NEXT_TELEMETRY_DISABLED=1 node --trace-deprecation packages/next/dist/bin/next", "clean-trace-jaeger": "node scripts/rm.mjs test/integration/basic/.next && TRACE_TARGET=JAEGER pnpm next build test/integration/basic", - "debug": "cross-env NEXT_TELEMETRY_DISABLED=1 node --inspect packages/next/dist/bin/next", + "debug": "cross-env NEXT_TELEMETRY_DISABLED=1 node --inspect --trace-deprecation --enable-source-maps packages/next/dist/bin/next", "postinstall": "node scripts/git-configure.mjs && node scripts/install-native.mjs", "version": "pnpm install --no-frozen-lockfile && IS_PUBLISH=yes ./scripts/check-pre-compiled.sh && git add .", "prepare": "husky", From cfd816ddb8af2e075d605b3b66d6794795a77e80 Mon Sep 17 00:00:00 2001 From: Cody Olsen <81981+stipsan@users.noreply.github.com> Date: Tue, 22 Oct 2024 22:14:43 +0200 Subject: [PATCH 08/44] Update Sanity example to next v15 (#71640) --- examples/cms-sanity/app/(blog)/actions.ts | 2 +- examples/cms-sanity/app/(blog)/layout.tsx | 82 +++++++++---------- .../app/(blog)/posts/[slug]/page.tsx | 8 +- .../app/api/draft-mode/enable/route.ts | 8 ++ examples/cms-sanity/app/api/draft/route.tsx | 27 ------ examples/cms-sanity/next.config.js | 10 --- examples/cms-sanity/next.config.ts | 10 +++ examples/cms-sanity/package.json | 40 ++++----- examples/cms-sanity/sanity.config.ts | 2 +- examples/cms-sanity/sanity/lib/fetch.ts | 19 +++-- examples/cms-sanity/sanity/lib/token.ts | 8 -- 11 files changed, 96 insertions(+), 120 deletions(-) create mode 100644 examples/cms-sanity/app/api/draft-mode/enable/route.ts delete mode 100644 examples/cms-sanity/app/api/draft/route.tsx delete mode 100644 examples/cms-sanity/next.config.js create mode 100644 examples/cms-sanity/next.config.ts diff --git a/examples/cms-sanity/app/(blog)/actions.ts b/examples/cms-sanity/app/(blog)/actions.ts index 7b5cc9ee80a92c..b8f951f237292d 100644 --- a/examples/cms-sanity/app/(blog)/actions.ts +++ b/examples/cms-sanity/app/(blog)/actions.ts @@ -5,7 +5,7 @@ import { draftMode } from "next/headers"; export async function disableDraftMode() { "use server"; await Promise.allSettled([ - draftMode().disable(), + (await draftMode()).disable(), // Simulate a delay to show the loading state new Promise((resolve) => setTimeout(resolve, 1000)), ]); diff --git a/examples/cms-sanity/app/(blog)/layout.tsx b/examples/cms-sanity/app/(blog)/layout.tsx index 6a23f51370b072..b6954df828195a 100644 --- a/examples/cms-sanity/app/(blog)/layout.tsx +++ b/examples/cms-sanity/app/(blog)/layout.tsx @@ -9,7 +9,6 @@ import { } from "next-sanity"; import { Inter } from "next/font/google"; import { draftMode } from "next/headers"; -import { Suspense } from "react"; import AlertBanner from "./alert-banner"; import PortableText from "./portable-text"; @@ -56,60 +55,53 @@ const inter = Inter({ display: "swap", }); -async function Footer() { - const data = await sanityFetch({ query: settingsQuery }); - const footer = data?.footer || []; - - return ( - - ); -} - -export default function RootLayout({ +export default async function RootLayout({ children, }: { children: React.ReactNode; }) { + const data = await sanityFetch({ query: settingsQuery }); + const footer = data?.footer || []; + const { isEnabled: isDraftMode } = await draftMode(); + return (
    - {draftMode().isEnabled && } + {isDraftMode && }
    {children}
    - -
    - {draftMode().isEnabled && } + {isDraftMode && } diff --git a/examples/cms-sanity/app/(blog)/posts/[slug]/page.tsx b/examples/cms-sanity/app/(blog)/posts/[slug]/page.tsx index c8a99e39e3dc64..125c419f18c56a 100644 --- a/examples/cms-sanity/app/(blog)/posts/[slug]/page.tsx +++ b/examples/cms-sanity/app/(blog)/posts/[slug]/page.tsx @@ -17,7 +17,7 @@ import { postQuery, settingsQuery } from "@/sanity/lib/queries"; import { resolveOpenGraphImage } from "@/sanity/lib/utils"; type Props = { - params: { slug: string }; + params: Promise<{ slug: string }>; }; const postSlugs = defineQuery( @@ -36,7 +36,11 @@ export async function generateMetadata( { params }: Props, parent: ResolvingMetadata, ): Promise { - const post = await sanityFetch({ query: postQuery, params, stega: false }); + const post = await sanityFetch({ + query: postQuery, + params, + stega: false, + }); const previousImages = (await parent).openGraph?.images || []; const ogImage = resolveOpenGraphImage(post?.coverImage); diff --git a/examples/cms-sanity/app/api/draft-mode/enable/route.ts b/examples/cms-sanity/app/api/draft-mode/enable/route.ts new file mode 100644 index 00000000000000..91986b76f3fb0e --- /dev/null +++ b/examples/cms-sanity/app/api/draft-mode/enable/route.ts @@ -0,0 +1,8 @@ +import { defineEnableDraftMode } from "next-sanity/draft-mode"; + +import { client } from "@/sanity/lib/client"; +import { token } from "@/sanity/lib/token"; + +export const { GET } = defineEnableDraftMode({ + client: client.withConfig({ token }), +}); diff --git a/examples/cms-sanity/app/api/draft/route.tsx b/examples/cms-sanity/app/api/draft/route.tsx deleted file mode 100644 index 38bf40eab07bc9..00000000000000 --- a/examples/cms-sanity/app/api/draft/route.tsx +++ /dev/null @@ -1,27 +0,0 @@ -/** - * This file is used to allow Presentation to set the app in Draft Mode, which will load Visual Editing - * and query draft content and preview the content as it will appear once everything is published - */ - -import { validatePreviewUrl } from "@sanity/preview-url-secret"; -import { draftMode } from "next/headers"; -import { redirect } from "next/navigation"; - -import { client } from "@/sanity/lib/client"; -import { token } from "@/sanity/lib/token"; - -const clientWithToken = client.withConfig({ token }); - -export async function GET(request: Request) { - const { isValid, redirectTo = "/" } = await validatePreviewUrl( - clientWithToken, - request.url, - ); - if (!isValid) { - return new Response("Invalid secret", { status: 401 }); - } - - draftMode().enable(); - - redirect(redirectTo); -} diff --git a/examples/cms-sanity/next.config.js b/examples/cms-sanity/next.config.js deleted file mode 100644 index 0a9e8f602209cf..00000000000000 --- a/examples/cms-sanity/next.config.js +++ /dev/null @@ -1,10 +0,0 @@ -/** @type {import('next').NextConfig} */ -module.exports = { - experimental: { - // Used to guard against accidentally leaking SANITY_API_READ_TOKEN to the browser - taint: true, - }, - logging: { - fetches: { fullUrl: false }, - }, -}; diff --git a/examples/cms-sanity/next.config.ts b/examples/cms-sanity/next.config.ts new file mode 100644 index 00000000000000..431420e579f958 --- /dev/null +++ b/examples/cms-sanity/next.config.ts @@ -0,0 +1,10 @@ +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = { + env: { + // Matches the behavior of `sanity dev` which sets styled-components to use the fastest way of inserting CSS rules in both dev and production. It's default behavior is to disable it in dev mode. + SC_DISABLE_SPEEDY: "false", + }, +}; + +export default nextConfig; diff --git a/examples/cms-sanity/package.json b/examples/cms-sanity/package.json index 6c0be210bc48ad..a0a9becc69ff44 100644 --- a/examples/cms-sanity/package.json +++ b/examples/cms-sanity/package.json @@ -2,7 +2,7 @@ "private": true, "scripts": { "predev": "npm run typegen", - "dev": "next", + "dev": "next --turbo", "prebuild": "npm run typegen", "build": "next build", "start": "next start", @@ -13,32 +13,32 @@ "typegen": "sanity schema extract && sanity typegen generate" }, "dependencies": { - "@sanity/assist": "^3.0.6", - "@sanity/icons": "^3.3.1", + "@sanity/assist": "^3.0.8", + "@sanity/icons": "^3.4.0", "@sanity/image-url": "^1.0.2", - "@sanity/preview-url-secret": "^1.6.20", - "@sanity/vision": "^3.55.0", - "@tailwindcss/typography": "^0.5.14", - "@types/node": "^20.14.13", - "@types/react": "^18.3.4", - "@types/react-dom": "^18.3.0", - "@vercel/speed-insights": "^1.0.12", + "@sanity/preview-url-secret": "^2.0.0", + "@sanity/vision": "^3.62.0", + "@tailwindcss/typography": "^0.5.15", + "@types/node": "^22.7.8", + "@types/react": "^18.3.11", + "@types/react-dom": "^18.3.1", + "@vercel/speed-insights": "^1.0.13", "autoprefixer": "^10.4.20", - "date-fns": "^3.6.0", - "next": "^14.2.5", - "next-sanity": "^9.4.7", - "postcss": "^8.4.41", + "date-fns": "^4.1.0", + "next": "^15.0.0", + "next-sanity": "^9.7.0", + "postcss": "^8.4.47", "react": "^18.3.1", "react-dom": "^18.3.1", - "sanity": "^3.55.0", + "sanity": "^3.62.0", "sanity-plugin-asset-source-unsplash": "^3.0.1", "server-only": "^0.0.1", - "styled-components": "^6.1.12", - "tailwindcss": "^3.4.10", - "typescript": "5.5.4" + "styled-components": "^6.1.13", + "tailwindcss": "^3.4.14", + "typescript": "5.6.3" }, "devDependencies": { - "eslint": "^8.57.0", - "eslint-config-next": "^14.2.5" + "eslint": "^9.13.0", + "eslint-config-next": "^15.0.0" } } diff --git a/examples/cms-sanity/sanity.config.ts b/examples/cms-sanity/sanity.config.ts index 4184819fe369ab..1372daaacf8029 100644 --- a/examples/cms-sanity/sanity.config.ts +++ b/examples/cms-sanity/sanity.config.ts @@ -71,7 +71,7 @@ export default defineConfig({ }), }, }, - previewUrl: { previewMode: { enable: "/api/draft" } }, + previewUrl: { previewMode: { enable: "/api/draft-mode/enable" } }, }), structureTool({ structure: pageStructure([settings]) }), // Configures the global "new document" button, and document actions, to suit the Settings document singleton diff --git a/examples/cms-sanity/sanity/lib/fetch.ts b/examples/cms-sanity/sanity/lib/fetch.ts index f4d79180f5ee2e..3c11d0d4c5ae71 100644 --- a/examples/cms-sanity/sanity/lib/fetch.ts +++ b/examples/cms-sanity/sanity/lib/fetch.ts @@ -13,22 +13,29 @@ import { token } from "@/sanity/lib/token"; export async function sanityFetch({ query, params = {}, - perspective = draftMode().isEnabled ? "previewDrafts" : "published", + perspective: _perspective, /** * Stega embedded Content Source Maps are used by Visual Editing by both the Sanity Presentation Tool and Vercel Visual Editing. * The Sanity Presentation Tool will enable Draft Mode when loading up the live preview, and we use it as a signal for when to embed source maps. * When outside of the Sanity Studio we also support the Vercel Toolbar Visual Editing feature, which is only enabled in production when it's a Vercel Preview Deployment. */ - stega = perspective === "previewDrafts" || - process.env.VERCEL_ENV === "preview", + stega: _stega, }: { query: QueryString; - params?: QueryParams; + params?: QueryParams | Promise; perspective?: Omit; stega?: boolean; }) { + const perspective = + _perspective || (await draftMode()).isEnabled + ? "previewDrafts" + : "published"; + const stega = + _stega || + perspective === "previewDrafts" || + process.env.VERCEL_ENV === "preview"; if (perspective === "previewDrafts") { - return client.fetch(query, params, { + return client.fetch(query, await params, { stega, perspective: "previewDrafts", // The token is required to fetch draft content @@ -39,7 +46,7 @@ export async function sanityFetch({ next: { revalidate: 0 }, }); } - return client.fetch(query, params, { + return client.fetch(query, await params, { stega, perspective: "published", // The `published` perspective is available on the API CDN diff --git a/examples/cms-sanity/sanity/lib/token.ts b/examples/cms-sanity/sanity/lib/token.ts index dd8757abdb724c..0908fa68462de2 100644 --- a/examples/cms-sanity/sanity/lib/token.ts +++ b/examples/cms-sanity/sanity/lib/token.ts @@ -1,15 +1,7 @@ import "server-only"; -import { experimental_taintUniqueValue } from "react"; - export const token = process.env.SANITY_API_READ_TOKEN; if (!token) { throw new Error("Missing SANITY_API_READ_TOKEN"); } - -experimental_taintUniqueValue( - "Do not pass the sanity API read token to the client.", - process, - token, -); From 9bd38dd10c2c0d72ca943ea77fadceed717ed211 Mon Sep 17 00:00:00 2001 From: Benjamin Woodruff Date: Tue, 22 Oct 2024 14:51:04 -0700 Subject: [PATCH 09/44] codemod(turbopack): Rewrite more Vc fields in structs as ResolvedVc (#71172) **This is a** *(mostly)* **machine-generated PR.** This uses a much updated version of the ast-grep based codemod script from #70927, which can now match a bunch more patterns. Codemod scripts: https://github.com/vercel/turbopack-resolved-vc-codemod/tree/90518e64cfaf9328546ff4688692f16f54d4fc3e I did a small bit of cleanup after running the script with: ```bash sg -U --pattern '$OBJ.resolve().await?.to_resolved().await?' -r '$OBJ.to_resolved().await?' ``` Notable additions since last time are: - Runs the compiler/fixer in a loop a few times, as fixing an issue often allows compilation to get further, creating new errors. - Can apply compiler-suggested edits (usually these are manual derefs needed with `*`) - Knows how to rewrite `$OBJ.cell()` to `$OBJ.resolved_cell()` - Knows how to rewrite `Vc::cell($ARG)` to `ResolvedVc::cell($ARG)` - Knows how to rewrite `$TYPE::cell($ARG)` to `$TYPE::resolved_cell($ARG)`. - Knows how to add `.to_resolved().await?` to expressions. --- crates/next-api/src/dynamic_imports.rs | 14 ++--- .../src/next_app/include_modules_module.rs | 8 +-- crates/next-core/src/next_client/context.rs | 20 ++++--- .../src/next_client/runtime_entry.rs | 8 +-- crates/next-core/src/next_config.rs | 8 +-- crates/next-core/src/next_edge/context.rs | 4 +- crates/next-core/src/next_server/context.rs | 18 +++---- crates/next-core/src/next_server/resolve.rs | 10 ++-- .../server_component_module.rs | 2 +- crates/next-core/src/pages_structure.rs | 8 +-- .../turbo-tasks-testing/tests/all_in_one.rs | 6 +-- .../crates/turbo-tasks-testing/tests/debug.rs | 8 +-- .../turbopack-browser/src/react_refresh.rs | 8 +-- .../turbopack-cli-utils/src/runtime_entry.rs | 12 ++--- .../crates/turbopack-cli/src/contexts.rs | 6 +-- .../turbopack-cli/src/dev/web_entry_source.rs | 16 ++++-- .../src/chunk/available_chunk_items.rs | 8 +-- .../crates/turbopack-core/src/chunk/mod.rs | 28 ++++++---- .../turbopack-core/src/compile_time_info.rs | 4 +- .../crates/turbopack-core/src/environment.rs | 14 ++--- turbopack/crates/turbopack-core/src/ident.rs | 4 +- .../crates/turbopack-core/src/issue/mod.rs | 16 +++--- .../turbopack-core/src/issue/resolve.rs | 4 +- .../crates/turbopack-core/src/resolve/mod.rs | 48 ++++++++++------- .../crates/turbopack-core/src/resolve/node.rs | 6 +-- .../turbopack-core/src/resolve/options.rs | 12 ++--- turbopack/crates/turbopack-css/src/asset.rs | 7 ++- .../crates/turbopack-css/src/chunk/mod.rs | 8 +-- .../turbopack-css/src/references/url.rs | 9 ++-- .../src/source/asset_graph.rs | 11 ++-- .../turbopack-dev-server/src/source/mod.rs | 24 +++++---- .../src/source/resolve.rs | 12 +++-- .../src/source/wrapping_source.rs | 2 +- .../src/chunk/placeable.rs | 8 +-- .../src/global_module_id_strategy.rs | 11 ++-- .../crates/turbopack-ecmascript/src/lib.rs | 12 ++--- .../src/references/esm/base.rs | 16 +++--- .../src/references/esm/export.rs | 16 +++--- .../src/references/mod.rs | 54 +++++++++++-------- .../side_effect_optimization/facade/module.rs | 2 +- .../side_effect_optimization/locals/module.rs | 2 +- .../src/side_effect_optimization/reference.rs | 8 +-- .../turbopack-ecmascript/src/transform/mod.rs | 4 +- .../crates/turbopack-image/src/process/mod.rs | 13 ++--- .../src/render/node_api_source.rs | 52 +++++++++--------- .../src/render/render_static.rs | 8 +-- .../src/render/rendered_source.rs | 6 ++- .../turbopack-node/src/transforms/webpack.rs | 9 ++-- .../turbopack-resolve/src/ecmascript.rs | 18 +++---- .../crates/turbopack-resolve/src/resolve.rs | 10 +++- .../crates/turbopack-tests/tests/execution.rs | 2 +- .../crates/turbopack-tests/tests/snapshot.rs | 2 +- turbopack/crates/turbopack/src/graph/mod.rs | 10 ++-- turbopack/crates/turbopack/src/lib.rs | 2 +- .../turbopack/src/module_options/mod.rs | 12 +++-- .../module_options/module_options_context.rs | 8 +-- 56 files changed, 364 insertions(+), 294 deletions(-) diff --git a/crates/next-api/src/dynamic_imports.rs b/crates/next-api/src/dynamic_imports.rs index bd4b919ec3758b..77ac436dc46558 100644 --- a/crates/next-api/src/dynamic_imports.rs +++ b/crates/next-api/src/dynamic_imports.rs @@ -11,7 +11,7 @@ use tracing::{Instrument, Level}; use turbo_tasks::{ graph::{GraphTraversal, NonDeterministic, VisitControlFlow, VisitedNodes}, trace::TraceRawVcs, - FxIndexMap, RcStr, ReadRef, TryJoinIterExt, Value, ValueToString, Vc, + FxIndexMap, RcStr, ReadRef, ResolvedVc, TryJoinIterExt, Value, ValueToString, Vc, }; use turbopack_core::{ chunk::{ @@ -162,7 +162,7 @@ pub(crate) async fn collect_next_dynamic_imports( .iter() .map(|module| async move { Ok(NextDynamicVisitEntry::Module( - module.resolve().await?, + module.to_resolved().await?, module.ident().to_string().await?, )) }) @@ -209,8 +209,8 @@ pub(crate) async fn collect_next_dynamic_imports( #[derive(Debug, PartialEq, Eq, Hash, Clone, TraceRawVcs, Serialize, Deserialize)] enum NextDynamicVisitEntry { - Module(Vc>, ReadRef), - DynamicImportsMap(Vc), + Module(ResolvedVc>, ReadRef), + DynamicImportsMap(ResolvedVc), } #[turbo_tasks::value(transparent)] @@ -227,7 +227,7 @@ async fn get_next_dynamic_edges( .iter() .map(|&referenced_module| async move { Ok(NextDynamicVisitEntry::Module( - referenced_module, + referenced_module.to_resolved().await?, referenced_module.ident().to_string().await?, )) }) @@ -236,7 +236,7 @@ async fn get_next_dynamic_edges( if let Some(dynamic_imports_map) = *dynamic_imports_map.await? { edges.reserve_exact(1); edges.push(NextDynamicVisitEntry::DynamicImportsMap( - dynamic_imports_map, + dynamic_imports_map.to_resolved().await?, )); } Ok(Vc::cell(edges)) @@ -264,7 +264,7 @@ impl turbo_tasks::graph::Visit for NextDynamicVisit { }; let client_asset_context = self.client_asset_context; async move { - Ok(get_next_dynamic_edges(client_asset_context, module) + Ok(get_next_dynamic_edges(client_asset_context, *module) .await? .into_iter() .cloned()) diff --git a/crates/next-core/src/next_app/include_modules_module.rs b/crates/next-core/src/next_app/include_modules_module.rs index bd1485e54dbf0b..d7dec3d17152c7 100644 --- a/crates/next-core/src/next_app/include_modules_module.rs +++ b/crates/next-core/src/next_app/include_modules_module.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use turbo_tasks::{RcStr, TryJoinIterExt, ValueToString, Vc}; +use turbo_tasks::{RcStr, ResolvedVc, TryJoinIterExt, ValueToString, Vc}; use turbo_tasks_fs::glob::Glob; use turbopack_core::{ asset::{Asset, AssetContent}, @@ -19,13 +19,13 @@ use turbopack_ecmascript::chunk::{ #[turbo_tasks::value] pub struct IncludeModulesModule { ident: Vc, - modules: Vec>>, + modules: Vec>>, } #[turbo_tasks::value_impl] impl IncludeModulesModule { #[turbo_tasks::function] - pub fn new(ident: Vc, modules: Vec>>) -> Vc { + pub fn new(ident: Vc, modules: Vec>>) -> Vc { Self { ident, modules }.cell() } } @@ -50,7 +50,7 @@ impl Module for IncludeModulesModule { .iter() .map(|&module| async move { Ok(Vc::upcast( - IncludedModuleReference::new(module).resolve().await?, + IncludedModuleReference::new(*module).resolve().await?, )) }) .try_join() diff --git a/crates/next-core/src/next_client/context.rs b/crates/next-core/src/next_client/context.rs index 236d4d8fb6bd79..282fe17c86ef8c 100644 --- a/crates/next-core/src/next_client/context.rs +++ b/crates/next-core/src/next_client/context.rs @@ -1,7 +1,7 @@ use std::iter::once; use anyhow::Result; -use turbo_tasks::{FxIndexMap, RcStr, Value, Vc}; +use turbo_tasks::{FxIndexMap, RcStr, ResolvedVc, Value, Vc}; use turbo_tasks_env::EnvMap; use turbo_tasks_fs::{FileSystem, FileSystemPath}; use turbopack::{ @@ -193,8 +193,8 @@ fn internal_assets_conditions() -> ContextCondition { #[turbo_tasks::function] pub async fn get_client_module_options_context( project_path: Vc, - execution_context: Vc, - env: Vc, + execution_context: ResolvedVc, + env: ResolvedVc, ty: Value, mode: Vc, next_config: Vc, @@ -202,7 +202,7 @@ pub async fn get_client_module_options_context( let next_mode = mode.await?; let resolve_options_context = - get_client_resolve_options_context(project_path, ty, mode, next_config, execution_context); + get_client_resolve_options_context(project_path, ty, mode, next_config, *execution_context); let tsconfig = get_typescript_transform_options(project_path); let decorators_options = get_decorators_transform_options(project_path); @@ -312,7 +312,7 @@ pub async fn get_client_module_options_context( ecmascript: EcmascriptOptionsContext { enable_jsx: Some(jsx_runtime_options), enable_typescript_transform: Some(tsconfig), - enable_decorators: Some(decorators_options), + enable_decorators: Some(decorators_options.to_resolved().await?), ..module_options_context.ecmascript.clone() }, enable_webpack_loaders, @@ -408,8 +408,10 @@ pub async fn get_client_runtime_entries( // because the bootstrap contains JSX which requires Refresh's global // functions to be available. if let Some(request) = enable_react_refresh { - runtime_entries - .push(RuntimeEntry::Request(request, project_root.join("_".into())).cell()) + runtime_entries.push( + RuntimeEntry::Request(request.to_resolved().await?, project_root.join("_".into())) + .cell(), + ) }; } @@ -418,7 +420,9 @@ pub async fn get_client_runtime_entries( RuntimeEntry::Request( Request::parse(Value::new(Pattern::Constant( "next/dist/client/app-next-turbopack.js".into(), - ))), + ))) + .to_resolved() + .await?, project_root.join("_".into()), ) .cell(), diff --git a/crates/next-core/src/next_client/runtime_entry.rs b/crates/next-core/src/next_client/runtime_entry.rs index 9661ea46bf151e..eb8f0353017db9 100644 --- a/crates/next-core/src/next_client/runtime_entry.rs +++ b/crates/next-core/src/next_client/runtime_entry.rs @@ -12,8 +12,8 @@ use turbopack_ecmascript::resolve::cjs_resolve; #[turbo_tasks::value(shared)] pub enum RuntimeEntry { - Request(Vc, Vc), - Evaluatable(Vc>), + Request(ResolvedVc, Vc), + Evaluatable(ResolvedVc>), Source(ResolvedVc>), } @@ -25,7 +25,7 @@ impl RuntimeEntry { asset_context: Vc>, ) -> Result> { let (request, path) = match *self.await? { - RuntimeEntry::Evaluatable(e) => return Ok(EvaluatableAssets::one(e)), + RuntimeEntry::Evaluatable(e) => return Ok(EvaluatableAssets::one(*e)), RuntimeEntry::Source(source) => { return Ok(EvaluatableAssets::one(source.to_evaluatable(asset_context))); } @@ -34,7 +34,7 @@ impl RuntimeEntry { let modules = cjs_resolve( Vc::upcast(PlainResolveOrigin::new(asset_context, path)), - request, + *request, None, false, ) diff --git a/crates/next-core/src/next_config.rs b/crates/next-core/src/next_config.rs index fc9c5723ca9e47..38b659bd860e9d 100644 --- a/crates/next-core/src/next_config.rs +++ b/crates/next-core/src/next_config.rs @@ -3,7 +3,7 @@ use std::collections::HashSet; use anyhow::{bail, Context, Result}; use serde::{Deserialize, Deserializer, Serialize}; use serde_json::Value as JsonValue; -use turbo_tasks::{trace::TraceRawVcs, FxIndexMap, RcStr, TaskInput, Vc}; +use turbo_tasks::{trace::TraceRawVcs, FxIndexMap, RcStr, ResolvedVc, TaskInput, Vc}; use turbo_tasks_env::EnvMap; use turbo_tasks_fs::FileSystemPath; use turbopack::module_options::{ @@ -481,7 +481,7 @@ pub enum ReactCompilerOptionsOrBoolean { } #[turbo_tasks::value(transparent)] -pub struct OptionalReactCompilerOptions(Option>); +pub struct OptionalReactCompilerOptions(Option>); #[turbo_tasks::value(eq = "manual")] #[derive(Clone, Debug, Default, PartialEq)] @@ -1080,11 +1080,11 @@ impl NextConfig { compilation_mode: None, panic_threshold: None, } - .cell(), + .resolved_cell(), )) } Some(ReactCompilerOptionsOrBoolean::Option(options)) => OptionalReactCompilerOptions( - Some(ReactCompilerOptions { ..options.clone() }.cell()), + Some(ReactCompilerOptions { ..options.clone() }.resolved_cell()), ), _ => OptionalReactCompilerOptions(None), }; diff --git a/crates/next-core/src/next_edge/context.rs b/crates/next-core/src/next_edge/context.rs index 962b67f4b32ab5..e68f79b72393fc 100644 --- a/crates/next-core/src/next_edge/context.rs +++ b/crates/next-core/src/next_edge/context.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use turbo_tasks::{FxIndexMap, RcStr, Value, Vc}; +use turbo_tasks::{FxIndexMap, RcStr, ResolvedVc, Value, Vc}; use turbo_tasks_env::EnvMap; use turbo_tasks_fs::FileSystemPath; use turbopack::resolve_options_context::ResolveOptionsContext; @@ -60,7 +60,7 @@ async fn next_edge_defines(define_env: Vc) -> Result, + project_path: ResolvedVc, define_env: Vc, ) -> Result> { Ok(free_var_references!( diff --git a/crates/next-core/src/next_server/context.rs b/crates/next-core/src/next_server/context.rs index db235f5c3c4817..c0fb49b2aa6fd5 100644 --- a/crates/next-core/src/next_server/context.rs +++ b/crates/next-core/src/next_server/context.rs @@ -1,7 +1,7 @@ use std::iter::once; use anyhow::{bail, Result}; -use turbo_tasks::{FxIndexMap, RcStr, Value, Vc}; +use turbo_tasks::{FxIndexMap, RcStr, ResolvedVc, Value, Vc}; use turbo_tasks_env::{EnvMap, ProcessEnv}; use turbo_tasks_fs::{FileSystem, FileSystemPath}; use turbopack::{ @@ -179,7 +179,7 @@ pub async fn get_server_resolve_options_context( let server_external_packages_plugin = ExternalCjsModulesResolvePlugin::new( project_path, project_path.root(), - ExternalPredicate::Only(Vc::cell(external_packages)).cell(), + ExternalPredicate::Only(ResolvedVc::cell(external_packages)).cell(), *next_config.import_externals().await?, ); @@ -202,7 +202,7 @@ pub async fn get_server_resolve_options_context( ExternalCjsModulesResolvePlugin::new( project_path, project_path.root(), - ExternalPredicate::AllExcept(Vc::cell(transpiled_packages)).cell(), + ExternalPredicate::AllExcept(ResolvedVc::cell(transpiled_packages)).cell(), *next_config.import_externals().await?, ) }; @@ -375,7 +375,7 @@ fn internal_assets_conditions() -> ContextCondition { #[turbo_tasks::function] pub async fn get_server_module_options_context( project_path: Vc, - execution_context: Vc, + execution_context: ResolvedVc, ty: Value, mode: Vc, next_config: Vc, @@ -569,7 +569,7 @@ pub async fn get_server_module_options_context( ecmascript: EcmascriptOptionsContext { enable_jsx: Some(jsx_runtime_options), enable_typescript_transform: Some(tsconfig), - enable_decorators: Some(decorators_options), + enable_decorators: Some(decorators_options.to_resolved().await?), ..module_options_context.ecmascript }, enable_webpack_loaders, @@ -632,7 +632,7 @@ pub async fn get_server_module_options_context( ecmascript: EcmascriptOptionsContext { enable_jsx: Some(jsx_runtime_options), enable_typescript_transform: Some(tsconfig), - enable_decorators: Some(decorators_options), + enable_decorators: Some(decorators_options.to_resolved().await?), ..module_options_context.ecmascript }, enable_webpack_loaders, @@ -706,7 +706,7 @@ pub async fn get_server_module_options_context( ecmascript: EcmascriptOptionsContext { enable_jsx: Some(rsc_jsx_runtime_options), enable_typescript_transform: Some(tsconfig), - enable_decorators: Some(decorators_options), + enable_decorators: Some(decorators_options.to_resolved().await?), ..module_options_context.ecmascript }, enable_webpack_loaders, @@ -779,7 +779,7 @@ pub async fn get_server_module_options_context( ecmascript: EcmascriptOptionsContext { enable_jsx: Some(rsc_jsx_runtime_options), enable_typescript_transform: Some(tsconfig), - enable_decorators: Some(decorators_options), + enable_decorators: Some(decorators_options.to_resolved().await?), ..module_options_context.ecmascript }, enable_webpack_loaders, @@ -869,7 +869,7 @@ pub async fn get_server_module_options_context( ecmascript: EcmascriptOptionsContext { enable_jsx: Some(jsx_runtime_options), enable_typescript_transform: Some(tsconfig), - enable_decorators: Some(decorators_options), + enable_decorators: Some(decorators_options.to_resolved().await?), ..module_options_context.ecmascript }, enable_webpack_loaders, diff --git a/crates/next-core/src/next_server/resolve.rs b/crates/next-core/src/next_server/resolve.rs index eaadf6a96e2bd8..c5e3a5baabd462 100644 --- a/crates/next-core/src/next_server/resolve.rs +++ b/crates/next-core/src/next_server/resolve.rs @@ -1,6 +1,6 @@ use anyhow::Result; use serde::{Deserialize, Serialize}; -use turbo_tasks::{trace::TraceRawVcs, RcStr, Value, Vc}; +use turbo_tasks::{trace::TraceRawVcs, RcStr, ResolvedVc, Value, Vc}; use turbo_tasks_fs::{self, glob::Glob, FileJsonContent, FileSystemPath}; use turbopack_core::{ issue::{Issue, IssueExt, IssueSeverity, IssueStage, OptionStyledString, StyledString}, @@ -24,10 +24,10 @@ use turbopack_core::{ pub enum ExternalPredicate { /// Mark all modules as external if they're not listed in the list. /// Applies only to imports outside of node_modules. - AllExcept(Vc>), + AllExcept(ResolvedVc>), /// Only mark modules listed as external, whether inside node_modules or /// not. - Only(Vc>), + Only(ResolvedVc>), } /// Mark modules as external, so they're resolved at runtime instead of bundled. @@ -111,7 +111,7 @@ impl AfterResolvePlugin for ExternalCjsModulesResolvePlugin { return Ok(ResolveResultOption::none()); } - let exception_glob = packages_glob(*exceptions).await?; + let exception_glob = packages_glob(**exceptions).await?; if let Some(PackagesGlobs { path_glob, @@ -127,7 +127,7 @@ impl AfterResolvePlugin for ExternalCjsModulesResolvePlugin { false } ExternalPredicate::Only(externals) => { - let external_glob = packages_glob(*externals).await?; + let external_glob = packages_glob(**externals).await?; if let Some(PackagesGlobs { path_glob, diff --git a/crates/next-core/src/next_server_component/server_component_module.rs b/crates/next-core/src/next_server_component/server_component_module.rs index 5c684e69d52e36..d69c8dfe36e610 100644 --- a/crates/next-core/src/next_server_component/server_component_module.rs +++ b/crates/next-core/src/next_server_component/server_component_module.rs @@ -122,7 +122,7 @@ impl EcmascriptChunkPlaceable for NextServerComponentModule { exports, star_exports: vec![module_reference], } - .cell(), + .resolved_cell(), ) .cell() } diff --git a/crates/next-core/src/pages_structure.rs b/crates/next-core/src/pages_structure.rs index 87deebe96a959c..284623574bcc96 100644 --- a/crates/next-core/src/pages_structure.rs +++ b/crates/next-core/src/pages_structure.rs @@ -1,6 +1,6 @@ use anyhow::Result; use tracing::Instrument; -use turbo_tasks::{RcStr, ValueToString, Vc}; +use turbo_tasks::{RcStr, ResolvedVc, ValueToString, Vc}; use turbo_tasks_fs::{ DirectoryContent, DirectoryEntry, FileSystemEntryType, FileSystemPath, FileSystemPathOption, }; @@ -12,7 +12,7 @@ use crate::next_import_map::get_next_package; pub struct PagesStructureItem { pub base_path: Vc, pub extensions: Vc>, - pub fallback_path: Option>, + pub fallback_path: Option>, /// Pathname of this item in the Next.js router. pub next_router_path: Vc, @@ -29,7 +29,7 @@ impl PagesStructureItem { fn new( base_path: Vc, extensions: Vc>, - fallback_path: Option>, + fallback_path: Option>, next_router_path: Vc, original_path: Vc, ) -> Vc { @@ -53,7 +53,7 @@ impl PagesStructureItem { } } if let Some(fallback_path) = self.fallback_path { - Ok(fallback_path) + Ok(*fallback_path) } else { Ok(self.base_path) } diff --git a/turbopack/crates/turbo-tasks-testing/tests/all_in_one.rs b/turbopack/crates/turbo-tasks-testing/tests/all_in_one.rs index 2d2356e27820f9..a5c50d36b669bc 100644 --- a/turbopack/crates/turbo-tasks-testing/tests/all_in_one.rs +++ b/turbopack/crates/turbo-tasks-testing/tests/all_in_one.rs @@ -3,7 +3,7 @@ #![feature(arbitrary_self_types_pointers)] use anyhow::{anyhow, bail, Result}; -use turbo_tasks::{RcStr, Value, ValueToString, Vc}; +use turbo_tasks::{RcStr, ResolvedVc, Value, ValueToString, Vc}; use turbo_tasks_testing::{register, run, Registration}; static REGISTRATION: Registration = register!(); @@ -22,7 +22,7 @@ async fn all_in_one() { let c = MyStructValue { value: 42, - next: Some(MyStructValue::new(a)), + next: Some(MyStructValue::new(a).to_resolved().await?), } .into(); @@ -101,7 +101,7 @@ impl ValueToString for MyEnumValue { #[turbo_tasks::value(shared)] struct MyStructValue { value: u32, - next: Option>, + next: Option>, } #[turbo_tasks::value_impl] diff --git a/turbopack/crates/turbo-tasks-testing/tests/debug.rs b/turbopack/crates/turbo-tasks-testing/tests/debug.rs index 35d13c8d4e6f55..fc44f7c56e8c33 100644 --- a/turbopack/crates/turbo-tasks-testing/tests/debug.rs +++ b/turbopack/crates/turbo-tasks-testing/tests/debug.rs @@ -47,7 +47,7 @@ async fn enum_none_debug() { #[tokio::test] async fn enum_transparent_debug() { run(®ISTRATION, || async { - let a: Vc = Enum::Transparent(Transparent(42).resolved_cell()).cell(); + let a: Vc = Enum::Transparent(Transparent(42).cell()).cell(); assert_eq!( format!("{:?}", a.dbg().await?), r#"Enum :: Transparent( @@ -63,7 +63,7 @@ async fn enum_transparent_debug() { #[tokio::test] async fn enum_inner_vc_debug() { run(®ISTRATION, || async { - let a: Vc = Enum::Enum(Enum::None.resolved_cell()).cell(); + let a: Vc = Enum::Enum(Enum::None.cell()).cell(); assert_eq!( format!("{:?}", a.dbg().await?), r#"Enum :: Enum( @@ -163,8 +163,8 @@ struct Transparent(u32); #[turbo_tasks::value(shared)] enum Enum { None, - Transparent(ResolvedVc), - Enum(ResolvedVc), + Transparent(Vc), + Enum(Vc), } #[turbo_tasks::value(shared)] diff --git a/turbopack/crates/turbopack-browser/src/react_refresh.rs b/turbopack/crates/turbopack-browser/src/react_refresh.rs index 359a7703fc7fe8..66648990c32e72 100644 --- a/turbopack/crates/turbopack-browser/src/react_refresh.rs +++ b/turbopack/crates/turbopack-browser/src/react_refresh.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use turbo_tasks::{Value, Vc}; +use turbo_tasks::{ResolvedVc, Value, Vc}; use turbo_tasks_fs::FileSystemPath; use turbopack_core::{ issue::{Issue, IssueExt, IssueSeverity, IssueStage, OptionStyledString, StyledString}, @@ -23,14 +23,14 @@ fn react_refresh_request_in_next() -> Vc { #[turbo_tasks::value] pub enum ResolveReactRefreshResult { NotFound, - Found(Vc), + Found(ResolvedVc), } impl ResolveReactRefreshResult { pub fn as_request(&self) -> Option> { match self { ResolveReactRefreshResult::NotFound => None, - ResolveReactRefreshResult::Found(r) => Some(*r), + ResolveReactRefreshResult::Found(r) => Some(**r), } } pub fn is_found(&self) -> bool { @@ -62,7 +62,7 @@ pub async fn assert_can_resolve_react_refresh( .first_source(); if result.await?.is_some() { - return Ok(ResolveReactRefreshResult::Found(request).cell()); + return Ok(ResolveReactRefreshResult::Found(request.to_resolved().await?).cell()); } } ReactRefreshResolvingIssue { path }.cell().emit(); diff --git a/turbopack/crates/turbopack-cli-utils/src/runtime_entry.rs b/turbopack/crates/turbopack-cli-utils/src/runtime_entry.rs index 04d9c377fdfce6..ae243b5d4aeaa8 100644 --- a/turbopack/crates/turbopack-cli-utils/src/runtime_entry.rs +++ b/turbopack/crates/turbopack-cli-utils/src/runtime_entry.rs @@ -1,5 +1,5 @@ use anyhow::{bail, Result}; -use turbo_tasks::{ValueToString, Vc}; +use turbo_tasks::{ResolvedVc, ValueToString, Vc}; use turbo_tasks_fs::FileSystemPath; use turbopack_core::{ chunk::{EvaluatableAsset, EvaluatableAssetExt, EvaluatableAssets}, @@ -12,8 +12,8 @@ use turbopack_resolve::ecmascript::cjs_resolve; #[turbo_tasks::value(shared)] pub enum RuntimeEntry { - Request(Vc, Vc), - Evaluatable(Vc>), + Request(ResolvedVc, ResolvedVc), + Evaluatable(ResolvedVc>), Source(Vc>), } @@ -25,7 +25,7 @@ impl RuntimeEntry { asset_context: Vc>, ) -> Result> { let (request, path) = match *self.await? { - RuntimeEntry::Evaluatable(e) => return Ok(EvaluatableAssets::one(e)), + RuntimeEntry::Evaluatable(e) => return Ok(EvaluatableAssets::one(*e)), RuntimeEntry::Source(source) => { return Ok(EvaluatableAssets::one(source.to_evaluatable(asset_context))); } @@ -33,8 +33,8 @@ impl RuntimeEntry { }; let modules = cjs_resolve( - Vc::upcast(PlainResolveOrigin::new(asset_context, path)), - request, + Vc::upcast(PlainResolveOrigin::new(asset_context, *path)), + *request, None, false, ) diff --git a/turbopack/crates/turbopack-cli/src/contexts.rs b/turbopack/crates/turbopack-cli/src/contexts.rs index 6d6566e57c82ec..b8fc3ee26ea472 100644 --- a/turbopack/crates/turbopack-cli/src/contexts.rs +++ b/turbopack/crates/turbopack-cli/src/contexts.rs @@ -1,7 +1,7 @@ use std::fmt; use anyhow::Result; -use turbo_tasks::{RcStr, Value, Vc}; +use turbo_tasks::{RcStr, ResolvedVc, Value, Vc}; use turbo_tasks_fs::{FileSystem, FileSystemPath}; use turbopack::{ ecmascript::{EcmascriptInputTransform, TreeShakingMode}, @@ -98,8 +98,8 @@ pub async fn get_client_resolve_options_context( #[turbo_tasks::function] async fn get_client_module_options_context( project_path: Vc, - execution_context: Vc, - env: Vc, + execution_context: ResolvedVc, + env: ResolvedVc, node_env: Vc, ) -> Result> { let module_options_context = ModuleOptionsContext { diff --git a/turbopack/crates/turbopack-cli/src/dev/web_entry_source.rs b/turbopack/crates/turbopack-cli/src/dev/web_entry_source.rs index d4814a3758cf67..d0f0c401b80dbf 100644 --- a/turbopack/crates/turbopack-cli/src/dev/web_entry_source.rs +++ b/turbopack/crates/turbopack-cli/src/dev/web_entry_source.rs @@ -1,5 +1,5 @@ use anyhow::{anyhow, Result}; -use turbo_tasks::{RcStr, TryJoinIterExt, Value, Vc}; +use turbo_tasks::{RcStr, ResolvedVc, TryJoinIterExt, Value, Vc}; use turbo_tasks_env::ProcessEnv; use turbo_tasks_fs::FileSystemPath; use turbopack_browser::{react_refresh::assert_can_resolve_react_refresh, BrowserChunkingContext}; @@ -52,21 +52,27 @@ pub fn get_client_chunking_context( #[turbo_tasks::function] pub async fn get_client_runtime_entries( - project_path: Vc, + project_path: ResolvedVc, ) -> Result> { - let resolve_options_context = get_client_resolve_options_context(project_path); + let resolve_options_context = get_client_resolve_options_context(*project_path); let mut runtime_entries = Vec::new(); let enable_react_refresh = - assert_can_resolve_react_refresh(project_path, resolve_options_context) + assert_can_resolve_react_refresh(*project_path, resolve_options_context) .await? .as_request(); // It's important that React Refresh come before the regular bootstrap file, // because the bootstrap contains JSX which requires Refresh's global // functions to be available. if let Some(request) = enable_react_refresh { - runtime_entries.push(RuntimeEntry::Request(request, project_path.join("_".into())).cell()) + runtime_entries.push( + RuntimeEntry::Request( + request.to_resolved().await?, + project_path.join("_".into()).to_resolved().await?, + ) + .cell(), + ) }; runtime_entries.push( diff --git a/turbopack/crates/turbopack-core/src/chunk/available_chunk_items.rs b/turbopack/crates/turbopack-core/src/chunk/available_chunk_items.rs index ddf5f02880d73a..b05c9d31f1de00 100644 --- a/turbopack/crates/turbopack-core/src/chunk/available_chunk_items.rs +++ b/turbopack/crates/turbopack-core/src/chunk/available_chunk_items.rs @@ -1,8 +1,8 @@ use anyhow::Result; use serde::{Deserialize, Serialize}; use turbo_tasks::{ - debug::ValueDebugFormat, trace::TraceRawVcs, FxIndexMap, TryFlatJoinIterExt, TryJoinIterExt, - ValueToString, Vc, + debug::ValueDebugFormat, trace::TraceRawVcs, FxIndexMap, ResolvedVc, TryFlatJoinIterExt, + TryJoinIterExt, ValueToString, Vc, }; use turbo_tasks_hash::Xxh3Hash64Hasher; @@ -24,7 +24,7 @@ pub struct AvailableChunkItemInfoMap(FxIndexMap>, Availabl /// `include` queries. #[turbo_tasks::value] pub struct AvailableChunkItems { - parent: Option>, + parent: Option>, chunk_items: Vc, } @@ -57,7 +57,7 @@ impl AvailableChunkItems { .try_flat_join() .await?; Ok(AvailableChunkItems { - parent: Some(self), + parent: Some(self.to_resolved().await?), chunk_items: Vc::cell(chunk_items.into_iter().collect()), } .cell()) diff --git a/turbopack/crates/turbopack-core/src/chunk/mod.rs b/turbopack/crates/turbopack-core/src/chunk/mod.rs index 07ebb48010f7ed..93f444cde3adc3 100644 --- a/turbopack/crates/turbopack-core/src/chunk/mod.rs +++ b/turbopack/crates/turbopack-core/src/chunk/mod.rs @@ -240,7 +240,7 @@ enum ChunkContentGraphNode { module: Vc>, }, // ModuleReferences that are not placed in the current chunk group - ExternalModuleReference(Vc>), + ExternalModuleReference(ResolvedVc>), /// A list of directly referenced chunk items from which `is_async_module` /// will be inherited. InheritAsyncInfo { @@ -257,7 +257,7 @@ enum ChunkGraphNodeToReferences { #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, TraceRawVcs)] struct ChunkGraphEdge { - key: Option>>, + key: Option>>, node: ChunkContentGraphNode, } @@ -346,14 +346,18 @@ async fn graph_node_to_referenced_nodes( else { return Ok(vec![ChunkGraphEdge { key: None, - node: ChunkContentGraphNode::ExternalModuleReference(reference), + node: ChunkContentGraphNode::ExternalModuleReference( + reference.to_resolved().await?, + ), }]); }; let Some(chunking_type) = *chunkable_module_reference.chunking_type().await? else { return Ok(vec![ChunkGraphEdge { key: None, - node: ChunkContentGraphNode::ExternalModuleReference(reference), + node: ChunkContentGraphNode::ExternalModuleReference( + reference.to_resolved().await?, + ), }]); }; @@ -371,7 +375,9 @@ async fn graph_node_to_referenced_nodes( return Ok(( Some(ChunkGraphEdge { key: None, - node: ChunkContentGraphNode::ExternalModuleReference(reference), + node: ChunkContentGraphNode::ExternalModuleReference( + reference.to_resolved().await?, + ), }), None, )); @@ -385,7 +391,7 @@ async fn graph_node_to_referenced_nodes( .await?; Ok(( Some(ChunkGraphEdge { - key: Some(module), + key: Some(module.to_resolved().await?), node: ChunkContentGraphNode::ChunkItem { item: chunk_item, ident: module.ident().to_string().await?, @@ -401,7 +407,7 @@ async fn graph_node_to_referenced_nodes( .await?; Ok(( Some(ChunkGraphEdge { - key: Some(module), + key: Some(module.to_resolved().await?), node: ChunkContentGraphNode::ChunkItem { item: chunk_item, ident: module.ident().to_string().await?, @@ -436,7 +442,7 @@ async fn graph_node_to_referenced_nodes( .await?; Ok(( Some(ChunkGraphEdge { - key: Some(module), + key: Some(module.to_resolved().await?), node: ChunkContentGraphNode::ChunkItem { item: chunk_item, ident: module.ident().to_string().await?, @@ -518,7 +524,7 @@ impl Visit for ChunkContentVisit { } }; - if !self.processed_modules.insert(module) { + if !self.processed_modules.insert(*module) { return VisitControlFlow::Skip(node); } @@ -582,7 +588,7 @@ async fn chunk_content_internal_parallel( return Ok(None); }; Ok(Some(ChunkGraphEdge { - key: Some(entry), + key: Some(entry.to_resolved().await?), node: ChunkContentGraphNode::ChunkItem { item: chunkable_module .as_chunk_item(chunking_context) @@ -628,7 +634,7 @@ async fn chunk_content_internal_parallel( } ChunkContentGraphNode::ExternalModuleReference(reference) => { let reference = reference.resolve().await?; - external_module_references.insert(reference); + external_module_references.insert(*reference); } ChunkContentGraphNode::InheritAsyncInfo { item, references } => { for &(reference, ty) in &references { diff --git a/turbopack/crates/turbopack-core/src/compile_time_info.rs b/turbopack/crates/turbopack-core/src/compile_time_info.rs index 916da133d0b721..90f4305983ea54 100644 --- a/turbopack/crates/turbopack-core/src/compile_time_info.rs +++ b/turbopack/crates/turbopack-core/src/compile_time_info.rs @@ -1,4 +1,4 @@ -use turbo_tasks::{FxIndexMap, RcStr, Vc}; +use turbo_tasks::{FxIndexMap, RcStr, ResolvedVc, Vc}; use turbo_tasks_fs::FileSystemPath; use crate::environment::Environment; @@ -203,7 +203,7 @@ impl CompileTimeDefines { pub enum FreeVarReference { EcmaScriptModule { request: RcStr, - lookup_path: Option>, + lookup_path: Option>, export: Option, }, Value(CompileTimeDefineValue), diff --git a/turbopack/crates/turbopack-core/src/environment.rs b/turbopack/crates/turbopack-core/src/environment.rs index 31812a7a9b3801..c4482100481227 100644 --- a/turbopack/crates/turbopack-core/src/environment.rs +++ b/turbopack/crates/turbopack-core/src/environment.rs @@ -5,7 +5,7 @@ use std::{ use anyhow::{anyhow, Context, Result}; use swc_core::ecma::preset_env::{Version, Versions}; -use turbo_tasks::{RcStr, Value, Vc}; +use turbo_tasks::{RcStr, ResolvedVc, Value, Vc}; use turbo_tasks_env::ProcessEnv; use crate::target::CompileTarget; @@ -247,8 +247,8 @@ impl NodeJsEnvironment { #[turbo_tasks::function] pub async fn runtime_versions(&self) -> Result> { let str = match *self.node_version.await? { - NodeJsVersion::Current(process_env) => get_current_nodejs_version(process_env), - NodeJsVersion::Static(version) => version, + NodeJsVersion::Current(process_env) => get_current_nodejs_version(*process_env), + NodeJsVersion::Static(version) => *version, } .await?; @@ -261,7 +261,7 @@ impl NodeJsEnvironment { } #[turbo_tasks::function] - pub fn current(process_env: Vc>) -> Vc { + pub fn current(process_env: ResolvedVc>) -> Vc { Self::cell(NodeJsEnvironment { compile_target: CompileTarget::current(), node_version: NodeJsVersion::cell(NodeJsVersion::Current(process_env)), @@ -272,13 +272,13 @@ impl NodeJsEnvironment { #[turbo_tasks::value(shared)] pub enum NodeJsVersion { - Current(Vc>), - Static(Vc), + Current(ResolvedVc>), + Static(ResolvedVc), } impl Default for NodeJsVersion { fn default() -> Self { - NodeJsVersion::Static(Vc::cell(DEFAULT_NODEJS_VERSION.into())) + NodeJsVersion::Static(ResolvedVc::cell(DEFAULT_NODEJS_VERSION.into())) } } diff --git a/turbopack/crates/turbopack-core/src/ident.rs b/turbopack/crates/turbopack-core/src/ident.rs index d0174c788146f5..5e8f583d0bbfff 100644 --- a/turbopack/crates/turbopack-core/src/ident.rs +++ b/turbopack/crates/turbopack-core/src/ident.rs @@ -23,7 +23,7 @@ pub struct AssetIdent { /// The part of the asset that is a (ECMAScript) module pub part: Option>, /// The asset layer the asset was created from. - pub layer: Option>, + pub layer: Option>, } impl AssetIdent { @@ -158,7 +158,7 @@ impl AssetIdent { } #[turbo_tasks::function] - pub fn with_layer(&self, layer: Vc) -> Vc { + pub fn with_layer(&self, layer: ResolvedVc) -> Vc { let mut this = self.clone(); this.layer = Some(layer); Self::new(Value::new(this)) diff --git a/turbopack/crates/turbopack-core/src/issue/mod.rs b/turbopack/crates/turbopack-core/src/issue/mod.rs index ffebdb4e217306..b364fe27382f3d 100644 --- a/turbopack/crates/turbopack-core/src/issue/mod.rs +++ b/turbopack/crates/turbopack-core/src/issue/mod.rs @@ -429,7 +429,7 @@ impl CapturedIssues { #[derive(Clone, Debug)] pub struct IssueSource { source: Vc>, - range: Option>, + range: Option>, } /// The end position is the first character after the range @@ -460,7 +460,7 @@ impl IssueSource { ) -> Vc { Self::cell(IssueSource { source, - range: Some(SourceRange::LineColumn(start, end).cell()), + range: Some(SourceRange::LineColumn(start, end).resolved_cell()), }) } @@ -492,7 +492,7 @@ impl IssueSource { if let Some((source, start, end)) = mapped { return Ok(Self::cell(IssueSource { source, - range: Some(SourceRange::LineColumn(start, end).cell()), + range: Some(SourceRange::LineColumn(start, end).resolved_cell()), })); } } @@ -514,9 +514,11 @@ impl IssueSource { source, range: match (start == 0, end == 0) { (true, true) => None, - (false, false) => Some(SourceRange::ByteOffset(start - 1, end - 1).cell()), - (false, true) => Some(SourceRange::ByteOffset(start - 1, start - 1).cell()), - (true, false) => Some(SourceRange::ByteOffset(end - 1, end - 1).cell()), + (false, false) => Some(SourceRange::ByteOffset(start - 1, end - 1).resolved_cell()), + (false, true) => { + Some(SourceRange::ByteOffset(start - 1, start - 1).resolved_cell()) + } + (true, false) => Some(SourceRange::ByteOffset(end - 1, end - 1).resolved_cell()), }, }) } @@ -541,7 +543,7 @@ impl IssueSource { range: if let FileLinesContent::Lines(lines) = &*source.content().lines().await? { let start = find_line_and_column(lines.as_ref(), start); let end = find_line_and_column(lines.as_ref(), end); - Some(SourceRange::LineColumn(start, end).cell()) + Some(SourceRange::LineColumn(start, end).resolved_cell()) } else { None }, diff --git a/turbopack/crates/turbopack-core/src/issue/resolve.rs b/turbopack/crates/turbopack-core/src/issue/resolve.rs index dd054507987112..c9633312ff28fd 100644 --- a/turbopack/crates/turbopack-core/src/issue/resolve.rs +++ b/turbopack/crates/turbopack-core/src/issue/resolve.rs @@ -1,7 +1,7 @@ use std::fmt::Write; use anyhow::Result; -use turbo_tasks::{RcStr, ReadRef, ValueToString, Vc}; +use turbo_tasks::{RcStr, ReadRef, ResolvedVc, ValueToString, Vc}; use turbo_tasks_fs::FileSystemPath; use super::{Issue, IssueSource, IssueStage, OptionIssueSource, OptionStyledString, StyledString}; @@ -22,7 +22,7 @@ pub struct ResolvingIssue { pub file_path: Vc, pub resolve_options: Vc, pub error_message: Option, - pub source: Option>, + pub source: Option>, } #[turbo_tasks::value_impl] diff --git a/turbopack/crates/turbopack-core/src/resolve/mod.rs b/turbopack/crates/turbopack-core/src/resolve/mod.rs index b41cc191bf7224..c6d855105c4adb 100644 --- a/turbopack/crates/turbopack-core/src/resolve/mod.rs +++ b/turbopack/crates/turbopack-core/src/resolve/mod.rs @@ -10,8 +10,8 @@ use anyhow::{bail, Result}; use serde::{Deserialize, Serialize}; use tracing::{Instrument, Level}; use turbo_tasks::{ - fxindexmap, fxindexset, trace::TraceRawVcs, FxIndexMap, RcStr, TaskInput, TryJoinIterExt, - Value, ValueToString, Vc, + fxindexmap, fxindexset, trace::TraceRawVcs, FxIndexMap, RcStr, ResolvedVc, TaskInput, + TryJoinIterExt, Value, ValueToString, Vc, }; use turbo_tasks_fs::{ util::normalize_request, FileSystemEntryType, FileSystemPath, RealPathResult, @@ -67,7 +67,7 @@ pub enum ModuleResolveResultItem { OutputAsset(Vc>), External(RcStr, ExternalType), Ignore, - Error(Vc), + Error(ResolvedVc), Empty, Custom(u8), } @@ -675,7 +675,9 @@ impl ResolveResult { } ResolveResultItem::Ignore => ModuleResolveResultItem::Ignore, ResolveResultItem::Empty => ModuleResolveResultItem::Empty, - ResolveResultItem::Error(e) => ModuleResolveResultItem::Error(e), + ResolveResultItem::Error(e) => { + ModuleResolveResultItem::Error(e.to_resolved().await?) + } ResolveResultItem::Custom(u8) => { ModuleResolveResultItem::Custom(u8) } @@ -1202,8 +1204,8 @@ pub async fn find_context_file_or_package_key( #[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize, TraceRawVcs, Debug)] enum FindPackageItem { - PackageDirectory(Vc), - PackageFile(Vc), + PackageDirectory(ResolvedVc), + PackageFile(ResolvedVc), } #[turbo_tasks::value] @@ -1236,7 +1238,9 @@ async fn find_package( if let Some(fs_path) = dir_exists(fs_path, &mut affecting_sources).await? { - packages.push(FindPackageItem::PackageDirectory(fs_path)); + packages.push(FindPackageItem::PackageDirectory( + fs_path.to_resolved().await?, + )); } } } @@ -1259,10 +1263,14 @@ async fn find_package( { match ty { FileSystemEntryType::Directory => { - packages.push(FindPackageItem::PackageDirectory(package_dir)); + packages.push(FindPackageItem::PackageDirectory( + package_dir.to_resolved().await?, + )); } FileSystemEntryType::File => { - packages.push(FindPackageItem::PackageFile(package_dir)); + packages.push(FindPackageItem::PackageFile( + package_dir.to_resolved().await?, + )); } _ => {} } @@ -1274,7 +1282,9 @@ async fn find_package( let package_file = package_dir.append(extension.clone()); if let Some(package_file) = exists(package_file, &mut affecting_sources).await? { - packages.push(FindPackageItem::PackageFile(package_file)); + packages.push(FindPackageItem::PackageFile( + package_file.to_resolved().await?, + )); } } } @@ -1435,7 +1445,7 @@ pub async fn url_resolve( origin: Vc>, request: Vc, reference_type: Value, - issue_source: Option>, + issue_source: Option>, is_optional: bool, ) -> Result> { let resolve_options = origin.resolve_options(reference_type.clone()); @@ -2362,7 +2372,7 @@ async fn resolve_module_request( FindPackageItem::PackageDirectory(package_path) => { results.push(resolve_into_package( Value::new(path.clone()), - package_path, + *package_path, query, fragment, options, @@ -2372,7 +2382,7 @@ async fn resolve_module_request( if path.is_match("") { let resolved = resolved( RequestKey::new(".".into()), - package_path, + *package_path, lookup_path, request, options_value, @@ -2721,7 +2731,7 @@ pub async fn handle_resolve_error( request: Vc, resolve_options: Vc, is_optional: bool, - source: Option>, + source: Option>, ) -> Result> { async fn is_unresolvable(result: Vc) -> Result { Ok(*result.resolve().await?.is_unresolvable().await?) @@ -2765,7 +2775,7 @@ pub async fn handle_resolve_source_error( request: Vc, resolve_options: Vc, is_optional: bool, - source: Option>, + source: Option>, ) -> Result> { async fn is_unresolvable(result: Vc) -> Result { Ok(*result.resolve().await?.is_unresolvable().await?) @@ -2809,7 +2819,7 @@ async fn emit_resolve_error_issue( request: Vc, resolve_options: Vc, err: anyhow::Error, - source: Option>, + source: Option>, ) -> Result<()> { let severity = if is_optional || resolve_options.await?.loose_errors { IssueSeverity::Warning.cell() @@ -2836,7 +2846,7 @@ async fn emit_unresolvable_issue( reference_type: Value, request: Vc, resolve_options: Vc, - source: Option>, + source: Option>, ) -> Result<()> { let severity = if is_optional || resolve_options.await?.loose_errors { IssueSeverity::Warning.cell() @@ -2875,7 +2885,7 @@ pub enum ModulePart { /// all exports are unused. Evaluation, /// Represents an export of a module. - Export(Vc), + Export(ResolvedVc), /// Represents a renamed export of a module. RenamedExport { original_export: Vc, @@ -2902,7 +2912,7 @@ impl ModulePart { } #[turbo_tasks::function] pub fn export(export: RcStr) -> Vc { - ModulePart::Export(Vc::cell(export)).cell() + ModulePart::Export(ResolvedVc::cell(export)).cell() } #[turbo_tasks::function] pub fn renamed_export(original_export: RcStr, export: RcStr) -> Vc { diff --git a/turbopack/crates/turbopack-core/src/resolve/node.rs b/turbopack/crates/turbopack-core/src/resolve/node.rs index efcab014270c60..534e9da2639c52 100644 --- a/turbopack/crates/turbopack-core/src/resolve/node.rs +++ b/turbopack/crates/turbopack-core/src/resolve/node.rs @@ -1,4 +1,4 @@ -use turbo_tasks::Vc; +use turbo_tasks::{ResolvedVc, Vc}; use turbo_tasks_fs::FileSystemPath; use super::options::{ @@ -7,7 +7,7 @@ use super::options::{ }; #[turbo_tasks::function] -pub fn node_cjs_resolve_options(root: Vc) -> Vc { +pub fn node_cjs_resolve_options(root: ResolvedVc) -> Vc { let conditions: ResolutionConditions = [ ("node".into(), ConditionValue::Set), ("require".into(), ConditionValue::Set), @@ -37,7 +37,7 @@ pub fn node_cjs_resolve_options(root: Vc) -> Vc } #[turbo_tasks::function] -pub fn node_esm_resolve_options(root: Vc) -> Vc { +pub fn node_esm_resolve_options(root: ResolvedVc) -> Vc { let conditions: ResolutionConditions = [ ("node".into(), ConditionValue::Set), ("import".into(), ConditionValue::Set), diff --git a/turbopack/crates/turbopack-core/src/resolve/options.rs b/turbopack/crates/turbopack-core/src/resolve/options.rs index 2662a6257a2c05..762c70b900d1e1 100644 --- a/turbopack/crates/turbopack-core/src/resolve/options.rs +++ b/turbopack/crates/turbopack-core/src/resolve/options.rs @@ -3,8 +3,8 @@ use std::{collections::BTreeMap, future::Future, pin::Pin}; use anyhow::{bail, Result}; use serde::{Deserialize, Serialize}; use turbo_tasks::{ - debug::ValueDebugFormat, trace::TraceRawVcs, FxIndexSet, RcStr, TryJoinIterExt, Value, - ValueToString, Vc, + debug::ValueDebugFormat, trace::TraceRawVcs, FxIndexSet, RcStr, ResolvedVc, TryJoinIterExt, + Value, ValueToString, Vc, }; use turbo_tasks_fs::{glob::Glob, FileSystemPath}; @@ -31,7 +31,7 @@ pub struct ExcludedExtensions(pub FxIndexSet); pub enum ResolveModules { /// when inside of path, use the list of directories to /// resolve inside these - Nested(Vc, Vec), + Nested(ResolvedVc, Vec), /// look into that directory, unless the request has an excluded extension Path { dir: Vc, @@ -95,7 +95,7 @@ pub enum ResolveInPackage { pub enum ImportMapping { External(Option, ExternalType), /// An already resolved result that will be returned directly. - Direct(Vc), + Direct(ResolvedVc), /// A request alias that will be resolved first, and fall back to resolving /// the original request if it fails. Useful for the tsconfig.json /// `compilerOptions.paths` option and Next aliases. @@ -152,7 +152,7 @@ impl AliasTemplate for Vc { ImportMapping::PrimaryAlternative(name, context) => { ReplacedImportMapping::PrimaryAlternative((*name).clone().into(), *context) } - ImportMapping::Direct(v) => ReplacedImportMapping::Direct(*v), + ImportMapping::Direct(v) => ReplacedImportMapping::Direct(**v), ImportMapping::Ignore => ReplacedImportMapping::Ignore, ImportMapping::Empty => ReplacedImportMapping::Empty, ImportMapping::Alternatives(alternatives) => ReplacedImportMapping::Alternatives( @@ -189,7 +189,7 @@ impl AliasTemplate for Vc { *context, ) } - ImportMapping::Direct(v) => ReplacedImportMapping::Direct(*v), + ImportMapping::Direct(v) => ReplacedImportMapping::Direct(**v), ImportMapping::Ignore => ReplacedImportMapping::Ignore, ImportMapping::Empty => ReplacedImportMapping::Empty, ImportMapping::Alternatives(alternatives) => ReplacedImportMapping::Alternatives( diff --git a/turbopack/crates/turbopack-css/src/asset.rs b/turbopack/crates/turbopack-css/src/asset.rs index f4b6e8470581b0..93b3b005eecaf4 100644 --- a/turbopack/crates/turbopack-css/src/asset.rs +++ b/turbopack/crates/turbopack-css/src/asset.rs @@ -238,7 +238,10 @@ impl CssChunkItem for CssModuleChunkItem { if let Some(css_item) = Vc::try_resolve_downcast::>(item).await? { - imports.push(CssImport::Internal(import_ref, css_item)); + imports.push(CssImport::Internal( + import_ref.to_resolved().await?, + css_item, + )); } } } @@ -260,7 +263,7 @@ impl CssChunkItem for CssModuleChunkItem { if let Some(css_item) = Vc::try_resolve_downcast::>(item).await? { - imports.push(CssImport::Composes(css_item)); + imports.push(CssImport::Composes(css_item.to_resolved().await?)); } } } diff --git a/turbopack/crates/turbopack-css/src/chunk/mod.rs b/turbopack/crates/turbopack-css/src/chunk/mod.rs index 9abf43210b9f1e..5087e77d5f56eb 100644 --- a/turbopack/crates/turbopack-css/src/chunk/mod.rs +++ b/turbopack/crates/turbopack-css/src/chunk/mod.rs @@ -4,7 +4,9 @@ pub mod source_map; use std::fmt::Write; use anyhow::{bail, Result}; -use turbo_tasks::{FxIndexSet, RcStr, TryJoinIterExt, Value, ValueDefault, ValueToString, Vc}; +use turbo_tasks::{ + FxIndexSet, RcStr, ResolvedVc, TryJoinIterExt, Value, ValueDefault, ValueToString, Vc, +}; use turbo_tasks_fs::{rope::Rope, File, FileSystem}; use turbopack_core::{ asset::{Asset, AssetContent}, @@ -350,8 +352,8 @@ pub trait CssChunkPlaceable: ChunkableModule + Module + Asset {} #[turbo_tasks::value(shared)] pub enum CssImport { External(Vc), - Internal(Vc, Vc>), - Composes(Vc>), + Internal(ResolvedVc, Vc>), + Composes(ResolvedVc>), } #[derive(Debug)] diff --git a/turbopack/crates/turbopack-css/src/references/url.rs b/turbopack/crates/turbopack-css/src/references/url.rs index 1448aa693458a2..94591797322be5 100644 --- a/turbopack/crates/turbopack-css/src/references/url.rs +++ b/turbopack/crates/turbopack-css/src/references/url.rs @@ -10,7 +10,7 @@ use swc_core::css::{ ast::UrlValue, visit::{VisitMut, VisitMutWith}, }; -use turbo_tasks::{debug::ValueDebug, RcStr, Value, ValueToString, Vc}; +use turbo_tasks::{debug::ValueDebug, RcStr, ResolvedVc, Value, ValueToString, Vc}; use turbopack_core::{ chunk::{ ChunkableModule, ChunkableModuleReference, ChunkingContext, ChunkingType, @@ -28,7 +28,7 @@ use crate::{embed::CssEmbed, StyleSheetLike}; #[turbo_tasks::value(into = "new")] pub enum ReferencedAsset { - Some(Vc>), + Some(ResolvedVc>), None, } @@ -68,7 +68,10 @@ impl UrlAssetReference { if let Some(embeddable) = Vc::try_resolve_downcast::>(chunk_item).await? { - return Ok(ReferencedAsset::Some(embeddable.embedded_asset()).into()); + return Ok(ReferencedAsset::Some( + embeddable.embedded_asset().to_resolved().await?, + ) + .into()); } } bail!( diff --git a/turbopack/crates/turbopack-dev-server/src/source/asset_graph.rs b/turbopack/crates/turbopack-dev-server/src/source/asset_graph.rs index cb6afbf7e259a0..05ac567d7e6140 100644 --- a/turbopack/crates/turbopack-dev-server/src/source/asset_graph.rs +++ b/turbopack/crates/turbopack-dev-server/src/source/asset_graph.rs @@ -5,8 +5,8 @@ use std::{ use anyhow::Result; use turbo_tasks::{ - fxindexset, Completion, FxIndexMap, FxIndexSet, RcStr, State, TryJoinIterExt, Value, - ValueToString, Vc, + fxindexset, Completion, FxIndexMap, FxIndexSet, RcStr, ResolvedVc, State, TryJoinIterExt, + Value, ValueToString, Vc, }; use turbo_tasks_fs::FileSystemPath; use turbopack_core::{ @@ -338,7 +338,10 @@ impl Introspectable for AssetGraphContentSource { Ok(Vc::cell( root_asset_children .chain(expanded_asset_children) - .chain(once((expanded_key, Vc::upcast(FullyExpaned(self).cell())))) + .chain(once(( + expanded_key, + Vc::upcast(FullyExpaned(self.to_resolved().await?).cell()), + ))) .collect(), )) } @@ -350,7 +353,7 @@ fn fully_expaned_introspectable_type() -> Vc { } #[turbo_tasks::value] -struct FullyExpaned(Vc); +struct FullyExpaned(ResolvedVc); #[turbo_tasks::value_impl] impl Introspectable for FullyExpaned { diff --git a/turbopack/crates/turbopack-dev-server/src/source/mod.rs b/turbopack/crates/turbopack-dev-server/src/source/mod.rs index 6531bcc6671fa0..1e799bb3ef7afb 100644 --- a/turbopack/crates/turbopack-dev-server/src/source/mod.rs +++ b/turbopack/crates/turbopack-dev-server/src/source/mod.rs @@ -89,9 +89,9 @@ pub struct StaticContent { /// The content of a result that is returned by a content source. pub enum ContentSourceContent { NotFound, - Static(Vc), - HttpProxy(Vc), - Rewrite(Vc), + Static(ResolvedVc), + HttpProxy(ResolvedVc), + Rewrite(ResolvedVc), /// Continue with the next route Next, } @@ -119,31 +119,33 @@ impl GetContentSourceContent for ContentSourceContent { #[turbo_tasks::value_impl] impl ContentSourceContent { #[turbo_tasks::function] - pub fn static_content(content: Vc>) -> Vc { + pub fn static_content( + content: ResolvedVc>, + ) -> Vc { ContentSourceContent::Static( StaticContent { - content, + content: *content, status_code: 200, headers: HeaderList::empty(), } - .cell(), + .resolved_cell(), ) .cell() } #[turbo_tasks::function] pub fn static_with_headers( - content: Vc>, + content: ResolvedVc>, status_code: u16, - headers: Vc, + headers: ResolvedVc, ) -> Vc { ContentSourceContent::Static( StaticContent { - content, + content: *content, status_code, - headers, + headers: *headers, } - .cell(), + .resolved_cell(), ) .cell() } diff --git a/turbopack/crates/turbopack-dev-server/src/source/resolve.rs b/turbopack/crates/turbopack-dev-server/src/source/resolve.rs index 8b56aa7c6c4e03..0db0873fbbed07 100644 --- a/turbopack/crates/turbopack-dev-server/src/source/resolve.rs +++ b/turbopack/crates/turbopack-dev-server/src/source/resolve.rs @@ -8,7 +8,7 @@ use hyper::{ header::{HeaderName as HyperHeaderName, HeaderValue as HyperHeaderValue}, Uri, }; -use turbo_tasks::{RcStr, TransientInstance, Value, Vc}; +use turbo_tasks::{RcStr, ResolvedVc, TransientInstance, Value, Vc}; use super::{ headers::{HeaderValue, Headers}, @@ -24,7 +24,7 @@ use super::{ #[turbo_tasks::value(serialization = "none")] pub enum ResolveSourceRequestResult { NotFound, - Static(Vc, Vc), + Static(Vc, ResolvedVc), HttpProxy(Vc), } @@ -107,13 +107,15 @@ pub async fn resolve_source_request( } ContentSourceContent::Static(static_content) => { return Ok(ResolveSourceRequestResult::Static( - *static_content, - HeaderList::new(response_header_overwrites), + **static_content, + HeaderList::new(response_header_overwrites) + .to_resolved() + .await?, ) .cell()); } ContentSourceContent::HttpProxy(proxy_result) => { - return Ok(ResolveSourceRequestResult::HttpProxy(*proxy_result).cell()); + return Ok(ResolveSourceRequestResult::HttpProxy(**proxy_result).cell()); } ContentSourceContent::Next => continue, } diff --git a/turbopack/crates/turbopack-dev-server/src/source/wrapping_source.rs b/turbopack/crates/turbopack-dev-server/src/source/wrapping_source.rs index 235c9c2ce0ed37..d0e906d5fc5a87 100644 --- a/turbopack/crates/turbopack-dev-server/src/source/wrapping_source.rs +++ b/turbopack/crates/turbopack-dev-server/src/source/wrapping_source.rs @@ -79,7 +79,7 @@ impl GetContentSourceContent for WrappedGetContentSourceContent { response_headers: rewrite.response_headers, request_headers: rewrite.request_headers, } - .cell(), + .resolved_cell(), ) .cell()); } diff --git a/turbopack/crates/turbopack-ecmascript/src/chunk/placeable.rs b/turbopack/crates/turbopack-ecmascript/src/chunk/placeable.rs index 9fe28b18cceb81..8d33649349e304 100644 --- a/turbopack/crates/turbopack-ecmascript/src/chunk/placeable.rs +++ b/turbopack/crates/turbopack-ecmascript/src/chunk/placeable.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use turbo_tasks::{TryFlatJoinIterExt, Vc}; +use turbo_tasks::{ResolvedVc, TryFlatJoinIterExt, Vc}; use turbo_tasks_fs::{glob::Glob, FileJsonContent, FileSystemPath}; use turbopack_core::{ asset::Asset, @@ -33,7 +33,7 @@ pub trait EcmascriptChunkPlaceable: ChunkableModule + Module + Asset { enum SideEffectsValue { None, Constant(bool), - Glob(Vc), + Glob(ResolvedVc), } #[turbo_tasks::function] @@ -100,7 +100,7 @@ async fn side_effects_from_package_json( .try_flat_join() .await?; return Ok( - SideEffectsValue::Glob(Glob::alternatives(globs).resolve().await?).cell(), + SideEffectsValue::Glob(Glob::alternatives(globs).to_resolved().await?).cell(), ); } else { SideEffectsInPackageJsonIssue { @@ -190,7 +190,7 @@ pub async fn is_marked_as_side_effect_free( #[turbo_tasks::value(shared)] pub enum EcmascriptExports { - EsmExports(Vc), + EsmExports(ResolvedVc), DynamicNamespace, CommonJs, EmptyCommonJs, diff --git a/turbopack/crates/turbopack-ecmascript/src/global_module_id_strategy.rs b/turbopack/crates/turbopack-ecmascript/src/global_module_id_strategy.rs index 7a2d3be26e0488..a04089fea5a88c 100644 --- a/turbopack/crates/turbopack-ecmascript/src/global_module_id_strategy.rs +++ b/turbopack/crates/turbopack-ecmascript/src/global_module_id_strategy.rs @@ -1,7 +1,7 @@ use anyhow::Result; use turbo_tasks::{ graph::{AdjacencyMap, GraphTraversal}, - FxIndexMap, FxIndexSet, RcStr, TryJoinIterExt, ValueToString, Vc, + FxIndexMap, FxIndexSet, RcStr, ResolvedVc, TryJoinIterExt, ValueToString, Vc, }; use turbo_tasks_hash::hash_xxh3_hash64; use turbopack_core::{ @@ -24,14 +24,14 @@ pub struct PreprocessedChildrenIdents { #[turbo_tasks::value(shared)] pub enum ReferencedModule { Module(Vc>), - AsyncLoaderModule(Vc>), + AsyncLoaderModule(ResolvedVc>), } impl ReferencedModule { fn module(&self) -> Vc> { match *self { ReferencedModule::Module(module) => module, - ReferencedModule::AsyncLoaderModule(module) => module, + ReferencedModule::AsyncLoaderModule(module) => *module, } } } @@ -89,7 +89,10 @@ async fn referenced_modules(module: Vc>) -> Result, options: Vc, compile_time_info: Vc, - inner_assets: Option>, + inner_assets: Option>, } impl EcmascriptModuleAssetBuilder { - pub fn with_inner_assets(mut self, inner_assets: Vc) -> Self { + pub fn with_inner_assets(mut self, inner_assets: ResolvedVc) -> Self { self.inner_assets = Some(inner_assets); self } @@ -219,7 +219,7 @@ impl EcmascriptModuleAssetBuilder { self.transforms, self.options, self.compile_time_info, - inner_assets, + *inner_assets, ) } else { EcmascriptModuleAsset::new( @@ -296,7 +296,7 @@ impl EcmascriptModuleAsset { #[derive(Copy, Clone)] pub(crate) struct ModuleTypeResult { pub module_type: SpecifiedModuleType, - pub referenced_package_json: Option>, + pub referenced_package_json: Option>, } #[turbo_tasks::value_impl] @@ -312,7 +312,7 @@ impl ModuleTypeResult { #[turbo_tasks::function] fn new_with_package_json( module_type: SpecifiedModuleType, - package_json: Vc, + package_json: ResolvedVc, ) -> Vc { Self::cell(ModuleTypeResult { module_type, @@ -526,7 +526,7 @@ impl Module for EcmascriptModuleAsset { ident.add_asset(Vc::cell(name.to_string().into()), asset.ident()); } ident.add_modifier(modifier()); - ident.layer = Some(self.asset_context.layer()); + ident.layer = Some(self.asset_context.layer().to_resolved().await?); Ok(AssetIdent::new(Value::new(ident))) } else { Ok(self diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs index b917c057fe7092..b41a16c8b904bf 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs @@ -5,7 +5,7 @@ use swc_core::{ ecma::ast::{Decl, Expr, ExprStmt, Ident, Stmt}, quote, }; -use turbo_tasks::{RcStr, Value, ValueToString, Vc}; +use turbo_tasks::{RcStr, ResolvedVc, Value, ValueToString, Vc}; use turbo_tasks_fs::FileSystemPath; use turbopack_core::{ chunk::{ @@ -40,7 +40,7 @@ use crate::{ #[turbo_tasks::value] pub enum ReferencedAsset { - Some(Vc>), + Some(ResolvedVc>), External(RcStr, ExternalType), None, Unresolvable, @@ -87,7 +87,7 @@ impl ReferencedAsset { Vc::try_resolve_downcast::>(module) .await? { - return Ok(ReferencedAsset::Some(placeable).cell()); + return Ok(ReferencedAsset::Some(placeable.to_resolved().await?).cell()); } } // TODO ignore should probably be handled differently @@ -105,7 +105,7 @@ pub struct EsmAssetReference { pub request: Vc, pub annotations: ImportAnnotations, pub issue_source: Vc, - pub export_name: Option>, + pub export_name: Option>, pub import_externals: bool, } @@ -127,7 +127,7 @@ impl EsmAssetReference { request: Vc, issue_source: Vc, annotations: Value, - export_name: Option>, + export_name: Option>, import_externals: bool, ) -> Vc { Self::cell(EsmAssetReference { @@ -153,7 +153,7 @@ impl ModuleReference for EsmAssetReference { let ty = if matches!(self.annotations.module_type(), Some("json")) { EcmaScriptModulesReferenceSubType::ImportWithType(ImportWithType::Json) } else if let Some(part) = &self.export_name { - EcmaScriptModulesReferenceSubType::ImportPart(*part) + EcmaScriptModulesReferenceSubType::ImportPart(**part) } else { EcmaScriptModulesReferenceSubType::Import }; @@ -167,7 +167,7 @@ impl ModuleReference for EsmAssetReference { .expect("EsmAssetReference origin should be a EcmascriptModuleAsset"); return Ok(ModuleResolveResult::module( - EcmascriptModulePartAsset::select_part(module, part), + EcmascriptModulePartAsset::select_part(module, *part), ) .cell()); } @@ -192,7 +192,7 @@ impl ModuleReference for EsmAssetReference { let export = export_name.await?; if *is_export_missing(module, export.clone_value()).await? { InvalidExport { - export: export_name, + export: *export_name, module, source: self.issue_source, } diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs index 498bdb1a043582..62862f5a329d26 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs @@ -218,12 +218,12 @@ async fn handle_declared_export( .await? { return Ok(ControlFlow::Break(FollowExportsResult { - module, + module: *module, export_name: Some(name.clone()), ty: FoundExportType::SideEffects, })); } - return Ok(ControlFlow::Continue((module, name.clone()))); + return Ok(ControlFlow::Continue((*module, name.clone()))); } } EsmExport::ImportedNamespace(reference) => { @@ -231,7 +231,7 @@ async fn handle_declared_export( *ReferencedAsset::from_resolve_result(reference.resolve_reference()).await? { return Ok(ControlFlow::Break(FollowExportsResult { - module: m, + module: *m, export_name: None, ty: FoundExportType::Found, })); @@ -290,7 +290,7 @@ async fn get_all_export_names( if let ReferencedAsset::Some(m) = *ReferencedAsset::from_resolve_result(esm_ref.resolve_reference()).await? { - Some(get_all_export_names(m)) + Some(get_all_export_names(*m)) } else { None }, @@ -341,8 +341,8 @@ pub async fn expand_star_exports( if let ReferencedAsset::Some(asset) = &*ReferencedAsset::from_resolve_result(esm_ref.resolve_reference()).await? { - if checked_modules.insert(*asset) { - queue.push((*asset, asset.get_exports())); + if checked_modules.insert(**asset) { + queue.push((**asset, asset.get_exports())); } } } @@ -444,7 +444,7 @@ impl EsmExports { continue; }; - let export_info = expand_star_exports(*asset).await?; + let export_info = expand_star_exports(**asset).await?; for export in &export_info.star_exports { if !exports.contains_key(export) { @@ -456,7 +456,7 @@ impl EsmExports { } if export_info.has_dynamic_exports { - dynamic_exports.push(*asset); + dynamic_exports.push(**asset); } } diff --git a/turbopack/crates/turbopack-ecmascript/src/references/mod.rs b/turbopack/crates/turbopack-ecmascript/src/references/mod.rs index 91f6d931e367ad..7c8ceeae06176e 100644 --- a/turbopack/crates/turbopack-ecmascript/src/references/mod.rs +++ b/turbopack/crates/turbopack-ecmascript/src/references/mod.rs @@ -50,7 +50,9 @@ use swc_core::{ }, }; use tracing::Instrument; -use turbo_tasks::{FxIndexSet, RcStr, TryJoinIterExt, Upcast, Value, ValueToString, Vc}; +use turbo_tasks::{ + FxIndexSet, RcStr, ResolvedVc, TryJoinIterExt, Upcast, Value, ValueToString, Vc, +}; use turbo_tasks_fs::FileSystemPath; use turbopack_core::{ compile_time_info::{ @@ -168,7 +170,7 @@ pub struct AnalyzeEcmascriptModuleResultBuilder { exports: EcmascriptExports, async_module: Vc, successful: bool, - source_map: Option>, + source_map: Option>, bindings: Vec, } @@ -253,7 +255,7 @@ impl AnalyzeEcmascriptModuleResultBuilder { } /// Sets the analysis result ES export. - pub fn set_source_map(&mut self, source_map: Vc) { + pub fn set_source_map(&mut self, source_map: ResolvedVc) { self.source_map = Some(source_map); } @@ -324,7 +326,7 @@ impl AnalyzeEcmascriptModuleResultBuilder { let source_map = if let Some(source_map) = self.source_map { source_map } else { - OptionSourceMap::none() + OptionSourceMap::none().to_resolved().await? }; Ok(AnalyzeEcmascriptModuleResult::cell( AnalyzeEcmascriptModuleResult { @@ -336,7 +338,7 @@ impl AnalyzeEcmascriptModuleResultBuilder { exports: self.exports.into(), async_module: self.async_module, successful: self.successful, - source_map, + source_map: *source_map, }, )) } @@ -458,7 +460,7 @@ pub(crate) async fn analyse_ecmascript_module_internal( } = *module.determine_module_type().await?; if let Some(package_json) = referenced_package_json { - analysis.add_reference(PackageJsonReference::new(package_json)); + analysis.add_reference(PackageJsonReference::new(*package_json)); } if analyze_types { @@ -546,18 +548,20 @@ pub(crate) async fn analyse_ecmascript_module_internal( let reference = SourceMapReference::new(origin_path, source_map_origin); analysis.add_reference(reference); let source_map = reference.generate_source_map(); - analysis.set_source_map(convert_to_turbopack_source_map( - source_map, - source_map_origin, - )); + analysis.set_source_map( + convert_to_turbopack_source_map(source_map, source_map_origin) + .to_resolved() + .await?, + ); source_map_from_comment = true; } else if path.starts_with("data:application/json;base64,") { let source_map_origin = origin_path; let source_map = maybe_decode_data_url(path.into()); - analysis.set_source_map(convert_to_turbopack_source_map( - source_map, - source_map_origin, - )); + analysis.set_source_map( + convert_to_turbopack_source_map(source_map, source_map_origin) + .to_resolved() + .await?, + ); source_map_from_comment = true; } } @@ -566,10 +570,14 @@ pub(crate) async fn analyse_ecmascript_module_internal( Vc::try_resolve_sidecast::>(source).await? { let source_map_origin = source.ident().path(); - analysis.set_source_map(convert_to_turbopack_source_map( - generate_source_map.generate_source_map(), - source_map_origin, - )); + analysis.set_source_map( + convert_to_turbopack_source_map( + generate_source_map.generate_source_map(), + source_map_origin, + ) + .to_resolved() + .await?, + ); } } @@ -761,7 +769,7 @@ pub(crate) async fn analyse_ecmascript_module_internal( } .cell(); - EcmascriptExports::EsmExports(esm_exports) + EcmascriptExports::EsmExports(esm_exports.to_resolved().await?) } else if specified_type == SpecifiedModuleType::EcmaScript { match detect_dynamic_export(program) { DetectedDynamicExportType::CommonJs => { @@ -777,7 +785,7 @@ pub(crate) async fn analyse_ecmascript_module_internal( exports: Default::default(), star_exports: Default::default(), } - .cell(), + .resolved_cell(), ) } DetectedDynamicExportType::Namespace => EcmascriptExports::DynamicNamespace, @@ -788,7 +796,7 @@ pub(crate) async fn analyse_ecmascript_module_internal( exports: Default::default(), star_exports: Default::default(), } - .cell(), + .resolved_cell(), ), } } else { @@ -801,7 +809,7 @@ pub(crate) async fn analyse_ecmascript_module_internal( exports: Default::default(), star_exports: Default::default(), } - .cell(), + .resolved_cell(), ), DetectedDynamicExportType::None => EcmascriptExports::EmptyCommonJs, } @@ -2191,7 +2199,7 @@ async fn handle_free_var_reference( lookup_path.map_or(state.origin, |lookup_path| { Vc::upcast(PlainResolveOrigin::new( state.origin.asset_context(), - lookup_path, + *lookup_path, )) }), Request::parse(Value::new(request.clone().into())), diff --git a/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/facade/module.rs b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/facade/module.rs index 8dcec1e902f949..8fbfcea8b550aa 100644 --- a/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/facade/module.rs +++ b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/facade/module.rs @@ -255,7 +255,7 @@ impl EcmascriptChunkPlaceable for EcmascriptModuleFacadeModule { star_exports, } .cell(); - Ok(EcmascriptExports::EsmExports(exports).cell()) + Ok(EcmascriptExports::EsmExports(exports.to_resolved().await?).cell()) } #[turbo_tasks::function] diff --git a/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/locals/module.rs b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/locals/module.rs index 167108ff51e373..90faab22b121df 100644 --- a/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/locals/module.rs +++ b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/locals/module.rs @@ -94,7 +94,7 @@ impl EcmascriptChunkPlaceable for EcmascriptModuleLocalsModule { star_exports: vec![], } .cell(); - Ok(EcmascriptExports::EsmExports(exports).cell()) + Ok(EcmascriptExports::EsmExports(exports.to_resolved().await?).cell()) } #[turbo_tasks::function] diff --git a/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/reference.rs b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/reference.rs index ebb64fedf2d6de..fd07f2d0cefb6c 100644 --- a/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/reference.rs +++ b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/reference.rs @@ -1,6 +1,6 @@ use anyhow::{bail, Context, Result}; use swc_core::{common::DUMMY_SP, ecma::ast::Ident, quote}; -use turbo_tasks::{RcStr, ValueToString, Vc}; +use turbo_tasks::{RcStr, ResolvedVc, ValueToString, Vc}; use turbopack_core::{ chunk::{ ChunkItemExt, ChunkableModule, ChunkableModuleReference, ChunkingContext, ChunkingType, @@ -25,7 +25,7 @@ use crate::{ #[turbo_tasks::value] pub struct EcmascriptModulePartReference { pub module: Vc>, - pub part: Option>, + pub part: Option>, } #[turbo_tasks::value_impl] @@ -33,7 +33,7 @@ impl EcmascriptModulePartReference { #[turbo_tasks::function] pub fn new_part( module: Vc>, - part: Vc, + part: ResolvedVc, ) -> Vc { EcmascriptModulePartReference { module, @@ -77,7 +77,7 @@ impl ModuleReference for EcmascriptModulePartReference { | ModulePart::Facade | ModulePart::RenamedExport { .. } | ModulePart::RenamedNamespace { .. } => { - Vc::upcast(EcmascriptModuleFacadeModule::new(self.module, part)) + Vc::upcast(EcmascriptModuleFacadeModule::new(self.module, *part)) } ModulePart::Export(..) | ModulePart::Internal(..) => { bail!( diff --git a/turbopack/crates/turbopack-ecmascript/src/transform/mod.rs b/turbopack/crates/turbopack-ecmascript/src/transform/mod.rs index 264b011bb74fe0..77916db0e27e6a 100644 --- a/turbopack/crates/turbopack-ecmascript/src/transform/mod.rs +++ b/turbopack/crates/turbopack-ecmascript/src/transform/mod.rs @@ -18,7 +18,7 @@ use swc_core::{ }, quote, }; -use turbo_tasks::{RcStr, Vc}; +use turbo_tasks::{RcStr, ResolvedVc, Vc}; use turbo_tasks_fs::FileSystemPath; use turbopack_core::{ environment::Environment, @@ -30,7 +30,7 @@ use turbopack_core::{ pub enum EcmascriptInputTransform { CommonJs, Plugin(Vc), - PresetEnv(Vc), + PresetEnv(ResolvedVc), React { #[serde(default)] development: bool, diff --git a/turbopack/crates/turbopack-image/src/process/mod.rs b/turbopack/crates/turbopack-image/src/process/mod.rs index 2db40e084f459a..cc1c75dc195526 100644 --- a/turbopack/crates/turbopack-image/src/process/mod.rs +++ b/turbopack/crates/turbopack-image/src/process/mod.rs @@ -17,7 +17,7 @@ use image::{ use mime::Mime; use serde::{Deserialize, Serialize}; use serde_with::{serde_as, DisplayFromStr}; -use turbo_tasks::{debug::ValueDebugFormat, trace::TraceRawVcs, Vc}; +use turbo_tasks::{debug::ValueDebugFormat, trace::TraceRawVcs, ResolvedVc, Vc}; use turbo_tasks_fs::{File, FileContent, FileSystemPath}; use turbopack_core::{ error::PrettyPrintError, @@ -170,7 +170,7 @@ fn load_image_internal( .into(), ) .cell(), - title: Some(StyledString::Text("AVIF image not supported".into()).cell()), + title: Some(StyledString::Text("AVIF image not supported".into()).resolved_cell()), issue_severity: Some(IssueSeverity::Warning.into()), } .cell() @@ -188,7 +188,7 @@ fn load_image_internal( .into(), ) .cell(), - title: Some(StyledString::Text("WEBP image not supported".into()).cell()), + title: Some(StyledString::Text("WEBP image not supported".into()).resolved_cell()), issue_severity: Some(IssueSeverity::Warning.into()), } .cell() @@ -479,7 +479,7 @@ pub async fn optimize( struct ImageProcessingIssue { path: Vc, message: Vc, - title: Option>, + title: Option>, issue_severity: Option>, } @@ -502,8 +502,9 @@ impl Issue for ImageProcessingIssue { #[turbo_tasks::function] fn title(&self) -> Vc { - self.title - .unwrap_or(StyledString::Text("Processing image failed".into()).cell()) + *self + .title + .unwrap_or(StyledString::Text("Processing image failed".into()).resolved_cell()) } #[turbo_tasks::function] diff --git a/turbopack/crates/turbopack-node/src/render/node_api_source.rs b/turbopack/crates/turbopack-node/src/render/node_api_source.rs index 6ccbde5786072d..697647353d42ba 100644 --- a/turbopack/crates/turbopack-node/src/render/node_api_source.rs +++ b/turbopack/crates/turbopack-node/src/render/node_api_source.rs @@ -127,30 +127,34 @@ impl GetContentSourceContent for NodeApiContentSource { return Err(anyhow!("Missing request data")); }; let entry = self.entry.entry(data.clone()).await?; - Ok(ContentSourceContent::HttpProxy(render_proxy( - self.cwd, - self.env, - self.server_root.join(path.clone()), - entry.module, - entry.runtime_entries, - entry.chunking_context, - entry.intermediate_output_path, - entry.output_root, - entry.project_dir, - RenderData { - params: params.clone(), - method: method.clone(), - url: url.clone(), - original_url: original_url.clone(), - raw_query: raw_query.clone(), - raw_headers: raw_headers.clone(), - path: format!("/{}", path).into(), - data: Some(self.render_data.await?), - } - .cell(), - *body, - self.debug, - )) + Ok(ContentSourceContent::HttpProxy( + render_proxy( + self.cwd, + self.env, + self.server_root.join(path.clone()), + entry.module, + entry.runtime_entries, + entry.chunking_context, + entry.intermediate_output_path, + entry.output_root, + entry.project_dir, + RenderData { + params: params.clone(), + method: method.clone(), + url: url.clone(), + original_url: original_url.clone(), + raw_query: raw_query.clone(), + raw_headers: raw_headers.clone(), + path: format!("/{}", path).into(), + data: Some(self.render_data.await?), + } + .cell(), + *body, + self.debug, + ) + .to_resolved() + .await?, + ) .cell()) } } diff --git a/turbopack/crates/turbopack-node/src/render/render_static.rs b/turbopack/crates/turbopack-node/src/render/render_static.rs index 5835cd634a90a2..a9053d1c90897e 100644 --- a/turbopack/crates/turbopack-node/src/render/render_static.rs +++ b/turbopack/crates/turbopack-node/src/render/render_static.rs @@ -7,8 +7,8 @@ use futures::{ use parking_lot::Mutex; use serde::{Deserialize, Serialize}; use turbo_tasks::{ - duration_span, mark_finished, prevent_gc, util::SharedError, RawVc, TaskInput, ValueToString, - Vc, + duration_span, mark_finished, prevent_gc, util::SharedError, RawVc, ResolvedVc, TaskInput, + ValueToString, Vc, }; use turbo_tasks_bytes::{Bytes, Stream}; use turbo_tasks_env::ProcessEnv; @@ -46,7 +46,7 @@ pub enum StaticResult { headers: Vc, body: Body, }, - Rewrite(Vc), + Rewrite(ResolvedVc), } #[turbo_tasks::value_impl] @@ -66,7 +66,7 @@ impl StaticResult { } #[turbo_tasks::function] - pub fn rewrite(rewrite: Vc) -> Vc { + pub fn rewrite(rewrite: ResolvedVc) -> Vc { StaticResult::Rewrite(rewrite).cell() } } diff --git a/turbopack/crates/turbopack-node/src/render/rendered_source.rs b/turbopack/crates/turbopack-node/src/render/rendered_source.rs index 723307454d3fd1..b06a13927e356a 100644 --- a/turbopack/crates/turbopack-node/src/render/rendered_source.rs +++ b/turbopack/crates/turbopack-node/src/render/rendered_source.rs @@ -236,10 +236,12 @@ impl GetContentSourceContent for NodeRenderContentSource { headers: headers.await?.clone_value(), body: body.clone(), } - .cell(), + .resolved_cell(), ) .cell(), - StaticResult::Rewrite(rewrite) => ContentSourceContent::Rewrite(rewrite).cell(), + StaticResult::Rewrite(rewrite) => { + ContentSourceContent::Rewrite(rewrite.to_resolved().await?).cell() + } }) } } diff --git a/turbopack/crates/turbopack-node/src/transforms/webpack.rs b/turbopack/crates/turbopack-node/src/transforms/webpack.rs index a3cfdc29afb97d..3e3e829d1f6db7 100644 --- a/turbopack/crates/turbopack-node/src/transforms/webpack.rs +++ b/turbopack/crates/turbopack-node/src/transforms/webpack.rs @@ -7,7 +7,8 @@ use serde::{Deserialize, Serialize}; use serde_json::{json, Value as JsonValue}; use serde_with::serde_as; use turbo_tasks::{ - trace::TraceRawVcs, Completion, RcStr, TaskInput, TryJoinIterExt, Value, ValueToString, Vc, + trace::TraceRawVcs, Completion, RcStr, ResolvedVc, TaskInput, TryJoinIterExt, Value, + ValueToString, Vc, }; use turbo_tasks_bytes::stream::SingleValue; use turbo_tasks_env::ProcessEnv; @@ -229,7 +230,7 @@ impl WebpackLoadersProcessedAsset { context_ident_for_issue: this.source.ident(), asset_context: evaluate_context, chunking_context, - resolve_options_context: Some(transform.resolve_options_context), + resolve_options_context: Some(transform.resolve_options_context.to_resolved().await?), args: vec![ Vc::cell(content.into()), // We need to pass the query string to the loader @@ -380,7 +381,7 @@ pub struct WebpackLoaderContext { pub context_ident_for_issue: Vc, pub asset_context: Vc>, pub chunking_context: Vc>, - pub resolve_options_context: Option>, + pub resolve_options_context: Option>, pub args: Vec>, pub additional_invalidation: Vc, } @@ -498,7 +499,7 @@ impl EvaluateContext for WebpackLoaderContext { }; let lookup_path = self.cwd.join(lookup_path); let request = Request::parse(Value::new(Pattern::Constant(request))); - let options = resolve_options(lookup_path, resolve_options_context); + let options = resolve_options(lookup_path, *resolve_options_context); let options = apply_webpack_resolve_options(options, webpack_options); diff --git a/turbopack/crates/turbopack-resolve/src/ecmascript.rs b/turbopack/crates/turbopack-resolve/src/ecmascript.rs index d33bfc6180e202..141a16b1c71a13 100644 --- a/turbopack/crates/turbopack-resolve/src/ecmascript.rs +++ b/turbopack/crates/turbopack-resolve/src/ecmascript.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use turbo_tasks::{Value, Vc}; +use turbo_tasks::{ResolvedVc, Value, Vc}; use turbopack_core::{ issue::IssueSource, reference_type::{CommonJsReferenceSubType, EcmaScriptModulesReferenceSubType, ReferenceType}, @@ -80,7 +80,7 @@ pub async fn esm_resolve( request: Vc, ty: Value, is_optional: bool, - issue_source: Option>, + issue_source: Option>, ) -> Result> { let ty = Value::new(ReferenceType::EcmaScriptModules(ty.into_value())); let options = apply_esm_specific_options(origin.resolve_options(ty.clone()), ty.clone()) @@ -93,7 +93,7 @@ pub async fn esm_resolve( pub async fn cjs_resolve( origin: Vc>, request: Vc, - issue_source: Option>, + issue_source: Option>, is_optional: bool, ) -> Result> { // TODO pass CommonJsReferenceSubType @@ -106,9 +106,9 @@ pub async fn cjs_resolve( #[turbo_tasks::function] pub async fn cjs_resolve_source( - origin: Vc>, - request: Vc, - issue_source: Option>, + origin: ResolvedVc>, + request: ResolvedVc, + issue_source: Option>, is_optional: bool, ) -> Result> { // TODO pass CommonJsReferenceSubType @@ -119,7 +119,7 @@ pub async fn cjs_resolve_source( let result = resolve( origin.origin_path().parent().resolve().await?, ty.clone(), - request, + *request, options, ); @@ -127,7 +127,7 @@ pub async fn cjs_resolve_source( result, ty, origin.origin_path(), - request, + *request, options, is_optional, issue_source, @@ -141,7 +141,7 @@ async fn specific_resolve( options: Vc, reference_type: Value, is_optional: bool, - issue_source: Option>, + issue_source: Option>, ) -> Result> { let result = origin.resolve_asset(request, options, reference_type.clone()); diff --git a/turbopack/crates/turbopack-resolve/src/resolve.rs b/turbopack/crates/turbopack-resolve/src/resolve.rs index 6056066bd01920..bc80594cab50df 100644 --- a/turbopack/crates/turbopack-resolve/src/resolve.rs +++ b/turbopack/crates/turbopack-resolve/src/resolve.rs @@ -213,14 +213,20 @@ async fn base_resolve_options( extensions, modules: if let Some(environment) = emulating { if *environment.resolve_node_modules().await? { - vec![ResolveModules::Nested(root, vec!["node_modules".into()])] + vec![ResolveModules::Nested( + root.to_resolved().await?, + vec!["node_modules".into()], + )] } else { Vec::new() } } else { let mut mods = Vec::new(); if let Some(dir) = opt.enable_node_modules { - mods.push(ResolveModules::Nested(dir, vec!["node_modules".into()])); + mods.push(ResolveModules::Nested( + dir.to_resolved().await?, + vec!["node_modules".into()], + )); } mods }, diff --git a/turbopack/crates/turbopack-tests/tests/execution.rs b/turbopack/crates/turbopack-tests/tests/execution.rs index 43ce9db5ecd9dd..d31ed600227bc2 100644 --- a/turbopack/crates/turbopack-tests/tests/execution.rs +++ b/turbopack/crates/turbopack-tests/tests/execution.rs @@ -286,7 +286,7 @@ async fn run_test(prepared_test: Vc) -> Result> import_externals: true, ..Default::default() }, - preset_env_versions: Some(env), + preset_env_versions: Some(env.to_resolved().await?), tree_shaking_mode: options.tree_shaking_mode, rules: vec![( ContextCondition::InDirectory("node_modules".into()), diff --git a/turbopack/crates/turbopack-tests/tests/snapshot.rs b/turbopack/crates/turbopack-tests/tests/snapshot.rs index 50ba83a7f424e8..c11ab223ac29b6 100644 --- a/turbopack/crates/turbopack-tests/tests/snapshot.rs +++ b/turbopack/crates/turbopack-tests/tests/snapshot.rs @@ -278,7 +278,7 @@ async fn run_test(resource: RcStr) -> Result> { use_swc_css: options.use_swc_css, ..Default::default() }, - preset_env_versions: Some(env), + preset_env_versions: Some(env.to_resolved().await?), rules: vec![( ContextCondition::InDirectory("node_modules".into()), ModuleOptionsContext { diff --git a/turbopack/crates/turbopack/src/graph/mod.rs b/turbopack/crates/turbopack/src/graph/mod.rs index 2e2d37535db0df..a096cb0f8a0248 100644 --- a/turbopack/crates/turbopack/src/graph/mod.rs +++ b/turbopack/crates/turbopack/src/graph/mod.rs @@ -1,12 +1,12 @@ use std::collections::HashSet; use anyhow::Result; -use turbo_tasks::Vc; +use turbo_tasks::{ResolvedVc, Vc}; use turbopack_core::output::OutputAsset; #[turbo_tasks::value(shared)] pub enum AggregatedGraph { - Leaf(Vc>), + Leaf(ResolvedVc>), Node { depth: usize, content: HashSet>, @@ -17,7 +17,7 @@ pub enum AggregatedGraph { #[turbo_tasks::value_impl] impl AggregatedGraph { #[turbo_tasks::function] - fn leaf(asset: Vc>) -> Vc { + fn leaf(asset: ResolvedVc>) -> Vc { Self::cell(AggregatedGraph::Leaf(asset)) } } @@ -36,7 +36,7 @@ impl AggregatedGraph { #[turbo_tasks::function] pub async fn content(self: Vc) -> Result> { Ok(match *self.await? { - AggregatedGraph::Leaf(asset) => AggregatedGraphNodeContent::Asset(asset).into(), + AggregatedGraph::Leaf(asset) => AggregatedGraphNodeContent::Asset(*asset).into(), AggregatedGraph::Node { ref content, .. } => { AggregatedGraphNodeContent::Children(content.clone()).into() } @@ -50,7 +50,7 @@ impl AggregatedGraph { let mut refs = HashSet::new(); for reference in asset.references().await?.iter() { let reference = reference.resolve().await?; - if asset != reference { + if asset != reference.to_resolved().await? { refs.insert(AggregatedGraph::leaf(reference)); } } diff --git a/turbopack/crates/turbopack/src/lib.rs b/turbopack/crates/turbopack/src/lib.rs index 0c015f84df5567..3dc82e7e63aa1c 100644 --- a/turbopack/crates/turbopack/src/lib.rs +++ b/turbopack/crates/turbopack/src/lib.rs @@ -106,7 +106,7 @@ async fn apply_module_type( module_type: Vc, reference_type: Value, part: Option>, - inner_assets: Option>, + inner_assets: Option>, runtime_code: bool, ) -> Result> { let module_type = &*module_type.await?; diff --git a/turbopack/crates/turbopack/src/module_options/mod.rs b/turbopack/crates/turbopack/src/module_options/mod.rs index cfd5753398de8c..96a515ba8abd70 100644 --- a/turbopack/crates/turbopack/src/module_options/mod.rs +++ b/turbopack/crates/turbopack/src/module_options/mod.rs @@ -140,7 +140,9 @@ impl ModuleOptions { let ecmascript_options_vc = ecmascript_options.cell(); if let Some(env) = preset_env_versions { - transforms.push(EcmascriptInputTransform::PresetEnv(env)); + transforms.push(EcmascriptInputTransform::PresetEnv( + env.to_resolved().await?, + )); } if let Some(enable_typeof_window_inlining) = enable_typeof_window_inlining { @@ -418,13 +420,13 @@ impl ModuleOptions { vec![ModuleRuleEffect::SourceTransforms(Vc::cell(vec![ Vc::upcast(PostCssTransform::new( node_evaluate_asset_context( - execution_context, + *execution_context, Some(import_map), None, "postcss".into(), true, ), - execution_context, + *execution_context, options.config_location, )), ]))], @@ -562,13 +564,13 @@ impl ModuleOptions { vec![ModuleRuleEffect::SourceTransforms(Vc::cell(vec![ Vc::upcast(WebpackLoaders::new( node_evaluate_asset_context( - execution_context, + *execution_context, Some(import_map), None, "webpack_loaders".into(), false, ), - execution_context, + *execution_context, rule.loaders, rule.rename_as.clone(), resolve_options_context, diff --git a/turbopack/crates/turbopack/src/module_options/module_options_context.rs b/turbopack/crates/turbopack/src/module_options/module_options_context.rs index 7cd69e4c39eff8..5c0b8436b9addd 100644 --- a/turbopack/crates/turbopack/src/module_options/module_options_context.rs +++ b/turbopack/crates/turbopack/src/module_options/module_options_context.rs @@ -1,5 +1,5 @@ use serde::{Deserialize, Serialize}; -use turbo_tasks::{trace::TraceRawVcs, FxIndexMap, RcStr, ValueDefault, Vc}; +use turbo_tasks::{trace::TraceRawVcs, FxIndexMap, RcStr, ResolvedVc, ValueDefault, Vc}; use turbopack_core::{ chunk::MinifyType, condition::ContextCondition, environment::Environment, resolve::options::ImportMapping, @@ -119,8 +119,8 @@ pub struct ModuleOptionsContext { pub enable_mdx: bool, pub enable_mdx_rs: Option>, - pub preset_env_versions: Option>, - pub execution_context: Option>, + pub preset_env_versions: Option>, + pub execution_context: Option>, pub side_effect_free_packages: Vec, pub tree_shaking_mode: Option, @@ -142,7 +142,7 @@ pub struct EcmascriptOptionsContext { /// normal resolution. pub enable_types: bool, pub enable_typescript_transform: Option>, - pub enable_decorators: Option>, + pub enable_decorators: Option>, pub esm_url_rewrite_behavior: Option, /// References to externals from ESM imports should use `import()` and make /// async modules. From cfa003c7842eaa73bf3242dfa8bed1cc8732148d Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Wed, 23 Oct 2024 00:31:05 +0200 Subject: [PATCH 10/44] Add --turbopack CLI flag (#71657) 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` --------- Co-authored-by: Will Binns-Smith --- .../next-integration-stat/src/index.ts | 2 +- bench/heavy-npm-deps/package.json | 2 +- crates/napi/src/turbopack.rs | 2 +- crates/next-core/src/mode.rs | 2 +- .../07-configuring/05-mdx.mdx | 2 +- .../11-upgrading/05-from-create-react-app.mdx | 2 +- .../06-cli/create-next-app.mdx | 2 +- docs/02-app/02-api-reference/06-cli/next.mdx | 2 +- docs/04-architecture/turbopack.mdx | 6 ++--- packages/create-next-app/README.md | 2 +- packages/create-next-app/create-app.ts | 6 ++--- packages/create-next-app/index.ts | 22 +++++++++---------- packages/create-next-app/templates/index.ts | 4 ++-- packages/create-next-app/templates/types.ts | 2 +- packages/next-codemod/bin/upgrade.ts | 12 +++++----- packages/next/src/bin/next.ts | 3 ++- packages/next/src/cli/next-dev.ts | 3 ++- .../VersionStalenessInfo.tsx | 2 +- packages/next/src/lib/turbopack-warning.ts | 2 +- packages/next/src/server/config-shared.ts | 8 +++---- packages/next/src/server/lib/app-info-log.ts | 2 +- packages/next/src/server/next.ts | 3 ++- .../acceptance-app/version-staleness.test.ts | 6 ++--- .../integration/create-next-app/index.test.ts | 6 ++--- .../package-manager/bun.test.ts | 4 ++-- .../package-manager/npm.test.ts | 4 ++-- .../package-manager/pnpm.test.ts | 4 ++-- .../package-manager/yarn.test.ts | 4 ++-- .../create-next-app/prompts.test.ts | 8 +++---- .../create-next-app/templates/app.test.ts | 18 +++++++-------- .../create-next-app/templates/matrix.test.ts | 2 +- .../create-next-app/templates/pages.test.ts | 18 +++++++-------- .../turbopack-unsupported-log/index.test.ts | 6 ++--- 33 files changed, 88 insertions(+), 85 deletions(-) diff --git a/.github/actions/next-integration-stat/src/index.ts b/.github/actions/next-integration-stat/src/index.ts index ba7c7eda344380..5b04b29bb5db44 100644 --- a/.github/actions/next-integration-stat/src/index.ts +++ b/.github/actions/next-integration-stat/src/index.ts @@ -735,7 +735,7 @@ const createCommentPostAsync = console.log('Created a new comment', result.data.html_url) } -// An action report failed next.js integration test with --turbo +// An action report failed next.js integration test with --turbopack async function run() { const { token, diff --git a/bench/heavy-npm-deps/package.json b/bench/heavy-npm-deps/package.json index b4c266a4bf9903..30232df4158097 100644 --- a/bench/heavy-npm-deps/package.json +++ b/bench/heavy-npm-deps/package.json @@ -3,7 +3,7 @@ "version": "0.1.0", "private": true, "scripts": { - "dev-turbopack": "next dev --turbo", + "dev-turbopack": "next dev --turbopack", "dev-webpack": "next dev", "build-turbopack": "TURBOPACK=1 TURBOPACK_BUILD=1 next build", "build-webpack": "next build", diff --git a/crates/napi/src/turbopack.rs b/crates/napi/src/turbopack.rs index bff2f71c0b96a5..99ecde69fdd79e 100644 --- a/crates/napi/src/turbopack.rs +++ b/crates/napi/src/turbopack.rs @@ -13,7 +13,7 @@ use crate::next_api::project::NapiDefineEnv; #[napi(object, object_to_js = false)] #[derive(Debug)] pub struct NextBuildContext { - // Added by Next.js for next build --turbo specifically. + // Added by Next.js for next build --turbopack specifically. /// The root directory of the workspace. pub root: Option, diff --git a/crates/next-core/src/mode.rs b/crates/next-core/src/mode.rs index c5a29ef486b1d8..67915d95fb70ee 100644 --- a/crates/next-core/src/mode.rs +++ b/crates/next-core/src/mode.rs @@ -6,7 +6,7 @@ use turbopack_ecmascript_runtime::RuntimeType; #[turbo_tasks::value(shared)] #[derive(Debug, Copy, Clone, TaskInput, Ord, PartialOrd, Hash)] pub enum NextMode { - /// `next dev --turbo` + /// `next dev --turbopack` Development, /// `next build` Build, diff --git a/docs/02-app/01-building-your-application/07-configuring/05-mdx.mdx b/docs/02-app/01-building-your-application/07-configuring/05-mdx.mdx index 18f9ed4d4eee34..551c74cedddb02 100644 --- a/docs/02-app/01-building-your-application/07-configuring/05-mdx.mdx +++ b/docs/02-app/01-building-your-application/07-configuring/05-mdx.mdx @@ -784,7 +784,7 @@ module.exports = withMDX({ > **Good to know**: > -> This option is required when processing markdown and MDX while using [Turbopack](/docs/architecture/turbopack) (`next dev --turbo`). +> This option is required when processing markdown and MDX while using [Turbopack](/docs/architecture/turbopack) (`next dev --turbopack`). ## Helpful Links diff --git a/docs/02-app/01-building-your-application/11-upgrading/05-from-create-react-app.mdx b/docs/02-app/01-building-your-application/11-upgrading/05-from-create-react-app.mdx index d574ae3774acea..41e38fef71bd4a 100644 --- a/docs/02-app/01-building-your-application/11-upgrading/05-from-create-react-app.mdx +++ b/docs/02-app/01-building-your-application/11-upgrading/05-from-create-react-app.mdx @@ -480,7 +480,7 @@ Create React App and Next.js both default to using webpack for bundling. When migrating your CRA application to Next.js, you might have a custom webpack configuration you're looking to migrate. Next.js supports providing a [custom webpack configuration](/docs/app/api-reference/next-config-js/webpack). -Further, Next.js has support for [Turbopack](/docs/app/api-reference/next-config-js/turbo) through `next dev --turbo` to improve your local dev performance. Turbopack supports some [webpack loaders](/docs/app/api-reference/next-config-js/turbo) as well for compatibility and incremental adoption. +Further, Next.js has support for [Turbopack](/docs/app/api-reference/next-config-js/turbo) through `next dev --turbopack` to improve your local dev performance. Turbopack supports some [webpack loaders](/docs/app/api-reference/next-config-js/turbo) as well for compatibility and incremental adoption. ## Next Steps diff --git a/docs/02-app/02-api-reference/06-cli/create-next-app.mdx b/docs/02-app/02-api-reference/06-cli/create-next-app.mdx index dec87bc06a653e..8ba658ab111ae6 100644 --- a/docs/02-app/02-api-reference/06-cli/create-next-app.mdx +++ b/docs/02-app/02-api-reference/06-cli/create-next-app.mdx @@ -28,7 +28,7 @@ The following options are available: | `--eslint` | Initialize with ESLint config | | `--app` | Initialize as an App Router project | | `--src-dir` | Initialize inside a `src/` directory | -| `--turbo` | Enable Turbopack by default for development | +| `--turbopack` | Enable Turbopack by default for development | | `--import-alias ` | Specify import alias to use (default "@/\*") | | `--empty` | Initialize an empty project | | `--use-npm` | Explicitly tell the CLI to bootstrap the application using npm | diff --git a/docs/02-app/02-api-reference/06-cli/next.mdx b/docs/02-app/02-api-reference/06-cli/next.mdx index 23e26ed1f983fe..cf25a2678c9333 100644 --- a/docs/02-app/02-api-reference/06-cli/next.mdx +++ b/docs/02-app/02-api-reference/06-cli/next.mdx @@ -45,7 +45,7 @@ The following commands are available: | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | | `-h, --help` | Show all available options. | | `[directory]` | A directory in which to build the application. If not provided, current directory is used. | -| `--turbo` | Starts development mode using [Turbopack](https://nextjs.org/docs/architecture/turbopack). | +| `--turbopack` | Starts development mode using [Turbopack](https://nextjs.org/docs/architecture/turbopack). | | `-p` or `--port ` | Specify a port number on which to start the application. Default: 3000, env: PORT | | `-H`or `--hostname ` | Specify a hostname on which to start the application. Useful for making the application available for other devices on the network. Default: 0.0.0.0 | | `--experimental-https` | Starts the server with HTTPS and generates a self-signed certificate. | diff --git a/docs/04-architecture/turbopack.mdx b/docs/04-architecture/turbopack.mdx index 7d52e4e92e8635..3ca3f67c1e353e 100644 --- a/docs/04-architecture/turbopack.mdx +++ b/docs/04-architecture/turbopack.mdx @@ -7,12 +7,12 @@ description: Turbopack is an incremental bundler optimized for JavaScript and Ty ## Usage -Turbopack can be used in Next.js in both the `pages` and `app` directories for faster local development. To enable Turbopack, use the `--turbo` flag when running the Next.js development server. +Turbopack can be used in Next.js in both the `pages` and `app` directories for faster local development. To enable Turbopack, use the `--turbopack` flag when running the Next.js development server. ```json filename="package.json" highlight={3} { "scripts": { - "dev": "next dev --turbo", + "dev": "next dev --turbopack", "build": "next build", "start": "next start", "lint": "next lint" @@ -76,6 +76,6 @@ These features are currently not supported: ## Generating Trace Files -Trace files allow the Next.js team to investigate and improve performance metrics and memory usage. To generate a trace file, append `NEXT_TURBOPACK_TRACING=1` to the `next dev --turbo` command, this will generate a `.next/trace.log` file. +Trace files allow the Next.js team to investigate and improve performance metrics and memory usage. To generate a trace file, append `NEXT_TURBOPACK_TRACING=1` to the `next dev --turbopack` command, this will generate a `.next/trace.log` file. When reporting issues related to Turbopack performance and memory usage, please include the trace file in your [GitHub](https://github.com/vercel/next.js) issue. diff --git a/packages/create-next-app/README.md b/packages/create-next-app/README.md index a966c3f44bd41c..d41665a41d570f 100644 --- a/packages/create-next-app/README.md +++ b/packages/create-next-app/README.md @@ -59,7 +59,7 @@ Options: Initialize inside a `src/` directory. - --turbo + --turbopack Enable Turbopack by default for development. diff --git a/packages/create-next-app/create-app.ts b/packages/create-next-app/create-app.ts index 48ecd555cb1c2d..33f0b24105e613 100644 --- a/packages/create-next-app/create-app.ts +++ b/packages/create-next-app/create-app.ts @@ -36,7 +36,7 @@ export async function createApp({ importAlias, skipInstall, empty, - turbo, + turbopack, disableGit, }: { appPath: string @@ -51,7 +51,7 @@ export async function createApp({ importAlias: string skipInstall: boolean empty: boolean - turbo: boolean + turbopack: boolean disableGit?: boolean }): Promise { let repoInfo: RepoInfo | undefined @@ -233,7 +233,7 @@ export async function createApp({ srcDir, importAlias, skipInstall, - turbo, + turbopack, }) } diff --git a/packages/create-next-app/index.ts b/packages/create-next-app/index.ts index bdeb7598d9beeb..013a5bc5cb4726 100644 --- a/packages/create-next-app/index.ts +++ b/packages/create-next-app/index.ts @@ -52,7 +52,7 @@ const program = new Command(packageJson.name) .option('--eslint', 'Initialize with ESLint config.') .option('--app', 'Initialize as an App Router project.') .option('--src-dir', "Initialize inside a 'src/' directory.") - .option('--turbo', 'Enable Turbopack by default for development.') + .option('--turbopack', 'Enable Turbopack by default for development.') .option( '--import-alias ', 'Specify import alias to use (default "@/*").' @@ -233,7 +233,7 @@ async function run(): Promise { importAlias: '@/*', customizeImportAlias: false, empty: false, - turbo: false, + turbopack: false, disableGit: false, } const getPrefOrDefault = (field: string) => @@ -351,22 +351,22 @@ async function run(): Promise { } } - if (!opts.turbo && !args.includes('--no-turbo')) { + if (!opts.turbopack && !args.includes('--no-turbopack')) { if (skipPrompt) { - opts.turbo = getPrefOrDefault('turbo') + opts.turbopack = getPrefOrDefault('turbopack') } else { const styledTurbo = blue('Turbopack') - const { turbo } = await prompts({ + const { turbopack } = await prompts({ onState: onPromptState, type: 'toggle', - name: 'turbo', + name: 'turbopack', message: `Would you like to use ${styledTurbo} for ${`next dev`}?`, - initial: getPrefOrDefault('turbo'), + initial: getPrefOrDefault('turbopack'), active: 'Yes', inactive: 'No', }) - opts.turbo = Boolean(turbo) - preferences.turbo = Boolean(turbo) + opts.turbopack = Boolean(turbopack) + preferences.turbopack = Boolean(turbopack) } } @@ -429,7 +429,7 @@ async function run(): Promise { importAlias: opts.importAlias, skipInstall: opts.skipInstall, empty: opts.empty, - turbo: opts.turbo, + turbopack: opts.turbopack, disableGit: opts.disableGit, }) } catch (reason) { @@ -461,7 +461,7 @@ async function run(): Promise { importAlias: opts.importAlias, skipInstall: opts.skipInstall, empty: opts.empty, - turbo: opts.turbo, + turbopack: opts.turbopack, disableGit: opts.disableGit, }) } diff --git a/packages/create-next-app/templates/index.ts b/packages/create-next-app/templates/index.ts index b9b00901c7afcb..5aba2dbd14464d 100644 --- a/packages/create-next-app/templates/index.ts +++ b/packages/create-next-app/templates/index.ts @@ -43,7 +43,7 @@ export const installTemplate = async ({ srcDir, importAlias, skipInstall, - turbo, + turbopack, }: InstallTemplateArgs) => { console.log(bold(`Using ${packageManager}.`)); @@ -188,7 +188,7 @@ export const installTemplate = async ({ version: "0.1.0", private: true, scripts: { - dev: `next dev${turbo ? " --turbo" : ""}`, + dev: `next dev${turbopack ? " --turbopack" : ""}`, build: "next build", start: "next start", lint: "next lint", diff --git a/packages/create-next-app/templates/types.ts b/packages/create-next-app/templates/types.ts index 1837495ab8a08d..2e6a0b0ff84723 100644 --- a/packages/create-next-app/templates/types.ts +++ b/packages/create-next-app/templates/types.ts @@ -29,5 +29,5 @@ export interface InstallTemplateArgs { srcDir: boolean; importAlias: string; skipInstall: boolean; - turbo: boolean; + turbopack: boolean; } diff --git a/packages/next-codemod/bin/upgrade.ts b/packages/next-codemod/bin/upgrade.ts index 36dc28ce548820..dc2f7f31638037 100644 --- a/packages/next-codemod/bin/upgrade.ts +++ b/packages/next-codemod/bin/upgrade.ts @@ -403,16 +403,16 @@ function isUsingAppDir(projectPath: string): boolean { * Heuristics are used to determine whether to Turbopack is enabled or not and * to determine how to update the dev script. * - * 1. If the dev script contains `--turbo` option, we assume that Turbopack is + * 1. If the dev script contains `--turbopack` option, we assume that Turbopack is * already enabled. * 2. If the dev script contains the string `next dev`, we replace it to - * `next dev --turbo`. - * 3. Otherwise, we ask the user to manually add `--turbo` to their dev command, + * `next dev --turbopack`. + * 3. Otherwise, we ask the user to manually add `--turbopack` to their dev command, * showing the current dev command as the initial value. */ async function suggestTurbopack(packageJson: any): Promise { const devScript: string = packageJson.scripts['dev'] - if (devScript.includes('--turbo')) return + if (devScript.includes('--turbopack')) return const responseTurbopack = await prompts( { @@ -431,7 +431,7 @@ async function suggestTurbopack(packageJson: any): Promise { if (devScript.includes('next dev')) { packageJson.scripts['dev'] = devScript.replace( 'next dev', - 'next dev --turbo' + 'next dev --turbopack' ) return } @@ -444,7 +444,7 @@ async function suggestTurbopack(packageJson: any): Promise { { type: 'text', name: 'customDevScript', - message: 'Please manually add "--turbo" to your dev command.', + message: 'Please manually add "--turbopack" to your dev command.', initial: devScript, }, { onCancel } diff --git a/packages/next/src/bin/next.ts b/packages/next/src/bin/next.ts index 0711197a56b5cd..56a864f4cc5fde 100755 --- a/packages/next/src/bin/next.ts +++ b/packages/next/src/bin/next.ts @@ -157,7 +157,8 @@ program 'If no directory is provided, the current directory will be used.' )}` ) - .option('--turbo', 'Starts development mode using Turbopack (beta).') + .option('--turbo', 'Starts development mode using Turbopack.') + .option('--turbopack', 'Starts development mode using Turbopack.') .addOption( new Option( '-p, --port ', diff --git a/packages/next/src/cli/next-dev.ts b/packages/next/src/cli/next-dev.ts index f66e539e47b639..ee58538022cfe3 100644 --- a/packages/next/src/cli/next-dev.ts +++ b/packages/next/src/cli/next-dev.ts @@ -40,6 +40,7 @@ import { flushAllTraces, trace } from '../trace' export type NextDevOptions = { turbo?: boolean + turbopack?: boolean port: number hostname?: string experimentalHttps?: boolean @@ -232,7 +233,7 @@ const nextDev = async ( hostname: host, } - if (options.turbo) { + if (options.turbo || options.turbopack) { process.env.TURBOPACK = '1' } diff --git a/packages/next/src/client/components/react-dev-overlay/internal/components/VersionStalenessInfo/VersionStalenessInfo.tsx b/packages/next/src/client/components/react-dev-overlay/internal/components/VersionStalenessInfo/VersionStalenessInfo.tsx index c6d90b16245fa7..7287998e51814e 100644 --- a/packages/next/src/client/components/react-dev-overlay/internal/components/VersionStalenessInfo/VersionStalenessInfo.tsx +++ b/packages/next/src/client/components/react-dev-overlay/internal/components/VersionStalenessInfo/VersionStalenessInfo.tsx @@ -28,7 +28,7 @@ export function VersionStalenessInfo({ (learn more) )} - {process.env.TURBOPACK ? ' (turbo)' : ''} + {process.env.TURBOPACK ? ' (Turbopack)' : ''} ) } diff --git a/packages/next/src/lib/turbopack-warning.ts b/packages/next/src/lib/turbopack-warning.ts index b43bb004dda272..4813cd19387529 100644 --- a/packages/next/src/lib/turbopack-warning.ts +++ b/packages/next/src/lib/turbopack-warning.ts @@ -47,7 +47,7 @@ const unsupportedTurbopackNextConfigOptions = [ 'experimental.urlImports', ] -// The following will need to be supported by `next build --turbo` +// The following will need to be supported by `next build --turbopack` const unsupportedProductionSpecificTurbopackNextConfigOptions: string[] = [ // TODO: Support disabling sourcemaps, currently they're always enabled. // 'productionBrowserSourceMaps', diff --git a/packages/next/src/server/config-shared.ts b/packages/next/src/server/config-shared.ts index 8a2810c2f6302c..13a0daec70e24f 100644 --- a/packages/next/src/server/config-shared.ts +++ b/packages/next/src/server/config-shared.ts @@ -115,7 +115,7 @@ export type TurboRuleConfigItem = export interface ExperimentalTurboOptions { /** - * (`next --turbo` only) A mapping of aliased imports to modules to load in their place. + * (`next --turbopack` only) A mapping of aliased imports to modules to load in their place. * * @see [Resolve Alias](https://nextjs.org/docs/app/api-reference/next-config-js/turbo#resolve-alias) */ @@ -125,21 +125,21 @@ export interface ExperimentalTurboOptions { > /** - * (`next --turbo` only) A list of extensions to resolve when importing files. + * (`next --turbopack` only) A list of extensions to resolve when importing files. * * @see [Resolve Extensions](https://nextjs.org/docs/app/api-reference/next-config-js/turbo#resolve-extensions) */ resolveExtensions?: string[] /** - * (`next --turbo` only) A list of webpack loaders to apply when running with Turbopack. + * (`next --turbopack` only) A list of webpack loaders to apply when running with Turbopack. * * @see [Turbopack Loaders](https://nextjs.org/docs/app/api-reference/next-config-js/turbo#webpack-loaders) */ loaders?: Record /** - * (`next --turbo` only) A list of webpack loaders to apply when running with Turbopack. + * (`next --turbopack` only) A list of webpack loaders to apply when running with Turbopack. * * @see [Turbopack Loaders](https://nextjs.org/docs/app/api-reference/next-config-js/turbo#webpack-loaders) */ diff --git a/packages/next/src/server/lib/app-info-log.ts b/packages/next/src/server/lib/app-info-log.ts index cd8858447009c6..fb94929350644c 100644 --- a/packages/next/src/server/lib/app-info-log.ts +++ b/packages/next/src/server/lib/app-info-log.ts @@ -23,7 +23,7 @@ export function logStartInfo({ Log.bootstrap( `${bold( purple(`${Log.prefixes.ready} Next.js ${process.env.__NEXT_VERSION}`) - )}${process.env.TURBOPACK ? ' (turbo)' : ''}` + )}${process.env.TURBOPACK ? ' (Turbopack)' : ''}` ) if (appUrl) { Log.bootstrap(`- Local: ${appUrl}`) diff --git a/packages/next/src/server/next.ts b/packages/next/src/server/next.ts index 7ebfef9dfa1c40..ed57c8f34fb040 100644 --- a/packages/next/src/server/next.ts +++ b/packages/next/src/server/next.ts @@ -354,9 +354,10 @@ class NextCustomServer extends NextServer { function createServer( options: NextServerOptions & { turbo?: boolean + turbopack?: boolean } ): NextServer { - if (options && options.turbo) { + if (options && (options.turbo || options.turbopack)) { process.env.TURBOPACK = '1' } // The package is used as a TypeScript plugin. diff --git a/test/development/acceptance-app/version-staleness.test.ts b/test/development/acceptance-app/version-staleness.test.ts index c2d5f272c87b3a..844ca1f17d42bf 100644 --- a/test/development/acceptance-app/version-staleness.test.ts +++ b/test/development/acceptance-app/version-staleness.test.ts @@ -49,7 +49,7 @@ describe('Error Overlay version staleness', () => { if (process.env.TURBOPACK) { expect(await getStaleness(browser)).toMatchInlineSnapshot( - `"Next.js (1.0.0) is outdated (learn more) (turbo)"` + `"Next.js (1.0.0) is outdated (learn more) (Turbopack)"` ) } else { expect(await getStaleness(browser)).toMatchInlineSnapshot( @@ -86,7 +86,7 @@ describe('Error Overlay version staleness', () => { if (process.env.TURBOPACK) { expect(await getStaleness(browser)).toMatchInlineSnapshot( - `"Next.js (2.0.0) is outdated (learn more) (turbo)"` + `"Next.js (2.0.0) is outdated (learn more) (Turbopack)"` ) } else { expect(await getStaleness(browser)).toMatchInlineSnapshot( @@ -120,7 +120,7 @@ describe('Error Overlay version staleness', () => { if (process.env.TURBOPACK) { expect(await getStaleness(browser)).toMatchInlineSnapshot( - `"Next.js (3.0.0) is outdated (learn more) (turbo)"` + `"Next.js (3.0.0) is outdated (learn more) (Turbopack)"` ) } else { expect(await getStaleness(browser)).toMatchInlineSnapshot( diff --git a/test/integration/create-next-app/index.test.ts b/test/integration/create-next-app/index.test.ts index ee0cad947fd281..1495f3a38d7073 100644 --- a/test/integration/create-next-app/index.test.ts +++ b/test/integration/create-next-app/index.test.ts @@ -34,7 +34,7 @@ describe('create-next-app', () => { projectName, '--ts', '--app', - '--no-turbo', + '--no-turbopack', '--no-eslint', '--no-tailwind', '--no-src-dir', @@ -75,7 +75,7 @@ describe('create-next-app', () => { projectName, '--ts', '--app', - '--no-turbo', + '--no-turbopack', '--eslint', '--no-tailwind', '--no-src-dir', @@ -105,7 +105,7 @@ describe('create-next-app', () => { projectName, '--ts', '--app', - '--no-turbo', + '--no-turbopack', '--no-eslint', '--no-tailwind', '--no-src-dir', diff --git a/test/integration/create-next-app/package-manager/bun.test.ts b/test/integration/create-next-app/package-manager/bun.test.ts index 5a0fbba552b3dc..d3a682d6fd9554 100644 --- a/test/integration/create-next-app/package-manager/bun.test.ts +++ b/test/integration/create-next-app/package-manager/bun.test.ts @@ -38,7 +38,7 @@ describe('create-next-app with package manager bun', () => { '--ts', '--app', '--use-bun', - '--no-turbo', + '--no-turbopack', '--no-eslint', '--no-src-dir', '--no-tailwind', @@ -67,7 +67,7 @@ describe('create-next-app with package manager bun', () => { projectName, '--ts', '--app', - '--no-turbo', + '--no-turbopack', '--no-eslint', '--no-src-dir', '--no-tailwind', diff --git a/test/integration/create-next-app/package-manager/npm.test.ts b/test/integration/create-next-app/package-manager/npm.test.ts index c1148da09ed2b0..14b08201d0a658 100644 --- a/test/integration/create-next-app/package-manager/npm.test.ts +++ b/test/integration/create-next-app/package-manager/npm.test.ts @@ -33,7 +33,7 @@ describe('create-next-app with package manager npm', () => { '--ts', '--app', '--use-npm', - '--no-turbo', + '--no-turbopack', '--no-eslint', '--no-src-dir', '--no-tailwind', @@ -62,7 +62,7 @@ describe('create-next-app with package manager npm', () => { projectName, '--ts', '--app', - '--no-turbo', + '--no-turbopack', '--no-eslint', '--no-src-dir', '--no-tailwind', diff --git a/test/integration/create-next-app/package-manager/pnpm.test.ts b/test/integration/create-next-app/package-manager/pnpm.test.ts index 6d59f84adc3af7..5ac5889be0bbcd 100644 --- a/test/integration/create-next-app/package-manager/pnpm.test.ts +++ b/test/integration/create-next-app/package-manager/pnpm.test.ts @@ -33,7 +33,7 @@ describe('create-next-app with package manager pnpm', () => { '--ts', '--app', '--use-pnpm', - '--no-turbo', + '--no-turbopack', '--no-eslint', '--no-src-dir', '--no-tailwind', @@ -62,7 +62,7 @@ describe('create-next-app with package manager pnpm', () => { projectName, '--ts', '--app', - '--no-turbo', + '--no-turbopack', '--no-eslint', '--no-src-dir', '--no-tailwind', diff --git a/test/integration/create-next-app/package-manager/yarn.test.ts b/test/integration/create-next-app/package-manager/yarn.test.ts index 0e39d1f019dfb2..4a034db66b63d6 100644 --- a/test/integration/create-next-app/package-manager/yarn.test.ts +++ b/test/integration/create-next-app/package-manager/yarn.test.ts @@ -41,7 +41,7 @@ describe('create-next-app with package manager yarn', () => { '--ts', '--app', '--use-yarn', - '--no-turbo', + '--no-turbopack', '--no-eslint', '--no-src-dir', '--no-tailwind', @@ -70,7 +70,7 @@ describe('create-next-app with package manager yarn', () => { projectName, '--ts', '--app', - '--no-turbo', + '--no-turbopack', '--no-eslint', '--no-src-dir', '--no-tailwind', diff --git a/test/integration/create-next-app/prompts.test.ts b/test/integration/create-next-app/prompts.test.ts index ee8f4628d6a358..2facdfe59ae7ab 100644 --- a/test/integration/create-next-app/prompts.test.ts +++ b/test/integration/create-next-app/prompts.test.ts @@ -25,7 +25,7 @@ describe('create-next-app prompts', () => { '--ts', '--app', '--eslint', - '--no-turbo', + '--no-turbopack', '--no-src-dir', '--no-tailwind', '--no-import-alias', @@ -64,7 +64,7 @@ describe('create-next-app prompts', () => { projectName, '--app', '--eslint', - '--no-turbo', + '--no-turbopack', '--no-tailwind', '--no-src-dir', '--no-import-alias', @@ -101,7 +101,7 @@ describe('create-next-app prompts', () => { '--ts', '--app', '--eslint', - '--no-turbo', + '--no-turbopack', '--no-src-dir', '--no-import-alias', ], @@ -137,7 +137,7 @@ describe('create-next-app prompts', () => { '--ts', '--app', '--eslint', - '--no-turbo', + '--no-turbopack', '--no-tailwind', '--no-src-dir', ], diff --git a/test/integration/create-next-app/templates/app.test.ts b/test/integration/create-next-app/templates/app.test.ts index 2222a3208d952f..317472fd8744e1 100644 --- a/test/integration/create-next-app/templates/app.test.ts +++ b/test/integration/create-next-app/templates/app.test.ts @@ -30,7 +30,7 @@ describe('create-next-app --app (App Router)', () => { projectName, '--js', '--app', - '--no-turbo', + '--no-turbopack', '--eslint', '--no-src-dir', '--no-tailwind', @@ -59,7 +59,7 @@ describe('create-next-app --app (App Router)', () => { projectName, '--ts', '--app', - '--no-turbo', + '--no-turbopack', '--eslint', '--no-src-dir', '--no-tailwind', @@ -86,7 +86,7 @@ describe('create-next-app --app (App Router)', () => { projectName, '--ts', '--app', - '--no-turbo', + '--no-turbopack', '--eslint', '--src-dir', '--no-tailwind', @@ -122,7 +122,7 @@ describe('create-next-app --app (App Router)', () => { projectName, '--ts', '--app', - '--no-turbo', + '--no-turbopack', '--eslint', '--src-dir', '--tailwind', @@ -157,7 +157,7 @@ describe('create-next-app --app (App Router)', () => { projectName, '--ts', '--app', - '--no-turbo', + '--no-turbopack', '--eslint', '--src-dir', '--empty', @@ -195,7 +195,7 @@ describe('create-next-app --app (App Router)', () => { projectName, '--ts', '--app', - '--no-turbo', + '--no-turbopack', '--eslint', '--src-dir', '--tailwind', @@ -225,7 +225,7 @@ describe('create-next-app --app (App Router)', () => { }) }) - it('should enable turbopack dev with --turbo flag', async () => { + it('should enable turbopack dev with --turbopack flag', async () => { await useTempDir(async (cwd) => { const projectName = 'app-turbo' const { exitCode } = await run( @@ -234,7 +234,7 @@ describe('create-next-app --app (App Router)', () => { '--ts', '--app', '--eslint', - '--turbo', + '--turbopack', '--no-src-dir', '--no-tailwind', '--no-import-alias', @@ -248,7 +248,7 @@ describe('create-next-app --app (App Router)', () => { expect(exitCode).toBe(0) const projectRoot = join(cwd, projectName) const pkgJson = require(join(projectRoot, 'package.json')) - expect(pkgJson.scripts.dev).toBe('next dev --turbo') + expect(pkgJson.scripts.dev).toBe('next dev --turbopack') }) }) }) diff --git a/test/integration/create-next-app/templates/matrix.test.ts b/test/integration/create-next-app/templates/matrix.test.ts index c5965debb21c1a..1f9ea8c60e36a9 100644 --- a/test/integration/create-next-app/templates/matrix.test.ts +++ b/test/integration/create-next-app/templates/matrix.test.ts @@ -21,7 +21,7 @@ describe.each(['app', 'pages'] as const)( const allFlagValues = { app: [isApp ? '--app' : '--no-app'], - turbo: [process.env.TURBOPACK ? '--turbo' : '--no-turbo'], + turbo: [process.env.TURBOPACK ? '--turbopack' : '--no-turbopack'], ts: ['--js', '--ts'], importAlias: [ diff --git a/test/integration/create-next-app/templates/pages.test.ts b/test/integration/create-next-app/templates/pages.test.ts index 14114efaf99d6b..c7afcb5d452e10 100644 --- a/test/integration/create-next-app/templates/pages.test.ts +++ b/test/integration/create-next-app/templates/pages.test.ts @@ -30,7 +30,7 @@ describe('create-next-app --no-app (Pages Router)', () => { projectName, '--js', '--no-app', - '--no-turbo', + '--no-turbopack', '--eslint', '--no-src-dir', '--no-tailwind', @@ -64,7 +64,7 @@ describe('create-next-app --no-app (Pages Router)', () => { projectName, '--ts', '--no-app', - '--no-turbo', + '--no-turbopack', '--eslint', '--no-src-dir', '--no-tailwind', @@ -95,7 +95,7 @@ describe('create-next-app --no-app (Pages Router)', () => { projectName, '--ts', '--no-app', - '--no-turbo', + '--no-turbopack', '--eslint', '--src-dir', '--no-tailwind', @@ -130,7 +130,7 @@ describe('create-next-app --no-app (Pages Router)', () => { projectName, '--ts', '--no-app', - '--no-turbo', + '--no-turbopack', '--eslint', '--src-dir', '--tailwind', @@ -166,7 +166,7 @@ describe('create-next-app --no-app (Pages Router)', () => { projectName, '--ts', '--no-app', - '--no-turbo', + '--no-turbopack', '--eslint', '--src-dir', '--no-tailwind', @@ -205,7 +205,7 @@ describe('create-next-app --no-app (Pages Router)', () => { projectName, '--ts', '--no-app', - '--no-turbo', + '--no-turbopack', '--eslint', '--src-dir', '--tailwind', @@ -236,7 +236,7 @@ describe('create-next-app --no-app (Pages Router)', () => { }) }) - it('should enable turbopack dev with --turbo flag', async () => { + it('should enable turbopack dev with --turbopack flag', async () => { await useTempDir(async (cwd) => { const projectName = 'pages-turbo' const { exitCode } = await run( @@ -245,7 +245,7 @@ describe('create-next-app --no-app (Pages Router)', () => { '--ts', '--no-app', '--eslint', - '--turbo', + '--turbopack', '--no-src-dir', '--no-tailwind', '--no-import-alias', @@ -259,7 +259,7 @@ describe('create-next-app --no-app (Pages Router)', () => { expect(exitCode).toBe(0) const projectRoot = join(cwd, projectName) const pkgJson = require(join(projectRoot, 'package.json')) - expect(pkgJson.scripts.dev).toBe('next dev --turbo') + expect(pkgJson.scripts.dev).toBe('next dev --turbopack') }) }) }) diff --git a/test/integration/turbopack-unsupported-log/index.test.ts b/test/integration/turbopack-unsupported-log/index.test.ts index 5824a68f4ad25f..ddadf0d86c0bda 100644 --- a/test/integration/turbopack-unsupported-log/index.test.ts +++ b/test/integration/turbopack-unsupported-log/index.test.ts @@ -26,7 +26,7 @@ describe('turbopack unsupported features log', () => { try { expect(await renderViaHTTP(appPort, '/')).toContain('hello world') - expect(output).toContain('(turbo)') + expect(output).toContain('(Turbopack)') expect(output).not.toContain( 'You are using configuration and/or tools that are not yet' ) @@ -50,7 +50,7 @@ describe('turbopack unsupported features log', () => { }) try { - expect(output).toContain('(turbo)') + expect(output).toContain('(Turbopack)') expect(output).not.toContain( 'You are using configuration and/or tools that are not yet' ) @@ -84,7 +84,7 @@ describe('turbopack unsupported features log', () => { try { await check(() => { - expect(output).toContain('(turbo)') + expect(output).toContain('(Turbopack)') expect(output).toContain( 'You are using configuration and/or tools that are not yet' ) From a7a7b19aec34a221fce96f33c808c0c0675fd63e Mon Sep 17 00:00:00 2001 From: Josh Story Date: Tue, 22 Oct 2024 16:12:54 -0700 Subject: [PATCH 11/44] [dynamicIO] detect metadata boundaries in dev using server component stacks (#71666) Component stacks in dev are sourcemapped and currently there is a bug that prevents the right function name from showing up which interrupts our ability to detect incomplete metadata in dev --- packages/next/src/lib/metadata/metadata.tsx | 6 ++++++ .../next/src/server/app-render/create-component-tree.tsx | 2 ++ 2 files changed, 8 insertions(+) diff --git a/packages/next/src/lib/metadata/metadata.tsx b/packages/next/src/lib/metadata/metadata.tsx index 91f6f7875b589c..a3f755c1036b77 100644 --- a/packages/next/src/lib/metadata/metadata.tsx +++ b/packages/next/src/lib/metadata/metadata.tsx @@ -33,6 +33,10 @@ import type { import { isNotFoundError } from '../../client/components/not-found' import type { MetadataContext } from './types/resolvers' import type { WorkStore } from '../../server/app-render/work-async-storage.external' +import { + METADATA_BOUNDARY_NAME, + VIEWPORT_BOUNDARY_NAME, +} from './metadata-constants' // Use a promise to share the status of the metadata resolving, // returning two components `MetadataTree` and `MetadataOutlet` @@ -110,6 +114,7 @@ export function createMetadataComponents({ return null } } + Viewport.displayName = VIEWPORT_BOUNDARY_NAME async function metadata() { return getResolvedMetadata( @@ -146,6 +151,7 @@ export function createMetadataComponents({ return null } } + Metadata.displayName = METADATA_BOUNDARY_NAME async function getMetadataAndViewportReady(): Promise { await viewport() diff --git a/packages/next/src/server/app-render/create-component-tree.tsx b/packages/next/src/server/app-render/create-component-tree.tsx index b6714cccc9d915..d355c052a0a369 100644 --- a/packages/next/src/server/app-render/create-component-tree.tsx +++ b/packages/next/src/server/app-render/create-component-tree.tsx @@ -21,6 +21,7 @@ import { StaticGenBailoutError } from '../../client/components/static-generation import type { LoadingModuleData } from '../../shared/lib/app-router-context.shared-runtime' import type { Params } from '../request/params' import { workUnitAsyncStorage } from './work-unit-async-storage.external' +import { OUTLET_BOUNDARY_NAME } from '../../lib/metadata/metadata-constants' /** * Use the provided loader tree to create the React Component tree. @@ -736,3 +737,4 @@ async function MetadataOutlet({ } return null } +MetadataOutlet.displayName = OUTLET_BOUNDARY_NAME From b075951c68192239a98e05f225bff042fe22e43d Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Tue, 22 Oct 2024 23:24:16 +0000 Subject: [PATCH 12/44] v15.0.1-canary.3 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 17 files changed, 32 insertions(+), 32 deletions(-) diff --git a/lerna.json b/lerna.json index 537ea00c62ff87..98eaa81d9f72ef 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "15.0.1-canary.2" + "version": "15.0.1-canary.3" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 0ba76039ac00b5..4d946ade872cd4 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "15.0.1-canary.2", + "version": "15.0.1-canary.3", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 064cdacf563ca1..4d58da91bcbf78 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "15.0.1-canary.2", + "version": "15.0.1-canary.3", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "15.0.1-canary.2", + "@next/eslint-plugin-next": "15.0.1-canary.3", "@rushstack/eslint-patch": "^1.10.3", "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 1ac79088e97ef0..fe13b06cabba8b 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "15.0.1-canary.2", + "version": "15.0.1-canary.3", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index b397fe0e273dde..30ab2e10245a36 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,7 +1,7 @@ { "name": "@next/font", "private": true, - "version": "15.0.1-canary.2", + "version": "15.0.1-canary.3", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 8526a8fb194e7f..3d7dc7b8642ebe 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "15.0.1-canary.2", + "version": "15.0.1-canary.3", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 1c6c39e4b062dd..02f560cabdcbcb 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "15.0.1-canary.2", + "version": "15.0.1-canary.3", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 4e5d81d4f50564..0fb72b89524dfd 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "15.0.1-canary.2", + "version": "15.0.1-canary.3", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index b7eacbb13147c2..c6d798160501a5 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "15.0.1-canary.2", + "version": "15.0.1-canary.3", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index c2fbc1d221dc3e..da36436536da0f 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "15.0.1-canary.2", + "version": "15.0.1-canary.3", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index e690d839ae1071..7eee7ece44906a 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "15.0.1-canary.2", + "version": "15.0.1-canary.3", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index edf286fbff2fae..c41c3c5ab4b526 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "15.0.1-canary.2", + "version": "15.0.1-canary.3", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index f54d9f9ac7d912..442bad6ce1fdb6 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "15.0.1-canary.2", + "version": "15.0.1-canary.3", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 307400d05cf259..2825430f0992c5 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "15.0.1-canary.2", + "version": "15.0.1-canary.3", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -95,7 +95,7 @@ ] }, "dependencies": { - "@next/env": "15.0.1-canary.2", + "@next/env": "15.0.1-canary.3", "@swc/counter": "0.1.3", "@swc/helpers": "0.5.13", "busboy": "1.6.0", @@ -159,11 +159,11 @@ "@jest/types": "29.5.0", "@mswjs/interceptors": "0.23.0", "@napi-rs/triples": "1.2.0", - "@next/font": "15.0.1-canary.2", - "@next/polyfill-module": "15.0.1-canary.2", - "@next/polyfill-nomodule": "15.0.1-canary.2", - "@next/react-refresh-utils": "15.0.1-canary.2", - "@next/swc": "15.0.1-canary.2", + "@next/font": "15.0.1-canary.3", + "@next/polyfill-module": "15.0.1-canary.3", + "@next/polyfill-nomodule": "15.0.1-canary.3", + "@next/react-refresh-utils": "15.0.1-canary.3", + "@next/swc": "15.0.1-canary.3", "@opentelemetry/api": "1.6.0", "@playwright/test": "1.41.2", "@swc/core": "1.7.0-nightly-20240714.1", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 8caf726a445b9d..758af23e5450a8 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "15.0.1-canary.2", + "version": "15.0.1-canary.3", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 255011650ded46..337607191e033b 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "15.0.1-canary.2", + "version": "15.0.1-canary.3", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -26,7 +26,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "15.0.1-canary.2", + "next": "15.0.1-canary.3", "outdent": "0.8.0", "prettier": "2.5.1", "typescript": "5.5.3" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4ee5c8f4ce604f..0c6e5d04ab2570 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -795,7 +795,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 15.0.1-canary.2 + specifier: 15.0.1-canary.3 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.10.3 @@ -859,7 +859,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 15.0.1-canary.2 + specifier: 15.0.1-canary.3 version: link:../next-env '@swc/counter': specifier: 0.1.3 @@ -987,19 +987,19 @@ importers: specifier: 1.2.0 version: 1.2.0 '@next/font': - specifier: 15.0.1-canary.2 + specifier: 15.0.1-canary.3 version: link:../font '@next/polyfill-module': - specifier: 15.0.1-canary.2 + specifier: 15.0.1-canary.3 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 15.0.1-canary.2 + specifier: 15.0.1-canary.3 version: link:../next-polyfill-nomodule '@next/react-refresh-utils': - specifier: 15.0.1-canary.2 + specifier: 15.0.1-canary.3 version: link:../react-refresh-utils '@next/swc': - specifier: 15.0.1-canary.2 + specifier: 15.0.1-canary.3 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1633,7 +1633,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 15.0.1-canary.2 + specifier: 15.0.1-canary.3 version: link:../next outdent: specifier: 0.8.0 From 914d0f3c4a66153bef916939df3c516567544df6 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Wed, 23 Oct 2024 00:06:45 +0000 Subject: [PATCH 13/44] v15.0.1 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 17 files changed, 32 insertions(+), 32 deletions(-) diff --git a/lerna.json b/lerna.json index 98eaa81d9f72ef..84541a6dd61515 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "15.0.1-canary.3" + "version": "15.0.1" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 4d946ade872cd4..d6bf6896784e36 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "15.0.1-canary.3", + "version": "15.0.1", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 4d58da91bcbf78..3b44f714949cd9 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "15.0.1-canary.3", + "version": "15.0.1", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "15.0.1-canary.3", + "@next/eslint-plugin-next": "15.0.1", "@rushstack/eslint-patch": "^1.10.3", "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index fe13b06cabba8b..3f5d615b045c62 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "15.0.1-canary.3", + "version": "15.0.1", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 30ab2e10245a36..20061d0e29a9d6 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,7 +1,7 @@ { "name": "@next/font", "private": true, - "version": "15.0.1-canary.3", + "version": "15.0.1", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 3d7dc7b8642ebe..aa6317f6c3019a 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "15.0.1-canary.3", + "version": "15.0.1", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 02f560cabdcbcb..37efac64f58f03 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "15.0.1-canary.3", + "version": "15.0.1", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 0fb72b89524dfd..f14fce094436ec 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "15.0.1-canary.3", + "version": "15.0.1", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index c6d798160501a5..f79bc489e94ae2 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "15.0.1-canary.3", + "version": "15.0.1", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index da36436536da0f..8390b76e7c8f50 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "15.0.1-canary.3", + "version": "15.0.1", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 7eee7ece44906a..03ce725713a641 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "15.0.1-canary.3", + "version": "15.0.1", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index c41c3c5ab4b526..fd57c20497de0f 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "15.0.1-canary.3", + "version": "15.0.1", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 442bad6ce1fdb6..4aa3897d79bc6b 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "15.0.1-canary.3", + "version": "15.0.1", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 2825430f0992c5..550ef8b3d43897 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "15.0.1-canary.3", + "version": "15.0.1", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -95,7 +95,7 @@ ] }, "dependencies": { - "@next/env": "15.0.1-canary.3", + "@next/env": "15.0.1", "@swc/counter": "0.1.3", "@swc/helpers": "0.5.13", "busboy": "1.6.0", @@ -159,11 +159,11 @@ "@jest/types": "29.5.0", "@mswjs/interceptors": "0.23.0", "@napi-rs/triples": "1.2.0", - "@next/font": "15.0.1-canary.3", - "@next/polyfill-module": "15.0.1-canary.3", - "@next/polyfill-nomodule": "15.0.1-canary.3", - "@next/react-refresh-utils": "15.0.1-canary.3", - "@next/swc": "15.0.1-canary.3", + "@next/font": "15.0.1", + "@next/polyfill-module": "15.0.1", + "@next/polyfill-nomodule": "15.0.1", + "@next/react-refresh-utils": "15.0.1", + "@next/swc": "15.0.1", "@opentelemetry/api": "1.6.0", "@playwright/test": "1.41.2", "@swc/core": "1.7.0-nightly-20240714.1", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 758af23e5450a8..87fe26321e6767 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "15.0.1-canary.3", + "version": "15.0.1", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 337607191e033b..fc748fe063e3a1 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "15.0.1-canary.3", + "version": "15.0.1", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -26,7 +26,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "15.0.1-canary.3", + "next": "15.0.1", "outdent": "0.8.0", "prettier": "2.5.1", "typescript": "5.5.3" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0c6e5d04ab2570..e5b4f92af874d4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -795,7 +795,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 15.0.1-canary.3 + specifier: 15.0.1 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.10.3 @@ -859,7 +859,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 15.0.1-canary.3 + specifier: 15.0.1 version: link:../next-env '@swc/counter': specifier: 0.1.3 @@ -987,19 +987,19 @@ importers: specifier: 1.2.0 version: 1.2.0 '@next/font': - specifier: 15.0.1-canary.3 + specifier: 15.0.1 version: link:../font '@next/polyfill-module': - specifier: 15.0.1-canary.3 + specifier: 15.0.1 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 15.0.1-canary.3 + specifier: 15.0.1 version: link:../next-polyfill-nomodule '@next/react-refresh-utils': - specifier: 15.0.1-canary.3 + specifier: 15.0.1 version: link:../react-refresh-utils '@next/swc': - specifier: 15.0.1-canary.3 + specifier: 15.0.1 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1633,7 +1633,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 15.0.1-canary.3 + specifier: 15.0.1 version: link:../next outdent: specifier: 0.8.0 From b2582447d0a884c8aa2995132e3eddc3743fb2ca Mon Sep 17 00:00:00 2001 From: ytori Date: Wed, 23 Oct 2024 09:32:52 +0900 Subject: [PATCH 14/44] docs: fix broken link in Architecture/Turbopack documentation (#71412) This PR fixes a broken link (404 Not Found) in the [Architecture/Turbopack](https://nextjs.org/docs/architecture/turbopack) documentation. It appears the actual URL differs from the expected one, so I have corrected it to the expected URL. expected URL : https://nextjs.org/docs/canary/architecture/nextjs-compiler#supported-features actual URL : https://nextjs.org/docs/canary/architecture/docs/canary/architecture/nextjs-compiler#supported-features ![image](https://github.com/user-attachments/assets/ea63f62d-f00a-4a02-a330-20be1e8a67c7) Co-authored-by: JJ Kasper --- docs/04-architecture/turbopack.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/04-architecture/turbopack.mdx b/docs/04-architecture/turbopack.mdx index 3ca3f67c1e353e..e8c6e5b50e5242 100644 --- a/docs/04-architecture/turbopack.mdx +++ b/docs/04-architecture/turbopack.mdx @@ -43,7 +43,7 @@ These features are currently not supported: - A subset of [Webpack loaders](/docs/app/api-reference/next-config-js/turbo#configuring-webpack-loaders) are supported in Turbopack. - Babel (`.babelrc`) - Turbopack leverages the [SWC](/docs/architecture/nextjs-compiler#why-swc) compiler for all transpilation and optimizations. This means that Babel is not included by default. - - If you have a `.babelrc` file, you might no longer need it because Next.js includes common Babel plugins as SWC transforms that can be enabled. You can read more about this in the [compiler documentation](docs/architecture/nextjs-compiler#supported-features). + - If you have a `.babelrc` file, you might no longer need it because Next.js includes common Babel plugins as SWC transforms that can be enabled. You can read more about this in the [compiler documentation](/docs/architecture/nextjs-compiler#supported-features). - If you still need to use Babel after verifying your particular use case is not covered, you can leverage Turbopack's [support for custom webpack loaders](/docs/app/api-reference/next-config-js/turbo#configuring-webpack-loaders) to include `babel-loader`. - Creating a root layout automatically in App Router. - This behavior is currently not supported since it changes input files, instead, an error will be shown for you to manually add a root layout in the desired location. From 03ff785c831c7cff29461197af1d435c088b37eb Mon Sep 17 00:00:00 2001 From: Hendrik Liebau Date: Wed, 23 Oct 2024 02:35:46 +0200 Subject: [PATCH 15/44] Read page name from work store in server module map proxy (#71669) This avoids a race condition when running `next build` where the manifest singleton might be overwritten with the next page's manifest while the previous page is still being rendered. With this PR, we are not storing a page-specific singleton but the whole manifest, and only when accessing an entry is the page read from the work store, and thus scoped to the current page. An exception is when a server module map is needed during module evaluation when no work store is provided, e.g. to create a server action using a higher-order function. In this case it should be safe to return any entry from the manifest that matches the action ID. They all refer to the same module ID, which must also exist in the current page bundle. (This is currently not guaranteed in Turbopack, and needs to be fixed.) --- .../src/build/templates/edge-app-route.ts | 1 - .../next/src/build/templates/edge-ssr-app.ts | 1 - .../src/server/app-render/action-utils.ts | 31 ++++++++++++++++--- .../next/src/server/app-render/app-render.tsx | 5 +-- packages/next/src/server/load-components.ts | 7 ++--- 5 files changed, 31 insertions(+), 14 deletions(-) diff --git a/packages/next/src/build/templates/edge-app-route.ts b/packages/next/src/build/templates/edge-app-route.ts index 39a8c2584a6f6b..b3514afe44c78b 100644 --- a/packages/next/src/build/templates/edge-app-route.ts +++ b/packages/next/src/build/templates/edge-app-route.ts @@ -21,7 +21,6 @@ if (rscManifest && rscServerManifest) { serverActionsManifest: rscServerManifest, serverModuleMap: createServerModuleMap({ serverActionsManifest: rscServerManifest, - pageName: 'VAR_PAGE', }), }) } diff --git a/packages/next/src/build/templates/edge-ssr-app.ts b/packages/next/src/build/templates/edge-ssr-app.ts index 2b2e6cc1eb4a6c..4eb8a04de9a452 100644 --- a/packages/next/src/build/templates/edge-ssr-app.ts +++ b/packages/next/src/build/templates/edge-ssr-app.ts @@ -60,7 +60,6 @@ if (rscManifest && rscServerManifest) { serverActionsManifest: rscServerManifest, serverModuleMap: createServerModuleMap({ serverActionsManifest: rscServerManifest, - pageName: 'VAR_PAGE', }), }) } diff --git a/packages/next/src/server/app-render/action-utils.ts b/packages/next/src/server/app-render/action-utils.ts index f5ebaa3c698bd7..3a115de3b8d43f 100644 --- a/packages/next/src/server/app-render/action-utils.ts +++ b/packages/next/src/server/app-render/action-utils.ts @@ -2,6 +2,7 @@ import type { ActionManifest } from '../../build/webpack/plugins/flight-client-e import { normalizeAppPath } from '../../shared/lib/router/utils/app-paths' import { pathHasPrefix } from '../../shared/lib/router/utils/path-has-prefix' import { removePathPrefix } from '../../shared/lib/router/utils/remove-path-prefix' +import { workAsyncStorage } from './work-async-storage.external' // This function creates a Flight-acceptable server module map proxy from our // Server Reference Manifest similar to our client module map. @@ -9,19 +10,41 @@ import { removePathPrefix } from '../../shared/lib/router/utils/remove-path-pref // are relevant to the runtime, workers, etc. that React doesn't need to know. export function createServerModuleMap({ serverActionsManifest, - pageName, }: { serverActionsManifest: ActionManifest - pageName: string }) { return new Proxy( {}, { get: (_, id: string) => { - const workerEntry = + const workers = serverActionsManifest[ process.env.NEXT_RUNTIME === 'edge' ? 'edge' : 'node' - ][id].workers[normalizeWorkerPageName(pageName)] + ][id].workers + + const workStore = workAsyncStorage.getStore() + + let workerEntry: + | { moduleId: string | number; async: boolean } + | string + | undefined + + if (workStore) { + workerEntry = workers[normalizeWorkerPageName(workStore.page)] + } else { + // If there's no work store defined, we can assume that a server + // module map is needed during module evaluation, e.g. to create a + // server action using a higher-order function. Therefore it should be + // safe to return any entry from the manifest that matches the action + // ID. They all refer to the same module ID, which must also exist in + // the current page bundle. TODO: This is currently not guaranteed in + // Turbopack, and needs to be fixed. + workerEntry = Object.values(workers).at(0) + } + + if (!workerEntry) { + return undefined + } if (typeof workerEntry === 'string') { return { id: workerEntry, name: id, chunks: [] } diff --git a/packages/next/src/server/app-render/app-render.tsx b/packages/next/src/server/app-render/app-render.tsx index f9108f44ab3f06..04c5260d2577d3 100644 --- a/packages/next/src/server/app-render/app-render.tsx +++ b/packages/next/src/server/app-render/app-render.tsx @@ -1057,10 +1057,7 @@ async function renderToHTMLOrFlightImpl( // TODO: fix this typescript const clientReferenceManifest = renderOpts.clientReferenceManifest! - const serverModuleMap = createServerModuleMap({ - serverActionsManifest, - pageName: renderOpts.page, - }) + const serverModuleMap = createServerModuleMap({ serverActionsManifest }) setReferenceManifestsSingleton({ clientReferenceManifest, diff --git a/packages/next/src/server/load-components.ts b/packages/next/src/server/load-components.ts index 887039d06ad5a9..5c826205a16ebf 100644 --- a/packages/next/src/server/load-components.ts +++ b/packages/next/src/server/load-components.ts @@ -172,16 +172,15 @@ async function loadComponentsImpl({ : null, ]) - // Before requring the actual page module, we have to set the reference manifests - // to our global store so Server Action's encryption util can access to them - // at the top level of the page module. + // Before requiring the actual page module, we have to set the reference + // manifests to our global store so Server Action's encryption util can access + // to them at the top level of the page module. if (serverActionsManifest && clientReferenceManifest) { setReferenceManifestsSingleton({ clientReferenceManifest, serverActionsManifest, serverModuleMap: createServerModuleMap({ serverActionsManifest, - pageName: page, }), }) } From f91cdec44d85c2a27397cba7ef8feaa9daf6ee28 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Wed, 23 Oct 2024 02:36:20 +0200 Subject: [PATCH 16/44] test: migrate rest async api usage in tests (#71663) --- test/e2e/app-dir/actions/app/header/edge/validator.js | 2 +- .../parallel-routes/app/@breadcrumbs/[id]/page.js | 3 ++- .../app-css/app/loading-bug/[categorySlug]/page.js | 3 ++- .../app-css/app/not-found/clientcomponent/page.js | 4 ++-- test/e2e/app-dir/app-esm-js/app/app/hooks.js | 2 +- .../app/bad-response-page/[slug]/page.js | 2 +- .../app-fetch-deduping/app/blog/[slug]/page.js | 2 +- test/e2e/app-dir/app-middleware/app/headers/page.js | 4 ++-- test/e2e/app-dir/app-middleware/middleware.js | 2 +- .../[region]/(default)/dynamic-area/[slug]/page.js | 2 +- .../app/[region]/(default)/layout.js | 2 +- .../app/[region]/(default)/static-prefetch/page.js | 2 +- .../app-dir/app-prefetch/app/dashboard/[id]/page.js | 3 ++- .../app-prefetch/app/prefetch-auto/[slug]/page.js | 3 ++- .../app/revalidate-1/[slug]/data.json/route.ts | 3 ++- .../app-routes/app/static/[slug]/data.json/route.ts | 3 ++- .../app-static/app/blog/[author]/[slug]/page.js | 3 ++- .../app-dir/app-static/app/blog/[author]/layout.js | 6 +++++- test/e2e/app-dir/app-static/app/blog/[author]/page.js | 3 ++- .../app-dir/app-static/app/dynamic-error/[id]/page.js | 3 ++- .../app/dynamic-no-gen-params-ssr/[slug]/page.js | 3 ++- .../app/dynamic-no-gen-params/[slug]/page.js | 4 +++- .../app/force-dynamic-no-prerender/[id]/page.js | 2 +- .../app/force-dynamic-prerender/[slug]/page.js | 3 ++- .../app-static/app/force-static/[slug]/page.js | 3 ++- .../e2e/app-dir/app-static/app/force-static/layout.js | 6 +++--- .../app/gen-params-dynamic-revalidate/[slug]/page.js | 3 ++- .../app-static/app/gen-params-dynamic/[slug]/page.js | 3 ++- .../[lang]/[slug]/page.js | 3 ++- .../[lang]/[slug]/page.js | 3 ++- .../app/partial-gen-params/[lang]/[slug]/page.js | 3 ++- .../app/ssg-draft-mode/[[...route]]/page.js | 2 +- .../app/static-to-dynamic-error-forced/[id]/page.js | 5 +++-- .../app/static-to-dynamic-error/[id]/page.js | 5 +++-- .../authorization/route-cookies/route.js | 2 +- test/e2e/app-dir/app/app/back-forward/[id]/page.js | 4 +++- .../app-dir/app/app/catch-all-edge/[...slug]/page.js | 3 ++- .../app/app/catch-all-optional/[[...slug]]/page.js | 3 ++- test/e2e/app-dir/app/app/catch-all/[...slug]/page.js | 3 ++- .../app/app/dashboard/deployments/info/[id]/page.js | 3 ++- .../app/app/dynamic-client/[category]/[id]/layout.js | 6 +++++- .../app/app/dynamic-client/[category]/[id]/page.js | 7 ++++++- .../app/app/dynamic-client/[category]/layout.js | 6 +++++- test/e2e/app-dir/app/app/dynamic-client/layout.js | 6 +++++- .../app-dir/app/app/dynamic/[category]/[id]/layout.js | 6 +++++- .../app-dir/app/app/dynamic/[category]/[id]/page.js | 7 ++++++- test/e2e/app-dir/app/app/dynamic/[category]/layout.js | 6 +++++- test/e2e/app-dir/app/app/dynamic/layout.js | 6 +++++- test/e2e/app-dir/app/app/link-hard-push/[id]/page.js | 3 ++- .../app-dir/app/app/link-hard-replace/[id]/page.js | 3 ++- .../app/app/loading-bug/[categorySlug]/page.js | 3 ++- .../app-dir/app/app/param-and-query/[slug]/page.js | 10 +++++++--- test/e2e/app-dir/app/app/partial-match-[id]/page.js | 4 ++-- .../app/app/searchparams-normalization-bug/page.js | 4 ++-- .../custom-cache-control/app/app-ssg/[slug]/page.tsx | 3 ++- .../fixtures/cache-scoped/app/connection/page.js | 2 +- .../fixtures/main/app/force-dynamic/page.js | 2 +- .../fixtures/main/app/force-static/page.js | 2 +- .../dynamic-data/fixtures/main/app/top-level/page.js | 2 +- .../fixtures/require-static/app/connection/page.js | 2 +- .../fixtures/require-static/app/cookies/page.js | 2 +- .../fixtures/require-static/app/headers/page.js | 2 +- .../app/dynamic-params/[slug]/page.tsx | 3 ++- .../edge-route-rewrite/app/dynamic/[slug]/route.ts | 3 ++- .../errors/app/ssr-error-client-component/page.js | 4 ++-- .../app-future/[lang]/(dashboard)/[teamSlug]/page.tsx | 3 ++- .../app/page-with-headers/page.tsx | 4 ++-- .../app-dir/hooks/app/hooks/use-draft-mode/page.js | 4 ++-- test/e2e/app-dir/hooks/app/hooks/use-headers/page.js | 4 ++-- .../app/base/[param1]/[param2]/layout.tsx | 9 +++++---- .../layout-params/app/base/[param1]/layout.tsx | 9 +++++---- test/e2e/app-dir/layout-params/app/base/layout.tsx | 9 +++++---- .../layout-params/app/catchall/[...params]/layout.tsx | 9 +++++---- test/e2e/app-dir/layout-params/app/layout.tsx | 9 +++++---- .../app/optional-catchall/[[...params]]/layout.tsx | 9 +++++---- test/e2e/app-dir/logging/app/headers/page.js | 4 ++-- .../next-after-app/app/nodejs/[id]/dynamic/page.js | 3 ++- .../app/nodejs/[id]/with-action/page.js | 3 ++- .../app/nodejs/[id]/with-metadata/page.js | 3 ++- .../next-after-app/app/nodejs/nested-after/page.js | 2 +- .../app/(group)/group-dynamic/[id]/page.js | 3 ++- .../app/dynamic-layout-without-not-found/[id]/page.js | 6 +++++- .../app-dir/not-found/basic/app/dynamic/[id]/page.js | 6 +++++- .../basic/app/error-boundary/nested/[dynamic]/page.js | 3 ++- .../app/(group)/group-dynamic/[id]/page.js | 3 ++- .../[username]/@modal/default.js | 2 +- .../[locale]/nested/[foo]/[bar]/@slot/[baz]/page.tsx | 2 +- .../[locale]/nested/[foo]/[bar]/@slot0/[baz]/page.tsx | 2 +- .../[locale]/nested/[foo]/[bar]/@slot0/default.tsx | 2 +- .../nested/[foo]/[bar]/@slot1/[baz]/[qux]/page.tsx | 2 +- .../[locale]/nested/[foo]/[bar]/@slot1/[baz]/page.tsx | 2 +- .../app/[locale]/nested/@slot0/bar/page.tsx | 2 +- .../app/[locale]/nested/@slot0/foo/page.tsx | 2 +- .../app/[locale]/nested/@slot1/baz/page.tsx | 2 +- .../[dynamic]/@modal/(.)login/page.tsx | 11 +++++------ .../app/dynamic-refresh/[dynamic]/page.tsx | 6 +++--- .../app/refreshing/@modal/(.)login/page.tsx | 8 +++----- .../app/refreshing/page.tsx | 5 +++-- .../ppr-full/app/dynamic-data/force-dynamic/page.jsx | 3 ++- .../ppr-full/app/dynamic-data/force-static/page.jsx | 3 ++- .../incidental-postpone/force-dynamic/page.jsx | 3 ++- .../incidental-postpone/force-static/page.jsx | 3 ++- .../app/dynamic-data/incidental-postpone/page.jsx | 4 ++-- test/e2e/app-dir/ppr-full/app/dynamic-data/page.jsx | 4 ++-- .../app/dynamic/force-dynamic/nested/[slug]/page.jsx | 6 +++++- .../fallback/client/params/layout/[slug]/layout.jsx | 7 ++++++- .../app/fallback/client/params/page/[slug]/page.jsx | 3 ++- .../app/fallback/dynamic/error/[slug]/page.jsx | 3 ++- .../app/fallback/dynamic/params/[slug]/page.jsx | 7 ++++--- .../app/fallback/nested/params/[...slug]/page.jsx | 3 ++- .../ppr-full/app/fallback/params/[slug]/page.jsx | 3 ++- test/e2e/app-dir/ppr-full/app/loading/[slug]/page.jsx | 6 +++++- test/e2e/app-dir/ppr-full/app/nested/[slug]/page.jsx | 6 +++++- .../ppr-full/app/no-suspense/nested/[slug]/page.jsx | 6 +++++- .../app-dir/ppr-full/app/on-demand/[slug]/page.jsx | 6 +++++- .../incremental/app/[locale]/about/page.jsx | 6 +++++- .../incremental/app/[locale]/layout.jsx | 8 +++++++- .../ppr-navigations/incremental/app/[locale]/page.jsx | 6 +++++- .../incremental/app/[locale]/static/page.jsx | 6 +++++- .../app/catch-all/[[...slug]]/page.tsx | 3 ++- .../ppr-navigations/search-params/app/page.tsx | 5 ++--- .../simple/app/[locale]/about/page.jsx | 6 +++++- .../ppr-navigations/simple/app/[locale]/layout.jsx | 8 +++++++- .../ppr-navigations/simple/app/[locale]/page.jsx | 6 +++++- .../ppr/app/no-suspense/node/gsp/[slug]/page.jsx | 3 ++- .../app-dir/ppr/app/suspense/node/gsp/[slug]/page.jsx | 3 ++- .../rewrites-redirects/app/[...params]/page.tsx | 5 ++--- .../app/[slug]/page.tsx | 3 ++- .../app/blog/[slug]/page.tsx | 3 ++- test/e2e/app-dir/rsc-basic/app/page.js | 4 ++-- .../app/(shallow)/dynamic/[id]/page.tsx | 3 ++- .../app-dynamic-error/app/dynamic-error/page.js | 4 ++-- 132 files changed, 351 insertions(+), 187 deletions(-) diff --git a/test/e2e/app-dir/actions/app/header/edge/validator.js b/test/e2e/app-dir/actions/app/header/edge/validator.js index 3f0f7c78252e2a..a578bd36de90fa 100644 --- a/test/e2e/app-dir/actions/app/header/edge/validator.js +++ b/test/e2e/app-dir/actions/app/header/edge/validator.js @@ -3,7 +3,7 @@ import { cookies } from 'next/headers' export function validator(action) { return async function (arg) { 'use server' - const auth = cookies().get('edge-auth') + const auth = (await cookies()).get('edge-auth') if (auth?.value !== '1') { throw new Error('Unauthorized request') } diff --git a/test/e2e/app-dir/app-client-cache/fixtures/parallel-routes/app/@breadcrumbs/[id]/page.js b/test/e2e/app-dir/app-client-cache/fixtures/parallel-routes/app/@breadcrumbs/[id]/page.js index 43ade54c21804c..ce9c8a00f15579 100644 --- a/test/e2e/app-dir/app-client-cache/fixtures/parallel-routes/app/@breadcrumbs/[id]/page.js +++ b/test/e2e/app-dir/app-client-cache/fixtures/parallel-routes/app/@breadcrumbs/[id]/page.js @@ -1,4 +1,5 @@ -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params return (
    Catchall
    {JSON.stringify(params)}
    {' '} diff --git a/test/e2e/app-dir/app-css/app/loading-bug/[categorySlug]/page.js b/test/e2e/app-dir/app-css/app/loading-bug/[categorySlug]/page.js index 714616632e9671..ed795b5505d8e0 100644 --- a/test/e2e/app-dir/app-css/app/loading-bug/[categorySlug]/page.js +++ b/test/e2e/app-dir/app-css/app/loading-bug/[categorySlug]/page.js @@ -7,7 +7,8 @@ const fetchCategory = async (categorySlug) => { return categorySlug + 'abc' } -export default function Page({ params }) { +export default function Page(props) { + const params = use(props.params) const category = use(fetchCategory(params.categorySlug)) return
    {category}
    diff --git a/test/e2e/app-dir/app-css/app/not-found/clientcomponent/page.js b/test/e2e/app-dir/app-css/app/not-found/clientcomponent/page.js index 066490779210eb..4d28919b28e723 100644 --- a/test/e2e/app-dir/app-css/app/not-found/clientcomponent/page.js +++ b/test/e2e/app-dir/app-css/app/not-found/clientcomponent/page.js @@ -2,8 +2,8 @@ import ClientComp from './client-component' import { headers } from 'next/headers' -export default function Page() { +export default async function Page() { // Opt-in to SSR. - headers() + await headers() return } diff --git a/test/e2e/app-dir/app-esm-js/app/app/hooks.js b/test/e2e/app-dir/app-esm-js/app/app/hooks.js index bd406ba2852e80..c9e3f658b98d64 100644 --- a/test/e2e/app-dir/app-esm-js/app/app/hooks.js +++ b/test/e2e/app-dir/app-esm-js/app/app/hooks.js @@ -3,7 +3,7 @@ import { ClientHooks } from './client-hooks' import { headers, cookies } from 'next/headers' export function useHooks() { - headers() + use(headers()) use(cookies()) return } diff --git a/test/e2e/app-dir/app-fetch-deduping/app/bad-response-page/[slug]/page.js b/test/e2e/app-dir/app-fetch-deduping/app/bad-response-page/[slug]/page.js index 6b900ddbc6a7ee..93981ffc1efb5c 100644 --- a/test/e2e/app-dir/app-fetch-deduping/app/bad-response-page/[slug]/page.js +++ b/test/e2e/app-dir/app-fetch-deduping/app/bad-response-page/[slug]/page.js @@ -20,7 +20,7 @@ export async function generateStaticParams() { ] } -export default async function Page({ params }) { +export default async function Page() { const data = await fetch( `http://localhost:${process.env.TEST_SERVER_PORT}?status=404` ).then((res) => res.text()) diff --git a/test/e2e/app-dir/app-fetch-deduping/app/blog/[slug]/page.js b/test/e2e/app-dir/app-fetch-deduping/app/blog/[slug]/page.js index 3e8ac4de29dfd8..5f20cc8551c678 100644 --- a/test/e2e/app-dir/app-fetch-deduping/app/blog/[slug]/page.js +++ b/test/e2e/app-dir/app-fetch-deduping/app/blog/[slug]/page.js @@ -18,7 +18,7 @@ export async function generateStaticParams() { ] } -export default async function Page({ params }) { +export default async function Page() { const data = await fetch( `http://localhost:${process.env.TEST_SERVER_PORT}` ).then((res) => res.text()) diff --git a/test/e2e/app-dir/app-middleware/app/headers/page.js b/test/e2e/app-dir/app-middleware/app/headers/page.js index e7d5e20ddf94e2..977111f49c646b 100644 --- a/test/e2e/app-dir/app-middleware/app/headers/page.js +++ b/test/e2e/app-dir/app-middleware/app/headers/page.js @@ -1,7 +1,7 @@ import { headers } from 'next/headers' -export default function SSRPage() { - const headersObj = Object.fromEntries(headers()) +export default async function SSRPage() { + const headersObj = Object.fromEntries(await headers()) return ( <>

    app-dir

    diff --git a/test/e2e/app-dir/app-middleware/middleware.js b/test/e2e/app-dir/app-middleware/middleware.js index e8409c227b9479..0e4dd2ea8ad958 100644 --- a/test/e2e/app-dir/app-middleware/middleware.js +++ b/test/e2e/app-dir/app-middleware/middleware.js @@ -8,7 +8,7 @@ import { headers as nextHeaders, draftMode } from 'next/headers' export async function middleware(request) { const headersFromRequest = new Headers(request.headers) // It should be able to import and use `headers` inside middleware - const headersFromNext = nextHeaders() + const headersFromNext = await nextHeaders() headersFromRequest.set('x-from-middleware', 'hello-from-middleware') // make sure headers() from `next/headers` is behaving properly diff --git a/test/e2e/app-dir/app-prefetch-static/app/[region]/(default)/dynamic-area/[slug]/page.js b/test/e2e/app-dir/app-prefetch-static/app/[region]/(default)/dynamic-area/[slug]/page.js index 6040b75de167bf..f446c87c26ef65 100644 --- a/test/e2e/app-dir/app-prefetch-static/app/[region]/(default)/dynamic-area/[slug]/page.js +++ b/test/e2e/app-dir/app-prefetch-static/app/[region]/(default)/dynamic-area/[slug]/page.js @@ -1,3 +1,3 @@ -export default async function DynamicPage({ params, searchParams }) { +export default async function DynamicPage(props) { return
    Hello from Dynamic Prefetch Page
    } diff --git a/test/e2e/app-dir/app-prefetch-static/app/[region]/(default)/layout.js b/test/e2e/app-dir/app-prefetch-static/app/[region]/(default)/layout.js index 92c69396f61f7c..28231e51868d55 100644 --- a/test/e2e/app-dir/app-prefetch-static/app/[region]/(default)/layout.js +++ b/test/e2e/app-dir/app-prefetch-static/app/[region]/(default)/layout.js @@ -1,6 +1,6 @@ export const regions = ['SE', 'DE'] -export default async function Layout({ children, params }) { +export default function Layout({ children }) { return children } diff --git a/test/e2e/app-dir/app-prefetch-static/app/[region]/(default)/static-prefetch/page.js b/test/e2e/app-dir/app-prefetch-static/app/[region]/(default)/static-prefetch/page.js index 067d0371e6aef7..00f20c489d4a97 100644 --- a/test/e2e/app-dir/app-prefetch-static/app/[region]/(default)/static-prefetch/page.js +++ b/test/e2e/app-dir/app-prefetch-static/app/[region]/(default)/static-prefetch/page.js @@ -1,6 +1,6 @@ export const dynamic = 'force-dynamic' -export default async function StaticPrefetchPage({ params }) { +export default function StaticPrefetchPage(props) { return (

    Hello from Static Prefetch Page

    diff --git a/test/e2e/app-dir/app-prefetch/app/dashboard/[id]/page.js b/test/e2e/app-dir/app-prefetch/app/dashboard/[id]/page.js index 186f6bbecc23ad..755901b394f88c 100644 --- a/test/e2e/app-dir/app-prefetch/app/dashboard/[id]/page.js +++ b/test/e2e/app-dir/app-prefetch/app/dashboard/[id]/page.js @@ -12,7 +12,8 @@ export function generateStaticParams() { return [{ id: 'static' }] } -export default function IdPage({ params }) { +export default function IdPage(props) { + const params = use(props.params) const data = use(getData()) console.log(data) diff --git a/test/e2e/app-dir/app-prefetch/app/prefetch-auto/[slug]/page.js b/test/e2e/app-dir/app-prefetch/app/prefetch-auto/[slug]/page.js index 23c8bdc9b5cb18..f6e85c314a3b8f 100644 --- a/test/e2e/app-dir/app-prefetch/app/prefetch-auto/[slug]/page.js +++ b/test/e2e/app-dir/app-prefetch/app/prefetch-auto/[slug]/page.js @@ -9,7 +9,8 @@ function getData() { return res } -export default async function Page({ params }) { +export default async function Page(props) { + const params = await props.params const result = await getData() return ( diff --git a/test/e2e/app-dir/app-routes/app/revalidate-1/[slug]/data.json/route.ts b/test/e2e/app-dir/app-routes/app/revalidate-1/[slug]/data.json/route.ts index 975ef0f51e050f..2b356d93eea216 100644 --- a/test/e2e/app-dir/app-routes/app/revalidate-1/[slug]/data.json/route.ts +++ b/test/e2e/app-dir/app-routes/app/revalidate-1/[slug]/data.json/route.ts @@ -9,8 +9,9 @@ export function generateStaticParams() { export const GET = async ( req: NextRequest, - { params }: { params: Promise<{ slug: string }> } + props: { params: Promise<{ slug: string }> } ) => { + const params = await props.params const resolvedParams = await params return NextResponse.json({ params: resolvedParams, now: Date.now() }) } diff --git a/test/e2e/app-dir/app-routes/app/static/[slug]/data.json/route.ts b/test/e2e/app-dir/app-routes/app/static/[slug]/data.json/route.ts index 570a309dcf13a7..6faa0b27efa587 100644 --- a/test/e2e/app-dir/app-routes/app/static/[slug]/data.json/route.ts +++ b/test/e2e/app-dir/app-routes/app/static/[slug]/data.json/route.ts @@ -7,8 +7,9 @@ export function generateStaticParams() { export const GET = async ( req: NextRequest, - { params }: { params: Promise<{ slug: string }> } + props: { params: Promise<{ slug: string }> } ) => { + const params = await props.params const resolvedParams = await params return NextResponse.json({ params: resolvedParams, now: Date.now() }) } diff --git a/test/e2e/app-dir/app-static/app/blog/[author]/[slug]/page.js b/test/e2e/app-dir/app-static/app/blog/[author]/[slug]/page.js index 5ae52dfe56be72..b910caff3511a6 100644 --- a/test/e2e/app-dir/app-static/app/blog/[author]/[slug]/page.js +++ b/test/e2e/app-dir/app-static/app/blog/[author]/[slug]/page.js @@ -2,7 +2,8 @@ import { notFound } from 'next/navigation' export const dynamicParams = true -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params if (params.author === 'shu') { notFound() } diff --git a/test/e2e/app-dir/app-static/app/blog/[author]/layout.js b/test/e2e/app-dir/app-static/app/blog/[author]/layout.js index 3f6a1da93c5b3a..c206d2ea77a026 100644 --- a/test/e2e/app-dir/app-static/app/blog/[author]/layout.js +++ b/test/e2e/app-dir/app-static/app/blog/[author]/layout.js @@ -1,4 +1,8 @@ -export default function Layout({ children, params }) { +export default async function Layout(props) { + const params = await props.params + + const { children } = props + return ( <>

    {JSON.stringify(params)}

    diff --git a/test/e2e/app-dir/app-static/app/blog/[author]/page.js b/test/e2e/app-dir/app-static/app/blog/[author]/page.js index fa5e3e0b23d6c4..aea63fbe0877c4 100644 --- a/test/e2e/app-dir/app-static/app/blog/[author]/page.js +++ b/test/e2e/app-dir/app-static/app/blog/[author]/page.js @@ -2,7 +2,8 @@ import Link from 'next/link' export const dynamicParams = false -export default async function Page({ params }) { +export default async function Page(props) { + const params = await props.params await fetch('https://example.vercel.sh', { next: { revalidate: 10 }, }) diff --git a/test/e2e/app-dir/app-static/app/dynamic-error/[id]/page.js b/test/e2e/app-dir/app-static/app/dynamic-error/[id]/page.js index 837c29b4708762..c10d5574131d2c 100644 --- a/test/e2e/app-dir/app-static/app/dynamic-error/[id]/page.js +++ b/test/e2e/app-dir/app-static/app/dynamic-error/[id]/page.js @@ -2,7 +2,8 @@ import { cookies } from 'next/headers' export const dynamic = 'error' -export default async function Page({ params }) { +export default async function Page(props) { + const params = await props.params // When PPR is enabled, we will bailout on parameter access. if (!process.env.__NEXT_EXPERIMENTAL_PPR) { if (params.id.includes('static-bailout')) { diff --git a/test/e2e/app-dir/app-static/app/dynamic-no-gen-params-ssr/[slug]/page.js b/test/e2e/app-dir/app-static/app/dynamic-no-gen-params-ssr/[slug]/page.js index 834d9077d28d1b..a9598add5c593b 100644 --- a/test/e2e/app-dir/app-static/app/dynamic-no-gen-params-ssr/[slug]/page.js +++ b/test/e2e/app-dir/app-static/app/dynamic-no-gen-params-ssr/[slug]/page.js @@ -1,6 +1,7 @@ export const revalidate = 0 -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params return ( <>

    /dynamic-no-gen-params-ssr

    diff --git a/test/e2e/app-dir/app-static/app/dynamic-no-gen-params/[slug]/page.js b/test/e2e/app-dir/app-static/app/dynamic-no-gen-params/[slug]/page.js index 97682547a4d625..7e6fae1089f934 100644 --- a/test/e2e/app-dir/app-static/app/dynamic-no-gen-params/[slug]/page.js +++ b/test/e2e/app-dir/app-static/app/dynamic-no-gen-params/[slug]/page.js @@ -1,8 +1,10 @@ 'use client' +import { use } from 'react' import Link from 'next/link' -export default function Page({ params }) { +export default function Page(props) { + const params = use(props.params) return ( <>

    /dynamic-no-gen-params

    diff --git a/test/e2e/app-dir/app-static/app/force-dynamic-no-prerender/[id]/page.js b/test/e2e/app-dir/app-static/app/force-dynamic-no-prerender/[id]/page.js index e42e7e48da2c74..f83ba7972fb279 100644 --- a/test/e2e/app-dir/app-static/app/force-dynamic-no-prerender/[id]/page.js +++ b/test/e2e/app-dir/app-static/app/force-dynamic-no-prerender/[id]/page.js @@ -1,5 +1,5 @@ export const dynamic = 'force-dynamic' -export default function Page({ params }) { +export default function Page(props) { throw new Error('this should not attempt prerendering with force-dynamic') } diff --git a/test/e2e/app-dir/app-static/app/force-dynamic-prerender/[slug]/page.js b/test/e2e/app-dir/app-static/app/force-dynamic-prerender/[slug]/page.js index eb86c1b4e31973..279e3636fb4ea7 100644 --- a/test/e2e/app-dir/app-static/app/force-dynamic-prerender/[slug]/page.js +++ b/test/e2e/app-dir/app-static/app/force-dynamic-prerender/[slug]/page.js @@ -8,7 +8,8 @@ export const generateStaticParams = async () => { return [{ slug: 'frameworks' }] } -export default async function Page({ params }) { +export default async function Page(props) { + const params = await props.params const result = (await cookies()).get('session')?.value ? 'has cookie' : 'no cookie' diff --git a/test/e2e/app-dir/app-static/app/force-static/[slug]/page.js b/test/e2e/app-dir/app-static/app/force-static/[slug]/page.js index 0083019a243cc6..4589e03f984aff 100644 --- a/test/e2e/app-dir/app-static/app/force-static/[slug]/page.js +++ b/test/e2e/app-dir/app-static/app/force-static/[slug]/page.js @@ -13,7 +13,8 @@ function Dynamic({ params }) { return

    {JSON.stringify(params)}

    } -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params return (

    /force-static/[slug]

    diff --git a/test/e2e/app-dir/app-static/app/force-static/layout.js b/test/e2e/app-dir/app-static/app/force-static/layout.js index b41b643fe1f25a..8296c22976a9e4 100644 --- a/test/e2e/app-dir/app-static/app/force-static/layout.js +++ b/test/e2e/app-dir/app-static/app/force-static/layout.js @@ -1,8 +1,8 @@ import { cookies, headers } from 'next/headers' -export default function Layout({ children }) { - const curHeaders = headers() - const curCookies = cookies() +export default async function Layout({ children }) { + const curHeaders = await headers() + const curCookies = await cookies() return ( <> diff --git a/test/e2e/app-dir/app-static/app/gen-params-dynamic-revalidate/[slug]/page.js b/test/e2e/app-dir/app-static/app/gen-params-dynamic-revalidate/[slug]/page.js index 23b94efed6e8c0..598b8fc8ed3683 100644 --- a/test/e2e/app-dir/app-static/app/gen-params-dynamic-revalidate/[slug]/page.js +++ b/test/e2e/app-dir/app-static/app/gen-params-dynamic-revalidate/[slug]/page.js @@ -6,7 +6,8 @@ export async function generateStaticParams() { return [{ slug: 'one' }] } -export default async function page({ params }) { +export default async function page(props) { + const params = await props.params const { slug } = params let data diff --git a/test/e2e/app-dir/app-static/app/gen-params-dynamic/[slug]/page.js b/test/e2e/app-dir/app-static/app/gen-params-dynamic/[slug]/page.js index f9d5366ea389b1..334b53337a5682 100644 --- a/test/e2e/app-dir/app-static/app/gen-params-dynamic/[slug]/page.js +++ b/test/e2e/app-dir/app-static/app/gen-params-dynamic/[slug]/page.js @@ -4,7 +4,8 @@ export async function generateStaticParams() { return [{ slug: 'one' }] } -export default async function page({ params }) { +export default async function page(props) { + const params = await props.params const { slug } = params const data = await fetchRetry( 'https://next-data-api-endpoint.vercel.app/api/random', diff --git a/test/e2e/app-dir/app-static/app/partial-gen-params-no-additional-lang/[lang]/[slug]/page.js b/test/e2e/app-dir/app-static/app/partial-gen-params-no-additional-lang/[lang]/[slug]/page.js index 45da73dcfed373..dcad8f27bb8ee4 100644 --- a/test/e2e/app-dir/app-static/app/partial-gen-params-no-additional-lang/[lang]/[slug]/page.js +++ b/test/e2e/app-dir/app-static/app/partial-gen-params-no-additional-lang/[lang]/[slug]/page.js @@ -23,7 +23,8 @@ export async function generateStaticParams() { ] } -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params return ( <>

    /partial-gen-params/[lang]/[slug]

    diff --git a/test/e2e/app-dir/app-static/app/partial-gen-params-no-additional-slug/[lang]/[slug]/page.js b/test/e2e/app-dir/app-static/app/partial-gen-params-no-additional-slug/[lang]/[slug]/page.js index 7e132527eb4c4d..c954dc87e6d644 100644 --- a/test/e2e/app-dir/app-static/app/partial-gen-params-no-additional-slug/[lang]/[slug]/page.js +++ b/test/e2e/app-dir/app-static/app/partial-gen-params-no-additional-slug/[lang]/[slug]/page.js @@ -23,7 +23,8 @@ export async function generateStaticParams() { ] } -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params return ( <>

    /partial-gen-params/[lang]/[slug]

    diff --git a/test/e2e/app-dir/app-static/app/partial-gen-params/[lang]/[slug]/page.js b/test/e2e/app-dir/app-static/app/partial-gen-params/[lang]/[slug]/page.js index 47c212176f0113..1f8bc986307070 100644 --- a/test/e2e/app-dir/app-static/app/partial-gen-params/[lang]/[slug]/page.js +++ b/test/e2e/app-dir/app-static/app/partial-gen-params/[lang]/[slug]/page.js @@ -1,4 +1,5 @@ -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params return ( <>

    /partial-gen-params/[lang]/[slug]

    diff --git a/test/e2e/app-dir/app-static/app/ssg-draft-mode/[[...route]]/page.js b/test/e2e/app-dir/app-static/app/ssg-draft-mode/[[...route]]/page.js index 9b3ef6f1bc6d5c..a8c5d759eeff1c 100644 --- a/test/e2e/app-dir/app-static/app/ssg-draft-mode/[[...route]]/page.js +++ b/test/e2e/app-dir/app-static/app/ssg-draft-mode/[[...route]]/page.js @@ -5,7 +5,7 @@ export default async function Page() { 'https://next-data-api-endpoint.vercel.app/api/random' ).then((res) => res.text()) - const { isEnabled } = draftMode() + const { isEnabled } = await draftMode() return (
    diff --git a/test/e2e/app-dir/app-static/app/static-to-dynamic-error-forced/[id]/page.js b/test/e2e/app-dir/app-static/app/static-to-dynamic-error-forced/[id]/page.js index 5f6b80e43da435..20d5272c9705d8 100644 --- a/test/e2e/app-dir/app-static/app/static-to-dynamic-error-forced/[id]/page.js +++ b/test/e2e/app-dir/app-static/app/static-to-dynamic-error-forced/[id]/page.js @@ -2,9 +2,10 @@ import { cookies } from 'next/headers' export const dynamic = 'force-static' -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params if (params.id.includes('static-bailout')) { - console.log('calling cookies', cookies()) + console.log('calling cookies', await cookies()) } return ( diff --git a/test/e2e/app-dir/app-static/app/static-to-dynamic-error/[id]/page.js b/test/e2e/app-dir/app-static/app/static-to-dynamic-error/[id]/page.js index 076ac3c9ad5848..e34027da0bcd4e 100644 --- a/test/e2e/app-dir/app-static/app/static-to-dynamic-error/[id]/page.js +++ b/test/e2e/app-dir/app-static/app/static-to-dynamic-error/[id]/page.js @@ -1,8 +1,9 @@ import { cookies } from 'next/headers' -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params if (params.id.includes('static-bailout')) { - console.log('calling cookies', cookies()) + console.log('calling cookies', await cookies()) } return ( diff --git a/test/e2e/app-dir/app-static/app/variable-revalidate/authorization/route-cookies/route.js b/test/e2e/app-dir/app-static/app/variable-revalidate/authorization/route-cookies/route.js index 6933f6af261cad..e6f804475bbfb3 100644 --- a/test/e2e/app-dir/app-static/app/variable-revalidate/authorization/route-cookies/route.js +++ b/test/e2e/app-dir/app-static/app/variable-revalidate/authorization/route-cookies/route.js @@ -2,7 +2,7 @@ import { cookies } from 'next/headers' import { NextResponse } from 'next/server' export async function GET() { - const cookieData = cookies() + const cookieData = await cookies() const data = await fetch( 'https://next-data-api-endpoint.vercel.app/api/random', diff --git a/test/e2e/app-dir/app/app/back-forward/[id]/page.js b/test/e2e/app-dir/app/app/back-forward/[id]/page.js index 12da862d8a19ee..f2484917ff9775 100644 --- a/test/e2e/app-dir/app/app/back-forward/[id]/page.js +++ b/test/e2e/app-dir/app/app/back-forward/[id]/page.js @@ -1,8 +1,10 @@ 'use client' +import { use } from 'react' import Link from 'next/link' import { useRouter } from 'next/navigation' -export default function Page({ params }) { +export default function Page(props) { + const params = use(props.params) const router = useRouter() return ( <> diff --git a/test/e2e/app-dir/app/app/catch-all-edge/[...slug]/page.js b/test/e2e/app-dir/app/app/catch-all-edge/[...slug]/page.js index fada8420e95d66..780c94f08f69dc 100644 --- a/test/e2e/app-dir/app/app/catch-all-edge/[...slug]/page.js +++ b/test/e2e/app-dir/app/app/catch-all-edge/[...slug]/page.js @@ -1,6 +1,7 @@ export const runtime = 'edge' -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params return ( <>

    catch-all edge page

    diff --git a/test/e2e/app-dir/app/app/catch-all-optional/[[...slug]]/page.js b/test/e2e/app-dir/app/app/catch-all-optional/[[...slug]]/page.js index 7a7a7b4d92dd0a..5f19e2af72adbc 100644 --- a/test/e2e/app-dir/app/app/catch-all-optional/[[...slug]]/page.js +++ b/test/e2e/app-dir/app/app/catch-all-optional/[[...slug]]/page.js @@ -1,4 +1,5 @@ -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params return (

    hello from /catch-all-optional/{params.slug?.join('/')} diff --git a/test/e2e/app-dir/app/app/catch-all/[...slug]/page.js b/test/e2e/app-dir/app/app/catch-all/[...slug]/page.js index 55ba1e45595179..db22bcab2c0e36 100644 --- a/test/e2e/app-dir/app/app/catch-all/[...slug]/page.js +++ b/test/e2e/app-dir/app/app/catch-all/[...slug]/page.js @@ -1,7 +1,8 @@ import Widget from './components/widget' import NotAPage from './not-a-page' -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params return ( <>

    diff --git a/test/e2e/app-dir/app/app/dashboard/deployments/info/[id]/page.js b/test/e2e/app-dir/app/app/dashboard/deployments/info/[id]/page.js index df11944f5ad101..6039777eabb3e9 100644 --- a/test/e2e/app-dir/app/app/dashboard/deployments/info/[id]/page.js +++ b/test/e2e/app-dir/app/app/dashboard/deployments/info/[id]/page.js @@ -1,4 +1,5 @@ -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params return ( <>

    diff --git a/test/e2e/app-dir/app/app/dynamic-client/[category]/[id]/layout.js b/test/e2e/app-dir/app/app/dynamic-client/[category]/[id]/layout.js index 0d09ad0787599c..358162b55ec795 100644 --- a/test/e2e/app-dir/app/app/dynamic-client/[category]/[id]/layout.js +++ b/test/e2e/app-dir/app/app/dynamic-client/[category]/[id]/layout.js @@ -1,4 +1,8 @@ -export default function IdLayout({ children, params }) { +export default async function IdLayout(props) { + const params = await props.params + + const { children } = props + return ( <>

    diff --git a/test/e2e/app-dir/app/app/dynamic-client/[category]/[id]/page.js b/test/e2e/app-dir/app/app/dynamic-client/[category]/[id]/page.js index d3a6c0a1fe41d3..34fef9f7e6e66a 100644 --- a/test/e2e/app-dir/app/app/dynamic-client/[category]/[id]/page.js +++ b/test/e2e/app-dir/app/app/dynamic-client/[category]/[id]/page.js @@ -1,4 +1,5 @@ 'use client' +import { use } from 'react' import { useSearchParams } from 'next/navigation' import dynamic from 'next/dynamic' @@ -7,7 +8,11 @@ const Button = dynamic(() => import('../../../../components/button/button').then((mod) => mod.Button) ) -export default function IdPage({ children, params }) { +export default function IdPage(props) { + const params = use(props.params) + + const { children } = props + return ( <>

    diff --git a/test/e2e/app-dir/app/app/dynamic-client/[category]/layout.js b/test/e2e/app-dir/app/app/dynamic-client/[category]/layout.js index 2744b8a83916dd..0a0e910ef3543d 100644 --- a/test/e2e/app-dir/app/app/dynamic-client/[category]/layout.js +++ b/test/e2e/app-dir/app/app/dynamic-client/[category]/layout.js @@ -1,4 +1,8 @@ -export default function CategoryLayout({ children, params }) { +export default async function CategoryLayout(props) { + const params = await props.params + + const { children } = props + return ( <>

    diff --git a/test/e2e/app-dir/app/app/dynamic-client/layout.js b/test/e2e/app-dir/app/app/dynamic-client/layout.js index 549e0e30e6721d..d1508fbed59035 100644 --- a/test/e2e/app-dir/app/app/dynamic-client/layout.js +++ b/test/e2e/app-dir/app/app/dynamic-client/layout.js @@ -1,4 +1,8 @@ -export default function DynamicLayout({ children, params }) { +export default async function DynamicLayout(props) { + const params = await props.params + + const { children } = props + return ( <>

    diff --git a/test/e2e/app-dir/app/app/dynamic/[category]/[id]/layout.js b/test/e2e/app-dir/app/app/dynamic/[category]/[id]/layout.js index 0d09ad0787599c..358162b55ec795 100644 --- a/test/e2e/app-dir/app/app/dynamic/[category]/[id]/layout.js +++ b/test/e2e/app-dir/app/app/dynamic/[category]/[id]/layout.js @@ -1,4 +1,8 @@ -export default function IdLayout({ children, params }) { +export default async function IdLayout(props) { + const params = await props.params + + const { children } = props + return ( <>

    diff --git a/test/e2e/app-dir/app/app/dynamic/[category]/[id]/page.js b/test/e2e/app-dir/app/app/dynamic/[category]/[id]/page.js index a9551752a6ec37..be49503a994e7b 100644 --- a/test/e2e/app-dir/app/app/dynamic/[category]/[id]/page.js +++ b/test/e2e/app-dir/app/app/dynamic/[category]/[id]/page.js @@ -1,4 +1,9 @@ -export default async function IdPage({ children, params, searchParams }) { +export default async function IdPage(props) { + const params = await props.params + const searchParams = await props.searchParams + + const { children } = props + return ( <>

    diff --git a/test/e2e/app-dir/app/app/dynamic/[category]/layout.js b/test/e2e/app-dir/app/app/dynamic/[category]/layout.js index 2744b8a83916dd..0a0e910ef3543d 100644 --- a/test/e2e/app-dir/app/app/dynamic/[category]/layout.js +++ b/test/e2e/app-dir/app/app/dynamic/[category]/layout.js @@ -1,4 +1,8 @@ -export default function CategoryLayout({ children, params }) { +export default async function CategoryLayout(props) { + const params = await props.params + + const { children } = props + return ( <>

    diff --git a/test/e2e/app-dir/app/app/dynamic/layout.js b/test/e2e/app-dir/app/app/dynamic/layout.js index 549e0e30e6721d..d1508fbed59035 100644 --- a/test/e2e/app-dir/app/app/dynamic/layout.js +++ b/test/e2e/app-dir/app/app/dynamic/layout.js @@ -1,4 +1,8 @@ -export default function DynamicLayout({ children, params }) { +export default async function DynamicLayout(props) { + const params = await props.params + + const { children } = props + return ( <>

    diff --git a/test/e2e/app-dir/app/app/link-hard-push/[id]/page.js b/test/e2e/app-dir/app/app/link-hard-push/[id]/page.js index 0ce09bfa6ab7ea..3ff5c07c857251 100644 --- a/test/e2e/app-dir/app/app/link-hard-push/[id]/page.js +++ b/test/e2e/app-dir/app/app/link-hard-push/[id]/page.js @@ -1,7 +1,8 @@ import Link from 'next/link' import { nanoid } from 'nanoid' -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params const other = params.id === '123' ? '456' : '123' return ( <> diff --git a/test/e2e/app-dir/app/app/link-hard-replace/[id]/page.js b/test/e2e/app-dir/app/app/link-hard-replace/[id]/page.js index 6f69c10520d125..03a5877dd1620d 100644 --- a/test/e2e/app-dir/app/app/link-hard-replace/[id]/page.js +++ b/test/e2e/app-dir/app/app/link-hard-replace/[id]/page.js @@ -1,7 +1,8 @@ import Link from 'next/link' import { nanoid } from 'nanoid' -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params const other = params.id === '123' ? '456' : '123' return ( <> diff --git a/test/e2e/app-dir/app/app/loading-bug/[categorySlug]/page.js b/test/e2e/app-dir/app/app/loading-bug/[categorySlug]/page.js index 714616632e9671..ed795b5505d8e0 100644 --- a/test/e2e/app-dir/app/app/loading-bug/[categorySlug]/page.js +++ b/test/e2e/app-dir/app/app/loading-bug/[categorySlug]/page.js @@ -7,7 +7,8 @@ const fetchCategory = async (categorySlug) => { return categorySlug + 'abc' } -export default function Page({ params }) { +export default function Page(props) { + const params = use(props.params) const category = use(fetchCategory(params.categorySlug)) return
    {category}
    diff --git a/test/e2e/app-dir/app/app/param-and-query/[slug]/page.js b/test/e2e/app-dir/app/app/param-and-query/[slug]/page.js index 36a2c54250015c..38a1b3e454b3d0 100644 --- a/test/e2e/app-dir/app/app/param-and-query/[slug]/page.js +++ b/test/e2e/app-dir/app/app/param-and-query/[slug]/page.js @@ -1,13 +1,17 @@ 'use client' -export default async function Page({ params, searchParams }) { +import { use } from 'react' + +export default function Page(props) { + const searchParams = use(props.searchParams) + const params = use(props.params) return (

    - hello from /param-and-query/{params.slug}?slug={(await searchParams).slug} + hello from /param-and-query/{params.slug}?slug={searchParams.slug}

    ) } diff --git a/test/e2e/app-dir/app/app/partial-match-[id]/page.js b/test/e2e/app-dir/app/app/partial-match-[id]/page.js index 33429192f2adc4..95ba9eacc1adde 100644 --- a/test/e2e/app-dir/app/app/partial-match-[id]/page.js +++ b/test/e2e/app-dir/app/app/partial-match-[id]/page.js @@ -1,7 +1,7 @@ -export default function DeploymentsPage(props) { +export default async function DeploymentsPage(props) { return ( <> -

    hello from app/partial-match-[id]. ID is: {props.params.id}

    +

    hello from app/partial-match-[id]. ID is: {(await props.params).id}

    ) } diff --git a/test/e2e/app-dir/app/app/searchparams-normalization-bug/page.js b/test/e2e/app-dir/app/app/searchparams-normalization-bug/page.js index f2dfa3499ee8a9..07b0663e79c5f6 100644 --- a/test/e2e/app-dir/app/app/searchparams-normalization-bug/page.js +++ b/test/e2e/app-dir/app/app/searchparams-normalization-bug/page.js @@ -1,7 +1,7 @@ import Button from './client-component' import { headers } from 'next/headers' -export default function Page() { - const headerStore = headers() +export default async function Page() { + const headerStore = await headers() const headerValue = headerStore.get('test') || 'empty' return ( diff --git a/test/e2e/app-dir/custom-cache-control/app/app-ssg/[slug]/page.tsx b/test/e2e/app-dir/custom-cache-control/app/app-ssg/[slug]/page.tsx index 70eb489bb26b9a..0975d482424517 100644 --- a/test/e2e/app-dir/custom-cache-control/app/app-ssg/[slug]/page.tsx +++ b/test/e2e/app-dir/custom-cache-control/app/app-ssg/[slug]/page.tsx @@ -8,7 +8,8 @@ export function generateStaticParams() { ] } -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params return ( <>

    /app-ssg/[slug]

    diff --git a/test/e2e/app-dir/dynamic-data/fixtures/cache-scoped/app/connection/page.js b/test/e2e/app-dir/dynamic-data/fixtures/cache-scoped/app/connection/page.js index d15afc39b167ae..37afc69fc6f5a8 100644 --- a/test/e2e/app-dir/dynamic-data/fixtures/cache-scoped/app/connection/page.js +++ b/test/e2e/app-dir/dynamic-data/fixtures/cache-scoped/app/connection/page.js @@ -3,7 +3,7 @@ import { unstable_cache as cache } from 'next/cache' const cachedConnection = cache(async () => connection()) -export default async function Page({ searchParams }) { +export default async function Page(props) { await cachedConnection() return (
    diff --git a/test/e2e/app-dir/dynamic-data/fixtures/main/app/force-dynamic/page.js b/test/e2e/app-dir/dynamic-data/fixtures/main/app/force-dynamic/page.js index cfee26df62328c..a250df1d12e6c3 100644 --- a/test/e2e/app-dir/dynamic-data/fixtures/main/app/force-dynamic/page.js +++ b/test/e2e/app-dir/dynamic-data/fixtures/main/app/force-dynamic/page.js @@ -17,7 +17,7 @@ export default async function Page({ searchParams }) {

    headers

    - {Array.from(headers().entries()).map(([key, value]) => { + {Array.from((await headers()).entries()).map(([key, value]) => { if (key === 'cookie') return null return (
    diff --git a/test/e2e/app-dir/dynamic-data/fixtures/main/app/force-static/page.js b/test/e2e/app-dir/dynamic-data/fixtures/main/app/force-static/page.js index 6974704ef9b895..6cea00d189779f 100644 --- a/test/e2e/app-dir/dynamic-data/fixtures/main/app/force-static/page.js +++ b/test/e2e/app-dir/dynamic-data/fixtures/main/app/force-static/page.js @@ -17,7 +17,7 @@ export default async function Page({ searchParams }) {

    headers

    - {Array.from(headers().entries()).map(([key, value]) => { + {Array.from((await headers()).entries()).map(([key, value]) => { if (key === 'cookie') return null return (
    diff --git a/test/e2e/app-dir/dynamic-data/fixtures/main/app/top-level/page.js b/test/e2e/app-dir/dynamic-data/fixtures/main/app/top-level/page.js index a99598bd4dfa50..3cd347e46f6b58 100644 --- a/test/e2e/app-dir/dynamic-data/fixtures/main/app/top-level/page.js +++ b/test/e2e/app-dir/dynamic-data/fixtures/main/app/top-level/page.js @@ -15,7 +15,7 @@ export default async function Page({ searchParams }) {

    headers

    - {Array.from(headers().entries()).map(([key, value]) => { + {Array.from((await headers()).entries()).map(([key, value]) => { if (key === 'cookie') return null return (
    diff --git a/test/e2e/app-dir/dynamic-data/fixtures/require-static/app/connection/page.js b/test/e2e/app-dir/dynamic-data/fixtures/require-static/app/connection/page.js index 79beaf4c4059b1..b1375be951ebfe 100644 --- a/test/e2e/app-dir/dynamic-data/fixtures/require-static/app/connection/page.js +++ b/test/e2e/app-dir/dynamic-data/fixtures/require-static/app/connection/page.js @@ -2,7 +2,7 @@ import { connection } from 'next/server' export const dynamic = 'error' -export default async function Page({ searchParams }) { +export default async function Page(props) { await connection() return (
    diff --git a/test/e2e/app-dir/dynamic-data/fixtures/require-static/app/cookies/page.js b/test/e2e/app-dir/dynamic-data/fixtures/require-static/app/cookies/page.js index 754f3a41447094..9f1f160414e682 100644 --- a/test/e2e/app-dir/dynamic-data/fixtures/require-static/app/cookies/page.js +++ b/test/e2e/app-dir/dynamic-data/fixtures/require-static/app/cookies/page.js @@ -2,7 +2,7 @@ import { cookies } from 'next/headers' export const dynamic = 'error' -export default async function Page({ searchParams }) { +export default async function Page(props) { return (
    diff --git a/test/e2e/app-dir/dynamic-data/fixtures/require-static/app/headers/page.js b/test/e2e/app-dir/dynamic-data/fixtures/require-static/app/headers/page.js index 1b3486550f8162..674a2a30e9c3bc 100644 --- a/test/e2e/app-dir/dynamic-data/fixtures/require-static/app/headers/page.js +++ b/test/e2e/app-dir/dynamic-data/fixtures/require-static/app/headers/page.js @@ -11,7 +11,7 @@ export default async function Page() {

    headers

    - {Array.from(headers().entries()).map(([key, value]) => { + {Array.from((await headers()).entries()).map(([key, value]) => { if (key === 'cookie') return null return (
    diff --git a/test/e2e/app-dir/dynamic-io-segment-configs/app/dynamic-params/[slug]/page.tsx b/test/e2e/app-dir/dynamic-io-segment-configs/app/dynamic-params/[slug]/page.tsx index 7df18935de8ac8..fc72c63b684251 100644 --- a/test/e2e/app-dir/dynamic-io-segment-configs/app/dynamic-params/[slug]/page.tsx +++ b/test/e2e/app-dir/dynamic-io-segment-configs/app/dynamic-params/[slug]/page.tsx @@ -3,7 +3,8 @@ export async function generateStaticParams() { return [{ slug: 'foo' }, { slug: 'bar' }, { slug: 'baz' }] } -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params const { slug } = params return
    Hello from {slug}
    } diff --git a/test/e2e/app-dir/edge-route-rewrite/app/dynamic/[slug]/route.ts b/test/e2e/app-dir/edge-route-rewrite/app/dynamic/[slug]/route.ts index 70baa7bac15a86..2c42a54d45f1b7 100644 --- a/test/e2e/app-dir/edge-route-rewrite/app/dynamic/[slug]/route.ts +++ b/test/e2e/app-dir/edge-route-rewrite/app/dynamic/[slug]/route.ts @@ -1,7 +1,8 @@ export const runtime = 'edge' export const dynamic = 'force-dynamic' -export function GET(req, { params }) { +export async function GET(req, props) { + const params = await props.params return new Response( `Hello from /app/dynamic/[slug]/route.ts. Slug: ${params.slug}` ) diff --git a/test/e2e/app-dir/errors/app/ssr-error-client-component/page.js b/test/e2e/app-dir/errors/app/ssr-error-client-component/page.js index 5b6bb43c2cc526..36a32fbfb40893 100644 --- a/test/e2e/app-dir/errors/app/ssr-error-client-component/page.js +++ b/test/e2e/app-dir/errors/app/ssr-error-client-component/page.js @@ -1,8 +1,8 @@ import ClientComp from './client-component' import { headers } from 'next/headers' -export default function Page() { +export default async function Page() { // Opt-in to SSR. - headers() + await headers() return } diff --git a/test/e2e/app-dir/front-redirect-issue/app/app-future/[lang]/(dashboard)/[teamSlug]/page.tsx b/test/e2e/app-dir/front-redirect-issue/app/app-future/[lang]/(dashboard)/[teamSlug]/page.tsx index 6559e4d85d7e17..a9222d01cb4fcc 100644 --- a/test/e2e/app-dir/front-redirect-issue/app/app-future/[lang]/(dashboard)/[teamSlug]/page.tsx +++ b/test/e2e/app-dir/front-redirect-issue/app/app-future/[lang]/(dashboard)/[teamSlug]/page.tsx @@ -1,6 +1,7 @@ import { redirect, notFound } from 'next/navigation' -export default async function TeamDashboardPage({ params }: any) { +export default async function TeamDashboardPage(props: any) { + const params = await props.params await new Promise((resolve) => setTimeout(resolve, 1000)) const username = 'vercel-user' if (params.teamSlug === username) { diff --git a/test/e2e/app-dir/headers-static-bailout/app/page-with-headers/page.tsx b/test/e2e/app-dir/headers-static-bailout/app/page-with-headers/page.tsx index 00c49b0df56de0..5e95772dcecc18 100644 --- a/test/e2e/app-dir/headers-static-bailout/app/page-with-headers/page.tsx +++ b/test/e2e/app-dir/headers-static-bailout/app/page-with-headers/page.tsx @@ -1,8 +1,8 @@ import { nanoid } from 'nanoid' import { headers } from 'next/headers' -export default function Page() { - headers() +export default async function Page() { + await headers() return ( <>

    Dynamic Page

    diff --git a/test/e2e/app-dir/hooks/app/hooks/use-draft-mode/page.js b/test/e2e/app-dir/hooks/app/hooks/use-draft-mode/page.js index bf91e2ee399f1c..7ed8503a40f864 100644 --- a/test/e2e/app-dir/hooks/app/hooks/use-draft-mode/page.js +++ b/test/e2e/app-dir/hooks/app/hooks/use-draft-mode/page.js @@ -1,7 +1,7 @@ import { draftMode } from 'next/headers' -export default function Page() { - const { isEnabled } = draftMode() +export default async function Page() { + const { isEnabled } = await draftMode() return ( <> diff --git a/test/e2e/app-dir/hooks/app/hooks/use-headers/page.js b/test/e2e/app-dir/hooks/app/hooks/use-headers/page.js index c55642f17fa490..cceb5b01cb8dfd 100644 --- a/test/e2e/app-dir/hooks/app/hooks/use-headers/page.js +++ b/test/e2e/app-dir/hooks/app/hooks/use-headers/page.js @@ -1,7 +1,7 @@ import { headers } from 'next/headers' -export default function Page() { - const headersList = headers() +export default async function Page() { + const headersList = await headers() const hasHeader = headersList.get('x-use-headers') === 'value' const referer = headersList.get('referer') diff --git a/test/e2e/app-dir/layout-params/app/base/[param1]/[param2]/layout.tsx b/test/e2e/app-dir/layout-params/app/base/[param1]/[param2]/layout.tsx index a86d479a889057..97344427aa9e47 100644 --- a/test/e2e/app-dir/layout-params/app/base/[param1]/[param2]/layout.tsx +++ b/test/e2e/app-dir/layout-params/app/base/[param1]/[param2]/layout.tsx @@ -1,13 +1,14 @@ import React from 'react' import ShowParams from '../../../show-params' -export default async function Layout({ - children, - params, -}: { +export default async function Layout(props: { children: React.ReactNode params: Promise<{}> }) { + const params = await props.params + + const { children } = props + return (
    diff --git a/test/e2e/app-dir/layout-params/app/base/[param1]/layout.tsx b/test/e2e/app-dir/layout-params/app/base/[param1]/layout.tsx index 6bbacf3a656e3c..301f5dde4b60d1 100644 --- a/test/e2e/app-dir/layout-params/app/base/[param1]/layout.tsx +++ b/test/e2e/app-dir/layout-params/app/base/[param1]/layout.tsx @@ -1,13 +1,14 @@ import React from 'react' import ShowParams from '../../show-params' -export default async function Layout({ - children, - params, -}: { +export default async function Layout(props: { children: React.ReactNode params: Promise<{}> }) { + const params = await props.params + + const { children } = props + return (
    diff --git a/test/e2e/app-dir/layout-params/app/base/layout.tsx b/test/e2e/app-dir/layout-params/app/base/layout.tsx index 98b9f3ca2385f7..98686e5ed57fe9 100644 --- a/test/e2e/app-dir/layout-params/app/base/layout.tsx +++ b/test/e2e/app-dir/layout-params/app/base/layout.tsx @@ -1,13 +1,14 @@ import React from 'react' import ShowParams from '../show-params' -export default async function Layout({ - children, - params, -}: { +export default async function Layout(props: { children: React.ReactNode params: Promise<{}> }) { + const params = await props.params + + const { children } = props + return (
    diff --git a/test/e2e/app-dir/layout-params/app/catchall/[...params]/layout.tsx b/test/e2e/app-dir/layout-params/app/catchall/[...params]/layout.tsx index 6bbacf3a656e3c..301f5dde4b60d1 100644 --- a/test/e2e/app-dir/layout-params/app/catchall/[...params]/layout.tsx +++ b/test/e2e/app-dir/layout-params/app/catchall/[...params]/layout.tsx @@ -1,13 +1,14 @@ import React from 'react' import ShowParams from '../../show-params' -export default async function Layout({ - children, - params, -}: { +export default async function Layout(props: { children: React.ReactNode params: Promise<{}> }) { + const params = await props.params + + const { children } = props + return (
    diff --git a/test/e2e/app-dir/layout-params/app/layout.tsx b/test/e2e/app-dir/layout-params/app/layout.tsx index 8fdcdc6cb8b61f..b21a3a451b17dd 100644 --- a/test/e2e/app-dir/layout-params/app/layout.tsx +++ b/test/e2e/app-dir/layout-params/app/layout.tsx @@ -1,13 +1,14 @@ import React from 'react' import ShowParams from './show-params' -export default async function Layout({ - children, - params, -}: { +export default async function Layout(props: { children: React.ReactNode params: Promise<{}> }) { + const params = await props.params + + const { children } = props + return ( diff --git a/test/e2e/app-dir/layout-params/app/optional-catchall/[[...params]]/layout.tsx b/test/e2e/app-dir/layout-params/app/optional-catchall/[[...params]]/layout.tsx index 6bbacf3a656e3c..301f5dde4b60d1 100644 --- a/test/e2e/app-dir/layout-params/app/optional-catchall/[[...params]]/layout.tsx +++ b/test/e2e/app-dir/layout-params/app/optional-catchall/[[...params]]/layout.tsx @@ -1,13 +1,14 @@ import React from 'react' import ShowParams from '../../show-params' -export default async function Layout({ - children, - params, -}: { +export default async function Layout(props: { children: React.ReactNode params: Promise<{}> }) { + const params = await props.params + + const { children } = props + return (
    diff --git a/test/e2e/app-dir/logging/app/headers/page.js b/test/e2e/app-dir/logging/app/headers/page.js index a4946331291b5a..d442f5d1222031 100644 --- a/test/e2e/app-dir/logging/app/headers/page.js +++ b/test/e2e/app-dir/logging/app/headers/page.js @@ -1,6 +1,6 @@ import { headers } from 'next/headers' -export default function Page() { - headers() +export default async function Page() { + await headers() return

    {'headers()'}

    } diff --git a/test/e2e/app-dir/next-after-app/app/nodejs/[id]/dynamic/page.js b/test/e2e/app-dir/next-after-app/app/nodejs/[id]/dynamic/page.js index d378b4fa795c4b..4f2006302bcdb8 100644 --- a/test/e2e/app-dir/next-after-app/app/nodejs/[id]/dynamic/page.js +++ b/test/e2e/app-dir/next-after-app/app/nodejs/[id]/dynamic/page.js @@ -4,7 +4,8 @@ import { cliLog } from '../../../../utils/log' const thing = cache(() => Symbol('cache me please')) -export default function Index({ params }) { +export default async function Index(props) { + const params = await props.params const valueFromRender = thing() after(() => { diff --git a/test/e2e/app-dir/next-after-app/app/nodejs/[id]/with-action/page.js b/test/e2e/app-dir/next-after-app/app/nodejs/[id]/with-action/page.js index 24dff11ddb61c4..d001d57bd9af84 100644 --- a/test/e2e/app-dir/next-after-app/app/nodejs/[id]/with-action/page.js +++ b/test/e2e/app-dir/next-after-app/app/nodejs/[id]/with-action/page.js @@ -4,7 +4,8 @@ import { cliLog } from '../../../../utils/log' const thing = cache(() => Symbol('cache me please')) -export default function Index({ params }) { +export default async function Index(props) { + const params = await props.params const action = async () => { 'use server' diff --git a/test/e2e/app-dir/next-after-app/app/nodejs/[id]/with-metadata/page.js b/test/e2e/app-dir/next-after-app/app/nodejs/[id]/with-metadata/page.js index 696440e417d235..bebd69f2afc243 100644 --- a/test/e2e/app-dir/next-after-app/app/nodejs/[id]/with-metadata/page.js +++ b/test/e2e/app-dir/next-after-app/app/nodejs/[id]/with-metadata/page.js @@ -1,7 +1,8 @@ import { unstable_after as after } from 'next/server' import { cliLog } from '../../../../utils/log' -export function generateMetadata({ params }) { +export async function generateMetadata(props) { + const params = await props.params after(() => { cliLog({ source: '[metadata] /[id]/with-metadata', diff --git a/test/e2e/app-dir/next-after-app/app/nodejs/nested-after/page.js b/test/e2e/app-dir/next-after-app/app/nodejs/nested-after/page.js index e8f5c0b10eb3dc..b80e86a7f3038b 100644 --- a/test/e2e/app-dir/next-after-app/app/nodejs/nested-after/page.js +++ b/test/e2e/app-dir/next-after-app/app/nodejs/nested-after/page.js @@ -4,7 +4,7 @@ import { cliLog } from '../../../utils/log' const thing = cache(() => Symbol('cache me please')) -export default async function Index({ params }) { +export default async function Index(props) { await connection() const valueFromRender = thing() diff --git a/test/e2e/app-dir/not-found-default/app/(group)/group-dynamic/[id]/page.js b/test/e2e/app-dir/not-found-default/app/(group)/group-dynamic/[id]/page.js index f28071f5be5b5b..edeff78612fee6 100644 --- a/test/e2e/app-dir/not-found-default/app/(group)/group-dynamic/[id]/page.js +++ b/test/e2e/app-dir/not-found-default/app/(group)/group-dynamic/[id]/page.js @@ -1,6 +1,7 @@ import { notFound } from 'next/navigation' -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params if (params.id === '404') { notFound() } diff --git a/test/e2e/app-dir/not-found/basic/app/dynamic-layout-without-not-found/[id]/page.js b/test/e2e/app-dir/not-found/basic/app/dynamic-layout-without-not-found/[id]/page.js index 9618e367358970..8638f5df50c1b0 100644 --- a/test/e2e/app-dir/not-found/basic/app/dynamic-layout-without-not-found/[id]/page.js +++ b/test/e2e/app-dir/not-found/basic/app/dynamic-layout-without-not-found/[id]/page.js @@ -3,7 +3,11 @@ import { notFound } from 'next/navigation' // avoid static generation to fill the dynamic params export const dynamic = 'force-dynamic' -export default function Page({ params: { id } }) { +export default async function Page(props) { + const params = await props.params + + const { id } = params + if (id === '404') { notFound() } diff --git a/test/e2e/app-dir/not-found/basic/app/dynamic/[id]/page.js b/test/e2e/app-dir/not-found/basic/app/dynamic/[id]/page.js index bc4249f9d59676..ec018524b925ed 100644 --- a/test/e2e/app-dir/not-found/basic/app/dynamic/[id]/page.js +++ b/test/e2e/app-dir/not-found/basic/app/dynamic/[id]/page.js @@ -3,7 +3,11 @@ import { notFound } from 'next/navigation' // avoid static generation to fill the dynamic params export const dynamic = 'force-dynamic' -export default function Page({ params: { id } }) { +export default async function Page(props) { + const params = await props.params + + const { id } = params + if (id === '404') { notFound() } diff --git a/test/e2e/app-dir/not-found/basic/app/error-boundary/nested/[dynamic]/page.js b/test/e2e/app-dir/not-found/basic/app/error-boundary/nested/[dynamic]/page.js index 623218d0e366bc..5f034cc5f4635d 100644 --- a/test/e2e/app-dir/not-found/basic/app/error-boundary/nested/[dynamic]/page.js +++ b/test/e2e/app-dir/not-found/basic/app/error-boundary/nested/[dynamic]/page.js @@ -1,7 +1,8 @@ import { notFound } from 'next/navigation' import React from 'react' -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params if (params.dynamic === 'trigger-not-found') { notFound() } diff --git a/test/e2e/app-dir/not-found/group-route-root-not-found/app/(group)/group-dynamic/[id]/page.js b/test/e2e/app-dir/not-found/group-route-root-not-found/app/(group)/group-dynamic/[id]/page.js index 0f514527eb10c5..68afd0b833b94f 100644 --- a/test/e2e/app-dir/not-found/group-route-root-not-found/app/(group)/group-dynamic/[id]/page.js +++ b/test/e2e/app-dir/not-found/group-route-root-not-found/app/(group)/group-dynamic/[id]/page.js @@ -2,7 +2,8 @@ import { notFound } from 'next/navigation' export const dynamic = 'force-dynamic' -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params if (params.id === '404') { notFound() } diff --git a/test/e2e/app-dir/parallel-routes-and-interception/app/(group)/intercepting-parallel-modal/[username]/@modal/default.js b/test/e2e/app-dir/parallel-routes-and-interception/app/(group)/intercepting-parallel-modal/[username]/@modal/default.js index a6a4d62eae8726..88a733f86e3ed3 100644 --- a/test/e2e/app-dir/parallel-routes-and-interception/app/(group)/intercepting-parallel-modal/[username]/@modal/default.js +++ b/test/e2e/app-dir/parallel-routes-and-interception/app/(group)/intercepting-parallel-modal/[username]/@modal/default.js @@ -1,3 +1,3 @@ -export default function Page({ params }) { +export default function Page(props) { return
    default modal slot
    } diff --git a/test/e2e/app-dir/parallel-routes-catchall-default/app/[locale]/nested/[foo]/[bar]/@slot/[baz]/page.tsx b/test/e2e/app-dir/parallel-routes-catchall-default/app/[locale]/nested/[foo]/[bar]/@slot/[baz]/page.tsx index 6078f8edee1d12..1cfe465cbed24a 100644 --- a/test/e2e/app-dir/parallel-routes-catchall-default/app/[locale]/nested/[foo]/[bar]/@slot/[baz]/page.tsx +++ b/test/e2e/app-dir/parallel-routes-catchall-default/app/[locale]/nested/[foo]/[bar]/@slot/[baz]/page.tsx @@ -1,3 +1,3 @@ -export default function Page({ params }) { +export default function Page(props) { return
    /[locale]/nested/[foo]/[bar]/@slot/[baz]/page.tsx
    } diff --git a/test/e2e/app-dir/parallel-routes-catchall-dynamic-segment/app/[locale]/nested/[foo]/[bar]/@slot0/[baz]/page.tsx b/test/e2e/app-dir/parallel-routes-catchall-dynamic-segment/app/[locale]/nested/[foo]/[bar]/@slot0/[baz]/page.tsx index 20352333680b33..f6550acdf7189e 100644 --- a/test/e2e/app-dir/parallel-routes-catchall-dynamic-segment/app/[locale]/nested/[foo]/[bar]/@slot0/[baz]/page.tsx +++ b/test/e2e/app-dir/parallel-routes-catchall-dynamic-segment/app/[locale]/nested/[foo]/[bar]/@slot0/[baz]/page.tsx @@ -1,3 +1,3 @@ -export default function Page({ params }) { +export default function Page(props) { return
    /[locale]/nested/[foo]/[bar]/@slot0/[baz]/page.tsx
    } diff --git a/test/e2e/app-dir/parallel-routes-catchall-dynamic-segment/app/[locale]/nested/[foo]/[bar]/@slot0/default.tsx b/test/e2e/app-dir/parallel-routes-catchall-dynamic-segment/app/[locale]/nested/[foo]/[bar]/@slot0/default.tsx index 00a1761e9ed439..08411c06317f7a 100644 --- a/test/e2e/app-dir/parallel-routes-catchall-dynamic-segment/app/[locale]/nested/[foo]/[bar]/@slot0/default.tsx +++ b/test/e2e/app-dir/parallel-routes-catchall-dynamic-segment/app/[locale]/nested/[foo]/[bar]/@slot0/default.tsx @@ -1,3 +1,3 @@ -export default function Page({ params }) { +export default function Page(props) { return
    /[locale]/nested/[foo]/[bar]/@slot0/default.tsx
    } diff --git a/test/e2e/app-dir/parallel-routes-catchall-dynamic-segment/app/[locale]/nested/[foo]/[bar]/@slot1/[baz]/[qux]/page.tsx b/test/e2e/app-dir/parallel-routes-catchall-dynamic-segment/app/[locale]/nested/[foo]/[bar]/@slot1/[baz]/[qux]/page.tsx index e7fa85b2758c4f..1c318b0536ea6f 100644 --- a/test/e2e/app-dir/parallel-routes-catchall-dynamic-segment/app/[locale]/nested/[foo]/[bar]/@slot1/[baz]/[qux]/page.tsx +++ b/test/e2e/app-dir/parallel-routes-catchall-dynamic-segment/app/[locale]/nested/[foo]/[bar]/@slot1/[baz]/[qux]/page.tsx @@ -1,3 +1,3 @@ -export default function Page({ params }) { +export default function Page(props) { return
    /[locale]/nested/[foo]/[bar]/@slot1/[baz]/[qux]/page.tsx
    } diff --git a/test/e2e/app-dir/parallel-routes-catchall-dynamic-segment/app/[locale]/nested/[foo]/[bar]/@slot1/[baz]/page.tsx b/test/e2e/app-dir/parallel-routes-catchall-dynamic-segment/app/[locale]/nested/[foo]/[bar]/@slot1/[baz]/page.tsx index 689772ea5aedb3..3b4b0f1328bdec 100644 --- a/test/e2e/app-dir/parallel-routes-catchall-dynamic-segment/app/[locale]/nested/[foo]/[bar]/@slot1/[baz]/page.tsx +++ b/test/e2e/app-dir/parallel-routes-catchall-dynamic-segment/app/[locale]/nested/[foo]/[bar]/@slot1/[baz]/page.tsx @@ -1,3 +1,3 @@ -export default function Page({ params }) { +export default function Page(props) { return
    /[locale]/nested/[foo]/[bar]/@slot1/[baz]/page.tsx
    } diff --git a/test/e2e/app-dir/parallel-routes-catchall-slotted-non-catchalls/app/[locale]/nested/@slot0/bar/page.tsx b/test/e2e/app-dir/parallel-routes-catchall-slotted-non-catchalls/app/[locale]/nested/@slot0/bar/page.tsx index 274474eb60c7d0..ea33ff24c0f478 100644 --- a/test/e2e/app-dir/parallel-routes-catchall-slotted-non-catchalls/app/[locale]/nested/@slot0/bar/page.tsx +++ b/test/e2e/app-dir/parallel-routes-catchall-slotted-non-catchalls/app/[locale]/nested/@slot0/bar/page.tsx @@ -1,3 +1,3 @@ -export default function Page({ params }) { +export default function Page(props) { return
    /[locale]/nested/@slot0/bar/page.tsx
    } diff --git a/test/e2e/app-dir/parallel-routes-catchall-slotted-non-catchalls/app/[locale]/nested/@slot0/foo/page.tsx b/test/e2e/app-dir/parallel-routes-catchall-slotted-non-catchalls/app/[locale]/nested/@slot0/foo/page.tsx index 5467ec64277990..86a80719cfcde8 100644 --- a/test/e2e/app-dir/parallel-routes-catchall-slotted-non-catchalls/app/[locale]/nested/@slot0/foo/page.tsx +++ b/test/e2e/app-dir/parallel-routes-catchall-slotted-non-catchalls/app/[locale]/nested/@slot0/foo/page.tsx @@ -1,3 +1,3 @@ -export default function Page({ params }) { +export default function Page(props) { return
    /[locale]/nested/@slot0/foo/page.tsx
    } diff --git a/test/e2e/app-dir/parallel-routes-catchall-slotted-non-catchalls/app/[locale]/nested/@slot1/baz/page.tsx b/test/e2e/app-dir/parallel-routes-catchall-slotted-non-catchalls/app/[locale]/nested/@slot1/baz/page.tsx index f82a2c5db676fb..333cf5ec873b29 100644 --- a/test/e2e/app-dir/parallel-routes-catchall-slotted-non-catchalls/app/[locale]/nested/@slot1/baz/page.tsx +++ b/test/e2e/app-dir/parallel-routes-catchall-slotted-non-catchalls/app/[locale]/nested/@slot1/baz/page.tsx @@ -1,3 +1,3 @@ -export default function Page({ params }) { +export default function Page(props) { return
    /[locale]/nested/@slot1/baz/page.tsx
    } diff --git a/test/e2e/app-dir/parallel-routes-revalidation/app/dynamic-refresh/[dynamic]/@modal/(.)login/page.tsx b/test/e2e/app-dir/parallel-routes-revalidation/app/dynamic-refresh/[dynamic]/@modal/(.)login/page.tsx index ad8a4c280bd52f..3296952a5f742f 100644 --- a/test/e2e/app-dir/parallel-routes-revalidation/app/dynamic-refresh/[dynamic]/@modal/(.)login/page.tsx +++ b/test/e2e/app-dir/parallel-routes-revalidation/app/dynamic-refresh/[dynamic]/@modal/(.)login/page.tsx @@ -4,12 +4,14 @@ import { UpdateSearchParamsButton } from '../../../../components/UpdateSearchPar const getRandom = async () => Math.random() -export default async function Page({ params, searchParams }) { +export default async function Page(props) { + const searchParams = await props.searchParams + const params = await props.params const someProp = await getRandom() return ( -
    {(await params).dynamic}
    +
    {params.dynamic}
    Modal Page @@ -17,10 +19,7 @@ export default async function Page({ params, searchParams }) {
    - +
    ) diff --git a/test/e2e/app-dir/parallel-routes-revalidation/app/dynamic-refresh/[dynamic]/page.tsx b/test/e2e/app-dir/parallel-routes-revalidation/app/dynamic-refresh/[dynamic]/page.tsx index 07a2856a5ef44c..c92536645608fd 100644 --- a/test/e2e/app-dir/parallel-routes-revalidation/app/dynamic-refresh/[dynamic]/page.tsx +++ b/test/e2e/app-dir/parallel-routes-revalidation/app/dynamic-refresh/[dynamic]/page.tsx @@ -1,8 +1,8 @@ import Link from 'next/link' import { UpdateSearchParamsButton } from '../../components/UpdateSearchParamsButton' -export default async function Home({ searchParams }) { - const sp = await searchParams +export default async function Home(props) { + const searchParams = await props.searchParams return (
    @@ -11,7 +11,7 @@ export default async function Home({ searchParams }) {
    Random # from Root Page: {Math.random()}
    - +
    ) } diff --git a/test/e2e/app-dir/parallel-routes-revalidation/app/refreshing/@modal/(.)login/page.tsx b/test/e2e/app-dir/parallel-routes-revalidation/app/refreshing/@modal/(.)login/page.tsx index dac2630832c053..82dfbdb2359b29 100644 --- a/test/e2e/app-dir/parallel-routes-revalidation/app/refreshing/@modal/(.)login/page.tsx +++ b/test/e2e/app-dir/parallel-routes-revalidation/app/refreshing/@modal/(.)login/page.tsx @@ -4,7 +4,8 @@ import { UpdateSearchParamsButton } from '../../../components/UpdateSearchParams const getRandom = async () => Math.random() -export default async function Page({ searchParams }) { +export default async function Page(props) { + const searchParams = await props.searchParams const someProp = await getRandom() return ( @@ -16,10 +17,7 @@ export default async function Page({ searchParams }) {
    - +
    ) diff --git a/test/e2e/app-dir/parallel-routes-revalidation/app/refreshing/page.tsx b/test/e2e/app-dir/parallel-routes-revalidation/app/refreshing/page.tsx index 68f5fb29b99c5e..82075982d7705c 100644 --- a/test/e2e/app-dir/parallel-routes-revalidation/app/refreshing/page.tsx +++ b/test/e2e/app-dir/parallel-routes-revalidation/app/refreshing/page.tsx @@ -1,7 +1,8 @@ import Link from 'next/link' import { UpdateSearchParamsButton } from '../components/UpdateSearchParamsButton' -export default async function Home({ searchParams }) { +export default async function Home(props) { + const searchParams = await props.searchParams return (
    @@ -10,7 +11,7 @@ export default async function Home({ searchParams }) {
    Random # from Root Page: {Math.random()}
    - +
    ) } diff --git a/test/e2e/app-dir/ppr-full/app/dynamic-data/force-dynamic/page.jsx b/test/e2e/app-dir/ppr-full/app/dynamic-data/force-dynamic/page.jsx index d58e7bd96aa9e8..59ce4604bd7882 100644 --- a/test/e2e/app-dir/ppr-full/app/dynamic-data/force-dynamic/page.jsx +++ b/test/e2e/app-dir/ppr-full/app/dynamic-data/force-dynamic/page.jsx @@ -4,7 +4,8 @@ import { ServerHtml } from '../../../components/server-html' export const dynamic = 'force-dynamic' -export default ({ searchParams }) => { +export default async (props) => { + const searchParams = await props.searchParams return ( <> diff --git a/test/e2e/app-dir/ppr-full/app/dynamic-data/force-static/page.jsx b/test/e2e/app-dir/ppr-full/app/dynamic-data/force-static/page.jsx index 47f57780e72bb3..7b4d6e97b09c72 100644 --- a/test/e2e/app-dir/ppr-full/app/dynamic-data/force-static/page.jsx +++ b/test/e2e/app-dir/ppr-full/app/dynamic-data/force-static/page.jsx @@ -5,7 +5,8 @@ import { ServerHtml } from '../../../components/server-html' export const dynamic = 'force-static' export const revalidate = 60 -export default ({ searchParams }) => { +export default async (props) => { + const searchParams = await props.searchParams return ( <> diff --git a/test/e2e/app-dir/ppr-full/app/dynamic-data/incidental-postpone/force-dynamic/page.jsx b/test/e2e/app-dir/ppr-full/app/dynamic-data/incidental-postpone/force-dynamic/page.jsx index 98ec3d0ac1e2df..d50918e635673f 100644 --- a/test/e2e/app-dir/ppr-full/app/dynamic-data/incidental-postpone/force-dynamic/page.jsx +++ b/test/e2e/app-dir/ppr-full/app/dynamic-data/incidental-postpone/force-dynamic/page.jsx @@ -4,7 +4,8 @@ import { ServerHtml } from '../../../../components/server-html' export const dynamic = 'force-dynamic' -export default ({ searchParams }) => { +export default async (props) => { + const searchParams = await props.searchParams return ( <> diff --git a/test/e2e/app-dir/ppr-full/app/dynamic-data/incidental-postpone/force-static/page.jsx b/test/e2e/app-dir/ppr-full/app/dynamic-data/incidental-postpone/force-static/page.jsx index 4eec05d6e9b4ba..353bec982dbb64 100644 --- a/test/e2e/app-dir/ppr-full/app/dynamic-data/incidental-postpone/force-static/page.jsx +++ b/test/e2e/app-dir/ppr-full/app/dynamic-data/incidental-postpone/force-static/page.jsx @@ -4,7 +4,8 @@ import { ServerHtml } from '../../../../components/server-html' export const dynamic = 'force-static' -export default ({ searchParams }) => { +export default async (props) => { + const searchParams = await props.searchParams return ( <> diff --git a/test/e2e/app-dir/ppr-full/app/dynamic-data/incidental-postpone/page.jsx b/test/e2e/app-dir/ppr-full/app/dynamic-data/incidental-postpone/page.jsx index 2a3a3f98a3b7fa..5e7cd19c170950 100644 --- a/test/e2e/app-dir/ppr-full/app/dynamic-data/incidental-postpone/page.jsx +++ b/test/e2e/app-dir/ppr-full/app/dynamic-data/incidental-postpone/page.jsx @@ -2,12 +2,12 @@ import { Suspense, unstable_postpone as postpone } from 'react' import { Optimistic } from '../../../components/optimistic' import { ServerHtml } from '../../../components/server-html' -export default ({ searchParams }) => { +export default (props) => { return ( <> - + diff --git a/test/e2e/app-dir/ppr-full/app/dynamic-data/page.jsx b/test/e2e/app-dir/ppr-full/app/dynamic-data/page.jsx index 509e2bd384b5f1..2fb79364b84997 100644 --- a/test/e2e/app-dir/ppr-full/app/dynamic-data/page.jsx +++ b/test/e2e/app-dir/ppr-full/app/dynamic-data/page.jsx @@ -2,12 +2,12 @@ import { Suspense } from 'react' import { Optimistic } from '../../components/optimistic' import { ServerHtml } from '../../components/server-html' -export default ({ searchParams }) => { +export default (props) => { return ( <> - + ) diff --git a/test/e2e/app-dir/ppr-full/app/dynamic/force-dynamic/nested/[slug]/page.jsx b/test/e2e/app-dir/ppr-full/app/dynamic/force-dynamic/nested/[slug]/page.jsx index 7295f699058927..5926fdd9370011 100644 --- a/test/e2e/app-dir/ppr-full/app/dynamic/force-dynamic/nested/[slug]/page.jsx +++ b/test/e2e/app-dir/ppr-full/app/dynamic/force-dynamic/nested/[slug]/page.jsx @@ -7,7 +7,11 @@ export function generateStaticParams() { return [] } -export default ({ params: { slug } }) => { +export default async (props) => { + const params = await props.params + + const { slug } = params + return ( {children} diff --git a/test/e2e/app-dir/ppr-full/app/fallback/client/params/page/[slug]/page.jsx b/test/e2e/app-dir/ppr-full/app/fallback/client/params/page/[slug]/page.jsx index 9a53bb80b8240f..0470609db7dac2 100644 --- a/test/e2e/app-dir/ppr-full/app/fallback/client/params/page/[slug]/page.jsx +++ b/test/e2e/app-dir/ppr-full/app/fallback/client/params/page/[slug]/page.jsx @@ -1,6 +1,7 @@ import Dynamic from './dynamic' -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params return (
    diff --git a/test/e2e/app-dir/ppr-full/app/fallback/dynamic/error/[slug]/page.jsx b/test/e2e/app-dir/ppr-full/app/fallback/dynamic/error/[slug]/page.jsx index 592773a9a0bd5a..9eb251aa21fc60 100644 --- a/test/e2e/app-dir/ppr-full/app/fallback/dynamic/error/[slug]/page.jsx +++ b/test/e2e/app-dir/ppr-full/app/fallback/dynamic/error/[slug]/page.jsx @@ -1,6 +1,7 @@ import { setTimeout } from 'timers/promises' -export default async function Page({ params }) { +export default async function Page(props) { + const params = await props.params await setTimeout(1000) const { slug } = params diff --git a/test/e2e/app-dir/ppr-full/app/fallback/dynamic/params/[slug]/page.jsx b/test/e2e/app-dir/ppr-full/app/fallback/dynamic/params/[slug]/page.jsx index bec77bf1db5bd8..bbb3f0d30caec7 100644 --- a/test/e2e/app-dir/ppr-full/app/fallback/dynamic/params/[slug]/page.jsx +++ b/test/e2e/app-dir/ppr-full/app/fallback/dynamic/params/[slug]/page.jsx @@ -2,13 +2,14 @@ import { headers } from 'next/headers' import { Suspense } from 'react' import { setTimeout } from 'timers/promises' -function Dynamic() { - const agent = headers().get('user-agent') +async function Dynamic() { + const agent = (await headers()).get('user-agent') return
    {agent}
    } -export default async function Page({ params }) { +export default async function Page(props) { + const params = await props.params await setTimeout(1000) const { slug } = params diff --git a/test/e2e/app-dir/ppr-full/app/fallback/nested/params/[...slug]/page.jsx b/test/e2e/app-dir/ppr-full/app/fallback/nested/params/[...slug]/page.jsx index 9ff830ad21f796..441f074f8610e2 100644 --- a/test/e2e/app-dir/ppr-full/app/fallback/nested/params/[...slug]/page.jsx +++ b/test/e2e/app-dir/ppr-full/app/fallback/nested/params/[...slug]/page.jsx @@ -1,6 +1,7 @@ import { setTimeout } from 'timers/promises' -export default async function Page({ params }) { +export default async function Page(props) { + const params = await props.params await setTimeout(1000) return
    {params.slug.join('/')}
    diff --git a/test/e2e/app-dir/ppr-full/app/fallback/params/[slug]/page.jsx b/test/e2e/app-dir/ppr-full/app/fallback/params/[slug]/page.jsx index ddc915c6967310..00e16814f07529 100644 --- a/test/e2e/app-dir/ppr-full/app/fallback/params/[slug]/page.jsx +++ b/test/e2e/app-dir/ppr-full/app/fallback/params/[slug]/page.jsx @@ -1,6 +1,7 @@ import { setTimeout } from 'timers/promises' -export default async function Page({ params }) { +export default async function Page(props) { + const params = await props.params await setTimeout(1000) return
    {params.slug}
    diff --git a/test/e2e/app-dir/ppr-full/app/loading/[slug]/page.jsx b/test/e2e/app-dir/ppr-full/app/loading/[slug]/page.jsx index 027d39da1c2b64..d8518345b228d9 100644 --- a/test/e2e/app-dir/ppr-full/app/loading/[slug]/page.jsx +++ b/test/e2e/app-dir/ppr-full/app/loading/[slug]/page.jsx @@ -3,7 +3,11 @@ import { Dynamic } from '../../../components/dynamic' export const revalidate = 60 -export default ({ params: { slug } }) => { +export default async (props) => { + const params = await props.params + + const { slug } = params + return ( }> diff --git a/test/e2e/app-dir/ppr-full/app/nested/[slug]/page.jsx b/test/e2e/app-dir/ppr-full/app/nested/[slug]/page.jsx index fec0c0923d4271..52958d91692705 100644 --- a/test/e2e/app-dir/ppr-full/app/nested/[slug]/page.jsx +++ b/test/e2e/app-dir/ppr-full/app/nested/[slug]/page.jsx @@ -3,7 +3,11 @@ import { Dynamic } from '../../../components/dynamic' export const revalidate = 60 -export default ({ params: { slug } }) => { +export default async (props) => { + const params = await props.params + + const { slug } = params + return ( }> diff --git a/test/e2e/app-dir/ppr-full/app/no-suspense/nested/[slug]/page.jsx b/test/e2e/app-dir/ppr-full/app/no-suspense/nested/[slug]/page.jsx index d7f48f3a261371..82f5bb47fb8e20 100644 --- a/test/e2e/app-dir/ppr-full/app/no-suspense/nested/[slug]/page.jsx +++ b/test/e2e/app-dir/ppr-full/app/no-suspense/nested/[slug]/page.jsx @@ -1,7 +1,11 @@ import React from 'react' import { Dynamic } from '../../../../components/dynamic' -export default ({ params: { slug } }) => { +export default async (props) => { + const params = await props.params + + const { slug } = params + return } diff --git a/test/e2e/app-dir/ppr-full/app/on-demand/[slug]/page.jsx b/test/e2e/app-dir/ppr-full/app/on-demand/[slug]/page.jsx index 289d8a9d632566..b502b635f3be4e 100644 --- a/test/e2e/app-dir/ppr-full/app/on-demand/[slug]/page.jsx +++ b/test/e2e/app-dir/ppr-full/app/on-demand/[slug]/page.jsx @@ -1,7 +1,11 @@ import React, { Suspense } from 'react' import { Dynamic } from '../../../components/dynamic' -export default ({ params: { slug } }) => { +export default async (props) => { + const params = await props.params + + const { slug } = params + return ( }> diff --git a/test/e2e/app-dir/ppr-navigations/incremental/app/[locale]/about/page.jsx b/test/e2e/app-dir/ppr-navigations/incremental/app/[locale]/about/page.jsx index 636270b79b6e9c..9f500c2a9d4f38 100644 --- a/test/e2e/app-dir/ppr-navigations/incremental/app/[locale]/about/page.jsx +++ b/test/e2e/app-dir/ppr-navigations/incremental/app/[locale]/about/page.jsx @@ -2,6 +2,10 @@ import { TestPage } from '../../../components/page' export const experimental_ppr = true -export default function Page({ params: { locale } }) { +export default async function Page(props) { + const params = await props.params + + const { locale } = params + return } diff --git a/test/e2e/app-dir/ppr-navigations/incremental/app/[locale]/layout.jsx b/test/e2e/app-dir/ppr-navigations/incremental/app/[locale]/layout.jsx index b55a7751211b5d..9a9315cdfd84ec 100644 --- a/test/e2e/app-dir/ppr-navigations/incremental/app/[locale]/layout.jsx +++ b/test/e2e/app-dir/ppr-navigations/incremental/app/[locale]/layout.jsx @@ -4,7 +4,13 @@ export async function generateStaticParams() { return locales.map((locale) => ({ locale })) } -export default function Layout({ children, params: { locale } }) { +export default async function Layout(props) { + const params = await props.params + + const { locale } = params + + const { children } = props + return ( {children} diff --git a/test/e2e/app-dir/ppr-navigations/incremental/app/[locale]/page.jsx b/test/e2e/app-dir/ppr-navigations/incremental/app/[locale]/page.jsx index abd02b646d87fc..873daac7a1ae73 100644 --- a/test/e2e/app-dir/ppr-navigations/incremental/app/[locale]/page.jsx +++ b/test/e2e/app-dir/ppr-navigations/incremental/app/[locale]/page.jsx @@ -1,5 +1,9 @@ import { TestPage } from '../../components/page' -export default function Page({ params: { locale } }) { +export default async function Page(props) { + const params = await props.params + + const { locale } = params + return } diff --git a/test/e2e/app-dir/ppr-navigations/incremental/app/[locale]/static/page.jsx b/test/e2e/app-dir/ppr-navigations/incremental/app/[locale]/static/page.jsx index 4fa3febf3a8378..05e2f78bd9a0f1 100644 --- a/test/e2e/app-dir/ppr-navigations/incremental/app/[locale]/static/page.jsx +++ b/test/e2e/app-dir/ppr-navigations/incremental/app/[locale]/static/page.jsx @@ -1,5 +1,9 @@ import { TestPage } from '../../../components/page' -export default function Page({ params: { locale } }) { +export default async function Page(props) { + const params = await props.params + + const { locale } = params + return } diff --git a/test/e2e/app-dir/ppr-navigations/prefetch-navigation/app/catch-all/[[...slug]]/page.tsx b/test/e2e/app-dir/ppr-navigations/prefetch-navigation/app/catch-all/[[...slug]]/page.tsx index 0f6ceaf66b023d..a60418f2e1e6f7 100644 --- a/test/e2e/app-dir/ppr-navigations/prefetch-navigation/app/catch-all/[[...slug]]/page.tsx +++ b/test/e2e/app-dir/ppr-navigations/prefetch-navigation/app/catch-all/[[...slug]]/page.tsx @@ -2,7 +2,8 @@ import { unstable_noStore } from 'next/cache' import Link from 'next/link' import React, { Suspense } from 'react' -export default async function Page({ params }) { +export default async function Page(props) { + const params = await props.params return (

    Params: {JSON.stringify(params)}

    diff --git a/test/e2e/app-dir/ppr-navigations/search-params/app/page.tsx b/test/e2e/app-dir/ppr-navigations/search-params/app/page.tsx index 0a537075c1d414..6907812891cbc9 100644 --- a/test/e2e/app-dir/ppr-navigations/search-params/app/page.tsx +++ b/test/e2e/app-dir/ppr-navigations/search-params/app/page.tsx @@ -2,11 +2,10 @@ import Link from 'next/link' type AnySearchParams = { [key: string]: string | Array | undefined } -export default async function Page({ - searchParams, -}: { +export default async function Page(props: { searchParams: Promise }) { + const searchParams = await props.searchParams const hasParams = Object.keys(searchParams).length > 0 return ( <> diff --git a/test/e2e/app-dir/ppr-navigations/simple/app/[locale]/about/page.jsx b/test/e2e/app-dir/ppr-navigations/simple/app/[locale]/about/page.jsx index c9bf684ee86732..a9f03d649ac0f0 100644 --- a/test/e2e/app-dir/ppr-navigations/simple/app/[locale]/about/page.jsx +++ b/test/e2e/app-dir/ppr-navigations/simple/app/[locale]/about/page.jsx @@ -1,5 +1,9 @@ import { TestPage } from '../../../components/page' -export default function Page({ params: { locale } }) { +export default async function Page(props) { + const params = await props.params + + const { locale } = params + return } diff --git a/test/e2e/app-dir/ppr-navigations/simple/app/[locale]/layout.jsx b/test/e2e/app-dir/ppr-navigations/simple/app/[locale]/layout.jsx index b55a7751211b5d..9a9315cdfd84ec 100644 --- a/test/e2e/app-dir/ppr-navigations/simple/app/[locale]/layout.jsx +++ b/test/e2e/app-dir/ppr-navigations/simple/app/[locale]/layout.jsx @@ -4,7 +4,13 @@ export async function generateStaticParams() { return locales.map((locale) => ({ locale })) } -export default function Layout({ children, params: { locale } }) { +export default async function Layout(props) { + const params = await props.params + + const { locale } = params + + const { children } = props + return ( {children} diff --git a/test/e2e/app-dir/ppr-navigations/simple/app/[locale]/page.jsx b/test/e2e/app-dir/ppr-navigations/simple/app/[locale]/page.jsx index abd02b646d87fc..873daac7a1ae73 100644 --- a/test/e2e/app-dir/ppr-navigations/simple/app/[locale]/page.jsx +++ b/test/e2e/app-dir/ppr-navigations/simple/app/[locale]/page.jsx @@ -1,5 +1,9 @@ import { TestPage } from '../../components/page' -export default function Page({ params: { locale } }) { +export default async function Page(props) { + const params = await props.params + + const { locale } = params + return } diff --git a/test/e2e/app-dir/ppr/app/no-suspense/node/gsp/[slug]/page.jsx b/test/e2e/app-dir/ppr/app/no-suspense/node/gsp/[slug]/page.jsx index f801cb021f18bc..a7e4ffe221ba58 100644 --- a/test/e2e/app-dir/ppr/app/no-suspense/node/gsp/[slug]/page.jsx +++ b/test/e2e/app-dir/ppr/app/no-suspense/node/gsp/[slug]/page.jsx @@ -2,7 +2,8 @@ export function generateStaticParams() { return [{ slug: 'foo' }] } -export default async function Page({ params }) { +export default async function Page(props) { + const params = await props.params return (
    Hello World! diff --git a/test/e2e/app-dir/ppr/app/suspense/node/gsp/[slug]/page.jsx b/test/e2e/app-dir/ppr/app/suspense/node/gsp/[slug]/page.jsx index 8fd1559f4b37b3..a7157e3c8651ec 100644 --- a/test/e2e/app-dir/ppr/app/suspense/node/gsp/[slug]/page.jsx +++ b/test/e2e/app-dir/ppr/app/suspense/node/gsp/[slug]/page.jsx @@ -4,7 +4,8 @@ export function generateStaticParams() { return [{ slug: 'foo' }] } -export default async function Page({ params }) { +export default async function Page(props) { + const params = await props.params return (
    Hello World! diff --git a/test/e2e/app-dir/rewrites-redirects/app/[...params]/page.tsx b/test/e2e/app-dir/rewrites-redirects/app/[...params]/page.tsx index c6b42b1965224a..45b1a4580e971d 100644 --- a/test/e2e/app-dir/rewrites-redirects/app/[...params]/page.tsx +++ b/test/e2e/app-dir/rewrites-redirects/app/[...params]/page.tsx @@ -1,8 +1,7 @@ -export default async function Page({ - params, -}: { +export default async function Page(props: { params: Promise<{ params: Array }> }) { + const params = await props.params const { params: catchAllParams } = await params return (
    diff --git a/test/e2e/app-dir/router-stuck-dynamic-static-segment/app/[slug]/page.tsx b/test/e2e/app-dir/router-stuck-dynamic-static-segment/app/[slug]/page.tsx index 71aa0623bdcc8f..81b549cd046296 100644 --- a/test/e2e/app-dir/router-stuck-dynamic-static-segment/app/[slug]/page.tsx +++ b/test/e2e/app-dir/router-stuck-dynamic-static-segment/app/[slug]/page.tsx @@ -1,6 +1,7 @@ import Link from 'next/link' -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params return (

    Visiting page {params.slug}

    diff --git a/test/e2e/app-dir/router-stuck-dynamic-static-segment/app/blog/[slug]/page.tsx b/test/e2e/app-dir/router-stuck-dynamic-static-segment/app/blog/[slug]/page.tsx index ac82ad80adb713..76b46bd7c4fb15 100644 --- a/test/e2e/app-dir/router-stuck-dynamic-static-segment/app/blog/[slug]/page.tsx +++ b/test/e2e/app-dir/router-stuck-dynamic-static-segment/app/blog/[slug]/page.tsx @@ -1,6 +1,7 @@ import Link from 'next/link' -export default function Blog({ params }) { +export default async function Blog(props) { + const params = await props.params return (

    Blog post {params.slug}

    diff --git a/test/e2e/app-dir/rsc-basic/app/page.js b/test/e2e/app-dir/rsc-basic/app/page.js index e641a48827bca5..f709ccf951c5b5 100644 --- a/test/e2e/app-dir/rsc-basic/app/page.js +++ b/test/e2e/app-dir/rsc-basic/app/page.js @@ -4,8 +4,8 @@ import { headers } from 'next/headers' const envVar = process.env.ENV_VAR_TEST const headerKey = 'x-next-test-client' -export default function Index() { - const headersList = headers() +export default async function Index() { + const headersList = await headers() const header = headersList.get(headerKey) return ( diff --git a/test/e2e/app-dir/shallow-routing/app/(shallow)/dynamic/[id]/page.tsx b/test/e2e/app-dir/shallow-routing/app/(shallow)/dynamic/[id]/page.tsx index 6d94f0bb1bcdd5..8000d287b3daf2 100644 --- a/test/e2e/app-dir/shallow-routing/app/(shallow)/dynamic/[id]/page.tsx +++ b/test/e2e/app-dir/shallow-routing/app/(shallow)/dynamic/[id]/page.tsx @@ -1,4 +1,5 @@ -export default function Page({ params }) { +export default async function Page(props) { + const params = await props.params return ( <>

    Page ID: {params.id}

    diff --git a/test/integration/app-dynamic-error/app/dynamic-error/page.js b/test/integration/app-dynamic-error/app/dynamic-error/page.js index 584c0363072e69..d03db5f9305345 100644 --- a/test/integration/app-dynamic-error/app/dynamic-error/page.js +++ b/test/integration/app-dynamic-error/app/dynamic-error/page.js @@ -2,8 +2,8 @@ import { headers } from 'next/headers' export const dynamic = 'error' -export default function Page() { - headers() +export default async function Page() { + await headers() return ( <>

    /dynamic-error

    From 5a54933a5dcd8b93b79a82078fc2cab25707bbba Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Wed, 23 Oct 2024 02:36:48 +0200 Subject: [PATCH 17/44] codemod: should not transform when param is not used (#71664) --- .../access-props-39.input.tsx | 7 +++++++ .../access-props-39.output.tsx | 7 +++++++ .../lib/async-request-api/next-async-dynamic-prop.ts | 7 +++---- 3 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 packages/next-codemod/transforms/__testfixtures__/next-async-request-api-dynamic-props/access-props-39.input.tsx create mode 100644 packages/next-codemod/transforms/__testfixtures__/next-async-request-api-dynamic-props/access-props-39.output.tsx diff --git a/packages/next-codemod/transforms/__testfixtures__/next-async-request-api-dynamic-props/access-props-39.input.tsx b/packages/next-codemod/transforms/__testfixtures__/next-async-request-api-dynamic-props/access-props-39.input.tsx new file mode 100644 index 00000000000000..bad3318722e60f --- /dev/null +++ b/packages/next-codemod/transforms/__testfixtures__/next-async-request-api-dynamic-props/access-props-39.input.tsx @@ -0,0 +1,7 @@ +export default function Page({ params, children }) { + return children +} + +export function generateMetadata(props) { + return {} +} diff --git a/packages/next-codemod/transforms/__testfixtures__/next-async-request-api-dynamic-props/access-props-39.output.tsx b/packages/next-codemod/transforms/__testfixtures__/next-async-request-api-dynamic-props/access-props-39.output.tsx new file mode 100644 index 00000000000000..bad3318722e60f --- /dev/null +++ b/packages/next-codemod/transforms/__testfixtures__/next-async-request-api-dynamic-props/access-props-39.output.tsx @@ -0,0 +1,7 @@ +export default function Page({ params, children }) { + return children +} + +export function generateMetadata(props) { + return {} +} diff --git a/packages/next-codemod/transforms/lib/async-request-api/next-async-dynamic-prop.ts b/packages/next-codemod/transforms/lib/async-request-api/next-async-dynamic-prop.ts index 3207ec5729d9c0..7bcb08df06b017 100644 --- a/packages/next-codemod/transforms/lib/async-request-api/next-async-dynamic-prop.ts +++ b/packages/next-codemod/transforms/lib/async-request-api/next-async-dynamic-prop.ts @@ -695,9 +695,8 @@ export function transformDynamicProps( : null const paramPropertyName = paramsPropertyName || matchedPropName - // if propName is not used in lower scope, and it stars with unused prefix `_`, - // also skip the transformation - + // If propName is an identifier and not used in lower scope, + // also skip the transformation. const hasUsedInBody = j(functionBodyPath) .find(j.Identifier, { @@ -705,7 +704,7 @@ export function transformDynamicProps( }) .size() > 0 - if (!hasUsedInBody && paramPropertyName.startsWith('_')) continue + if (!hasUsedInBody && j.Identifier.check(paramsProperty)) continue // Search the usage of propName in the function body, // if they're all awaited or wrapped with use(), skip the transformation From 96d6a96dc3adb9c57dc05e11f13789260fdee502 Mon Sep 17 00:00:00 2001 From: Sebastian Ong <78428559+SebassNoob@users.noreply.github.com> Date: Wed, 23 Oct 2024 08:39:39 +0800 Subject: [PATCH 18/44] fix: docs for dynamic routing in next 15 (#71531) ### What? Fixes the `params` prop in https://nextjs.org/docs/canary/app/building-your-application/routing/dynamic-routes Also fixes a typo: `synchronoulsy` -> `synchronously` ### Why? There is a breaking change in `next@15.0.0-rc.1`: https://nextjs.org/blog/next-15-rc2#async-request-apis-breaking-change Although the api docs have been updated, these have not been. ### How? updates the docs. (relevant) build and lint passes locally. ran the prettier fix. --------- Co-authored-by: JJ Kasper --- .../01-routing/10-dynamic-routes.mdx | 28 ++++++++++++++----- .../02-file-conventions/default.mdx | 2 +- .../02-file-conventions/layout.mdx | 2 +- .../02-file-conventions/page.mdx | 4 +-- .../02-api-reference/04-functions/cookies.mdx | 2 +- .../04-functions/draft-mode.mdx | 2 +- .../02-api-reference/04-functions/headers.mdx | 2 +- 7 files changed, 28 insertions(+), 14 deletions(-) diff --git a/docs/02-app/01-building-your-application/01-routing/10-dynamic-routes.mdx b/docs/02-app/01-building-your-application/01-routing/10-dynamic-routes.mdx index cb15eccae1fbfc..517ef51087f0db 100644 --- a/docs/02-app/01-building-your-application/01-routing/10-dynamic-routes.mdx +++ b/docs/02-app/01-building-your-application/01-routing/10-dynamic-routes.mdx @@ -22,14 +22,20 @@ Dynamic Segments are passed as the `params` prop to [`layout`](/docs/app/api-ref For example, a blog could include the following route `app/blog/[slug]/page.js` where `[slug]` is the Dynamic Segment for blog posts. ```tsx filename="app/blog/[slug]/page.tsx" switcher -export default function Page({ params }: { params: { slug: string } }) { - return
    My Post: {params.slug}
    +export default async function Page({ + params, +}: { + params: Promise<{ slug: string }> +}) { + const slug = (await params).slug + return
    My Post: {slug}
    } ``` ```jsx filename="app/blog/[slug]/page.js" switcher -export default function Page({ params }) { - return
    My Post: {params.slug}
    +export default async function Page({ params }) { + const slug = (await params).slug + return
    My Post: {slug}
    } ``` @@ -41,7 +47,11 @@ export default function Page({ params }) { See the [generateStaticParams()](#generating-static-params) page to learn how to generate the params for the segment. -> **Good to know**: Dynamic Segments are equivalent to [Dynamic Routes](/docs/pages/building-your-application/routing/dynamic-routes) in the `pages` directory. +## Good to know + +- Since the `params` prop is a promise. You must use async/await or React's use function to access the values. + - In version 14 and earlier, `params` was a synchronous prop. To help with backwards compatability, you can still access it synchronously in Next.js 15, but this behavior will be deprecated in the future. +- Dynamic Segments are equivalent to [Dynamic Routes](/docs/pages/building-your-application/routing/dynamic-routes) in the `pages` directory. ## Generating Static Params @@ -105,13 +115,17 @@ The difference between **catch-all** and **optional catch-all** segments is that When using TypeScript, you can add types for `params` depending on your configured route segment. ```tsx filename="app/blog/[slug]/page.tsx" switcher -export default function Page({ params }: { params: { slug: string } }) { +export default async function Page({ + params, +}: { + params: Promise<{ slug: string }> +}) { return

    My Page

    } ``` ```jsx filename="app/blog/[slug]/page.js" switcher -export default function Page({ params }) { +export default async function Page({ params }) { return

    My Page

    } ``` diff --git a/docs/02-app/02-api-reference/02-file-conventions/default.mdx b/docs/02-app/02-api-reference/02-file-conventions/default.mdx index eca38db9ef4859..22ec26d9ea3440 100644 --- a/docs/02-app/02-api-reference/02-file-conventions/default.mdx +++ b/docs/02-app/02-api-reference/02-file-conventions/default.mdx @@ -55,4 +55,4 @@ export default async function Default({ params }) { | `app/[artist]/[album]/@sidebar/default.js` | `/zack/next` | `Promise<{ artist: 'zack', album: 'next' }>` | - Since the `params` prop is a promise. You must use `async/await` or React's [`use`](https://react.dev/reference/react/use) function to access the values. - - In version 14 and earlier, `params` was a synchronous prop. To help with backwards compatability, you can still access it synchronoulsy in Next.js 15, but this behavior will be deprecated in the future. + - In version 14 and earlier, `params` was a synchronous prop. To help with backwards compatability, you can still access it synchronously in Next.js 15, but this behavior will be deprecated in the future. diff --git a/docs/02-app/02-api-reference/02-file-conventions/layout.mdx b/docs/02-app/02-api-reference/02-file-conventions/layout.mdx index dc0933a108b8d8..19a5e412481bef 100644 --- a/docs/02-app/02-api-reference/02-file-conventions/layout.mdx +++ b/docs/02-app/02-api-reference/02-file-conventions/layout.mdx @@ -82,7 +82,7 @@ export default async function Layout({ params }) { | `app/blog/[...slug]/layout.js` | `/blog/1/2` | `Promise<{ slug: ['1', '2'] }>` | - Since the `params` prop is a promise. You must use `async/await` or React's [`use`](https://react.dev/reference/react/use) function to access the values. - - In version 14 and earlier, `params` was a synchronous prop. To help with backwards compatability, you can still access it synchronoulsy in Next.js 15, but this behavior will be deprecated in the future. + - In version 14 and earlier, `params` was a synchronous prop. To help with backwards compatability, you can still access it synchronously in Next.js 15, but this behavior will be deprecated in the future. ### Root Layouts diff --git a/docs/02-app/02-api-reference/02-file-conventions/page.mdx b/docs/02-app/02-api-reference/02-file-conventions/page.mdx index 65b79ae95c2f62..3b9373f7c33f2d 100644 --- a/docs/02-app/02-api-reference/02-file-conventions/page.mdx +++ b/docs/02-app/02-api-reference/02-file-conventions/page.mdx @@ -54,7 +54,7 @@ export default async function Page({ params }) { | `app/shop/[...slug]/page.js` | `/shop/1/2` | `Promise<{ slug: ['1', '2'] }>` | - Since the `params` prop is a promise. You must use `async/await` or React's [`use`](https://react.dev/reference/react/use) function to access the values. - - In version 14 and earlier, `params` was a synchronous prop. To help with backwards compatability, you can still access it synchronoulsy in Next.js 15, but this behavior will be deprecated in the future. + - In version 14 and earlier, `params` was a synchronous prop. To help with backwards compatability, you can still access it synchronously in Next.js 15, but this behavior will be deprecated in the future. #### `searchParams` (optional) @@ -83,7 +83,7 @@ export default async function Page({ searchParams }) { | `/shop?a=1&a=2` | `Promise<{ a: ['1', '2'] }>` | - Since the `searchParams` prop is a promise. You must use `async/await` or React's [`use`](https://react.dev/reference/react/use) function to access the values. - - In version 14 and earlier, `searchParams` was a synchronous prop. To help with backwards compatability, you can still access it synchronoulsy in Next.js 15, but this behavior will be deprecated in the future. + - In version 14 and earlier, `searchParams` was a synchronous prop. To help with backwards compatability, you can still access it synchronously in Next.js 15, but this behavior will be deprecated in the future. - `searchParams` is a **[Dynamic API](/docs/app/building-your-application/rendering/server-components#server-rendering-strategies#dynamic-apis)** whose values cannot be known ahead of time. Using it will opt the page into **[dynamic rendering](/docs/app/building-your-application/rendering/server-components#dynamic-rendering)** at request time. - `searchParams` is a plain JavaScript object, not a `URLSearchParams` instance. diff --git a/docs/02-app/02-api-reference/04-functions/cookies.mdx b/docs/02-app/02-api-reference/04-functions/cookies.mdx index 13762003552a90..6358fbe11fed0b 100644 --- a/docs/02-app/02-api-reference/04-functions/cookies.mdx +++ b/docs/02-app/02-api-reference/04-functions/cookies.mdx @@ -65,7 +65,7 @@ To learn more about these options, see the [MDN docs](https://developer.mozilla. ## Good to know - `cookies` is an **asynchronous** function that returns a promise. You must use `async/await` or React's [`use`](https://react.dev/reference/react/use) function to access cookies. - - In version 14 and earlier, `cookies` was a synchronous function. To help with backwards compatability, you can still access it synchronoulsy in Next.js 15, but this behavior will be deprecated in the future. + - In version 14 and earlier, `cookies` was a synchronous function. To help with backwards compatability, you can still access it synchronously in Next.js 15, but this behavior will be deprecated in the future. - `cookies` is a [Dynamic API](/docs/app/building-your-application/rendering/server-components#dynamic-apis) whose returned values cannot be known ahead of time. Using it in a layout or page will opt a route into [dynamic rendering](/docs/app/building-your-application/rendering/server-components#dynamic-rendering). - The `.delete` method can only be called: - In a [Server Action](/docs/app/building-your-application/data-fetching/server-actions-and-mutations) or [Route Handler](/docs/app/building-your-application/routing/route-handlers). diff --git a/docs/02-app/02-api-reference/04-functions/draft-mode.mdx b/docs/02-app/02-api-reference/04-functions/draft-mode.mdx index ec6deee7fd7800..c3bd0e1c43f733 100644 --- a/docs/02-app/02-api-reference/04-functions/draft-mode.mdx +++ b/docs/02-app/02-api-reference/04-functions/draft-mode.mdx @@ -39,7 +39,7 @@ The following methods and properties are available: ## Good to know - `draftMode` is an **asynchronous** function that returns a promise. You must use `async/await` or React's [`use`](https://react.dev/reference/react/use) function. - - In version 14 and earlier, `draftMode` was a synchronous function. To help with backwards compatability, you can still access it synchronoulsy in Next.js 15, but this behavior will be deprecated in the future. + - In version 14 and earlier, `draftMode` was a synchronous function. To help with backwards compatability, you can still access it synchronously in Next.js 15, but this behavior will be deprecated in the future. - A new bypass cookie value will be generated each time you run `next build`. This ensures that the bypass cookie can’t be guessed. - To test Draft Mode locally over HTTP, your browser will need to allow third-party cookies and local storage access. diff --git a/docs/02-app/02-api-reference/04-functions/headers.mdx b/docs/02-app/02-api-reference/04-functions/headers.mdx index 95ea99742cbf8d..8158ab9bb9e82d 100644 --- a/docs/02-app/02-api-reference/04-functions/headers.mdx +++ b/docs/02-app/02-api-reference/04-functions/headers.mdx @@ -43,7 +43,7 @@ export default async function Page() { ## Good to know - `headers` is an **asynchronous** function that returns a promise. You must use `async/await` or React's [`use`](https://react.dev/reference/react/use) function. - - In version 14 and earlier, `headers` was a synchronous function. To help with backwards compatability, you can still access it synchronoulsy in Next.js 15, but this behavior will be deprecated in the future. + - In version 14 and earlier, `headers` was a synchronous function. To help with backwards compatability, you can still access it synchronously in Next.js 15, but this behavior will be deprecated in the future. - Since `headers` is read-only, you cannot `set` or `delete` the outgoing request headers. - `headers` is a [Dynamic API](/docs/app/building-your-application/rendering/server-components#server-rendering-strategies#dynamic-apis) whose returned values cannot be known ahead of time. Using it in will opt a route into **[dynamic rendering](/docs/app/building-your-application/rendering/server-components#dynamic-rendering)**. From 5abd11763c0f0c8138355ffd737da3a03d7e463f Mon Sep 17 00:00:00 2001 From: tatsuteb Date: Wed, 23 Oct 2024 13:01:53 +0900 Subject: [PATCH 19/44] [Docs] Remove the 'new' keyword from the GET function sample code. (#71671) The json() method returns a Response object, so remove the new keyword. Co-authored-by: JJ Kasper --- docs/02-app/02-api-reference/02-file-conventions/route.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/02-app/02-api-reference/02-file-conventions/route.mdx b/docs/02-app/02-api-reference/02-file-conventions/route.mdx index afe7b17c3bf800..6a02881797be8d 100644 --- a/docs/02-app/02-api-reference/02-file-conventions/route.mdx +++ b/docs/02-app/02-api-reference/02-file-conventions/route.mdx @@ -7,13 +7,13 @@ Route Handlers allow you to create custom request handlers for a given route usi ```ts filename="route.ts" switcher export async function GET() { - return new Response.json({ message: 'Hello World' }) + return Response.json({ message: 'Hello World' }) } ``` ```js filename="route.js" switcher export async function GET() { - return new Response.json({ message: 'Hello World' }) + return Response.json({ message: 'Hello World' }) } ``` From 4292752f52918fefd3753dd8e1cb8d6210c6229c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=83=9E=E3=83=AB=E3=82=B3=E3=83=A1?= Date: Wed, 23 Oct 2024 13:25:16 +0900 Subject: [PATCH 20/44] chore: fix wrong path of comments (#71682) ## Description At #44405, many files moved. Then sync comment paths. Co-authored-by: JJ Kasper --- crates/next-core/src/util.rs | 4 ++-- .../js/src/browser/dev/hmr-client/websocket.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/next-core/src/util.rs b/crates/next-core/src/util.rs index 2c707771af0c25..76551718ba7467 100644 --- a/crates/next-core/src/util.rs +++ b/crates/next-core/src/util.rs @@ -70,7 +70,7 @@ pub async fn pathname_for_path( Ok(Vc::cell(path)) } -// Adapted from https://github.com/vercel/next.js/blob/canary/packages/next/shared/lib/router/utils/get-asset-path-from-route.ts +// Adapted from https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/router/utils/get-asset-path-from-route.ts // TODO(alexkirsz) There's no need to create an intermediate string here (and // below), we should instead return an `impl Display`. pub fn get_asset_prefix_from_pathname(pathname: &str) -> String { @@ -83,7 +83,7 @@ pub fn get_asset_prefix_from_pathname(pathname: &str) -> String { } } -// Adapted from https://github.com/vercel/next.js/blob/canary/packages/next/shared/lib/router/utils/get-asset-path-from-route.ts +// Adapted from https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/router/utils/get-asset-path-from-route.ts pub fn get_asset_path_from_pathname(pathname: &str, ext: &str) -> String { format!("{}{}", get_asset_prefix_from_pathname(pathname), ext) } diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/hmr-client/websocket.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/hmr-client/websocket.ts index d7da330bb81736..21f7e3c2b6c6a2 100644 --- a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/hmr-client/websocket.ts +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/hmr-client/websocket.ts @@ -1,4 +1,4 @@ -// Adapted from https://github.com/vercel/next.js/blob/canary/packages/next/client/dev/error-overlay/websocket.ts +// Adapted from https://github.com/vercel/next.js/blob/canary/packages/next/src/client/dev/error-overlay/websocket.ts let source: WebSocket; const eventCallbacks: ((msg: WebSocketMessage) => void)[] = []; From d61d6314f2551d6685d92b3638d50272a9320e8e Mon Sep 17 00:00:00 2001 From: Josh Story Date: Tue, 22 Oct 2024 21:32:04 -0700 Subject: [PATCH 21/44] [dynamicIO] complete refactor to prerender (#71687) In the initial change to adopt prerender for SSR for dynamicIO I missed an instance of renderToReadableStream. This completes the work --- packages/next/src/server/app-render/app-render.tsx | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/next/src/server/app-render/app-render.tsx b/packages/next/src/server/app-render/app-render.tsx index 04c5260d2577d3..766c4d487da814 100644 --- a/packages/next/src/server/app-render/app-render.tsx +++ b/packages/next/src/server/app-render/app-render.tsx @@ -3156,7 +3156,7 @@ async function prerenderToStream( try { htmlStream = await prerenderAndAbortInSequentialTasks( - () => { + async () => { const teedStream = ( workUnitAsyncStorage.run( // The store to scope @@ -3176,11 +3176,11 @@ async function prerenderToStream( reactServerStream = teedStream[0] const rscForSSRStream = teedStream[1] - const renderToReadableStream = require('react-dom/server.edge') - .renderToReadableStream as (typeof import('react-dom/server.edge'))['renderToReadableStream'] - const pendingHTMLStream = workUnitAsyncStorage.run( + const prerender = require('react-dom/static.edge') + .prerender as (typeof import('react-dom/static.edge'))['prerender'] + const { prelude } = await workUnitAsyncStorage.run( finalSSRPrerenderStore, - renderToReadableStream, + prerender, {}) - return pendingHTMLStream + return prelude }, () => { finalSSRController.abort(abortReason) From c1cfee3e1df3b1432a94035f55d878d76d408ff4 Mon Sep 17 00:00:00 2001 From: Sam Ko Date: Tue, 22 Oct 2024 22:40:20 -0700 Subject: [PATCH 22/44] docs(next-config): remove mention of appIsrStatus is on canary (#71695) ## Why? [`appIsrStatus`](https://nextjs.org/docs/canary/app/api-reference/next-config-js/devIndicators#appisrstatus-static-indicator) is stable now, so this note is no longer necessary. --- .../02-app/02-api-reference/05-next-config-js/devIndicators.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/02-app/02-api-reference/05-next-config-js/devIndicators.mdx b/docs/02-app/02-api-reference/05-next-config-js/devIndicators.mdx index 08a4990c445dc7..0631f1435d6eee 100644 --- a/docs/02-app/02-api-reference/05-next-config-js/devIndicators.mdx +++ b/docs/02-app/02-api-reference/05-next-config-js/devIndicators.mdx @@ -22,8 +22,6 @@ description: Optimized pages include an indicator to let you know if it's being ## `appIsrStatus` (Static Indicator) -> This option is available in Next.js canary. - Next.js displays a static indicator in the bottom corner of the screen that signals if a route will be prerendered at build time. This makes it easier to understand whether a route is static or dynamic, and for you to identify if a route [opts out of static rendering](#static-route-not-showing-the-indicator). Date: Wed, 23 Oct 2024 15:01:27 +0900 Subject: [PATCH 23/44] fix: metadata image route normalize path posix for windows (#71673) ### Why? When handling the opengraph-image size exceeding the limit, we mapped with string literal between Rust and JavaScript. The Rust string literal contains backslashes `\` on Windows, incompatible with JavaScript string syntax. Following up on #71615. Fixes #71582 --- .../src/build/webpack/loaders/next-metadata-route-loader.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/next/src/build/webpack/loaders/next-metadata-route-loader.ts b/packages/next/src/build/webpack/loaders/next-metadata-route-loader.ts index f709ce018a9aa0..a3b71536555857 100644 --- a/packages/next/src/build/webpack/loaders/next-metadata-route-loader.ts +++ b/packages/next/src/build/webpack/loaders/next-metadata-route-loader.ts @@ -76,6 +76,8 @@ async function getStaticAssetRouteCode( resourcePath: string, fileBaseName: string ) { + resourcePath = path.posix.normalize(resourcePath) + const cache = fileBaseName === 'favicon' ? 'public, max-age=0, must-revalidate' From e9b18d6493ce4db07bf89a3b165343192ba568a5 Mon Sep 17 00:00:00 2001 From: Prakhar Shukla Date: Wed, 23 Oct 2024 12:39:07 +0530 Subject: [PATCH 24/44] next-codemod(upgrade): optional catch when missing dev script (#71598) ### Why? During the next-codemod upgrade, when the `dev` script is missing, it throws while reading `.includes` the undefined value. Fixes #71597 --------- Co-authored-by: Jiwon Choi --- packages/next-codemod/bin/upgrade.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next-codemod/bin/upgrade.ts b/packages/next-codemod/bin/upgrade.ts index dc2f7f31638037..973a1ff7c941bf 100644 --- a/packages/next-codemod/bin/upgrade.ts +++ b/packages/next-codemod/bin/upgrade.ts @@ -412,7 +412,7 @@ function isUsingAppDir(projectPath: string): boolean { */ async function suggestTurbopack(packageJson: any): Promise { const devScript: string = packageJson.scripts['dev'] - if (devScript.includes('--turbopack')) return + if (devScript?.includes('--turbopack')) return const responseTurbopack = await prompts( { From 51d6e76596f42ea51dad6b4bf6fb7817d91a79ec Mon Sep 17 00:00:00 2001 From: Hendrik Liebau Date: Wed, 23 Oct 2024 09:54:51 +0200 Subject: [PATCH 25/44] Avoid server action function indirection in Turbopack (#71628) --- crates/next-api/src/server_actions.rs | 36 +++++++++---------- crates/next-core/src/next_manifests/mod.rs | 11 ++++-- .../plugins/flight-client-entry-plugin.ts | 6 +--- .../src/server/app-render/action-utils.ts | 5 --- .../src/server/use-cache/use-cache-wrapper.ts | 2 +- .../use-cache/app/with-server-action/form.tsx | 22 ++++++++++++ .../app/with-server-action/layout.tsx | 14 ++++++++ .../use-cache/app/with-server-action/page.tsx | 17 +++++++++ test/e2e/app-dir/use-cache/use-cache.test.ts | 10 ++++++ 9 files changed, 92 insertions(+), 31 deletions(-) create mode 100644 test/e2e/app-dir/use-cache/app/with-server-action/form.tsx create mode 100644 test/e2e/app-dir/use-cache/app/with-server-action/layout.tsx create mode 100644 test/e2e/app-dir/use-cache/app/with-server-action/page.tsx diff --git a/crates/next-api/src/server_actions.rs b/crates/next-api/src/server_actions.rs index 785624cb9ed094..69290b003fcd1d 100644 --- a/crates/next-api/src/server_actions.rs +++ b/crates/next-api/src/server_actions.rs @@ -3,7 +3,9 @@ use std::{collections::BTreeMap, io::Write, iter::once}; use anyhow::{bail, Context, Result}; use indexmap::map::Entry; use next_core::{ - next_manifests::{ActionLayer, ActionManifestWorkerEntry, ServerReferenceManifest}, + next_manifests::{ + ActionLayer, ActionManifestModuleId, ActionManifestWorkerEntry, ServerReferenceManifest, + }, util::NextRuntime, }; use swc_core::{ @@ -22,7 +24,7 @@ use turbo_tasks::{ use turbo_tasks_fs::{self, rope::RopeBuilder, File, FileSystemPath}; use turbopack_core::{ asset::AssetContent, - chunk::{ChunkItemExt, ChunkableModule, ChunkingContext, EvaluatableAsset}, + chunk::{ChunkItem, ChunkItemExt, ChunkableModule, ChunkingContext, EvaluatableAsset}, context::AssetContext, file_source::FileSource, module::{Module, Modules}, @@ -69,11 +71,8 @@ pub(crate) async fn create_server_actions_manifest( .await? .context("loader module must be evaluatable")?; - let loader_id = loader - .as_chunk_item(Vc::upcast(chunking_context)) - .id() - .to_string(); - let manifest = build_manifest(node_root, page_name, runtime, actions, loader_id).await?; + let chunk_item = loader.as_chunk_item(Vc::upcast(chunking_context)); + let manifest = build_manifest(node_root, page_name, runtime, actions, chunk_item).await?; Ok(ServerActionsManifest { loader: evaluable, manifest, @@ -96,11 +95,11 @@ async fn build_server_actions_loader( ) -> Result>> { let actions = actions.await?; - // Every module which exports an action (that is accessible starting from our - // app page entry point) will be present. We generate a single loader file - // which lazily imports the respective module's chunk_item id and invokes - // the exported action function. - let mut contents = RopeBuilder::from("__turbopack_export_value__({\n"); + // Every module which exports an action (that is accessible starting from + // our app page entry point) will be present. We generate a single loader + // file which re-exports the respective module's action function using the + // hashed ID as export name. + let mut contents = RopeBuilder::from(""); let mut import_map = FxIndexMap::default(); for (hash_id, (_layer, name, module)) in actions.iter() { let index = import_map.len(); @@ -109,11 +108,9 @@ async fn build_server_actions_loader( .or_insert_with(|| format!("ACTIONS_MODULE{index}").into()); writeln!( contents, - " '{hash_id}': (...args) => Promise.resolve(require('{module_name}')).then(mod => \ - (0, mod['{name}'])(...args)),", + "export {{{name} as '{hash_id}'}} from '{module_name}'" )?; } - write!(contents, "}});")?; let output_path = project_path.join(format!(".next-internal/server/app{page_name}/actions.js").into()); @@ -143,7 +140,7 @@ async fn build_manifest( page_name: RcStr, runtime: NextRuntime, actions: Vc, - loader_id: Vc, + chunk_item: Vc>, ) -> Result>> { let manifest_path_prefix = &page_name; let manifest_path = node_root @@ -155,7 +152,7 @@ async fn build_manifest( let key = format!("app{page_name}"); let actions_value = actions.await?; - let loader_id_value = loader_id.await?; + let loader_id = chunk_item.id().to_string().await?; let mapping = match runtime { NextRuntime::Edge => &mut manifest.edge, NextRuntime::NodeJs => &mut manifest.node, @@ -165,7 +162,10 @@ async fn build_manifest( let entry = mapping.entry(hash_id.as_str()).or_default(); entry.workers.insert( &key, - ActionManifestWorkerEntry::String(loader_id_value.as_str()), + ActionManifestWorkerEntry { + module_id: ActionManifestModuleId::String(loader_id.as_str()), + is_async: *chunk_item.is_self_async().await?, + }, ); entry.layer.insert(&key, *layer); } diff --git a/crates/next-core/src/next_manifests/mod.rs b/crates/next-core/src/next_manifests/mod.rs index 9f5f2ae487ffc3..ac89d4b5daeb25 100644 --- a/crates/next-core/src/next_manifests/mod.rs +++ b/crates/next-core/src/next_manifests/mod.rs @@ -194,9 +194,16 @@ pub struct ActionManifestEntry<'a> { } #[derive(Serialize, Debug)] -#[serde(rename_all = "camelCase")] +pub struct ActionManifestWorkerEntry<'a> { + #[serde(rename = "moduleId")] + pub module_id: ActionManifestModuleId<'a>, + #[serde(rename = "async")] + pub is_async: bool, +} + +#[derive(Serialize, Debug)] #[serde(untagged)] -pub enum ActionManifestWorkerEntry<'a> { +pub enum ActionManifestModuleId<'a> { String(&'a str), Number(f64), } diff --git a/packages/next/src/build/webpack/plugins/flight-client-entry-plugin.ts b/packages/next/src/build/webpack/plugins/flight-client-entry-plugin.ts index 89ff129159c400..90031aca88eaa2 100644 --- a/packages/next/src/build/webpack/plugins/flight-client-entry-plugin.ts +++ b/packages/next/src/build/webpack/plugins/flight-client-entry-plugin.ts @@ -55,11 +55,7 @@ const PLUGIN_NAME = 'FlightClientEntryPlugin' type Actions = { [actionId: string]: { workers: { - [name: string]: - | { moduleId: string | number; async: boolean } - // TODO: This is legacy for Turbopack, and needs to be changed to the - // object above. - | string + [name: string]: { moduleId: string | number; async: boolean } } // Record which layer the action is in (rsc or sc_action), in the specific entry. layer: { diff --git a/packages/next/src/server/app-render/action-utils.ts b/packages/next/src/server/app-render/action-utils.ts index 3a115de3b8d43f..ac4ee71f499aad 100644 --- a/packages/next/src/server/app-render/action-utils.ts +++ b/packages/next/src/server/app-render/action-utils.ts @@ -26,7 +26,6 @@ export function createServerModuleMap({ let workerEntry: | { moduleId: string | number; async: boolean } - | string | undefined if (workStore) { @@ -46,10 +45,6 @@ export function createServerModuleMap({ return undefined } - if (typeof workerEntry === 'string') { - return { id: workerEntry, name: id, chunks: [] } - } - const { moduleId, async } = workerEntry return { id: moduleId, name: id, chunks: [], async } diff --git a/packages/next/src/server/use-cache/use-cache-wrapper.ts b/packages/next/src/server/use-cache/use-cache-wrapper.ts index 94864d188f7e01..9597aaf1bc0b4d 100644 --- a/packages/next/src/server/use-cache/use-cache-wrapper.ts +++ b/packages/next/src/server/use-cache/use-cache-wrapper.ts @@ -679,7 +679,7 @@ export function cache(kind: string, id: string, fn: any) { moduleMap: isEdgeRuntime ? clientReferenceManifest.edgeRscModuleMapping : clientReferenceManifest.rscModuleMapping, - serverModuleMap: null, + serverModuleMap: getServerModuleMap(), } return createFromReadableStream(stream, { diff --git a/test/e2e/app-dir/use-cache/app/with-server-action/form.tsx b/test/e2e/app-dir/use-cache/app/with-server-action/form.tsx new file mode 100644 index 00000000000000..fdd21fd93da6ea --- /dev/null +++ b/test/e2e/app-dir/use-cache/app/with-server-action/form.tsx @@ -0,0 +1,22 @@ +'use client' + +import { ReactNode } from 'react' +import { useActionState } from 'react' + +export function Form({ + action, + children, +}: { + action: () => Promise + children: ReactNode +}) { + const [result, formAction] = useActionState(action, 'initial') + + return ( + + +

    {result}

    + {children} + + ) +} diff --git a/test/e2e/app-dir/use-cache/app/with-server-action/layout.tsx b/test/e2e/app-dir/use-cache/app/with-server-action/layout.tsx new file mode 100644 index 00000000000000..7ca1569e06a679 --- /dev/null +++ b/test/e2e/app-dir/use-cache/app/with-server-action/layout.tsx @@ -0,0 +1,14 @@ +import { connection } from 'next/server' + +export default async function DynamicLayout({ + children, +}: { + children: React.ReactNode +}) { + // TODO: This is a workaround for Turbopack. Figure out why this fails during + // prerendering with: + // TypeError: Cannot read properties of undefined (reading 'Form') + await connection() + + return children +} diff --git a/test/e2e/app-dir/use-cache/app/with-server-action/page.tsx b/test/e2e/app-dir/use-cache/app/with-server-action/page.tsx new file mode 100644 index 00000000000000..1aea39cefb4090 --- /dev/null +++ b/test/e2e/app-dir/use-cache/app/with-server-action/page.tsx @@ -0,0 +1,17 @@ +import { Form } from './form' + +async function action() { + 'use server' + + return 'result' +} + +export default async function Page() { + 'use cache' + + return ( +
    +

    {Date.now()}

    +
    + ) +} diff --git a/test/e2e/app-dir/use-cache/use-cache.test.ts b/test/e2e/app-dir/use-cache/use-cache.test.ts index d327d1e5e275f1..2947448c0149aa 100644 --- a/test/e2e/app-dir/use-cache/use-cache.test.ts +++ b/test/e2e/app-dir/use-cache/use-cache.test.ts @@ -231,4 +231,14 @@ describe('use-cache', () => { expect(meta.headers['x-next-cache-tags']).toContain('a,c,b') }) } + + it('can reference server actions in "use cache" functions', async () => { + const browser = await next.browser('/with-server-action') + expect(await browser.elementByCss('p').text()).toBe('initial') + await browser.elementByCss('button').click() + + await retry(async () => { + expect(await browser.elementByCss('p').text()).toBe('result') + }) + }) }) From ca559a5281ff2e2f345cc45e4d05a82e7ba83c9f Mon Sep 17 00:00:00 2001 From: Miguel da Mota Date: Wed, 23 Oct 2024 15:27:34 +0200 Subject: [PATCH 26/44] fix: exclude `basePath` in `findSourceMapURL` (#71719) This PR fixes #71706. When having an error client side and there is a `basePath` defined, the basePath is being used to locate the sourcemap of the given file which results in an error. With these changes the `basePath` gets removed from the `filename` passed to `findSourceMapURL` If you have questions, feel free to ask! --- packages/next/src/client/app-find-source-map-url.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/next/src/client/app-find-source-map-url.ts b/packages/next/src/client/app-find-source-map-url.ts index 7b2006e703322f..b143c755568b7d 100644 --- a/packages/next/src/client/app-find-source-map-url.ts +++ b/packages/next/src/client/app-find-source-map-url.ts @@ -8,7 +8,10 @@ export const findSourceMapURL = url.searchParams.set( 'filename', - filename.replace(new RegExp(`^${document.location.origin}`), '') + filename.replace( + new RegExp(`^${document.location.origin}${basePath}`), + '' + ) ) return url.href From 3643c8b4df015d49f06b5edd22acea6517a3aa7d Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Wed, 23 Oct 2024 16:39:40 +0200 Subject: [PATCH 27/44] fix: stack frame text color in dark mode (#71656) --- .../react-dev-overlay/internal/container/RuntimeError/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/src/client/components/react-dev-overlay/internal/container/RuntimeError/index.tsx b/packages/next/src/client/components/react-dev-overlay/internal/container/RuntimeError/index.tsx index cd24b26c2b3b1f..2d6710524a3f87 100644 --- a/packages/next/src/client/components/react-dev-overlay/internal/container/RuntimeError/index.tsx +++ b/packages/next/src/client/components/react-dev-overlay/internal/container/RuntimeError/index.tsx @@ -149,7 +149,7 @@ export const styles = css` margin-bottom: var(--size-gap); font-family: var(--font-stack-monospace); font-size: var(--size-font); - color: #222; + color: #666; } [data-nextjs-call-stack-frame] > h3[data-nextjs-frame-expanded='false'] { color: #666; From b08f75557c3cd2f4c3bf9c61f31e49f4cc619794 Mon Sep 17 00:00:00 2001 From: "Sebastian \"Sebbie\" Silbermann" Date: Wed, 23 Oct 2024 16:40:50 +0200 Subject: [PATCH 28/44] react-sync: Ignore update notices from npm (#71717) `npm view` prints a notice when a new update is available to `stderr` tricking us into thinking there was an error. ``` npm notice npm notice New minor version of npm available! 10.7.0 -> 10.9.0 npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.9.0 npm notice To update run: npm install -g npm@10.9.0 npm notice ``` Running with `--silent` avoids these unrelated warnings (see https://github.com/npm/npm/issues/2040#issuecomment-3504495). ## Test plan https://github.com/vercel/next.js/pull/71718 --- scripts/sync-react.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/sync-react.js b/scripts/sync-react.js index 171434cff8dec7..431178826f4c2a 100644 --- a/scripts/sync-react.js +++ b/scripts/sync-react.js @@ -211,7 +211,7 @@ async function main() { ) { const { stdout, stderr } = await execa( 'npm', - ['view', 'react@canary', 'version'], + ['--silent', 'view', 'react@canary', 'version'], { // Avoid "Usage Error: This project is configured to use pnpm". cwd: '/tmp', From aed6c4c0a03388088184656f6c0bd570670531fb Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Wed, 23 Oct 2024 16:41:15 +0200 Subject: [PATCH 29/44] Fix: revert the bad node binary handling (#71723) --- packages/next/src/build/webpack-config.ts | 20 +++++------ .../loaders/next-server-binary-loader.ts | 12 ------- ...ernalize-node-binary-browser-error.test.ts | 35 +++++++++---------- .../externalize-node-binary.test.ts | 3 +- 4 files changed, 27 insertions(+), 43 deletions(-) delete mode 100644 packages/next/src/build/webpack/loaders/next-server-binary-loader.ts diff --git a/packages/next/src/build/webpack-config.ts b/packages/next/src/build/webpack-config.ts index 57ab6cee13f390..d65810e6c31e93 100644 --- a/packages/next/src/build/webpack-config.ts +++ b/packages/next/src/build/webpack-config.ts @@ -1202,7 +1202,6 @@ export default async function getBaseWebpackConfig( 'next-metadata-route-loader', 'modularize-import-loader', 'next-barrel-loader', - 'next-server-binary-loader', 'next-error-browser-binary-loader', ].reduce( (alias, loader) => { @@ -1291,17 +1290,14 @@ export default async function getBaseWebpackConfig( or: WEBPACK_LAYERS.GROUP.neutralTarget, }, }, - { - test: /[\\/].*?\.node$/, - loader: isNodeServer - ? 'next-server-binary-loader' - : 'next-error-browser-binary-loader', - // On server side bundling, only apply to app router, do not apply to pages router; - // On client side or edge runtime bundling, always error. - ...(isNodeServer && { - issuerLayer: isWebpackBundledLayer, - }), - }, + ...(isNodeServer + ? [] + : [ + { + test: /[\\/].*?\.node$/, + loader: 'next-error-browser-binary-loader', + }, + ]), ...(hasAppDir ? [ { diff --git a/packages/next/src/build/webpack/loaders/next-server-binary-loader.ts b/packages/next/src/build/webpack/loaders/next-server-binary-loader.ts deleted file mode 100644 index a395d8476fd7d3..00000000000000 --- a/packages/next/src/build/webpack/loaders/next-server-binary-loader.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { webpack } from 'next/dist/compiled/webpack/webpack' -import path from 'path' - -export default function nextErrorBrowserBinaryLoader( - this: webpack.LoaderContext -) { - let relativePath = path.relative(this.rootContext, this.resourcePath) - if (!relativePath.startsWith('.')) { - relativePath = './' + relativePath - } - return `module.exports = __non_webpack_require__(${JSON.stringify(relativePath)})` -} diff --git a/test/development/app-dir/externalize-node-binary-browser-error/externalize-node-binary-browser-error.test.ts b/test/development/app-dir/externalize-node-binary-browser-error/externalize-node-binary-browser-error.test.ts index e67478a937ca79..8dd9d5e51b5412 100644 --- a/test/development/app-dir/externalize-node-binary-browser-error/externalize-node-binary-browser-error.test.ts +++ b/test/development/app-dir/externalize-node-binary-browser-error/externalize-node-binary-browser-error.test.ts @@ -4,26 +4,25 @@ import { getRedboxDescription, getRedboxSource, } from 'next-test-utils' -;(process.env.TURBOPACK ? describe.skip : describe)( - 'externalize-node-binary-browser-error', - () => { - const { next } = nextTestSetup({ - files: __dirname, - }) - it('should error when import node binary on browser side', async () => { - const browser = await next.browser('/') - await assertHasRedbox(browser) - const redbox = { - description: await getRedboxDescription(browser), - source: await getRedboxSource(browser), - } +// FIXME: er-enable when we have a better implementation of node binary resolving +describe.skip('externalize-node-binary-browser-error', () => { + const { next } = nextTestSetup({ + files: __dirname, + }) - expect(redbox.description).toBe('Failed to compile') - expect(redbox.source).toMatchInlineSnapshot(` + it('should error when import node binary on browser side', async () => { + const browser = await next.browser('/') + await assertHasRedbox(browser) + const redbox = { + description: await getRedboxDescription(browser), + source: await getRedboxSource(browser), + } + + expect(redbox.description).toBe('Failed to compile') + expect(redbox.source).toMatchInlineSnapshot(` "./node_modules/foo-browser-import-binary/binary.node Error: Node.js binary module ./node_modules/foo-browser-import-binary/binary.node is not supported in the browser. Please only use the module on server side" `) - }) - } -) + }) +}) diff --git a/test/e2e/app-dir/externalize-node-binary/externalize-node-binary.test.ts b/test/e2e/app-dir/externalize-node-binary/externalize-node-binary.test.ts index bf5090cb24ee73..07017d378bd4ef 100644 --- a/test/e2e/app-dir/externalize-node-binary/externalize-node-binary.test.ts +++ b/test/e2e/app-dir/externalize-node-binary/externalize-node-binary.test.ts @@ -1,6 +1,7 @@ import { nextTestSetup } from 'e2e-utils' -describe('externalize-node-binary', () => { +// FIXME: er-enable when we have a better implementation of node binary resolving +describe.skip('externalize-node-binary', () => { const { next } = nextTestSetup({ files: __dirname, }) From 741f8300b629938de558bf257adf36ef48172789 Mon Sep 17 00:00:00 2001 From: Jiwon Choi Date: Wed, 23 Oct 2024 23:55:20 +0900 Subject: [PATCH 30/44] next-codemod: add empty `pnpm-workspace.yaml` to test fixtures to bypass PNPM workspace checks (#71726) ### Why? Since dep installation within next-codemod runs `pnpm install` on the Next.js repo, it installs in the workspace root scope during testing. We could add a layer for testing like adding a flag `--no-workspace`, but it will reduce confidence between the actual running and testing. Therefore added an empty `pnpm-workspace.yaml` file to each fixture. ### How? By doing this, both installation and testing will have same environment of running, `pnpm install` only. To prevent created `pnpm-lockfile` to be shipped, gitignored it. This way, we keep things simple and make sure tests match real-world use better. The empty `pnpm-workspace.yaml` files make `pnpm` treat each fixture separately, which is closer to how it'll work for users. --- packages/next-codemod/bin/__testfixtures__/.gitignore | 1 + .../bin/__testfixtures__/geo-ip-usage/pnpm-workspace.yaml | 0 .../bin/__testfixtures__/next-14-installed/pnpm-workspace.yaml | 0 .../next-15-canary-43-installed/pnpm-workspace.yaml | 0 .../next-15-canary-44-installed/pnpm-workspace.yaml | 0 .../bin/__testfixtures__/no-geo-ip-usage/pnpm-workspace.yaml | 0 .../__testfixtures__/peer-dep-out-of-range/pnpm-workspace.yaml | 0 .../react-18-installed-mixed-router/pnpm-workspace.yaml | 0 .../react-18-installed-pure-app-router/pnpm-workspace.yaml | 0 .../react-18-installed-pure-pages-router/pnpm-workspace.yaml | 0 .../react-19-installed-mixed-router/pnpm-workspace.yaml | 0 .../react-19-installed-pure-app-router/pnpm-workspace.yaml | 0 .../react-19-installed-pure-pages-router/pnpm-workspace.yaml | 0 packages/next-codemod/scripts/test-upgrade-fixture.sh | 2 +- 14 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 packages/next-codemod/bin/__testfixtures__/.gitignore create mode 100644 packages/next-codemod/bin/__testfixtures__/geo-ip-usage/pnpm-workspace.yaml create mode 100644 packages/next-codemod/bin/__testfixtures__/next-14-installed/pnpm-workspace.yaml create mode 100644 packages/next-codemod/bin/__testfixtures__/next-15-canary-43-installed/pnpm-workspace.yaml create mode 100644 packages/next-codemod/bin/__testfixtures__/next-15-canary-44-installed/pnpm-workspace.yaml create mode 100644 packages/next-codemod/bin/__testfixtures__/no-geo-ip-usage/pnpm-workspace.yaml create mode 100644 packages/next-codemod/bin/__testfixtures__/peer-dep-out-of-range/pnpm-workspace.yaml create mode 100644 packages/next-codemod/bin/__testfixtures__/react-18-installed-mixed-router/pnpm-workspace.yaml create mode 100644 packages/next-codemod/bin/__testfixtures__/react-18-installed-pure-app-router/pnpm-workspace.yaml create mode 100644 packages/next-codemod/bin/__testfixtures__/react-18-installed-pure-pages-router/pnpm-workspace.yaml create mode 100644 packages/next-codemod/bin/__testfixtures__/react-19-installed-mixed-router/pnpm-workspace.yaml create mode 100644 packages/next-codemod/bin/__testfixtures__/react-19-installed-pure-app-router/pnpm-workspace.yaml create mode 100644 packages/next-codemod/bin/__testfixtures__/react-19-installed-pure-pages-router/pnpm-workspace.yaml diff --git a/packages/next-codemod/bin/__testfixtures__/.gitignore b/packages/next-codemod/bin/__testfixtures__/.gitignore new file mode 100644 index 00000000000000..bd5535a6035b27 --- /dev/null +++ b/packages/next-codemod/bin/__testfixtures__/.gitignore @@ -0,0 +1 @@ +pnpm-lock.yaml diff --git a/packages/next-codemod/bin/__testfixtures__/geo-ip-usage/pnpm-workspace.yaml b/packages/next-codemod/bin/__testfixtures__/geo-ip-usage/pnpm-workspace.yaml new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/packages/next-codemod/bin/__testfixtures__/next-14-installed/pnpm-workspace.yaml b/packages/next-codemod/bin/__testfixtures__/next-14-installed/pnpm-workspace.yaml new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/packages/next-codemod/bin/__testfixtures__/next-15-canary-43-installed/pnpm-workspace.yaml b/packages/next-codemod/bin/__testfixtures__/next-15-canary-43-installed/pnpm-workspace.yaml new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/packages/next-codemod/bin/__testfixtures__/next-15-canary-44-installed/pnpm-workspace.yaml b/packages/next-codemod/bin/__testfixtures__/next-15-canary-44-installed/pnpm-workspace.yaml new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/packages/next-codemod/bin/__testfixtures__/no-geo-ip-usage/pnpm-workspace.yaml b/packages/next-codemod/bin/__testfixtures__/no-geo-ip-usage/pnpm-workspace.yaml new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/packages/next-codemod/bin/__testfixtures__/peer-dep-out-of-range/pnpm-workspace.yaml b/packages/next-codemod/bin/__testfixtures__/peer-dep-out-of-range/pnpm-workspace.yaml new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/packages/next-codemod/bin/__testfixtures__/react-18-installed-mixed-router/pnpm-workspace.yaml b/packages/next-codemod/bin/__testfixtures__/react-18-installed-mixed-router/pnpm-workspace.yaml new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/packages/next-codemod/bin/__testfixtures__/react-18-installed-pure-app-router/pnpm-workspace.yaml b/packages/next-codemod/bin/__testfixtures__/react-18-installed-pure-app-router/pnpm-workspace.yaml new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/packages/next-codemod/bin/__testfixtures__/react-18-installed-pure-pages-router/pnpm-workspace.yaml b/packages/next-codemod/bin/__testfixtures__/react-18-installed-pure-pages-router/pnpm-workspace.yaml new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/packages/next-codemod/bin/__testfixtures__/react-19-installed-mixed-router/pnpm-workspace.yaml b/packages/next-codemod/bin/__testfixtures__/react-19-installed-mixed-router/pnpm-workspace.yaml new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/packages/next-codemod/bin/__testfixtures__/react-19-installed-pure-app-router/pnpm-workspace.yaml b/packages/next-codemod/bin/__testfixtures__/react-19-installed-pure-app-router/pnpm-workspace.yaml new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/packages/next-codemod/bin/__testfixtures__/react-19-installed-pure-pages-router/pnpm-workspace.yaml b/packages/next-codemod/bin/__testfixtures__/react-19-installed-pure-pages-router/pnpm-workspace.yaml new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/packages/next-codemod/scripts/test-upgrade-fixture.sh b/packages/next-codemod/scripts/test-upgrade-fixture.sh index 1a86df2c23823a..ffa800b980efec 100755 --- a/packages/next-codemod/scripts/test-upgrade-fixture.sh +++ b/packages/next-codemod/scripts/test-upgrade-fixture.sh @@ -11,7 +11,7 @@ cd "$1" || exit 1 # We're only interested in the changes the upgrade command does. git add -A . rm -rf node_modules -pnpm install --ignore-workspace --no-lockfile +pnpm install node "$NEXT_CODEMOD_BIN" upgrade "${@:2}" git --no-pager diff . git restore . From bbad635af2a5d5bb6c00f5e9ef5312b9752c9047 Mon Sep 17 00:00:00 2001 From: Zack Tanner <1939140+ztanner@users.noreply.github.com> Date: Wed, 23 Oct 2024 07:56:23 -0700 Subject: [PATCH 31/44] warn on sync access if dynamicIO is not enabled (#71696) 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. --- ...eduped-by-callsite-server-error-logger.ts} | 13 +++- packages/next/src/server/request/cookies.ts | 2 +- .../next/src/server/request/draft-mode.ts | 2 +- packages/next/src/server/request/headers.ts | 2 +- packages/next/src/server/request/params.ts | 2 +- .../next/src/server/request/search-params.ts | 2 +- .../async-request-warnings.test.ts | 62 +++++++++---------- 7 files changed, 46 insertions(+), 39 deletions(-) rename packages/next/src/server/{create-deduped-by-callsite-server-error-loger.ts => create-deduped-by-callsite-server-error-logger.ts} (84%) diff --git a/packages/next/src/server/create-deduped-by-callsite-server-error-loger.ts b/packages/next/src/server/create-deduped-by-callsite-server-error-logger.ts similarity index 84% rename from packages/next/src/server/create-deduped-by-callsite-server-error-loger.ts rename to packages/next/src/server/create-deduped-by-callsite-server-error-logger.ts index 84ce1d6ea0f779..7549c2cbdb934a 100644 --- a/packages/next/src/server/create-deduped-by-callsite-server-error-loger.ts +++ b/packages/next/src/server/create-deduped-by-callsite-server-error-logger.ts @@ -8,13 +8,20 @@ const cache = ? React.cache : (fn: (key: unknown) => void) => fn +// When Dynamic IO is enabled, we record these as errors so that they +// are captured by the dev overlay as it's more critical to fix these +// when enabled. +const logErrorOrWarn = process.env.__NEXT_DYNAMIC_IO + ? console.error + : console.warn + // We don't want to dedupe across requests. // The developer might've just attempted to fix the warning so we should warn again if it still happens. const flushCurrentErrorIfNew = cache( // eslint-disable-next-line @typescript-eslint/no-unused-vars -- cache key (key: unknown) => { try { - console.error(errorRef.current) + logErrorOrWarn(errorRef.current) } finally { errorRef.current = null } @@ -41,7 +48,7 @@ export function createDedupedByCallsiteServerErrorLoggerDev( if (process.env.NODE_ENV !== 'production') { const callStackFrames = new Error().stack?.split('\n') if (callStackFrames === undefined || callStackFrames.length < 4) { - console.error(message) + logErrorOrWarn(message) } else { // Error: // logDedupedError @@ -53,7 +60,7 @@ export function createDedupedByCallsiteServerErrorLoggerDev( flushCurrentErrorIfNew(key) } } else { - console.error(message) + logErrorOrWarn(message) } } } diff --git a/packages/next/src/server/request/cookies.ts b/packages/next/src/server/request/cookies.ts index 7fa30631a35901..5b18fcfc1b1225 100644 --- a/packages/next/src/server/request/cookies.ts +++ b/packages/next/src/server/request/cookies.ts @@ -20,7 +20,7 @@ import { import { getExpectedRequestStore } from '../app-render/work-unit-async-storage.external' import { StaticGenBailoutError } from '../../client/components/static-generation-bailout' import { makeHangingPromise } from '../dynamic-rendering-utils' -import { createDedupedByCallsiteServerErrorLoggerDev } from '../create-deduped-by-callsite-server-error-loger' +import { createDedupedByCallsiteServerErrorLoggerDev } from '../create-deduped-by-callsite-server-error-logger' import { scheduleImmediate } from '../../lib/scheduler' /** diff --git a/packages/next/src/server/request/draft-mode.ts b/packages/next/src/server/request/draft-mode.ts index e4af8d9cc8caaa..954f48a43b380b 100644 --- a/packages/next/src/server/request/draft-mode.ts +++ b/packages/next/src/server/request/draft-mode.ts @@ -9,7 +9,7 @@ import { postponeWithTracking, trackSynchronousRequestDataAccessInDev, } from '../app-render/dynamic-rendering' -import { createDedupedByCallsiteServerErrorLoggerDev } from '../create-deduped-by-callsite-server-error-loger' +import { createDedupedByCallsiteServerErrorLoggerDev } from '../create-deduped-by-callsite-server-error-logger' import { StaticGenBailoutError } from '../../client/components/static-generation-bailout' import { DynamicServerError } from '../../client/components/hooks-server-context' diff --git a/packages/next/src/server/request/headers.ts b/packages/next/src/server/request/headers.ts index fc6fd2b02c7741..87cfa1fadb38f0 100644 --- a/packages/next/src/server/request/headers.ts +++ b/packages/next/src/server/request/headers.ts @@ -17,7 +17,7 @@ import { } from '../app-render/dynamic-rendering' import { StaticGenBailoutError } from '../../client/components/static-generation-bailout' import { makeHangingPromise } from '../dynamic-rendering-utils' -import { createDedupedByCallsiteServerErrorLoggerDev } from '../create-deduped-by-callsite-server-error-loger' +import { createDedupedByCallsiteServerErrorLoggerDev } from '../create-deduped-by-callsite-server-error-logger' import { scheduleImmediate } from '../../lib/scheduler' /** diff --git a/packages/next/src/server/request/params.ts b/packages/next/src/server/request/params.ts index 4318387b137fd8..81a4e72cab7cc2 100644 --- a/packages/next/src/server/request/params.ts +++ b/packages/next/src/server/request/params.ts @@ -19,7 +19,7 @@ import { import { InvariantError } from '../../shared/lib/invariant-error' import { describeStringPropertyAccess, wellKnownProperties } from './utils' import { makeHangingPromise } from '../dynamic-rendering-utils' -import { createDedupedByCallsiteServerErrorLoggerDev } from '../create-deduped-by-callsite-server-error-loger' +import { createDedupedByCallsiteServerErrorLoggerDev } from '../create-deduped-by-callsite-server-error-logger' import { scheduleImmediate } from '../../lib/scheduler' export type Params = Record | undefined> diff --git a/packages/next/src/server/request/search-params.ts b/packages/next/src/server/request/search-params.ts index 21fc2187e94205..578e95549a42ed 100644 --- a/packages/next/src/server/request/search-params.ts +++ b/packages/next/src/server/request/search-params.ts @@ -19,7 +19,7 @@ import { } from '../app-render/work-unit-async-storage.external' import { InvariantError } from '../../shared/lib/invariant-error' import { makeHangingPromise } from '../dynamic-rendering-utils' -import { createDedupedByCallsiteServerErrorLoggerDev } from '../create-deduped-by-callsite-server-error-loger' +import { createDedupedByCallsiteServerErrorLoggerDev } from '../create-deduped-by-callsite-server-error-logger' import { describeStringPropertyAccess, describeHasCheckingStringProperty, diff --git a/test/development/app-dir/async-request-warnings/async-request-warnings.test.ts b/test/development/app-dir/async-request-warnings/async-request-warnings.test.ts index 9f0acb054c3179..3c146eee612c22 100644 --- a/test/development/app-dir/async-request-warnings/async-request-warnings.test.ts +++ b/test/development/app-dir/async-request-warnings/async-request-warnings.test.ts @@ -11,15 +11,15 @@ describe('dynamic-requests warnings', () => { const browser = await next.browser('/request/cookies') const browserLogs = await browser.log() - const browserConsoleErrors = browserLogs - .filter((log) => log.source === 'error') + const browserConsoleWarnings = browserLogs + .filter((log) => log.source === 'warning') .map((log) => log.message) const terminalOutput = next.cliOutput.slice(nextDevBootstrapOutputIndex) const terminalCookieErrors = terminalOutput.split('\n').filter((line) => { return line.includes('Route "/request/cookies') }) - expect({ browserConsoleErrors, terminalCookieErrors }).toEqual({ - browserConsoleErrors: [ + expect({ browserConsoleWarnings, terminalCookieErrors }).toEqual({ + browserConsoleWarnings: [ expect.stringContaining("`cookies().get('page')`."), expect.stringContaining("`cookies().get('component')`."), expect.stringContaining("`cookies().has('component')`."), @@ -39,16 +39,16 @@ describe('dynamic-requests warnings', () => { const browser = await next.browser('/request/draftMode') - const browserLogsserLogs = await browser.log() - const browserConsoleErrors = browserLogsserLogs - .filter((log) => log.source === 'error') + const browserLogs = await browser.log() + const browserConsoleWarnings = browserLogs + .filter((log) => log.source === 'warning') .map((log) => log.message) const terminalOutput = next.cliOutput.slice(nextDevBootstrapOutputIndex) const terminalCookieErrors = terminalOutput.split('\n').filter((line) => { return line.includes('Route "/request/draftMode') }) - expect({ browserConsoleErrors, terminalCookieErrors }).toEqual({ - browserConsoleErrors: [ + expect({ browserConsoleWarnings, terminalCookieErrors }).toEqual({ + browserConsoleWarnings: [ expect.stringContaining('`draftMode().isEnabled`.'), expect.stringContaining('`draftMode().isEnabled`.'), expect.stringContaining('`draftMode().enable()`.'), @@ -68,16 +68,16 @@ describe('dynamic-requests warnings', () => { const browser = await next.browser('/request/headers') - const browserLogsserLogs = await browser.log() - const browserConsoleErrors = browserLogsserLogs - .filter((log) => log.source === 'error') + const browserLogs = await browser.log() + const browserConsoleWarnings = browserLogs + .filter((log) => log.source === 'warning') .map((log) => log.message) const terminalOutput = next.cliOutput.slice(nextDevBootstrapOutputIndex) const terminalCookieErrors = terminalOutput.split('\n').filter((line) => { return line.includes('Route "/request/headers') }) - expect({ browserConsoleErrors, terminalCookieErrors }).toEqual({ - browserConsoleErrors: [ + expect({ browserConsoleWarnings, terminalCookieErrors }).toEqual({ + browserConsoleWarnings: [ expect.stringContaining("`headers().get('page')`."), expect.stringContaining("`headers().get('component')`."), expect.stringContaining("`headers().has('component')`."), @@ -97,16 +97,16 @@ describe('dynamic-requests warnings', () => { const browser = await next.browser('/request/params/[slug]') - const browserLogsserLogs = await browser.log() - const browserConsoleErrors = browserLogsserLogs - .filter((log) => log.source === 'error') + const browserLogs = await browser.log() + const browserConsoleWarnings = browserLogs + .filter((log) => log.source === 'warning') .map((log) => log.message) const terminalOutput = next.cliOutput.slice(nextDevBootstrapOutputIndex) const terminalCookieErrors = terminalOutput.split('\n').filter((line) => { return line.includes('Route "/request/params/[slug]') }) - expect({ browserConsoleErrors, terminalCookieErrors }).toEqual({ - browserConsoleErrors: [ + expect({ browserConsoleWarnings, terminalCookieErrors }).toEqual({ + browserConsoleWarnings: [ expect.stringContaining('`params.slug`.'), expect.stringContaining('`params.slug`.'), expect.stringContaining('`params.slug`.'), @@ -126,16 +126,16 @@ describe('dynamic-requests warnings', () => { const browser = await next.browser('/request/searchParams') - const browserLogsserLogs = await browser.log() - const browserConsoleErrors = browserLogsserLogs - .filter((log) => log.source === 'error') + const browserLogs = await browser.log() + const browserConsoleWarnings = browserLogs + .filter((log) => log.source === 'warning') .map((log) => log.message) const terminalOutput = next.cliOutput.slice(nextDevBootstrapOutputIndex) const terminalCookieErrors = terminalOutput.split('\n').filter((line) => { return line.includes('Route "/request/searchParams') }) - expect({ browserConsoleErrors, terminalCookieErrors }).toEqual({ - browserConsoleErrors: [ + expect({ browserConsoleWarnings, terminalCookieErrors }).toEqual({ + browserConsoleWarnings: [ expect.stringContaining('`searchParams.slug`.'), expect.stringContaining('`searchParams.slug`.'), expect.stringContaining('`searchParams.slug`.'), @@ -154,24 +154,24 @@ describe('dynamic-requests warnings', () => { it('should have no warnings on normal rsc page without accessing params', async () => { const browser = await next.browser('/no-access/normal') const browserLogItems = await browser.log() - const browserConsoleErrors = browserLogItems - .filter((log) => log.source === 'error') + const browserConsoleWarnings = browserLogItems + .filter((log) => log.source === 'warning') .map((log) => log.message) - expect(browserConsoleErrors.length).toBe(0) + expect(browserConsoleWarnings.length).toBe(0) }) it('should only have hydration warnings on hydration mismatch page without accessing params', async () => { const browser = await next.browser('/no-access/mismatch') const browserLogItems = await browser.log() console.log('browserLogItems', browserLogItems) - const browserConsoleErrors = browserLogItems - .filter((log) => log.source === 'error') + const browserConsoleWarnings = browserLogItems + .filter((log) => log.source === 'warning') .map((log) => log.message) // We assert there are zero logged errors but first we assert specific strings b/c we want a better // failure message if these do appear - expect(browserConsoleErrors).toEqual( + expect(browserConsoleWarnings).toEqual( expect.not.arrayContaining([ expect.stringContaining('param property was accessed directly with'), expect.stringContaining( @@ -182,7 +182,7 @@ describe('dynamic-requests warnings', () => { // Even though there is a hydration error it does show up in the logs list b/c it is an // uncaught Error not a console.error. We expect there to be no logged errors - expect(browserConsoleErrors.length).toBe(0) + expect(browserConsoleWarnings.length).toBe(0) }) }) }) From 40790d8576d05b119db3711186029d55562753c2 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Wed, 23 Oct 2024 15:05:08 +0000 Subject: [PATCH 32/44] v15.0.2-canary.0 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 17 files changed, 32 insertions(+), 32 deletions(-) diff --git a/lerna.json b/lerna.json index 84541a6dd61515..53bdaa8bc82ccb 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "15.0.1" + "version": "15.0.2-canary.0" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index d6bf6896784e36..564b9268750394 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "15.0.1", + "version": "15.0.2-canary.0", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 3b44f714949cd9..26321c99cd4227 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "15.0.1", + "version": "15.0.2-canary.0", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "15.0.1", + "@next/eslint-plugin-next": "15.0.2-canary.0", "@rushstack/eslint-patch": "^1.10.3", "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 3f5d615b045c62..8c6580436137e4 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "15.0.1", + "version": "15.0.2-canary.0", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 20061d0e29a9d6..fab3d913fe1c57 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,7 +1,7 @@ { "name": "@next/font", "private": true, - "version": "15.0.1", + "version": "15.0.2-canary.0", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index aa6317f6c3019a..fddd0a1047ca9b 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "15.0.1", + "version": "15.0.2-canary.0", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 37efac64f58f03..899e0949f25a3b 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "15.0.1", + "version": "15.0.2-canary.0", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index f14fce094436ec..5b01aba40e1704 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "15.0.1", + "version": "15.0.2-canary.0", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index f79bc489e94ae2..95e772fd14621f 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "15.0.1", + "version": "15.0.2-canary.0", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 8390b76e7c8f50..153f5cadf07502 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "15.0.1", + "version": "15.0.2-canary.0", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 03ce725713a641..f9e5ec5c89ef49 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "15.0.1", + "version": "15.0.2-canary.0", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index fd57c20497de0f..1fcab439f86ca7 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "15.0.1", + "version": "15.0.2-canary.0", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 4aa3897d79bc6b..8e523cdedd5cde 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "15.0.1", + "version": "15.0.2-canary.0", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 550ef8b3d43897..d8bce91f815eab 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "15.0.1", + "version": "15.0.2-canary.0", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -95,7 +95,7 @@ ] }, "dependencies": { - "@next/env": "15.0.1", + "@next/env": "15.0.2-canary.0", "@swc/counter": "0.1.3", "@swc/helpers": "0.5.13", "busboy": "1.6.0", @@ -159,11 +159,11 @@ "@jest/types": "29.5.0", "@mswjs/interceptors": "0.23.0", "@napi-rs/triples": "1.2.0", - "@next/font": "15.0.1", - "@next/polyfill-module": "15.0.1", - "@next/polyfill-nomodule": "15.0.1", - "@next/react-refresh-utils": "15.0.1", - "@next/swc": "15.0.1", + "@next/font": "15.0.2-canary.0", + "@next/polyfill-module": "15.0.2-canary.0", + "@next/polyfill-nomodule": "15.0.2-canary.0", + "@next/react-refresh-utils": "15.0.2-canary.0", + "@next/swc": "15.0.2-canary.0", "@opentelemetry/api": "1.6.0", "@playwright/test": "1.41.2", "@swc/core": "1.7.0-nightly-20240714.1", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 87fe26321e6767..76212c12dce9f9 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "15.0.1", + "version": "15.0.2-canary.0", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index fc748fe063e3a1..6106657bd6ef4e 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "15.0.1", + "version": "15.0.2-canary.0", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -26,7 +26,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "15.0.1", + "next": "15.0.2-canary.0", "outdent": "0.8.0", "prettier": "2.5.1", "typescript": "5.5.3" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e5b4f92af874d4..3f4127d52472a8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -795,7 +795,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 15.0.1 + specifier: 15.0.2-canary.0 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.10.3 @@ -859,7 +859,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 15.0.1 + specifier: 15.0.2-canary.0 version: link:../next-env '@swc/counter': specifier: 0.1.3 @@ -987,19 +987,19 @@ importers: specifier: 1.2.0 version: 1.2.0 '@next/font': - specifier: 15.0.1 + specifier: 15.0.2-canary.0 version: link:../font '@next/polyfill-module': - specifier: 15.0.1 + specifier: 15.0.2-canary.0 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 15.0.1 + specifier: 15.0.2-canary.0 version: link:../next-polyfill-nomodule '@next/react-refresh-utils': - specifier: 15.0.1 + specifier: 15.0.2-canary.0 version: link:../react-refresh-utils '@next/swc': - specifier: 15.0.1 + specifier: 15.0.2-canary.0 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1633,7 +1633,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 15.0.1 + specifier: 15.0.2-canary.0 version: link:../next outdent: specifier: 0.8.0 From 4835be182b88f67f282c30db4278c30fe9e5b483 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Wed, 23 Oct 2024 17:28:44 +0200 Subject: [PATCH 33/44] Docs: Update default marker for fetch cache option (#71728) This page was showing the outdated default. --- docs/02-app/02-api-reference/04-functions/fetch.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/02-app/02-api-reference/04-functions/fetch.mdx b/docs/02-app/02-api-reference/04-functions/fetch.mdx index 055d5f1f791525..bbc3e9f3f8ca78 100644 --- a/docs/02-app/02-api-reference/04-functions/fetch.mdx +++ b/docs/02-app/02-api-reference/04-functions/fetch.mdx @@ -49,10 +49,10 @@ Configure how the request should interact with Next.js [Data Cache](/docs/app/bu fetch(`https://...`, { cache: 'force-cache' | 'no-store' }) ``` -- **`force-cache`** (default): Next.js looks for a matching request in its Data Cache. +- **`no-store`** (default): Next.js fetches the resource from the remote server on every request without looking in the cache, and it will not update the cache with the downloaded resource. +- **`force-cache`**: Next.js looks for a matching request in its Data Cache. - If there is a match and it is fresh, it will be returned from the cache. - If there is no match or a stale match, Next.js will fetch the resource from the remote server and update the cache with the downloaded resource. -- **`no-store`**: Next.js fetches the resource from the remote server on every request without looking in the cache, and it will not update the cache with the downloaded resource. ### `options.next.revalidate` From e1632ccbe0498fe65a36e0dd520da164802e7143 Mon Sep 17 00:00:00 2001 From: Can Temizyurek <101304677+cantemizyurek@users.noreply.github.com> Date: Wed, 23 Oct 2024 12:16:16 -0400 Subject: [PATCH 34/44] [docs] Fix page.tsx parameter types (#71680) Closes https://github.com/vercel/next.js/issues/71679 Co-authored-by: Zack Tanner <1939140+ztanner@users.noreply.github.com> --- .../03-rendering/04-partial-prerendering.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/02-app/01-building-your-application/03-rendering/04-partial-prerendering.mdx b/docs/02-app/01-building-your-application/03-rendering/04-partial-prerendering.mdx index 2e51f677cb32e2..3e23c39f06795c 100644 --- a/docs/02-app/01-building-your-application/03-rendering/04-partial-prerendering.mdx +++ b/docs/02-app/01-building-your-application/03-rendering/04-partial-prerendering.mdx @@ -197,7 +197,7 @@ import { Table } from './table' export default function Page({ searchParams, }: { - searchParams: { sort: string } + searchParams: Promise<{ sort: string }> }) { return (
    From 465d1bbc51ae5fbba8870d7c8cfc56f95f4f221e Mon Sep 17 00:00:00 2001 From: Can Temizyurek <101304677+cantemizyurek@users.noreply.github.com> Date: Wed, 23 Oct 2024 12:27:41 -0400 Subject: [PATCH 35/44] [docs] Fix table.js containing TS code (#71677) Closes https://github.com/vercel/next.js/issues/71675. Co-authored-by: Zack Tanner <1939140+ztanner@users.noreply.github.com> --- .../03-rendering/04-partial-prerendering.mdx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/02-app/01-building-your-application/03-rendering/04-partial-prerendering.mdx b/docs/02-app/01-building-your-application/03-rendering/04-partial-prerendering.mdx index 3e23c39f06795c..8445c6e1c7a419 100644 --- a/docs/02-app/01-building-your-application/03-rendering/04-partial-prerendering.mdx +++ b/docs/02-app/01-building-your-application/03-rendering/04-partial-prerendering.mdx @@ -235,10 +235,8 @@ export async function Table({ ``` ```jsx filename="app/table.js" switcher -export async function Table({ searchParams }: { - searchParams: Promise<{ sort: string }> -}) { - const sort = (await searchParams).sort === 'true'; +export async function Table({ searchParams }) { + const sort = (await searchParams).sort === 'true' return '...' } ``` From babc6a0242ffabca14f39d748f2905229d45f352 Mon Sep 17 00:00:00 2001 From: "Sebastian \"Sebbie\" Silbermann" Date: Wed, 23 Oct 2024 18:55:39 +0200 Subject: [PATCH 36/44] Update React from `69d4b800-20241021` to `45804af1-20241021` (#71718) --- examples/reproduction-template/package.json | 4 +- package.json | 34 +- packages/create-next-app/templates/index.ts | 2 +- packages/next/package.json | 4 +- .../cjs/react-dom-client.development.js | 10 +- .../cjs/react-dom-client.production.js | 10 +- .../cjs/react-dom-profiling.development.js | 10 +- .../cjs/react-dom-profiling.profiling.js | 10 +- ...t-dom-server-legacy.browser.development.js | 2 +- ...ct-dom-server-legacy.browser.production.js | 2 +- ...eact-dom-server-legacy.node.development.js | 2 +- ...react-dom-server-legacy.node.production.js | 2 +- .../react-dom-server.browser.development.js | 6 +- .../react-dom-server.browser.production.js | 6 +- .../cjs/react-dom-server.bun.production.js | 6 +- .../cjs/react-dom-server.edge.development.js | 6 +- .../cjs/react-dom-server.edge.production.js | 6 +- .../cjs/react-dom-server.node.development.js | 6 +- .../cjs/react-dom-server.node.production.js | 6 +- .../react-dom-unstable_testing.development.js | 10 +- .../react-dom-unstable_testing.production.js | 10 +- .../cjs/react-dom.development.js | 2 +- .../cjs/react-dom.production.js | 2 +- .../cjs/react-dom.react-server.development.js | 2 +- .../cjs/react-dom.react-server.production.js | 2 +- .../react-dom-experimental/package.json | 4 +- .../cjs/react-dom-client.development.js | 10 +- .../cjs/react-dom-client.production.js | 10 +- .../cjs/react-dom-profiling.development.js | 10 +- .../cjs/react-dom-profiling.profiling.js | 10 +- ...t-dom-server-legacy.browser.development.js | 2 +- ...ct-dom-server-legacy.browser.production.js | 2 +- ...eact-dom-server-legacy.node.development.js | 2 +- ...react-dom-server-legacy.node.production.js | 2 +- .../react-dom-server.browser.development.js | 6 +- .../react-dom-server.browser.production.js | 6 +- .../cjs/react-dom-server.bun.production.js | 6 +- .../cjs/react-dom-server.edge.development.js | 6 +- .../cjs/react-dom-server.edge.production.js | 6 +- .../cjs/react-dom-server.node.development.js | 6 +- .../cjs/react-dom-server.node.production.js | 6 +- .../react-dom/cjs/react-dom.development.js | 2 +- .../react-dom/cjs/react-dom.production.js | 2 +- .../cjs/react-dom.react-server.development.js | 2 +- .../cjs/react-dom.react-server.production.js | 2 +- .../next/src/compiled/react-dom/package.json | 4 +- .../cjs/react.development.js | 2 +- .../cjs/react.production.js | 2 +- .../cjs/react.react-server.development.js | 2 +- .../cjs/react.react-server.production.js | 2 +- .../next/src/compiled/react-is/package.json | 2 +- ...om-turbopack-client.browser.development.js | 4 +- .../package.json | 4 +- ...om-turbopack-client.browser.development.js | 4 +- .../react-server-dom-turbopack/package.json | 4 +- ...-dom-webpack-client.browser.development.js | 4 +- .../package.json | 4 +- ...-dom-webpack-client.browser.development.js | 4 +- .../react-server-dom-webpack/package.json | 4 +- .../compiled/react/cjs/react.development.js | 2 +- .../compiled/react/cjs/react.production.js | 2 +- .../cjs/react.react-server.development.js | 2 +- .../cjs/react.react-server.production.js | 2 +- .../next/src/compiled/unistore/unistore.js | 2 +- packages/third-parties/package.json | 2 +- pnpm-lock.yaml | 376 +++++++++--------- run-tests.js | 2 +- test/.stats-app/package.json | 4 +- .../first-time-setup-js/package.json | 4 +- .../first-time-setup-ts/package.json | 4 +- test/lib/next-modes/base.ts | 2 +- 71 files changed, 357 insertions(+), 357 deletions(-) diff --git a/examples/reproduction-template/package.json b/examples/reproduction-template/package.json index dfde8547e644cd..2ea88b49fff880 100644 --- a/examples/reproduction-template/package.json +++ b/examples/reproduction-template/package.json @@ -7,8 +7,8 @@ }, "dependencies": { "next": "canary", - "react": "19.0.0-rc-69d4b800-20241021", - "react-dom": "19.0.0-rc-69d4b800-20241021" + "react": "19.0.0-rc-45804af1-20241021", + "react-dom": "19.0.0-rc-45804af1-20241021" }, "devDependencies": { "@types/node": "20.12.12", diff --git a/package.json b/package.json index dc41e33e18feef..5c38c3482dca51 100644 --- a/package.json +++ b/package.json @@ -209,19 +209,19 @@ "pretty-bytes": "5.3.0", "pretty-ms": "7.0.0", "random-seed": "0.3.0", - "react": "19.0.0-rc-69d4b800-20241021", + "react": "19.0.0-rc-45804af1-20241021", "react-17": "npm:react@17.0.2", - "react-builtin": "npm:react@19.0.0-rc-69d4b800-20241021", - "react-dom": "19.0.0-rc-69d4b800-20241021", + "react-builtin": "npm:react@19.0.0-rc-45804af1-20241021", + "react-dom": "19.0.0-rc-45804af1-20241021", "react-dom-17": "npm:react-dom@17.0.2", - "react-dom-builtin": "npm:react-dom@19.0.0-rc-69d4b800-20241021", - "react-dom-experimental-builtin": "npm:react-dom@0.0.0-experimental-69d4b800-20241021", - "react-experimental-builtin": "npm:react@0.0.0-experimental-69d4b800-20241021", - "react-is-builtin": "npm:react-is@19.0.0-rc-69d4b800-20241021", - "react-server-dom-turbopack": "19.0.0-rc-69d4b800-20241021", - "react-server-dom-turbopack-experimental": "npm:react-server-dom-turbopack@0.0.0-experimental-69d4b800-20241021", - "react-server-dom-webpack": "19.0.0-rc-69d4b800-20241021", - "react-server-dom-webpack-experimental": "npm:react-server-dom-webpack@0.0.0-experimental-69d4b800-20241021", + "react-dom-builtin": "npm:react-dom@19.0.0-rc-45804af1-20241021", + "react-dom-experimental-builtin": "npm:react-dom@0.0.0-experimental-45804af1-20241021", + "react-experimental-builtin": "npm:react@0.0.0-experimental-45804af1-20241021", + "react-is-builtin": "npm:react-is@19.0.0-rc-45804af1-20241021", + "react-server-dom-turbopack": "19.0.0-rc-45804af1-20241021", + "react-server-dom-turbopack-experimental": "npm:react-server-dom-turbopack@0.0.0-experimental-45804af1-20241021", + "react-server-dom-webpack": "19.0.0-rc-45804af1-20241021", + "react-server-dom-webpack-experimental": "npm:react-server-dom-webpack@0.0.0-experimental-45804af1-20241021", "react-ssr-prepass": "1.0.8", "react-virtualized": "9.22.3", "relay-compiler": "13.0.2", @@ -231,8 +231,8 @@ "resolve-from": "5.0.0", "sass": "1.54.0", "satori": "0.10.9", - "scheduler-builtin": "npm:scheduler@0.25.0-rc-69d4b800-20241021", - "scheduler-experimental-builtin": "npm:scheduler@0.0.0-experimental-69d4b800-20241021", + "scheduler-builtin": "npm:scheduler@0.25.0-rc-45804af1-20241021", + "scheduler-experimental-builtin": "npm:scheduler@0.0.0-experimental-45804af1-20241021", "seedrandom": "3.0.5", "semver": "7.3.7", "shell-quote": "1.7.3", @@ -272,10 +272,10 @@ "@babel/traverse": "7.22.5", "@types/react": "npm:types-react@19.0.0-rc.0", "@types/react-dom": "npm:types-react-dom@19.0.0-rc.0", - "react": "19.0.0-rc-69d4b800-20241021", - "react-dom": "19.0.0-rc-69d4b800-20241021", - "react-is": "19.0.0-rc-69d4b800-20241021", - "scheduler": "0.25.0-rc-69d4b800-20241021" + "react": "19.0.0-rc-45804af1-20241021", + "react-dom": "19.0.0-rc-45804af1-20241021", + "react-is": "19.0.0-rc-45804af1-20241021", + "scheduler": "0.25.0-rc-45804af1-20241021" }, "patchedDependencies": { "webpack-sources@3.2.3": "patches/webpack-sources@3.2.3.patch" diff --git a/packages/create-next-app/templates/index.ts b/packages/create-next-app/templates/index.ts index 5aba2dbd14464d..1540c3a3f2f7f7 100644 --- a/packages/create-next-app/templates/index.ts +++ b/packages/create-next-app/templates/index.ts @@ -13,7 +13,7 @@ import { GetTemplateFileArgs, InstallTemplateArgs } from "./types"; // Do not rename or format. sync-react script relies on this line. // prettier-ignore -const nextjsReactPeerVersion = "19.0.0-rc-69d4b800-20241021"; +const nextjsReactPeerVersion = "19.0.0-rc-45804af1-20241021"; /** * Get the file path for a given file in a template, e.g. "next.config.js". diff --git a/packages/next/package.json b/packages/next/package.json index d8bce91f815eab..9bca2bfb5f83c0 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -107,8 +107,8 @@ "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.41.2", "babel-plugin-react-compiler": "*", - "react": "^18.2.0 || 19.0.0-rc-69d4b800-20241021", - "react-dom": "^18.2.0 || 19.0.0-rc-69d4b800-20241021", + "react": "^18.2.0 || 19.0.0-rc-45804af1-20241021", + "react-dom": "^18.2.0 || 19.0.0-rc-45804af1-20241021", "sass": "^1.3.0" }, "peerDependenciesMeta": { diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.development.js index 27ea411951986d..2bb99000f7eec0 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.development.js @@ -24912,11 +24912,11 @@ }; (function () { var isomorphicReactPackageVersion = React.version; - if ("19.0.0-experimental-69d4b800-20241021" !== isomorphicReactPackageVersion) + if ("19.0.0-experimental-45804af1-20241021" !== isomorphicReactPackageVersion) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion + - "\n - react-dom: 19.0.0-experimental-69d4b800-20241021\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-experimental-45804af1-20241021\nLearn more: https://react.dev/warnings/version-mismatch") ); })(); ("function" === typeof Map && @@ -24953,11 +24953,11 @@ !(function () { var internals = { bundleType: 1, - version: "19.0.0-experimental-69d4b800-20241021", + version: "19.0.0-experimental-45804af1-20241021", rendererPackageName: "react-dom", currentDispatcherRef: ReactSharedInternals, findFiberByHostInstance: getClosestInstanceFromNode, - reconcilerVersion: "19.0.0-experimental-69d4b800-20241021" + reconcilerVersion: "19.0.0-experimental-45804af1-20241021" }; internals.overrideHookState = overrideHookState; internals.overrideHookStateDeletePath = overrideHookStateDeletePath; @@ -25099,7 +25099,7 @@ listenToAllSupportedEvents(container); return new ReactDOMHydrationRoot(initialChildren); }; - exports.version = "19.0.0-experimental-69d4b800-20241021"; + exports.version = "19.0.0-experimental-45804af1-20241021"; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.production.js index d8dc700064a998..7db6e2675deb1c 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.production.js @@ -15133,14 +15133,14 @@ ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = function (target) { }; var isomorphicReactPackageVersion$jscomp$inline_1670 = React.version; if ( - "19.0.0-experimental-69d4b800-20241021" !== + "19.0.0-experimental-45804af1-20241021" !== isomorphicReactPackageVersion$jscomp$inline_1670 ) throw Error( formatProdErrorMessage( 527, isomorphicReactPackageVersion$jscomp$inline_1670, - "19.0.0-experimental-69d4b800-20241021" + "19.0.0-experimental-45804af1-20241021" ) ); ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { @@ -15162,11 +15162,11 @@ ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { }; var internals$jscomp$inline_2135 = { bundleType: 0, - version: "19.0.0-experimental-69d4b800-20241021", + version: "19.0.0-experimental-45804af1-20241021", rendererPackageName: "react-dom", currentDispatcherRef: ReactSharedInternals, findFiberByHostInstance: getClosestInstanceFromNode, - reconcilerVersion: "19.0.0-experimental-69d4b800-20241021" + reconcilerVersion: "19.0.0-experimental-45804af1-20241021" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_2136 = __REACT_DEVTOOLS_GLOBAL_HOOK__; @@ -15270,4 +15270,4 @@ exports.hydrateRoot = function (container, initialChildren, options) { listenToAllSupportedEvents(container); return new ReactDOMHydrationRoot(initialChildren); }; -exports.version = "19.0.0-experimental-69d4b800-20241021"; +exports.version = "19.0.0-experimental-45804af1-20241021"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.development.js index 7a2974177f1fb7..bf2eb9c42e99e8 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.development.js @@ -24969,11 +24969,11 @@ }; (function () { var isomorphicReactPackageVersion = React.version; - if ("19.0.0-experimental-69d4b800-20241021" !== isomorphicReactPackageVersion) + if ("19.0.0-experimental-45804af1-20241021" !== isomorphicReactPackageVersion) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion + - "\n - react-dom: 19.0.0-experimental-69d4b800-20241021\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-experimental-45804af1-20241021\nLearn more: https://react.dev/warnings/version-mismatch") ); })(); ("function" === typeof Map && @@ -25010,11 +25010,11 @@ !(function () { var internals = { bundleType: 1, - version: "19.0.0-experimental-69d4b800-20241021", + version: "19.0.0-experimental-45804af1-20241021", rendererPackageName: "react-dom", currentDispatcherRef: ReactSharedInternals, findFiberByHostInstance: getClosestInstanceFromNode, - reconcilerVersion: "19.0.0-experimental-69d4b800-20241021" + reconcilerVersion: "19.0.0-experimental-45804af1-20241021" }; internals.overrideHookState = overrideHookState; internals.overrideHookStateDeletePath = overrideHookStateDeletePath; @@ -25486,7 +25486,7 @@ exports.useFormStatus = function () { return resolveDispatcher().useHostTransitionStatus(); }; - exports.version = "19.0.0-experimental-69d4b800-20241021"; + exports.version = "19.0.0-experimental-45804af1-20241021"; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.profiling.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.profiling.js index 39c8dadc3bcb7e..3d323e56dcd10b 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.profiling.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.profiling.js @@ -16023,14 +16023,14 @@ ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = function (target) { }; var isomorphicReactPackageVersion$jscomp$inline_1743 = React.version; if ( - "19.0.0-experimental-69d4b800-20241021" !== + "19.0.0-experimental-45804af1-20241021" !== isomorphicReactPackageVersion$jscomp$inline_1743 ) throw Error( formatProdErrorMessage( 527, isomorphicReactPackageVersion$jscomp$inline_1743, - "19.0.0-experimental-69d4b800-20241021" + "19.0.0-experimental-45804af1-20241021" ) ); ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { @@ -16052,11 +16052,11 @@ ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { }; var internals$jscomp$inline_2181 = { bundleType: 0, - version: "19.0.0-experimental-69d4b800-20241021", + version: "19.0.0-experimental-45804af1-20241021", rendererPackageName: "react-dom", currentDispatcherRef: ReactSharedInternals, findFiberByHostInstance: getClosestInstanceFromNode, - reconcilerVersion: "19.0.0-experimental-69d4b800-20241021" + reconcilerVersion: "19.0.0-experimental-45804af1-20241021" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_2182 = __REACT_DEVTOOLS_GLOBAL_HOOK__; @@ -16321,7 +16321,7 @@ exports.useFormState = function (action, initialState, permalink) { exports.useFormStatus = function () { return ReactSharedInternals.H.useHostTransitionStatus(); }; -exports.version = "19.0.0-experimental-69d4b800-20241021"; +exports.version = "19.0.0-experimental-45804af1-20241021"; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.development.js index ed67a566273dc9..7262acd7b2b543 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.development.js @@ -9295,5 +9295,5 @@ 'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToReadableStream" which supports Suspense on the server' ); }; - exports.version = "19.0.0-experimental-69d4b800-20241021"; + exports.version = "19.0.0-experimental-45804af1-20241021"; })(); diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.production.js index 95b28cfdd1ec3b..75d4290a535dc1 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.production.js @@ -6060,4 +6060,4 @@ exports.renderToString = function (children, options) { 'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToReadableStream" which supports Suspense on the server' ); }; -exports.version = "19.0.0-experimental-69d4b800-20241021"; +exports.version = "19.0.0-experimental-45804af1-20241021"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.development.js index eb35edd4612bf9..61bb3c26cdb295 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.development.js @@ -9295,5 +9295,5 @@ 'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToPipeableStream" which supports Suspense on the server' ); }; - exports.version = "19.0.0-experimental-69d4b800-20241021"; + exports.version = "19.0.0-experimental-45804af1-20241021"; })(); diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.production.js index 06d89f286cf283..55ac84877c0417 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.production.js @@ -6152,4 +6152,4 @@ exports.renderToString = function (children, options) { 'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToPipeableStream" which supports Suspense on the server' ); }; -exports.version = "19.0.0-experimental-69d4b800-20241021"; +exports.version = "19.0.0-experimental-45804af1-20241021"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.development.js index 24474748a86e62..d9d7c002717bf5 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.development.js @@ -8193,11 +8193,11 @@ } function ensureCorrectIsomorphicReactVersion() { var isomorphicReactPackageVersion = React.version; - if ("19.0.0-experimental-69d4b800-20241021" !== isomorphicReactPackageVersion) + if ("19.0.0-experimental-45804af1-20241021" !== isomorphicReactPackageVersion) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion + - "\n - react-dom: 19.0.0-experimental-69d4b800-20241021\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-experimental-45804af1-20241021\nLearn more: https://react.dev/warnings/version-mismatch") ); } var React = require("next/dist/compiled/react-experimental"), @@ -9977,5 +9977,5 @@ startWork(request); }); }; - exports.version = "19.0.0-experimental-69d4b800-20241021"; + exports.version = "19.0.0-experimental-45804af1-20241021"; })(); diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.production.js index 6c64e446421788..2c2f8b6c6bfded 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.production.js @@ -6589,12 +6589,12 @@ function getPostponedState(request) { } function ensureCorrectIsomorphicReactVersion() { var isomorphicReactPackageVersion = React.version; - if ("19.0.0-experimental-69d4b800-20241021" !== isomorphicReactPackageVersion) + if ("19.0.0-experimental-45804af1-20241021" !== isomorphicReactPackageVersion) throw Error( formatProdErrorMessage( 527, isomorphicReactPackageVersion, - "19.0.0-experimental-69d4b800-20241021" + "19.0.0-experimental-45804af1-20241021" ) ); } @@ -6849,4 +6849,4 @@ exports.resumeAndPrerender = function (children, postponedState, options) { startWork(request); }); }; -exports.version = "19.0.0-experimental-69d4b800-20241021"; +exports.version = "19.0.0-experimental-45804af1-20241021"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.bun.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.bun.production.js index 49728b4a9d0391..339edea1ffeeab 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.bun.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.bun.production.js @@ -6071,13 +6071,13 @@ function addToReplayParent(node, parentKeyPath, trackedPostpones) { } var isomorphicReactPackageVersion$jscomp$inline_779 = React.version; if ( - "19.0.0-experimental-69d4b800-20241021" !== + "19.0.0-experimental-45804af1-20241021" !== isomorphicReactPackageVersion$jscomp$inline_779 ) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion$jscomp$inline_779 + - "\n - react-dom: 19.0.0-experimental-69d4b800-20241021\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-experimental-45804af1-20241021\nLearn more: https://react.dev/warnings/version-mismatch") ); exports.renderToReadableStream = function (children, options) { return new Promise(function (resolve, reject) { @@ -6168,4 +6168,4 @@ exports.renderToReadableStream = function (children, options) { startWork(request); }); }; -exports.version = "19.0.0-experimental-69d4b800-20241021"; +exports.version = "19.0.0-experimental-45804af1-20241021"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.development.js index a8e5344ea5a6a1..348c1d046aec12 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.development.js @@ -8210,11 +8210,11 @@ } function ensureCorrectIsomorphicReactVersion() { var isomorphicReactPackageVersion = React.version; - if ("19.0.0-experimental-69d4b800-20241021" !== isomorphicReactPackageVersion) + if ("19.0.0-experimental-45804af1-20241021" !== isomorphicReactPackageVersion) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion + - "\n - react-dom: 19.0.0-experimental-69d4b800-20241021\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-experimental-45804af1-20241021\nLearn more: https://react.dev/warnings/version-mismatch") ); } var React = require("next/dist/compiled/react-experimental"), @@ -10001,5 +10001,5 @@ const setTimeoutOrImmediate = ? globalThis['set' + 'Immediate'] : setTimeout; - exports.version = "19.0.0-experimental-69d4b800-20241021"; + exports.version = "19.0.0-experimental-45804af1-20241021"; })(); diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.production.js index 97152ac336b544..61df9e40486ea0 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.production.js @@ -6691,11 +6691,11 @@ function getPostponedState(request) { } function ensureCorrectIsomorphicReactVersion() { var isomorphicReactPackageVersion = React.version; - if ("19.0.0-experimental-69d4b800-20241021" !== isomorphicReactPackageVersion) + if ("19.0.0-experimental-45804af1-20241021" !== isomorphicReactPackageVersion) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion + - "\n - react-dom: 19.0.0-experimental-69d4b800-20241021\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-experimental-45804af1-20241021\nLearn more: https://react.dev/warnings/version-mismatch") ); } ensureCorrectIsomorphicReactVersion(); @@ -6960,4 +6960,4 @@ const setTimeoutOrImmediate = ? globalThis['set' + 'Immediate'] : setTimeout; -exports.version = "19.0.0-experimental-69d4b800-20241021"; +exports.version = "19.0.0-experimental-45804af1-20241021"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.development.js index 78e600b4c21ca8..bd4deae60a5c09 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.development.js @@ -8074,11 +8074,11 @@ } function ensureCorrectIsomorphicReactVersion() { var isomorphicReactPackageVersion = React.version; - if ("19.0.0-experimental-69d4b800-20241021" !== isomorphicReactPackageVersion) + if ("19.0.0-experimental-45804af1-20241021" !== isomorphicReactPackageVersion) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion + - "\n - react-dom: 19.0.0-experimental-69d4b800-20241021\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-experimental-45804af1-20241021\nLearn more: https://react.dev/warnings/version-mismatch") ); } function createDrainHandler(destination, request) { @@ -9851,5 +9851,5 @@ } }; }; - exports.version = "19.0.0-experimental-69d4b800-20241021"; + exports.version = "19.0.0-experimental-45804af1-20241021"; })(); diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.production.js index d4d6df2f38b35a..7dbca94bb2dba5 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.production.js @@ -6570,11 +6570,11 @@ function getPostponedState(request) { } function ensureCorrectIsomorphicReactVersion() { var isomorphicReactPackageVersion = React.version; - if ("19.0.0-experimental-69d4b800-20241021" !== isomorphicReactPackageVersion) + if ("19.0.0-experimental-45804af1-20241021" !== isomorphicReactPackageVersion) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion + - "\n - react-dom: 19.0.0-experimental-69d4b800-20241021\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-experimental-45804af1-20241021\nLearn more: https://react.dev/warnings/version-mismatch") ); } ensureCorrectIsomorphicReactVersion(); @@ -6825,4 +6825,4 @@ exports.resumeToPipeableStream = function (children, postponedState, options) { } }; }; -exports.version = "19.0.0-experimental-69d4b800-20241021"; +exports.version = "19.0.0-experimental-45804af1-20241021"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.development.js index 100e5023cb4e06..6ed645c51082c7 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.development.js @@ -25246,11 +25246,11 @@ }; (function () { var isomorphicReactPackageVersion = React.version; - if ("19.0.0-experimental-69d4b800-20241021" !== isomorphicReactPackageVersion) + if ("19.0.0-experimental-45804af1-20241021" !== isomorphicReactPackageVersion) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion + - "\n - react-dom: 19.0.0-experimental-69d4b800-20241021\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-experimental-45804af1-20241021\nLearn more: https://react.dev/warnings/version-mismatch") ); })(); ("function" === typeof Map && @@ -25287,11 +25287,11 @@ !(function () { var internals = { bundleType: 1, - version: "19.0.0-experimental-69d4b800-20241021", + version: "19.0.0-experimental-45804af1-20241021", rendererPackageName: "react-dom", currentDispatcherRef: ReactSharedInternals, findFiberByHostInstance: getClosestInstanceFromNode, - reconcilerVersion: "19.0.0-experimental-69d4b800-20241021" + reconcilerVersion: "19.0.0-experimental-45804af1-20241021" }; internals.overrideHookState = overrideHookState; internals.overrideHookStateDeletePath = overrideHookStateDeletePath; @@ -25599,5 +25599,5 @@ } }; }; - exports.version = "19.0.0-experimental-69d4b800-20241021"; + exports.version = "19.0.0-experimental-45804af1-20241021"; })(); diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.production.js index b757d98fbc0f23..9069363086a947 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.production.js @@ -15462,14 +15462,14 @@ ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = function (target) { }; var isomorphicReactPackageVersion$jscomp$inline_1699 = React.version; if ( - "19.0.0-experimental-69d4b800-20241021" !== + "19.0.0-experimental-45804af1-20241021" !== isomorphicReactPackageVersion$jscomp$inline_1699 ) throw Error( formatProdErrorMessage( 527, isomorphicReactPackageVersion$jscomp$inline_1699, - "19.0.0-experimental-69d4b800-20241021" + "19.0.0-experimental-45804af1-20241021" ) ); ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { @@ -15491,11 +15491,11 @@ ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { }; var internals$jscomp$inline_2169 = { bundleType: 0, - version: "19.0.0-experimental-69d4b800-20241021", + version: "19.0.0-experimental-45804af1-20241021", rendererPackageName: "react-dom", currentDispatcherRef: ReactSharedInternals, findFiberByHostInstance: getClosestInstanceFromNode, - reconcilerVersion: "19.0.0-experimental-69d4b800-20241021" + reconcilerVersion: "19.0.0-experimental-45804af1-20241021" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_2170 = __REACT_DEVTOOLS_GLOBAL_HOOK__; @@ -15750,4 +15750,4 @@ exports.observeVisibleRects = function ( } }; }; -exports.version = "19.0.0-experimental-69d4b800-20241021"; +exports.version = "19.0.0-experimental-45804af1-20241021"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.development.js index 918a6674251ccd..92c2504af98ca2 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.development.js @@ -416,7 +416,7 @@ exports.useFormStatus = function () { return resolveDispatcher().useHostTransitionStatus(); }; - exports.version = "19.0.0-experimental-69d4b800-20241021"; + exports.version = "19.0.0-experimental-45804af1-20241021"; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.production.js index 8c4b561c342945..1636e2208d6182 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.production.js @@ -207,4 +207,4 @@ exports.useFormState = function (action, initialState, permalink) { exports.useFormStatus = function () { return ReactSharedInternals.H.useHostTransitionStatus(); }; -exports.version = "19.0.0-experimental-69d4b800-20241021"; +exports.version = "19.0.0-experimental-45804af1-20241021"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.development.js index 1bda6d495d5c73..acfb24be3740aa 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.development.js @@ -336,5 +336,5 @@ })) : Internals.d.m(href)); }; - exports.version = "19.0.0-experimental-69d4b800-20241021"; + exports.version = "19.0.0-experimental-45804af1-20241021"; })(); diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.production.js index 5953f461578f80..e2af19bbaf8ef8 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.production.js @@ -149,4 +149,4 @@ exports.preloadModule = function (href, options) { }); } else Internals.d.m(href); }; -exports.version = "19.0.0-experimental-69d4b800-20241021"; +exports.version = "19.0.0-experimental-45804af1-20241021"; diff --git a/packages/next/src/compiled/react-dom-experimental/package.json b/packages/next/src/compiled/react-dom-experimental/package.json index cdf77c883a1959..14c9adb9ab2279 100644 --- a/packages/next/src/compiled/react-dom-experimental/package.json +++ b/packages/next/src/compiled/react-dom-experimental/package.json @@ -72,10 +72,10 @@ "./package.json": "./package.json" }, "dependencies": { - "scheduler": "0.0.0-experimental-69d4b800-20241021" + "scheduler": "0.0.0-experimental-45804af1-20241021" }, "peerDependencies": { - "react": "0.0.0-experimental-69d4b800-20241021" + "react": "0.0.0-experimental-45804af1-20241021" }, "browser": { "./server.js": "./server.browser.js", diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-client.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom-client.development.js index 5c5fd9e31e844e..0e642e8f297e8b 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-client.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-client.development.js @@ -24439,11 +24439,11 @@ }; (function () { var isomorphicReactPackageVersion = React.version; - if ("19.0.0-rc-69d4b800-20241021" !== isomorphicReactPackageVersion) + if ("19.0.0-rc-45804af1-20241021" !== isomorphicReactPackageVersion) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion + - "\n - react-dom: 19.0.0-rc-69d4b800-20241021\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-rc-45804af1-20241021\nLearn more: https://react.dev/warnings/version-mismatch") ); })(); ("function" === typeof Map && @@ -24480,11 +24480,11 @@ !(function () { var internals = { bundleType: 1, - version: "19.0.0-rc-69d4b800-20241021", + version: "19.0.0-rc-45804af1-20241021", rendererPackageName: "react-dom", currentDispatcherRef: ReactSharedInternals, findFiberByHostInstance: getClosestInstanceFromNode, - reconcilerVersion: "19.0.0-rc-69d4b800-20241021" + reconcilerVersion: "19.0.0-rc-45804af1-20241021" }; internals.overrideHookState = overrideHookState; internals.overrideHookStateDeletePath = overrideHookStateDeletePath; @@ -24628,7 +24628,7 @@ listenToAllSupportedEvents(container); return new ReactDOMHydrationRoot(initialChildren); }; - exports.version = "19.0.0-rc-69d4b800-20241021"; + exports.version = "19.0.0-rc-45804af1-20241021"; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-client.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom-client.production.js index 1873757e03d7ee..b2401439104bef 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-client.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-client.production.js @@ -14971,14 +14971,14 @@ ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = function (target) { }; var isomorphicReactPackageVersion$jscomp$inline_1677 = React.version; if ( - "19.0.0-rc-69d4b800-20241021" !== + "19.0.0-rc-45804af1-20241021" !== isomorphicReactPackageVersion$jscomp$inline_1677 ) throw Error( formatProdErrorMessage( 527, isomorphicReactPackageVersion$jscomp$inline_1677, - "19.0.0-rc-69d4b800-20241021" + "19.0.0-rc-45804af1-20241021" ) ); ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { @@ -15000,11 +15000,11 @@ ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { }; var internals$jscomp$inline_2148 = { bundleType: 0, - version: "19.0.0-rc-69d4b800-20241021", + version: "19.0.0-rc-45804af1-20241021", rendererPackageName: "react-dom", currentDispatcherRef: ReactSharedInternals, findFiberByHostInstance: getClosestInstanceFromNode, - reconcilerVersion: "19.0.0-rc-69d4b800-20241021" + reconcilerVersion: "19.0.0-rc-45804af1-20241021" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_2149 = __REACT_DEVTOOLS_GLOBAL_HOOK__; @@ -15108,4 +15108,4 @@ exports.hydrateRoot = function (container, initialChildren, options) { listenToAllSupportedEvents(container); return new ReactDOMHydrationRoot(initialChildren); }; -exports.version = "19.0.0-rc-69d4b800-20241021"; +exports.version = "19.0.0-rc-45804af1-20241021"; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-profiling.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom-profiling.development.js index 28a96be7eb27a2..2afc3e9f97bd29 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-profiling.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-profiling.development.js @@ -24496,11 +24496,11 @@ }; (function () { var isomorphicReactPackageVersion = React.version; - if ("19.0.0-rc-69d4b800-20241021" !== isomorphicReactPackageVersion) + if ("19.0.0-rc-45804af1-20241021" !== isomorphicReactPackageVersion) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion + - "\n - react-dom: 19.0.0-rc-69d4b800-20241021\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-rc-45804af1-20241021\nLearn more: https://react.dev/warnings/version-mismatch") ); })(); ("function" === typeof Map && @@ -24537,11 +24537,11 @@ !(function () { var internals = { bundleType: 1, - version: "19.0.0-rc-69d4b800-20241021", + version: "19.0.0-rc-45804af1-20241021", rendererPackageName: "react-dom", currentDispatcherRef: ReactSharedInternals, findFiberByHostInstance: getClosestInstanceFromNode, - reconcilerVersion: "19.0.0-rc-69d4b800-20241021" + reconcilerVersion: "19.0.0-rc-45804af1-20241021" }; internals.overrideHookState = overrideHookState; internals.overrideHookStateDeletePath = overrideHookStateDeletePath; @@ -25015,7 +25015,7 @@ exports.useFormStatus = function () { return resolveDispatcher().useHostTransitionStatus(); }; - exports.version = "19.0.0-rc-69d4b800-20241021"; + exports.version = "19.0.0-rc-45804af1-20241021"; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-profiling.profiling.js b/packages/next/src/compiled/react-dom/cjs/react-dom-profiling.profiling.js index 131fc4fb4453d2..e8a093ccd00dfe 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-profiling.profiling.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-profiling.profiling.js @@ -15622,14 +15622,14 @@ ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = function (target) { }; var isomorphicReactPackageVersion$jscomp$inline_1768 = React.version; if ( - "19.0.0-rc-69d4b800-20241021" !== + "19.0.0-rc-45804af1-20241021" !== isomorphicReactPackageVersion$jscomp$inline_1768 ) throw Error( formatProdErrorMessage( 527, isomorphicReactPackageVersion$jscomp$inline_1768, - "19.0.0-rc-69d4b800-20241021" + "19.0.0-rc-45804af1-20241021" ) ); ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { @@ -15651,11 +15651,11 @@ ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { }; var internals$jscomp$inline_1775 = { bundleType: 0, - version: "19.0.0-rc-69d4b800-20241021", + version: "19.0.0-rc-45804af1-20241021", rendererPackageName: "react-dom", currentDispatcherRef: ReactSharedInternals, findFiberByHostInstance: getClosestInstanceFromNode, - reconcilerVersion: "19.0.0-rc-69d4b800-20241021", + reconcilerVersion: "19.0.0-rc-45804af1-20241021", getLaneLabelMap: function () { for ( var map = new Map(), lane = 1, index$275 = 0; @@ -15935,7 +15935,7 @@ exports.useFormState = function (action, initialState, permalink) { exports.useFormStatus = function () { return ReactSharedInternals.H.useHostTransitionStatus(); }; -exports.version = "19.0.0-rc-69d4b800-20241021"; +exports.version = "19.0.0-rc-45804af1-20241021"; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.development.js index f1590a5aee19b8..935a57bbe6344e 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.development.js @@ -8570,5 +8570,5 @@ 'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToReadableStream" which supports Suspense on the server' ); }; - exports.version = "19.0.0-rc-69d4b800-20241021"; + exports.version = "19.0.0-rc-45804af1-20241021"; })(); diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.production.js index 432e4dc93d78b5..25ad8d3e7ef811 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.production.js @@ -5623,4 +5623,4 @@ exports.renderToString = function (children, options) { 'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToReadableStream" which supports Suspense on the server' ); }; -exports.version = "19.0.0-rc-69d4b800-20241021"; +exports.version = "19.0.0-rc-45804af1-20241021"; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.development.js index 9308a6aa4f259c..5d90520831e850 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.development.js @@ -8570,5 +8570,5 @@ 'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToPipeableStream" which supports Suspense on the server' ); }; - exports.version = "19.0.0-rc-69d4b800-20241021"; + exports.version = "19.0.0-rc-45804af1-20241021"; })(); diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.production.js index 4a9bb5d692c124..ddc7fa36a2a031 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.production.js @@ -5701,4 +5701,4 @@ exports.renderToString = function (children, options) { 'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToPipeableStream" which supports Suspense on the server' ); }; -exports.version = "19.0.0-rc-69d4b800-20241021"; +exports.version = "19.0.0-rc-45804af1-20241021"; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.development.js index 9795a44d56aa92..8c09a0665c2e11 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.development.js @@ -7296,11 +7296,11 @@ } function ensureCorrectIsomorphicReactVersion() { var isomorphicReactPackageVersion = React.version; - if ("19.0.0-rc-69d4b800-20241021" !== isomorphicReactPackageVersion) + if ("19.0.0-rc-45804af1-20241021" !== isomorphicReactPackageVersion) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion + - "\n - react-dom: 19.0.0-rc-69d4b800-20241021\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-rc-45804af1-20241021\nLearn more: https://react.dev/warnings/version-mismatch") ); } var React = require("next/dist/compiled/react"), @@ -8952,5 +8952,5 @@ startWork(request); }); }; - exports.version = "19.0.0-rc-69d4b800-20241021"; + exports.version = "19.0.0-rc-45804af1-20241021"; })(); diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.production.js index c8abc222281de1..f1743044bc8266 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.production.js @@ -5956,12 +5956,12 @@ function abort(request, reason) { } function ensureCorrectIsomorphicReactVersion() { var isomorphicReactPackageVersion = React.version; - if ("19.0.0-rc-69d4b800-20241021" !== isomorphicReactPackageVersion) + if ("19.0.0-rc-45804af1-20241021" !== isomorphicReactPackageVersion) throw Error( formatProdErrorMessage( 527, isomorphicReactPackageVersion, - "19.0.0-rc-69d4b800-20241021" + "19.0.0-rc-45804af1-20241021" ) ); } @@ -6108,4 +6108,4 @@ exports.renderToReadableStream = function (children, options) { startWork(request); }); }; -exports.version = "19.0.0-rc-69d4b800-20241021"; +exports.version = "19.0.0-rc-45804af1-20241021"; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server.bun.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server.bun.production.js index 11ab12e0e1109a..d42d4366615293 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server.bun.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server.bun.production.js @@ -5594,13 +5594,13 @@ function abort(request, reason) { } var isomorphicReactPackageVersion$jscomp$inline_731 = React.version; if ( - "19.0.0-rc-69d4b800-20241021" !== + "19.0.0-rc-45804af1-20241021" !== isomorphicReactPackageVersion$jscomp$inline_731 ) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion$jscomp$inline_731 + - "\n - react-dom: 19.0.0-rc-69d4b800-20241021\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-rc-45804af1-20241021\nLearn more: https://react.dev/warnings/version-mismatch") ); exports.renderToReadableStream = function (children, options) { return new Promise(function (resolve, reject) { @@ -5691,4 +5691,4 @@ exports.renderToReadableStream = function (children, options) { startWork(request); }); }; -exports.version = "19.0.0-rc-69d4b800-20241021"; +exports.version = "19.0.0-rc-45804af1-20241021"; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.development.js index 9e24284fc2fe91..8586c6db2d8093 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.development.js @@ -7313,11 +7313,11 @@ } function ensureCorrectIsomorphicReactVersion() { var isomorphicReactPackageVersion = React.version; - if ("19.0.0-rc-69d4b800-20241021" !== isomorphicReactPackageVersion) + if ("19.0.0-rc-45804af1-20241021" !== isomorphicReactPackageVersion) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion + - "\n - react-dom: 19.0.0-rc-69d4b800-20241021\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-rc-45804af1-20241021\nLearn more: https://react.dev/warnings/version-mismatch") ); } var React = require("next/dist/compiled/react"), @@ -8976,5 +8976,5 @@ const setTimeoutOrImmediate = ? globalThis['set' + 'Immediate'] : setTimeout; - exports.version = "19.0.0-rc-69d4b800-20241021"; + exports.version = "19.0.0-rc-45804af1-20241021"; })(); diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.production.js index 4bdcc6477578ee..8171e86a71f0b1 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.production.js @@ -6044,11 +6044,11 @@ function abort(request, reason) { } function ensureCorrectIsomorphicReactVersion() { var isomorphicReactPackageVersion = React.version; - if ("19.0.0-rc-69d4b800-20241021" !== isomorphicReactPackageVersion) + if ("19.0.0-rc-45804af1-20241021" !== isomorphicReactPackageVersion) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion + - "\n - react-dom: 19.0.0-rc-69d4b800-20241021\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-rc-45804af1-20241021\nLearn more: https://react.dev/warnings/version-mismatch") ); } ensureCorrectIsomorphicReactVersion(); @@ -6205,4 +6205,4 @@ const setTimeoutOrImmediate = ? globalThis['set' + 'Immediate'] : setTimeout; -exports.version = "19.0.0-rc-69d4b800-20241021"; +exports.version = "19.0.0-rc-45804af1-20241021"; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server.node.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server.node.development.js index 75137559d4b4d5..8dcbcebab48dcf 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server.node.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server.node.development.js @@ -7188,11 +7188,11 @@ } function ensureCorrectIsomorphicReactVersion() { var isomorphicReactPackageVersion = React.version; - if ("19.0.0-rc-69d4b800-20241021" !== isomorphicReactPackageVersion) + if ("19.0.0-rc-45804af1-20241021" !== isomorphicReactPackageVersion) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion + - "\n - react-dom: 19.0.0-rc-69d4b800-20241021\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-rc-45804af1-20241021\nLearn more: https://react.dev/warnings/version-mismatch") ); } function createDrainHandler(destination, request) { @@ -8839,5 +8839,5 @@ } }; }; - exports.version = "19.0.0-rc-69d4b800-20241021"; + exports.version = "19.0.0-rc-45804af1-20241021"; })(); diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server.node.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server.node.production.js index 4900048acd52e2..47c384c1ab4bfb 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server.node.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server.node.production.js @@ -5936,11 +5936,11 @@ function abort(request, reason) { } function ensureCorrectIsomorphicReactVersion() { var isomorphicReactPackageVersion = React.version; - if ("19.0.0-rc-69d4b800-20241021" !== isomorphicReactPackageVersion) + if ("19.0.0-rc-45804af1-20241021" !== isomorphicReactPackageVersion) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion + - "\n - react-dom: 19.0.0-rc-69d4b800-20241021\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-rc-45804af1-20241021\nLearn more: https://react.dev/warnings/version-mismatch") ); } ensureCorrectIsomorphicReactVersion(); @@ -6089,4 +6089,4 @@ exports.renderToPipeableStream = function (children, options) { } }; }; -exports.version = "19.0.0-rc-69d4b800-20241021"; +exports.version = "19.0.0-rc-45804af1-20241021"; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom.development.js index a179f8a9f59123..9ddd3e02109223 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom.development.js @@ -416,7 +416,7 @@ exports.useFormStatus = function () { return resolveDispatcher().useHostTransitionStatus(); }; - exports.version = "19.0.0-rc-69d4b800-20241021"; + exports.version = "19.0.0-rc-45804af1-20241021"; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom.production.js index efa9b123a24704..503152a20cdc58 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom.production.js @@ -207,4 +207,4 @@ exports.useFormState = function (action, initialState, permalink) { exports.useFormStatus = function () { return ReactSharedInternals.H.useHostTransitionStatus(); }; -exports.version = "19.0.0-rc-69d4b800-20241021"; +exports.version = "19.0.0-rc-45804af1-20241021"; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom.react-server.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom.react-server.development.js index f207c0e548da36..73154d39deed84 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom.react-server.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom.react-server.development.js @@ -336,5 +336,5 @@ })) : Internals.d.m(href)); }; - exports.version = "19.0.0-rc-69d4b800-20241021"; + exports.version = "19.0.0-rc-45804af1-20241021"; })(); diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom.react-server.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom.react-server.production.js index 4c0dd03ec87721..958a320427e1d9 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom.react-server.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom.react-server.production.js @@ -149,4 +149,4 @@ exports.preloadModule = function (href, options) { }); } else Internals.d.m(href); }; -exports.version = "19.0.0-rc-69d4b800-20241021"; +exports.version = "19.0.0-rc-45804af1-20241021"; diff --git a/packages/next/src/compiled/react-dom/package.json b/packages/next/src/compiled/react-dom/package.json index 7e7de96833d7ca..029d5dd8f16468 100644 --- a/packages/next/src/compiled/react-dom/package.json +++ b/packages/next/src/compiled/react-dom/package.json @@ -67,10 +67,10 @@ "./package.json": "./package.json" }, "dependencies": { - "scheduler": "0.25.0-rc-69d4b800-20241021" + "scheduler": "0.25.0-rc-45804af1-20241021" }, "peerDependencies": { - "react": "19.0.0-rc-69d4b800-20241021" + "react": "19.0.0-rc-45804af1-20241021" }, "browser": { "./server.js": "./server.browser.js", diff --git a/packages/next/src/compiled/react-experimental/cjs/react.development.js b/packages/next/src/compiled/react-experimental/cjs/react.development.js index 2f4fb3e128d897..cf25b67396ddae 100644 --- a/packages/next/src/compiled/react-experimental/cjs/react.development.js +++ b/packages/next/src/compiled/react-experimental/cjs/react.development.js @@ -1237,7 +1237,7 @@ exports.useTransition = function () { return resolveDispatcher().useTransition(); }; - exports.version = "19.0.0-experimental-69d4b800-20241021"; + exports.version = "19.0.0-experimental-45804af1-20241021"; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && diff --git a/packages/next/src/compiled/react-experimental/cjs/react.production.js b/packages/next/src/compiled/react-experimental/cjs/react.production.js index 70763bad10bd2a..ff0dba79db48f9 100644 --- a/packages/next/src/compiled/react-experimental/cjs/react.production.js +++ b/packages/next/src/compiled/react-experimental/cjs/react.production.js @@ -567,4 +567,4 @@ exports.useSyncExternalStore = function ( exports.useTransition = function () { return ReactSharedInternals.H.useTransition(); }; -exports.version = "19.0.0-experimental-69d4b800-20241021"; +exports.version = "19.0.0-experimental-45804af1-20241021"; diff --git a/packages/next/src/compiled/react-experimental/cjs/react.react-server.development.js b/packages/next/src/compiled/react-experimental/cjs/react.react-server.development.js index 7c573a9c22d723..2807feff370688 100644 --- a/packages/next/src/compiled/react-experimental/cjs/react.react-server.development.js +++ b/packages/next/src/compiled/react-experimental/cjs/react.react-server.development.js @@ -978,5 +978,5 @@ exports.useMemo = function (create, deps) { return resolveDispatcher().useMemo(create, deps); }; - exports.version = "19.0.0-experimental-69d4b800-20241021"; + exports.version = "19.0.0-experimental-45804af1-20241021"; })(); diff --git a/packages/next/src/compiled/react-experimental/cjs/react.react-server.production.js b/packages/next/src/compiled/react-experimental/cjs/react.react-server.production.js index b970f5402fbb71..ff9410acd1c418 100644 --- a/packages/next/src/compiled/react-experimental/cjs/react.react-server.production.js +++ b/packages/next/src/compiled/react-experimental/cjs/react.react-server.production.js @@ -567,4 +567,4 @@ exports.useId = function () { exports.useMemo = function (create, deps) { return ReactSharedInternals.H.useMemo(create, deps); }; -exports.version = "19.0.0-experimental-69d4b800-20241021"; +exports.version = "19.0.0-experimental-45804af1-20241021"; diff --git a/packages/next/src/compiled/react-is/package.json b/packages/next/src/compiled/react-is/package.json index e9d5088f9a63cb..e21d636d2273b6 100644 --- a/packages/next/src/compiled/react-is/package.json +++ b/packages/next/src/compiled/react-is/package.json @@ -1,6 +1,6 @@ { "name": "react-is", - "version": "19.0.0-rc-69d4b800-20241021", + "version": "19.0.0-rc-45804af1-20241021", "description": "Brand checking of React Elements.", "main": "index.js", "sideEffects": false, diff --git a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-client.browser.development.js b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-client.browser.development.js index 33e444a137cc35..7af45efc22c4ed 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-client.browser.development.js +++ b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-client.browser.development.js @@ -2652,10 +2652,10 @@ return hook.checkDCE ? !0 : !1; })({ bundleType: 1, - version: "19.0.0-experimental-69d4b800-20241021", + version: "19.0.0-experimental-45804af1-20241021", rendererPackageName: "react-server-dom-turbopack", currentDispatcherRef: ReactSharedInternals, - reconcilerVersion: "19.0.0-experimental-69d4b800-20241021", + reconcilerVersion: "19.0.0-experimental-45804af1-20241021", getCurrentComponentInfo: function () { return currentOwnerInDEV; } diff --git a/packages/next/src/compiled/react-server-dom-turbopack-experimental/package.json b/packages/next/src/compiled/react-server-dom-turbopack-experimental/package.json index d943b08f3a8eda..0a90e7e3edf793 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack-experimental/package.json +++ b/packages/next/src/compiled/react-server-dom-turbopack-experimental/package.json @@ -48,7 +48,7 @@ "neo-async": "^2.6.1" }, "peerDependencies": { - "react": "0.0.0-experimental-69d4b800-20241021", - "react-dom": "0.0.0-experimental-69d4b800-20241021" + "react": "0.0.0-experimental-45804af1-20241021", + "react-dom": "0.0.0-experimental-45804af1-20241021" } } \ No newline at end of file diff --git a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.development.js b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.development.js index f76909fba2d7f6..e125e6252aa892 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.development.js +++ b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.development.js @@ -2448,10 +2448,10 @@ return hook.checkDCE ? !0 : !1; })({ bundleType: 1, - version: "19.0.0-rc-69d4b800-20241021", + version: "19.0.0-rc-45804af1-20241021", rendererPackageName: "react-server-dom-turbopack", currentDispatcherRef: ReactSharedInternals, - reconcilerVersion: "19.0.0-rc-69d4b800-20241021", + reconcilerVersion: "19.0.0-rc-45804af1-20241021", getCurrentComponentInfo: function () { return currentOwnerInDEV; } diff --git a/packages/next/src/compiled/react-server-dom-turbopack/package.json b/packages/next/src/compiled/react-server-dom-turbopack/package.json index 3ceed87fcfad41..d41add0b37e46b 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack/package.json +++ b/packages/next/src/compiled/react-server-dom-turbopack/package.json @@ -48,7 +48,7 @@ "neo-async": "^2.6.1" }, "peerDependencies": { - "react": "19.0.0-rc-69d4b800-20241021", - "react-dom": "19.0.0-rc-69d4b800-20241021" + "react": "19.0.0-rc-45804af1-20241021", + "react-dom": "19.0.0-rc-45804af1-20241021" } } \ No newline at end of file diff --git a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-client.browser.development.js b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-client.browser.development.js index f9f1f69023d867..89e274516b42e6 100644 --- a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-client.browser.development.js +++ b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-client.browser.development.js @@ -2667,10 +2667,10 @@ return hook.checkDCE ? !0 : !1; })({ bundleType: 1, - version: "19.0.0-experimental-69d4b800-20241021", + version: "19.0.0-experimental-45804af1-20241021", rendererPackageName: "react-server-dom-webpack", currentDispatcherRef: ReactSharedInternals, - reconcilerVersion: "19.0.0-experimental-69d4b800-20241021", + reconcilerVersion: "19.0.0-experimental-45804af1-20241021", getCurrentComponentInfo: function () { return currentOwnerInDEV; } diff --git a/packages/next/src/compiled/react-server-dom-webpack-experimental/package.json b/packages/next/src/compiled/react-server-dom-webpack-experimental/package.json index bbd8f790026412..b19976e1f830ac 100644 --- a/packages/next/src/compiled/react-server-dom-webpack-experimental/package.json +++ b/packages/next/src/compiled/react-server-dom-webpack-experimental/package.json @@ -64,8 +64,8 @@ "webpack-sources": "^3.2.0" }, "peerDependencies": { - "react": "0.0.0-experimental-69d4b800-20241021", - "react-dom": "0.0.0-experimental-69d4b800-20241021", + "react": "0.0.0-experimental-45804af1-20241021", + "react-dom": "0.0.0-experimental-45804af1-20241021", "webpack": "^5.59.0" } } \ No newline at end of file diff --git a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js index 096aa32d8fdb5a..3b19f0cbffe792 100644 --- a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js +++ b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js @@ -2463,10 +2463,10 @@ return hook.checkDCE ? !0 : !1; })({ bundleType: 1, - version: "19.0.0-rc-69d4b800-20241021", + version: "19.0.0-rc-45804af1-20241021", rendererPackageName: "react-server-dom-webpack", currentDispatcherRef: ReactSharedInternals, - reconcilerVersion: "19.0.0-rc-69d4b800-20241021", + reconcilerVersion: "19.0.0-rc-45804af1-20241021", getCurrentComponentInfo: function () { return currentOwnerInDEV; } diff --git a/packages/next/src/compiled/react-server-dom-webpack/package.json b/packages/next/src/compiled/react-server-dom-webpack/package.json index 25c5e8631da0c8..5c44356a36c3fb 100644 --- a/packages/next/src/compiled/react-server-dom-webpack/package.json +++ b/packages/next/src/compiled/react-server-dom-webpack/package.json @@ -64,8 +64,8 @@ "webpack-sources": "^3.2.0" }, "peerDependencies": { - "react": "19.0.0-rc-69d4b800-20241021", - "react-dom": "19.0.0-rc-69d4b800-20241021", + "react": "19.0.0-rc-45804af1-20241021", + "react-dom": "19.0.0-rc-45804af1-20241021", "webpack": "^5.59.0" } } \ No newline at end of file diff --git a/packages/next/src/compiled/react/cjs/react.development.js b/packages/next/src/compiled/react/cjs/react.development.js index 0001373c0b0ac3..2e40ab706e369e 100644 --- a/packages/next/src/compiled/react/cjs/react.development.js +++ b/packages/next/src/compiled/react/cjs/react.development.js @@ -1520,7 +1520,7 @@ exports.useTransition = function () { return resolveDispatcher().useTransition(); }; - exports.version = "19.0.0-rc-69d4b800-20241021"; + exports.version = "19.0.0-rc-45804af1-20241021"; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && diff --git a/packages/next/src/compiled/react/cjs/react.production.js b/packages/next/src/compiled/react/cjs/react.production.js index 79ec2bf87ae8d8..f2fe8095bb3627 100644 --- a/packages/next/src/compiled/react/cjs/react.production.js +++ b/packages/next/src/compiled/react/cjs/react.production.js @@ -536,4 +536,4 @@ exports.useSyncExternalStore = function ( exports.useTransition = function () { return ReactSharedInternals.H.useTransition(); }; -exports.version = "19.0.0-rc-69d4b800-20241021"; +exports.version = "19.0.0-rc-45804af1-20241021"; diff --git a/packages/next/src/compiled/react/cjs/react.react-server.development.js b/packages/next/src/compiled/react/cjs/react.react-server.development.js index 165b8fbbb9e923..a974cd8503fc0d 100644 --- a/packages/next/src/compiled/react/cjs/react.react-server.development.js +++ b/packages/next/src/compiled/react/cjs/react.react-server.development.js @@ -1117,5 +1117,5 @@ exports.useMemo = function (create, deps) { return resolveDispatcher().useMemo(create, deps); }; - exports.version = "19.0.0-rc-69d4b800-20241021"; + exports.version = "19.0.0-rc-45804af1-20241021"; })(); diff --git a/packages/next/src/compiled/react/cjs/react.react-server.production.js b/packages/next/src/compiled/react/cjs/react.react-server.production.js index e5035e62c5169f..a55d67063b702d 100644 --- a/packages/next/src/compiled/react/cjs/react.react-server.production.js +++ b/packages/next/src/compiled/react/cjs/react.react-server.production.js @@ -424,4 +424,4 @@ exports.useId = function () { exports.useMemo = function (create, deps) { return ReactSharedInternals.H.useMemo(create, deps); }; -exports.version = "19.0.0-rc-69d4b800-20241021"; +exports.version = "19.0.0-rc-45804af1-20241021"; diff --git a/packages/next/src/compiled/unistore/unistore.js b/packages/next/src/compiled/unistore/unistore.js index 4ab4454ee4a10b..641590aa4187cc 100644 --- a/packages/next/src/compiled/unistore/unistore.js +++ b/packages/next/src/compiled/unistore/unistore.js @@ -1 +1 @@ -(()=>{var t={37:t=>{function n(t,i){for(var _ in i)t[_]=i[_];return t}t.exports=function(t){var i=[];function u(t){for(var _=[],a=0;a{var t={19:t=>{function n(t,i){for(var _ in i)t[_]=i[_];return t}t.exports=function(t){var i=[];function u(t){for(var _=[],a=0;a=18'} peerDependencies: '@types/react': npm:types-react@19.0.0-rc.0 - react: 19.0.0-rc-69d4b800-20241021 - react-dom: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 + react-dom: 19.0.0-rc-45804af1-20241021 peerDependenciesMeta: '@types/react': optional: true @@ -10547,7 +10547,7 @@ packages: lucide-react@0.383.0: resolution: {integrity: sha512-13xlG0CQCJtzjSQYwwJ3WRqMHtRj3EXmLlorrARt7y+IHnxUCp3XyFNL1DfaGySWxHObDvnu1u1dV+0VMKHUSg==} peerDependencies: - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} @@ -12756,28 +12756,28 @@ packages: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true - react-dom@0.0.0-experimental-69d4b800-20241021: - resolution: {integrity: sha512-2i38+ABM/fPtqDozsynvT1UGMg6fdCym3QsZzdOQedtbfcuCw4vr5qzoxKiNj+KKYwBGdwLBjGkqoR33T85afQ==} + react-dom@0.0.0-experimental-45804af1-20241021: + resolution: {integrity: sha512-d8okk5fqn91Hec2nm/MC2X69i4Lu6I9k6KGnoseHdWBNadK5jJKVz3pEjnsYcXC6BbMhdX5cdaWtnszL7Gwovw==} peerDependencies: - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 react-dom@17.0.2: resolution: {integrity: sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==} peerDependencies: - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 - react-dom@19.0.0-rc-69d4b800-20241021: - resolution: {integrity: sha512-ZXBsP/kTDLI9QopUaUgYJhmmAhO8aKz7DCv2Ui2rA9boCfJ/dRRh6BlVidsyb2dPzG01rItdRFQqwbP+x9s5Rg==} + react-dom@19.0.0-rc-45804af1-20241021: + resolution: {integrity: sha512-8hOckEFO7Vxo+nH/EEddIGdencOFT0/3iJqF3mKrqv71n1xxhYcp0595JbT/DP31G8bHfDcBSMWVhIvyCGWy/A==} peerDependencies: - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 react-dom@19.0.0-rc-f90a6bcc-20240827: resolution: {integrity: sha512-oUa/reDvGtjRcxi8u+GYHaDHanudaO28+G+Wvxm50CItW1xwIFN2Nn7foJxxDS9lFLGdRWZvjxldZEPAUSuXbg==} peerDependencies: - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 - react-is@19.0.0-rc-69d4b800-20241021: - resolution: {integrity: sha512-aa07RwFePjPGNw0QEdTGYD9MFJHXUOqtKwSGZbNFZIUcsQRCXNudFvv/Ywv+Hp0KM60J4rTdF6+zew3pZAMm1g==} + react-is@19.0.0-rc-45804af1-20241021: + resolution: {integrity: sha512-mpLHD6G7cziX6n3Y3uKdm9SKp7fuHuLMwB/+mfEXCcJu721LZwEfl3vZuJMo7daxKToL8em7DUCtoS7YuZkfOA==} react-is@19.0.0-rc-f90a6bcc-20240827: resolution: {integrity: sha512-1tXoLFzVbqHAQeY3CwpyF5IYbkwgSoNHhrhS8qOrfiZIh2461h/C1BP/JVIxwyL51wHhUgLsAc/M8g0OcEhV1A==} @@ -12788,8 +12788,8 @@ packages: react-number-format@5.4.0: resolution: {integrity: sha512-NWdICrqLhI7rAS8yUeLVd6Wr4cN7UjJ9IBTS0f/a9i7UB4x4Ti70kGnksBtZ7o4Z7YRbvCMMR/jQmkoOBa/4fg==} peerDependencies: - react: 19.0.0-rc-69d4b800-20241021 - react-dom: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 + react-dom: 19.0.0-rc-45804af1-20241021 react-refresh@0.12.0: resolution: {integrity: sha512-suLIhrU2IHKL5JEKR/fAwJv7bbeq4kJ+pJopf77jHwuR+HmJS/HbrPIGsTBUVfw7tXPOmYv7UJ7PCaN49e8x4A==} @@ -12800,7 +12800,7 @@ packages: engines: {node: '>=10'} peerDependencies: '@types/react': npm:types-react@19.0.0-rc.0 - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 peerDependenciesMeta: '@types/react': optional: true @@ -12810,58 +12810,58 @@ packages: engines: {node: '>=10'} peerDependencies: '@types/react': npm:types-react@19.0.0-rc.0 - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 peerDependenciesMeta: '@types/react': optional: true - react-server-dom-turbopack@0.0.0-experimental-69d4b800-20241021: - resolution: {integrity: sha512-ccG4B3G3dv7kCXXtBzH6OviMBytlkefnC8k0YZtZofNPwzgbF/l/YyLE9HPlZ6wdoV2O0RmBH8DZ6ZzJPaJx+w==} + react-server-dom-turbopack@0.0.0-experimental-45804af1-20241021: + resolution: {integrity: sha512-lDpTsfobz4gPBytii+4//YQcqTfYWpltUnHUTXaEj/YT7Tmatxr/tzl+6mU5n9FeTsznFrnSDO+T1505fbEddA==} engines: {node: '>=0.10.0'} peerDependencies: - react: 19.0.0-rc-69d4b800-20241021 - react-dom: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 + react-dom: 19.0.0-rc-45804af1-20241021 - react-server-dom-turbopack@19.0.0-rc-69d4b800-20241021: - resolution: {integrity: sha512-PlQv2ZHt736H8KDQFGtj9G9qQ5picBIailch+5cEgi4gGoh7GudBH5cGNX80KStVOJA3O7uDgxvpXb0HInZiuA==} + react-server-dom-turbopack@19.0.0-rc-45804af1-20241021: + resolution: {integrity: sha512-FlKajxk0B7lZMO9+nxSjF8kDCgZff8jvPkMOQ8CRN6+W5DKGncyS3NAFFHE9I7L4KpRwJ3NqOwQHAmctIND23w==} engines: {node: '>=0.10.0'} peerDependencies: - react: 19.0.0-rc-69d4b800-20241021 - react-dom: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 + react-dom: 19.0.0-rc-45804af1-20241021 - react-server-dom-webpack@0.0.0-experimental-69d4b800-20241021: - resolution: {integrity: sha512-XtfBlg5FamWCN0Gw/L5beZGigawN2U0AfALAfErCxVbfr7nUNgEfFYildTo1j3eAni6FgmRGXjyyzZoA4HB0LA==} + react-server-dom-webpack@0.0.0-experimental-45804af1-20241021: + resolution: {integrity: sha512-PZgt3jBVfgvqzuL/vvRbfAuyWjKug3c6+k29MuZbEtX8y6o7HN9XZkxQvroqJ8eInfd3hP09bpySod4e13AVMg==} engines: {node: '>=0.10.0'} peerDependencies: - react: 19.0.0-rc-69d4b800-20241021 - react-dom: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 + react-dom: 19.0.0-rc-45804af1-20241021 webpack: 5.90.0 - react-server-dom-webpack@19.0.0-rc-69d4b800-20241021: - resolution: {integrity: sha512-aVFSN+fH6Qa3K5UQm0Od0JSuIBnhyutV06Mtz815X6V+Qmc1lhBbotxJTMiZECDUEHsvlLkKMSFY6HyWmWN07w==} + react-server-dom-webpack@19.0.0-rc-45804af1-20241021: + resolution: {integrity: sha512-kpJHfOOxr1l/QiY5jVuEc08bP0qL7nm+VXBbqHCu/IC21rNU4k7e9KZeEs5Z0LYPlTV6FyKz3TtLoVsdryDvKA==} engines: {node: '>=0.10.0'} peerDependencies: - react: 19.0.0-rc-69d4b800-20241021 - react-dom: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 + react-dom: 19.0.0-rc-45804af1-20241021 webpack: 5.90.0 react-shallow-renderer@16.15.0: resolution: {integrity: sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA==} peerDependencies: - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 react-ssr-prepass@1.0.8: resolution: {integrity: sha512-O0gfRA1SaK+9ITKxqfnXsej2jF+OHGP/+GxD4unROQaM/0/UczGF9fuF+wTboxaQoKdIf4FvS3h/OigWh704VA==} peerDependencies: - react: 19.0.0-rc-69d4b800-20241021 - react-is: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 + react-is: 19.0.0-rc-45804af1-20241021 react-style-singleton@2.2.1: resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} engines: {node: '>=10'} peerDependencies: '@types/react': npm:types-react@19.0.0-rc.0 - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 peerDependenciesMeta: '@types/react': optional: true @@ -12869,30 +12869,30 @@ packages: react-test-renderer@18.2.0: resolution: {integrity: sha512-JWD+aQ0lh2gvh4NM3bBM42Kx+XybOxCpgYK7F8ugAlpaTSnWsX+39Z4XkOykGZAHrjwwTZT3x3KxswVWxHPUqA==} peerDependencies: - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 react-textarea-autosize@8.5.3: resolution: {integrity: sha512-XT1024o2pqCuZSuBt9FwHlaDeNtVrtCXu0Rnz88t1jUGheCLa3PhjE1GH8Ctm2axEtvdCl5SUHYschyQ0L5QHQ==} engines: {node: '>=10'} peerDependencies: - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 react-virtualized@9.22.3: resolution: {integrity: sha512-MKovKMxWTcwPSxE1kK1HcheQTWfuCxAuBoSTf2gwyMM21NdX/PXUhnoP8Uc5dRKd+nKm8v41R36OellhdCpkrw==} peerDependencies: - react: 19.0.0-rc-69d4b800-20241021 - react-dom: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 + react-dom: 19.0.0-rc-45804af1-20241021 - react@0.0.0-experimental-69d4b800-20241021: - resolution: {integrity: sha512-XzpJaS54l6oSocqTeq7WpVJWdy9QMwDypeYlcsZtp8DutsULGzo3zj0P6PtNLpSqbnBuK+U/oAZsmyVRPWLM+g==} + react@0.0.0-experimental-45804af1-20241021: + resolution: {integrity: sha512-qb4Fk8l8Ny6B1Wj4HG4yTyVvmKUqNfySHgTHiJnBEJURMJFOYqQfEij6sZIAiCtClJlh3k5fHpxPfb/KHrMahw==} engines: {node: '>=0.10.0'} react@17.0.2: resolution: {integrity: sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==} engines: {node: '>=0.10.0'} - react@19.0.0-rc-69d4b800-20241021: - resolution: {integrity: sha512-dXki4tN+rP+4xhsm65q/QI/19VCZdu5vPcy4h6zaJt20XP8/1r/LCwrLFYuj8hElbNz5AmxW6JtRa7ej0BzZdg==} + react@19.0.0-rc-45804af1-20241021: + resolution: {integrity: sha512-RYkYXmX7Iia56DQJaNK0Ribh5uF/sDBNirtNNHNNqqa3wpIlcFOkRvPTW3RSwAXmBVnEZlKbeaMhlBT9p52lqA==} engines: {node: '>=0.10.0'} react@19.0.0-rc-f90a6bcc-20240827: @@ -13412,11 +13412,11 @@ packages: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} - scheduler@0.0.0-experimental-69d4b800-20241021: - resolution: {integrity: sha512-ktKRugwXfvd9CfJFm3LT0+MygPEsvSXqDFfCpRJEOBf+aQSt0sfo6vamsr+ucvS+HztiomYQi3nTFqKA2bdJNg==} + scheduler@0.0.0-experimental-45804af1-20241021: + resolution: {integrity: sha512-uu+2uRtipEw7t13aTsQId7wAj2/1LvxSrfYZzOp0pW0XQ94IdAXdj/5l39xF/EItjB4dhLvfTDkBHLApud4f9Q==} - scheduler@0.25.0-rc-69d4b800-20241021: - resolution: {integrity: sha512-S5AYX/YhMAN6u9AXgKYbZP4U4ZklC6R9Q7HmFSBk7d4DLiHVNxvAvlSvuM4nxFkwOk50MnpfTKQ7UWHXDOc9Eg==} + scheduler@0.25.0-rc-45804af1-20241021: + resolution: {integrity: sha512-8jyu/iy3tGFNakMMCWnKw/vsiTcapDyl0LKlZ3fUKBcBicZAkrrCC1bdqVFx0Ioxgry1SzOrCGcZLM7vtWK00A==} schema-utils@2.7.1: resolution: {integrity: sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==} @@ -13961,8 +13961,8 @@ packages: engines: {node: '>= 16'} peerDependencies: babel-plugin-styled-components: '>= 2' - react: 19.0.0-rc-69d4b800-20241021 - react-dom: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 + react-dom: 19.0.0-rc-45804af1-20241021 peerDependenciesMeta: babel-plugin-styled-components: optional: true @@ -13976,7 +13976,7 @@ packages: peerDependencies: '@babel/core': '*' babel-plugin-macros: '*' - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 peerDependenciesMeta: '@babel/core': optional: true @@ -14053,7 +14053,7 @@ packages: swr@2.2.4: resolution: {integrity: sha512-njiZ/4RiIhoOlAaLYDqwz5qH/KZXVilRLvomrx83HjzCWTfa+InyfAjv05PSFxnmLzZkNO9ZfvgoqzAaEI4sGQ==} peerDependencies: - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 symbol-observable@1.0.1: resolution: {integrity: sha512-Kb3PrPYz4HanVF1LVGuAdW6LoVgIwjUYJGzFe7NDrBLCN4lsV/5J0MFurV+ygS4bRVwrCEt2c7MQ1R2a72oJDw==} @@ -14774,7 +14774,7 @@ packages: engines: {node: '>=10'} peerDependencies: '@types/react': npm:types-react@19.0.0-rc.0 - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 peerDependenciesMeta: '@types/react': optional: true @@ -14782,13 +14782,13 @@ packages: use-composed-ref@1.3.0: resolution: {integrity: sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==} peerDependencies: - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 use-isomorphic-layout-effect@1.1.2: resolution: {integrity: sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==} peerDependencies: '@types/react': '*' - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 peerDependenciesMeta: '@types/react': optional: true @@ -14797,7 +14797,7 @@ packages: resolution: {integrity: sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==} peerDependencies: '@types/react': '*' - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 peerDependenciesMeta: '@types/react': optional: true @@ -14807,7 +14807,7 @@ packages: engines: {node: '>=10'} peerDependencies: '@types/react': npm:types-react@19.0.0-rc.0 - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 peerDependenciesMeta: '@types/react': optional: true @@ -14815,7 +14815,7 @@ packages: use-sync-external-store@1.2.0: resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} peerDependencies: - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -17471,17 +17471,17 @@ snapshots: '@emotion/memoize@0.8.1': {} - '@emotion/react@11.11.1(react@19.0.0-rc-69d4b800-20241021)(types-react@19.0.0-rc.0)': + '@emotion/react@11.11.1(react@19.0.0-rc-45804af1-20241021)(types-react@19.0.0-rc.0)': dependencies: '@babel/runtime': 7.22.5 '@emotion/babel-plugin': 11.11.0 '@emotion/cache': 11.11.0 '@emotion/serialize': 1.1.2 - '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@19.0.0-rc-69d4b800-20241021) + '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@19.0.0-rc-45804af1-20241021) '@emotion/utils': 1.2.1 '@emotion/weak-memoize': 0.3.1 hoist-non-react-statics: 3.3.2 - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 optionalDependencies: '@types/react': types-react@19.0.0-rc.0 transitivePeerDependencies: @@ -17499,9 +17499,9 @@ snapshots: '@emotion/unitless@0.8.1': {} - '@emotion/use-insertion-effect-with-fallbacks@1.0.1(react@19.0.0-rc-69d4b800-20241021)': + '@emotion/use-insertion-effect-with-fallbacks@1.0.1(react@19.0.0-rc-45804af1-20241021)': dependencies: - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 '@emotion/utils@1.2.1': {} @@ -18894,11 +18894,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@mdx-js/react@2.2.1(react@19.0.0-rc-69d4b800-20241021)': + '@mdx-js/react@2.2.1(react@19.0.0-rc-45804af1-20241021)': dependencies: '@types/mdx': 2.0.3 '@types/react': types-react@19.0.0-rc.0 - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 '@mdx-js/react@2.2.1(react@19.0.0-rc-f90a6bcc-20240827)': dependencies: @@ -19714,13 +19714,13 @@ snapshots: '@types/jest': 29.5.5 jest: 29.7.0(@types/node@20.12.3)(babel-plugin-macros@3.1.0) - '@testing-library/react@15.0.7(react-dom@19.0.0-rc-69d4b800-20241021(react@19.0.0-rc-69d4b800-20241021))(react@19.0.0-rc-69d4b800-20241021)(types-react@19.0.0-rc.0)': + '@testing-library/react@15.0.7(react-dom@19.0.0-rc-45804af1-20241021(react@19.0.0-rc-45804af1-20241021))(react@19.0.0-rc-45804af1-20241021)(types-react@19.0.0-rc.0)': dependencies: '@babel/runtime': 7.22.5 '@testing-library/dom': 10.1.0 '@types/react-dom': types-react-dom@19.0.0-rc.0 - react: 19.0.0-rc-69d4b800-20241021 - react-dom: 19.0.0-rc-69d4b800-20241021(react@19.0.0-rc-69d4b800-20241021) + react: 19.0.0-rc-45804af1-20241021 + react-dom: 19.0.0-rc-45804af1-20241021(react@19.0.0-rc-45804af1-20241021) optionalDependencies: '@types/react': types-react@19.0.0-rc.0 @@ -24818,7 +24818,7 @@ snapshots: hoist-non-react-statics@3.3.2: dependencies: - react-is: 19.0.0-rc-69d4b800-20241021 + react-is: 19.0.0-rc-45804af1-20241021 homedir-polyfill@1.0.3: dependencies: @@ -29119,25 +29119,25 @@ snapshots: '@jest/types': 24.9.0 ansi-regex: 4.1.0 ansi-styles: 3.2.1 - react-is: 19.0.0-rc-69d4b800-20241021 + react-is: 19.0.0-rc-45804af1-20241021 pretty-format@27.5.1: dependencies: ansi-regex: 5.0.1 ansi-styles: 5.2.0 - react-is: 19.0.0-rc-69d4b800-20241021 + react-is: 19.0.0-rc-45804af1-20241021 pretty-format@29.5.0: dependencies: '@jest/schemas': 29.4.3 ansi-styles: 5.2.0 - react-is: 19.0.0-rc-69d4b800-20241021 + react-is: 19.0.0-rc-45804af1-20241021 pretty-format@29.7.0: dependencies: '@jest/schemas': 29.6.3 ansi-styles: 5.2.0 - react-is: 19.0.0-rc-69d4b800-20241021 + react-is: 19.0.0-rc-45804af1-20241021 pretty-ms@7.0.0: dependencies: @@ -29194,7 +29194,7 @@ snapshots: dependencies: loose-envify: 1.4.0 object-assign: 4.1.1 - react-is: 19.0.0-rc-69d4b800-20241021 + react-is: 19.0.0-rc-45804af1-20241021 property-information@5.6.0: dependencies: @@ -29368,29 +29368,29 @@ snapshots: minimist: 1.2.8 strip-json-comments: 2.0.1 - react-dom@0.0.0-experimental-69d4b800-20241021(react@19.0.0-rc-69d4b800-20241021): + react-dom@0.0.0-experimental-45804af1-20241021(react@19.0.0-rc-45804af1-20241021): dependencies: - react: 19.0.0-rc-69d4b800-20241021 - scheduler: 0.25.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 + scheduler: 0.25.0-rc-45804af1-20241021 - react-dom@17.0.2(react@19.0.0-rc-69d4b800-20241021): + react-dom@17.0.2(react@19.0.0-rc-45804af1-20241021): dependencies: loose-envify: 1.4.0 object-assign: 4.1.1 - react: 19.0.0-rc-69d4b800-20241021 - scheduler: 0.25.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 + scheduler: 0.25.0-rc-45804af1-20241021 - react-dom@19.0.0-rc-69d4b800-20241021(react@19.0.0-rc-69d4b800-20241021): + react-dom@19.0.0-rc-45804af1-20241021(react@19.0.0-rc-45804af1-20241021): dependencies: - react: 19.0.0-rc-69d4b800-20241021 - scheduler: 0.25.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 + scheduler: 0.25.0-rc-45804af1-20241021 react-dom@19.0.0-rc-f90a6bcc-20240827(react@19.0.0-rc-f90a6bcc-20240827): dependencies: react: 19.0.0-rc-f90a6bcc-20240827 - scheduler: 0.25.0-rc-69d4b800-20241021 + scheduler: 0.25.0-rc-45804af1-20241021 - react-is@19.0.0-rc-69d4b800-20241021: {} + react-is@19.0.0-rc-45804af1-20241021: {} react-is@19.0.0-rc-f90a6bcc-20240827: {} @@ -29423,48 +29423,48 @@ snapshots: optionalDependencies: '@types/react': types-react@19.0.0-rc.0 - react-server-dom-turbopack@0.0.0-experimental-69d4b800-20241021(react-dom@19.0.0-rc-69d4b800-20241021(react@19.0.0-rc-69d4b800-20241021))(react@19.0.0-rc-69d4b800-20241021): + react-server-dom-turbopack@0.0.0-experimental-45804af1-20241021(react-dom@19.0.0-rc-45804af1-20241021(react@19.0.0-rc-45804af1-20241021))(react@19.0.0-rc-45804af1-20241021): dependencies: acorn-loose: 8.3.0 neo-async: 2.6.1 - react: 19.0.0-rc-69d4b800-20241021 - react-dom: 19.0.0-rc-69d4b800-20241021(react@19.0.0-rc-69d4b800-20241021) + react: 19.0.0-rc-45804af1-20241021 + react-dom: 19.0.0-rc-45804af1-20241021(react@19.0.0-rc-45804af1-20241021) - react-server-dom-turbopack@19.0.0-rc-69d4b800-20241021(react-dom@19.0.0-rc-69d4b800-20241021(react@19.0.0-rc-69d4b800-20241021))(react@19.0.0-rc-69d4b800-20241021): + react-server-dom-turbopack@19.0.0-rc-45804af1-20241021(react-dom@19.0.0-rc-45804af1-20241021(react@19.0.0-rc-45804af1-20241021))(react@19.0.0-rc-45804af1-20241021): dependencies: acorn-loose: 8.3.0 neo-async: 2.6.1 - react: 19.0.0-rc-69d4b800-20241021 - react-dom: 19.0.0-rc-69d4b800-20241021(react@19.0.0-rc-69d4b800-20241021) + react: 19.0.0-rc-45804af1-20241021 + react-dom: 19.0.0-rc-45804af1-20241021(react@19.0.0-rc-45804af1-20241021) - react-server-dom-webpack@0.0.0-experimental-69d4b800-20241021(react-dom@19.0.0-rc-69d4b800-20241021(react@19.0.0-rc-69d4b800-20241021))(react@19.0.0-rc-69d4b800-20241021)(webpack@5.90.0(@swc/core@1.6.13(@swc/helpers@0.5.13))): + react-server-dom-webpack@0.0.0-experimental-45804af1-20241021(react-dom@19.0.0-rc-45804af1-20241021(react@19.0.0-rc-45804af1-20241021))(react@19.0.0-rc-45804af1-20241021)(webpack@5.90.0(@swc/core@1.6.13(@swc/helpers@0.5.13))): dependencies: acorn-loose: 8.3.0 neo-async: 2.6.1 - react: 19.0.0-rc-69d4b800-20241021 - react-dom: 19.0.0-rc-69d4b800-20241021(react@19.0.0-rc-69d4b800-20241021) + react: 19.0.0-rc-45804af1-20241021 + react-dom: 19.0.0-rc-45804af1-20241021(react@19.0.0-rc-45804af1-20241021) webpack: 5.90.0(@swc/core@1.6.13(@swc/helpers@0.5.13)) webpack-sources: 3.2.3(patch_hash=jbynf5dc46ambamq3wuyho6hkq) - react-server-dom-webpack@19.0.0-rc-69d4b800-20241021(react-dom@19.0.0-rc-69d4b800-20241021(react@19.0.0-rc-69d4b800-20241021))(react@19.0.0-rc-69d4b800-20241021)(webpack@5.90.0(@swc/core@1.6.13(@swc/helpers@0.5.13))): + react-server-dom-webpack@19.0.0-rc-45804af1-20241021(react-dom@19.0.0-rc-45804af1-20241021(react@19.0.0-rc-45804af1-20241021))(react@19.0.0-rc-45804af1-20241021)(webpack@5.90.0(@swc/core@1.6.13(@swc/helpers@0.5.13))): dependencies: acorn-loose: 8.3.0 neo-async: 2.6.1 - react: 19.0.0-rc-69d4b800-20241021 - react-dom: 19.0.0-rc-69d4b800-20241021(react@19.0.0-rc-69d4b800-20241021) + react: 19.0.0-rc-45804af1-20241021 + react-dom: 19.0.0-rc-45804af1-20241021(react@19.0.0-rc-45804af1-20241021) webpack: 5.90.0(@swc/core@1.6.13(@swc/helpers@0.5.13)) webpack-sources: 3.2.3(patch_hash=jbynf5dc46ambamq3wuyho6hkq) - react-shallow-renderer@16.15.0(react@19.0.0-rc-69d4b800-20241021): + react-shallow-renderer@16.15.0(react@19.0.0-rc-45804af1-20241021): dependencies: object-assign: 4.1.1 - react: 19.0.0-rc-69d4b800-20241021 - react-is: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 + react-is: 19.0.0-rc-45804af1-20241021 - react-ssr-prepass@1.0.8(react-is@19.0.0-rc-f90a6bcc-20240827)(react@19.0.0-rc-69d4b800-20241021): + react-ssr-prepass@1.0.8(react-is@19.0.0-rc-f90a6bcc-20240827)(react@19.0.0-rc-45804af1-20241021): dependencies: object-is: 1.0.2 - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 react-is: 19.0.0-rc-f90a6bcc-20240827 react-style-singleton@2.2.1(react@19.0.0-rc-f90a6bcc-20240827)(types-react@19.0.0-rc.0): @@ -29476,12 +29476,12 @@ snapshots: optionalDependencies: '@types/react': types-react@19.0.0-rc.0 - react-test-renderer@18.2.0(react@19.0.0-rc-69d4b800-20241021): + react-test-renderer@18.2.0(react@19.0.0-rc-45804af1-20241021): dependencies: - react: 19.0.0-rc-69d4b800-20241021 - react-is: 19.0.0-rc-69d4b800-20241021 - react-shallow-renderer: 16.15.0(react@19.0.0-rc-69d4b800-20241021) - scheduler: 0.25.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 + react-is: 19.0.0-rc-45804af1-20241021 + react-shallow-renderer: 16.15.0(react@19.0.0-rc-45804af1-20241021) + scheduler: 0.25.0-rc-45804af1-20241021 react-textarea-autosize@8.5.3(react@19.0.0-rc-f90a6bcc-20240827)(types-react@19.0.0-rc.0): dependencies: @@ -29492,25 +29492,25 @@ snapshots: transitivePeerDependencies: - '@types/react' - react-virtualized@9.22.3(react-dom@19.0.0-rc-69d4b800-20241021(react@19.0.0-rc-69d4b800-20241021))(react@19.0.0-rc-69d4b800-20241021): + react-virtualized@9.22.3(react-dom@19.0.0-rc-45804af1-20241021(react@19.0.0-rc-45804af1-20241021))(react@19.0.0-rc-45804af1-20241021): dependencies: '@babel/runtime': 7.22.5 clsx: 1.1.1 dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 - react: 19.0.0-rc-69d4b800-20241021 - react-dom: 19.0.0-rc-69d4b800-20241021(react@19.0.0-rc-69d4b800-20241021) + react: 19.0.0-rc-45804af1-20241021 + react-dom: 19.0.0-rc-45804af1-20241021(react@19.0.0-rc-45804af1-20241021) react-lifecycles-compat: 3.0.4 - react@0.0.0-experimental-69d4b800-20241021: {} + react@0.0.0-experimental-45804af1-20241021: {} react@17.0.2: dependencies: loose-envify: 1.4.0 object-assign: 4.1.1 - react@19.0.0-rc-69d4b800-20241021: {} + react@19.0.0-rc-45804af1-20241021: {} react@19.0.0-rc-f90a6bcc-20240827: {} @@ -30201,9 +30201,9 @@ snapshots: dependencies: xmlchars: 2.2.0 - scheduler@0.0.0-experimental-69d4b800-20241021: {} + scheduler@0.0.0-experimental-45804af1-20241021: {} - scheduler@0.25.0-rc-69d4b800-20241021: {} + scheduler@0.25.0-rc-45804af1-20241021: {} schema-utils@2.7.1: dependencies: @@ -30810,7 +30810,7 @@ snapshots: dependencies: inline-style-parser: 0.1.1 - styled-components@6.0.0-rc.3(react-dom@19.0.0-rc-69d4b800-20241021(react@19.0.0-rc-69d4b800-20241021))(react@19.0.0-rc-69d4b800-20241021): + styled-components@6.0.0-rc.3(react-dom@19.0.0-rc-45804af1-20241021(react@19.0.0-rc-45804af1-20241021))(react@19.0.0-rc-45804af1-20241021): dependencies: '@babel/cli': 7.21.5(@babel/core@7.22.5) '@babel/core': 7.22.5 @@ -30825,8 +30825,8 @@ snapshots: '@emotion/unitless': 0.8.1 css-to-react-native: 3.2.0 postcss: 8.4.31 - react: 19.0.0-rc-69d4b800-20241021 - react-dom: 19.0.0-rc-69d4b800-20241021(react@19.0.0-rc-69d4b800-20241021) + react: 19.0.0-rc-45804af1-20241021 + react-dom: 19.0.0-rc-45804af1-20241021(react@19.0.0-rc-45804af1-20241021) shallowequal: 1.1.0 stylis: 4.2.0 tslib: 2.5.3 @@ -30838,10 +30838,10 @@ snapshots: postcss: 7.0.32 postcss-load-plugins: 2.3.0 - styled-jsx@5.1.6(@babel/core@7.22.5)(babel-plugin-macros@3.1.0)(react@19.0.0-rc-69d4b800-20241021): + styled-jsx@5.1.6(@babel/core@7.22.5)(babel-plugin-macros@3.1.0)(react@19.0.0-rc-45804af1-20241021): dependencies: client-only: 0.0.1 - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 optionalDependencies: '@babel/core': 7.22.5 babel-plugin-macros: 3.1.0 @@ -30931,11 +30931,11 @@ snapshots: picocolors: 1.0.1 stable: 0.1.8 - swr@2.2.4(react@19.0.0-rc-69d4b800-20241021): + swr@2.2.4(react@19.0.0-rc-45804af1-20241021): dependencies: client-only: 0.0.1 - react: 19.0.0-rc-69d4b800-20241021 - use-sync-external-store: 1.2.0(react@19.0.0-rc-69d4b800-20241021) + react: 19.0.0-rc-45804af1-20241021 + use-sync-external-store: 1.2.0(react@19.0.0-rc-45804af1-20241021) symbol-observable@1.0.1: {} @@ -31599,9 +31599,9 @@ snapshots: unist-util-is: 5.2.0 unist-util-visit-parents: 5.1.3 - unistore@3.4.1(react@19.0.0-rc-69d4b800-20241021): + unistore@3.4.1(react@19.0.0-rc-45804af1-20241021): optionalDependencies: - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 universal-github-app-jwt@1.1.1: dependencies: @@ -31719,9 +31719,9 @@ snapshots: optionalDependencies: '@types/react': types-react@19.0.0-rc.0 - use-sync-external-store@1.2.0(react@19.0.0-rc-69d4b800-20241021): + use-sync-external-store@1.2.0(react@19.0.0-rc-45804af1-20241021): dependencies: - react: 19.0.0-rc-69d4b800-20241021 + react: 19.0.0-rc-45804af1-20241021 util-deprecate@1.0.2: {} diff --git a/run-tests.js b/run-tests.js index fc657283a0255d..3209b2c8be1ce2 100644 --- a/run-tests.js +++ b/run-tests.js @@ -20,7 +20,7 @@ const { getTestFilter } = require('./test/get-test-filter') // Do not rename or format. sync-react script relies on this line. // prettier-ignore -const nextjsReactPeerVersion = "19.0.0-rc-69d4b800-20241021"; +const nextjsReactPeerVersion = "19.0.0-rc-45804af1-20241021"; let argv = require('yargs/yargs')(process.argv.slice(2)) .string('type') diff --git a/test/.stats-app/package.json b/test/.stats-app/package.json index b60b364b4f7f35..6529685fbb9bf2 100644 --- a/test/.stats-app/package.json +++ b/test/.stats-app/package.json @@ -4,8 +4,8 @@ "license": "MIT", "dependencies": { "next": "latest", - "react": "19.0.0-rc-69d4b800-20241021", - "react-dom": "19.0.0-rc-69d4b800-20241021" + "react": "19.0.0-rc-45804af1-20241021", + "react-dom": "19.0.0-rc-45804af1-20241021" }, "engines": { "node": ">=18.18.0" diff --git a/test/e2e/next-test/first-time-setup-js/package.json b/test/e2e/next-test/first-time-setup-js/package.json index 0cd91e60b1b0ed..3039062e94c149 100644 --- a/test/e2e/next-test/first-time-setup-js/package.json +++ b/test/e2e/next-test/first-time-setup-js/package.json @@ -8,7 +8,7 @@ }, "dependencies": { "next": "canary", - "react": "19.0.0-rc-69d4b800-20241021", - "react-dom": "19.0.0-rc-69d4b800-20241021" + "react": "19.0.0-rc-45804af1-20241021", + "react-dom": "19.0.0-rc-45804af1-20241021" } } diff --git a/test/e2e/next-test/first-time-setup-ts/package.json b/test/e2e/next-test/first-time-setup-ts/package.json index 3beeabf6a272f0..51c7ee58779367 100644 --- a/test/e2e/next-test/first-time-setup-ts/package.json +++ b/test/e2e/next-test/first-time-setup-ts/package.json @@ -8,8 +8,8 @@ }, "dependencies": { "next": "canary", - "react": "19.0.0-rc-69d4b800-20241021", - "react-dom": "19.0.0-rc-69d4b800-20241021" + "react": "19.0.0-rc-45804af1-20241021", + "react-dom": "19.0.0-rc-45804af1-20241021" }, "devDependencies": { "@types/react": "^18", diff --git a/test/lib/next-modes/base.ts b/test/lib/next-modes/base.ts index 89d55f86b6cffd..4b11cfe0d11ae8 100644 --- a/test/lib/next-modes/base.ts +++ b/test/lib/next-modes/base.ts @@ -51,7 +51,7 @@ type OmitFirstArgument = F extends ( // Do not rename or format. sync-react script relies on this line. // prettier-ignore -const nextjsReactPeerVersion = "19.0.0-rc-69d4b800-20241021"; +const nextjsReactPeerVersion = "19.0.0-rc-45804af1-20241021"; export class NextInstance { protected files: FileRef | { [filename: string]: string | FileRef } From 6fba7b2410bec40a6b66e77802bd3c82a0b3bff5 Mon Sep 17 00:00:00 2001 From: Jiwon Choi Date: Thu, 24 Oct 2024 02:10:09 +0900 Subject: [PATCH 37/44] next-upgrade: do not add `--turbopack` flag when `--turbo` exists in `next dev` (#71730) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Why? 1. When `next dev --turbo` existed, it added `--turbopack` since it was looking for existing `--turbopack` only. 2. When there's no `"dev"` script found in package.json, inform the user we weren't able to enable Turbopack for them. - https://github.com/vercel/next.js/releases/tag/v15.0.1-canary.3 ## Test Plan ### Suggest Turbopack ``` pnpm test:upgrade-fixture bin/__testfixtures__/suggest-turbopack ``` ```diff "scripts": { - "dev": "next dev" + "dev": "next dev --turbopack" }, ``` ### Change `--turbo` to `--turbopack` ``` pnpm test:upgrade-fixture bin/__testfixtures__/change-turbo-to-turbopack ``` CLI output includes: ``` ✔ Replaced "--turbo" with "--turbopack" in your dev script. ``` ```diff "scripts": { - "dev": "next dev --turbo" + "dev": "next dev --turbopack" }, ``` --- packages/next-codemod/bin/upgrade.ts | 35 ++++++++++++++++++---------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/packages/next-codemod/bin/upgrade.ts b/packages/next-codemod/bin/upgrade.ts index 973a1ff7c941bf..e8425129137e24 100644 --- a/packages/next-codemod/bin/upgrade.ts +++ b/packages/next-codemod/bin/upgrade.ts @@ -412,23 +412,34 @@ function isUsingAppDir(projectPath: string): boolean { */ async function suggestTurbopack(packageJson: any): Promise { const devScript: string = packageJson.scripts['dev'] - if (devScript?.includes('--turbopack')) return - const responseTurbopack = await prompts( - { - type: 'confirm', - name: 'enable', - message: 'Enable Turbopack for next dev?', - initial: true, - }, - { onCancel } - ) - - if (!responseTurbopack.enable) { + if (!devScript) { + console.log( + `${pc.red('⨯')} Could not find a "dev" script in your package.json.` + ) return } if (devScript.includes('next dev')) { + // covers "--turbopack" as well + if (devScript.includes('--turbo')) { + return + } + + const responseTurbopack = await prompts( + { + type: 'confirm', + name: 'enable', + message: `Enable Turbopack for ${pc.bold('next dev')}?`, + initial: true, + }, + { onCancel } + ) + + if (!responseTurbopack.enable) { + return + } + packageJson.scripts['dev'] = devScript.replace( 'next dev', 'next dev --turbopack' From 064970e0834a64f2bb1da90ee7c14c670e744818 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Wed, 23 Oct 2024 19:28:03 +0200 Subject: [PATCH 38/44] feat: stitch errors with react owner stack (#70393) --- crates/next-core/src/next_config.rs | 8 + crates/next-core/src/next_import_map.rs | 21 +- .../webpack/plugins/define-env-plugin.ts | 3 + packages/next/src/client/app-index.tsx | 17 +- .../globals/intercept-console-error.ts | 2 +- .../react-dev-overlay/app/ReactDevOverlay.tsx | 31 +-- .../app/hot-reloader-client.tsx | 22 +- .../react-dev-overlay/client-entry.tsx | 1 - .../internal/container/Errors.tsx | 11 +- .../internal/helpers/console-error.ts | 19 +- .../internal/helpers/parse-component-stack.ts | 1 + .../internal/helpers/stitched-error.ts | 42 ++++ .../internal/helpers/use-error-handler.ts | 68 +++--- packages/next/src/client/index.tsx | 3 +- .../next/src/client/on-recoverable-error.ts | 27 --- .../react-client-callbacks/app-router.ts | 96 ++++++++ .../report-global-error.ts | 8 + .../client/react-client-callbacks/shared.ts | 21 ++ .../next/src/lib/needs-experimental-react.ts | 3 +- packages/next/src/server/config-schema.ts | 1 + packages/next/src/server/config-shared.ts | 7 + .../acceptance-app/ReactRefreshLogBox.test.ts | 58 ++--- .../acceptance/ReactRefreshLogBox.test.ts | 6 +- .../app-dir/dynamic-error-trace/index.test.ts | 48 ++-- .../owner-stack/app/browser/caught/page.js | 44 ++++ .../app/browser/reject-promise/page.js | 16 ++ .../owner-stack/app/browser/uncaught/page.js | 16 ++ .../app-dir/owner-stack/app/layout.js | 7 + .../app-dir/owner-stack/app/ssr/page.js | 14 ++ .../app-dir/owner-stack/next.config.js | 10 + .../app-dir/owner-stack/owner-stack.test.ts | 222 ++++++++++++++++++ test/lib/next-test-utils.ts | 9 - 32 files changed, 661 insertions(+), 201 deletions(-) create mode 100644 packages/next/src/client/components/react-dev-overlay/internal/helpers/stitched-error.ts delete mode 100644 packages/next/src/client/on-recoverable-error.ts create mode 100644 packages/next/src/client/react-client-callbacks/app-router.ts create mode 100644 packages/next/src/client/react-client-callbacks/report-global-error.ts create mode 100644 packages/next/src/client/react-client-callbacks/shared.ts create mode 100644 test/development/app-dir/owner-stack/app/browser/caught/page.js create mode 100644 test/development/app-dir/owner-stack/app/browser/reject-promise/page.js create mode 100644 test/development/app-dir/owner-stack/app/browser/uncaught/page.js create mode 100644 test/development/app-dir/owner-stack/app/layout.js create mode 100644 test/development/app-dir/owner-stack/app/ssr/page.js create mode 100644 test/development/app-dir/owner-stack/next.config.js create mode 100644 test/development/app-dir/owner-stack/owner-stack.test.ts diff --git a/crates/next-core/src/next_config.rs b/crates/next-core/src/next_config.rs index 38b659bd860e9d..aa89641edfb31f 100644 --- a/crates/next-core/src/next_config.rs +++ b/crates/next-core/src/next_config.rs @@ -561,6 +561,7 @@ pub struct ExperimentalConfig { /// directory. ppr: Option, taint: Option, + react_owner_stack: Option, #[serde(rename = "dynamicIO")] dynamic_io: Option, proxy_timeout: Option, @@ -1148,6 +1149,13 @@ impl NextConfig { Vc::cell(self.experimental.taint.unwrap_or(false)) } + #[turbo_tasks::function] + pub async fn enable_react_owner_stack(self: Vc) -> Result> { + Ok(Vc::cell( + self.await?.experimental.react_owner_stack.unwrap_or(false), + )) + } + #[turbo_tasks::function] pub fn use_swc_css(&self) -> Vc { Vc::cell( diff --git a/crates/next-core/src/next_import_map.rs b/crates/next-core/src/next_import_map.rs index 724fc5ef5706ec..1ac0cf374ee7c6 100644 --- a/crates/next-core/src/next_import_map.rs +++ b/crates/next-core/src/next_import_map.rs @@ -116,12 +116,14 @@ pub async fn get_next_client_import_map( match ty.into_value() { ClientContextType::Pages { .. } => {} ClientContextType::App { app_dir } => { - let react_flavor = - if *next_config.enable_ppr().await? || *next_config.enable_taint().await? { - "-experimental" - } else { - "" - }; + let react_flavor = if *next_config.enable_ppr().await? + || *next_config.enable_taint().await? + || *next_config.enable_react_owner_stack().await? + { + "-experimental" + } else { + "" + }; import_map.insert_exact_alias( "react", @@ -683,7 +685,12 @@ async fn rsc_aliases( ) -> Result<()> { let ppr = *next_config.enable_ppr().await?; let taint = *next_config.enable_taint().await?; - let react_channel = if ppr || taint { "-experimental" } else { "" }; + let react_owner_stack = *next_config.enable_react_owner_stack().await?; + let react_channel = if ppr || taint || react_owner_stack { + "-experimental" + } else { + "" + }; let react_client_package = get_react_client_package(&next_config).await?; let mut alias = FxIndexMap::default(); diff --git a/packages/next/src/build/webpack/plugins/define-env-plugin.ts b/packages/next/src/build/webpack/plugins/define-env-plugin.ts index e12c205c1f28a8..20ad88f8f6f140 100644 --- a/packages/next/src/build/webpack/plugins/define-env-plugin.ts +++ b/packages/next/src/build/webpack/plugins/define-env-plugin.ts @@ -185,6 +185,9 @@ export function getDefineEnv({ ), 'process.env.__NEXT_PPR': checkIsAppPPREnabled(config.experimental.ppr), 'process.env.__NEXT_DYNAMIC_IO': !!config.experimental.dynamicIO, + 'process.env.__NEXT_REACT_OWNER_STACK': Boolean( + config.experimental.reactOwnerStack + ), 'process.env.__NEXT_AFTER': config.experimental.after ?? false, 'process.env.NEXT_DEPLOYMENT_ID': config.deploymentId || false, 'process.env.__NEXT_FETCH_CACHE_KEY_PREFIX': fetchCacheKeyPrefix ?? '', diff --git a/packages/next/src/client/app-index.tsx b/packages/next/src/client/app-index.tsx index 3c059896a6fe50..c39d36c01316a6 100644 --- a/packages/next/src/client/app-index.tsx +++ b/packages/next/src/client/app-index.tsx @@ -9,7 +9,11 @@ import React, { use } from 'react' // eslint-disable-next-line import/no-extraneous-dependencies import { createFromReadableStream } from 'react-server-dom-webpack/client' import { HeadManagerContext } from '../shared/lib/head-manager-context.shared-runtime' -import { onRecoverableError } from './on-recoverable-error' +import { onRecoverableError } from './react-client-callbacks/shared' +import { + onCaughtError, + onUncaughtError, +} from './react-client-callbacks/app-router' import { callServer } from './app-call-server' import { findSourceMapURL } from './app-find-source-map-url' import { @@ -23,6 +27,8 @@ import { MissingSlotContext } from '../shared/lib/app-router-context.shared-runt /// +const isReactOwnerStackEnabled = !!process.env.__NEXT_REACT_OWNER_STACK + const appElement: HTMLElement | Document | null = document const encoder = new TextEncoder() @@ -227,8 +233,17 @@ export function hydrate() { const rootLayoutMissingTags = window.__next_root_layout_missing_tags const hasMissingTags = !!rootLayoutMissingTags?.length + const errorCallbacks = + isReactOwnerStackEnabled && process.env.NODE_ENV !== 'production' + ? { + onCaughtError, + onUncaughtError, + } + : undefined + const options = { onRecoverableError, + ...errorCallbacks, } satisfies ReactDOMClient.RootOptions const isError = document.documentElement.id === '__next_error__' || hasMissingTags diff --git a/packages/next/src/client/components/globals/intercept-console-error.ts b/packages/next/src/client/components/globals/intercept-console-error.ts index 81aaf9fec029cc..c0d608c2524a3f 100644 --- a/packages/next/src/client/components/globals/intercept-console-error.ts +++ b/packages/next/src/client/components/globals/intercept-console-error.ts @@ -2,7 +2,7 @@ import isError from '../../../lib/is-error' import { isNextRouterError } from '../is-next-router-error' import { handleClientError } from '../react-dev-overlay/internal/helpers/use-error-handler' -const originConsoleError = window.console.error +export const originConsoleError = window.console.error // Patch console.error to collect information about hydration errors export function patchConsoleError() { diff --git a/packages/next/src/client/components/react-dev-overlay/app/ReactDevOverlay.tsx b/packages/next/src/client/components/react-dev-overlay/app/ReactDevOverlay.tsx index fd32ad6cfdd8ce..75cfeb06eb94b9 100644 --- a/packages/next/src/client/components/react-dev-overlay/app/ReactDevOverlay.tsx +++ b/packages/next/src/client/components/react-dev-overlay/app/ReactDevOverlay.tsx @@ -1,17 +1,16 @@ -import * as React from 'react' +import React from 'react' import { ACTION_UNHANDLED_ERROR, type OverlayState } from '../shared' - import { ShadowPortal } from '../internal/components/ShadowPortal' import { BuildError } from '../internal/container/BuildError' -import { Errors } from '../internal/container/Errors' -import { StaticIndicator } from '../internal/container/StaticIndicator' -import type { SupportedErrorEvent } from '../internal/container/Errors' +import { Errors, type SupportedErrorEvent } from '../internal/container/Errors' import { parseStack } from '../internal/helpers/parse-stack' +import { StaticIndicator } from '../internal/container/StaticIndicator' import { Base } from '../internal/styles/Base' import { ComponentStyles } from '../internal/styles/ComponentStyles' import { CssReset } from '../internal/styles/CssReset' import { RootLayoutMissingTagsError } from '../internal/container/root-layout-missing-tags-error' import type { Dispatcher } from './hot-reloader-client' +import { RuntimeErrorHandler } from '../internal/helpers/runtime-error-handler' interface ReactDevOverlayState { reactError: SupportedErrorEvent | null @@ -21,7 +20,6 @@ export default class ReactDevOverlay extends React.PureComponent< state: OverlayState dispatcher?: Dispatcher children: React.ReactNode - onReactError: (error: Error) => void }, ReactDevOverlayState > { @@ -29,6 +27,8 @@ export default class ReactDevOverlay extends React.PureComponent< static getDerivedStateFromError(error: Error): ReactDevOverlayState { if (!error.stack) return { reactError: null } + + RuntimeErrorHandler.hadRuntimeError = true return { reactError: { id: 0, @@ -41,10 +41,6 @@ export default class ReactDevOverlay extends React.PureComponent< } } - componentDidCatch(componentErr: Error) { - this.props.onReactError(componentErr) - } - render() { const { state, children, dispatcher } = this.props const { reactError } = this.state @@ -79,20 +75,11 @@ export default class ReactDevOverlay extends React.PureComponent< /> ) : ( <> - {reactError ? ( - - ) : hasRuntimeErrors ? ( + {hasRuntimeErrors ? ( { + const stitchedError = getReactStitchedError(reason) dispatch({ type: ACTION_UNHANDLED_REJECTION, - reason: reason, - frames: parseStack(reason.stack!), + reason: stitchedError, + frames: parseStack(stitchedError.stack || ''), }) }, [dispatch] ) - const handleOnReactError = useCallback(() => { - RuntimeErrorHandler.hadRuntimeError = true - }, []) useErrorHandler(handleOnUnhandledError, handleOnUnhandledRejection) const webSocketRef = useWebsocket(assetPrefix) @@ -674,11 +676,7 @@ export default function HotReload({ ]) return ( - + {children} ) diff --git a/packages/next/src/client/components/react-dev-overlay/client-entry.tsx b/packages/next/src/client/components/react-dev-overlay/client-entry.tsx index f737d2d5cdb27f..bb508ceaa65051 100644 --- a/packages/next/src/client/components/react-dev-overlay/client-entry.tsx +++ b/packages/next/src/client/components/react-dev-overlay/client-entry.tsx @@ -42,7 +42,6 @@ export function createDevOverlayElement(reactEl: React.ReactElement) { {}} > {reactEl} diff --git a/packages/next/src/client/components/react-dev-overlay/internal/container/Errors.tsx b/packages/next/src/client/components/react-dev-overlay/internal/container/Errors.tsx index d158813ec21706..74abe30891589a 100644 --- a/packages/next/src/client/components/react-dev-overlay/internal/container/Errors.tsx +++ b/packages/next/src/client/components/react-dev-overlay/internal/container/Errors.tsx @@ -31,7 +31,7 @@ import { } from '../helpers/hydration-error-info' import { NodejsInspectorCopyButton } from '../components/nodejs-inspector' import { CopyButton } from '../components/copy-button' -import { ConsoleError } from '../helpers/console-error' +import { isUnhandledConsoleOrRejection } from '../helpers/console-error' export type SupportedErrorEvent = { id: number @@ -61,11 +61,11 @@ function ErrorDescription({ error: Error hydrationWarning: string | null }) { - const isFromConsoleError = error instanceof ConsoleError + const isUnhandledError = isUnhandledConsoleOrRejection(error) // If there's hydration warning or console error, skip displaying the error name return ( <> - {isFromConsoleError || hydrationWarning ? '' : error.name + ': '} + {isUnhandledError || hydrationWarning ? '' : error.name + ': '} {isServerError ? 'Server Error' - : isFromConsoleError + : isUnhandledError ? 'Console Error' : 'Unhandled Runtime Error'}

    diff --git a/packages/next/src/client/components/react-dev-overlay/internal/helpers/console-error.ts b/packages/next/src/client/components/react-dev-overlay/internal/helpers/console-error.ts index 0c516532b591ac..c3f35a8fcecc77 100644 --- a/packages/next/src/client/components/react-dev-overlay/internal/helpers/console-error.ts +++ b/packages/next/src/client/components/react-dev-overlay/internal/helpers/console-error.ts @@ -1,6 +1,15 @@ -export class ConsoleError extends Error { - constructor(message: string) { - super(message) - this.name = 'ConsoleError' - } +// Represent non Error shape unhandled promise rejections or console.error errors. +// Those errors will be captured and displayed in Error Overlay. +type UnhandledError = Error & { digest: 'NEXT_UNHANDLED_ERROR' } + +export function createUnhandledError(message: string): UnhandledError { + const error = new Error(message) as UnhandledError + error.digest = 'NEXT_UNHANDLED_ERROR' + return error +} + +export const isUnhandledConsoleOrRejection = ( + error: any +): error is UnhandledError => { + return error && error.digest === 'NEXT_UNHANDLED_ERROR' } diff --git a/packages/next/src/client/components/react-dev-overlay/internal/helpers/parse-component-stack.ts b/packages/next/src/client/components/react-dev-overlay/internal/helpers/parse-component-stack.ts index b671fe48902bca..7d674c8f146a69 100644 --- a/packages/next/src/client/components/react-dev-overlay/internal/helpers/parse-component-stack.ts +++ b/packages/next/src/client/components/react-dev-overlay/internal/helpers/parse-component-stack.ts @@ -72,6 +72,7 @@ export function parseComponentStack( ): ComponentStackFrame[] { const componentStackFrames: ComponentStackFrame[] = [] for (const line of componentStack.trim().split('\n')) { + // TODO: support safari stack trace // Get component and file from the component stack line const match = /at ([^ ]+)( \((.*)\))?/.exec(line) if (match?.[1]) { diff --git a/packages/next/src/client/components/react-dev-overlay/internal/helpers/stitched-error.ts b/packages/next/src/client/components/react-dev-overlay/internal/helpers/stitched-error.ts new file mode 100644 index 00000000000000..d52677cce20974 --- /dev/null +++ b/packages/next/src/client/components/react-dev-overlay/internal/helpers/stitched-error.ts @@ -0,0 +1,42 @@ +import React from 'react' +import isError from '../../../../../lib/is-error' + +const captureOwnerStack = (React as any).captureOwnerStack || (() => '') + +const REACT_ERROR_STACK_BOTTOM_FRAME = 'react-stack-bottom-frame' +const REACT_ERROR_STACK_BOTTOM_FRAME_REGEX = new RegExp( + `(at ${REACT_ERROR_STACK_BOTTOM_FRAME} )|(${REACT_ERROR_STACK_BOTTOM_FRAME}\\@)` +) + +export function getReactStitchedError(err: T): Error | T { + if (!process.env.__NEXT_REACT_OWNER_STACK) { + return err + } + + const isErrorInstance = isError(err) + const originStack = isErrorInstance ? err.stack || '' : '' + const originMessage = isErrorInstance ? err.message : '' + const stackLines = originStack.split('\n') + const indexOfSplit = stackLines.findIndex((line) => + REACT_ERROR_STACK_BOTTOM_FRAME_REGEX.test(line) + ) + const isOriginalReactError = indexOfSplit >= 0 // has the react-stack-bottom-frame + let newStack = isOriginalReactError + ? stackLines.slice(0, indexOfSplit).join('\n') + : originStack + + const newError = new Error(originMessage) + // Copy all enumerable properties, e.g. digest + Object.assign(newError, err) + newError.stack = newStack + + // Avoid duplicate overriding stack frames + const ownerStack = captureOwnerStack() + if (ownerStack && newStack.endsWith(ownerStack) === false) { + newStack += ownerStack + // Override stack + newError.stack = newStack + } + + return newError +} diff --git a/packages/next/src/client/components/react-dev-overlay/internal/helpers/use-error-handler.ts b/packages/next/src/client/components/react-dev-overlay/internal/helpers/use-error-handler.ts index 13ffcfbcaa0995..71e8d29dfcedc0 100644 --- a/packages/next/src/client/components/react-dev-overlay/internal/helpers/use-error-handler.ts +++ b/packages/next/src/client/components/react-dev-overlay/internal/helpers/use-error-handler.ts @@ -4,7 +4,7 @@ import { isNextRouterError } from '../../../is-next-router-error' import { storeHydrationErrorStateFromConsoleArgs } from './hydration-error-info' import { formatConsoleArgs } from '../../../../lib/console' import isError from '../../../../../lib/is-error' -import { ConsoleError } from './console-error' +import { createUnhandledError } from './console-error' import { enqueueConsecutiveDedupedError } from './enqueue-client-error' export type ErrorHandler = (error: Error) => void @@ -22,7 +22,7 @@ export function handleClientError( if (!originError || !isError(originError)) { // If it's not an error, format the args into an error const formattedErrorMessage = formatConsoleArgs(consoleErrorArgs) - error = new ConsoleError(formattedErrorMessage) + error = createUnhandledError(formattedErrorMessage) } else { error = originError } @@ -60,6 +60,32 @@ export function useErrorHandler( }, [handleOnUnhandledError, handleOnUnhandledRejection]) } +function onUnhandledError(event: WindowEventMap['error']): void | boolean { + if (isNextRouterError(event.error)) { + event.preventDefault() + return false + } + handleClientError(event.error, []) +} + +function onUnhandledRejection(ev: WindowEventMap['unhandledrejection']): void { + const reason = ev?.reason + if (isNextRouterError(reason)) { + ev.preventDefault() + return + } + + let error = reason + if (error && !isError(error)) { + error = createUnhandledError(error + '') + } + + rejectionQueue.push(error) + for (const handler of rejectionHandlers) { + handler(error) + } +} + export function handleGlobalErrors() { if (typeof window !== 'undefined') { try { @@ -67,41 +93,7 @@ export function handleGlobalErrors() { Error.stackTraceLimit = 50 } catch {} - window.addEventListener( - 'error', - (event: WindowEventMap['error']): void | boolean => { - if (isNextRouterError(event.error)) { - event.preventDefault() - return false - } - handleClientError(event.error, []) - } - ) - - window.addEventListener( - 'unhandledrejection', - (ev: WindowEventMap['unhandledrejection']): void => { - const reason = ev?.reason - if (isNextRouterError(reason)) { - ev.preventDefault() - return - } - - if ( - !reason || - !(reason instanceof Error) || - typeof reason.stack !== 'string' - ) { - // A non-error was thrown, we don't have anything to show. :-( - return - } - - const e = reason - rejectionQueue.push(e) - for (const handler of rejectionHandlers) { - handler(e) - } - } - ) + window.addEventListener('error', onUnhandledError) + window.addEventListener('unhandledrejection', onUnhandledRejection) } } diff --git a/packages/next/src/client/index.tsx b/packages/next/src/client/index.tsx index 405b5c936f134d..b6ad90c2faeafe 100644 --- a/packages/next/src/client/index.tsx +++ b/packages/next/src/client/index.tsx @@ -1,7 +1,6 @@ /* global location */ // imports polyfill from `@next/polyfill-module` after build. import '../build/polyfills/polyfill-module' - import type Router from '../shared/lib/router/router' import type { AppComponent, @@ -46,7 +45,7 @@ import { SearchParamsContext, PathParamsContext, } from '../shared/lib/hooks-client-context.shared-runtime' -import { onRecoverableError } from './on-recoverable-error' +import { onRecoverableError } from './react-client-callbacks/shared' import tracer from './tracing/tracer' import reportToSocket from './tracing/report-to-socket' diff --git a/packages/next/src/client/on-recoverable-error.ts b/packages/next/src/client/on-recoverable-error.ts deleted file mode 100644 index c2273e0fe01dae..00000000000000 --- a/packages/next/src/client/on-recoverable-error.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { isBailoutToCSRError } from '../shared/lib/lazy-dynamic/bailout-to-csr' - -// x-ref: https://github.com/facebook/react/blob/d4bc16a7d69eb2ea38a88c8ac0b461d5f72cdcab/packages/react-dom/src/client/ReactDOMRoot.js#L83 -const defaultOnRecoverableError = - typeof reportError === 'function' - ? // In modern browsers, reportError will dispatch an error event, - // emulating an uncaught JavaScript error. - reportError - : (error: any) => { - window.console.error(error) - } - -export function onRecoverableError( - err: unknown, - errorInfo: { componentStack?: string } -) { - // In development mode, pass along the component stack to the error - if (process.env.NODE_ENV === 'development' && errorInfo.componentStack) { - ;(err as any)._componentStack = errorInfo.componentStack - } - // Using default react onRecoverableError - - // Skip certain custom errors which are not expected to be reported on client - if (isBailoutToCSRError(err)) return - - defaultOnRecoverableError(err) -} diff --git a/packages/next/src/client/react-client-callbacks/app-router.ts b/packages/next/src/client/react-client-callbacks/app-router.ts new file mode 100644 index 00000000000000..cb7a27de9a314b --- /dev/null +++ b/packages/next/src/client/react-client-callbacks/app-router.ts @@ -0,0 +1,96 @@ +// This file is only used in app router due to the specific error state handling. + +import type { HydrationOptions } from 'react-dom/client' +import { getReactStitchedError } from '../components/react-dev-overlay/internal/helpers/stitched-error' +import { handleClientError } from '../components/react-dev-overlay/internal/helpers/use-error-handler' +import { isNextRouterError } from '../components/is-next-router-error' +import { isBailoutToCSRError } from '../../shared/lib/lazy-dynamic/bailout-to-csr' +import { reportGlobalError } from './report-global-error' +import isError from '../../lib/is-error' +import { originConsoleError } from '../components/globals/intercept-console-error' + +export const onCaughtError: HydrationOptions['onCaughtError'] = ( + err, + errorInfo +) => { + // Skip certain custom errors which are not expected to be reported on client + if (isBailoutToCSRError(err) || isNextRouterError(err)) return + + const stitchedError = getReactStitchedError(err) + + if (process.env.NODE_ENV === 'development') { + const errorBoundaryComponent = errorInfo?.errorBoundary?.constructor + const errorBoundaryName = + // read react component displayName + (errorBoundaryComponent as any)?.displayName || + errorBoundaryComponent?.name || + 'Unknown' + + const componentThatErroredFrame = errorInfo?.componentStack?.split('\n')[1] + + // Match chrome or safari stack trace + const matches = + // regex to match the function name in the stack trace + // example 1: at Page (http://localhost:3000/_next/static/chunks/pages/index.js?ts=1631600000000:2:1) + // example 2: Page@http://localhost:3000/_next/static/chunks/pages/index.js?ts=1631600000000:2:1 + componentThatErroredFrame?.match(/\s+at (\w+)\s+|(\w+)@/) ?? [] + const componentThatErroredName = matches[1] || matches[2] || 'Unknown' + + // In development mode, pass along the component stack to the error + if (process.env.NODE_ENV === 'development' && errorInfo.componentStack) { + ;(stitchedError as any)._componentStack = errorInfo.componentStack + } + + // Create error location with errored component and error boundary, to match the behavior of default React onCaughtError handler. + const errorBoundaryMessage = `It was handled by the <${errorBoundaryName}> error boundary.` + const componentErrorMessage = componentThatErroredName + ? `The above error occurred in the <${componentThatErroredName}> component.` + : `The above error occurred in one of your components.` + + const errorLocation = `${componentErrorMessage} ${errorBoundaryMessage}` + + const originErrorStack = isError(err) ? err.stack || '' : '' + + // Log the modified error message with stack so without being intercepted again. + originConsoleError(originErrorStack + '\n\n' + errorLocation) + handleClientError(stitchedError, []) + } else { + originConsoleError(err) + } +} + +export const onUncaughtError: HydrationOptions['onUncaughtError'] = ( + err, + errorInfo +) => { + // Skip certain custom errors which are not expected to be reported on client + if (isBailoutToCSRError(err) || isNextRouterError(err)) return + + const stitchedError = getReactStitchedError(err) + + if (process.env.NODE_ENV === 'development') { + const componentThatErroredFrame = errorInfo?.componentStack?.split('\n')[1] + + // Match chrome or safari stack trace + const matches = + componentThatErroredFrame?.match(/\s+at (\w+)\s+|(\w+)@/) ?? [] + const componentThatErroredName = matches[1] || matches[2] || 'Unknown' + + // In development mode, pass along the component stack to the error + if (process.env.NODE_ENV === 'development' && errorInfo.componentStack) { + ;(stitchedError as any)._componentStack = errorInfo.componentStack + } + + // Create error location with errored component and error boundary, to match the behavior of default React onCaughtError handler. + const errorLocation = componentThatErroredName + ? `The above error occurred in the <${componentThatErroredName}> component.` + : `The above error occurred in one of your components.` + + const errStack = (stitchedError as any).stack || '' + // Log the modified error message with stack so without being intercepted again. + originConsoleError(errStack + '\n\n' + errorLocation) + reportGlobalError(stitchedError) + } else { + reportGlobalError(err) + } +} diff --git a/packages/next/src/client/react-client-callbacks/report-global-error.ts b/packages/next/src/client/react-client-callbacks/report-global-error.ts new file mode 100644 index 00000000000000..719640b79f0c87 --- /dev/null +++ b/packages/next/src/client/react-client-callbacks/report-global-error.ts @@ -0,0 +1,8 @@ +export const reportGlobalError = + typeof reportError === 'function' + ? // In modern browsers, reportError will dispatch an error event, + // emulating an uncaught JavaScript error. + reportError + : (error: unknown) => { + window.console.error(error) + } diff --git a/packages/next/src/client/react-client-callbacks/shared.ts b/packages/next/src/client/react-client-callbacks/shared.ts new file mode 100644 index 00000000000000..645e4b473332ee --- /dev/null +++ b/packages/next/src/client/react-client-callbacks/shared.ts @@ -0,0 +1,21 @@ +// This module can be shared between both pages router and app router + +import type { HydrationOptions } from 'react-dom/client' +import { isBailoutToCSRError } from '../../shared/lib/lazy-dynamic/bailout-to-csr' +import { reportGlobalError } from './report-global-error' +import { getReactStitchedError } from '../components/react-dev-overlay/internal/helpers/stitched-error' + +export const onRecoverableError: HydrationOptions['onRecoverableError'] = ( + err, + errorInfo +) => { + const stitchedError = getReactStitchedError(err) + // In development mode, pass along the component stack to the error + if (process.env.NODE_ENV === 'development' && errorInfo.componentStack) { + ;(stitchedError as any)._componentStack = errorInfo.componentStack + } + // Skip certain custom errors which are not expected to be reported on client + if (isBailoutToCSRError(err)) return + + reportGlobalError(stitchedError) +} diff --git a/packages/next/src/lib/needs-experimental-react.ts b/packages/next/src/lib/needs-experimental-react.ts index 373d4d61b146ec..7e617aa7780449 100644 --- a/packages/next/src/lib/needs-experimental-react.ts +++ b/packages/next/src/lib/needs-experimental-react.ts @@ -1,5 +1,6 @@ import type { NextConfig } from '../server/config-shared' export function needsExperimentalReact(config: NextConfig) { - return Boolean(config.experimental?.ppr || config.experimental?.taint) + const { ppr, taint, reactOwnerStack } = config.experimental || {} + return Boolean(ppr || taint || reactOwnerStack) } diff --git a/packages/next/src/server/config-schema.ts b/packages/next/src/server/config-schema.ts index 8cc21968441dcc..c4c38ed3f98746 100644 --- a/packages/next/src/server/config-schema.ts +++ b/packages/next/src/server/config-schema.ts @@ -333,6 +333,7 @@ export const configSchema: zod.ZodType = z.lazy(() => .readonly() .optional(), taint: z.boolean().optional(), + reactOwnerStack: z.boolean().optional(), prerenderEarlyExit: z.boolean().optional(), proxyTimeout: z.number().gte(0).optional(), scrollRestoration: z.boolean().optional(), diff --git a/packages/next/src/server/config-shared.ts b/packages/next/src/server/config-shared.ts index 13a0daec70e24f..72336f8502d012 100644 --- a/packages/next/src/server/config-shared.ts +++ b/packages/next/src/server/config-shared.ts @@ -462,6 +462,12 @@ export interface ExperimentalConfig { */ taint?: boolean + /** + * Enables leveraging experimental captureOwnerStack API in React, + * to create a better stack trace for React errors. + */ + reactOwnerStack?: boolean + serverActions?: { /** * Allows adjusting body parser size limit for server actions. @@ -1141,6 +1147,7 @@ export const defaultConfig: NextConfig = { process.env.__NEXT_TEST_MODE && process.env.__NEXT_EXPERIMENTAL_PPR === 'true' ), + reactOwnerStack: false, webpackBuildWorker: undefined, webpackMemoryOptimizations: false, optimizeServerReact: true, diff --git a/test/development/acceptance-app/ReactRefreshLogBox.test.ts b/test/development/acceptance-app/ReactRefreshLogBox.test.ts index 9ba28b42a91a25..a15c58df37be36 100644 --- a/test/development/acceptance-app/ReactRefreshLogBox.test.ts +++ b/test/development/acceptance-app/ReactRefreshLogBox.test.ts @@ -4,7 +4,6 @@ import { FileRef, nextTestSetup } from 'e2e-utils' import { check, describeVariants as describe, - expandCallStack, getRedboxCallStackCollapsed, retry, } from 'next-test-utils' @@ -777,7 +776,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => { await cleanup() }) - test('Call stack count for client error', async () => { + test('Call stack for client error', async () => { const { session, browser, cleanup } = await sandbox( next, new Map([ @@ -796,25 +795,30 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => { ]) ) - await session.assertHasRedbox() - - await expandCallStack(browser) - - // Expect more than the default amount of frames - // The default stackTraceLimit results in max 9 [data-nextjs-call-stack-frame] elements - const callStackFrames = await browser.elementsByCss( - '[data-nextjs-call-stack-frame]' - ) + try { + await session.assertHasRedbox() - expect(callStackFrames.length).toBeGreaterThan(9) + // Should still show the errored line in source code + const source = await session.getRedboxSource() + expect(source).toContain('app/page.js') + expect(source).toContain(`throw new Error('Client error')`) - const moduleGroup = await browser.elementsByCss( - '[data-nextjs-collapsed-call-stack-details]' - ) - // Expect some of the call stack frames to be grouped (by React or Next.js) - expect(moduleGroup.length).toBeGreaterThan(0) + await expect( + browser.hasElementByCssSelector( + '[data-nextjs-data-runtime-error-collapsed-action]' + ) + ).resolves.toEqual(false) - await cleanup() + const stackFrameElements = await browser.elementsByCss( + '[data-nextjs-call-stack-frame]' + ) + const stackFrames = ( + await Promise.all(stackFrameElements.map((f) => f.innerText())) + ).filter(Boolean) + expect(stackFrames).toEqual([]) + } finally { + await cleanup() + } }) test('Call stack for server error', async () => { @@ -849,20 +853,10 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => { const stackFrameElements = await browser.elementsByCss( '[data-nextjs-call-stack-frame]' ) - const stackFrames = await Promise.all( - stackFrameElements.map((f) => f.innerText()) - ) - expect(stackFrames).toEqual( - // TODO: Show useful stack - [ - // Internal frames of React. - // Feel free to adjust until we show useful stacks. - '', - '', - '', - '', - ] - ) + const stackFrames = ( + await Promise.all(stackFrameElements.map((f) => f.innerText())) + ).filter(Boolean) + expect(stackFrames).toEqual([]) } finally { await cleanup() } diff --git a/test/development/acceptance/ReactRefreshLogBox.test.ts b/test/development/acceptance/ReactRefreshLogBox.test.ts index e4c31236795614..ce0a5ed73b524f 100644 --- a/test/development/acceptance/ReactRefreshLogBox.test.ts +++ b/test/development/acceptance/ReactRefreshLogBox.test.ts @@ -1,7 +1,7 @@ /* eslint-env jest */ import { sandbox } from 'development-sandbox' import { FileRef, nextTestSetup } from 'e2e-utils' -import { describeVariants as describe, expandCallStack } from 'next-test-utils' +import { describeVariants as describe } from 'next-test-utils' import path from 'path' import { outdent } from 'outdent' @@ -765,8 +765,6 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => { await session.assertHasRedbox() - await expandCallStack(browser) - // Expect more than the default amount of frames // The default stackTraceLimit results in max 9 [data-nextjs-call-stack-frame] elements const callStackFrames = await browser.elementsByCss( @@ -805,7 +803,6 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => { ]) ) await session.assertHasRedbox() - await expandCallStack(browser) let callStackFrames = await browser.elementsByCss( '[data-nextjs-call-stack-frame]' ) @@ -835,7 +832,6 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => { ]) ) await session.assertHasRedbox() - await expandCallStack(browser) // Should still show the errored line in source code const source = await session.getRedboxSource() diff --git a/test/development/app-dir/dynamic-error-trace/index.test.ts b/test/development/app-dir/dynamic-error-trace/index.test.ts index 7ee4c25f8fc3d7..7208f5dcc521fe 100644 --- a/test/development/app-dir/dynamic-error-trace/index.test.ts +++ b/test/development/app-dir/dynamic-error-trace/index.test.ts @@ -1,27 +1,16 @@ import { nextTestSetup } from 'e2e-utils' -import { - assertHasRedbox, - shouldRunTurboDevTest, - getRedboxSource, -} from 'next-test-utils' +import { assertHasRedbox, getRedboxSource } from 'next-test-utils' import { outdent } from 'outdent' +const isReactExperimental = process.env.__NEXT_EXPERIMENTAL_PPR === 'true' + +function normalizeStackTrace(trace) { + return trace.replace(/ \(.*\)/g, '') +} + describe('app dir - dynamic error trace', () => { const { next, skipped } = nextTestSetup({ files: __dirname, - dependencies: { - swr: 'latest', - }, - packageJson: { - scripts: { - build: 'next build', - dev: `next ${shouldRunTurboDevTest() ? 'dev --turbo' : 'dev'}`, - start: 'next start', - }, - }, - installCommand: 'pnpm install', - startCommand: (global as any).isNextDev ? 'pnpm dev' : 'pnpm start', - buildCommand: 'pnpm build', skipDeployment: true, }) if (skipped) return @@ -40,20 +29,15 @@ describe('app dir - dynamic error trace', () => { const stackFrameElements = await browser.elementsByCss( '[data-nextjs-call-stack-frame]' ) - const stackFrames = await Promise.all( - // TODO: Why is this text empty? - stackFrameElements.map((f) => f.innerText()) - ) - expect(stackFrames).toEqual( - // TODO: Show useful stack - [ - // Internal frames of React. - // Feel free to adjust until we show useful stacks. - '', - '', - '', - '', - ] + const stackFramesContent = // TODO: Why is this text empty? + (await Promise.all(stackFrameElements.map((f) => f.innerText()))) + // Filter out the frames having code snippet but without methodName and source + .filter(Boolean) + .join('\n') + + // TODO: Show useful stack + expect(normalizeStackTrace(stackFramesContent)).toMatchInlineSnapshot( + isReactExperimental ? `""` : `""` ) const codeframe = await getRedboxSource(browser) diff --git a/test/development/app-dir/owner-stack/app/browser/caught/page.js b/test/development/app-dir/owner-stack/app/browser/caught/page.js new file mode 100644 index 00000000000000..4d1f6fea4c41f3 --- /dev/null +++ b/test/development/app-dir/owner-stack/app/browser/caught/page.js @@ -0,0 +1,44 @@ +'use client' + +import { Component } from 'react' + +class MyErrorBoundary extends Component { + static getDerivedStateFromError(error) { + return { error } + } + + state = { error: null } + + render() { + if (this.state.error) { + return 'failed' + } + return this.props.children + } +} + +function Inner() { + return ( + + + + ) +} + +function Thrower() { + useErrorHook() +} + +function useThrowError() { + if (typeof window !== 'undefined') { + throw new Error('browser error') + } +} + +function useErrorHook() { + useThrowError() +} + +export default function Page() { + return +} diff --git a/test/development/app-dir/owner-stack/app/browser/reject-promise/page.js b/test/development/app-dir/owner-stack/app/browser/reject-promise/page.js new file mode 100644 index 00000000000000..04da000b806b11 --- /dev/null +++ b/test/development/app-dir/owner-stack/app/browser/reject-promise/page.js @@ -0,0 +1,16 @@ +'use client' + +function useThrowError() { + if (typeof window !== 'undefined') { + Promise.reject('string in rejected promise') + } +} + +function useErrorHook() { + useThrowError() +} + +export default function Page() { + useErrorHook() + return

    hello world

    +} diff --git a/test/development/app-dir/owner-stack/app/browser/uncaught/page.js b/test/development/app-dir/owner-stack/app/browser/uncaught/page.js new file mode 100644 index 00000000000000..68fd414429de6f --- /dev/null +++ b/test/development/app-dir/owner-stack/app/browser/uncaught/page.js @@ -0,0 +1,16 @@ +'use client' + +function useThrowError() { + if (typeof window !== 'undefined') { + throw new Error('browser error') + } +} + +function useErrorHook() { + useThrowError() +} + +export default function Page() { + useErrorHook() + return

    hello world

    +} diff --git a/test/development/app-dir/owner-stack/app/layout.js b/test/development/app-dir/owner-stack/app/layout.js new file mode 100644 index 00000000000000..a3a86a5ca1e12c --- /dev/null +++ b/test/development/app-dir/owner-stack/app/layout.js @@ -0,0 +1,7 @@ +export default function Root({ children }) { + return ( + + {children} + + ) +} diff --git a/test/development/app-dir/owner-stack/app/ssr/page.js b/test/development/app-dir/owner-stack/app/ssr/page.js new file mode 100644 index 00000000000000..73a83f860b7cc3 --- /dev/null +++ b/test/development/app-dir/owner-stack/app/ssr/page.js @@ -0,0 +1,14 @@ +'use client' + +function useThrowError() { + throw new Error('ssr error') +} + +function useErrorHook() { + useThrowError() +} + +export default function Page() { + useErrorHook() + return

    hello world

    +} diff --git a/test/development/app-dir/owner-stack/next.config.js b/test/development/app-dir/owner-stack/next.config.js new file mode 100644 index 00000000000000..d14b1bf8fdc37b --- /dev/null +++ b/test/development/app-dir/owner-stack/next.config.js @@ -0,0 +1,10 @@ +/** + * @type {import('next').NextConfig} + */ +const nextConfig = { + experimental: { + reactOwnerStack: true, + }, +} + +module.exports = nextConfig diff --git a/test/development/app-dir/owner-stack/owner-stack.test.ts b/test/development/app-dir/owner-stack/owner-stack.test.ts new file mode 100644 index 00000000000000..4c68745ace6520 --- /dev/null +++ b/test/development/app-dir/owner-stack/owner-stack.test.ts @@ -0,0 +1,222 @@ +import { nextTestSetup } from 'e2e-utils' +import { + assertHasRedbox, + assertNoRedbox, + waitForAndOpenRuntimeError, + getRedboxDescription, +} from 'next-test-utils' + +// TODO: parse the location and assert them in the future +// Remove the location `()` part in every line of stack trace; +// Remove the leading spaces in every line of stack trace; +// Remove the trailing spaces in every line of stack trace; +function normalizeStackTrace(trace: string) { + return trace + .replace(/\(.*\)/g, '') + .replace(/^\s+/gm, '') + .trim() +} + +async function getStackFramesContent(browser) { + const stackFrameElements = await browser.elementsByCss( + '[data-nextjs-call-stack-frame]' + ) + const stackFramesContent = ( + await Promise.all( + stackFrameElements.map(async (frame) => { + const functionNameEl = await frame.$('[data-nextjs-frame-expanded]') + const sourceEl = await frame.$('[data-has-source]') + const functionName = functionNameEl + ? await functionNameEl.innerText() + : '' + const source = sourceEl ? await sourceEl.innerText() : '' + + if (!functionName) { + return '' + } + return `at ${functionName} (${source})` + }) + ) + ) + .filter(Boolean) + .join('\n') + + return stackFramesContent +} + +describe('app-dir - owner-stack', () => { + const { next } = nextTestSetup({ + files: __dirname, + }) + + it('should log stitched error for browser uncaught errors', async () => { + const browser = await next.browser('/browser/uncaught') + + await assertHasRedbox(browser) + + const stackFramesContent = await getStackFramesContent(browser) + if (process.env.TURBOPACK) { + expect(stackFramesContent).toMatchInlineSnapshot(` + "at useErrorHook (app/browser/uncaught/page.js (10:3)) + at Page (app/browser/uncaught/page.js (14:3))" + `) + } else { + expect(stackFramesContent).toMatchInlineSnapshot(` + "at useThrowError (app/browser/uncaught/page.js (10:3)) + at useErrorHook (app/browser/uncaught/page.js (14:3))" + `) + } + + const logs = await browser.log() + const errorLog = logs.find((log) => { + return log.message.includes('Error: browser error') + }).message + + if (process.env.TURBOPACK) { + expect(normalizeStackTrace(errorLog)).toMatchInlineSnapshot(` + "Error: browser error + at useThrowError + at useErrorHook + at Page + at react-stack-bottom-frame + at renderWithHooks + at updateFunctionComponent + at beginWork + at runWithFiberInDEV + at performUnitOfWork + at workLoopSync + at renderRootSync + at performWorkOnRoot + at performWorkOnRootViaSchedulerTask + at MessagePort.performWorkUntilDeadline + The above error occurred in the component. It was handled by the error boundary." + `) + } else { + expect(normalizeStackTrace(errorLog)).toMatchInlineSnapshot(` + "Error: browser error + at useThrowError + at useErrorHook + at Page + at react-stack-bottom-frame + at renderWithHooks + at updateFunctionComponent + at beginWork + at runWithFiberInDEV + at performUnitOfWork + at workLoopSync + at renderRootSync + at performWorkOnRoot + at performWorkOnRootViaSchedulerTask + at MessagePort.performWorkUntilDeadline + The above error occurred in the component. It was handled by the error boundary." + `) + } + }) + + it('should log stitched error for browser caught errors', async () => { + const browser = await next.browser('/browser/caught') + + await assertNoRedbox(browser) + + const logs = await browser.log() + const errorLog = logs.find((log) => { + return log.message.includes('Error: browser error') + }).message + + await waitForAndOpenRuntimeError(browser) + + const stackFramesContent = await getStackFramesContent(browser) + + if (process.env.TURBOPACK) { + expect(stackFramesContent).toMatchInlineSnapshot(` + "at useErrorHook (app/browser/caught/page.js (39:3)) + at Thrower (app/browser/caught/page.js (29:3)) + at Inner (app/browser/caught/page.js (23:7)) + at Page (app/browser/caught/page.js (43:10))" + `) + } else { + expect(stackFramesContent).toMatchInlineSnapshot(` + "at useThrowError (app/browser/caught/page.js (39:3)) + at useErrorHook (app/browser/caught/page.js (29:3)) + at Thrower (app/browser/caught/page.js (23:8)) + at Inner (app/browser/caught/page.js (43:11))" + `) + } + + expect(normalizeStackTrace(errorLog)).toMatchInlineSnapshot(` + "Error: browser error + at useThrowError + at useErrorHook + at Thrower + at react-stack-bottom-frame + at renderWithHooks + at updateFunctionComponent + at beginWork + at runWithFiberInDEV + at performUnitOfWork + at workLoopSync + at renderRootSync + at performWorkOnRoot + at performWorkOnRootViaSchedulerTask + at MessagePort.performWorkUntilDeadline + The above error occurred in the component. It was handled by the error boundary." + `) + }) + + it('should log stitched error for SSR errors', async () => { + const browser = await next.browser('/ssr') + + await assertHasRedbox(browser) + + const stackFramesContent = await getStackFramesContent(browser) + if (process.env.TURBOPACK) { + expect(stackFramesContent).toMatchInlineSnapshot(` + "at useErrorHook (app/ssr/page.js (8:3)) + at Page (app/ssr/page.js (12:3))" + `) + } else { + expect(stackFramesContent).toMatchInlineSnapshot(` + "at useThrowError (app/ssr/page.js (8:3)) + at useErrorHook (app/ssr/page.js (12:3))" + `) + } + + const logs = await browser.log() + const errorLog = logs.find((log) => { + return log.message.includes('Error: ssr error') + }).message + + expect(normalizeStackTrace(errorLog)).toMatchInlineSnapshot(` + "Error: ssr error + at useThrowError + at useErrorHook + at Page + at react-stack-bottom-frame + at renderWithHooks + at updateFunctionComponent + at beginWork + at runWithFiberInDEV + at performUnitOfWork + at workLoopSync + at renderRootSync + at performWorkOnRoot + at performWorkOnRootViaSchedulerTask + at MessagePort.performWorkUntilDeadline + The above error occurred in the component. It was handled by the error boundary." + `) + }) + + it('should capture unhandled promise rejections', async () => { + const browser = await next.browser('/browser/reject-promise') + + await waitForAndOpenRuntimeError(browser) + await assertHasRedbox(browser) + + const description = await getRedboxDescription(browser) + expect(description).toMatchInlineSnapshot(`"string in rejected promise"`) + + // Promise rejection has no owner stack + const stackFramesContent = await getStackFramesContent(browser) + expect(stackFramesContent).toMatchInlineSnapshot(`""`) + }) +}) diff --git a/test/lib/next-test-utils.ts b/test/lib/next-test-utils.ts index 872fdaf4e9dd40..818452a9eda9e9 100644 --- a/test/lib/next-test-utils.ts +++ b/test/lib/next-test-utils.ts @@ -1253,15 +1253,6 @@ export async function toggleCollapseComponentStack( .click() } -export async function expandCallStack( - browser: BrowserInterface -): Promise { - // Open full Call Stack - await browser - .elementByCss('[data-nextjs-data-runtime-error-collapsed-action]') - .click() -} - export async function getRedboxCallStack( browser: BrowserInterface ): Promise { From 223b416ddb7dc5f9fd26cf7e4f3d481dc925c7a9 Mon Sep 17 00:00:00 2001 From: eps1lon Date: Thu, 17 Oct 2024 22:49:50 +0200 Subject: [PATCH 39/44] chore: `getOriginalCodeFrame` match declared return type and actual return type --- .../src/client/components/react-dev-overlay/server/shared.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/src/client/components/react-dev-overlay/server/shared.ts b/packages/next/src/client/components/react-dev-overlay/server/shared.ts index 3696d51b88ba20..7b53e0904a2073 100644 --- a/packages/next/src/client/components/react-dev-overlay/server/shared.ts +++ b/packages/next/src/client/components/react-dev-overlay/server/shared.ts @@ -50,7 +50,7 @@ export function findSourcePackage({ export function getOriginalCodeFrame( frame: StackFrame, source: string | null -): string | null | undefined { +): string | null { if (!source || isInternal(frame.file)) { return null } From 3d231ad047e89e32529ea5c9a5760e091247a0b5 Mon Sep 17 00:00:00 2001 From: eps1lon Date: Tue, 22 Oct 2024 19:53:28 +0200 Subject: [PATCH 40/44] Current behavior --- ...amic-io-errors.prospective-fallback.test.ts | 1 + .../fixtures/default/app/layout.js | 7 +++++++ .../default/app/rsc-error-log-cause/page.js | 10 ++++++++++ .../fixtures/default/app/rsc-error-log/page.js | 9 +++++++++ .../fixtures/default/next.config.js | 10 ++++++++++ .../server-source-maps.test.ts | 18 ++++++++++++++++++ 6 files changed, 55 insertions(+) create mode 100644 test/e2e/app-dir/server-source-maps/fixtures/default/app/layout.js create mode 100644 test/e2e/app-dir/server-source-maps/fixtures/default/app/rsc-error-log-cause/page.js create mode 100644 test/e2e/app-dir/server-source-maps/fixtures/default/app/rsc-error-log/page.js create mode 100644 test/e2e/app-dir/server-source-maps/fixtures/default/next.config.js create mode 100644 test/e2e/app-dir/server-source-maps/server-source-maps.test.ts diff --git a/test/e2e/app-dir/dynamic-io-errors/dynamic-io-errors.prospective-fallback.test.ts b/test/e2e/app-dir/dynamic-io-errors/dynamic-io-errors.prospective-fallback.test.ts index 308d7514f3f75f..2d84b3c1b01c65 100644 --- a/test/e2e/app-dir/dynamic-io-errors/dynamic-io-errors.prospective-fallback.test.ts +++ b/test/e2e/app-dir/dynamic-io-errors/dynamic-io-errors.prospective-fallback.test.ts @@ -27,6 +27,7 @@ describe(`Dynamic IO Prospective Fallback`, () => { // we expect the build to fail } + // TODO: Assert on component stack expect(next.cliOutput).toContain( 'In Route "/blog/[slug]" this component accessed data without a fallback UI available somewhere above it using Suspense.' ) diff --git a/test/e2e/app-dir/server-source-maps/fixtures/default/app/layout.js b/test/e2e/app-dir/server-source-maps/fixtures/default/app/layout.js new file mode 100644 index 00000000000000..a3a86a5ca1e12c --- /dev/null +++ b/test/e2e/app-dir/server-source-maps/fixtures/default/app/layout.js @@ -0,0 +1,7 @@ +export default function Root({ children }) { + return ( + + {children} + + ) +} diff --git a/test/e2e/app-dir/server-source-maps/fixtures/default/app/rsc-error-log-cause/page.js b/test/e2e/app-dir/server-source-maps/fixtures/default/app/rsc-error-log-cause/page.js new file mode 100644 index 00000000000000..cbeade4a077fb7 --- /dev/null +++ b/test/e2e/app-dir/server-source-maps/fixtures/default/app/rsc-error-log-cause/page.js @@ -0,0 +1,10 @@ +function logError(cause) { + const error = new Error('Boom', { cause }) + console.error(error) +} + +export default function Page() { + const error = new Error('Boom') + logError(error) + return null +} diff --git a/test/e2e/app-dir/server-source-maps/fixtures/default/app/rsc-error-log/page.js b/test/e2e/app-dir/server-source-maps/fixtures/default/app/rsc-error-log/page.js new file mode 100644 index 00000000000000..383f4689b600c5 --- /dev/null +++ b/test/e2e/app-dir/server-source-maps/fixtures/default/app/rsc-error-log/page.js @@ -0,0 +1,9 @@ +function logError() { + const error = new Error('Boom') + console.error(error) +} + +export default function Page() { + logError() + return null +} diff --git a/test/e2e/app-dir/server-source-maps/fixtures/default/next.config.js b/test/e2e/app-dir/server-source-maps/fixtures/default/next.config.js new file mode 100644 index 00000000000000..70e8c4e01e19b9 --- /dev/null +++ b/test/e2e/app-dir/server-source-maps/fixtures/default/next.config.js @@ -0,0 +1,10 @@ +/** + * @type {import('next').NextConfig} + */ +const nextConfig = { + experimental: { + serverSourceMaps: true, + }, +} + +module.exports = nextConfig diff --git a/test/e2e/app-dir/server-source-maps/server-source-maps.test.ts b/test/e2e/app-dir/server-source-maps/server-source-maps.test.ts new file mode 100644 index 00000000000000..2859fad95022fe --- /dev/null +++ b/test/e2e/app-dir/server-source-maps/server-source-maps.test.ts @@ -0,0 +1,18 @@ +import * as path from 'path' +import { nextTestSetup } from 'e2e-utils' + +describe('app-dir - server source maps', () => { + const { skipped } = nextTestSetup({ + files: path.join(__dirname, 'fixtures/default'), + }) + + if (skipped) return + + it('logged errors have a sourcemapped stack with a codeframe', async () => { + // TODO: Write test once we run with `--enable-source-maps` when `experimental.serverSourceMaps` is set + }) + + it('logged errors have a sourcemapped `cause`', async () => { + // TODO: Write test once we run with `--enable-source-maps` when `experimental.serverSourceMaps` is set + }) +}) From 577a0a74dc9b12ff373e606355d045c8ca82cb0b Mon Sep 17 00:00:00 2001 From: eps1lon Date: Tue, 22 Oct 2024 19:55:15 +0200 Subject: [PATCH 41/44] Ensure DevTools receive unsourcemapped stacks E.g. Node.js inspector or Browser debuggers --- .../error-inspect.tsx | 3 + packages/next/src/server/node-environment.ts | 3 + .../next/src/server/patch-error-inspect.ts | 201 ++++++++++++++++++ .../prospective-fallback/next.config.js | 1 + 4 files changed, 208 insertions(+) create mode 100644 packages/next/src/server/node-environment-extensions/error-inspect.tsx create mode 100644 packages/next/src/server/patch-error-inspect.ts diff --git a/packages/next/src/server/node-environment-extensions/error-inspect.tsx b/packages/next/src/server/node-environment-extensions/error-inspect.tsx new file mode 100644 index 00000000000000..e086cbd003bd69 --- /dev/null +++ b/packages/next/src/server/node-environment-extensions/error-inspect.tsx @@ -0,0 +1,3 @@ +import { patchErrorInspect } from '../patch-error-inspect' + +patchErrorInspect() diff --git a/packages/next/src/server/node-environment.ts b/packages/next/src/server/node-environment.ts index 83d97ac3a15714..4eefc81a16dc77 100644 --- a/packages/next/src/server/node-environment.ts +++ b/packages/next/src/server/node-environment.ts @@ -1,6 +1,9 @@ // This file should be imported before any others. It sets up the environment // for later imports to work properly. +// Import before anything else so that unexpected errors in other extensions are properly formatted. +import './node-environment-extensions/error-inspect' + import './node-environment-baseline' import './node-environment-extensions/random' import './node-environment-extensions/date' diff --git a/packages/next/src/server/patch-error-inspect.ts b/packages/next/src/server/patch-error-inspect.ts new file mode 100644 index 00000000000000..387c06208d85ae --- /dev/null +++ b/packages/next/src/server/patch-error-inspect.ts @@ -0,0 +1,201 @@ +import { findSourceMap } from 'module' +import type * as util from 'util' +import { SourceMapConsumer as SyncSourceMapConsumer } from 'next/dist/compiled/source-map' +import type { StackFrame } from 'next/dist/compiled/stacktrace-parser' +import { parseStack } from '../client/components/react-dev-overlay/server/middleware' +import { getOriginalCodeFrame } from '../client/components/react-dev-overlay/server/shared' + +// TODO: Implement for Edge runtime +const inspectSymbol = Symbol.for('nodejs.util.inspect.custom') + +function frameToString(frame: StackFrame): string { + return frame.methodName + ? ` at ${frame.methodName} (${frame.file}:${frame.lineNumber}:${frame.column})` + : ` at ${frame.file}:${frame.lineNumber}:${frame.column}` +} + +function prepareUnsourcemappedStackTrace( + error: Error, + structuredStackTrace: any[] +): string { + const name = error.name || 'Error' + const message = error.message || '' + let stack = name + ': ' + message + for (let i = 0; i < structuredStackTrace.length; i++) { + stack += '\n at ' + structuredStackTrace[i].toString() + } + return stack +} + +function shouldIgnoreListByDefault(file: string): boolean { + return ( + // TODO: Solve via `ignoreList` instead. Tricky because node internals are not part of the sourcemap. + file.startsWith('node:') || + // C&P from setup-dev-bundler + // TODO: Taken from setup-dev-bundler but these seem too broad + // file.includes('web/adapter') || + // file.includes('web/globals') || + // file.includes('sandbox/context') || + // TODO: Seems too aggressive? + file.includes('') || + file.startsWith('eval') + ) +} + +function getSourcemappedFrameIfPossible( + frame: StackFrame, + sourcemapConsumers: Map +): { + stack: StackFrame + // DEV only + code: string | null +} | null { + if (frame.file === null) { + return null + } + + let sourcemap = sourcemapConsumers.get(frame.file) + if (sourcemap === undefined) { + const moduleSourcemap = findSourceMap(frame.file) + if (moduleSourcemap === undefined) { + return null + } + sourcemap = new SyncSourceMapConsumer( + // @ts-expect-error -- Module.SourceMap['version'] is number but SyncSourceMapConsumer wants a string + moduleSourcemap.payload + ) + sourcemapConsumers.set(frame.file, sourcemap) + } + + const sourcePosition = sourcemap.originalPositionFor({ + column: frame.column ?? 0, + line: frame.lineNumber ?? 1, + }) + + if (sourcePosition.source === null) { + return null + } + + const sourceContent: string | null = + sourcemap.sourceContentFor( + sourcePosition.source, + /* returnNullOnMissing */ true + ) ?? null + + const originalFrame: StackFrame = { + methodName: + sourcePosition.name || + // default is not a valid identifier in JS so webpack uses a custom variable when it's an unnamed default export + // Resolve it back to `default` for the method name if the source position didn't have the method. + frame.methodName + ?.replace('__WEBPACK_DEFAULT_EXPORT__', 'default') + ?.replace('__webpack_exports__.', ''), + column: sourcePosition.column, + file: sourcePosition.source, + lineNumber: sourcePosition.line, + // TODO: c&p from async createOriginalStackFrame but why not frame.arguments? + arguments: [], + } + + return { + stack: originalFrame, + code: + process.env.NODE_ENV !== 'production' + ? getOriginalCodeFrame(originalFrame, sourceContent) + : null, + } +} + +function parseAndSourceMap(error: Error): string { + // We overwrote Error.prepareStackTrace earlier so error.stack is not sourcemapped. + let unparsedStack = String(error.stack) + + let idx = unparsedStack.indexOf('react-stack-bottom-frame') + if (idx !== -1) { + idx = unparsedStack.lastIndexOf('\n', idx) + } + if (idx !== -1) { + // Cut off everything after the bottom frame since it'll be React internals. + unparsedStack = unparsedStack.slice(0, idx) + } + + const unsourcemappedStack = parseStack(unparsedStack) + const sourcemapConsumers = new Map() + + let sourceMappedStack = '' + let sourceFrameDEV: null | string = null + for (const frame of unsourcemappedStack) { + if (frame.file === null) { + sourceMappedStack += '\n' + frameToString(frame) + } else if (!shouldIgnoreListByDefault(frame.file)) { + const sourcemappedFrame = getSourcemappedFrameIfPossible( + frame, + sourcemapConsumers + ) + + if (sourcemappedFrame === null) { + sourceMappedStack += '\n' + frameToString(frame) + } else { + // TODO: Use the first frame that's not ignore-listed + if ( + process.env.NODE_ENV !== 'production' && + sourcemappedFrame.code !== null && + sourceFrameDEV !== null + ) { + sourceFrameDEV = sourcemappedFrame.code + } + // TODO: Hide if ignore-listed but consider what happens if every frame is ignore listed. + sourceMappedStack += '\n' + frameToString(sourcemappedFrame.stack) + } + } + } + + return ( + error.message + + sourceMappedStack + + (sourceFrameDEV !== null ? '\n' + sourceFrameDEV : '') + ) +} + +export function patchErrorInspect() { + Error.prepareStackTrace = prepareUnsourcemappedStackTrace + + // @ts-expect-error -- TODO upstream types + // eslint-disable-next-line no-extend-native -- We're not extending but overriding. + Error.prototype[inspectSymbol] = function ( + depth: number, + inspectOptions: util.InspectOptions, + inspect: typeof util.inspect + ): string { + // Create a new Error object with the source mapping applied and then use native + // Node.js formatting on the result. + const newError = + this.cause !== undefined + ? // Setting an undefined `cause` would print `[cause]: undefined` + new Error(this.message, { cause: this.cause }) + : new Error(this.message) + + // TODO: Ensure `class MyError extends Error {}` prints `MyError` as the name + newError.stack = parseAndSourceMap(this) + + const originalCustomInspect = (newError as any)[inspectSymbol] + // Prevent infinite recursion. + // { customInspect: false } would result in `error.cause` not using our inspect. + Object.defineProperty(newError, inspectSymbol, { + value: undefined, + enumerable: false, + writable: true, + }) + try { + return inspect(newError, { + ...inspectOptions, + depth: + (inspectOptions.depth ?? + // Default in Node.js + 2) - depth, + }) + } finally { + ;(newError as any)[inspectSymbol] = originalCustomInspect + } + } +} diff --git a/test/e2e/app-dir/dynamic-io-errors/fixtures/prospective-fallback/next.config.js b/test/e2e/app-dir/dynamic-io-errors/fixtures/prospective-fallback/next.config.js index bb76fc99dc6b63..195ad29be3c541 100644 --- a/test/e2e/app-dir/dynamic-io-errors/fixtures/prospective-fallback/next.config.js +++ b/test/e2e/app-dir/dynamic-io-errors/fixtures/prospective-fallback/next.config.js @@ -1,5 +1,6 @@ module.exports = { experimental: { dynamicIO: true, + serverSourceMaps: true, }, } From 301976189ccdc37c7cfbd4e630d524c64a7bbc02 Mon Sep 17 00:00:00 2001 From: eps1lon Date: Wed, 23 Oct 2024 12:10:00 +0200 Subject: [PATCH 42/44] Handle missing location when printing stackframe --- packages/next/src/server/patch-error-inspect.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/next/src/server/patch-error-inspect.ts b/packages/next/src/server/patch-error-inspect.ts index 387c06208d85ae..47eba1b3258eea 100644 --- a/packages/next/src/server/patch-error-inspect.ts +++ b/packages/next/src/server/patch-error-inspect.ts @@ -9,9 +9,13 @@ import { getOriginalCodeFrame } from '../client/components/react-dev-overlay/ser const inspectSymbol = Symbol.for('nodejs.util.inspect.custom') function frameToString(frame: StackFrame): string { + let sourceLocation = frame.lineNumber !== null ? `:${frame.lineNumber}` : '' + if (frame.column !== null && sourceLocation !== '') { + sourceLocation += `:${frame.column}` + } return frame.methodName - ? ` at ${frame.methodName} (${frame.file}:${frame.lineNumber}:${frame.column})` - : ` at ${frame.file}:${frame.lineNumber}:${frame.column}` + ? ` at ${frame.methodName} (${frame.file}${sourceLocation})` + : ` at ${frame.file}${frame.lineNumber}:${frame.column}` } function prepareUnsourcemappedStackTrace( From 30e196f21d245ac45a914ba903f7aa3b11c1a78e Mon Sep 17 00:00:00 2001 From: eps1lon Date: Wed, 23 Oct 2024 12:11:04 +0200 Subject: [PATCH 43/44] Add follow-up item for correct name computation --- .../next/src/server/patch-error-inspect.ts | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/packages/next/src/server/patch-error-inspect.ts b/packages/next/src/server/patch-error-inspect.ts index 47eba1b3258eea..b81e89df734b38 100644 --- a/packages/next/src/server/patch-error-inspect.ts +++ b/packages/next/src/server/patch-error-inspect.ts @@ -18,11 +18,18 @@ function frameToString(frame: StackFrame): string { : ` at ${frame.file}${frame.lineNumber}:${frame.column}` } +function computeErrorName(error: Error): string { + // TODO: Node.js seems to use a different algorithm + // class ReadonlyRequestCookiesError extends Error {}` would read `ReadonlyRequestCookiesError: [...]` + // in the stack i.e. seems like under certain conditions it favors the constructor name. + return error.name || 'Error' +} + function prepareUnsourcemappedStackTrace( error: Error, structuredStackTrace: any[] ): string { - const name = error.name || 'Error' + const name = computeErrorName(error) const message = error.message || '' let stack = name + ': ' + message for (let i = 0; i < structuredStackTrace.length; i++) { @@ -34,15 +41,15 @@ function prepareUnsourcemappedStackTrace( function shouldIgnoreListByDefault(file: string): boolean { return ( // TODO: Solve via `ignoreList` instead. Tricky because node internals are not part of the sourcemap. - file.startsWith('node:') || + file.startsWith('node:') // C&P from setup-dev-bundler // TODO: Taken from setup-dev-bundler but these seem too broad // file.includes('web/adapter') || // file.includes('web/globals') || // file.includes('sandbox/context') || // TODO: Seems too aggressive? - file.includes('') || - file.startsWith('eval') + // file.includes('') || + // file.startsWith('eval') ) } @@ -101,18 +108,24 @@ function getSourcemappedFrameIfPossible( arguments: [], } + const codeFrame = + process.env.NODE_ENV !== 'production' + ? getOriginalCodeFrame(originalFrame, sourceContent) + : null + return { stack: originalFrame, - code: - process.env.NODE_ENV !== 'production' - ? getOriginalCodeFrame(originalFrame, sourceContent) - : null, + code: codeFrame, } } function parseAndSourceMap(error: Error): string { // We overwrote Error.prepareStackTrace earlier so error.stack is not sourcemapped. let unparsedStack = String(error.stack) + // We could just read it from `error.stack`. + // This works around cases where a 3rd party `Error.prepareStackTrace` implementation + // doesn't implement the name computation correctly. + const errorName = computeErrorName(error) let idx = unparsedStack.indexOf('react-stack-bottom-frame') if (idx !== -1) { @@ -155,6 +168,8 @@ function parseAndSourceMap(error: Error): string { } return ( + errorName + + ': ' + error.message + sourceMappedStack + (sourceFrameDEV !== null ? '\n' + sourceFrameDEV : '') From e5624b549d0b87e0034e3f4938e178ec6bb352be Mon Sep 17 00:00:00 2001 From: eps1lon Date: Wed, 23 Oct 2024 12:12:06 +0200 Subject: [PATCH 44/44] follow-up item to check if codeframes don't use colors in non-tty env --- .../src/client/components/react-dev-overlay/server/shared.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/next/src/client/components/react-dev-overlay/server/shared.ts b/packages/next/src/client/components/react-dev-overlay/server/shared.ts index 7b53e0904a2073..4fede2333ea2c4 100644 --- a/packages/next/src/client/components/react-dev-overlay/server/shared.ts +++ b/packages/next/src/client/components/react-dev-overlay/server/shared.ts @@ -65,6 +65,7 @@ export function getOriginalCodeFrame( column: frame.column ?? 0, }, }, + // TODO: Only in TTY { forceColor: true } ) }