从Next.js 12迁移至Next.js 13时出现Cannot read properties of undefined (reading 'call')运行时错误
Next.js 12 迁移至13时出现 "Cannot read properties of undefined (reading 'call')" 运行时错误
迁移操作步骤:
- 执行命令创建项目:
npx create-next-app - 在配置中启用app目录:
experimental : { appDir : true, }
- 删除pages文件夹,创建app目录,结构如下:
-app --page.tsx --layout.tsx --head.tsx
各文件代码如下:
layout.tsx
import Footer from "../ui/Footer"; import Header from "../ui/Header"; import '../styles/globals.css'; export default function Layout({ children }: { children: React.ReactNode }) { return ( <html lang="en"> <body className="font-sans bg-gradient-to-b from-neutral-900 to-indigo-900"> <Header /> <main className="min-h-screen flex justify-center items-center flex-1 "> {children} </main> <Footer /> </body> </html> ); }
page.tsx
import Card from "../ui/Card"; export default function Page() { return ( <div className="flex items-center justify-center flex-wrap large:max-w-2xl medium:max-w-md"> <Card title="JWT" logo="🌸" desc="Industry standard method for secure claim representation." /> </div> ); }
head.tsx
export default function Head() { return ( <> <title>Authenticator</title> <meta name="description" content="A playground to explore different types of authentication/authorization using different services in educational purposes." key="description" /> <link rel="icon" href="/favicon.ico" /> <meta name="viewport" content="initial-scale=1.0, width=device-width" /> </> ); }
可能的原因及解决步骤
升级到稳定版Next.js 13
早期Next.js 13的app目录处于实验阶段,bug较多。确保安装13.4及以上的稳定版本:npm install next@latest react@latest react-dom@latest移除废弃的head.tsx
Next.js 13的App Router已不再支持单独的head.tsx,需将头部配置合并到layout.tsx中,或使用Metadata API:- 合并到layout.tsx的写法:
import Footer from "../ui/Footer"; import Header from "../ui/Header"; import '../styles/globals.css'; export default function Layout({ children }: { children: React.ReactNode }) { return ( <html lang="en"> <head> <title>Authenticator</title> <meta name="description" content="A playground to explore different types of authentication/authorization using different services in educational purposes." key="description" /> <link rel="icon" href="/favicon.ico" /> <meta name="viewport" content="initial-scale=1.0, width=device-width" /> </head> <body className="font-sans bg-gradient-to-b from-neutral-900 to-indigo-900"> <Header /> <main className="min-h-screen flex justify-center items-center flex-1 "> {children} </main> <Footer /> </body> </html> ); } - 推荐的Metadata API写法:
export const metadata = { title: "Authenticator", description: "A playground to explore different types of authentication/authorization using different services in educational purposes.", icons: { icon: "/favicon.ico", }, viewport: "initial-scale=1.0, width=device-width", };
- 合并到layout.tsx的写法:
检查UI组件兼容性
确认Header、Footer、Card等自定义组件未使用Pages Router专属API(如旧版useRouter、getServerSideProps),替换为App Router兼容的写法(如useRouter从next/navigation导入)。清除缓存重启服务
清理项目缓存并重新安装依赖,解决旧代码残留问题:rm -rf .next node_modules package-lock.json npm install npm run dev校验tsconfig.json配置
确保配置符合Next.js 13要求,添加或确认以下内容:{ "compilerOptions": { "target": "es5", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, "strict": true, "forceConsistentCasingInFileNames": true, "noEmit": true, "esModuleInterop": true, "module": "esnext", "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve", "incremental": true, "plugins": [{ "name": "next" }], "paths": { "@/*": ["./*"] } }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], "exclude": ["node_modules"] }
内容的提问来源于stack exchange,提问作者voq
相关产品推荐
相关产品推荐

