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
Clone https://github.com/TidyIQ/nextjs-issue e execute npm run dev
.
Sem problema
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:
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:
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`)
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 👍🏽
Comentários muito úteis
Atualização para Next.js moderno (9.4+)
Você pode usar
fs
com segurança emgetStaticProps
ougetServerSideProps
, 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 degetInitialProps
.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: