Next.js: الجيل الثابت / تحسينات SSG

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

ملخص

اسمح لـ Next.js بأن يصبح مختلطًا تمامًا من خلال توفير طرق للقيام بكل من الإنشاء الثابت والعرض من جانب الخادم على أساس كل صفحة.

  • طريقتان جديدتان لجلب البيانات لكل صفحة

    • getStaticProps - الاشتراك في الجيل الثابت (SSG) عند next build مرة.

    • getServerSideProps - الاشتراك في العرض من جانب الخادم (SSR) الذي يتم عرضه عند الطلب.

  • طريقة جديدة لتوليد ثابت (SSG) مجموعة من المسارات من مصادر ديناميكية

    • getStaticPaths - إرجاع قائمة المعلمات للمسارات الديناميكية للقيام بإنشاء ثابت (SSG)

يناقش RFC حصريًا إضافات API. جميع الوظائف الجديدة متوافقة تمامًا مع الإصدارات السابقة ويمكن اعتمادها بشكل تدريجي. لا يقدم RFC هذا أي إهمال.

خلفية

عند إنشاء مواقع الويب أو تطبيقات الويب ، يتعين عليك عمومًا الاختيار بين استراتيجيتين: إنشاء ثابت (SSG) أو عرض من جانب الخادم (SSR).

يتيح لك Next.js بدلاً من ذلك إنشاء تطبيقات مختلطة تتيح لك اختيار الإستراتيجية المستخدمة لكل صفحة. بدءًا من Next.js 9 ، يتم تحسين الصفحات التي لا تحتوي على getInitialProps بشكل ثابت وإخراجها كملفات .html عند next build .

ومع ذلك ، قد ترغب في القيام بجلب البيانات أثناء إنشاء صفحات ثابتة لحالة الاستخدام الخاصة بك.

على سبيل المثال ، لإنشاء صفحات تسويق بشكل ثابت من CMS أو قسم مدونة بالموقع.

سيؤدي استخدام getInitialProps إلى اشتراكك في SSR في هذه الحالة.

يحتوي Next.js حاليًا على أمر next export ، والذي يجعل التطبيق SSG بالكامل ، ويفقد الطبيعة المختلطة لـ Next.js.

إذا كنت تستخدم next export مع getInitialProps فهناك مشكلة أخرى تظهر. يتم استدعاء getInitialProps في وقت الإنشاء (وهو أمر رائع) ، ولكن عند استخدام next/link للتنقل بين الصفحات يسمى getInitialProps جانب العميل ، بدلاً من استخدام next export النتيجة.

هذا يعني أيضًا أن مصدر البيانات (نقطة نهاية CMS / API) يتم استدعاؤه مباشرة على الانتقالات من جانب العميل ، إذا كان مصدر البيانات الخاص بك معطلاً ، فإن الانتقالات من جانب العميل تنقطع أثناء التنقل بين الصفحات.

لقد تعاونا مع مستخدمين كثيفين لـ SSG و next export في Next.js مثل HashiCorp (شكرًاjescalan) وبحثنا على نطاق واسع في القيود الصحيحة لتقديم طريقتين جديدتين لجلب البيانات: getStaticProps و getServerSideProps . ولكن أيضًا طريقة لتوفير معلمات لإنشاء صفحات ثابتة للمسارات الديناميكية بشكل ثابت: getStaticPaths (استبدال exportPathMap لكل صفحة).

تتمتع هذه الأساليب الجديدة بالعديد من المزايا مقارنة بنموذج getInitialProps حيث يوجد تمييز واضح بين ما سيصبح SSG مقابل SSR.

  • يشير getStaticProps إلى الصفحة التي سيتم إنشاؤها بشكل ثابت في وقت الإنشاء (عند تشغيل next build )
  • يسمح getStaticPaths بإرجاع قائمة من المعلمات لتوليدها في وقت الإنشاء للمسارات الديناميكية
  • يشير getServerSideProps إلى الصفحة التي سيتم عرضها من جانب الخادم عند كل طلب وهي الأكثر تشابهًا مع السلوك الحالي getInitialProps عند استخدام الخادم.

يتيح لنا فصل هذه الطرق أيضًا توفير كائن السياق الصحيح الذي يمكن كتابته باستخدام TypeScript. عندما تختار إستراتيجية عرض معينة تحصل على القيم الصحيحة ، حاليًا مع getInitialProps عليك تخمين ما هو متاح في SSG مقابل SSR عند استخدام TypeScript.

علاوة على ذلك ، من خلال توضيح هذه الأساليب ، سيسمح لنا بتوثيق المفاضلات المختلفة بشكل أكثر وضوحًا.

تطبيق

لاحظ أن كل هذه الطرق ذات مستوى أعلى في ملف مكون الصفحة ولا يمكن دمجها ، على غرار getInitialProps .

getStaticProps

استخدام getStaticProps يعني أن الصفحة سيتم عرضها بشكل ثابت في وقت الإنشاء (SSG).

ستتيح لك هذه الطريقة الجديدة القيام بجلب البيانات لصفحة سيتم إنشاؤها بشكل ثابت في ملف .html عند next build مرة.

سيقوم Next.js أيضًا تلقائيًا بإنشاء ملف JSON يحمل نتيجة getStaticProps عند next build مرة. يتم استخدام هذا للتوجيه من جانب العميل.

عند التوجيه من جانب العميل من خلال next/link أو next/router ، سيقوم Next.js بجلب ملف JSON هذا للحصول على الخاصيات اللازمة لعرض الصفحة من جانب العميل.

يتم إرجاع الخصائص تحت مفتاح props بحيث يمكن تقديم خيارات أخرى في المستقبل.

// pages/index.js

// getStaticProps is only called server-side
// In theory you could do direct database queries
export async function getStaticProps(context) {
  return {
    // Unlike `getInitialProps` the props are returned under a props key
    // The reasoning behind this is that there's potentially more options
    // that will be introduced in the future.
    // For example to allow you to further control behavior per-page.
    props: {}
  };
}

سيحتوي context على:

  • params - المعلمات عندما تكون على مسار ديناميكي.

getStaticPaths

هذا امتداد لاستخدام getStaticProps للمسارات الديناميكية.

يستبدل getStaticPaths الحاجة إلى وجود exportPathMap ويعمل لكل صفحة.

نظرًا لأنك قد ترغب في إنشاء قائمة ثابتة من عناوين url التي تحتوي على معلمة ديناميكية ، كما في المثال أدناه slug . سيوفر Next.js طريقة getStaticPaths تسمح بإعادة قائمة عناوين url. نظرًا لأنها طريقة async يمكنك أيضًا جلب هذه القائمة من مصدر بيانات مثل CMS.

// pages/blog/[slug].js

// `getStaticProps` gets a `params` object holding the dynamic parameters
// For `/blog/hello-world` it would look like `{ slug: 'hello-world }`
export async function getStaticProps({ params }) {
  return {
    props: {}
  };
}

// `getStaticPaths` allows the user to return a list of parameters to
// render to HTML at build time.
export async function getStaticPaths() {
  return {
    paths: [
      // This renders /blog/hello-world to HTML at build time
      { params: { slug: "hello-world" } }
    ]
  };
}

تراجع

في كثير من الحالات ، قد لا ترغب في العرض المسبق لكل مسار ممكن في التطبيق الخاص بك في وقت الإنشاء (على سبيل المثال إذا كان لديك ملايين المنتجات). لهذا السبب ، ستنشئ Next.js تلقائيًا صفحة fallback تُعرض للصفحة بدون بيانات (بحيث يمكن إظهار حالة التحميل) عندما لم يتم إنشاء الصفحة بعد.

سيكون السلوك الدقيق للخدمة هو:

  • طلب وارد

    • يتحقق Next.js مما إذا كان المسار قد تم إنشاؤه في وقت الإنشاء

    • إذا تم إنشاء المسار



      • تخدم مباشرة



    • إذا لم يتم إنشاء المسار



      • خدمة الاحتياط


      • يعرض Next.js الصفحة (مع البيانات) في الخلفية ويضيفها إلى قائمة الصفحات التي تم إنشاؤها


      • الطلب اللاحق لنفس المسار سيخدم الصفحة التي تم إنشاؤها


      • يضمن ذلك تمتع المستخدمين دائمًا بتجربة سريعة وألا يكون لديهم أبدًا TTFB بطيئًا من عرض الخادم مع الحفاظ على عمليات الإنشاء السريعة وخصائص التوليد الثابت



في حالة رغبتك في أن تؤدي المسارات التي لم يتم إنشاؤها في وقت الإنشاء إلى 404 ، فمن الممكن أيضًا عن طريق إرجاع fallback: false من getStaticPaths

// `getStaticPaths` allows the user to return a list of parameters to
// render to HTML at build time.
export async function getStaticPaths() {
  return {
    // Opt-out of the described fallback behavior
    fallback: false,
    paths: [
      // This renders /blog/hello-world to HTML at build time
      { params: { slug: "hello-world" } }
    ]
  };
}

getServerSideProps

عند استخدام getServerSideProps ، لا يتم إنشاء الصفحة بشكل ثابت (SSG) وبدلاً من ذلك يتم عرضها عند الطلب عند كل طلب إلى الخادم (SSR).

سيعرض Next.js أيضًا تلقائيًا نقطة نهاية API التي تعرض نتيجة استدعاء getServerSideProps . يتم استخدام هذا للتوجيه من جانب العميل.

عند التوجيه من جانب العميل عبر next/link أو next/router ، سيقوم Next.js بجلب نقطة نهاية واجهة برمجة التطبيقات المكشوفة هذه للحصول على بيانات JSON التي يتم تحويلها إلى الخاصيات اللازمة لعرض صفحة جانب العميل.

هذه الطريقة هي الأكثر تشابهًا مع getInitialProps ، حيث يكون الاختلاف الرئيسي getServerSideProps يتم تنفيذه دائمًا من جانب الخادم بدلاً من المتصفح. إما على العرض من جانب الخادم أو جلب واجهة برمجة التطبيقات عند التوجيه من جانب العميل.

على غرار getStaticProps ، يتم إرجاع الخصائص تحت مفتاح props .

// pages/index.js

// getServerSideProps is only called server-side
// In theory you could do direct database queries
export async function getServerSideProps(context) {
  return {
    // Unlike `getInitialProps` the props are returned under a props key
    // The reasoning behind this is that there's potentially more options
    // that will be introduced in the future.
    // For example to allow you to further control behavior per-page.
    props: {}
  };
}

سيحتوي context على:

  • params - المعلمات الموجودة على مسار ديناميكي
  • req - كائن طلب HTTP
  • res - كائن استجابة HTTP
  • query - سلسلة الاستعلام (لست متأكدًا تمامًا من هذه السلسلة ، ولكن ربما تكون مطلوبة)

تأليف timneutkens ، Timer ، ijjk ،lfades. تعاون مع rauchg و jescalan وآخرين 🚀

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

تم إصدار دعم الجيل التالي من دعم إنشاء الموقع الثابت (SSG) باعتباره مستقرًا في Next.js 9.3!

يتضمن هذا الإصدار أيضًا دعمًا لـ "وضع المعاينة" ، أو القدرة على تجاوز الصفحة المعروضة مسبقًا وعرض الصفحة عند الطلب للمستخدمين المصرح لهم .

يمكنك قراءة المزيد حول هذا الموضوع في منشور المدونة الخاص بنا. إذا كنت تعمل أكثر ، فانتقل مباشرةً إلى مستنداتنا !

ال 250 كومينتر

export async function getStaticProps(context) {
  return {
    // Unlike `getInitialProps` the props are returned under a props key
    // The reasoning behind this is that there's potentially more options
    // that will be introduced in the future.
    // For example to allow you to further control behavior per-page.
    props: {}
  };
}

أنا مهتم بمعرفة الظروف التي سنحتاجها لإرجاع بيانات إضافية بخلاف ما يمكن احتوائه في props . لقد وجدت أن التفسير المضمّن "لزيادة التحكم في السلوك لكل صفحة" غامض بعض الشيء.

تبدو مثيرة جدا للاهتمام! هل سيكون بديلاً لـ getInitialProps أم جنبًا إلى جنب؟ على سبيل المثال ، بالنسبة لحالة الاستخدام الخاصة بنا ، تعد واجهة برمجة تطبيقات جلب البيانات خدمة عامة. لذلك في التنقل من جانب العميل ، نتوقع أن يقوم العميل باستدعاء طبقة API مباشرة ، بينما في SSR يستدعيها الخادم. من الآن فصاعدًا ، هل سيستمر حل حالة الاستخدام هذه بالطريقة السابقة؟

أنا مهتم بمعرفة الظروف التي سنحتاجها لإرجاع بيانات إضافية بخلاف ما يمكن احتواؤه في props . لقد وجدت أن التفسير المضمّن "لزيادة التحكم في السلوك لكل صفحة" غامض بعض الشيء.

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

تبدو مثيرة جدا للاهتمام! هل سيكون بديلاً لـ getInitialProps أم جنبًا إلى جنب؟ على سبيل المثال ، بالنسبة لحالة الاستخدام الخاصة بنا ، تعد واجهة برمجة تطبيقات جلب البيانات خدمة عامة. لذلك في التنقل من جانب العميل ، نتوقع أن يقوم العميل باستدعاء طبقة API مباشرة ، بينما في SSR يستدعيها الخادم. من الآن فصاعدًا ، هل سيستمر حل حالة الاستخدام هذه بالطريقة السابقة؟

بشكل عام ، لهذا السلوك بعض الجوانب السلبية ، على سبيل المثال عمليات جلب الشلال التي يمكن أن تكون بطيئة من مناطق معينة حول العالم. يسمح الأسلوب getServerProps بتخزين الاستجابة مؤقتًا بشكل أكثر كفاءة.

هذا يبدو مثيرًا للاهتمام حقًا! فكرة رائعة!

لدي مخاوف بشأن النشر على الرغم من ...

دعنا نتخيل أنني أستضيف الآن.
بالنسبة لعملية النشر الأولى ، من الواضح أن التطبيقات بأكملها مبنية على النشر.

بعد ذلك ، أقوم بتغيير بعض المحتوى في CMS وأتطلع إلى إعادة بناء صفحات SSG فقط ، لكن رمز التطبيق لم يتغير.

ينطلق الإنذار فورًا ، في هذه الحالة إذا قمت بتشغيل الإنشاء ، فهناك حلان محتملان:

1) لا يتم إعادة بناء أي شيء ، حيث يتم تخزين كل شيء مؤقتًا - لم يتغير أي رمز و blabla.
2) أنا --force الآن ، والآن يتم إعادة بناء "كل شيء" ، لكنني طلبت فقط إعادة بناء صفحات SSG.

_ هذه مجرد فرضيات ، لأن ذلك يعتمد على أنظمة البناء نفسها - ما مدى وعيهم بـ Next_

من المحتمل أن يؤثر هذا على أي حل استضافة آخر.

التالي نفسه لديه .next/cache ... كيف يمكن أن يلعب هذا حول ذلك؟

joltmode هذا هو الحال بشكل أساسي لكل مولد موقع ثابت حاليًا. يتم الاحتفاظ بـ .next/cache بين عمليات النشر على Now وإعادة الاستخدام. ضع في اعتبارك أنك ربما تستخدم حاليًا getInitialProps لهذه الحالة مع التخزين المؤقت (من المحتمل https://zeit.co/blog/serverless-pre-rendering) ، والذي يعرض ديناميكيًا في وظيفة بدون خادم ثم يخزن مؤقتًا على CDN الخاص بنا ، وهذا لا يزال السلوك جيدًا تمامًا وسيستمر في العمل إذا كنت تستخدم getServerProps .

رائع حقًا ، يتناسب بشكل جيد مع كيفية استخدامنا لـ Next لمشاريع العملاء ، وسيزيل بعض التعليمات البرمجية المعيارية التي ننسخها.

هناك شيء واحد يجب مراعاته وهو تسمية getStaticProps و getServerProps ، إذا أعادوا {props} وخيارات أخرى محتملة في المستقبل ، ألن تكون * Props محيرة؟ ربما تكون getStaticConfiguration و getStaticSetup و getStaticOptions أكثر عمومية؟

kibs دائمًا ما تتعلق قيم الإرجاع بكيفية التعامل مع الدعائم. لذا فإن التسمية جيدة IMO.

هذا رائع بكل بساطة! يعمل هذا على حل كل حالة استخدام واحتجت إلى ذلك مؤخرًا أو قد أفكر فيه أثناء تطوير تطبيقات الويب الخاصة والمهنية. لقد منعتني للتو من بدء تشغيل مولد الموقع الهجين الخاص بي ، شكرًا!

يمكنني أيضًا أن أتعلق بأن الأساليب الجديدة أفضل من getInitialProps() و exportPathMap() ، والتي بدت مربكة بعض الشيء بالنسبة لي في البداية عندما بدأت في استخدام Next.js وحفرت في SSR / SSG. يعتبر نهج كل صفحة أكثر منطقية بالنسبة لي أيضًا.

لا استطيع الانتظار لتجربة هذا!

مجرد ملاحظة جانبية: في المثال الأخير ، أعتقد أن getServerProps() ينقصه المعلمة context .

مجرد ملاحظة جانبية: في المثال الأخير ، أعتقد أن getServerProps () تفتقد إلى معلمة سياق.

مثبت!

هذا يبدو رائعا! أنا فقط أتساءل من منظور مستخدم TypeScript إذا كان استخدام getStaticProps و getStaticPaths و getServerProps كطرق ثابتة في مكون الصفحة (مثل getInitialProps في الوقت الحالي) يكون أسهل في الكتابة / الاستخدام بشكل صحيح.

const Page: NextPage<Props> = (props) => ...

// Explicit types needed here
export const getStaticPaths: NextGetStaticPaths<Params> = () => ...
export const getStaticProps: NextGetStaticProps<Props, Params> = (context) => ...
export const getServerProps: NextGetServerProps<Props> = (context) => ...

export default Page

// vs.

const Page: NextPage<Props, Params> = (props) => ...

// Static method types come from NextPage<Props, Params>
Page.getStaticPaths = () => ...
Page.getStaticProps = (context) => ...
Page.getServerProps = (context) => ..

export default Page

herrstucki المشكلة في هذا النهج هي أنه يصبح من الصعب بشكل كبير هز الشجرة (اقرأ: قريب من المستحيل). مما يعني أنه سيتم شحن رمز غير ضروري إلى المتصفح.

timneutkens نقطة جيدة ... ولكن بعد ذلك لن يكون الملف المنفصل أكثر منطقية؟ أم أن شيئًا من هذا القبيل "موثوق به" قابل للاهتزاز؟

// This should all be removed in client-side code …
import {fetchQuery, queryTag} from 'big-data-fetching-lib';
const query = queryTag`...`
export const getStaticProps = async () => ({ props: await fetchQuery(query) })

// Only this should be included client-side
export default (props) => ...

herrstucki يمكننا أن

تبدو مثيرة جدا للاهتمام! هل سيكون بديلاً لـ getInitialProps أم جنبًا إلى جنب؟ على سبيل المثال ، بالنسبة لحالة الاستخدام الخاصة بنا ، تعد واجهة برمجة تطبيقات جلب البيانات خدمة عامة. لذلك في التنقل من جانب العميل ، نتوقع أن يقوم العميل باستدعاء طبقة API مباشرة ، بينما في SSR يستدعيها الخادم. من الآن فصاعدًا ، هل سيستمر حل حالة الاستخدام هذه بالطريقة السابقة؟

بشكل عام ، لهذا السلوك بعض الجوانب السلبية ، على سبيل المثال عمليات جلب الشلال التي يمكن أن تكون بطيئة من مناطق معينة حول العالم. يسمح الأسلوب getServerProps بتخزين الاستجابة مؤقتًا بشكل أكثر كفاءة.

بالتأكيد ، لكنني أتحدث عن تجنب RTT لخادم التفاعل على الإطلاق. ضع في اعتبارك الحالة التي يتم فيها تخزين إخراج SSR من الخادم مؤقتًا في وكيل خادم CDN / ذاكرة التخزين المؤقت. بالإضافة إلى ذلك ، مع جلب البيانات لتصفح العميل الذي يستدعي مباشرة طبقة واجهة برمجة تطبيقات مختلفة (شائعة في الويب / التطبيقات / جميع العملاء) ، يعني أن طبقة خادم Next.js لا تحتاج إلى توسيع نطاقها كثيرًا في سيناريو حركة المرور العالية.

أتفهم وجهة نظرك في عمليات جلب الشلال ، ولكن منح المستهلكين القدرة على التعامل مع الخادم التالي كطبقة SSR مقابل مصدر بيانات سيسمح بإعدادات قياس أفضل بكثير.

تبدو مثيرة جدا للاهتمام! هل سيكون بديلاً لـ getInitialProps أم جنبًا إلى جنب؟ على سبيل المثال ، بالنسبة لحالة الاستخدام الخاصة بنا ، تعد واجهة برمجة تطبيقات جلب البيانات خدمة عامة. لذلك في التنقل من جانب العميل ، نتوقع أن يقوم العميل باستدعاء طبقة API مباشرة ، بينما في SSR يستدعيها الخادم. من الآن فصاعدًا ، هل سيستمر حل حالة الاستخدام هذه بالطريقة السابقة؟

بشكل عام ، لهذا السلوك بعض الجوانب السلبية ، على سبيل المثال عمليات جلب الشلال التي يمكن أن تكون بطيئة من مناطق معينة حول العالم. يسمح الأسلوب getServerProps بتخزين الاستجابة مؤقتًا بشكل أكثر كفاءة.

بالتأكيد ، لكنني أتحدث عن تجنب RTT لخادم التفاعل على الإطلاق. ضع في اعتبارك الحالة التي يتم فيها تخزين إخراج SSR من الخادم مؤقتًا في وكيل خادم CDN / ذاكرة التخزين المؤقت. بالإضافة إلى ذلك ، مع جلب البيانات لتصفح العميل الذي يستدعي مباشرة طبقة واجهة برمجة تطبيقات مختلفة (شائعة في الويب / التطبيقات / جميع العملاء) ، يعني أن طبقة خادم Next.js لا تحتاج إلى توسيع نطاقها كثيرًا في سيناريو حركة المرور العالية.

أتفهم وجهة نظرك في عمليات جلب الشلال ، ولكن منح المستهلكين القدرة على التعامل مع الخادم التالي كطبقة SSR مقابل مصدر بيانات سيسمح بإعدادات قياس أفضل بكثير.

أعتقد أنك تسيء فهم أن هذا السلوك الجديد يعني أنه يمكنك بالفعل تخزين النتائج الكاملة مؤقتًا على CDN نظرًا لأن CDN يدعم الاستجابات الديناميكية. لم يكن هذا ممكنًا في السابق بشكل موثوق مع getInitialProps.

timneutkens لقد لعبت مع الكناري ، في محاولة babel-plugin-preval إلى getStaticProps . واجهت مشكلة مع fs .

أحاول قراءة ملفات .md الخاصة بدليلي ./pages/blog/ والتكرار بينها حتى أتمكن من إنشاء صفحة فهرس مدونة تحتوي على جميع منشوراتي

import React from 'react';
import Link from 'next/link';
import fs from 'fs-extra';

const Index = ({ posts }) => (
  <div>
    Hello World. <Thing msg="hello" />
    <Link href="/thing">
      <a>About</a>
    </Link>
    {posts.map(p => (
      <div key={p.title}>{p.title}</div>
    ))}
  </div>
);

Index.getStaticProps = async () => {
  const items = await fs.readdir('./pages/blog');
  items.forEach(path => /* .... do some stuff ... */ )
  return { props: { posts: items } };
};

export default Index;

هذا الرمز يؤدي إلى هذا الخطأ:

Module not found: Can't resolve 'fs' in '/Users/jared/Downloads/nextjs-typescript-template/node_modules/fs-extra/lib'

IIRC من Razzle ، يتعلق هذا الخطأ بأجزاء نظام ملفات webpack (أو عدم وجودها). أعتقد أنني أصلحت هذا مرة واحدة مع Razzle عن طريق إضافة هذا إلى webpack config.

node: {
  fs: "empty";
}

لقد جربت هذا next.config.js ، لكنه يجعل الخطأ يختفي. يبدو على الرغم من أن fs / fs-extra لا يعمل بالفعل ، أو أنه يعمل ، وربما المسارات لا تعمل (غير واضحة بالنسبة لي). أي أفكار في ذلك؟

سؤالي الآخر ، بشكل عام ، هو ما تتخيله أن أفضل الممارسات ستكون لاستخدام الاستيراد مقابل الطلب في getStaticProps . إذا لم أكن مخطئًا ، فسيحاول المقتطف أعلاه استيراد fs-extra في React بشكل متماثل ؟؟. هل من الأفضل بالتالي تغيير الاستيراد إلى طلب مضمّن مثل هذا؟

js Index.getStaticProps = async () => { const fs = require('fs-extra'); // only require when needed at SSG const props = await fs.readdir('./pages/blog'); return { props: { posts } }; };

أعتقد أنك تسيء فهم أن هذا السلوك الجديد يعني أنه يمكنك بالفعل تخزين النتائج الكاملة مؤقتًا على CDN نظرًا لأن CDN يدعم الاستجابات الديناميكية. لم يكن هذا ممكنًا في السابق بشكل موثوق مع getInitialProps.

آه ، أعتقد أنني فهمت ما تعنيه. هل يعني ذلك أن getServerProps على الجيل الأول من SSR سينشئ نقطة نهاية فريدة ، في تجزئة محتوى قابلة للعنونة ، ربما في عنوان URL ، ربما يمكننا بعد ذلك تخزينها مؤقتًا على CDN؟ الجانب السلبي الوحيد لهذا هو أن ذاكرة التخزين المؤقت المذكورة لن تكون قابلة للمشاركة بين التطبيقات غير التالية (android / ios) والتطبيقات التالية. بالإضافة إلى ذلك ، مع مصدر بيانات خارجي ، تكون توجيهات التحكم في ذاكرة التخزين المؤقت أولية ، ولكن هنا نظرًا لأن Next سيتولى مسؤولية تقديم البيانات ، نحتاج إلى واجهات برمجة التطبيقات أو الدعائم لتحديد تلك الخاصة بنقاط نهاية البيانات التي تم إنشاؤها.

jaredpalmer أفترض أن https://github.com/zeit/next.js/issues/9524#issuecomment -558628066 (بما في ذلك قلقي بشأن إمكانية اهتزاز الشجرة الموثوقة ) سيتم حلها من خلال وجود ملف منفصل سيتم تجميعه بشكل منفصل تمامًا عن كود حزمة العميل؟ على سبيل المثال

pages/
    foo.js
    foo.data.js (<- exports getStaticProps etc.)

or:

pages/
    foo.js
pages-data/
    foo.js (<- exports getStaticProps etc.)

لم يتم تنفيذ اهتزاز شجرة jaredpalmer على الكناري بعد.

كما هو الحال دائمًا ، شكرًا لك على كل ما تفعله. لقد كان من دواعي سرور Next.js العمل معها ، وكما قلت من قبل ، يتيح لنا كل إصدار تقريبًا تقريبًا تقليل حجم قواعد الرموز التي أديرها. شيء مذهل.

من الصعب أن تنتقد طلب التعليقات هذا لأنه ، كما هو مكتوب ، مفيد على الفور لعدد كبير من التطبيقات. ومع ذلك ، أريد أن أتناول سطرًا واحدًا لست متأكدًا من أنني أتفق معه:

"يستبدل getStaticPaths الحاجة إلى وجود exportPathMap ويعمل لكل صفحة."

في بعض التطبيقات ، يكون من غير العملي أو المستحيل معرفة المسارات في وقت الإنشاء. بعض الأمثلة ستكون:

  • صفحات ملف تعريف المستخدم
  • صفحات المنتج (للشركات التي لديها مخزون سريع التغير)
  • صفحات تفاصيل أوامر المبيعات

من المحتمل أن تكون مسارات صفحات مثل هذه بالصيغة /entity-name/entity-id وتعمل المسارات الديناميكية لـ Next بشكل جيد حقًا حيث يمكنك القيام بأشياء مثل router.push('/customers/[customerId]', '/customers/baer') . لا يزال هناك صيد. إذا كنت تخطط لخدمة هذه الملفات بشكل ثابت بشيء مثل Serve و Netlify و NGINX وما إلى ذلك ، فستحتاج إلى إنشاء مجموعة من عمليات إعادة التوجيه حتى لا يحصل المستخدمون على 404 عند تحديث الصفحة ، وللقيام بذلك ، لا يزال بإمكانك تحتاج exportPathMap .

يتم نسخ ما يلي ، كما هو تقريبًا ، من قاعدة بيانات أعمل عليها بانتظام:

const buildServeConfig = redirects => {
  const config = {
    public: `dist`,
    trailingSlash: true,
    rewrites: redirects
  };

  const outputPath = `${__dirname}/serve.json`;

  fs.writeFile(outputPath, JSON.stringify(config, null, 2), err => {
    if (err) {
      throw err;
    }
    // eslint-disable-next-line no-console
    console.log(`Generated: ${outputPath}`);
  });
};

...

exportPathMap: function(defaultPathMap, { dev, outDir }) {
  const redirects = Object.entries(defaultPathMap)
    // No need to create a redirect rule for `/dirname/` or `/dirname/index.html`
    .filter(([url]) => url !== `/` && url !== `/index`)
    .map(([url, { page }]) => ({
      // Replaces /[customerId] with /:customerId
      source: url.replace(/]/g, ``).replace(/\[/g, `:`),
      destination: `${page}/index.html`
    }));

  // By default, the routes are sorted such that a route like `/order/:orderId`
  // comes before `/order/new`. Since the `:orderId` portion of `/order/:orderId` 
  // is a wildcard, the route `/order/new` will be a match and consider `new` 
  // as a value for `:orderId`. To get past this, we sort the redirects by the 
  // number of parameters in ascending order.
  const sortedRedirects = [...redirects].sort(
    (currentRedirect, nextRedirect) =>
      currentRedirect.source.split(`:`).length >
      nextRedirect.source.split(`:`).length
  );

  buildServeConfig(sortedRedirects);

  return defaultPathMap;
}

أفهم أن RFC هذا لا يلغي أو يزيل أي واجهات برمجة تطبيقات وأدرك أيضًا أنه من الممكن إنشاء عمليات إعادة التوجيه هذه من خلال اجتياز دليل الإنشاء ، لذلك حتى لو تم إهماله ، فقد حصلت على فتحة ecape لطيفة. لكنها لا "تلغي الحاجة إلى getStaticPaths ."

مرة أخرى ، شكرًا لك على تفكيرك في كيفية إدارة هذا المشروع

هل getStaticProps / getStaticPaths و getServerProps حصريان؟ على سبيل المثال ، هل من الممكن الحصول على جزء معروض مسبقًا وجزء ديناميكي في نفس الوقت؟

نعم هم كما هو واحد هو توليد ثابت وواحد هو تقديم من جانب الخادم.

يعمل هذا على إصلاح أحد الأشياء الكبيرة التي افتقدتها من Gatsby قبل انتقالنا إلى Next:

لدينا ملف JSON متآلف (100s of kbs) نقوم بسحب البيانات منه لعرض صفحاتنا التي لا تتغير أبدًا. في Gatsby ، قمنا بتحميل ملف JSON في مخطط GraphQL واستفسرنا عن ذلك ، فقط أخذنا البيانات التي نحتاجها لعرض صفحة معينة. مع Next ، أسهل / أنظف طريقة وجدناها للقيام بذلك هي import monolith from './monolith.json' ، والتي تتطلب من المستخدم تنزيل ملف JSON بأكمله.

يعالج RFC 100٪ حالة الاستخدام هذه ويجعل الخطوة التالية أقرب إلى أن تكون على قدم المساواة مع Gatsby في المناطق التي يضيء Gatsby (من الواضح أن Gatsby لا يمكنه تشغيل SSR ، لذلك أنا أتحدث فقط عن عروض وقت الإنشاء الثابتة)

timneutkens ، شكرا لك على RFC!

لدي حالة استخدام لـ Next.js ناقشتها مؤخرًا معrauchg.

يسلم Next.js DX سلسًا للغاية وبعض الإعدادات الافتراضية المعقولة. لذلك ، أنا مهتم باستخدام Next.js لتطبيق مُقدم من جانب العميل فقط ، وهو تطبيق Smart TV.

تطبيقات Smart TV هي تطبيقات ويب كلاسيكية تقريبًا يتم تشغيلها بواسطة محرك متصفح التلفزيون:

  1. يتم تجميع التطبيق في حزمة: الأنماط والنصوص والصور و _index.html_ والشهادات وملف تكوين التلفزيون.
  2. يتم إرسال الحزمة إلى متجر تطبيقات النظام الأساسي للمراجعة.
  3. يتم بعد ذلك تثبيت الحزمة من المتجر كتطبيق ويتم تشغيلها بواسطة المستخدم.

الشيء هو أن الحزمة يتم استضافتها بشكل ثابت بواسطة جهاز التلفزيون نفسه ولا يتم تحميلها من الخادم. وبالتالي ، لا يوجد خيار SSR ممكن (لا يتعرض Node.js للمطورين لهذه الأغراض). لكن التطبيق نفسه ديناميكي (على سبيل المثال ، Netflix).

لذلك ، نحتاج إلى تشغيل SPA يستضيفه خادم ويب ثابت.

كما أفهم ، فإن إلغاء الاشتراك في getServerProps (أو getInitialProps ) سيساعد تمامًا على تجنب SSR. ولكن ماذا يحدث مع العرض الديناميكي على العميل؟ وماذا عن التوجيه في هذه الحالة؟ وفقًا لـ RFC هذا ، لم تتم معالجة المشكلة بعد. timneutkens ، هل يمكنك ، من فضلك ، اقتراح أفضل طريقة لتمكين العرض من جانب العميل فقط في Next.js؟ وما إذا كان يناسب Next.js في المقام الأول؟ شكرا!

ملاحظة: يمكنني إنشاء مشكلة لحالة الاستخدام هذه إذا كنت تعتقد أنه من الأفضل مناقشتها بشكل منفصل.

grushetsky هل يمكنك إنشاء إصدار مختلف. هذا سؤال مختلف تمامًا عما تتم مناقشته في RFC

timneutkens يعد وعد RFC هذا أحد الأشياء التي جعلتني متحمسًا جدًا لـ Next! فقط للتوضيح ، سيظل getInitialProps موجودًا أيضًا ، أليس كذلك؟

outdooricon الصحيح - getInitialProps موجودًا في المستقبل المنظور.

حسب RFC:

يناقش RFC حصريًا إضافات API. جميع الوظائف الجديدة متوافقة تمامًا مع الإصدارات السابقة ويمكن اعتمادها بشكل تدريجي. لا يقدم RFC هذا أي إهمال.

RFC رائع ، متحمس جدًا لهذا!

لقد كنت أفكر في getServerProps فيما يتعلق بحالة استخدام معينة ، مع وضع النتائج في ذاكرة تخزين مؤقت. نظرًا لأن هذا يتحول إلى نقطة نهاية API ويتم تسليم النتيجة إلى المكون كدعامات ، فهل هناك طريقة محددة لوضع النتيجة في ذاكرة تخزين مؤقت خارجية مثل Redux و GraphQL-caches وما إلى ذلك من جانب العميل؟

إذا فهمت getInitialProps بشكل صحيح ، نظرًا لأنه ثابت وغير متزامن ، فإن Next لديه الفرصة لانتظار اكتماله قبل عرض المكون لأول مرة. يتيح لنا هذا وضع الأشياء في ذاكرة تخزين مؤقت خارجية هناك. لن يكون هذا هو الحال مع getServerProps نظرًا لأنه يعمل على الخادم ، ويبدو أن وضع الأشياء في ذاكرة تخزين مؤقت في دورة حياة المكون يعني أنه يتعين علينا تقديم عرض حيث لا تتوفر البيانات في ذاكرة التخزين المؤقت حتى الآن ، حتى لو كانت متوفرة في الدعائم؟

قد يكون هذا مقصودًا بالطبع وقد أفتقد طريقة ما ، لكنني اعتقدت أنني سأطلب ما إذا كان هذا شيء تم النظر فيه؟

تحرير: أعتقد أن هذا ينطبق أيضًا على getStaticProps . 😄

ربما فاتني ذلك في مكان ما ، ولكن كيف نتعامل مع المواقف التي يتم فيها تخزين المحتوى مؤقتًا ، ولكن يتم تحديثه في ديسيبل أو إنشاء منشور مدونة جديد؟ هل هناك حاجة لعمل بناء جديد تلقائيًا؟ أظن ذلك.

أولا! اقتراح رائع ، إنه تحسين هائل يزيد عن exportPathMaps في حالة استخدام معظم الأشخاص. إنه حقًا موضع تقدير. مع ذلك ، أجد صعوبة في فهم كيف سنتمكن من جعله يعمل مع تدويل المسار.

هل هناك أي اقتراحات حول كيفية التعامل مع مسارات i18n مسبوقة؟ تتطلب حالة الاستخدام المحددة الخاصة بي إنشاء بضعة آلاف على صفحات بها بادئات مختلفة لعناوين URL و country-lang.

/nl/brillen
/gb/glasses
/es/gafas
...

يبدو أن getStaticPaths سيكون مفيدًا حقًا عندما تكون بادئة عنوان url معروفة جيدًا ، كما في المثال الخاص بك (باستخدام /blog/[id].js ). ولكن كيف تعتقد أن تنفيذ getStaticPaths سيبدو إذا كان يحتاج إلى إنشاء مسارات على مستوى الجذر ، ببادئة ديناميكية (country-lang) ومسار ديناميكي؟

reaktivo pages/[lang]/blog/[id].js -> في getStaticPaths كل عناوين url لعرضها بشكل ثابت.

timneutkens هل من فكرة متى سيكون هذا متاحًا / قابلًا للاختبار؟

بشكل عام ، لا نعطي ETAs لأننا نختبر الميزات على نطاق واسع مقابل تطبيقات الإنتاج للتأكد من أن الحل صحيح.

ستجعلني هذه التحسينات أوقف مشروعي الفينومي "الذي لم يتم الاحتفاظ به" تمامًا (رد فعل ssg الذي لا يستخدمه أحد سواي). من الرائع رؤية Next.js وهو يضيف هذه الأجزاء المفقودة!

أود أن أوضح شك. النظر في استخدام CMS مثل وورد. كما أفهمها ، باستخدام طريقة getStaticPaths ، سأقوم بإحضار جميع المشاركات وتمرير قائمة مثل:

export async function getStaticPaths () {
  return [
    // This renders / blog / hello-world to HTML at build time
    {params: {slug: "hello-world"}}
  ];
}

سيتم استخدام الرابط الثابت لكل منشور في طريقة getStaticProps لجلب المحتوى.
سيحدث هذا في بناء npm.
سؤالي عن المنشورات الجديدة التي ستضاف بعد البناء.
هل سيتم استخدام طريقة getStaticProps لجلب هذا المنشور الجديد بواسطة slug؟
هل ستحتوي هذه المشاركة الجديدة على ملف .html مثل ذلك الموجود في الإصدار السابق؟
أحب العمل مع التالي وفي العديد من المشاريع التي لدي ، سيكون هذا جيدًا جدًا.

لا شيء مرتبط بشكل مباشر ، لكن الدعم غير قادر على إعطائي إجابة تطابق سؤالي.

قد يكون ما تقترحه هنا هو الحل ، ولكن في الوقت الحالي ، لا يمكنني إجراء nextJS لإنشاء JAMSTACK استنادًا إلى تغييرات webhooks.

إذا كان لدي getInitialProps ، فسيتم تقديم الخادم.
إذا لم أفعل ، فأنا مجرد CDNized ، لكن بدون العرض المسبق ليس كذلك؟ وستكون الصفحة بدون محتوى طالما أن XHR لم تعد (وداعًا لتحسين محركات البحث)

هل لديك أي مثال قيد التشغيل الآن من Jamstack مع nextJS ويمكننا القيام به على netlify.

شكرا،
أندرياس

مرحبًا ScreamZ - هذا التغيير ، على ما أعتقد ، هو ما يتيح إنشاء موقع ثابت بالكامل باستخدام nextjs. لقد تمكنا من تجميع موقع nextjs ليكون ثابتًا باستخدام next export لفترة طويلة ، لكنه لا يزال يجلب البيانات على انتقالات المسار من جانب العميل باستخدام getInitialProps . مع القدرة على استخدام getStaticProps ، يمكنك تشغيل انتقالات من جانب العميل دون جلب أي بيانات إضافية - يتم جلب جميع البيانات التي تم جلبها في getStaticProps مرة واحدة ، في وقت الإنشاء ، ولا يتم تحديثها في مباشر ما لم تقم بإعادة البناء مرة أخرى. هذه هي البنية الكلاسيكية للمواقع الثابتة المستندة إلى البيانات ، قم بربط مصدر البيانات الخاص بك بالمضيف الخاص بك عبر webhook وعندما يتغير مصدر البيانات ، فإنك تخبر المضيف بإعادة بناء موقعك.

هناك الكثير من الأمثلة الحالية لمواقع nextjs الثابتة تمامًا ، ومن التافه تشغيل موقع nextjs على netlify. يعمل موقع الويب الخاص بشركتي حاليًا على nextjs ، ويستضيفه netlify ، ونأمل أن يكون هذا مثالًا جيدًا.

تجدر الإشارة إلى أن خدمة الاستضافة في zeit هي أيضًا شيء يستحق النظر فيه بشدة. الأسعار متشابهة تمامًا ، وتكاملها مع مواقع nextjs لا يعلى عليه - لا تحتاج حرفيًا حتى إلى تكوين أي شيء على الإطلاق ، ما عليك سوى ربط github وستدرك استضافة zeit أنك تقوم بتشغيل nextjs وتكوينها ونشرها تلقائيًا كل شىء.

هذا ليس إعلانًا بأي حال من الأحوال ، فأنا لا أعمل من أجل zeit ، بل مجرد تأييد حقيقي. يمكنك بالتأكيد أن تجعله يعمل مع netlify ، وأنا شخصياً لدي العديد من المواقع كدليل. لكنك ستحتاج إلى فهم كيفية عمل nextjs تمامًا ، وستحتاج إلى التأكد من تكوين كل شيء بشكل صحيح لتشغيله بسلاسة على netlify. إذا كنت تبحث عن الاستضافة الأبسط والأكثر مضمونة لموقع nextjs ، فسأجرب استضافة zeit.

jescalan شكرا لك على هذه المشاركة الرائعة 🙏🏻

ليس لدي مشكلة في استخدام NextJS مع netlify ، لأنه يمكنك استخدام Publish directory لتحديد المجلد out . ولكن في zeit Now ، لا توجد طريقة للقول ، من فضلك لا تستخدم SSR ولكن استخدم ثابتًا بالكامل مع next export .

ScreamZ هذا صحيح نوعًا ما ، لكنه يعتمد على كيفية تعريفك بالضبط لموقع "ثابت بالكامل". إذا كنت تستخدم getStaticProps لجميع صفحاتك مع خدمة استضافة zeit ، فإن ما ستحصل عليه يساوي فعليًا موقعًا ثابتًا ، حتى لو لم يتم تشغيله next export ، نظرًا لأن جميع الصفحات التي تحتوي على getStaticProps فقط عند نشر الموقع ، ويتم تقديمها مباشرة من CDN بعد ذلك.

الاختلاف الرئيسي هو أنه على حد علمي لا توجد طريقة لفرض ثبات جميع الصفحات على استضافة zeit (عدل: zeit غيرته مؤخرًا بحيث يتم تشغيل أي موقع به تكوين يحتوي على exportPathMap موقعًا ثابتًا بالكامل ، لذا لم يعد هذا صحيحًا). تتصرف الصفحات التي تحتوي على getStaticProps تمامًا مثل الصفحات التي تم إنشاؤها بواسطة next export - يتم تقديم نسخة ثابتة واحدة من الصفحة مباشرة من CDN في كل مرة. ولكن يمكنك أيضًا تشغيل بعض الصفحات بـ getServerProps أو getInitialProps وستتصرف كصفحات معروضة على الخادم. أنا شخصياً أرى هذا على أنه فائدة - إذا كانت هناك حاجة إلى مسار SSR ، فيمكنك ببساطة استخدام طريقة مختلفة لجلب البيانات وهذا المسار الفردي هو الآن SSR ، بينما يمكن أن تظل جميع مساراتك الأخرى ثابتة.

@ jescalan شكرا ،

لذلك فقط بحاجة إلى الانتظار حتى يتم تنفيذ هذا ، في هذه الأثناء سأستخدم netlify للثابت

هل هناك قصة حول تكوين SSG؟ على وجه التحديد ، نود استخدام عناصر الإنشاء المشتركة ولكن تشغيل next export مع تكوينات مختلفة لـ QA / prod. لن تتم قراءة قيم التكوين هذه إلا في getStaticProps . هل سيستخدم هذا serverRuntimeConfig أو publicRuntimeConfig أو process.env مباشرة؟

هبطتScreamZjescalan لقد-صفر التكوين next export الدعم في الآن معا اليوم معTimer (انه يستحق كل ساعة معتمدة). يمكنك ان تفعل:

"build": "next build && next export"

وسيعمل تلقائيًا.

اسمحوا لي أن أعرف كيف ستسير الامور 🙏

نعم ، لقد كنت الشخص الذي طلب الدعم وأخبروني أن هذا قد تم تنفيذه حتى الآن 😅 بقدر ما أستطيع أن أرى ، ستحتاج إلى تحديد خريطة تصدير في التكوين؟

ScreamZ لا ، يمكنك فقط إضافة next build && next export كما هو موضح أعلاه وستعمل.

timneutkens إذا قمت باستبدال getInitialProps بـ getServerProps ، فهل ما زلت بحاجة إلى إضافة target: 'serverless' إلى ملف التكوين لتمكين Server Pre Rendering ؟ شكرا.

كيف يمكننا أن نجرب هذه؟

كيف يمكننا أن نجرب هذه؟

أعتقد أن كل هذه الطرق تحتاج حاليًا إلى بادئة unstable_ ليتم التعرف عليها.

على سبيل المثال ، unstable_getStaticProps

تضمين التغريدة

هبطتScreamZjescalan لقد-صفر التكوين next export الدعم في الآن معا اليوم معTimer (انه يستحق كل ساعة معتمدة). يمكنك ان تفعل:

"build": "next build && next export"

وسيعمل تلقائيًا.

اسمحوا لي أن أعرف كيف ستسير الامور 🙏

يقوم سكريبت البناء الخاص بي بعمل أشياء أكثر قليلاً ولكن يبدو أنه يعمل مثل السحر:

"build": "graphql codegen && next build && npm run export",

الى جانب ذلك ، إنه رائع! كان هذا بالضبط ما كنت أبحث عنه 😅 (وداعا GatsbyJS ، إطار العمل المفضل لدي هو الآن قوي مثلك!)

شكرا جزيلا لمثل هذا التفاعل.

قمت أيضًا بالترقية إلى 9.1.6 وشاهدت ذلك بدهشة
Screenshot 2019-12-21 at 19 25 43

اعتقدت أن الخيط كان RFC ، يبدو أنه مفتوح لنا بالفعل ، أليس كذلك؟
ومع ذلك ، لا يتم تمكين أنواع Typescript في 9.1.6.

اللعنة ، أنا متحمس جدًا لذلك الآن! 🤣

الأسئلة الأخيرة:

  • إذا حصلت عليه ، سيتم إهمال getInitialProps في المستقبل؟ أم أنها لا تزال ذات صلة في بعض الحالات؟ مثال؟
  • يمكن أيضًا إهمال next export لصالح الصفحات التي بها getStaticProps و next build فقط؟

شكرا لهذه الأداة الرائعة 🙏🏻

إذا حصلت عليه ، سيتم إهمال getInitialProps في المستقبل؟ أم أنها لا تزال ذات صلة في بعض الحالات؟ مثال؟

كما قيل في RFC الأولي:

يناقش RFC حصريًا إضافات API. جميع الوظائف الجديدة متوافقة تمامًا مع الإصدارات السابقة ويمكن اعتمادها بشكل تدريجي. لا يقدم RFC هذا أي إهمال.

اعتقدت أن الخيط كان RFC ، يبدو أنه مفتوح لنا بالفعل ، أليس كذلك؟

الأمر ليس كذلك ، فنحن نجربه على تطبيقات ZEIT وقد هبطت بالفعل بعض مظاهر الرؤية (على سبيل المثال ، شجرة الصفحات التي رأيتها).

يمكن أيضًا إهمال التصدير التالي لصالح الصفحات التي تحتوي على getStaticProps والإصدار التالي فقط؟

صحيح ، بشكل عام ستنتهي فقط بعدم استخدام next export . سيتم الاحتفاظ بها لسبب التوافق العكسي ولكن بشكل عام سترغب في إنشاء تطبيق مختلط لأنه يمنحك جميع مزايا التصدير مع دعم ميزات أخرى مثل مسارات API واختيار العرض من جانب الخادم لبعض الصفحات.

كيف يمكننا أن نجرب هذه؟

أعتقد أن كل هذه الطرق تحتاج حاليًا إلى بادئة unstable_ ليتم التعرف عليها.

على سبيل المثال ، unstable_getStaticProps

نوصي بشدة بعدم استخدامه حتى الآن ، فهو تجريبي ويمكن أن ينفصل بين الإصدارات.

لذلك كنت ألعب بهذه الميزة ولاحظت أن ملف JSON الذي يحتوي على بيانات الصفحة يتم جلبه دائمًا بعد الوصول إلى صفحة SSG من صفحة أخرى.

هل تخططون أي تحسين مسبق للتحميل لملف JSON؟
ربما يتم تحميله مسبقًا عندما يكون المستخدم على وشك الانتقال إلى الصفحة (على سبيل المثال: يحوم المستخدم فوق ارتباط SSG) أو يقوم بالتحميل المسبق تمامًا كما تقوم بالتحميل المسبق لصفحات js الأخرى المشار إليها من مكون الارتباط.

أحب هذه الميزة بالمناسبة!

هل تخططون أي تحسين مسبق للتحميل لملف JSON؟

نعم فعلا.

لما يستحق ، أنا جميعًا مع الصادرات القابلة للتهتز من هذه funcs بدلاً من الملفات المنفصلة.

ما هي حالة هذه الميزة؟ ما هي حاصراته؟

mikestopcontinues يتم حاليًا اختبار RFC بشكل مكثف داخليًا من قبل فريقنا وبعض الشركاء المختارين. يمكنك الاشتراك في سلوكها التجريبي للغاية باستخدام البادئات unstable_ ، كما هو مذكور أعلاه ! 😄

يُرجى عدم ترحيل أعباء عمل الإنتاج إلى الأساليب الجديدة بالرغم من ذلك ، حيث لا يزال بإمكاننا تحديث واجهات برمجة التطبيقات بطرق متقطعة.

أنا شخصياً أستخدمه لإنشاء مواقع ثابتة من 8 إلى 20 ألف صفحة (مع إمكانية الحصول على بعض الطلبات الديناميكية في بعض الصفحات). إنه يعمل جيدًا (باستثناء الحد الأقصى لملفات 10K في الآن) ، الشيء الوحيد الذي أجده مخزيًا هو أنه بدون طريقة getStaticPaths ، يتم استدعاء getStaticProps عند كل عملية إعادة تحميل. أحد السلوكيات التي يمكن أن تكون جيدة هو أن المكالمة الأولى تنشئ ملف json والأخرى تستخدمه.

هل تم التخطيط للبناء الإضافي؟ لذلك فقط المحتوى الجديد / المتغير هو إعادة البناء؟

يمكنك الاشتراك في سلوكها التجريبي للغاية باستخدام البادئات unstable_ ، كما هو مذكور أعلاه !

أرغب في اختبار طريقة unstable_getServerProps ، لكن يبدو أنه تم تجاهلها في الوقت الحالي ، ولا يمكنني العثور عليها في أي مكان في zeit/next.js repo. هل لم يتم تطبيقه بعد ، أم أنني أفعله بشكل خاطئ؟

هل تم التخطيط للبناء الإضافي؟ لذلك فقط المحتوى الجديد / المتغير هو إعادة البناء؟

تم تصميم التطبيق مع وضع عمليات إعادة البناء الإضافية في الاعتبار ، ولكنه لم يتم دعمه بعد (ولم يتم تغطيته في RFC).

كن مطمئنًا ، الهندسة المعمارية جاهزة وسنستكشف هذا بعد استقرار هذه الميزات.
هذا هو سبب تحديد getStaticProps لكل صفحة ، وليس مرة واحدة للتطبيق بأكمله!

أرغب في اختبار طريقة unstable_getServerProps ، ولكن يبدو أنه تم تجاهلها في الوقت الحالي [...]

getServerProps غير متوفر في المعاينة بعد ، آسف!

getServerProps غير متوفر في المعاينة بعد ، آسف!

وذلك بفضل لرؤساء متابعة. سأشاهد بالتأكيد هذا الموضوع ، لأنه عندما تصل إلى الأرض لدي _ مجموعة _ من التعليمات البرمجية التي يمكن استبدالها بإعادة تسمية وظيفة واحدة! 😍

يُرجى التوضيح ، لست متأكدًا بنسبة 100٪ ما إذا كان getServerProps / getStaticProps متاحًا حاليًا للاستخدام أم لا.

بناءً على هذا الموضوع:

ولكن إذا كان الأمر كذلك ، فأنا أتساءل لماذا ألمح الجهاز الخاص بي إلى ذلك عندما قمت بتشغيل next build إذا لم تكن متوفرة بعد؟ لقد تركتني رؤية الرسالة بافتراض العمل الأولي بأن هذه الأساليب كانت قيد الإنتاج ، واستغرق الأمر بعض الوقت لأكتشف أنها ليست كذلك. فقط أشعر بالفضول حول المنطق أو إذا كان هناك شيء أسيء فهمه.

λ  (Server)  server-side renders at runtime (uses getInitialProps or getServerProps)
○  (Static)  automatically rendered as static HTML (uses no initial props)
●  (SSG)     automatically generated as static HTML + JSON (uses getStaticProps)

(في الإصدار التالي 9.1.6)

شكرا

stevenjchang إنهم متاحون باستخدام الصيغة التالية في pages/**/*.js :

export function unstable_getStaticPaths() {} // return [{params: {...}}, ...]
export function unstable_getStaticProps({params: {...}) {} // return {props: {...}}

ويجب أن أضيف أيضًا ، أنها رائعة ، على الرغم من أنها لا تزال صعبة بعض الشيء عند استخدام خادم dev.

على الرغم من أنها لا تزال صعبة بعض الشيء عند استخدام خادم dev.
تضمين التغريدة

هل يمكنك توضيح هذا من فضلك؟ لم يعطنا أي شخص آخر تعليقات سلبية حول تجربة خادم dev ، ونود حلها!

Timer أنا حقا أحب API الجديد. مشكلتي الرئيسية أثناء التطوير هي إعادة طلب json عند كل تحميل. يؤدي هذا إلى إبطاء الاختبار ، ولكنه أيضًا يشوه تجربة المستخدم عند تصفح الموقع فعليًا.

بعبارة "عند كل تحميل" تقصد تحميل الصفحة؟ أم إعادة البناء؟ أو...؟

mmmeff في كل مرة تنتقل فيها إلى نفس المسار ، فإنها تعيد طلب json. لذلك إذا نقرت ذهابًا وإيابًا بين صفحتين ، فإنك تقضي وقتًا طويلاً في انتظار البيانات.

mikestopcontinues هذا هو السلوك المقصود ، حيث غالبًا ما تكون أحدث البيانات هي الأفضل في التطوير. سيكون منفتحًا لمناقشة بعض الأساليب الاستدلالية الأفضل في إصدار جديد!

timneutkens هذا RFC يبدو واعدًا جدًا. لدي بعض الأسئلة / المخاوف بشأن الأمان ، وكيف يعمل بالضبط.

لنأخذ حالة عمل عامة تعتمد على SSR و SSG.

مفهوم

نريد عرض بعض المعلومات على موقع ويب ("تطبيق" AKA).
يتم تخزين هذه المعلومات في BDD التي يمكن الوصول إليها من خلال واجهة برمجة تطبيقات GraphQL.
بعض هذه المعلومات عامة ، وبعضها خاص (على سبيل المثال: البريد الإلكتروني للمستخدم / كلمة المرور).

يستخدم التطبيق مرحلتين:

  • مرحلة "التدريج" ، حيث يمكن للعميل رؤية التغييرات في الوقت الفعلي في تطبيق التدريج (يقومون بتحديث هذه المعلومات من خلال بعض المكاتب الخلفية أو ما شابه ذلك)
  • مرحلة "الإنتاج" ، حيث لا يمتلك العميل أي وصول ولا يمكنه تحديث أي شيء بنفسه. لتحديث تطبيق الإنتاج ، يجب إجراء عملية نشر جديدة. (يطلبون نشر إنتاج جديد ، من مكتبهم الخلفي المذكور)

في هذا السيناريو ، نستخدم SSR و SSG:

  • يستخدم تطبيق التدريج SSR ، لأنه يجلب البيانات في الوقت الفعلي من واجهة برمجة تطبيقات GraphQL (عند إنشاء صفحة)
  • يستخدم تطبيق الإنتاج SSG ، لأنه عند إجراء نشر جديد ، فإنه يجلب البيانات من واجهة برمجة تطبيقات GraphQL وينشئ صفحات ثابتة منها (وبالتالي فهي ثابتة ولن تتغير بعد الآن ، ولن يتم إجراء أي استعلام إلى واجهة برمجة تطبيقات GraphQL في وقت التشغيل (على الأقل ليس عند تحميل الصفحة))

يجب أن يكون هذا السيناريو عامًا بدرجة كافية ، ويجب أن يكون (IMHO) أحد حالات الاستخدام الرئيسية لاستخدام SSG.
لا يعد تطبيق الإنتاج أكثر من لقطة من التطبيق المرحلي.

بعض الأسئلة:

  1. هل هذا ممكن مع RFC هذا ؟ وجود نفس التطبيق يتصرف بشكل مختلف بناءً على "مرحلة" معينة (الإنتاج / التدريج)
  2. كيف يتم إدخال البيانات التي يتم جلبها من واجهة برمجة تطبيقات GraphQL؟

    • في التدريج ، يتم جلبها ديناميكيًا من خلال SSR أو CSR أثناء تنقل المستخدم عبر الصفحات (وستكون متاحة على المتصفح إذا تم جلبها أثناء CSR)

    • في الإنتاج ، يتم جلبها في وقت الإنشاء ، ولكن بعد ذلك ، هل يتم تخزينها داخل متغير عالمي JS وبالتالي يمكن قراءتها من قبل أي شخص؟ (مخاوف أمنية ، حيث يجب أن ندرك عدم إحضار البيانات الحساسة التي قد تكون متاحة على المتصفح ، على غرار كيفية القيام بذلك عند استخدام CSR)

  3. هل لديك أي قلق من هذا النهج مع SSR / SSG المختلط؟ (الأمان ، الأداء ، الصيانة ، إلخ.)

متى تخطط للافراج عن هذا؟ هل سيكون تحديثًا رئيسيًا (الإصدار 10) ، أم تحديثًا متوافقًا مع الإصدارات السابقة؟

مهلا،

هل جرب أي شخص هذا الحل باستخدام خادم مخصص وجعله يعمل؟

مثال:

// server.js

const express = require('express');
const next = require('next');

const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();

app.prepare().then(() => {
  const server = express();

  server.get('/blog/:id', (req, res) => {
    console.log('My params needed be passed to page:', req.params);
    return app.render(req, res, '/blogDetail', { id: req.params.id });
  });

  server.listen(port, err => {
    if (err) throw err;
    console.log(`> Ready on http://localhost:${port}`);
  });
});

// blogDetail.js
export async function unstable_getStaticProps(props) {
  console.log('What is passed', props);

  return {};
}

const BlogPostPage = ({ post }) => {
  return <div>Hey</div>;
}

export default BlogPostPage;
# Terminal output

My params needed be passed to page: { id: 'test' }
What is passed { params: undefined }

لماذا لا يستطيع getStaticProps تضمين سلسلة الاستعلام؟ لدي حاليًا صفحة يجب أن أقوم بها لـ SSR ببساطة للحصول على معلمات الاستعلام دون إعادة تصيير. يؤدي استخدام الخطاف useRouter إعادة تصيير متعددة ، لأن الاستعلام في البداية عبارة عن كائن فارغ. هذه صفحة تُستخدم لتتبع التحويل ، ومن الواضح أنها ليست بداية.

pjaws يذكر RFC على وجه التحديد getStaticProps للجيل الثابت. لا يمكن أن يتلقى HTML الثابت سلسلة استعلام.

إذن لماذا يمكنه تلقي معلمات عناوين URL الديناميكية؟ كيف يختلف هذا عن غيره؟

يوم الثلاثاء 14 يناير 2020 الساعة 1:30 صباحًا Tim Neutkens [email protected]
كتب:

pjaws https://github.com/pjaws RFC الذي يذكره على وجه التحديد
getStaticProps مخصص للجيل الثابت. لا يمكن أن تتلقى HTML الثابت ملف
سلسلة الاستعلام.

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/zeit/next.js/issues/9524؟email_source=notifications&email_token=AMVRRIQCKDJNF4MPWSLYNV3Q5WA2NA5CNFSM4JRPBEL2YY3PNVWWK3TUL52HS4DFVREXG43VMVB3940
أو إلغاء الاشتراك
https://github.com/notifications/unsubscribe-auth/AMVRRIRJXLYC4MC4U7DH7NDQ5WA2NANCNFSM4JRPBELQ
.

لأنه في getStaticPaths عليك إرجاع الصفحات التي سيتم عرضها في وقت الإنشاء.

تبدو هذه التغييرات واعدة جدًا ، وعمل رائع كما هو الحال دائمًا! 👍

أتساءل عن حالة استخدام وجود getInitialProps في _app.js لتلبية احتياجات البيانات المشتركة عبر الصفحات (مثل إعداد موفري السياق). هل أفهم بشكل صحيح أنه من المستحيل استخدام getStaticProps بنفس الطريقة؟ من الممكن فقط تحديده في صفحات فردية؟

أتساءل عن حالة استخدام getInitialProps في _app.js لتلبية احتياجات البيانات المشتركة عبر الصفحات (مثل إعداد موفري السياق). هل أفهم بشكل صحيح أنه من المستحيل استخدام getStaticProps بنفس الطريقة؟ من الممكن فقط تحديده في صفحات فردية؟

صحيح ، في البداية سيكون للصفحات الفردية فقط. قد يعيد النظر في وقت لاحق. سيستمر استدعاء getInitialProps لـ _app عند التصدير إلى HTML ثابت حتى تتمكن من الانتقال تدريجياً إلى getStaticProps.

مرحبًا يا رفاق ، سؤال واحد ذي صلة - كيف سيتم التعامل مع الأصول؟ لأنني أرى الآن أنه إذا كنت أستخدم نظام إدارة محتوى بدون رأس (حتى لو كانت وورد أو رسوم بيانية أو أي شيء آخر) ، فسيتم استخدام عنوان url الخاص بالأصل في html الثابت.

هناك نوعان من التفضيلات هنا - يتم استخدام روابط الأصول على هذا النحو.
ولكن على الأرجح - قم بتنزيل الأصل ، وقم ببناء html (رابط إليه محليًا) ثم ضع شبكة CDN في المقدمة. هذه هي الممارسة الأكثر قبولًا بكثير.

يرتبط هذا أيضًا بشكل جيد باستخدام أنظمة النشر مثل Netlify - التي تتمتع ببنية تحتية متاحة عالميًا أكثر ملاءمة بكثير من أي شيء مثل DatoCMS أو Graphcms. لذلك إذا كنت تستخدم Netlify كنشر ، فأنا أرغب في تقديم كل شيء من نطاق Netlify والسماح له بعمل سحره.

sandys إذا فهمت بشكل صحيح في https://github.com/zeit/next.js/issues/9054#issuecomment -570427085 فمن المفترض أن تقوم بتنزيل الأصول وتخزينها تحت .next/static وإنشاء رابط نفسك في getStaticProps .

هناك أيضًا فكرة وجود مسارات ثابتة لواجهة برمجة التطبيقات ، لكنني لست متأكدًا تمامًا من كيفية التحكم في سلوك التخزين المؤقت للمتصفح بهذا.

Janpot شكرا

الرجاء إضافة طلبي إلى وجود هذا مدمج. ربما يكون # 9054 أكثر عمومية ، لكنني أفكر من منظور SSG وهذا ضروري للغاية.

نسيت أن أذكر ، لكن تجزئة الأصول ستكون ضرورية أيضًا لـ SSG.

homoky ، لم أتمكن من الحصول على هذا العمل ، هل أحرزت أي تقدم في هذه الأثناء؟

homoky ، لم أتمكن من الحصول على هذا العمل ، هل أحرزت أي تقدم في هذه الأثناء؟

هذا غير ممكن وليس مخططًا أيضًا: # 10071

😢

sandys في الواقع الحل أبسط بكثير عند استخدام https://github.com/zeit/next.js/issues/9081 لإضافة إعادة كتابة من على سبيل المثال /images إلى نظام إدارة المحتوى. على سبيل المثال ، على ZEIT الآن ، ستقوم بالفعل بتخزين النتيجة مؤقتًا عند إضافة الرؤوس الصحيحة ، ولا حاجة إلى تنزيل إضافي (عبء ضخم عند الإنشاء).

timneutkens شكرا على الرد.
لست متأكدا تماما ما تعنيه. لذلك نحن نستخدم netlify - هل تقترح أن نحتفظ بعناوين URL CMS على هذا النحو ونقدم طبقة من CDN فوقه؟
لست متأكدًا تمامًا مما إذا كان netlify (الواجهة السحابية التي نخطط لاستخدامها) يمكنها العمل بسلاسة مع جميع هذه الخدمات.

إذا تم تنزيل الصور وجعلها جزءًا من النشر ، فسيتم تبسيط هذه المشكلة برمتها بشكل كبير. لأنني أقوم بإعداد CDN للتخزين المؤقت من عنوان url الأساسي (والذي سيتم تقديمه في حالتي من s3).

لست متأكدًا تمامًا مما إذا كان الحل الخاص بك يعتمد علي باستخدام Zeit NOW

إذا تم تنزيل الصور وجعلها جزءًا من النشر ، فسيتم تبسيط هذه المشكلة برمتها بشكل كبير. لأنني أقوم بإعداد CDN للتخزين المؤقت من عنوان url الأساسي (والذي سيتم تقديمه في حالتي من s3).

هذا في الواقع يجعل عملية البناء أكثر تعقيدًا وأبطأ بمقدار 10 مرات ، وبالتأكيد ليس أبسط.

لست متأكدًا تمامًا مما إذا كان الحل الخاص بك يعتمد علي باستخدام Zeit NOW

يعمل مع كل وكيل في العالم. بما في ذلك Cloudfront.

timneutkens نحن

أنا بالتأكيد لا أدعو إلى تشغيل هذا للجميع. سيكون الكثير من الناس سعداء بالارتباط العميق بنظام إدارة المحتوى. لكننا ندير موقعًا عالي الحركة وهذا بالتأكيد شيء تحتاجه مواقع مثلنا.

أيضا ، سامحني ، لكنني لم أفهم الحل الخاص بك. كيف يجب علينا تكوين هذا؟ أنا لا أملك السيطرة على عنوان url الذي يستخدمه نظام إدارة المحتوى. على سبيل المثال ، يبدأ Datocms في العرض من

نحن حياديون في وقت عملية البناء في الواقع. لا يهم إذا استغرق وقتا أطول

قد يكون هذا صحيحًا بالنسبة لتطبيقك ، ولكن هذا ليس هو الحال بالنسبة لغالبية التطبيقات.

ولكن لأسباب عديدة (بما في ذلك جميع الأصول التي يتم عرضها من خلال عنوان URL أساسي معروف) ، سيكون من المفضل للغاية أن يتم خبز هذا في الإصدار.

ليس من الضروري أن تكون كما قيل ، يمكنك استخدام إعادة كتابة تلك الوكلاء /images/* إلى عنوان url الخاص بـ cms ، على سبيل المثال www.datocms-asset.com/* أو ما شابه. ثم اربط كل الصور باستخدام /images .

لاحظ أن هذا بدأ في الخروج عن الموضوع.

sandys في الواقع يكون الحل أبسط بكثير عند استخدام # 9081 لإضافة إعادة كتابة من على سبيل المثال / الصور إلى نظام إدارة المحتوى. على سبيل المثال ، على ZEIT الآن ، ستقوم بالفعل بتخزين النتيجة مؤقتًا عند إضافة الرؤوس الصحيحة ، ولا حاجة إلى تنزيل إضافي (عبء ضخم عند الإنشاء).

timneutkens فقط

  1. تحسين الصور
  2. تجزئة الصور وتقديمها تحت هذا التجزئة
  3. توفير خريطة من عنوان url للصورة إلى عنوان url للصورة المجزأة التي يمكن تنزيلها في getStaticProps لإعادة تعيين عناوين url للصورة إلى نظيرتها الثابتة على نظام إدارة المحتوى

وهو ما أعتقد أنه ليس مستحيلاً. فقط تريد التأكد من أن هذا هو الإعداد المقترح.

يتعامل مقدمو

قد يكون هذا صحيحًا بالنسبة لتطبيقك ، ولكن هذا ليس هو الحال بالنسبة لغالبية التطبيقات.

مرة أخرى ، أنا لست وحدي هنا. هناك الكثير من الطلبات المماثلة. أنا أطلب منك أن تفكر في هذا.

https://spectrum.chat/next-js/general/how-would-you-handle-importing-remote-images-on-nextjs-static-export~30b2ba84-bc27-4da7-9ec8-21e4d5d287a3

على جانب gatsby أيضًا - https://github.com/gatsbyjs/gatsby/issues/14076

https://spectrum.chat/gatsby-js/general/adding-remote-images-during-node-creation~e704e6fb-24b2-46c6-b1fc-93189d2e28a4

https://github.com/njosefbeck/gatsby-source-stripe/#downloading -files

sandys هذا غير مرتبط بـ SSG RFC لذا لا تتردد في إنشاء مشكلة جديدة عند إصدارها.

ومع ذلك ، أردت فقط أن أذكر أنه في أذهاننا جميعًا ، يرتبط هذا ارتباطًا وثيقًا بـ SSG. نظرًا لأن الحالة المثالية هي أن يقوم أمر تصدير SSG بذلك. هذا ليس ضروريًا في حالات أخرى بشكل عام.
أفضل حالة هي أن تكون هذه ميزة اختيارية أثناء التصدير التالي.

ولكن ، كما يحلو لك - احترم قرارك.

لكنه شيء لا يفعله حتى الآن next export . ولهذا السبب هو شيء جديد تمامًا ولا علاقة له بـ RFC هذا.

كما أنه لن يكون مع getServerProps والعرض عند الطلب.

يتعامل مقدمو

👍 نعم ، هذا منطقي. ولكن هذا يعني أيضًا أنه إذا كنت تستخدم الصور في مشروعك وتريد تحسينها وتخزينها مؤقتًا ، فلديك خياران:

  1. بناء حزمة ويب مخصصة
  2. استخدام CMS خارجي

تعديل:

وإذا فهمت بشكل صحيح، file-loader مدرج بالفعل لCSS. ألا يتعلق الأمر بتمكينه لـ JS أيضًا؟

Janpot ، النقطة المحددة التي ذكرها Sandeep هي أن عناوين url ستأتي من مصدر خارجي ، وليس من المشروع نفسه. تضمين أداة تحميل الملفات بشكل افتراضي هو طلب ميزة مختلف.

لقد لاحظت أنه بالنسبة للمواقع التي تم نشرها في ZEIT الآن ، عندما يكون لدي صفحة بها عنوان URL ديناميكي باستخدام واجهات برمجة التطبيقات الثابتة الجديدة ، للصفحات التي لم يتم إنشاؤها بشكل ثابت باستخدام unstable_getStaticPaths ، الوظيفة unstable_getStaticProps يعمل

على سبيل المثال ، لدي صفحة /blog/[slug].js ، تعرض getStaticPaths بها المصفوفة:

[{ params: { slug: 'hello' } }]

ولدى getStaticProps بعض المنطق لقراءة ملف يعتمد على slug. عندما أقوم بزيارة /blog/hello ، يتم عرض الصفحة مسبقًا كما هو متوقع ، ولكن عندما أزور صفحة غير صالحة مثل /blog/doesnt-exist ، يتم تشغيل getStaticProps في وقت التشغيل ويظهر لي الخطأ 500 ، بدلاً من أ 404. أو إذا أضفت معالجة الأخطاء ، فسيتم عرض الصفحة بدلاً من 404 ، على الرغم من عدم إدراجها في الإخراج من getStaticPaths .

هل هذا المنطق مقصود؟

هذا تحسن عظيم كنا على وشك كتابة بعض نصوص ما قبل الإنشاء للقيام بذلك.
لقد اختبرت للتو نقل أحد مواقعنا إلى unstable_getStaticPaths و unstable_getStaticProps في 9.2 التالي ، وقد نجح الأمر.

لدينا انحدار واحد مقارنة بـ exportPathMap : عند إنشاء مسار باستخدام exportPathMap ، يمكنك تحديد شيء مثل هذا:

{
 "/path/to/page": {page: "/index", query: { pageId: 123 } }
}

وسوف يبني البناء الثابت

/path
   /to
     /page
       index.html

عند إرجاع المكافئ من unstable_getStaticPaths في القالب [slug].jsx ،

[{ slug: '/path/to/page' }]

ينشئ 9.2 التالي '٪ 2Fpath٪ 2F to٪ 2Fpage` بدلاً من الدلائل المتداخلة.

/%2Fpath%2Fto%2F
   index.html

يعد إنشاء الأدلة (مطابقة سلوك exportPathMap الحالي) أمرًا مهمًا لكيفية إنشاء الصفحات. نحن نستخدم ملف قالب واحد ولكن المسار المنشور قد يكون متداخلاً بشكل عشوائي.

dpfavand في هذه الحالة ، سترغب في استخدام مسار شامل: https://nextjs.org/blog/next-9-2#catch -all-dynamic-route

من المحتمل أن نحذر عند محاولتك إرجاع مسار يشتمل على خطوط مائلة ، ولكن السلوك صحيح عند استخدام [slug].js ، في حالتك أنت تريد [...slug].js .

متى من المتوقع أن يهبط هذا؟ هل سيكون في تصحيح 9.2 أم أنه إصدار ثانوي خاص به؟

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

نظرًا لأنها ميزة جديدة ، فستكون ثانوية.

نعم ، كنت أفهم ذلك عادةً ولكن المدونة 9.1.7 أعطت الانطباع
كان بالفعل في البرية.

يوم الجمعة 17 يناير 2020 الساعة 5:05 مساءً Tim Neutkens [email protected]
كتب:

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

-
أنت تتلقى هذا لأنك علقت.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/zeit/next.js/issues/9524؟email_source=notifications&email_token=ADKINGF724256WCEFHBFIH3Q6ITRXA5CNFSM4JRPBEL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW13
أو إلغاء الاشتراك
https://github.com/notifications/unsubscribe-auth/ADKINGBVCG6MFMOG5U2FGMDQ6ITRXANCNFSM4JRPBELQ
.

>

لاسيتر جريج
[email protected] [email protected]
الخلية (832) 495-9903

هل هناك أي شيء مثل getStaticProps ولكن يتم تشغيله مرة واحدة فقط للتطبيق بأكمله بدلاً من كل صفحة؟

حالة الاستخدام الخاصة بي هي أن لدي سياق رد فعل ( PricingPlansContext ) يتم استخدامه بواسطة صفحات متعددة وأريد استرداد البيانات (خطط التسعير) من الخادم الخارجي مرة واحدة فقط ، في وقت الإنشاء ( next export ). أبدًا في وقت التشغيل ودون الحاجة إلى الإضافة إلى getStaticProps من كل صفحة.

تحرير: وجدت تعليقًا ذا صلة أعلاه: https://github.com/zeit/next.js/issues/9524#issuecomment -574179540. نأمل أن يتم النظر فيه.

أنا استخدم babel plugin-popular` لذلك ، على الرغم من أنني رأيت أيضًا أشخاصًا يكتبون a
json داخل exportPathMa () مع next.config.js ، ثم يقومون باستيراده
ضمن التعليمات البرمجية الخاصة بهم.

انتهى بي الأمر بكتابة ملف json باستخدام برنامج نصي npm في الوقت الحالي ، ولكن شكرًا لاقتراح exportPathMap ، ربما يكون هذا مكانًا أفضل.

dpfavand في هذه الحالة ، سترغب في استخدام مسار شامل: https://nextjs.org/blog/next-9-2#catch -all-dynamic-route

من المحتمل أن نحذر عند محاولتك إرجاع مسار يشتمل على خطوط مائلة ، ولكن السلوك صحيح عند استخدام [slug].js ، في حالتك أنت تريد [...slug].js .

timneutkens شكرا على المتابعة. لقد جربت طريقتين دون جدوى. بشكل أساسي عند تحديد قيمة slug كسلسلة في getStaticPaths ، لا يتم تمريرها إلى getStaticProps على الإطلاق. عند إرجاع قيمة slug كمصفوفة ، يفشل البناء لأن القيمة يجب أن تكون سلسلة.

الحالة 1 ، بافتراض وجود ملف pages/[...slug].jsx ، slug كسلسلة:

export async function unstable_getStaticPaths() {
    return [{ params: { slug: 'en/about' } }];
}

export async function unstable_getStaticProps({ params }) {
    console.log('params', params);
    return { slug: params.slug };
}

في الحالة أعلاه ، params في getStaticProps كائن فارغ - لا يوجد مفتاح slug .

الحالة 2 ، pages/[...slug].jsx ، سبيكة صلبة كمصفوفة ،

export async function unstable_getStaticPaths() {
    const allPaths = Object.keys(pathMap).map(slug => ({ params: { slug } }));
    return [{ params: { slug: ['en', 'about'] } }];
}
export async function unstable_getStaticProps({ params }) {
    console.log('params', params);
    return { slug: params.slug };
}

في الحالة الثانية ، يفشل الإنشاء مع

> Build error occurred
{ Error: A required parameter (slug) was not provided as a string.
    at _validParamKeys.forEach.validParamKey (/project/node_modules/next/dist/build/utils.js:21:569)
    at Array.forEach (<anonymous>)
    at toPrerender.forEach.entry (/project/node_modules/next/dist/build/utils.js:21:495)
    at Array.forEach (<anonymous>)
    at Object.isPageStatic (/project/node_modules/next/dist/build/utils.js:17:122)
    at process._tickCallback (internal/process/next_tick.js:68:7) type: 'Error' }

لا أرى سوى معلمات المسار في أمثلة getStaticPaths أعلاه. هل سيكون من الممكن لمسارات SSG التي تتضمن معلمات الاستعلام؟ على سبيل المثال:

/store/widgets/circles-n-squares?sort=price&minWeight=2&color=black

أفكر بشكل خاص من منظور موقع التجارة الإلكترونية ، حيث سيكون من الصعب تغطية كل جانب من جوانب البحث عن المنتج في pathname لعنوان url.

لقد قمت بنشر رسالة هنا مؤخرًا ولم أتلق أي رد - بشكل أساسي ، يتصرف getStaticProps مثل getServerProps عند نشر موقع إلى ZEIT Now (أي تجاهل getStaticPaths والتعامل مع الطلبات ديناميكيًا) - أعتقد أن هذا خطأ؟

dpfavand أواجه نفس الشيء أيضًا! محاولة إنشاء موقع بداية لـ agilitycms و nextjs مع توجيه ديناميكي للصفحة استنادًا إلى الصفحات الموجودة في نظام إدارة المحتوى.

timneutkens شكرا على المتابعة. لقد جربت طريقتين دون جدوى. بشكل أساسي عند تحديد قيمة slug كسلسلة في getStaticPaths ، لا يتم تمريرها إلى getStaticProps على الإطلاق.

الحالة 1 ، بافتراض وجود ملف pages/[...slug].jsx ، slug كسلسلة:

export async function unstable_getStaticPaths() {
  return [{ params: { slug: 'en/about' } }];
}

export async function unstable_getStaticProps({ params }) {
  console.log('params', params);
  return { slug: params.slug };
}

في الحالة المذكورة أعلاه ، params في getStaticProps كائن فارغ - لا يوجد مفتاح slug .

راجع للشغل ، عالم صغير! شكرا مرة أخرى للتحدث في fastr_conf.

مرحبا timneutkens ،

أنا متحمس جدًا لفكرة جعل next.js يتصرف مثل مولد موقع ثابت.

أود أن أسأل كيف يمكن استخدام طرق getStaticProps و getStaticPaths في حالة طلب جزء كبير من البيانات مرة واحدة ثم استخدامها لإنشاء صفحات مختلفة.

على سبيل المثال ، أنا أستخدم عميل JavaScript SDK لنظام إدارة المحتوى المستند إلى API والذي يحتوي على طريقة لجلب جميع الكائنات المتاحة. بعض هذه الكائنات تمثل صفحات الموقع.

const entries = await cmsSdkCient.getEntries();

حتى الآن ، كنت أستخدم طريقة exportPathMap لجلب جميع الإدخالات من CMS مرة واحدة وإنشاء خريطة بين مسارات هذه الصفحة وبياناتها. تقوم الوظيفة exportPathMap بأمرين:

  1. يوفر خريطة للصفحات ببياناتها و ssr: true الذي يتم استهلاكه بواسطة getInitialProps في وقت التصدير
  2. يكتب نفس البيانات ، هذه المرة بـ ssr: false ، إلى ملفات init-props.json ، موضوعة في المجلد المطابق لمسار كل صفحة. بعد ذلك ، عندما يتم استدعاء getInitialProps من العميل ، يتم تحميل البيانات المطلوبة من init-props.json للصفحة المتطابقة.


next.config.js باستخدام exportPathMap

module.exports = {
  exportTrailingSlash: true,
  exportPathMap: (defaultPathMap, { outDir }) => {
    // load data from CMS
    const objects = await cmsSdkCient.getEntries();

    // create map between page paths and page data
    return objects.reduce((accum, object) => {

      // if the object does not have a slug, it is not a page
      if (!object.slug) return accum;

      const pagePath = '/' + object.slug;
      const ssrQueryData = Object.assign({ ssr: true }, object);
      const clientQueryData = Object.assign({ ssr: false }, object);

      // generate the map for export phase with {ssr: true}
      accum[pagePath] = {
        // using additional fields from the page object,
        // the pageFromPagePath() computes which page file should
        // be used to render the page object
        page: pageFromPagePath(object),
        query: ssrQueryData
      };

      // write json files that will be loaded by client
      if (outDir) {
        const jsonFilePath = path.join(outDir, _.trim(pagePath, '/'), 'init-props.json');
        fse.outputFileSync(jsonFilePath, JSON.stringify(clientQueryData));
      }

      return accum;
    }, {});
  }
}


الصفحات / my_page.js باستخدام getInitialProps

Index.getInitialProps = async (context) => {
  const ssr = _.get(context, 'query.ssr', false);
  if (ssr) {
    // we are on server, return the data
    return _.get(context, 'query', {});
  } else {
    // we are on client side, request the data through /init-props.json endpoint
    const url = context.asPath + '/init-props.json';
    return fetch(url).then(response => {
      return response.json();
    });
  }
};

يمكنني رؤية الميزة الكبيرة لاستخدام طرق getStaticProps و getStaticPaths التي ستقلل الكثير من التعليمات البرمجية المتعلقة بحفظ ملفات JSON وتحميلها من العميل.

// pages/my_page.js
export async function getStaticProps(context) {
  const objects = await cmsSdkCient.getEntries();
  const props = _.find(object, { type: 'my_page' })
  return { props };
}

// pages/blog/[slug].js
export async function getStaticProps(context) {
  const objects = await cmsSdkCient.getEntries();
  const props = _.find(object, { type: 'post', slug: context.params.slug })
  return { props };
}

export async function getStaticPaths() {
  const objects = await cmsSdkCient.getEntries();
  return objects
    .filter(object => object.type === 'post')
    .map(object => ({ params: { slug: object.slug } }))
}

ما يزعجني هو السؤال كيف يمكنني تحسين سير العمل لإحضار جميع الإدخالات مرة واحدة ، بدلاً من جلبها في كل مرة يتم فيها استدعاء getStaticProps أو getStaticPaths ؟

سؤال آخر ، قد لا يكون مرتبطًا بالضرورة بهذه المشكلة ، ولكن نظرًا لأننا في عالم مجموعات SSG ومصادر البيانات البعيدة ، فإن الأمر يستحق السؤال. بافتراض أن next.js يعمل في وضع dev ، فكيف يمكن للمرء إخطار next.js لإعادة تنفيذ هذه الطرق من أجل إعادة إحضار البيانات البعيدة وإعادة بناء الموقع.

smnh نظرًا لأنه "مجرد JavaScript" ، يمكنك جلب وتخزين النتائج مؤقتًا في طريقة جلب البيانات الخاصة بك. عندما يتم استدعاؤها مرة أخرى في طرق getStatic * في بعض الصفحات الأخرى ، فلن يتم ضرب الشبكة مرة أخرى.

أما سؤالك الثاني ، فيفعل ذلك تلقائيًا. قم بتشغيل next dev وأنت على ما يرام.

لا أرى سوى معلمات المسار في أمثلة getStaticPaths أعلاه. هل سيكون من الممكن لمسارات SSG التي تتضمن معلمات الاستعلام؟ على سبيل المثال:

/store/widgets/circles-n-squares?sort=price&minWeight=2&color=black

أفكر بشكل خاص من منظور موقع التجارة الإلكترونية ، حيث سيكون من الصعب تغطية كل جانب من جوانب البحث عن المنتج في pathname لعنوان url.

لا أعتقد أن هذا منطقي في سياق ssg. يُخرج SSG ملفًا لكل إدخال - معلمات الاستعلام ليست جزءًا من اسم الملف ، لذا ستحتاج إلى طبقة خادم لإعادة كتابة الطلبات إلى ملف فعلي. (ما هو اسم ملفك الثابت في المثال أعلاه؟) أقترح التفكير في تقديم العرض الافتراضي مسبقًا (ما تحصل عليه إذا قمت بزيارة الصفحة بدون أوجه) والتحديث من جانب العميل إذا كانت هناك معلمات استعلام في الطلب. لكن هذا يصبح مشكلة تتجاوز SSG RFC.

dpfavand أواجه نفس الشيء أيضًا! محاولة إنشاء موقع بداية لـ agilitycms و nextjs مع توجيه ديناميكي للصفحة استنادًا إلى الصفحات الموجودة في نظام إدارة المحتوى.

timneutkens شكرا على المتابعة. لقد جربت طريقتين دون جدوى. بشكل أساسي عند تحديد قيمة slug كسلسلة في getStaticPaths ، لا يتم تمريرها إلى getStaticProps على الإطلاق.
الحالة 1 ، بافتراض وجود ملف pages/[...slug].jsx ، slug كسلسلة:

export async function unstable_getStaticPaths() {
    return [{ params: { slug: 'en/about' } }];
}

export async function unstable_getStaticProps({ params }) {
    console.log('params', params);
    return { slug: params.slug };
}

في الحالة المذكورة أعلاه ، params في getStaticProps كائن فارغ - لا يوجد مفتاح slug .

راجع للشغل ، عالم صغير! شكرا مرة أخرى للتحدث في fastr_conf.

مهلا! بدأ فريق Nextjs في معالجة هذا الأمر ، وهناك تذكرة مفتوحة لمعالجة بعض المشكلات الإضافية مع تطبيق canary الحالي: https://github.com/zeit/next.js/issues/10190

smnh ما وحفظه في JSON قبل تشغيل build + export. ثم تقوم فقط باستيراد JSON مباشرة في الصفحة كوحدة نمطية.

لإعادة البناء ، لديّ webhooks تم إعداده في CMS لتشغيل Netlify build hooks عندما يتغير المحتوى ذي الصلة. عندئذٍ يمكن لـ GetStaticProps فقط جلب محتوى محدد للصفحة.

شكراzeusdeux
إعادة:

أما سؤالك الثاني ، فيفعل ذلك تلقائيًا. قم بتشغيل dev التالي وأنت على ما يرام.

إذا قمت بتخزينها مؤقتًا في وحدة نمطية ثم قمت بتغيير البيانات في CMS ، فكيف سيتم إبطال ذاكرة التخزين المؤقت وإعادة تشغيلها بواسطة dev ، ولكن دون التوقف next.js وتشغيله مرة أخرى :)

إذا قمت بتخزينها مؤقتًا في وحدة نمطية ثم قمت بتغيير البيانات في CMS ، فكيف سيتم إبطال ذاكرة التخزين المؤقت وإعادة تشغيلها بواسطة dev ، ولكن دون التوقف next.js وتشغيله مرة أخرى :)

يتم استدعاء getStaticPaths فقط في إصدار إنتاج ، لذلك يمكنك فقط إخبار طريقة الجلب بالتخزين المؤقت في حالة الوحدة النمطية عند استدعائها من تلك الوظيفة.

مرحبًا ، لم أر ما إذا كان أي شخص يواجه نفس المشكلة كما فعلت.

لنفترض أن لدي نفس الصفحة على مسارات متعددة بـ unstable_getStaticProps :

1. /providers/[category]/[city] 
2. /providers/[category] 

شفرة المصدر هي نفسها لكلتا الصفحتين ، لذا لا داعي للتكرار. لذلك بالنسبة للملف الأول الذي يحتوي على كود مصدر مع منطق ، فإن الملف الثاني يستورد الأول فقط مثل export { default } from './[city]'; .

لكنه يلقي خطأً بأن البيانات من getStaticProps غير محددة. إذا قمت بنسخ نفس الكود إلى كلا الملفين فإنه يعمل.

homoky تحتاج إلى إعادة تصدير الأساليب:

export { default, unstable_getStaticProps } from './[city]';

لقد كنت أحاول SSG ، لكن بدون حظ.

هل يجب أن ينتج عن الكود أدناه مع v9.2.1 SSG؟

function Page({ stars }) {
  return <div>Next stars: {stars}</div>
}

Page.unstable_getStaticProps = async ctx => {
  return { props: { stars: 5 } }
}

export default Page

يظهر ناتج وحدة التحكم الخاصة بي من next build :

Page                                                           Size     First Load
┌ ○ /                                                          354 B       72.1 kB
...
λ  (Server)  server-side renders at runtime (uses getInitialProps or getServerProps)
○  (Static)  automatically rendered as static HTML (uses no initial props)
●  (SSG)     automatically generated as static HTML + JSON (uses getStaticProps)

joostmeijles unstable_getStaticProps يحتاج إلى أن يتم تصديره بدلاً من إرفاقه بمكون الصفحة ، على سبيل المثال

export const unstable_getStaticProps = async () => {
  return {
    props: { stars: 5 }
  }
}

joostmeijles unstable_getStaticProps يحتاج إلى أن يتم تصديره بدلاً من إرفاقه بمكون الصفحة ، على سبيل المثال

export const unstable_getStaticProps = async () => {
  return {
    props: { stars: 5 }
  }
}

شكرا ، هذا يحلها.

إذا أراد أي شخص رؤية مثال عمل شامل لهذا ، فقم بإنشاء صفحات ديناميكية (من CMS) بمسار شامل و SSG تحقق من https://github.com/agility/agilitycms-next-starter- ssg.

لقد تعثرت عدة مرات واعتقدت أن هذا قد يكون مفيدًا للآخرين.

كيف يمكنني الوصول إلى مسارات API التالية أثناء الإنشاء باستخدام getStaticProps عند النشر على zeit.co/now؟ يتطلب الجلب المتماثل عنوان URL مطلق ؛ محليًا ، يعمل مع http: // localhost : 3000 ولكن ليس مع النشر الآن (أو فعلت ذلك بشكل خاطئ 🤷‍♂️). أيه أفكار؟

إذا كنت على صواب ، فسيتم نشر مسارات API كوظائف بدون خادم وأعتقد أنها غير جاهزة أثناء عملية الإنشاء؟

سترغب في استدعاء وظيفة مسار api الخاص بك مباشرةً لأن هذا أقل بكثير من تجاوز http.

سترغب في استدعاء وظيفة مسار api الخاص بك مباشرةً لأن هذا أقل بكثير من تجاوز http.

أي موارد يمكنني قراءتها في المستندات حول هذا الموضوع؟ أنا في منتصف عملية الترحيل إلى zeit.co/now :)

حرفيًا ، قم باستيراد واستدعاء الوظيفة:

import MyFunction from '../lib/somewhere'


export async function /* unstable_ */getStaticProps() {
  const result = await MyFunction()
}

سؤال آخر: هل من الممكن استخدام getStaticProps / getStaticPaths و getServerProps جنبًا إلى جنب؟ على سبيل المثال ، إذا قمت بعرض بعض الصفحات مسبقًا باستخدام SSG ، ولكن إذا لم يتم العثور على واحدة في ذاكرة التخزين المؤقت لـ CDN ، فحينئذٍ ستعود إلى SSR لإنشاء الصفحة عند الطلب؟

سيعود getStaticProps إلى SSR وسيضيف النتيجة إلى ذاكرة التخزين المؤقت ،

سيعود getStaticProps إلى SSR وسيضيف النتيجة إلى ذاكرة التخزين المؤقت ،

lfades ، إذا كنت

ولكن فقط للتأكد من فهمي ... لنفترض أن لدي صفحة مسار ديناميكي /products/[productId].js . إذا قدمت getStaticProps ، وعددًا محدودًا من النتائج من getStaticPaths ، فأنت تقول إذا لم يتم العثور على /products/123 في ذاكرة التخزين المؤقت CDN (لأنه لم يكن ' t in getStaticPaths ) ، سيتم الرجوع إلى SSR وتشغيل getStaticProps ثم تخزين النتيجة مؤقتًا كصفحة ثابتة؟

سؤال المتابعة: هل سينجح ذلك أيضًا إذا لم أقم بتوفير getStaticPaths على الإطلاق؟

flintinatux نعم ونعم 👍

سيتراجع getStaticProps إلى SSR ويضيف النتيجة إلى ذاكرة التخزين المؤقت

هذه مشكلة لأنه لا توجد طريقة لإجراء 404 ، نظرًا لأن getStaticProps لا يسمح بتغيير الكائن res - إما أنه سيكون 200 ، أو 500 إذا كان هناك خطأ أثناء استدعاء الوظيفة.

هل هذا مخطط للتغيير؟

@ davidbailey00 عند إنشاء مواقع ويب ثابتة لا تحتوي صفحات 404 بالفعل على رمز الحالة 404.

بالطبع إذا قمت بتصدير ثابت كامل ، فلا توجد طريقة لعمل أكواد الحالة ، لأن كل شيء هو مجرد ملف. أنا أتحدث عن نشر المواقع المختلطة باستخدام getStaticProps إلى ZEIT Now - يبدو أنه يجب أن تحترم getStaticPaths وتخدم صفحات 404 ، بدلاً من فرض عرض جميع الصفحات المطابقة للمسار الديناميكي بغض النظر عن هذا.

هذه ليست الطريقة التي تعمل بها الآن ، نفس الشيء على next start .

سأكرر كما قيل سابقًا: هذا تجريبي وأي شيء يمكن أن يتغير في السلوك.

ولكن من الممكن عرض صفحات 404 بـ getServerProps أو getInitialProps - إذا تجاهل getStaticPaths getStaticProps getStaticPaths عند التفكير في رمز الاستجابة ، فهذا يعني أنه غير صالح تمامًا لأي موقع يهتم بأمره سيو جيد.

سنقدم على الأرجح المزيد من الطرق للتعامل مع أكواد الحالة ، ولكن ضع في اعتبارك أن معظم المواقع الثابتة (مثل CRA) توجه /* إلى index.html حيث لا يزال 404 هو 200.

مرحبًا يا شباب ، لدي سؤال مباشر ، فأنا أقوم بإنشاء موقع ويب بسيط باستخدام [unstable_]getStaticProps لبعض الصفحات SSG. كل شيء يعمل بشكل جيد حتى الآن ، باستثناء أمبير .

إذا كانت الصفحة تحتوي على [unstable_]getStaticProps ، فسيتم تعطيل amp . فيما يلي مثال بسيط للعمل مع الإصدار v9.2.1 التالي حيث يمكنك التحقق من ذلك:

import React from "react";
import { useAmp } from "next/amp";

export const config = { amp: `hybrid` };

const AmpExample = ({ date }) => {
  const isAmp = useAmp();
  return (
    <>
      <p>
        Welcome to the {isAmp ? `AMP` : `normal`} version of the Index page!!
      </p>
      <p>date: {date}</p>
    </>
  );
};
/**
 * If I get the dynamic data from getStaticProps,
 * page is SSG render but AMP is disabled when accessing
 * with `/ampExample?amp=1`
 */
export async function unstable_getStaticProps() {
  return {
    props: {
      date: new Date().toISOString(),
    },
  };
}

/**
 * If I get the dynamic data from getInitialProps,
 * page is SSR render but AMP is disabled when accessing
 * with `/ampExample?amp=1`
 */
// AmpExample.getInitialProps = () => {
//   return { date: new Date().toISOString() }
// }
export default AmpExample;

أي مساعدة لفهم كيفية جعل الصفحات SSG بالبيانات و amp تعمل؟

مرحبًا ، ماذا عن دعم getStaticProps لمكون App ( _app.tsx ) أي لحالات مثل جلب البيانات المشتركة لجميع مكونات الصفحة أثناء مرحلة الإنشاء؟

مرحبًا ، ماذا عن دعم getStaticProps لمكون App ( _app.tsx ) أي لحالات مثل جلب البيانات المشتركة لجميع مكونات الصفحة أثناء مرحلة الإنشاء؟

@ pkral78 أستطيع أن أخبرك كيف

لقد أنشأت تخطيطًا باستخدام نهج "التخطيط كمكوِّن ترتيب أعلى (HOC)" (لم يعد موجودًا في مستندات التعلم 🤷‍♂️).

على أي حال ، قمت بإنشاء تخطيط مثل ما يلي (مجرد مثال):

import React from "react";
import Head from "next/head";

const withSSGLayout = Page => {
  const WithSSGLayout = props => {
    return (
      <>
        <Head>
          <title>My Web Page</title>
          <link rel="icon" href="/favicon.ico" />
          <meta name="viewport" content="width=device-width, initial-scale=1" />
          <link
            href="https://fonts.googleapis.com/css?family=Roboto:400,700&display=swap"
            rel="stylesheet"
          />
        </Head>
        <Page {...props} />
      </>
    );
  };

  WithSSGLayout.unstable_getStaticProps = async () => {
    const pageStaticProps = Page.unstable_getStaticProps
      ? await Page.unstable_getStaticProps()
      : {};

    // Here you can make parent level queries too
    return {
      props: {
        ...pageStaticProps.props,
        parentProp: `dynamic prop-${new Date().toISOString()}`,
      },
    };
  };
  return WithSSGLayout;
};

export default withSSGLayout;

وبعد ذلك ، في الصفحة التي تريد استخدام هذا الأسلوب ، يمكنك ببساطة إضافة HOC (يجب عليك تصدير [unstable_]getStaticProps بشكل صريح و amp لا يعملان معًا) ، لكنني وجدت "طريقة لطيفة" للحصول على طلب عالي المستوى ولكل صفحة استعلامات SSG.

import React from "react";
import withSSGLayout from "../hocs/withSSGLayout";

export const config = { amp: `true` };

const Index = props => {
  const { date, parentProp } = props;
  return (
    <div>
      <h1>Example</h1>
      <h3>Local Prop?: {date}</h3>
      <h3>Parent Prop?: {parentProp}</h3>
    </div>
  );
};

// In theory you could do direct database queries
Index.unstable_getStaticProps = async () => {
  // Here you can make page level queries
  return {
    props: {
      date: new Date().toISOString(),
    },
  };
};
const IndexHOC = withSSGLayout(Index);

export const { unstable_getStaticProps } = IndexHOC;
export default IndexHOC;

أود أن يتخلى إذا كان نهجا جيدا. في حالتي ، أستخدم هذه التقنية للاستعلام عن الروابط الموجودة في الصفحة الرئيسية ومحتوى كل صفحة في الصفحات. اتمني ان يكون مفيدا.

robertovg يجب عليك التصدير على مستوى الوحدة النمطية لأن الشفرة

timneutkens هل يمكنك اقتراح حل أفضل لهذا المثال الصغير ؟ كنت أحاول فقط الحصول على "استعلام SSG على مستوى التخطيط" و "استعلام SSG على مستوى الصفحة" بطريقة ما وفكرت في نهج تخطيط HOC هذا.

كان القيد الرئيسي بالنسبة لي هو "تصدير [unstable_] getStaticProps" الذي تحتاجه في كل صفحة لوضع علامة بصفحة SSG.

سألت في وقت سابق أنني سأقدر حقًا بعض المعلومات الإضافية حول ما إذا كان amp + SSG سيكون متوافقًا.

شكرا 🙏

robertovg أولاً ، افصل التخطيط عن البيانات ، لذلك بالنسبة للتخطيط المشترك سيكون لديك شيء بسيط مثل هذا:

import Layout from '../components/layout'

const Page = () => (
  <Layout>
    <h1>Hello World!</h1>
  </Layout>
)

export default Page

ثم بالنسبة إلى getStaticProps بإحضار البيانات المشتركة باستخدام طريقة من وحدة أخرى ، لذلك قد يبدو المثال الكامل كما يلي:

import fetchSharedData from '../lib/fetch-shared-data'
import Layout from '../components/layout'

export const unstable_getStaticProps = async () => {
  const sharedData = await fetchSharedData()
  const pageProps = {...}

  return {  props: { ...sharedData, ...pageProps } }
}

const Page = () => (
  <Layout>
    <h1>Hello World!</h1>
  </Layout>
)

export default Page

robertovg أولاً ، افصل التخطيط عن البيانات ، لذلك بالنسبة للتخطيط المشترك سيكون لديك شيء بسيط مثل هذا:

import Layout from '../components/layout'

const Page = () => (
  <Layout>
    <h1>Hello World!</h1>
  </Layout>
)

export default Page

ثم بالنسبة إلى getStaticProps بإحضار البيانات المشتركة باستخدام طريقة من وحدة أخرى ، لذلك قد يبدو المثال الكامل كما يلي:

import fetchSharedData from '../lib/fetch-shared-data'
import Layout from '../components/layout'

export const unstable_getStaticProps = async () => {
  const sharedData = await fetchSharedData()
  const pageProps = {...}

  return {  props: { ...sharedData, ...pageProps } }
}

const Page = () => (
  <Layout>
    <h1>Hello World!</h1>
  </Layout>
)

export default Page

أرى هذا الحل وأفهمه ولكن المشكلة التي كنت أحاول رفعها كانت كيفية توسيع نطاق استخدام البيانات المشتركة.
على سبيل المثال ، إذا كان لديك <Header /> يستخدم sharedData للحصول على الروابط وتلك القادمة من CMS مقطوعة الرأس. يجب عليك حقن <Header /> كطفل لـ <Layout /> مع الدعائم أو حل آخر. وتحتاج إلى تكرار الحقن <Header /> في جميع الصفحات التي تريد استخدامها.

باستخدام نهج HOC ، يمكنك فقط إضافة <Header /> مرة واحدة في HOC.

لهذا السبب اعتقدت أنها نقطة جيدة التي أثارها @ pkral78 ، لتجنب تكرار الكود إن أمكن.

لهذا السبب اعتقدت أنها نقطة جيدة التي أثارها @ pkral78 ، لتجنب تكرار الكود إن أمكن.

كان في ذهني. يجب أن تحتوي صفحة _app على getStaticProps الذي يتم استدعاؤه مرة واحدة أثناء عرض الصفحة الأولى ثم تمرير props المحفوظ إلى الصفحات المعروضة التالية. لكنني ما زلت أفكر فيما إذا كان المفهوم مناسبًا على الإطلاق.

لست متأكدًا مما إذا كان هذا النوع من الأشياء عبارة عن حالة استخدام مقصودة ، ولكن لا يبدو أنها تعمل:

// /pages/[...slug].jsx
import ReactDOMServer from "react-dom/server";

export async function unstable_getStaticProps({ params: { slug } }) {
  const filePath = "../content/" + slug.join("/") + ".mdx";
  const { default: Component } = await import(filePath);
  const content = ReactDOMServer.renderToStaticMarkup(<Component />);
  return {
    props: { title: slug.join(" "), content }
  };
}

export default function Page({ title, content }) {
  return (
    <div>
      <h1>{title}</h1>
      <div dangerouslySetInnerHTML={{ __html: content }} />
    </div>
  );
}

حتى لو لم تكن حالة استخدام مقصودة ، فإنها تسجل خطأ يبدو مريبًا بعض الشيء:

[ warn ]  ./pages/[...slug].jsx
Critical dependency: the request of a dependency is an expression

يحرر:

أوه ، حسنًا ، يتم حلها عندما أفعل

const { default: Component } = await import(`../content/${slug.join("/")}.mdx`);

https://codesandbox.io/s/happy-oskar-40bug

هذا يشكو من أن مسار ملف الاستيراد الخاص بك ديناميكي

في الخميس ، 30 كانون الثاني (يناير) 2020 الساعة 00:29 ، كتب Jan Potoms [email protected] :

لست متأكدا إذا كان هذا النوع من الأشياء
https://codesandbox.io/s/nifty-cache-jspqr هي حالة استخدام مقصودة ، ولكن
لا يبدو أنه يعمل:

// /pages/[...slug].jsximport ReactDOMServer from "reaction-dom / server" ؛
تصدير وظيفة غير متزامنة unstable_getStaticProps ({params: {slug}}) {
// ما مدى أمان هذا حتى؟
const filePath = "../content/" + slug.join ("/") + ".mdx" ؛
const {الافتراضي: المكون} = انتظار الاستيراد (filePath) ؛
محتوى const = ReactDOMServer.renderToStaticMarkup (مكون) ؛
إرجاع {
الدعائم: {title: slug.join ("")، content}
} ؛
}
تصدير صفحة الوظيفة الافتراضية ({title، content}) {
إرجاع (


{لقب}




) ؛
}

حتى لو لم تكن حالة استخدام مقصودة ، فإنها تسجل خطأ يبدو أنه ملف
بعض المشبوهة:

[تحذير] ./pages/ [...slug].jsx
التبعية الحرجة: طلب التبعية هو تعبير

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/zeit/next.js/issues/9524؟email_source=notifications&email_token=AAADKRKOL34WKTG7J5QFRJ3RAIGPBA5CNFSM4JRPBEL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBX
أو إلغاء الاشتراك
https://github.com/notifications/unsubscribe-auth/AAADKRIWNA2DSMWFRGD453DRAIGPBANCNFSM4JRPBELQ
.

لهذا السبب اعتقدت أنها نقطة جيدة التي أثارها @ pkral78 ، لتجنب تكرار الكود إن أمكن.

كان في ذهني. يجب أن تحتوي صفحة _app على getStaticProps الذي يتم استدعاؤه مرة واحدة أثناء عرض الصفحة الأولى ثم تمرير props المحفوظ إلى الصفحات المعروضة التالية. لكنني ما زلت أفكر فيما إذا كان مفهومًا مناسبًا على الإطلاق.

@ pkral78 ، قد يكون السبب في ذلك هو أنه في معظم مواقع SSG التي أتخيل تنفيذها مع Next ، أود الحصول على "قطعة مشتركة" (Header ، Footer ، Side Bars ...). ولماذا لا تقوم فقط بإجراء الاستعلام عن تلك القطعة الشائعة في _app إذا كنت بحاجة إلى ذلك ، وإتاحتها في الصفحات الفرعية دون الحاجة إلى ذلك يدويًا في كل صفحة.

قلقي الوحيد هو أنك إذا وضعته في _app.js ، فلن نتمكن من الحصول على أكثر من "قطعة مشتركة" واحدة اعتمادًا على الصفحة. مع الفكرة التي كنت أعمل عليها في وضع النماذج الأولية ، أردت أن أكون قادرًا على الحصول عليها في التخطيط لأنه سيسمح لنا بالحصول على تنسيقات متعددة اعتمادًا على نوع الصفحة التي تريد عرضها ، "ولهذا السبب اتصلت بـ withSSGLayout to HOC الخاص بي لأنني كنت أخطط ليس فقط للحصول على صفحات SSG ولكن SSR وصفحات قاعدة العملاء بالكامل ، أو حتى أكثر من SSGLayout واحد. ويمكن القيام بذلك إذا كان من الممكن أن تكون Layouts مسؤولة أيضًا عن طريقة الأصل getStaticProps .

على أي حال ، فإن وجود SSG في Next سيجعلها أداة لأي نوع من مواقع الويب 🙌

Janpot فيما يتعلق بـ https://github.com/zeit/next.js/issues/9524#issuecomment -580012327

يمكن أن نوصي بشدة أن تستخدم أبدا مسارات حيوية في import() . ستقوم بتجميع كل ملف ممكن أسفل المسار في حزمة JS وتقليل أداء الإنشاء بشكل كبير في القيام بذلك.

timneutkens بالتأكيد ، أمر منطقي. هل المقصود getStaticProps هو الاستعلام عن واجهات برمجة التطبيقات الخارجية فقط ، وليس نظام الملفات؟

Janpot يمكنك القراءة من نظام الملفات ، وغالبًا ما ينتهي بك الأمر بالاستعلام عن بعض واجهات برمجة التطبيقات الخارجية.

timneutkens حسنًا ، من الأفضل استخدام @mdx-js/runtime ثم ، بدلاً من الاعتماد على @next/mdx ما أعتقد.

import ReactDOMServer from "react-dom/server";
import { promises as fs } from "fs";
import MDX from "@mdx-js/runtime";

export async function unstable_getStaticProps({ params: { slug } }) {
  const mdxContent = await fs.readFile(`./content/${slug.join('/')}.mdx`, {
    encoding: "utf-8"
  });
  const content = ReactDOMServer.renderToStaticMarkup(<MDX>{mdxContent}</MDX>);
  return {
    props: { title: slug.join(" "), content }
  };
}

export default function Page({ title, content }) {
  return (
    <div>
      <h1>{title}</h1>
      <div dangerouslySetInnerHTML={{ __html: content }} />
    </div>
  );
}

تضمين التغريدة يمكنك أيضًا استخدام تخفيض السعر البسيط ، هذا ما نفعله لـ nextjs.org/docs.

بخصوص https://github.com/zeit/next.js/issues/9524#issuecomment -580207073 ، إنه تمامًا كما أستخدم حاليًا Next مع SSR. لدي طلب GraphQL يتم تنفيذه على مستوى التخطيط ، وتتم مشاركة محتواه مع المكونات الشائعة للتطبيق (شريط التنقل والتذييل والأبناء الديناميكيون). بعد ذلك ، يقوم الأطفال الديناميكيون عادةً بتقديم طلب GraphQL آخر لمحتوى خاص بالصفحة.

وبالتالي ، يبدو وجود طريقة لإعادة استخدام هذا أمرًا مهمًا ، لا أريد أن أضطر إلى تكرار التعليمات البرمجية في كل صفحة لجلب تلك البيانات الشائعة.

مهلا!
أنا جديد تمامًا هنا. بدأت للتو العمل على ترحيل التطبيق إلى NextJS.

هناك حالة استخدام أساسية من شأنها أن تستفيد بشكل كبير من هذه الميزة - إصدارات متعددة اللغات. يحتوي تطبيق الويب الذي أعمل عليه على 16 إصدارًا بلغة مع أكثر من 100.000 مشاهدة للصفحة يوميًا والقدرة على إنشاء صفحة مقصودة بشكل ثابت على سبيل المثال سيكون أمرًا رائعًا ولكن المشكلة تكمن في التوجيه.

باستخدام العرض الجانبي للخادم ، يمكنني قراءة عناوين الطلبات أو ملفات تعريف الارتباط وتقديم إصدار لغة مناسب ولكن بدونها ، هل الحل الوحيد لإنشاء مسارات لكل إصدار مثل / en و / de و / fr وعلى "/" اجعل NextJS يقوم بإعادة التوجيه فقط؟

بعد أن تعلمت عن ReactDOMServer.renderToStaticMarkup أضفته إلى وظيفتي unstable_getStaticProps ووجدت أنها حسنت نقاطي على (الهاتف المحمول) من 96 إلى 100 بفضل التحسين الجذري لوقت التفاعل والحد الأقصى المحتمل لتأخير الإدخال الأول .

يمكنني زيارة الصفحة بدون JavaScript ويتم تحميلها بشكل جيد ، لذلك يبدو أن React تقوم بعمل عند تحميل الصفحة ، على الرغم من استخدام SSG.

ربما يكون هذا نقصًا في فهمي حول React ، لكنني أتوقع أن يكون الأداء مع JavaScript وبدونه هو نفسه ، ولا أتوقع تقديم المكونات مسبقًا للمساعدة (اعتقدت أن هذا ما كان SSG يفعله).

هل المتوقع أم خطأ أم شيء أفعله خطأ؟

الالتزام المسبق: https://developers.google.com/speed/pagespeed/insights/؟url=https٪3A٪2F٪2F5e310826bcf5030008a91209--josephduffynextjs.netlify.com٪2Fposts٪2Fgathered-1-0-1&tab=mobile
الالتزام: https://github.com/JosephDuffy/josephduffy.co.uk/pull/54/commits/d23898b874e5088ebcfabf577ee396b476ed97e4
الالتزام اللاحق: https://developers.google.com/speed/pagespeed/insights/؟url=https٪3A٪2F٪2F5e3371beda1b8f0009368ef9--josephduffynextjs.netlify.com٪2Fposts٪2Fgathered-1-0-1&tab=mobile

تضمين التغريدة

لذلك يبدو أن React تعمل على تحميل الصفحة ، على الرغم من استخدام SSG.

إنه يرطب DOM. في الأساس:

  1. يقوم المستعرض الخاص بك بتحميل SSR html في متصفح DOM
  2. يعيد React بناء DOM الظاهري بالكامل
  3. يتخطى React هذه DOMs ويقوم بمزامنتها (الترطيب)

إذا كان المحتوى الخاص بك ثابتًا حقًا ، كما هو الحال في عدم وجود آثار جانبية أو معالجات للأحداث ، فإن الخطوتين 2. و 3. غير ضرورية نوعًا ما. باستخدام طريقتك ، تقوم بشكل أساسي بتقليل شجرة المكون الخاصة بك إلى مكون واحد بسمة واحدة ، وهو أمر سريع جدًا بالنسبة لـ React لتقديمها وترطيبها. (+ dangerouslySetInnerHTM يتم تجاهله أثناء الترطيب)

<div dangerouslySetInnerHTML={{ __html: props.htmlContent }} />

ضع في اعتبارك أن معالجات الأحداث والآثار الجانبية لن تعمل مع هذه الطريقة.

يحرر:

قد تكون إحدى الأفكار هي السماح بحذف التصدير الافتراضي على الصفحة إذا كان getStaticProps يعرض html ثابتًا. بمعنى آخر

export async function unstable_getStaticProps() {
  // ...
  return {
    props: { dangerouslySetInnerHTML: { __html: '<div>static content</div>' } }
  };
}

نظرًا لأنه لا يلزم عرض أي شيء من جانب العميل ، يمكن لـ next.js استبعاد وقت تشغيله من الصفحة وتضمين لغة html التي أعادها getStaticProps . وستعمل بنفس الطريقة كما لو تم استخدام dangerouslySetInnerHTML على العقدة الجذر next.js.
أعتقد أنه سيكون أسهل في التنفيذ من الترطيب الجزئي ، وإن كان أقل قوة. يمكن أن تؤدي إعادة استخدام مصطلحات React نفسها هنا إلى تقليل الالتباس حول كيفية عمل هذه الميزة.

أحاول ترحيل موقع ثابت إلى Next.js وأود إعادة توجيه جميع متغيرات .html لمشاركات المدونة إلى إصدارات لا تنتهي بـ .html. يبدو أن getStaticProps لا يحصل حاليًا على سياق ، لذا لا يمكنني إجراء فحص للارتباط الثابت وإعادة التوجيه. سيكون من المفيد لو حصل getStaticProps على سياق كامل حتى أتمكن من القيام ببعض الأشياء الشرطية به.

nodabladam يبدو أنك تبحث عن RFC

سيسمح لك RFC بتعريف شيء مثل هذا:

// next.config.js
module.exports = {
  redirects() {
    return [
      // Redirect from the old HTML version of a blog post
      {
        source: "/blog/:post.html",
        destination: "/blog/:post",
        permanent: true
      }
    ];
  }
};

يمكنك حاليًا تجربة هذه الميزة تحت المفتاح experimental :

// next.config.js
module.exports = {
  experimental: {
    redirects() {
      // ...
    }
  }
};

لقد قمت بتطبيق getStaticProps و getStaticPathNames في مشروع خاص بي (حوالي 8K صفحة).

ومع ذلك ، يتم حساب ملفات الإخراج ضمن حد 10 كيلو بايت للملفات لكل عملية نشر. مع 8K صفحة تحصل على 16K من ملفات الإخراج لأن كل صفحة تحصل أيضًا على ملف json.

هل هناك خطط لزيادة هذا الحد؟ أم يمكنني تجاوز هذا الحد؟

لدي نفس المشكلة.
أفهم أنهم يتطلعون إلى رفع هذا الحد ، لكنني لا أعرف متى سيتم نشره.

لذلك أستخدم getStaticProps في جميع الصفحات و getStaticPaths فقط في بعض منها وهي تعمل (تُنشئ صفحة المنتج الخاصة بي 70٪ من إجمالي الصفحات لذا لم أضع أي getStaticPaths فيها). أبقى تحت الحد لكنه ليس مثاليًا ، التحميل الأول طويل جدًا ويصعب التعامل مع أخطاء 404.

لدي نفس المشكلة.
أفهم أنهم يتطلعون إلى رفع هذا الحد ، لكنني لا أعرف متى سيتم نشره.

لذلك أستخدم getStaticProps في جميع الصفحات و getStaticPaths فقط في بعض منها وهي تعمل (تُنشئ صفحة المنتج الخاصة بي 70٪ من إجمالي الصفحات لذا لم أضع أي getStaticPaths فيها). أبقى تحت الحد لكنه ليس مثاليًا ، التحميل الأول طويل جدًا ويصعب التعامل مع أخطاء 404.

آمل أن يرفعوا الحد الأقصى قريبًا ، لكن آمل ألا يكون 20 ألفًا .. لن يكون ذلك كافيًا بالنسبة لي على المدى الطويل.

أرغب في تجنب أوقات التحميل الأولى باستخدام getStaticPaths .. قد أضطر إلى البحث عن حلول أخرى إلى جانب Zeit Now

سيعرض Next.js أيضًا تلقائيًا نقطة نهاية API التي تُرجع نتيجة استدعاء getServerProps. [...] سيقوم Next.js بجلب نقطة نهاية واجهة برمجة التطبيقات المكشوفة هذه للحصول على بيانات JSON التي يتم تحويلها إلى الدعائم اللازمة لعرض جانب عميل الصفحة.

سيقوم Next.js بجلب البيانات من نقطة النهاية هذه قبل إجراء تغيير المسار الفعلي وعرض مكون الصفحة (لا يمكنه ، على الأقل افتراضيًا ، القيام بذلك بأي طريقة أخرى). لذلك قد يواجه المستخدم موقعًا سريعًا للغاية بسبب إنشاء صفحات معينة بشكل ثابت ، ولكن إذا نقروا على رابط إلى صفحة SSR ، فسيتوقف الموقع فجأة قبل قليل من تغيير المسار.

هل هناك طريقة موصى بها لتحميل المكون _first_ بحيث يمكن ملؤه بمؤشرات التحميل والعناصر النائبة المتحركة وما إلى ذلك؟ (بدلاً من إضافتها إلى الصفحة الحالية). إذا لم يكن الأمر كذلك ، فهل يمكن أن تكون ذات صلة بالميزات المقترحة حديثًا؟ لقد حققت ذلك باستخدام مزيج من getInitialProps والخطافات داخل طريقة العرض ، لكنها تبدو فوضوية.

أعتقد أن نمط UX هذا (تبديل الصفحة الفوري) مفضل من قبل الكثيرين (معظمهم؟) ، لكنني لم أر أي أمثلة عليه باستخدام Next.js حتى الآن. لقد استخدمت إطار العمل لبضعة أيام فقط ، لذا يرجى تصحيح ما إذا كنت مخطئًا.

متحمس حقًا بشأن الميزات الجديدة! شكرا لعملكم.

nicoqh ، مخاوفك بشأن انتقالات الصفحة ليست خاصة بـ SSG ، نظرًا لأن getInitialProps . أستخدم nprogress لعرض شريط تقدم على الأقل في الأعلى أثناء تحميل الصفحة التالية ، لكنني أرى أيضًا هذا المثال لوجود انتقالات حقيقية للصفحة تبدو أقرب إلى ما تصفه. لم أجربها بنفسي ، لكني آمل أن تساعدك فيما تحتاجه:
https://github.com/zeit/next.js/tree/canary/examples/with-next-page-transitions

يبدو أن ملف json /_next/data/BUILD_ID/<file>.json الذي تم إرجاعه لا يحترم الأصول. يؤدي هذا إلى تحويل الملف إلى 404 بالنسبة لي في بيئة الإنتاج الخاصة بي نظرًا لأن لدي إعدادًا يتوقع أن يكون كل شيء _ التالي أحد الأصول التي تمر عبر CDN. يجب أن يتم توجيه ملفات json هذه في النهاية من خلال الأصول الأصلية (CDN) ، أليس كذلك؟

لدي نفس المشكلة.
أفهم أنهم يتطلعون إلى رفع هذا الحد ، لكنني لا أعرف متى سيتم نشره.
لذلك أستخدم getStaticProps في جميع الصفحات و getStaticPaths فقط في بعض منها وهي تعمل (تُنشئ صفحة المنتج الخاصة بي 70٪ من إجمالي الصفحات لذا لم أضع أي getStaticPaths فيها). أبقى تحت الحد لكنه ليس مثاليًا ، التحميل الأول طويل جدًا ويصعب التعامل مع أخطاء 404.

آمل أن يرفعوا الحد الأقصى قريبًا ، لكن آمل ألا يكون 20 ألفًا .. لن يكون ذلك كافيًا بالنسبة لي على المدى الطويل.

أرغب في تجنب أوقات التحميل الأولى باستخدام getStaticPaths .. قد أضطر إلى البحث عن حلول أخرى إلى جانب Zeit Now

erhankaradeniz و ziltosh يجب أن نطرح ذلك بشكل عام قريبًا جدًا. إذا كنت ترغب في الحصول على مساعدة بشأن ذلك في أسرع وقت ممكن ، فيمكنك الاتصال بي مباشرة أو [email protected] وسيقومون بالفرز.

لدي نفس المشكلة.
أفهم أنهم يتطلعون إلى رفع هذا الحد ، لكنني لا أعرف متى سيتم نشره.
لذلك أستخدم getStaticProps في جميع الصفحات و getStaticPaths فقط في بعض منها وهي تعمل (تُنشئ صفحة المنتج الخاصة بي 70٪ من إجمالي الصفحات لذا لم أضع أي getStaticPaths فيها). أبقى تحت الحد لكنه ليس مثاليًا ، التحميل الأول طويل جدًا ويصعب التعامل مع أخطاء 404.

آمل أن يرفعوا الحد الأقصى قريبًا ، لكن آمل ألا يكون 20 ألفًا .. لن يكون ذلك كافيًا بالنسبة لي على المدى الطويل.
أرغب في تجنب أوقات التحميل الأولى باستخدام getStaticPaths .. قد أضطر إلى البحث عن حلول أخرى إلى جانب Zeit Now

erhankaradeniz و Ziltosh يجب أن نطرح ذلك بشكل عام قريبًا جدًا. إذا كنت ترغب في الحصول على مساعدة بشأن ذلك في أسرع وقت ممكن ، فيمكنك الاتصال بي مباشرة أو [email protected] وسيقومون بالفرز.

kvangundy شكرا
لقد اتصلت بك على Twitter بخصوص هذه المشكلة ؛-)

erhankaradeniz هل يمكنك إرسال بريد إلكتروني إلى [email protected] بدلاً من ذلك؟ بهذه الطريقة ينتهي الأمر في نظامنا بشكل صحيح.

flintinatux ، شكرًا على النصيحة. لقد رأيت المثال ، وهو لا يساعد في تحميل مكون الصفحة قبل تحميل البيانات ، لذا فإن العناصر النائبة في الصفحة وما إلى ذلك غير ممكنة. إنه مثال مثير للاهتمام ، مع ذلك ، شكرًا!

أعتقد أنه لن يتم تناوله في هذه المشكلة ، مما يعني أنه خارج عن الموضوع ، لذلك سأجد مكانًا آخر لمناقشته :)

أعتقد أن طريقة تقسيم getInitialProps إلى getStaticProps & getServerProps أكثر نظافة! لدي سؤال بخصوص كيفية تأثير ذلك على حالة الاستخدام الخاصة بنا:
نريد إنشاء بنائين منفصلين: إصدار ثابت واحد لموقع prod الخاص بنا ، وإصدار واحد باستخدام SSR لبيئة التحرير.

كنت أفكر في إمكانية إرفاق getStaticProps مقابل getServerProps كطرق ثابتة اعتمادًا على البنية (على غرار https://github.com/zeit/next.js/issues/9524#issuecomment- 558617056) ، لكنني لست متأكدًا مما إذا كان من الممكن تصديرها بشكل مشروط كما هي. هل لديك أي أفكار إذا كان هذا ممكنًا لدعم ديناميكي / ثابت اعتمادًا على البنية؟

فيما يتعلق:

سيتم تحديث RFC ليعكس التغييرات لاحقًا ، مع الاستمرار في تكرار الاستخدام الفعلي في تطبيقاتنا.

أتساءل عما إذا كانت هناك طريقة لاستخدام نوع من طرق أحرف البدل للقبض على الطرق غير المعروفة في وقت الإنشاء. إنه لأمر رائع أنه يمكنني عرض صفحات ثابتة من على سبيل المثال بيانات CMS ، ولكن ماذا لو أضاف شخص ما عنصرًا جديدًا؟ ليس لدي صفحة ثابتة لذلك. هذه القضية خدشت رأسي لفترة طويلة.

لقد قمت بإعداد مسار ديناميكي لعرض الصفحات الثابتة _pages / [slug] .js_. تحصل _getStaticPaths_ على جميع الصفحات التي أريد عرضها بشكل ثابت. لدي _getStaticProps_ للاستعلام عن البيانات وتمريرها إلى وظيفة التقديم. يتم تقديم جميع الصفحات الواردة في _getStaticPaths_ كملفات HTML داخل _.next/server/static_ عند الإنشاء. رائعة!

الآن أقوم بتشغيل npm run start وهذه الصفحات كما ينبغي. لكن طلب عنوان url مفقود (مثل _ / foo_) يؤدي إلى إنشاء ملفات HTML و JSON ثابتة جديدة داخل _.next/server/static_. هذا ليس جيدا. كيف يمكنني جعل الخادم يعيد توجيه كافة عناوين url الأخرى إلى _pages / _error.js_؟

https://github.com/zeit/next.js/issues/9524#issuecomment -582777067

نحن نغطي ذلك أيضًا.

الآن أقوم بتشغيل بدء تشغيل npm وهذه الصفحات كما ينبغي. لكن طلب عنوان url مفقود (مثل / foo) يؤدي إلى إنشاء ملفات HTML و JSON ثابتة جديدة داخل .next / server / static. هذا ليس جيدا. كيف أجعل الخادم يعيد توجيه جميع عناوين url الأخرى إلى pages / _error.js؟

هذا لا يزال على متن الطائرة وليس سلوكًا غير متوقع حتى الآن.

مرة أخرى ، تذكير بأنك تستخدم ميزة تجريبية ويمكن أن يتغير السلوك في أي وقت. ستتغير الأشياء وربما تنقسم بين جميع الإصدارات أثناء استخدام هذا عندما يكون غير مستقر.

تضمين التغريدة أنا أفهم عدم الاستقرار. هل لديك أي فكرة عن كيفية إدارة هذا؟ مررت عبر الكود ولاحظت أن إلقاء خطأ داخل _unstable_getStaticProps_ يؤدي إلى ظهور صفحة الخطأ. قد تكون هذه طريقة جيدة للذهاب. سأحتاج فقط إلى طريقة لتمرير الخطأ إلى الأمام كما هو إلى _pages / _error.js_. أود إرسالها 404. الآن يصبح الرقم 500.

لقد قمت بنشر هذا عدة مرات من قبل في سلاسل رسائل أخرى ، ولكن "الانتقال إلى الخطأ" هو سلوك غير متوقع ، اعتبارًا من الآن يجب أن تعرض صفحتك حالة 404. ببساطة قال if(!data.something) { return <My404Component /> } ، ثم My404Component يجب أن يعيّن noindex العلامات الوصفية.

حقا؟ تشير الوثائق بوضوح إلى استخدام _pages / _error.js_ من أجل 404s.

راجع: https://nextjs.org/docs/advanced-features/custom-error-page

@ jiv-e هذا لـ 404s بسبب:

  • الصفحة غير موجودة
  • لم يتم العثور على الملف

إذا كانت لديك مسارات ديناميكية ، فيجب عليك التعامل مع حالة "404" كما قلت ، على سبيل المثال ، مثل https://nextjs.org/docs/advanced-features/custom-error-page#reusing -the-built-in-error- صفحة

فهمتك! شكرا!

أرغب في استخدام getStaticProps لجلب مفاتيح الترجمة / اللغة في وقت الإنشاء لأنها على الأرجح ستتغير مرة أو مرتين شهريًا أو حتى كل عام. أيضًا لا تحتاج إليها كدعامات JSON / داخل DOM. تكمن المشكلة في أنني لا أرغب في تمرير المفاتيح أسفل الشجرة إلى المكون حيث أستخدمها بالفعل - ما الأساليب المناسبة لحالة الاستخدام الخاصة بي؟

useTranslation () ربط (أو HOC) مع السياق؟

سيكون من الجيد أن يكون AppTree جزءًا من سياق NextGetStaticProps ( getStaticProps({ AppTree }) ). وإلا فلن يكون من الممكن تشغيل أشياء مثل apollos getDataFromTree على ssg.

في هذه المرحلة ، لا نخطط للسماح بمسح AppTree في getStaticProps لأنه أمر سيء حقًا للأداء (ردود فعل متسقة من الشركات). عندما تضيف getStaticProps إلى صفحة ما ، فإنها لا تزال تمر عبر getInitialProps من _app للسماح بالتبني المتزايد ، لذلك ستظل تعمل مع Apollo حقًا.

سيكون من الرائع لو كان لدينا وظائف SSG amp: 'hybrid' في نفس الوقت.
يمكن تحقيق ذلك عن طريق إنشاء ملفين لصفحة مثل هذه ، على سبيل المثال:

  • (SSG) index.html
  • (AMP) index.amp.html

سيسمح هذا للوكلاء بالحلول إلى مستند amp استنادًا إلى معلمة الاستعلام ?amp=1 .

سيكون من الرائع لو كان لدينا وظائف SSG amp: 'hybrid' في نفس الوقت.
يمكن تحقيق ذلك عن طريق إنشاء ملفين لصفحة مثل هذه ، على سبيل المثال:

  • (SSG) index.html
  • (AMP) index.amp.html

سيسمح هذا للوكلاء بالحلول إلى مستند amp استنادًا إلى معلمة الاستعلام ?amp=1 .

بالضبط @ Dacturne ، هذا هو الجانب السلبي الوحيد الذي أراه لبدء استخدام SSG بالفعل في المشاريع حيث كنت أعلق في هذا الموضوع منذ وقت.

🤞

jansedlon لقد قمت بعمل مشاركة مدونة للإجابة على سؤالك:

أتساءل عما إذا كانت هناك طريقة لاستخدام نوع من طرق أحرف البدل للقبض على الطرق غير المعروفة في وقت الإنشاء. إنه لأمر رائع أنه يمكنني عرض صفحات ثابتة من على سبيل المثال بيانات CMS ، ولكن ماذا لو أضاف شخص ما عنصرًا جديدًا؟ ليس لدي صفحة ثابتة لذلك. هذه القضية خدشت رأسي لفترة طويلة.

https://paqmind.com/ar/blog/ssr-is-not-the-future

(لا تنشر هنا لأنها كبيرة جدا)

@ ivan-kleshnin لقد ألقيت نظرة سريعة ويبدو الأمر مثيرًا للغاية! كنت قد وفرت لي مئات الساعات! شكرًا جزيلاً لك ، سألقي نظرة أكثر تعمقًا في وقت لاحق اليوم.

https://github.com/zeit/next.js/issues/9524#issuecomment -582799948

jansedlon كما قيل سابقًا ، نحن نعمل على شيء يتعلق بهذا الأمر لم يتم تغطيته في مدونة @ ivan-kleshnin. نأمل أن تكون قادرًا على مشاركة المزيد حول هذا قريبًا جدًا.

timneutkens أحب التغييرات حتى الآن 🙏 هل لديك أي خطط لتحسين / دعم ثابت + تدويل كامل؟

لقد استخدمنا واجهات برمجة التطبيقات الجديدة getStaticProps / getStaticPaths في ترحيلنا لـ tinacms.org من Gatsby إلى Next.js ، وحتى الآن كان الأمر رائعًا!

كانت إحدى العقبات التي واجهتنا في إنشاء موجز RSS. من الناحية المثالية ، نود إنشاءه بشكل ثابت ، نظرًا لأن المحتوى الذي يشير إليه يتم إنشاؤه بشكل ثابت. لا أرى طريقة للقيام بذلك حاليًا ، لذلك بدلاً من ذلك ، نتعامل معها فقط من جانب الخادم من خلال الاستعلام عن المحتوى وكتابة XML للاستجابة.

هل كان هناك أي نقاش حول دعم الإنشاء الثابت لأنواع المحتوى بخلاف HTML؟

لمعلوماتك بدأنا في استخدام getStaticProps على zeit الآن وأصدرنا باستخدام علامة --prod ولم يتم مسح ذاكرة التخزين المؤقت لملفات json في الإصدارات الجديدة. لقد نجح إعادة إصدار الإنتاج إلى استخدام ميزة الاسم المستعار وتم مسح ذاكرة التخزين المؤقت.

لقد استخدمنا واجهات برمجة التطبيقات الجديدة getStaticProps / getStaticPaths في ترحيلنا لـ tinacms.org من Gatsby إلى Next.js ، وحتى الآن كان الأمر رائعًا!

كانت إحدى العقبات التي واجهتنا في إنشاء موجز RSS. من الناحية المثالية ، نود إنشاءه بشكل ثابت ، نظرًا لأن المحتوى الذي يشير إليه يتم إنشاؤه بشكل ثابت. لا أرى طريقة للقيام بذلك حاليًا ، لذلك بدلاً من ذلك ، نتعامل معها فقط من جانب الخادم من خلال الاستعلام عن المحتوى وكتابة XML للاستجابة.

هل كان هناك أي نقاش حول دعم الإنشاء الثابت لأنواع المحتوى بخلاف HTML؟

كنت أفكر في ذلك بنفسي واكتشفت ذلك للتو. هنا نصوصي:

"scripts": {
    "dev": " next",
    "build": "yarn sitemap && next build",
    "start": "next start",
    "sitemap": "ts-node --project ./cli/tsconfig.spec.json ./cli/generateSitemap.ts"
  },

قبل أن يتم استدعاء next build yarn sitemap والذي يقوم بإنشاء خريطة موقع ثابتة. يمكنك استخدام نفس الأسلوب ، لتخزين جميع البيانات مؤقتًا إلى json على سبيل المثال ، والتي ستحتاجها في getStaticProps ويمكنك إعادة استخدامها على صفحات متعددة.

تم تحديث RFC ، وتغيير سلوك getStaticPaths قليلاً (تحتاج إلى إرجاع مفتاح paths الآن ، هذا يعكس getStaticProps حيث يجب إرجاع props . هذا التغيير لم يصل إلى Next.js حتى الآن.

تمت إضافة تفسير أيضًا لسلوك fallback (إنشاء الخلفية عند الطلب للصفحات التي لم يتم تصديرها في وقت الإنشاء).

إجراء تحديث آخر لـ RFC ، إضافة تفسير للتغييرات في تنقل العميل فيما يتعلق بحالة Loading .

قد نرغب في إضافة طريقة للمستخدمين لمعرفة ما إذا كانت حالة التحميل يتم عرضها من خلال خطاف React 🤔

أشياء عظيمة! كنت أتساءل فقط ، هل ستكون هناك طريقة للصفحات التي تم إنشاؤها بشكل ثابت لمشاركة البيانات بين مسارات متعددة باستخدام ملف JSON واحد (مثل تقسيم الشفرة ولكن للبيانات)؟

لقد اصطدمت بأحدث إصدار canary وحصلت على الفور على القليل من حالة Loading . في الماضي ، كان من الجيد أن نفترض بأمان أنني حصلت بالفعل على البيانات الصحيحة قبل أن تبدأ طبقة العرض في العرض. التحميل غير المتزامن القسري هو خروج كبير عن ذلك. لقد استمتعت حقًا بنزع جميع نقاط النهاية المعيارية التي ستحل محلها نقاط نهاية SSR الجديدة التي تم إنشاؤها تلقائيًا ، لكنني لم أكن أخطط لإعادة تصميم كل صفحة لتشمل حالات جديدة Loading .

أتفهم الرغبة في TTFB بشكل أسرع ، وفي المستقبل قد يكون هذا أمرًا رائعًا لتطبيقي. ولكن هل من الممكن جعل حالة Loading ميزة اشتراك أو إلغاء اشتراك ، على غرار fallback: false لـ getStaticPaths ؟ ربما export const enableLoadingState = false على الصفحة ، أو على مستوى الموقع في next.config.js .

https://github.com/zeit/next.js/issues/9524#issuecomment -583962425

مرة أخرى ، تذكير بأنك تستخدم ميزة تجريبية وأننا نجرب السلوك حاليًا.

قمت بنشر موقع SSG (التجريبي) الخاص بي على الآن (باستخدام إعداد افتراضي). إنه يعمل بشكل جيد ، لكنني أرى أخطاء 404 في علامة تبويب الشبكة عند تصفح الموقع. تشير جميع أخطاء 404 إلى _next/static/pages/[slug].js .

هل هذا السلوك المتوقع أثناء تجريبي؟ أم يجب علي تغيير بعض الإعدادات؟

joostmeijles يبدو أنك لا تقدم href و as إلى next/link . بالنسبة إلى الصفحات الديناميكية ، يجب أن تكون الصفحة href هي الصفحة href='/[slug]' ويجب أن يكون as هو عنوان URL as='/slug-1'

أحصل على 3 سجلات في وحدة التحكم أثناء الإنشاء ، هل هذا خطأ؟

// Page is showing three logs despite static path only having 2 entries and output generating only two files as intended
export default function Page(props){
    console.log("Page - should only show twice", props); 
    return <><h1>Page</h1></>
}

export async function unstable_getStaticProps(props) {
    console.log("unstable_getStaticProps - should only show twice", props);
    return {
      props
    };

}

export async function unstable_getStaticPaths() {
    console.log("show once")
    return {
        paths: [
        { params: { year: "1901" } },
        { params: { year: "1902" } },
        ]
    }
}

لا هذا متوقع حسب fallback في RFC.

لا هذا متوقع حسب fallback في RFC.

export async function unstable_getStaticPaths() {
    console.log("show once")
    return {
        fallback: false,
        paths: [
        // This renders /blog/hello-world to HTML at build time
        { params: { year: "1901" } },
        { params: { year: "1902" } },
        ]
    }
}

حاولت إلغاء الاشتراك ولكني أتلقى هذا الخطأ.

خطأ: تم إرجاع المفاتيح الإضافية من unstable_getStaticPaths في / [السنة] (احتياطي) الحقل الوحيد المسموح به حاليًا هو paths

تذكير مرة أخرى بأنك تستخدم ميزة تجريبية وأننا نجرب السلوك حاليًا ولا يتم تنفيذ كل شيء.

هل ستتوفر هذه الميزة getStaticProps للصفحات فقط؟
هل سيكون مثيرًا للاهتمام للتطبيق / المستند أيضًا ، على سبيل المثال جلب بعض التكوين العام للتطبيق؟

لقد نفذت هذا "بنجاح" وأنا سعيد بالنتائج حتى الآن .. لكني أتساءل هل هناك أي طريقة لجعل البنيات اللاحقة "أسرع"؟ على سبيل المثال ، تحقق مما إذا كانت الصفحات التي تم إنشاؤها بواسطة SSG لم تتغير ولا تعيد إنشاء تلك الصفحات؟ (ربما تمني التفكير مني)

timneutkens هل لديك أي خطط لإضافة منشئ sitemap.xml لصفحات SSG؟ أنا لا أتحدث حتى عن المسارات الديناميكية لأنني أعتقد أنه من الأسهل تنفيذها فقط للصفحات الثابتة في الوقت الحالي.

timneutkens هل لديك أي خطط لإضافة منشئ sitemap.xml لصفحات SSG؟ أنا لا أتحدث حتى عن المسارات الديناميكية لأنني أعتقد أنه من الأسهل تنفيذها فقط للصفحات الثابتة في الوقت الحالي.

نعم ، سيكون هذا خيارًا رائعًا. أقوم حاليًا بتوليد واحدة بنفسي باستخدام SSR. (لكن ملف sitemap.xml يستغرق وقتًا طويلاً للتحميل)

https://github.com/zeit/next.js/issues/9524#issuecomment -585293270

مبدئيًا للصفحات فقط لأنه سيكون هناك عمل آخر يؤثر على getStaticProps بعد هبوطه.

https://github.com/zeit/next.js/issues/9524#issuecomment -586957539

نعم ولكن ليس كجزء من طلب التعليقات هذا. ستكون هناك متابعة بعد هذه الأرض.

timneutkens أعتقد أن تنفيذ صفحات SSG سهل لأنه يمكنك دفع URI إلى مصفوفة في كل مرة يبني فيها Next صفحة ثابتة ، وبعد ذلك ، عندما ينتهي ، ما عليك سوى تعيين المصفوفة في كل علامة XML ، والانضمام إليها وإدراجها في المنتصف من علامة <sitemapindex> . يمكن أن يحتوي getStaticProps على مفتاح آخر في كائن الإرجاع باسم excludeFromSitemap لذا سيكون الإعداد الافتراضي لجميع الصفحات التي سيتم تضمينها في sitemap.xml ولكن مع خيار إلغاء الاشتراك.

إذا كان الأمر كذلك ، فسيكون للمطورين تحكمًا جيدًا في الصفحة الثابتة التي ستنتقل إلى خريطة الموقع (على سبيل المثال: إذا كانت الصفحة [foo] 's getStaticPaths المسارات مع foo params 'abc' و 'xyz' ولكن يجب أن يكون الملف 'abc' موجودًا في خريطة الموقع ، سيكون المطور قادرًا على تعيين excludeFromSitemap إلى true إذا كانت المعلمة ==='xyz' في getStaticProps .

أيضًا ، بالنسبة إلى SSR والصفحات الثابتة ، يمكن تصدير ثابت (مثل export const excludeFromSitemap = true; ) من ملف الصفحة ، تمامًا مثل getServerProps ، getStaticPaths و getStaticProps يتم تصدير

في صفحات SSG إذا كان هناك ثابت excludeFromSitemap (الصفحة الافتراضية) وكان هذا المفتاح موجودًا أيضًا في الكائن الذي تم إرجاعه من دالة getStaticProps (خاصة بالمسار) ، يجب أن تعمل القيمة المُصدَّرة كقيمة افتراضية قيمة جميع المسارات في تلك الصفحة والمسار المحدد excludeFromSitemap ، عند وجوده في الكائن getStaticProps ، يجب أن يتجاوز الإعداد الافتراضي للصفحة (لذلك يمكن أن تؤدي الصفحة export cosnt excludeFromSitemap = true ثم أضف المفتاح excludeFromSitemap إلى العنصر الذي تم إرجاعه من getStaticProps بقيمة false لاستبعاد جميع المسارات من خريطة الموقع باستثناء ذلك المحدد).

سيكون رمز إلحاق المصفوفة شيئًا من هذا القبيل (لقد حسبت جدول الحقيقة وحصلت على الحد الأدنى من التعبير المنطقي باستخدام خريطة Karnaugh):

//...somewhere else
const validExcludeFromSitemapTypes = ['boolean','undefined'];

//...for each path
const isSSG = !!getStaticPropsReturnedObj && typeof getStaticPropsReturnedObj === "object";
if(
    validExcludeFromSitemapTypes.indexOf(typeof pageExports.excludeFromSitemap)<0 ||
    (isSSG && validExcludeFromSitemapTypes.indexOf(typeof getStaticPropsReturnedObj.excludeFromSitemap)<0)
) {
    throw new Error("'excludeFromSitemap' can either be ommited (undefined) or be a boolean");
}
const defaultExcludedValue = !!pageExports.excludeFromSitemap;
const hasSpecificExcluded = isSSG && typeof getStaticPropsReturnedObj.excludeFromSitemap !== "undefined";
const specificExcludedValue =  isSSG ? !!getStaticPropsReturnedObj.excludeFromSitemap : false;

if(!specificExcludedValue && (!defaultExcludedValue || hasSpecificExcluded))
    sitemapURIs.push(correctlyEncodedURI);

سيكون تحويل المصفوفة إلى خريطة الموقع أمرًا سهلاً مثل القيام بذلك (بافتراض أن URIs في المصفوفة تم ترميزها بالفعل وتصفيتها بواسطة !excludeFromSitemap ):

function createSitemap(sitemapURIs: string[]): string {
    return `<sitemapindex>${sitemapURIs.map(u=>`<sitemap><loc>u/loc></sitemap>`).join('')}</sitemapindex>`;
}

أعتقد أن هذه الميزة ستظهر بشكل جيد في Next.JS لأن جزءًا من مهمتها هو منح المستخدمين درجة 100 SEO والحصول على sitemap.xml سيساعد بشكل كبير! (من المحتمل أيضًا إنشاء robots.txt بإضافة else إلى الشرط الذي يضيف المسارات إلى مصفوفة خريطة الموقع لإلحاق هذا المسار بمصفوفة أخرى من الصفحات غير المسموح بها)

في إصدار الإصدار الحالي ، عند استخدام unstable_getStaticPaths مع الوظيفة unstable_getStaticProps ، لا يمكنك إجراء مكالمات api للوظائف التي تعيش في /api/ .
نظرًا لأن الخادم لا يعمل ، فمن المستحيل إجراء الطلبات المقابلة وإنشاء الدعائم الثابتة بهذه الطريقة.
عليك إما عدم توفير وظائف المسارات (مما يجعل SSR هذا مع ذاكرة تخزين مؤقت ، والتي لا تزال لطيفة!) أو الاعتماد على SSR بدلاً من SSG.

ربما سيكون هذا إضافة جيدة لهذه الميزة؟ لست متأكدًا من أفضل طريقة هنا ، لقد قرأت اقتراحًا في مكان آخر ، والذي اقترح اختصار طلب http ، مع مسارات SSR و /api ، سيكون هذا مفيدًا هنا أيضًا.

ولكن كل هذا يعني بالطبع تشغيل التعليمات البرمجية في بيئة الإنشاء ، والتي من شأنها إجراء مكالمات إلى خدمات أخرى / مكالمات db أو ما شابه ذلك. يجب توضيح ذلك عند تنفيذ ذلك ، ولكنه سيكون إضافة رائعة لهذه الميزة.

reckter Yep ، لقد فعلت شيئًا مشابهًا بنفسي. اضطررت إلى الاتصال بـ db الخاص بي لكل طلب صفحة منفصلة أثناء إنشائها بشكل ثابت. شعر غريب جدا ...

آمل ألا تكون هذه هي حالة الاستخدام النهائية

سيكون من الجيد أن يكون لديك نوع من نص التهيئة يمكنك إعداده من next.config أو شيء من هذا القبيل ...

reckter طريقة لاختصار طلبات HTTP لمسارات API من SSG / SSR ستكون جيدة جدًا! إنه لمن الغريب أن أقدم طلبًا عبر الشبكة لنفسي بشأن أي من هذه السيناريوهات.

على أي حال ، فإن أحد الحلول الممكنة للوصول إلى مسارات API أثناء SSG هو أن يكون لديك خادم محلي يقوم بتشغيل المسارات /api قبل تجميع الصفحات الثابتة! لذلك ستكون خطوات البناء:

  1. قم بتشغيل خادم (ربما يسمى "خادم تجميع واجهة برمجة التطبيقات" أو شيء من هذا القبيل) يخدم فقط المسارات /api
  2. قم بتشغيل unstable_getStaticPaths
  3. قم بتشغيل unstable_getStaticProps
  4. تجميع الصفحات الثابتة

reckter بشكل أساسي ليس عليك استدعاء مسارات API ، يمكنك استدعاء الوظيفة التي تنفذها مباشرة ، وهذا أيضًا يتجنب الكثير من النفقات العامة التي تتجاوز أسباب http.

بشكل أساسي إذا كان لديك حاليًا مسار API يبدو كالتالي:

import myDb from 'mydatabaseprovider'
const db = myDb()

export default async (req, res) => {
  cont myData = await db.query('posts')
  res.json(myData)
}

يمكنك تغييره إلى:

import myDb from 'mydatabaseprovider'
const db = myDb()

export async function getData() {
  const myData = await db.query('posts')
  return myData
}

export default (req, res) => {
  const myData = await getData()
  res.json(myData)
}

ثم في صفحتك:

import {getData} from './api/myfunction'

export async function getStaticProps() {
  const myData = await getData()
  return {
    props: {
     myData
   }
  }
}

سيكون من الصعب أن تفعل الشيء نفسه مع واجهات برمجة تطبيقات GraphQL. وكذلك لمعظم REST.

استدعاء API! = جلب من DB (بشكل عام)
هناك دائمًا بعض منطق الأعمال في طبقة API مثل إعادة تسمية الحقول وإعادة تنسيق البيانات وما إلى ذلك.

أنا متأكد من أن لديك أسبابًا تمنع مكالمات pages/api ... لكن تجاوز واجهة برمجة التطبيقات الحقيقية لن يكون سهلاً أو رخيصًا. ولن يفوق بضع أجزاء من الألف من الثانية رسوم الكود الإضافي / التعقيد IMO.

كما أنه من الغريب أن يتم السماح بالطلبات لأي واجهة برمجة تطبيقات. ماعدا خاصتك 🤷‍♂

يؤدي استخدام unstable_getStaticPaths إلى إعادة تحميل الصفحة ، وفقدان الحالة الحالية في إعادة التحميل على سبيل المثال. هل سيتغير هذا السلوك في المستقبل؟

تحرير: يبدو أنه يمكن التحايل على هذا السلوك باستخدام الخيار as في الروابط أو جهاز التوجيه

<Link
  href='/item/[key]'
  as={`/item/${itemName}`}
>
router.push(
  '/item/[key]',
  `/item/${itemName}`
);

meesvandongen كان دائما <Link> غير صالح ، فسيأخذك إلى الجزء الخلفي ، ويعمل بشكل أساسي كـ <a> . يجب إقران الأجزاء الديناميكية مثل [key] مع القيم المقابلة.

reaktivo pages/[lang]/blog/[id].js -> في getStaticPaths كل عناوين url لعرضها بشكل ثابت.

https://github.com/zeit/next.js/issues/9524#issuecomment -562625858
في هذه الحالة ، يجب إضافة دالة getStaticPaths و getStaticProps لكل صفحة باستثناء index.js.
إذا كانت هناك بعض صفحات mdx ، فسيكون من الصعب صيانة المشروع

ضع في اعتبارك التغيير أو التوافق مع الأساليب الثابتة getStaticPaths getStaticProps . https://github.com/zeit/next.js/issues/9524#issuecomment -558617056
إذا كان الأمر كذلك ، فيمكن التفاف الصفحة بواسطة وظيفة ذات ترتيب أعلى أو مكون أعلى رتبة HOC.
بهذه الطريقة ، تكون الشفرة أكثر قابلية للصيانة وأكثر ملاءمة للمخطوطة.


اهتزاز الشجرة مقابل الديناميكي. يا لها من صداع مقايضة

باستخدام 9.2.3-canary.13 حاولت استخدام fallback: false في getStaticPaths مثل هذا:

  return {
    fallback: false,
    paths: slugs.map(slug => ({params: {slug: slug}}))
  }

لكنه فشل مع الخطأ التالي:

Error: Extra keys returned from unstable_getStaticPaths in /blog/[slug] (fallback) Expected: { paths: [] }

باستخدام 9.2.3-canary.13 حاولت استخدام fallback: false في getStaticPaths مثل هذا:

  return {
    fallback: false,
    paths: slugs.map(slug => ({params: {slug: slug}}))
  }

لكنه فشل مع الخطأ التالي:

Error: Extra keys returned from unstable_getStaticPaths in /blog/[slug] (fallback) Expected: { paths: [] }

أعتقد أنك بحاجة للخريطة إلى مستوى أعلى ، لذا تقوم الخريطة بإرجاع الكائن الذي لديك حاليًا ، ولكن مع سبيكة فريدة من نوعها. بدلا من رسم الخرائط في المسارات.

لم أقم بتحديث إصداري على nextjs حتى الآن ، ولكن يجب أن يكون مشابهًا:

return data.map(item => {
    return {
      params: {
        slug: item.slug,
      },
    }
  })

مساهمة رائعة! إنه حقًا يحسن عملية العرض الثابت.

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

بدلاً من ذلك ، يمكنك تغيير السلوك لاستدعاء getStaticProps بدون سياق عند إنشاء الإجراء الاحتياطي. سيكون هذا متسقًا مع كيفية عمل next export حاليًا (على سبيل المثال ، يتم تصدير /p/[id].js إلى /p/[id].html عن طريق تشغيل getInitialProps بدون سياق).

  • getStaticProps - الاشتراك في الجيل الثابت (SSG) عند next build مرة.
  • getServerProps - الاشتراك في العرض من جانب الخادم (SSR) الذي يتم عرضه عند الطلب.

10722

أعد تسمية getServerProps إلى getServerSideProps.

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

نقطة جيدة لذكرها! لدي أيضًا بعض أخطاء البناء / النشر لأنني فاتني ذلك.

تم تحديث RFC ليعكس التغييرات

تضمين التغريدة

  • الطلب اللاحق لنفس المسار سيخدم الصفحة التي تم إنشاؤها

أفترض أن هذا يعني أن Next.js سيخزن الصفحة التي تم إنشاؤها في ذاكرة التخزين المؤقت؟ هل هذه ذاكرة تخزين مؤقت في الذاكرة؟ هل ذاكرة التخزين المؤقت هذه مقيدة بحدود أم يمكن أن يؤدي ذلك إلى تسرب في الذاكرة؟

عندما تستخدم next start فإنه يستخدم lru-cache مشابهًا لمثال التخزين المؤقت الحالي ، الحد الافتراضي حاليًا هو 50 ميغابايت ، وقد نجعله قابلاً للتكوين لاحقًا: https://github.com/zeit/next.js/ blob / canary /pack / next / next-server / server / spr-cache.ts # L90

عندما تستضيف على ZEIT الآن يحدث الإنشاء والتخزين المؤقت على CDN / Proxy لذا فهو يعمل بشكل مختلف قليلاً ولا داعي للقلق بشأن تسرب الذاكرة أو إذا كنت تتجاوز حد lru.

👍 حسنًا ، يبدو معقولًا. هذا أكثر أو أقل ما كان يدور في خلدي باعتباره سلوكًا افتراضيًا معقولًا.

  • getStaticProps - الاشتراك في الجيل الثابت (SSG) عند next build مرة.
  • getServerProps - الاشتراك في العرض من جانب الخادم (SSR) الذي يتم عرضه عند الطلب.

10722

أعد تسمية getServerProps إلى getServerSideProps.

لماذا إعادة التسمية بالرغم من ذلك؟ IMHO getServerProps دقيقة بدرجة كافية وأقصر للكتابة ، إضافة Side تبدو زائدة عن الحاجة بالنسبة لي.

كنت أتساءل عما إذا كان هناك أي تغييرات تم إجراؤها على طريقة getStaticPaths؟ لم يتم إنشاء صفحاتي الديناميكية كصفحات ثابتة بعد الآن ، هل يتم تصديرها كوظائف lambda الآن؟

هل أنا محق عندما يكون السلوك الافتراضي الآن هو أن الصفحات يتم عرضها لأول مرة على أنها صفحات lambda وفقط بعد زيارة صفحة معينة ، يتم إنشاء الصفحة إلى صفحة ثابتة؟ (كما هو مذكور في الاحتياطية)

erhankaradeniz لم يتم إجراء أي تغييرات على getStaticPaths شأنها أن تكون صفحتك (صفحاتك) هي Lambdas. من المحتمل أن يكون هذا خطأ في الاستخدام.

هل يمكنك إظهار الرمز الخاص بك من فضلك حتى نتمكن من تحديد المشكلة؟

Timer في الوقت الحالي ، عدت إلى [email protected] حيث لا يزال بإمكاني استخدام المعلمات ، حتى

هذه هي الطريقة التي أنشأت بها مساراتي حاليًا:

return cityData.map(city => {
    return {
      params: {
        country: city.countrySlug,
        city: city.slug,
      },
    }
  })

وفي صفحة أخرى أفعل:

return cityData.map(city => {
    return {
      params: {
        country: city.countrySlug,
        city: city.slug,
      },
    }
  })

لم يتمكن من تحويله إلى إصدار الكناري الجديد بالمسارات. يجب أن أفعل شيئًا خاطئًا ، لأنه لا يتم تشغيل console.logs في getStaticPath

لدي مشاكل في العرض المسبق للمسار المتداخل و SSG:

// pages/[lang]/[...slugs].js

export async function getStaticPaths() {
  let knex = await import("knex/client").then(m => m.default)
  let pages = await knex("page").select(["lang", "url"])
  return {
    fallback: true,
    paths: pages.map(page => {
      return {
        params: {
          lang: page.lang,
          slugs: page.url == "/" ? [] : page.url.slice(1).split("/"),
        }
      }
    }),
  }
}

يؤدي إلي

Error occurred prerendering page "/en/". Read more: https://err.sh/next.js/prerender-error:
Error: The provided export path '/en/' doesn't match the '/[lang]/[...slugs]' page.

للصفحة الرئيسية. لسبب ما فشل NextJS في المطابقة

{lang: "en", slugs: []}

إلى

/[lang]/[...slugs]

إذا قدمت {lang: "en", slugs: ["/"]} فإنه يتم إنشاؤه ولكن بعنوان URL خاطئ:

├ ● /[lang]/[...slugs]      875 B        204 kB
├   ├ /en/credits
├   ├ /en/%2F

للسجل ، getServerSideProps يعمل بشكل جيد مع إعداد مشابه.

أعلم أنه تجريبي ولكن هذا الموضوع لتقديم ملاحظات ، أليس كذلك؟

pages/[lang]/[...slugs].js يطابق /en/abcdef وليس /en ، لذلك عليك حاليًا إنشاء pages/[lang]/index.js .

يوجد طلب ميزة مفتوح لهذا: https://github.com/zeit/next.js/issues/10488

بادئ ذي بدء ، هذا رائع. كنت آمل أن يكون لدي شيء مثل هذا في Next.js حتى أتمكن أخيرًا من الابتعاد عن Gatsby.js والحصول على تطبيق مختلط (ثابت + ديناميكي).

🚀 لقد جربت إصدار التطبيق المعقد الكناري ونصف المخبوز بشكل جيد. أعترف أنني لم أقرأ جميع التعليقات هنا ولكني لست متأكدًا مما إذا كان هز الشجرة قد تم تنفيذه بعد.

يبدو أن 🤔 getStaticPaths يشبه إلى حد كبير setStaticPaths حيث نقوم بتعريف المسار الثابت لسلوك SSG. هذا النوع من الخلط بيني وبين قليلا.

🧐 أتساءل عما إذا كان بإمكاننا تحسين أوقات الإنشاء من خلال إنشاء فئات؟ أعلم أن هذا سيعقد الإعداد ولكن الأمر يستحق ذلك. دعني أشرح:

ماذا لو كان لدينا شيء مثل setBuildCategory يعينه على blog أو pages أو أي شخص يريد 2020-content . ثم يبحث منشئ SSG عن فئة الصفحة التي تم تغييرها ويحاول فقط إعادة إنشاء هذه الفئة من مجموعة من ذاكرة التخزين المؤقت + عرض جديد. يمكن أن يساعدنا شيء من هذا القبيل في جعل SSG سريعًا وتجنب أوقات الإنشاء الضخمة للأشياء التي ليست عرضة للتغيير كثيرًا ولكن لا يزال من الممكن تغييرها ، لذا لا يمكن أرشفتها.

إذا كان ذلك منطقيًا ؛ يسعدني القفز على مكالمة والدردشة حول هذا الموضوع.

كيف يتم التعامل مع getServerSideProps باستخدام خادم مخصص؟

if (pathname === '/a') {
  app.render(req, res, '/b', query)
}

في المثال أعلاه ، ستؤدي زيارة /a إلى عرض الصفحة pages/b.js . لكن إعادة التوجيه من جانب العميل إلى /a تحاول تنزيل ملف a.json ، وهذا غير موجود في هذه الحالة.

هل من المفترض أن تكون لدينا شروط مماثلة لطلبات /_next/data/{BUILD_ID}/{PAGE}.json لعرض ملفات JSON مختلفة؟

لاستخدام fallback: true في getStaticPaths ، كيف أحصل على كائن req؟ يبدو الآن أنني لا أستطيع. السبب الذي أحتاجه هو الحصول على بعض ملفات تعريف الارتباط من المتصفح لمصادقة المسار

tylermcrobert كيف تتخيل الاستيلاء على ملفات تعريف الارتباط عندما لا يكون هناك طلب على الإطلاق ؟!
لا يمكن جعل المسارات ذات الواجهة الخلفية التي تعتمد على طلبات الزائر الحقيقية ثابتة بتعريفات "ثابت" و "ديناميكي". كي لا نقول أنه لا يمكنك الجمع بين الثابت والمصادقة ... إن جزء المصادقة فقط سينتمي إلى واجهة برمجة التطبيقات ورمز العميل بدلاً من الصفحات.

كيف يتم التعامل مع getServerSideProps باستخدام خادم مخصص؟

if (pathname === '/a') {
  app.render(req, res, '/b', query)
}

في المثال أعلاه ، ستؤدي زيارة /a إلى عرض الصفحة pages/b.js . لكن إعادة التوجيه من جانب العميل إلى /a تحاول تنزيل ملف a.json ، وهذا غير موجود في هذه الحالة.

هل من المفترض أن تكون لدينا شروط مماثلة لطلبات /_next/data/{BUILD_ID}/{PAGE}.json لعرض ملفات JSON مختلفة؟

يدعم Next.js معلمات المسار الديناميكي ، لذلك نادرًا ما تكون هناك حاجة لإعادة التعيين في خادم مخصص: https://nextjs.org/docs/routing/dynamic-routes

الأسلوب الذي حددته بالفعل لا يعمل مع <Link> (قد يتسبب في انتقال كامل للصفحة) لذا فإن getServerSideProps يعمل بالفعل.

tylermcrobert كيف تتخيل الاستيلاء على ملفات تعريف الارتباط عندما لا يكون هناك طلب على الإطلاق ؟!
لا يمكن جعل المسارات ذات الواجهة الخلفية التي تعتمد على طلبات الزائر الحقيقية ثابتة بتعريفات "ثابت" و "ديناميكي". كي لا نقول أنه لا يمكنك الجمع بين الثابت والمصادقة ... إن جزء المصادقة فقط سينتمي إلى واجهة برمجة التطبيقات ورمز العميل بدلاً من الصفحات.

ربما أسيء فهم الخيار الاحتياطي في هذه الحالة. ما تقوله منطقي تمامًا في سياق وقت البناء.

أليس fallback: true عندما لا يكون هناك مسار محدد مسبقًا؟ في هذه الحالة ، سيتم الوصول إلى رجوع من المتصفح ، أليس كذلك؟

tylermcrobert yes fallback: true case لها طلب لكن واجهة برمجة التطبيقات يجب أن تكون موحدة بواسطة "القاسم المشترك الأدنى". لا يمكنني تخيل نظام عمل حيث يتم بناء كل شيء بمجموعة واحدة من المباني ثم يتم تحديثه بشكل تدريجي بمجموعة مختلفة تمامًا من المباني. ستكون كارثة لدعم.

أعتقد أنك تفوت فكرة أن تلك البنيات المتزايدة ستظل مخزنة مؤقتًا بين البنيات. لذا فإن دور الزائر الأول سيؤثر على نتيجة البناء لجميع المستخدمين اللاحقين! تبدو فكرة سيئة.

@ ivan-kleshnin أفهم وأوافق بالتأكيد. السبب الذي أطلبه هو حالة الاستخدام الخاصة بي.

أنا أستخدم نظام إدارة محتوى بدون رأس يسمح بوظيفة المعاينة حتى لا يتم تضمين الصفحات التي ستحتاج إلى المعاينة في وقت الإنشاء (لأن الإدخال الذي تتم معاينته لن يكون موجودًا في هذه المرحلة). كنت أحسب أن هذه كانت حالة يأتي فيها الخيار الاحتياطي.

للوصول إلى تلك المعاينة ، أحتاج إلى الوصول إلى مرجع معاينة api الذي يتم توفيره عبر ملف تعريف الارتباط.

هل هذه حالة يجب فيها فقط إلغاء useStaticProps بالكامل؟ أكره أن أفقد ميزة الإنشاءات الثابتة لأنني لا أستطيع معاينة المستندات الخاصة بي.

تكمن جاذبية RFC على شيء مثل gatsby في أنه يمنحنا "تحكمًا مختلطًا" مع إنشاء موقع ثابت مما يجعل العمل مع أنظمة إدارة المحتوى بدون رأس

أنا أستخدم نظام إدارة محتوى بدون رأس يسمح بوظيفة المعاينة حتى لا يتم تضمين الصفحات التي ستحتاج إلى المعاينة في وقت الإنشاء (لأن الإدخال الذي تتم معاينته لن يكون موجودًا في هذه المرحلة). كنت أحسب أن هذه كانت حالة يأتي فيها الخيار الاحتياطي.

ترقبوا المزيد قريبًا

لذلك إذا فهمت هذا صحيحًا ، فيمكننا استخدام الخيار الصحيح عندما يسجل المستخدم في حالتي على سبيل المثال (لا توجد صفحة ثابتة نظرًا لأنها صفحة / مستخدم جديد) ولكن عندما يتلقى الملف الشخصي زيارة ، يتم إنشاؤه تلقائيًا؟

إرهان كارادينيز
http://www.erhankaradeniz.com

في 4 مارس 2020 ، الساعة 20:25 ، كتب Tim Neutkens [email protected] :


أنا أستخدم نظام إدارة محتوى بدون رأس يسمح بوظيفة المعاينة حتى لا يتم تضمين الصفحات التي ستحتاج إلى المعاينة في وقت الإنشاء (لأن الإدخال الذي تتم معاينته لن يكون موجودًا في هذه المرحلة). كنت أحسب أن هذه كانت حالة يأتي فيها الخيار الاحتياطي.

ترقبوا المزيد قريبًا

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذه الرسالة الإلكترونية مباشرةً ، أو اعرضها على GitHub ، أو قم بإلغاء الاشتراك.

تعد بيانات المستخدم مثالًا سيئًا لأنك تريد جلب جانب العميل هذا. يوجد احتياطي للصفحات التي لم يتم إنشاؤها في وقت الإنشاء بشكل ثابت عند الطلب. على سبيل المثال ، قد ترغب في إنشاء أفضل 100 مدونة في وقت الإنشاء وعدم إنشاء مدونات أخرى ذات حركة مرور أقل.

سيتم إرسال المستندات لذلك قريبًا.

نعم ، ما قصدته هو صفحة عنصر نائب .. سأقوم بإحضار بيانات المستخدم من جانب العميل بالفعل.

timneutkens هل سيكون هناك أي طريقة لحذف أو إعادة إنشاء صفحات معينة تم إنشاؤها بشكل ثابت؟

أهلا!!! يبدو مثل التطبيق الأمثل. أنا أحب كلاً من React و Next !!! جعل كل شيء أنيقًا وبسيطًا بالنسبة لنا لاستخدامه !! لكن المثال يتضمن فكرة مدونة. أود أن أرى مثالاً على تنفيذ عند الاستعلام عن نظام إدارة محتوى بدون رأس وإجراء عملية الجلب لكل صفحة / منشور كتصدير كعنصر ثابت.

// هتاف ، لأنه قريب من يوم الجمعة !!!

timneutkens هذا مثير 👌

أحد السيناريوهات التي نواجهها كثيرًا وليس لدي حل مثالي بعد مع next.js أو gatsby باستثناء المسارات الديناميكية أو إنشاء المشاريع في حلقة:

لأسباب تاريخية ، يتعين علينا التعامل مع مجالات متعددة (وليس هناك رغبة في تغيير ذلك) التي تخدم نفس / الصفحات بالضبط باستثناء التسعير والعملة وأرقام هواتف الدعم ومحددات اللغة. بطبيعتها ، تكون معظم صفحات التسويق هذه ثابتة إلى حد ما وسيكون من الكافي بناؤها يوميًا أو أسبوعيًا (مقابل جعلها تقدم عند كل طلب).

سؤالي / فكرتي: هل ترى طريقة (في المستقبل؟) يمكن لـ getStaticPaths إنشاء صفحات بناءً على شيء ليس معلمة مسار ولكن يمكن استخدامها على مستوى الطلب للتبديل بينها (على سبيل المثال ، بدون خادم تقوم الدالة بإرجاع نتيجة ثابتة مسبقة الإنشاء بناءً على locale )

هذا يعني أن https://mysite.com/my-product و https://mysite.co.uk/my-product سيخدمان صفحتين ثابتتين مختلفتين ولكن دون الحاجة إلى إنشاء تطبيقنا التالي 50 مرة أو الاضطرار إلى الوصول إلى CMS عند كل طلب😅

شكرًا مقدمًا وحريصًا على سماع أفكارك ، خاصة إذا كان هذا شيئًا للمستقبل يمكن حله / حله ❤️

أفكر في حالة استخدام حيث أرغب في استخدام SSG للصفحات المقصودة عالية الحركة لـ SEO ولتقليل حمل الخادم ، ولكني ما زلت أرغب في استخدام البيانات الحالية بعد الترطيب ، وتوجيه جانب العميل إلى هذه الصفحة. هل إصلاح الأجهزة التجارية؟

لذلك بشكل أساسي من جانب العميل في التوجيه إلى هذه الصفحة ، يجب أن يكون السلوك مثل getInitialProps (يتم جلب البيانات الحالية قبل أن تصبح الصفحة مرئية). وفي التوجيه من جانب الخادم إلى هذه الصفحة ، يجب تقديم HTML الثابت وترطيبه ، ثم (اختياريًا) يتم جلب بعض استجابات واجهة برمجة التطبيقات لتحديث بعض البيانات على الصفحة.

لقد لعبت للتو مع unstable_getStaticProps فقط لتجربته وواجهت صراعًا ممتعًا: من الصعب استخدام مسارات API مع getStaticProps .

لا تهتم بدلالات الكود ، ولكن فقط تدفق جلب البيانات:

// pages/api/healthcheck.ts
import { NextApiResponse, NextApiRequest } from 'next';

export type ApiHealthCheckResponse = {
  message: 'ok';
};

const healthCheckHandler = (
  req: NextApiRequest,
  res: NextApiResponse<ApiHealthCheckResponse | ''>,
) => {
  if (req.method === 'GET') {
    return res.status(200).json({ message: 'ok' });
  }

  return res.status(405).send('');
};

export default healthCheckHandler;
// pages/index.js
// ...

export async function unstable_getStaticProps() {
  return {
    props: {
      healthcheck: (await fetch('localhost:3000/api/healthcheck').json())
    },
  };
}

سيتعطل بناء الصفحة في وقت الإنشاء لأن الخادم لا يعمل. لست متأكدًا مما إذا كانت هذه حالة استخدام صالحة ، حيث لا ينبغي استخدام getStaticProps مع أي شيء ديناميكي للغاية ، لكنني اعتقدت أنه كان أمرًا مثيرًا للاهتمام لمشاركته (يمكنني تخيل نقطة نهاية واجهة برمجة تطبيقات الطريق المسؤولة عن الحصول على البيانات من واجهة برمجة تطبيقات أخرى وإعادة تنسيقها.

martpie قد ترغب في التحقق من هذا التعليق: https://github.com/zeit/next.js/issues/9524#issuecomment -589772756

تم إصدار دعم الجيل التالي من دعم إنشاء الموقع الثابت (SSG) باعتباره مستقرًا في Next.js 9.3!

يتضمن هذا الإصدار أيضًا دعمًا لـ "وضع المعاينة" ، أو القدرة على تجاوز الصفحة المعروضة مسبقًا وعرض الصفحة عند الطلب للمستخدمين المصرح لهم .

يمكنك قراءة المزيد حول هذا الموضوع في منشور المدونة الخاص بنا. إذا كنت تعمل أكثر ، فانتقل مباشرةً إلى مستنداتنا !

يرجى إرسال أي أسئلة إلى مجتمع Next.js GitHub !

هذا رائع جدا! شكرا على العمل الشاق!

لا يبدو أن هذه الميزة الجديدة تعمل مع الملحمة والإعادة الآن

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