Next.js项目本地正常但build失败,Vercel部署报错求助
Next.js项目本地正常但构建/部署失败的修复方案
问题详情
本地开发环境运行无任何错误,但执行npm run build时触发大量类型错误,部署到Vercel时显示npm run build exited 1,核心错误提示:
Type error: 'GetServerSideProps' refers to a value, but is being used as a type here. Did you mean 'typeof GetServerSideProps'?
已尝试删除node_modules并重装依赖,问题未解决。
错误原因
- 错误的导入方式:把
GetServerSideProps当作默认值从next导入,但它实际是Next.js提供的TypeScript类型,需要以类型方式导入。 - 命名冲突:自定义的导出函数名和导入的类型名重名,导致TypeScript混淆了“值”和“类型”的使用场景。
- Props类型不匹配:
collections被定义为单个Collection类型,但Sanity查询返回的是数组,类型不兼容。
修复步骤
1. 修正导入语句
移除错误的导入:
import GetServerSideProps from 'next';
改为导入类型(仅用于类型检查,不影响运行时):
import type { GetServerSideProps } from 'next';
2. 修正Props接口类型
把collections的类型从单个Collection改为数组Collection[]:
interface Props { collections: Collection[] }
3. 规范GetServerSideProps函数
Next.js官方约定使用小写的getServerSideProps作为导出名(大写也能运行,但小写是规范),同时可以用导入的类型给函数添加约束:
export const getServerSideProps: GetServerSideProps<Props> = async () => { // 函数逻辑不变 }
4. 额外优化(非核心但提升体验)
- 修正
Head中link标签的rel属性:原先是stylesheet,改为icon,避免浏览器把favicon当成样式表加载。 - 给
img标签添加有意义的alt文本,提升页面可访问性。 - 修正
Link的href路径,添加前置/避免相对路径问题。
修改后的完整Index.tsx代码
import Image from 'next/image' import Head from "next/head" import { sanityClient, urlFor } from "../sanity" import Link from 'next/link' import { Collection } from '../typings'; import type { GetServerSideProps } from 'next'; interface Props { collections: Collection[] } const Home = ({ collections }: Props) => { return ( <div className='bg-yellow-400 max-auto flex min-h-screen flex-col py-10 px-10 '> <Head> <title>Ordinal Cats</title> <link rel="icon" href="/favicon.ico" /> </Head> <h1 className='w-52 text-xl font-extralight sm:w-80 py-5'> <span className='font-extrabold underline decoration-orange-600/50'>Ordinal Cats</span> </h1> <main className='bg-orange-500 rounded-lg p-10 shadow-xl shadow-black items-center ' > <div className='grid space-x-3 md:grid-cols-1 lg:grid-cols-1 2xl:grid-cols-4'> {collections?.map(collection => ( <div key={collection.slug.current} className='flex flex-col items-center'> <img className='h-70 w-50 rounded-2xl object-cover' src={urlFor(collection.mainImage).url()} alt={collection.title} /> <div> <h2 className='text-3xl items-center text-center'>{collection.title}</h2> <p className='mt-2 text-sm text-white text-center'>{collection.description}</p> <Link href={`/${collection.slug.current}`}> <button className='cursor-pointer transition-all duration-200 hover:scale-105 h-16 bg-[#facf38] w-full text-black rounded-full mt-2 font-bold disabled:bg-gray-400'>Mint</button> </Link> </div> </div> ))} </div> </main> </div> ) } export default Home export const getServerSideProps: GetServerSideProps<Props> = async () => { const query = `*[_type == "collection"]{ _id, title, address, description, nftCollectionName, mainImage{ asset }, previewImage { asset }, slug { current }, creator -> { _id, name, address, slug{ current }, }, }` const collections = await sanityClient.fetch(query) return { props: { collections } } }
内容的提问来源于stack exchange,提问作者BADASS SKALLIES
相关产品推荐
相关产品推荐

