أنا أستخدم حزمة 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
.
لا خلاف
يمكنك استخدام fs
بأمان داخل getStaticProps
أو getServerSideProps
، بدون الحاجة إلى تكوين إضافي . تأكد من أنك تشير إلى المتغير في دورة حياة البيانات الخاصة بك حتى يتم اهتزازها بشكل صحيح.
يمكنك استخدام هذه الأداة لتتعلم بصريًا كيف تعمل!
إذا كنت لا تزال تعمل على إصدار Next.js القديم باستخدام getInitialProps
، فاقرأ أدناه 👇
الكود المقدم غير صالح - لن يكون هذا الملف متاحًا أبدًا من جانب العميل أثناء العرض:
تذكر أنه يمكنك فقط إجراء العمليات المتعلقة بـ 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
لم يتم التخلص منها.
مثال:
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 } }
}
كما ترى ، فأنا لا أستخدم 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
أقترح عليك قراءة المستندات للعثور على الحل :)
هذا رائع ، فاتني هذا الجزء في المستندات ، شكرًا! سوف أقوم بتحديث الكود الخاص بي 👍🏽
التعليق الأكثر فائدة
تحديث لـ 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
بالمحتوى التالي لإنشاء حزمة العميل: