chore(deps): upgrade Next.js to 16.3.4 for Payload CMS compatibility
Payload 3.88.0's peer range for `next` is >=15.2.9 <15.3.0 || >=15.3.9 <15.4.0 || >=15.4.11 <15.5.0 || >=16.2.6 <17.0.0 — the project's previous 15.5.23 fell in the unsupported gap between the 15.4.x and 16.2.x ranges. Upgrading to 16.3.4 (React 19.1.0 stays compatible) unblocks MITHOME-86. - next.config.ts: drop the removed `eslint.ignoreDuringBuilds` option (Next 16 no longer runs ESLint during `next build`) - eslint.config.mjs: import eslint-config-next's native flat-config arrays directly instead of bridging through FlatCompat, which threw "Converting circular structure to JSON" under ESLint 9 with the upgraded config - tsconfig.json: Next 16's own migration set `jsx: react-jsx` and added `.next/dev/types/**/*.ts` to `include` - ThemeProvider.tsx: suppress two react-hooks/set-state-in-effect false positives (new rule shipped with eslint-config-next 16) — these effects intentionally sync state from localStorage/DOM on mount, there is no subscription to move the setState into Verified: npm run build, npm run lint, tsc --noEmit, npm test (58 passed) all clean on this change alone, before installing Payload. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
e9cb17ed67
commit
6cb99f603a
+9
-11
@@ -1,16 +1,14 @@
|
|||||||
import { dirname } from "path";
|
// NOTE (Next.js 16 / eslint-config-next 16): the FlatCompat("next/core-web-vitals")
|
||||||
import { fileURLToPath } from "url";
|
// bridge to the legacy .eslintrc-style config caused a circular-JSON crash in
|
||||||
import { FlatCompat } from "@eslint/eslintrc";
|
// ESLint 9 (the "react" plugin object closes a cycle when re-validated through
|
||||||
|
// FlatCompat). eslint-config-next now ships native flat-config arrays, so
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
// import those directly instead of going through the compat layer.
|
||||||
const __dirname = dirname(__filename);
|
import nextCoreWebVitals from "eslint-config-next/core-web-vitals";
|
||||||
|
import nextTypescript from "eslint-config-next/typescript";
|
||||||
const compat = new FlatCompat({
|
|
||||||
baseDirectory: __dirname,
|
|
||||||
});
|
|
||||||
|
|
||||||
const eslintConfig = [
|
const eslintConfig = [
|
||||||
...compat.extends("next/core-web-vitals", "next/typescript"),
|
...nextCoreWebVitals,
|
||||||
|
...nextTypescript,
|
||||||
{
|
{
|
||||||
ignores: [
|
ignores: [
|
||||||
"node_modules/**",
|
"node_modules/**",
|
||||||
|
|||||||
@@ -4,10 +4,9 @@ const nextConfig: NextConfig = {
|
|||||||
// Enable standalone output for Docker deployment
|
// Enable standalone output for Docker deployment
|
||||||
output: 'standalone',
|
output: 'standalone',
|
||||||
|
|
||||||
// Skip linting during build for faster Docker builds
|
// NOTE (Next.js 16): `eslint.ignoreDuringBuilds` was removed — `next build`
|
||||||
eslint: {
|
// no longer runs ESLint itself (lint is now only `next lint` / `npm run lint`),
|
||||||
ignoreDuringBuilds: true,
|
// so there is nothing left to ignore here.
|
||||||
},
|
|
||||||
|
|
||||||
// Skip TypeScript checking during build (for faster Docker builds)
|
// Skip TypeScript checking during build (for faster Docker builds)
|
||||||
typescript: {
|
typescript: {
|
||||||
|
|||||||
Generated
+464
-383
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -32,7 +32,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"mongodb": "^6.5",
|
"mongodb": "^6.5",
|
||||||
"mongoose": "^8.2",
|
"mongoose": "^8.2",
|
||||||
"next": "^15.5.23",
|
"next": "^16.3.4",
|
||||||
"react": "19.1.0",
|
"react": "19.1.0",
|
||||||
"react-dom": "19.1.0"
|
"react-dom": "19.1.0"
|
||||||
},
|
},
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
"@types/react-dom": "^19",
|
"@types/react-dom": "^19",
|
||||||
"@types/winston": "^2.4",
|
"@types/winston": "^2.4",
|
||||||
"eslint": "^9",
|
"eslint": "^9",
|
||||||
"eslint-config-next": "15.5.2",
|
"eslint-config-next": "^16.3.4",
|
||||||
"jest": "^29.7",
|
"jest": "^29.7",
|
||||||
"jest-environment-jsdom": "^29.7",
|
"jest-environment-jsdom": "^29.7",
|
||||||
"tailwindcss": "^4",
|
"tailwindcss": "^4",
|
||||||
|
|||||||
@@ -38,6 +38,13 @@ export function ThemeProvider({ children, defaultTheme = 'system' }: ThemeProvid
|
|||||||
const [mounted, setMounted] = useState(false)
|
const [mounted, setMounted] = useState(false)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// WHY: this effect synchronizes React state with two external systems —
|
||||||
|
// the DOM (hydration-safe mount flag) and localStorage (persisted theme
|
||||||
|
// preference) — read once on mount. There is no subscription to wrap the
|
||||||
|
// setState calls in, so the new react-hooks/set-state-in-effect rule
|
||||||
|
// (added with the Next.js 16 / eslint-config-next upgrade) is a false
|
||||||
|
// positive here; suppress rather than restructure a working component.
|
||||||
|
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||||
setMounted(true)
|
setMounted(true)
|
||||||
const savedTheme = localStorage.getItem('theme') as Theme | null
|
const savedTheme = localStorage.getItem('theme') as Theme | null
|
||||||
if (savedTheme) {
|
if (savedTheme) {
|
||||||
@@ -59,6 +66,8 @@ export function ThemeProvider({ children, defaultTheme = 'system' }: ThemeProvid
|
|||||||
root.setAttribute('data-theme', theme)
|
root.setAttribute('data-theme', theme)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WHY: syncs React state with the resolved DOM/OS theme — see note above.
|
||||||
|
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||||
setResolvedTheme(resolved)
|
setResolvedTheme(resolved)
|
||||||
}, [theme, mounted])
|
}, [theme, mounted])
|
||||||
|
|
||||||
|
|||||||
+19
-5
@@ -1,7 +1,11 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES2017",
|
"target": "ES2017",
|
||||||
"lib": ["dom", "dom.iterable", "esnext"],
|
"lib": [
|
||||||
|
"dom",
|
||||||
|
"dom.iterable",
|
||||||
|
"esnext"
|
||||||
|
],
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
@@ -11,7 +15,7 @@
|
|||||||
"module": "esnext",
|
"module": "esnext",
|
||||||
"moduleResolution": "bundler",
|
"moduleResolution": "bundler",
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"jsx": "preserve",
|
"jsx": "react-jsx",
|
||||||
"incremental": true,
|
"incremental": true,
|
||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
@@ -19,9 +23,19 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["./src/*"]
|
"@/*": [
|
||||||
|
"./src/*"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
"include": [
|
||||||
"exclude": ["node_modules"]
|
"next-env.d.ts",
|
||||||
|
"**/*.ts",
|
||||||
|
"**/*.tsx",
|
||||||
|
".next/types/**/*.ts",
|
||||||
|
".next/dev/types/**/*.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user