sourcetip

모듈을 찾을 수 없습니다.Next.js 응용 프로그램에서 'fs'를 확인할 수 없습니다.

fileupload 2023. 3. 4. 15:08
반응형

모듈을 찾을 수 없습니다.Next.js 응용 프로그램에서 'fs'를 확인할 수 없습니다.

next.js 앱에서 무슨 일이 일어나고 있는지 알 수 없습니다.fs는 nodejs의 기본 파일 시스템 모듈입니다.module not found(모듈을 찾을 수 없습니다)라는 에러가 나타난다.

여기에 이미지 설명 입력

여기에 이미지 설명 입력

「 」를 사용하고 fs(서버측 렌더링을 포함한 모든 것이) 또는 에만 있는지 확인합니다.

'아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아.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
}

몇 시간 동안 이 문제에 대해 설명했습니다.솔루션도 Stackoverflow에 있습니다만, 다른 문제에 대해 설명하고 있습니다.-> https://stackoverflow.com/a/67478653/17562602

이 문제가 구글에 처음 등장하고, 아마 더 많은 사람들이 저와 같은 문제에 직면할 것이기 때문에, 저는 그들에게 약간의 수고를 덜기 위해 노력하겠습니다.

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;
  },
};

그것은 나에게 부적처럼 작용한다.

재현 가능한 최소 예제

사용량에 따른 자동 분할은 매우 놀라운 마법이기 때문에 깔끔한 최소한의 예는 웹 팩 초보자들에게 도움이 될 것입니다.

작업 hello 월드 기준선:

페이지/인덱스.인덱스

// Client + server code.

export default function IndexPage(props) {
  return <div>{props.msg}</div>
}

// Server-only code.

export function getStaticProps() {
  return { props: { msg: 'hello world' } }
}

패키지.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가 Next.js가 Next.js가 Next.js라는 알 수 있는 방법이 때문에 것은 .fs서버뿐입니다.또한 랜덤 요구 오류를 무시하지 않도록 해야 합니다.next는 Next.js에 대해서만 .getStaticProps[Next.js] (다음).js) [Next.js] (다음.js) [Next.js] (다음).

Next.js를 하여 Nextfs에 inside inside inside getStaticProps , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

// 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' } }
}

격도도마마마마마그래서 우리는 이 사건에 대한 어떤 언급도fsgetStaticPropsNext.js/Webpack은 위와 같이 쓸모없는 것이라도 서버 전용이라는 것을 이해시킵니다.

에 대해서도 마찬가지입니다.getServerSideProps ★★★★★★★★★★★★★★★★★」getStaticPaths.

상위 컴포넌트(HOC)는 자체 파일에 있어야 함

요,그러면요.IndexPage ★★★★★★★★★★★★★★★★★」getStaticProps서로 다르지만 유사한 페이지에 걸쳐 HOC를 사용하는 것입니다.HOCK를 사용하다

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함수 본문, 웹 팩이 하위 함수에서 이를 포착할 수 없습니다.

이 문제를 해결하는 유일한 방법은 다음과 같이 백엔드 전용 파일을 따로 만드는 것입니다.

페이지/인덱스.인덱스

// 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.displaces

// Client + server code.

import { makeIndexPage } from "../front"

export default makeIndexPage(false)

// Server-only code.

import { makeGetStaticProps } from "../back"

export const getStaticProps = makeGetStaticProps(false)

front.front.flash

// 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.filength를 클릭합니다.

// Server-only code.

const fs = require('fs')

export function makeGetStaticProps(isBlue) {
  return () => {
    return { props: {
      fs: Object.keys(fs).join(' '),
      isBlue,
    } }
  }
}

에는 이 .makeGetStaticProps, 당당에 할당getStaticProps 는 이 명령어를 통해 back파일은 서버 전용입니다.

합치려고 에 주의해 주세요.back.js ★★★★★★★★★★★★★★★★★」front.js할 수 1열로 1열로 정리할 수 있어요.아마도 그렇게 할 때export default makeIndexPage(true) 팩은 웹 팩 .front.js을 저장하기 때문에 fs 포 、 fs 、 file 、 file file file file file file 。

이것에 의해, 다음의 사이에 라이브러리 파일의 자연스러운 분할(기본적으로는 거의 필수)이 발생합니다.

  • front.js ★★★★★★★★★★★★★★★★★」front/*엔드 + 파일 + 드드런런 。이치노또한 백엔드는 프런트엔드가 할 수 있는 모든 작업을 수행할 수 있기 때문에(SSR는 제대로 하고 있습니까?), 백엔드에서도 사용할 수 있습니다.

    아마도 이것이 많은 공식 사례에서 기존의 "구성 요소" 폴더 뒤에 있는 아이디어일 것입니다.그러나 이 폴더에는 컴포넌트뿐만 아니라 프론트 엔드에서 사용되는 라이브러리 비컴포넌트 도우미/정수도 포함되어 있어야 하기 때문에 이는 잘못된 이름입니다.

  • back.js ★★★★★★★★★★★★★★★★★」back/* (외부)의 것)front/* 파일: 「 」입니다.할 수 합니다.수입하다

fs ,path또는 기타 노드 네이티브 모듈은 "getServerSide" 함수 등 서버측 코드 내에서만 사용할 수 있습니다.클라이언트에서 사용하려고 하면 console.log만 해도 오류가 발생합니다."console.log" 입니다.

fs를 Import하여 서버측에서 사용하는 경우 next.js는 서버측에서 사용하는 것을 알 수 있기 때문에 Import가 클라이언트번들에 추가되지 않습니다.

사용하던 패키지 중 하나가 에러를 표시해, 이 에러를 수정했습니다.

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_model" "index.model" :

if (typeof window !== "undefined") {
  window.TruffleContract = contract;
}

그래서 이 스크립트에 접속할 수 있습니다.window.TruffleContract하지만 이것은 효율적인 방법이 아니었다.

이 오류는 발생하는 대부분의 오류보다 약간 더 많은 추론을 필요로 하지만, 이는 단순한 이유로 발생합니다.

왜 이런 일이 일어나는지

next.js는 많은 프레임워크와 달리 서버 전용(브라우저에서 동작하지 않는 Node.js API) 코드를 페이지 파일로 Import할 수 있습니다.Next.js는 프로젝트를 빌드할 때 다음하나의 내장 메서드(코드 분할)에 어떤 코드가 있는지 체크함으로써 클라이언트 측 번들에서 서버 전용 코드를 삭제합니다.

  • getServerSideProps
  • getStaticProps
  • getStaticPaths

참고: 이 기능을 시각화하는 데모 앱이 있습니다.

Module not found: can't resolve 'xyz'이러한 메서드 이외의 서버 전용 코드를 사용하려고 하면 에러가 발생합니다.

오류 예 1 - 기본

이 오류를 재현하려면 간단한 Next.js 페이지 파일부터 시작합니다.

작업 파일

/** THIS FILE WORKS FINE! */

import type { GetServerSideProps } from "next";

import fs from "fs"; // our server-only import

type Props = {
  doesFileExist: boolean;
};

export const getServerSideProps: GetServerSideProps = async () => {
  const fileExists = fs.existsSync("/some-file"); 

  return {
    props: {
      doesFileExist: fileExists,
    },
  };
};

const ExamplePage = ({ doesFileExist }: Props) => {
  return <div>File exists?: {doesFileExist ? "Yes" : "No"}</div>;
};

export default ExamplePage;

이번에는 틀리다, 틀리다, 틀리다를 fs.existsSync이외의 방법getServerSideProps차이는 미묘하지만, 아래 코드는 우리의 두려움을 던져줄 것이다.Module not found

오류 파일

import type { GetServerSideProps } from "next";
import fs from "fs";

type Props = {
  doesFileExist: boolean;
};

/** ERROR!! - Module not found: can't resolve 'fs' */
const fileExists = fs.existsSync("/some-file");

export const getServerSideProps: GetServerSideProps = async () => {
  return {
    props: {
      doesFileExist: fileExists,
    },
  };
};

const ExamplePage = ({ doesFileExist }: Props) => {
  return <div>File exists?: {doesFileExist ? "Yes" : "No"}</div>;
};

export default ExamplePage;

오류 예 2 - 현실적

이 에러의 가장 일반적인(그리고 혼란스러운) 발생은, 복수의 타입의 코드(클라이언트측+서버측)를 포함한 모듈을 사용하고 있는 경우에 발생합니다.

'하다'라는 요.file-utils.ts:

import fs from 'fs'

// This code only works server-side
export function getFileExistence(filepath: string) {
  return fs.existsSync(filepath)
}

// This code works fine on both the server AND the client
export function formatResult(fileExistsResult: boolean) {
  return fileExistsResult ? 'Yes, file exists' : 'No, file does not exist'
}

이 모듈에서는 이론적으로는 클라이언트 측에서 동작해야 하는 서버 전용 방식과 "공유" 방식이 각각1개씩 있습니다(다만, 이론적으로는 완벽하지 않습니다).

이제 이것을 Next.js 페이지 파일에 통합해 보겠습니다.

/** ERROR!! */

import type { GetServerSideProps } from "next";

import { getFileExistence, formatResult } from './file-utils.ts'

type Props = {
  doesFileExist: boolean;
};

export const getServerSideProps: GetServerSideProps = async () => {
  return {
    props: {
      doesFileExist: getFileExistence('/some-file')
    },
  };
};

const ExamplePage = ({ doesFileExist }: Props) => {

  // ERROR!!!
  return <div>File exists?: {formatResult(doesFileExist)}</div>;
};

export default ExamplePage;

가 발생합니다. as as as as를 formatResult클라이언트 측에서는 모듈이 서버코드를 Import해야 합니다.

이 문제를 해결하려면 모듈을 2개의 카테고리로 분할해야 합니다.

  1. 서버만
  2. 공유 코드(클라이언트 또는 서버)
// file-utils.ts

import fs from 'fs'

// This code (and entire file) only works server-side
export function getFileExistence(filepath: string) {
  return fs.existsSync(filepath)
}
// file-format-utils.ts

// This code works fine on both the server AND the client
export function formatResult(fileExistsResult: boolean) {
  return fileExistsResult ? 'Yes, file exists' : 'No, file does not exist'
}

이제 WORKING 페이지 파일을 만들 수 있습니다.

/** WORKING! */

import type { GetServerSideProps } from "next";

import { getFileExistence } from './file-utils.ts' // server only
import { formatResult } from './file-format-utils.ts' // shared

type Props = {
  doesFileExist: boolean;
};

export const getServerSideProps: GetServerSideProps = async () => {
  return {
    props: {
      doesFileExist: getFileExistence('/some-file')
    },
  };
};

const ExamplePage = ({ doesFileExist }: Props) => {
  return <div>File exists?: {formatResult(doesFileExist)}</div>;
};

export default ExamplePage;

솔루션

이 문제를 해결하려면 다음 두 가지 방법이 있습니다.

  1. 올바른 방법
  2. "그냥 작동"하는 방법

"올바른' 방법

이 에러를 해결하는 가장 좋은 방법은, 이 에러가 발생하고 있는 이유를 이해하고 있는 것(상기)을 확인해, 서버측의 코드만을 사용하고 있는 것, 또는 그 외의 것은 사용하고 있지 않은 을 확인하는 것입니다.

또한 서버 측 코드와 클라이언트 측 코드를 모두 포함하는 모듈을 Import할 경우 해당 모듈클라이언트 측에서의 Import는 사용할 수 없습니다(위의 예 2 참조).

"Just get it facting" (그냥 작동

처럼 ' 수 있다', ' 수 있다', '바꿀 수 ' 이렇게 할 수.next.config.js특정 모듈을 무시합니다.즉, Next.js가 페이지 파일을 서버 전용과 공유 코드 에 분할하려고 할 때 클라이언트 측 구축에 실패한 Node.js API를 폴리필하려고 하지 않습니다.

이 경우 필요한 것은 다음과 같습니다.

/** next.config.js - with Webpack v5.x */
module.exports = {

  ... other settings ... 

  webpack: (config, { isServer }) => {
    
    // If client-side, don't polyfill `fs`
    if (!isServer) {
      config.resolve.fallback = {
        fs: false,
      };
    }

    return config;
  },

};

이 접근법의 결점

Webpack 문서의 resolve.fallback 섹션에 나타나 있듯이 이 설정 옵션의 주된 이유는 현재 Webpack이 원인입니다.v5.x코어 Node.js 모듈은 디폴트로 폴리필이 되지 않게 되었습니다.따라서 이 옵션의 주요 목적은 사용할 폴리필을 정의하는 방법을 제공하는 것입니다.

할 때false옵션으로서 "폴리필을 포함하지 않음"을 의미합니다.

이 방법은 작동하지만 취약할 수 있으며 프로젝트에 도입하는 모든 새 모듈을 포함하기 위해 지속적인 유지보수가 필요할 수 있습니다.기존 프로젝트/지원 레거시 코드를 변환하지 않는 한 Next.js가 실제로 코드를 분할하는 방법에 따라 모듈 구성이 개선되므로 위의 옵션 #1을 선택하는 것이 좋습니다.

Next.js에서 fs-extra를 사용하려고 하면 이 방법이 효과가 있었습니다.

module.exports = {
  webpack: (config) => {
    config.resolve.fallback = { fs: false, path: false, stream: false, constants: false };
    return config;

  }
}

NextJs 에서 NextJs가 하였습니다.export

export function getStaticProps()
/** @type {import('next').NextConfig} */
module.exports = {
  reactStrictMode: false,
  webpack5: true,
  webpack: (config) => {
    config.resolve.fallback = {
      fs: false,
      net: false,
      dns: false,
      child_process: false,
      tls: false,
    };

    return config;
  },
};

이 코드로 문제가 해결되어 공유하겠습니다.이 코드를 next.config 파일에 추가합니다.사용하고 있다

웹 팩 5

캐시 npm clean -f를 지웁니다.

노드 버전을 최신 안정 릴리스(14.17.0)로 업데이트했습니다.

구현하려는 모듈이 브라우저에서 실행되지 않도록 되어 있을 수 있습니다.즉, 서버측에서만 사용할 수 있습니다.

문제는 설치된 node.js의 이전 버전입니다.node.js 버전 14 이후가 필요합니다.해결방법은 node.js 웹페이지에 접속하여 최신 버전을 다운로드하여 설치하는 것이었습니다.그리고 나서 프로젝트를 다시 실행합니다.다 됐어!

바벨을 쓰려고 할 때도 같은 문제가 있었어요.

저는 이 방법이 효과가 있었습니다.

a # a 가 a 、.babelrc 프로젝트의 루트로 파일을 전송하여 프리셋과 플러그인을 정의합니다(경우 babel 매크로에 문제가 있어 정의했습니다).

{
    "presets": ["next/babel"],
    "plugins": ["macros"]
}

그 후 서버를 셧다운하고 다시 실행합니다.

정확히 이런 문제가 있었어요.는 '수입하다'에서이었습니다.types.d.tsfilename을 클릭합니다.

VSCode에서 제공하는 autofill 덕분에 이렇게 수입했습니다.

import {CUSTOM_TYPE} from './types'

다음과 같이 해야 합니다.

import {CUSTOM_TYPE} from './types.d'

....d하고 파일 을 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★types.ts.

.index.tsx단, '도움말 파일/의 도우미 파일/src이치노

nextJS 어플리케이션에서는 getServerSideProps() 바로 아래에 새로운 도우미 함수를 정의했지만 getServerSideProps() 내에서 아직 해당 함수를 호출하지 않았기 때문에 이 함수는 실행되었습니다.

이게 왜 문제를 일으켰는지 모르겠지만, 문제가 생겼어요.그 기능을 호출하거나 삭제하거나 주석을 달아야만 작동할 수 있었습니다.

마세요fs pages next., next.directory, next.directory, next.directory, next.directory, next.directory, next.directory, next.에 파일들이pages디렉토리가 브라우저 환경에서 실행되고 있습니다.

에는 util을 사용할 수 .fs예:/core

★★★★★★★★★★★★★★★.require in the .getStaticPropsenvironment.node.node.는 node.

// /pages/myPage/index.tsx
import View from './view';
export default View;

export async function getStaticProps() {
  const util = require('core/some-util-uses-fs').default; // getStaticProps runs in nodes
  const data = await util.getDataFromDisk();
  return {
    props: {
      data,
    },
  };
}

제 경우 Next.js 페이지의 인증 플로우를 리팩터링할 때 이 오류가 발생하였습니다.원인은 아직 제거하지 않은 미사용 수입품입니다.

이전에는 다음과 같이 페이지를 보호 경로로 설정했습니다.

export async function getServerSideProps ({ query, req, res }) {
  const session = await unstable_getServerSession(req, res, authOptions)
  if (!session) {
    return {
      redirect: {
        destination: '/signin',
        permanent: false,
      },
    }
  }
//... rest of server-side logic
}

리팩터링 중에 NextAuth useSession을 읽었습니다.거기서 읽은 내용에 근거해, 실장을 변경할 수 있었습니다.그 때문에, 간단하게 추가할 필요가 있었습니다.MyComponent.auth = true페이지를 보호하도록 설정합니다. 앞서 코드 했습니다.getServerSideProps그러나, 나는 아직 해당 코드 블록에 사용된 2개의 Import를 삭제하지 않았다.

import { unstable_getServerSession } from 'next-auth/next'
import { authOptions } from 'pages/api/auth/[...nextauth]'

나는 그 두 수입품 중 두 번째가 문제의 원인이었다고 생각한다.즉, 위의 모든 훌륭한 답변과 더불어 사용되지 않은 Import일 수도 있습니다.

이 에러는, Import는 했지만, 어느 곳에서도 마스터 할 수 없는 것이 원인일 수 있습니다.이건 나한테 효과가 있었어.코드를 확인하고 사용되지 않는 종속성을 제거했습니다.

언급URL : https://stackoverflow.com/questions/64926174/module-not-found-cant-resolve-fs-in-next-js-application

반응형