Next.js: Modul nicht gefunden: 'fs' kann nicht aufgelöst werden

Erstellt am 5. Juli 2019  ·  13Kommentare  ·  Quelle: vercel/next.js

Fehlerbericht

Beschreibe den Fehler

Ich verwende das beliebte find-up npm-Paket, das Locate-path als Abhängigkeit hat. locate-path erfordert fs im Code.

Wenn ich versuche, meine App auszuführen, erhalte ich die folgende Fehlermeldung:

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

Ich habe ein Problem im Locate-Path-Repository erstellt und sie haben bestätigt, dass das Problem nicht bei ihnen, sondern wahrscheinlich bei Webpack liegt. Ich verwende kein Webpack in meiner App, daher muss das Problem auf die Verwendung von Webpack durch Next.js zurückzuführen sein.

Fortpflanzen

Klonen Sie https://github.com/TidyIQ/nextjs-issue und führen Sie npm run dev .

Erwartetes Verhalten

Kein Problem

System Information

  • Betriebssystem: Windows 10
  • Version von Next.js: 8.1.1-canary.67

Hilfreichster Kommentar

Update für modernes Next.js (9.4+)

Sie können fs sicher innerhalb von getStaticProps oder getServerSideProps , es ist keine zusätzliche Konfiguration erforderlich . Stellen Sie sicher, dass Sie in Ihrem Datenlebenszyklus auf die Variable verweisen, damit der Baum korrekt weggeschüttelt wird.

Sie können dieses Tool verwenden , um visuell zu lernen, wie es funktioniert!

Wenn Sie noch auf einer älteren Next.js-Version mit getInitialProps aufbauen, lesen Sie weiter unten


Der bereitgestellte Code ist ungültig – diese Datei wäre während des Renderns nie auf der Clientseite verfügbar:

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

Denken Sie daran, dass Sie FS-bezogene Operationen nur _auf dem Server_ ausführen können. Das bedeutet, dass Sie beim Rendern nicht fs .

Wenn Sie fs , stellen Sie sicher, dass es nur innerhalb von getInitialProps .

Möglicherweise müssen Sie auch eine next.config.js Datei mit dem folgenden Inhalt erstellen, um das Client-Bundle zu erstellen:

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

    return config
  }
}

Alle 13 Kommentare

Update für modernes Next.js (9.4+)

Sie können fs sicher innerhalb von getStaticProps oder getServerSideProps , es ist keine zusätzliche Konfiguration erforderlich . Stellen Sie sicher, dass Sie in Ihrem Datenlebenszyklus auf die Variable verweisen, damit der Baum korrekt weggeschüttelt wird.

Sie können dieses Tool verwenden , um visuell zu lernen, wie es funktioniert!

Wenn Sie noch auf einer älteren Next.js-Version mit getInitialProps aufbauen, lesen Sie weiter unten


Der bereitgestellte Code ist ungültig – diese Datei wäre während des Renderns nie auf der Clientseite verfügbar:

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

Denken Sie daran, dass Sie FS-bezogene Operationen nur _auf dem Server_ ausführen können. Das bedeutet, dass Sie beim Rendern nicht fs .

Wenn Sie fs , stellen Sie sicher, dass es nur innerhalb von getInitialProps .

Möglicherweise müssen Sie auch eine next.config.js Datei mit dem folgenden Inhalt erstellen, um das Client-Bundle zu erstellen:

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

    return config
  }
}

Ich habe das gleiche Problem bei meiner lokalen, praktisch Vanilla-Installation, aber in den Beispielen von nextjs scheint dies kein Problem zu sein
https://github.com/zeit/next.js/tree/5787cbd9de33ea9add7cadeb04689b0d4b02976d/examples/blog-starter

Wie funktioniert es dort, ohne die Konfigurationsdatei zu ändern?

Verwenden Sie fs in getStaticProps / getServerSideProps, da diese aus dem Browserpaket entfernt werden.

Ich habe herausgefunden, was das Problem war. Wenn ich eine Funktion importiere, die fs , aber die Funktion nicht in getStaticProps ausführe/verwende, wird sie am Ende in das Browser-Bundle aufgenommen. Sobald die Funktion in getStaticProps referenziert wird, wird sie nicht mehr im Browserpaket angezeigt.

Ich denke, es gibt eine versteckte Logik, die Importe entfernt, die in getStaticProps verwendet, aber im Hauptexport nicht verwendet werden. Ich habe ein paar Stunden mit dem Debuggen verbracht, bis ich reproduzieren konnte, vielleicht lohnt es sich, irgendwo in den Dokumenten eine Randnotiz zu haben :)

Ist die versteckte Logik nicht nur der Baum des Webpacks? Es macht Sinn, wenn Sie es sich vorstellen, Next importiert getStaticProps in das Browser-Bundle, also entfernt es die darin verwendete importierte Funktion.

Wenn Sie nirgendwo darauf verweisen, geht Webpack vermutlich davon aus, dass Sie es wegen Nebenwirkungen importiert haben, sodass es immer noch in jedem Bundle enthalten ist.

Ist die versteckte Logik nicht nur der Baum des Webpacks? Es macht Sinn, wenn Sie es sich vorstellen, Next importiert getStaticProps in das Browser-Bundle, also entfernt es die darin verwendete importierte Funktion.

Wenn Sie nirgendwo darauf verweisen, geht Webpack vermutlich davon aus, dass Sie es wegen Nebenwirkungen importiert haben, sodass es immer noch in jedem Bundle enthalten ist.

Nein, Webpack Tree Shaking ist nicht ausgereift genug, um diese Exporte auf diese Weise zu erschüttern. Baumschütteln getStaticProps / getServerSideProps / getStaticPaths wird von diesem benutzerdefinierten Babel-Plugin verarbeitet, das wir erstellt haben: https://github.com/vercel/next.js/blob/canary/packages/next/build/babel/plugins/next-ssg-transform .ts

Oh danke für den Hinweis, sieht aus als hätte ich das Webpack überschätzt :)

Irgendein Grund, warum dies von _innerhalb_ getServerSideProps aus passieren würde?

Hallo zusammen. Wie @aloukissas habe ich das gleiche Problem, wenn ich dotenv in meinem index.js getStaticProps() . Es wird gelöst, wenn die Datei next.config.js hinzugefügt wird, wie im Anfangskommentar von

Irgendwelche Anhaltspunkte, warum das passiert? Ich singe Next.js v.9.4.0

Vielen Dank!

Ich hatte diesen Fehler bei der Verwendung von fast-glob .

Ich habe dieses großartige Tool verwendet , um den Code zu verstehen, der auf der Clientseite gebündelt wird.

Es stellte sich heraus, dass ich eine Variable aus einer Datei importiert habe, die fast-glob die intern fs aber ich habe die Variable nirgendwo in getStaticProps also importiert die Datei fast-glob wurden nicht eliminiert.

Ein Beispiel:

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

Wie Sie sehen, verwende ich BLOG_PATH nirgendwo in index.js , importiere es aber trotzdem. Ich verwende nur blogFilePaths also habe ich diesen Fehler erhalten.

Für mehr Kontext → https://github.com/vercel/next.js/discussions/17138

Danke @deadcoder0904 das ist mein 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} />}
    />
  )
}

Das von Ihnen erwähnte Tool zeigt, dass import 'dotenv/config' im Clientcode enthalten ist, und wahrscheinlich tritt der Fehler dadurch auf. Die Sache ist, dass ich es brauche, um aus den env-Variablen zu lesen.

Wahrscheinlich gibt es einen anderen besseren Weg, es zu tun, ich lerne noch Next.js :)

@ig-perez Ab Next v9.4 haben sie eine eingebaute Möglichkeit, Umgebungsvariablen zu laden → https://nextjs.org/docs/basic-features/environment-variables

Ich schlage vor, dass Sie die Dokumente lesen, um die Lösung zu finden :)

Das ist großartig, ich habe diesen Teil in der Dokumentation übersehen, danke! Ich werde meinen Code aktualisieren 👍🏽

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen