Next.js: Module introuvable : impossible de résoudre 'fs'

Créé le 5 juil. 2019  ·  13Commentaires  ·  Source: vercel/next.js

Rapport d'erreur

Décrivez le bogue

J'utilise le populaire package npm find-up , qui a locate-path en tant que dépendance. locate-path requiert fs dans son code.

Lorsque j'essaie d'exécuter mon application, le message d'erreur suivant s'affiche :

[ 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)

J'ai créé un problème dans le référentiel locate-path et ils ont confirmé que le problème ne les concernait pas, mais probablement avec webpack. Je n'utilise pas webpack dans mon application, le problème doit donc provenir de l'utilisation de webpack par Next.js.

Reproduire

Clonez https://github.com/TidyIQ/nextjs-issue et exécutez npm run dev .

Comportement prévisible

Pas de problème

Informations système

  • Système d'exploitation : Windows 10
  • Version de Next.js : 8.1.1-canary.67

Commentaire le plus utile

Mise à jour pour Next.js moderne (9.4+)

Vous pouvez utiliser en toute sécurité fs dans getStaticProps ou getServerSideProps , aucune configuration supplémentaire n'est requise . Assurez-vous de référencer la variable dans le cycle de vie de vos données afin qu'elle soit correctement supprimée de l'arborescence.

Vous pouvez utiliser cet outil pour apprendre visuellement comment cela fonctionne !

Si vous construisez toujours sur une ancienne version Next.js avec getInitialProps , lisez ci-dessous 👇


Le code fourni n'est pas valide -- ce fichier ne serait jamais disponible côté client lors du rendu :

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

N'oubliez pas que vous ne pouvez effectuer des opérations liées à FS que lorsque _sur le serveur_. Cela signifie que vous ne pouvez pas utiliser fs lors du rendu.

Si vous utilisez fs , assurez-vous que ce n'est que dans les getInitialProps .

Vous devrez peut-être également créer un fichier next.config.js avec le contenu suivant pour que le bundle client soit construit :

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

    return config
  }
}

Tous les 13 commentaires

Mise à jour pour Next.js moderne (9.4+)

Vous pouvez utiliser en toute sécurité fs dans getStaticProps ou getServerSideProps , aucune configuration supplémentaire n'est requise . Assurez-vous de référencer la variable dans le cycle de vie de vos données afin qu'elle soit correctement supprimée de l'arborescence.

Vous pouvez utiliser cet outil pour apprendre visuellement comment cela fonctionne !

Si vous construisez toujours sur une ancienne version Next.js avec getInitialProps , lisez ci-dessous 👇


Le code fourni n'est pas valide -- ce fichier ne serait jamais disponible côté client lors du rendu :

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

N'oubliez pas que vous ne pouvez effectuer des opérations liées à FS que lorsque _sur le serveur_. Cela signifie que vous ne pouvez pas utiliser fs lors du rendu.

Si vous utilisez fs , assurez-vous que ce n'est que dans les getInitialProps .

Vous devrez peut-être également créer un fichier next.config.js avec le contenu suivant pour que le bundle client soit construit :

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

    return config
  }
}

J'ai le même problème sur mon installation locale, pratiquement vanille, mais dans les exemples de nextjs, cela ne semble pas être un problème
https://github.com/zeit/next.js/tree/5787cbd9de33ea9add7cadeb04689b0d4b02976d/examples/blog-starter

qu'est-ce qui le fait fonctionner là-bas sans modifier le fichier de configuration ?

N'utilisez que fs dans getStaticProps / getServerSideProps car ceux-ci sont éliminés du bundle du navigateur.

J'ai découvert quel était le problème. Si j'importe une fonction qui utilise fs , mais que j'exécute/n'utilise pas la fonction dans getStaticProps, elle finira par être incluse dans le bundle du navigateur. Une fois que la fonction est référencée dans getStaticProps, elle cessera d'apparaître dans le bundle du navigateur.

Je suppose qu'il existe une logique cachée qui supprime les importations utilisées dans getStaticProps mais inutilisées dans l'exportation principale. J'ai passé quelques heures à déboguer jusqu'à ce que je puisse reproduire, cela vaut peut-être la peine d'avoir une note quelque part dans la documentation :)

La logique cachée n'est-elle pas juste l'arbre de webpack qui tremble ? Cela a du sens quand on y pense, Next n'importe pas getStaticProps dans le bundle du navigateur, il supprime donc la fonction importée qui y est utilisée.

Si vous ne le référencez nulle part, je suppose que webpack considère que vous l'avez importé pour des effets secondaires, il l'inclut donc toujours dans chaque bundle.

La logique cachée n'est-elle pas juste l'arbre de webpack qui tremble ? Cela a du sens quand on y pense, Next n'importe pas getStaticProps dans le bundle du navigateur, il supprime donc la fonction importée qui y est utilisée.

Si vous ne le référencez nulle part, je suppose que webpack considère que vous l'avez importé pour des effets secondaires, il l'inclut donc toujours dans chaque bundle.

Non, le webpack tree shake n'est pas assez sophistiqué pour ébranler ces exportations de cette manière. Le tremblement de l'arbre getStaticProps / getServerSideProps / getStaticPaths est géré par ce plugin Babel personnalisé que nous avons créé : https://github.com/vercel/next.js/blob/canary/packages/next/build/babel/plugins/next-ssg-transform .ts

Oh merci pour le pointeur, on dirait que j'ai surestimé webpack :)

Une raison pour laquelle cela se produirait à partir de _within_ getServerSideProps ?

Salut tout le monde. Comme @aloukissas, j'ai le même problème lorsque dotenv dans mon index.js getStaticProps() . Il est résolu lors de l'ajout du fichier next.config.js comme indiqué dans le commentaire initial de @Timer .

Des indices pourquoi cela se produit-il? Je ne chante pas Next.js v.9.4.0

Merci!

J'ai eu cette erreur lors de l'utilisation de fast-glob .

J'ai utilisé cet excellent outil pour comprendre le code qui est fourni côté client.

Il s'est avéré que j'importais une variable à partir d'un fichier qui utilise fast-glob qui utilise en interne fs mais je n'utilisais la variable nulle part à l'intérieur de getStaticProps donc les fichiers importent fast-glob n'étaient pas éliminés.

Un exemple:

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

Comme vous pouvez le voir, je n'utilise BLOG_PATH nulle part dans index.js mais je l'importe quand même. J'utilise seulement blogFilePaths donc cela m'a donné cette erreur.

Pour plus de contexte → https://github.com/vercel/next.js/discussions/17138

Merci @deadcoder0904 voici mon code :

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

L'outil que vous mentionnez montre que import 'dotenv/config' est inclus dans le code client, ce qui fait probablement apparaître l'erreur. Le fait est que j'en ai besoin pour lire à partir des variables d'environnement.

Il y a probablement une autre meilleure façon de le faire, j'apprends toujours Next.js :)

@ig-perez À partir de Next v9.4, ils ont un moyen intégré de charger des variables d'environnement → https://nextjs.org/docs/basic-features/environment-variables

Je vous suggère de lire la doc pour trouver la solution :)

C'est génial, j'ai raté cette partie dans la doc, merci ! Je vais mettre à jour mon code 👍🏽

Cette page vous a été utile?
0 / 5 - 0 notes