Next.js: لم يتم العثور على الوحدة النمطية: لا يمكن حل "fs"

تم إنشاؤها على ٥ يوليو ٢٠١٩  ·  13تعليقات  ·  مصدر: vercel/next.js

تقرير الشوائب

صف الخلل

أنا أستخدم حزمة find-up npm الشائعة ، والتي تحتوي على locate-path كاعتمادية. locate-path يتطلب fs داخل الكود الخاص به.

عندما أحاول تشغيل تطبيقي ، أتلقى رسالة الخطأ التالية:

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

لقد أنشأت مشكلة في repo locate-path وقد أكدوا أن المشكلة ليست معهم ، ولكن من المحتمل أن تكون مع حزمة الويب. لا أستخدم حزمة الويب في تطبيقي ، لذا يجب أن تكون المشكلة ناتجة عن استخدام Next.js لحزمة الويب.

لإعادة إنتاج

استنساخ https://github.com/TidyIQ/nextjs-issue وقم بتشغيل npm run dev .

سلوك متوقع

لا خلاف

معلومات النظام

  • نظام التشغيل: Windows 10
  • إصدار Next.js: 8.1.1-canary.67

التعليق الأكثر فائدة

تحديث لـ Next.js الحديث (9.4+)

يمكنك استخدام fs بأمان داخل getStaticProps أو getServerSideProps ، بدون الحاجة إلى تكوين إضافي . تأكد من أنك تشير إلى المتغير في دورة حياة البيانات الخاصة بك حتى يتم اهتزازها بشكل صحيح.

يمكنك استخدام هذه الأداة لتتعلم بصريًا كيف تعمل!

إذا كنت لا تزال تعمل على إصدار Next.js القديم باستخدام getInitialProps ، فاقرأ أدناه 👇


الكود المقدم غير صالح - لن يكون هذا الملف متاحًا أبدًا من جانب العميل أثناء العرض:

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

تذكر أنه يمكنك فقط إجراء العمليات المتعلقة بـ FS أثناء _ على الخادم_. هذا يعني أنه لا يمكنك استخدام fs أثناء العرض.

إذا كنت تستخدم fs ، فتأكد من أنها في حدود getInitialProps .

قد تحتاج أيضًا إلى إنشاء ملف next.config.js بالمحتوى التالي لإنشاء حزمة العميل:

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

    return config
  }
}

ال 13 كومينتر

تحديث لـ Next.js الحديث (9.4+)

يمكنك استخدام fs بأمان داخل getStaticProps أو getServerSideProps ، بدون الحاجة إلى تكوين إضافي . تأكد من أنك تشير إلى المتغير في دورة حياة البيانات الخاصة بك حتى يتم اهتزازها بشكل صحيح.

يمكنك استخدام هذه الأداة لتتعلم بصريًا كيف تعمل!

إذا كنت لا تزال تعمل على إصدار Next.js القديم باستخدام getInitialProps ، فاقرأ أدناه 👇


الكود المقدم غير صالح - لن يكون هذا الملف متاحًا أبدًا من جانب العميل أثناء العرض:

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

تذكر أنه يمكنك فقط إجراء العمليات المتعلقة بـ FS أثناء _ على الخادم_. هذا يعني أنه لا يمكنك استخدام fs أثناء العرض.

إذا كنت تستخدم fs ، فتأكد من أنها في حدود getInitialProps .

قد تحتاج أيضًا إلى إنشاء ملف next.config.js بالمحتوى التالي لإنشاء حزمة العميل:

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

    return config
  }
}

لدي نفس المشكلة في تثبيت الفانيليا المحلي الخاص بي ، ولكن في الأمثلة من nextjs ، لا يبدو أن هذا يمثل مشكلة
https://github.com/zeit/next.js/tree/5787cbd9de33ea9add7cadeb04689b0d4b02976d/examples/blog-starter

ما الذي يجعله يعمل هناك دون تعديل ملف التكوين؟

استخدم فقط fs في getStaticProps / getServerSideProps حيث يتم حذفها من حزمة المتصفح.

اكتشفت ما هي المشكلة. إذا قمت باستيراد دالة تستخدم fs ، لكن لا تقم بتشغيل / استخدام الوظيفة داخل getStaticProps ، فسوف ينتهي بها الأمر ليتم تضمينها في حزمة المتصفح. بمجرد الإشارة إلى الوظيفة داخل getStaticProps ، ستتوقف عن الظهور في حزمة المتصفح.

أعتقد أن هناك بعض المنطق المخفي الذي يزيل الواردات المستخدمة في getStaticProps ولكنها غير مستخدمة في التصدير الرئيسي. قضيت بضع ساعات في تصحيح الأخطاء حتى أتمكن من التكاثر ، وربما يستحق الأمر الحصول على ملاحظة جانبية في مكان ما في المستندات :)

أليس المنطق الخفي مجرد شجرة webpack تهتز؟ من المنطقي عندما تفكر في الأمر ، لا يقوم Next باستيراد getStaticProps في حزمة المتصفح ، لذلك يزيل الوظيفة المستوردة المستخدمة فيه.

إذا لم تقم بالإشارة إليها في أي مكان ، أعتقد أن حزمة الويب تعتبر أنك قمت باستيرادها من أجل الآثار الجانبية ، لذلك لا تزال تدرجها في كل حزمة.

أليس المنطق الخفي مجرد شجرة webpack تهتز؟ من المنطقي عندما تفكر في الأمر ، لا يقوم Next باستيراد getStaticProps في حزمة المتصفح ، لذلك يزيل الوظيفة المستوردة المستخدمة فيه.

إذا لم تقم بالإشارة إليها في أي مكان ، أعتقد أن حزمة الويب تعتبر أنك قمت باستيرادها من أجل الآثار الجانبية ، لذلك لا تزال تدرجها في كل حزمة.

لا ، اهتزاز شجرة webpack ليس معقدًا بما يكفي لزعزعة هذه الصادرات بهذه الطريقة. تهز الشجرة getStaticProps / getServerSideProps / getStaticPaths تتم معالجته بواسطة هذا المكون الإضافي Babel المخصص الذي أنشأناه: https://github.com/vercel/next.js/blob/canary/packages/next/build/babel/plugins/next-ssg-transform .ts

شكرًا على المؤشر ، يبدو أنني بالغت في تقدير حزمة الويب :)

هل يحدث هذا لأي سبب من _within_ getServerSideProps ؟

تحية للجميع. مثل aloukissas لدي نفس المشكلة عند استخدام dotenv في index.js getStaticProps() . يتم حلها عند إضافة ملف next.config.js كما هو موضح في تعليق Timer الأولي.

أي أدلة لماذا يحدث هذا؟ أقوم بإلغاء إلغاء Next.js v.9.4.0

شكرا!

حدث هذا الخطأ أثناء استخدام fast-glob .

لقد استخدمت هذه الأداة الرائعة لفهم الكود الذي يتم تجميعه في جانب العميل.

تبين ، أنني كنت أستورد متغيرًا من ملف يستخدم fast-glob والذي يستخدم داخليًا fs لكني لم أستخدم المتغير في أي مكان داخل getStaticProps لذلك تستورد الملفات fast-glob لم يتم التخلص منها.

مثال:

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

كما ترى ، فأنا لا أستخدم BLOG_PATH في أي مكان في index.js ولكن ما زلت أستورده. أنا أستخدم فقط blogFilePaths لذلك أعطاني هذا الخطأ.

لمزيد من السياق → https://github.com/vercel/next.js/discussions/17138

شكرا @ deadcoder0904 هذا هو الكود الخاص بي:

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

الأداة التي ذكرتها تظهر أن import 'dotenv/config' مضمن في كود العميل ، ومن المحتمل أن يكون هذا هو سبب ظهور الخطأ. الشيء هو أنني أحتاجه للقراءة من المتغيرات env.

ربما هناك طريقة أخرى أفضل للقيام بذلك ، ما زلت أتعلم Next.js :)

@ ig-perez اعتبارًا من الإصدار 9.4 التالي ، لديهم طريقة مضمنة لتحميل متغيرات البيئة → https://nextjs.org/docs/basic-features/environment-variables

أقترح عليك قراءة المستندات للعثور على الحل :)

هذا رائع ، فاتني هذا الجزء في المستندات ، شكرًا! سوف أقوم بتحديث الكود الخاص بي 👍🏽

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات