Next.js博客Vercel生产部署报错:找不到指定MDX文件
博客页面生产环境ENOENT文件找不到错误
Vercel日志错误信息
Error: ENOENT: no such file or directory, open '/var/task/src/content/hello.mdx' at Object.openSync (node:fs:601:3) at Object.readFileSync (node:fs:469:35) at PostPage (/var/task/.next/server/app/posts/[slug]/page.js:381:45) at S (/var/task/.next/server/chunks/789.js:6503:13) at eb (/var/task/.next/server/chunks/789.js:6618:21) at Array.toJSON (/var/task/.next/server/chunks/789.js:6422:20) at stringify (<anonymous>) at pb (/var/task/.next/server/chunks/789.js:6829:9) at mb (/var/task/.next/server/chunks/789.js:6728:29) at Timeout._onTimeout (/var/task/.next/server/chunks/789.js:6553:16) { errno: -2, syscall: 'open', code: 'ENOENT', path: '/var/task/src/content/hello.mdx' }
页面前端提示
Application error: a server-side exception has occurred (see the server logs for more information).
Digest: 2113801254
项目目录结构
my-app/ └── src/ ├── app/ │ ├── posts/ │ │ ├── page.js │ │ └── [slug]/ │ │ └── page.js or PostPage │ └── page.js ├── layout.js ├── page.js ├── components ├── content/ │ └── hello.mdx └── fonts
当前PostPage代码
export default function PostPage({ params }) { const post = fs.readFileSync( path.join(__dirname, "../../../../../src/content/" + params.slug + ".mdx"), "utf-8" ); const { data: frontmatter, content } = matter(post); const blog = DOMPurify.sanitize( marked.parse(content, { mangle: false, headerIds: false }) ); ..... //returns jsx with markdown content }
问题原因
本地开发时__dirname指向源码文件所在目录,手动拼接的相对路径能正确找到文件,但Vercel生产环境中,Next.js会把代码编译到.next/server目录下,此时__dirname的层级和本地完全不同,手动计算的../../../../../相对路径无法定位到src/content目录,导致文件找不到。
解决方案
用process.cwd()代替__dirname获取项目根目录,它在Vercel生产环境中指向项目根目录(/var/task),能稳定定位到src/content文件夹:
修改后的代码:
import fs from 'fs'; import path from 'path'; // 确保导入matter、DOMPurify、marked等依赖 export default function PostPage({ params }) { // 用process.cwd()拼接正确路径 const postPath = path.join(process.cwd(), 'src', 'content', `${params.slug}.mdx`); const post = fs.readFileSync(postPath, 'utf-8'); const { data: frontmatter, content } = matter(post); const blog = DOMPurify.sanitize( marked.parse(content, { mangle: false, headerIds: false }) ); ..... // 返回JSX内容 }
额外注意事项
- 确保
src/content目录下的.mdx文件都已正确提交到Git仓库,Vercel部署时会同步这些文件 - 若使用Next.js 13+ App Router,推荐使用异步的
fs.promises.readFile配合async/await,避免同步IO阻塞服务器:
export default async function PostPage({ params }) { const postPath = path.join(process.cwd(), 'src', 'content', `${params.slug}.mdx`); const post = await fs.promises.readFile(postPath, 'utf-8'); // 后续逻辑不变 }
内容的提问来源于stack exchange,提问作者Shivam Bhatnagar
相关产品推荐
相关产品推荐

