未找到模块:无法在 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,请确保它仅在getInitialPropsserverSideProps 内。 (包括服务器端渲染)。

您可能还需要创建一个包含以下内容的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 明白它将是仅限服务器的。

getServerSidePropsgetStaticPaths 的情况相同。

高阶组件 (HOC) 必须位于它们自己的文件中

现在,我们在不同但相似的页面中分解IndexPagegetStaticProps 的方法是使用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.jsfront.js 合并到一个文件中,则它不起作用,可能是因为当您这样做时,export default makeIndexPage(true) webpack 必然会尝试将整个 front.js 文件拉入前端,这包括 fs,所以它失败了。

这导致库文件在以下之间自然拆分:

front.jsfront/*:前端 + 后端文件。这些对前端来说是安全的。后端可以做前端可以做的任何事情(我们正在做 s-s-r 对吗?)所以这些也可以从后端使用 back.jsback/*(或者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 项目中找不到组件

Next.js:找不到模块:无法解析“canvg”

“未找到模块:错误:无法解析模块”错误在 signrequest-client 角度

未找到模块:错误:无法使用 Webpack 解析“fs”

未找到模块:无法解析“

Next.js:模块构建失败:错误:无法从“/home/ugurkaya/Desktop”中找到模块“react-hot-loader/babel”