未找到模块:无法在 Next.js 应用程序中解析“fs”
Posted
技术标签:
【中文标题】未找到模块:无法在 Next.js 应用程序中解析“fs”【英文标题】:Module not found: Can't resolve 'fs' in Next.js application 【发布时间】:2021-03-03 16:11:35 【问题描述】:无法确定我的 next.js 应用中发生了什么。因为 fs 是 nodejs 的默认文件系统模块。它给出了module not found的错误。
【问题讨论】:
删除node_modules
文件夹后尝试新的npm install
正如@AjitZero 所说,这将是问题所在。您也可以删除 package-lock.json
并运行 npm cache clean
然后 npm install
我删除了 node_modules 和 package-lock.json ,然后删除了 npm cache clean 和 npm install ...但仍然出现同样的错误。
你不能在浏览器中使用 fs 模块,它是一个 nodejs 模块。
【参考方案1】:
如果您使用fs
,请确保它仅在getInitialProps
或serverSideProps
内。 (包括服务器端渲染)。
您可能还需要创建一个包含以下内容的next.config.js
文件来构建客户端包:
对于webpack4
module.exports =
webpack: (config, isServer ) =>
// Fixes npm packages that depend on `fs` module
if (!isServer)
config.node =
fs: 'empty'
return config
对于webpack5
module.exports =
webpack5: true,
webpack: (config) =>
config.resolve.fallback = fs: false ;
return config;
,
;
注意:对于其他模块如path
,可以添加多个参数如
fs: false,
path: false
【讨论】:
这很好,但future: webpack5: true
应该像webpack5: true
一样位于顶层。谢谢!
好的,@AustinWitherow。让我检查并更新答案。谢谢指正。
黄金答案!只是我还必须在fs: false
之后添加path: false
。
当问题仅针对fs
提出时,@JusticeBringer。我可能无法添加代码,但让我将其添加为注释。【参考方案2】:
最小的可重现示例
一个简洁的最小示例将有利于 Webpack 初学者,因为基于使用的自动拆分是如此令人兴奋的魔法。
工作你好世界基线:
pages/index.js
// Client + server code.
export default function IndexPage(props)
return <div>props.msg</div>
// Server-only code.
export function getStaticProps()
return props: msg: 'hello world'
package.json
"name": "test",
"version": "1.0.0",
"scripts":
"dev": "next",
"build": "next build",
"start": "next start"
,
"dependencies":
"next": "12.0.7",
"react": "17.0.2",
"react-dom": "17.0.2"
运行:
npm install
npm run dev
现在让我们添加一个虚拟require('fs')
来炸毁它:
// Client + server code.
export default function IndexPage(props)
return <div>props.msg</div>
// Server-only code.
const fs = require('fs')
export function getStaticProps()
return props: msg: 'hello world'
失败:
Module not found: Can't resolve 'fs'
这并不奇怪,因为 Next.js 无法知道 fs
只是服务器,我们不希望它只是忽略随机的 require 错误,对吧? Next.js 只知道getStaticProps
,因为那是一个硬编码的 Next.js 函数名称。
好的,让我们通过在getStaticProps
中使用fs
来通知Next.js,以下再次起作用:
// Client + server code.
export default function IndexPage(props)
return <div>props.msg</div>
// Server-only code.
const fs = require('fs')
export function getStaticProps()
fs
return props: msg: 'hello world'
头脑等于炸毁。所以我们知道,在 getStaticProps
的正文中提到 fs
,即使是像上面这样无用的,也会让 Next.js/Webpack 明白它将是仅限服务器的。
getServerSideProps
和 getStaticPaths
的情况相同。
高阶组件 (HOC) 必须位于它们自己的文件中
现在,我们在不同但相似的页面中分解IndexPage
和getStaticProps
的方法是使用HOC,它们只是返回其他函数的函数。
HOC 通常会放在pages/
之外,然后在多个位置都需要,但是当您要考虑因素以进行概括时,您可能会想暂时将它们直接放在pages/
文件中,例如:
// Client + server code.
import Link from 'next/link'
export function makeIndexPage(isIndex)
return (props) =>
return <>
<Link href=isIndex ? '/index' : '/notindex'>
<a>isIndex ? 'index' : 'notindex'</a>
</Link>
<div>props.fs</div>
<div>props.isBlue</div>
</>
export default makeIndexPage(true)
// Server-only code.
const fs = require('fs')
export function makeGetStaticProps(isBlue)
return () =>
return props:
fs: Object.keys(fs).join(' '),
isBlue,
export const getStaticProps = makeGetStaticProps(true)
但如果你这样做,你会很难过:
Module not found: Can't resolve 'fs'
所以我们明白了另一件事:fs
的用法必须直接在 getStaticProps
函数体内,Webpack 无法在子函数中捕获它。
解决此问题的唯一方法是为仅后端的内容创建一个单独的文件,如下所示:
pages/index.js
// Client + server code.
import makeIndexPage from "../front"
export default makeIndexPage(true)
// Server-only code.
import makeGetStaticProps from "../back"
export const getStaticProps = makeGetStaticProps(true)
pages/notindex.js
// Client + server code.
import makeIndexPage from "../front"
export default makeIndexPage(false)
// Server-only code.
import makeGetStaticProps from "../back"
export const getStaticProps = makeGetStaticProps(false)
front.js
// Client + server code.
import Link from 'next/link'
export function makeIndexPage(isIndex)
return (props) =>
console.error('page');
return <>
<Link href=isIndex ? '/notindex' : '/'>
<a>isIndex ? 'notindex' : 'index'</a>
</Link>
<div>props.fs</div>
<div>props.isBlue</div>
</>
back.js
// Server-only code.
const fs = require('fs')
export function makeGetStaticProps(isBlue)
return () =>
return props:
fs: Object.keys(fs).join(' '),
isBlue,
Webpack 必须看到名称 makeGetStaticProps
被分配给 getStaticProps
,因此它决定整个 back
文件是服务器专用的。
请注意,如果您尝试将 back.js
和 front.js
合并到一个文件中,则它不起作用,可能是因为当您这样做时,export default makeIndexPage(true)
webpack 必然会尝试将整个 front.js
文件拉入前端,这包括 fs,所以它失败了。
这导致库文件在以下之间自然拆分:
front.js
和 front/*
:前端 + 后端文件。这些对前端来说是安全的。后端可以做前端可以做的任何事情(我们正在做 s-s-r 对吗?)所以这些也可以从后端使用
back.js
和 back/*
(或者front/*
之外的任何内容):仅后端文件。这些只能后端使用,在前端导入会报错
【讨论】:
【参考方案3】:fs
,path
或其他节点原生模块只能在服务器端代码中使用,例如“getServerSide”函数。如果您尝试在客户端使用它,即使您只是 console.log 也会出现错误。console.log 也应该在服务器端函数中运行。
当您导入“fs”并在服务器端使用它时,next.js 足够聪明,可以看到您在服务器端使用它,因此它不会将该导入添加到客户端包中
我使用的一个包给了我这个错误,我用这个修复了这个
module.exports =
webpack: (config, isServer ) =>
if (!isServer)
config.resolve.fallback.fs = false
return config
,
但这会在终端上引发警告:
"Critical dependency: require function is used in a way in which
dependencies cannot be statically extracted"
然后我尝试在浏览器上加载节点模块。我从node_modules复制了节点模块的“min.js”并放在“public/js/myPackage.js”中并用脚本加载它
export default function BaseLayout(children)
return (
<>
<Script
// this in public folder
src="/js/myPackage.js"
// this means this script will be loaded first
strategy="beforeInteractive"
/>
</>
)
这个包被附加到window
对象和node_modules源代码的index.js中:
if (typeof window !== "undefined")
window.TruffleContract = contract;
所以我可以以window.TruffleContract
的身份访问此脚本。但这不是一种有效的方法。
【讨论】:
【参考方案4】:您尝试实现的模块可能不应该在浏览器中运行。 IE。它只是服务器端的。
【讨论】:
为什么这是一个经过验证的答案,而它甚至不是一个答案? @asma 首先,*** 上没有什么比“经过验证的答案”更好的了。其次,OP 接受了这个答案而不是 ArjunKava 的答案,因为后者是在他们提出问题 6 个月后发布的,并且从那时起就不太在意接受更好的答案。此外,这是一个完全有效的推理。如果在客户端代码中使用,仅服务器包可以并且确实会导致此类问题。 PS:在过时的答案更新后,此答案不再固定在顶部,因此它不应该成为问题,因为这是帮助 OP when 他们需要的答案,因此是被接受的答案。 @asma 它提供了问题的答案并被 OP 接受。它可能不会像耶尔马兹的回答那样详细解决问题,但它在技术上没有任何问题。 “经过验证的答案”不是一回事,OP 接受对他们有用的答案。【参考方案5】:帮我清除缓存 npm 缓存清理 -f
然后将节点版本更新到最新的稳定版本(14.17.0)工作
【讨论】:
【参考方案6】:我的 NextJS 应用程序出现此错误,因为我在中缺少 export
export function getStaticProps()
【讨论】:
我有一个相关的错误,但是我拼错了 getServerSideProps 所以我使用了 fs 模块客户端。一个容易犯的错误!【参考方案7】:我在这上面花了几个小时,解决方案也在 *** 上,但在不同的问题上 -> https://***.com/a/67478653/17562602
在此我请求 MOD 许可转发此问题,因为此问题是第一个出现在 Google 上的问题,可能越来越多的人会偶然发现与我相同的问题,所以我会尝试为他们保存一些出汗
Soo,你需要在你的 next.config.js 中添加这个
module.exports =
future:
webpack5: true, // by default, if you customize webpack config, they switch back to version 4.
// Looks like backward compatibility approach.
,
webpack(config)
config.resolve.fallback =
...config.resolve.fallback, // if you miss it, all the other options in fallback, specified
// by next.js will be dropped. Doesn't make much sense, but how it is
fs: false, // the solution
;
return config;
,
;
它对我来说就像一个魅力
【讨论】:
【参考方案8】:对我来说,问题是安装了旧版本的 node.js。它需要 node.js 版本 14 及更高版本。解决方案是转到 node.js 网页,下载最新版本并安装它。然后重新运行项目。一切正常!
【讨论】:
当我尝试使用节点 14 构建时它对我不起作用。【参考方案9】:我在尝试使用 babel 时遇到了同样的问题。
对我来说这很有效:
#将.babelrc
文件添加到项目的根目录并定义预设和插件
(在我的例子中,我对 babel 的宏有一些问题,所以我定义了它们)
"presets": ["next/babel"],
"plugins": ["macros"]
然后关闭您的服务器并再次运行它
【讨论】:
【参考方案10】:我有这个确切的问题。我的问题是我正在导入我在 types.d.ts
文件中声明的类型。
感谢 VSCode 提供的自动填充功能,我是这样导入的。
import CUSTOM_TYPE from './types'
应该是这样的:
import CUSTOM_TYPE from './types.d'
就我而言,我认为.d
是不必要的,所以我最终将其完全删除并将我的文件重命名为types.ts
。
很奇怪,它被直接导入index.tsx
没有问题,但src
目录中的任何帮助文件/函数都会给我错误。
【讨论】:
【参考方案11】:如果尝试在 Next.js 中使用 fs-extra,这对我有用
module.exports =
webpack: (config) =>
config.resolve.fallback = fs: false, path: false, stream: false, constants: false ;
【讨论】:
以上是关于未找到模块:无法在 Next.js 应用程序中解析“fs”的主要内容,如果未能解决你的问题,请参考以下文章
Storybook 在 React、Next.JS、Typescript 项目中找不到组件
“未找到模块:错误:无法解析模块”错误在 signrequest-client 角度
Next.js:模块构建失败:错误:无法从“/home/ugurkaya/Desktop”中找到模块“react-hot-loader/babel”