From 4e2206f8ed57e9af5986e94ef8896e94db15556b Mon Sep 17 00:00:00 2001 From: pedrobonamin Date: Wed, 23 Oct 2024 17:45:57 +0200 Subject: [PATCH] feat(cli): add warning and docs for react-19 and Next.Js combination --- .../src/actions/init-project/initProject.ts | 22 +++++++++++++++++++ .../actions/init-project/readPackageJson.ts | 18 +++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 packages/@sanity/cli/src/actions/init-project/readPackageJson.ts diff --git a/packages/@sanity/cli/src/actions/init-project/initProject.ts b/packages/@sanity/cli/src/actions/init-project/initProject.ts index dac97466649..5b0d521c8ce 100644 --- a/packages/@sanity/cli/src/actions/init-project/initProject.ts +++ b/packages/@sanity/cli/src/actions/init-project/initProject.ts @@ -9,6 +9,7 @@ import execa, {type CommonOptions} from 'execa' import {deburr, noop} from 'lodash' import pFilter from 'p-filter' import resolveFrom from 'resolve-from' +import semver from 'semver' import {evaluate, patch} from 'silver-fleece' import which from 'which' @@ -55,6 +56,7 @@ import { promptForNextTemplate, promptForStudioPath, } from './prompts/nextjs' +import {readPackageJson} from './readPackageJson' import {reconfigureV2Project} from './reconfigureV2Project' import templates from './templates' import { @@ -128,6 +130,8 @@ export default async function initSanity( const cliFlags = args.extOptions const unattended = cliFlags.y || cliFlags.yes const print = unattended ? noop : output.print + const warn = (msg: string) => output.warn(chalk.yellow.bgBlack(msg)) + const intendedPlan = cliFlags['project-plan'] const intendedCoupon = cliFlags.coupon const reconfigure = cliFlags.reconfigure @@ -327,6 +331,24 @@ export default async function initSanity( // Ensure we are using the output path provided by user outputPath = answers.outputPath + const packageJson = readPackageJson(`${outputPath}/package.json`) + const reactVersion = packageJson.dependencies?.react + const isUsingReact19 = semver.coerce(reactVersion)?.major === 19 + if ( + detectedFramework?.slug === 'nextjs' && + // @ts-expect-error - Detected version is not typed into Framework interface + detectedFramework?.detectedVersion?.startsWith('15') && + isUsingReact19 + ) { + warn('╭────────────────────────────────────────────────────────────╮') + warn('│ │') + warn('│ It looks like you are using Next.js 15 and React 19 │') + warn('│ Please read our compatibility guide. │') + warn('│ https://www.sanity.io/help/react-19 │') + warn('│ │') + warn('╰────────────────────────────────────────────────────────────╯') + } + if (initNext) { const useTypeScript = unattended ? true : await promptForTypeScript(prompt) trace.log({step: 'useTypeScript', selectedOption: useTypeScript ? 'yes' : 'no'}) diff --git a/packages/@sanity/cli/src/actions/init-project/readPackageJson.ts b/packages/@sanity/cli/src/actions/init-project/readPackageJson.ts new file mode 100644 index 00000000000..ac9e9283ccf --- /dev/null +++ b/packages/@sanity/cli/src/actions/init-project/readPackageJson.ts @@ -0,0 +1,18 @@ +import fs from 'node:fs' + +import {type PackageJson} from '@sanity/cli' + +/** + * Read the `package.json` file at the given path + * + * @param filePath - Path to package.json to read + * @returns The parsed package.json + */ +export function readPackageJson(filePath: string): PackageJson { + try { + // eslint-disable-next-line no-sync + return JSON.parse(fs.readFileSync(filePath, 'utf8')) + } catch (err) { + throw new Error(`Failed to read "${filePath}": ${err.message}`) + } +}