NextJS使用getStaticProps读取本地文件报Can't resolve 'fs'错误如何解决
问题解决说明
首先明确:所有版本的NextJS均支持在服务端执行逻辑中读取本地JSON文件,你遇到的报错和功能支持无关,核心原因是包含fs引用的代码被打包到了客户端侧,浏览器环境不存在fs模块。
问题根因
你新搭建的项目大概率使用了NextJS 13+的App Router架构,而App Router已经废弃了getStaticProps语法,NextJS不会将你写的getStaticProps识别为仅服务端执行的代码,会把整个页面组件的代码都纳入客户端打包范围,自然会触发fs模块找不到的报错。
解决方案
分两种架构场景处理:
场景1:使用App Router(项目根目录存在app文件夹)
完全不需要写getStaticProps,直接利用App Router默认的服务端组件特性读取数据即可:
- 安装
server-only包,确保服务端代码不会被意外打包到客户端:
npm install server-only
- 在你的
readData.ts文件顶部引入该包:
import 'server-only' import { promises as fs } from "fs"; import path from "path"; // 原有代码保持不变 const readData = async(dir: string) => { const dataDirectory = path.join(process.cwd(), dir); const filenames = await fs.readdir(dataDirectory); const dataItems = filenames.map(async(filename) => { const filePath = path.join(dataDirectory, filename); const fileContents = await fs.readFile(filePath, "utf8"); const parsedItem = JSON.parse(fileContents); return parsedItem; }); return { data: await Promise.all(dataItems), }; }; export default readData;
- 调整页面代码,删除
getStaticProps,直接在异步服务端组件中调用读取逻辑:
import { FC } from "react"; import { Props } from "./types"; import readData from "../../../lib/api/readData"; const notebookPath = "notebooks"; // App Router默认是服务端组件,直接异步调用即可 const Home: FC<Props> = async () => { const notebookData = await readData(`/data/${notebookPath}`); const notebook = notebookData?.data; const props = { notebook, hallo: ["nice"], } console.log("Home props", props); return <h1>This is the rendering</h1>; }; export default Home;
- 清空你之前在
next.config.js中添加的所有webpack相关配置,这些都是过时的无效配置,反而会干扰NextJS的默认打包逻辑。
场景2:使用Page Router(项目根目录存在pages文件夹)
- 同样安装
server-only包,在readData.ts顶部引入。 - 检查全项目是否有除了
getStaticProps之外的位置导入了readData,如果有移除相关引用。 - 删除
next.config.js中所有webpack相关配置即可。
简化方案
如果你不需要动态读取目录下的所有JSON文件,也可以直接通过ES模块导入语法引入JSON文件,NextJS原生支持该特性,不需要额外配置:
import notebookData from '/data/notebooks/xxx.json'
内容的提问来源于stack exchange,提问作者Gutelaunetyp
相关产品推荐
相关产品推荐

