Next.js 13 App Router开发MDX博客遇fs模块无法解析错误
解决Next.js 13 App Router中「Module not found: Can't resolve 'fs'」错误
问题根源
你把Next.js 12 Pages Router的代码直接搬到App Router环境里,但两者的运行规则完全不同:
- 加了
"use client"的组件会在浏览器端运行,而fs是Node.js专属模块,浏览器环境不存在这个模块,所以触发报错。 - App Router已经废弃了
getStaticProps这类Pages Router的 data fetching方法,默认的page组件是服务器组件,支持直接在组件内写异步逻辑读取文件系统。
具体修复步骤
- 移除
"use client"指令:让page组件保持默认的服务器组件身份,这样就能在服务器端正常使用fs模块。 - 迁移
getStaticProps逻辑到组件内部:服务器组件允许异步函数,直接把文件读取、处理的逻辑放到page组件里执行。 - 替换客户端API(如果需要交互):App Router里不再使用
next/router的useRouter,要改用next/navigation的同名钩子,且必须把用到它的部分拆成单独的客户端组件(这类API只能在客户端组件中调用)。 - 调整
Head使用(可选):App Router推荐用metadataAPI替代next/head,如果要继续使用Head也可以,但注意它在App Router中的用法差异。
修改后的代码示例
import Head from 'next/head'; import BlogSidebar from '../../components/blog/sidebar'; import Pagination from '../../components/blog/pagination'; import fs from 'fs'; import matter from 'gray-matter'; import { join } from 'path'; // 封装异步获取文章数据的逻辑 async function getPosts() { const blogsDirectory = join(process.cwd(), '_blog'); const files = fs.readdirSync(blogsDirectory); let posts = files.map((fileName) => { const slug = fileName.replace(/\.md$/, ''); const fullPath = join(blogsDirectory, `${slug}.md`); const readFile = fs.readFileSync(fullPath, 'utf8'); const { data: frontmatter } = matter(readFile); return { slug, frontmatter, }; }); posts = posts.sort((job1, job2) => (job1.frontmatter.date > job2.frontmatter.date ? -1 : 1)); return posts; } // 异步page组件(App Router支持异步服务器组件) export default async function Page() { const posts = await getPosts(); console.log(posts, "posts"); return ( <div> <Head> <title>博客列表页</title> </Head> <BlogSidebar /> <Pagination posts={posts} /> {/* 其他页面内容 */} </div> ); }
若需客户端交互(如路由跳转)
如果页面需要用到useRouter这类客户端API,不要把整个page设为客户端组件,而是拆出独立的客户端组件:
// components/blog/ClientNavigation.js "use client"; import { useRouter } from 'next/navigation'; export default function ClientNavigation() { const router = useRouter(); // 这里编写需要客户端路由的逻辑 return <button onClick={() => router.back()}>返回上页</button>; }
之后在服务器组件的page中直接导入并使用这个组件即可。
内容的提问来源于stack exchange,提问作者Prasan Kumar
相关产品推荐
相关产品推荐

