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.
Clonez https://github.com/TidyIQ/nextjs-issue et exécutez npm run dev
.
Pas de problème
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 :
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:
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 } }
}
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 👍🏽
Commentaire le plus utile
Mise à jour pour Next.js moderne (9.4+)
Vous pouvez utiliser en toute sécurité
fs
dansgetStaticProps
ougetServerSideProps
, 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 lesgetInitialProps
.Vous devrez peut-être également créer un fichier
next.config.js
avec le contenu suivant pour que le bundle client soit construit :