Next.js部署Vercel后扫描目录生成sitemap.xml报错如何解决?
问题根因
- 首先是生产环境路径判断完全不符合Vercel的Next.js构建产物结构
你本地运行yarn start时,Node.js进程可以访问到项目根目录下的源码文件,但Vercel部署的serverless运行环境中,仅会保留构建后必要的运行时文件,你拼接的__dirname + '/projects'路径对应/var/task/.next/server/pages/projects,这个目录在Vercel的构建产物中根本不存在:Next.js构建时只会把页面编译后的JS bundle放到对应server目录,不会把源码层面的pages/projects目录原封不动拷贝到构建输出的server路径下。 - 其次是路径拼接写法不规范:直接用
+拼接路径没有考虑不同系统的路径分隔符差异,即使路径存在也有概率触发报错。
为什么本地运行正常
本地production模式运行时,Node.js进程的运行权限可以访问整个项目目录的所有文件,哪怕你拼接的路径不符合规范,也可能因为本地存在其他冗余文件、或者构建配置差异命中了 fallback 路径,不会触发报错。
修复方案
- 统一使用项目根目录作为路径基准,用
process.cwd()配合path.join拼接路径,避免相对路径和分隔符问题:
const path = require('path') const staticPagesProjects = fs .readdirSync( process.env.NODE_ENV === 'development' ? path.join(process.cwd(), 'src/pages/projects') // 生产环境直接从项目根目录读取源码里的projects目录,Vercel构建时会保留根目录的源码文件用于serverless运行 : path.join(process.cwd(), 'src/pages/projects') ) .filter((staticPage) => { return regex.test(staticPage) && !['index.html', '404.html', '500.html'].includes(staticPage) }) .map((staticPagePath) => { return `${baseUrl}/projects/${staticPagePath.replace(".html", "")}`; });
- 更稳定的替代方案:放弃在getServerSideProps里动态读取文件生成sitemap,改为构建时直接生成sitemap.xml文件写入public目录,完全避免运行时读文件的问题,性能也更高。
内容的提问来源于stack exchange,提问作者Alexandre Paiva
相关产品推荐
相关产品推荐

