Next.js: Módulo não encontrado: não é possível resolver 'fs'

Criado em 5 jul. 2019  ·  13Comentários  ·  Fonte: vercel/next.js

Relatório de erro

Descreva o bug

Estou usando o popular pacote find-up npm, que tem o caminho de localização como uma dependência. locate-path requer fs em seu código.

Quando tento executar meu aplicativo, recebo a seguinte mensagem de erro:

[ error ] ./node_modules/locate-path/index.js
Module not found: Can't resolve 'fs' in 'C:\...\node_modules\locate-path'
Could not find files for /index in .next/build-manifest.json
Promise { <pending> }
ModuleNotFoundError: Module not found: Error: Can't resolve 'fs' in 'C:\...\node_modules\locate-path'
    at factory.create (C:\...\node_modules\webpack\lib\Compilation.js:823:10)
    at factory (C:\...\node_modules\webpack\lib\NormalModuleFactory.js:397:22)
    at resolver (C:\...\node_modules\webpack\lib\NormalModuleFactory.js:130:21)
    at asyncLib.parallel (C:\...\node_modules\webpack\lib\NormalModuleFactory.js:224:22)
    at C:\...\node_modules\neo-async\async.js:2830:7
    at C:\...\node_modules\neo-async\async.js:6877:13
    at normalResolver.resolve (C:\...\node_modules\webpack\lib\NormalModuleFactory.js:214:25)
    at doResolve (C:\...\node_modules\enhanced-resolve\lib\Resolver.js:184:12)
    at hook.callAsync (C:\...\node_modules\enhanced-resolve\lib\Resolver.js:238:5)
    at _fn0 (eval at create (C:\...\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:15:1)
    at resolver.doResolve (C:\...\node_modules\enhanced-resolve\lib\UnsafeCachePlugin.js:37:5)
    at hook.callAsync (C:\...\node_modules\enhanced-resolve\lib\Resolver.js:238:5)
    at _fn0 (eval at create (C:\...\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:15:1)
    at hook.callAsync (C:\...\node_modules\enhanced-resolve\lib\Resolver.js:238:5)
    at _fn0 (eval at create (C:\...\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:27:1)
    at resolver.doResolve (C:\...\node_modules\enhanced-resolve\lib\DescriptionFilePlugin.js:42:38)

Eu criei um problema no repositório de

Reproduzir

Clone https://github.com/TidyIQ/nextjs-issue e execute npm run dev .

Comportamento esperado

Sem problema

Informação do sistema

  • SO: Windows 10
  • Versão de Next.js: 8.1.1-canary.67

Comentários muito úteis

Atualização para Next.js moderno (9.4+)

Você pode usar fs com segurança em getStaticProps ou getServerSideProps , nenhuma configuração extra necessária . Certifique-se de estar referenciando a variável em seu ciclo de vida de dados para que sua árvore seja corretamente abalada.

Você pode usar esta ferramenta para aprender visualmente como funciona!

Se você ainda está construindo uma versão legada do Next.js com getInitialProps , leia abaixo 👇


O código fornecido não é válido - este arquivo nunca estaria disponível no lado do cliente durante a renderização:

https://github.com/TidyIQ/nextjs-issue/blob/aef67b12d91d299d0978550005a40cbb34f74b71/pages/index.js#L5

Lembre-se de que você só pode fazer operações relacionadas ao FS enquanto _no servidor_. Isso significa que você não pode usar fs durante a renderização.

Se você usar fs , certifique-se de que está dentro de getInitialProps .

Também pode ser necessário criar um arquivo next.config.js com o seguinte conteúdo para que o pacote do cliente seja compilado:

module.exports = {
  webpack: (config, { isServer }) => {
    // Fixes npm packages that depend on `fs` module
    if (!isServer) {
      config.node = {
        fs: 'empty'
      }
    }

    return config
  }
}

Todos 13 comentários

Atualização para Next.js moderno (9.4+)

Você pode usar fs com segurança em getStaticProps ou getServerSideProps , nenhuma configuração extra necessária . Certifique-se de estar referenciando a variável em seu ciclo de vida de dados para que sua árvore seja corretamente abalada.

Você pode usar esta ferramenta para aprender visualmente como funciona!

Se você ainda está construindo uma versão legada do Next.js com getInitialProps , leia abaixo 👇


O código fornecido não é válido - este arquivo nunca estaria disponível no lado do cliente durante a renderização:

https://github.com/TidyIQ/nextjs-issue/blob/aef67b12d91d299d0978550005a40cbb34f74b71/pages/index.js#L5

Lembre-se de que você só pode fazer operações relacionadas ao FS enquanto _no servidor_. Isso significa que você não pode usar fs durante a renderização.

Se você usar fs , certifique-se de que está dentro de getInitialProps .

Também pode ser necessário criar um arquivo next.config.js com o seguinte conteúdo para que o pacote do cliente seja compilado:

module.exports = {
  webpack: (config, { isServer }) => {
    // Fixes npm packages that depend on `fs` module
    if (!isServer) {
      config.node = {
        fs: 'empty'
      }
    }

    return config
  }
}

Eu tenho o mesmo problema na minha instalação local, praticamente vanilla, porém nos exemplos de nextjs isso não parece ser um problema
https://github.com/zeit/next.js/tree/5787cbd9de33ea9add7cadeb04689b0d4b02976d/examples/blog-starter

o que o faz funcionar sem modificar o arquivo de configuração?

Use apenas fs em getStaticProps / getServerSideProps, pois esses são eliminados do pacote do navegador.

Eu descobri qual era o problema. Se eu importar uma função que usa fs , mas não executar / usar a função dentro de getStaticProps, ela acabará sendo incluída no pacote do navegador. Assim que a função for referenciada dentro de getStaticProps, ela deixará de aparecer no pacote do navegador.

Acho que há alguma lógica oculta que remove as importações usadas em getStaticProps, mas não usadas na exportação principal. Passei algumas horas depurando até conseguir reproduzir, talvez valha a pena ter uma nota em algum lugar dos documentos :)

A lógica oculta não é apenas a árvore do webpack tremendo? Faz sentido quando você pensa nisso, Next não importa getStaticProps no pacote do navegador, então ele remove a função importada usada nele.

Se você não fizer referência a ele em nenhum lugar, acho que o webpack considera que você o importou para efeitos colaterais, então ele ainda o inclui em todos os pacotes.

A lógica oculta não é apenas a árvore do webpack tremendo? Faz sentido quando você pensa nisso, Next não importa getStaticProps no pacote do navegador, então ele remove a função importada usada nele.

Se você não fizer referência a ele em nenhum lugar, acho que o webpack considera que você o importou para efeitos colaterais, então ele ainda o inclui em todos os pacotes.

Não, o webpack tree shake não é sofisticado o suficiente para sacudir essas exportações dessa forma. A agitação da árvore getStaticProps / getServerSideProps / getStaticPaths é controlada por este plug-in Babel personalizado que criamos: https://github.com/vercel/next.js/blob/canary/packages/next/build/babel/plugins/next-ssg-transform .ts

Obrigado pelo ponteiro, parece que superestimei o webpack :)

Há algum motivo para isso estar acontecendo em _dentro_ de getServerSideProps ?

Olá a todos. Como @aloukissas , tenho o mesmo problema ao usar dotenv em meu index.js getStaticProps() . Isso é resolvido ao adicionar o arquivo next.config.js conforme mostrado no comentário inicial do @Timer .

Alguma pista de por que isso está acontecendo? Estou cancelando Next.js v.9.4.0

Obrigado!

Eu tive este erro ao usar fast-glob .

Usei essa ótima ferramenta para entender o código que é empacotado no lado do cliente.

Acontece que eu estava importando uma variável de um arquivo que usa fast-glob que usa internamente fs mas não estava usando a variável em nenhum lugar dentro de getStaticProps então os arquivos importam fast-glob não estavam sendo eliminados.

Um exemplo:

mdxUtils.js

import glob from 'fast-glob'
import path from 'path'

export const BLOG_PATH = path.join(process.cwd(), 'posts')
export const blogFilePaths = glob.sync(`${BLOG_PATH}/blog/**/*.mdx`)

index.js

import { BLOG_PATH, blogFilePaths } from './mdxUtils'

export const getStaticProps = () => {
  const posts = blogFilePaths.map((filePath) => {
    ...
  }
  return { props: { posts } }
}

Como você pode ver, não estou usando BLOG_PATH em nenhum lugar em index.js mas ainda estou importando. Estou usando apenas blogFilePaths então ocorreu este erro.

Para mais contexto → https://github.com/vercel/next.js/discussions/17138

Obrigado @ deadcoder0904 este é o meu código:

import Layout from '../components/template'
import Main from '../components/main'
import Menu from '../components/menu'
import 'dotenv/config'

export async function getStaticProps () {
  const avatarLocation = process.env.AVATAR_URL
  const avatarTitle = process.env.AVATAR_TITLE

  return {
    props: {
      avatarLocation,
      avatarTitle
    }
  }
}

export default function RenderMainPage ({ avatarLocation, avatarTitle }) {
  return (
    <Layout
      avatarURL={avatarLocation}
      topLeft={<Menu />}
      middle={<Main avatarURL={avatarLocation} avatarTitle={avatarTitle} />}
    />
  )
}

A ferramenta que você mencionou mostra que import 'dotenv/config' está incluído no código do cliente e provavelmente é isso que está fazendo o erro aparecer. O fato é que preciso ler as variáveis ​​env.

Provavelmente há outra maneira melhor de fazer isso, ainda estou aprendendo Next.js :)

@ ig-perez A partir da Próxima v9.4, eles têm uma maneira integrada de carregar variáveis ​​de ambiente → https://nextjs.org/docs/basic-features/environment-variables

Eu sugiro que você leia a documentação para encontrar a solução :)

Isso é incrível, eu perdi essa parte da documentação, obrigado! Vou atualizar meu código 👍🏽

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

kenji4569 picture kenji4569  ·  3Comentários

knipferrc picture knipferrc  ·  3Comentários

jesselee34 picture jesselee34  ·  3Comentários

renatorib picture renatorib  ·  3Comentários

formula349 picture formula349  ·  3Comentários