Next.js: طلب الميزة: دعم Basepath

تم إنشاؤها على ٢١ أغسطس ٢٠١٨  ·  73تعليقات  ·  مصدر: vercel/next.js

طلب المواصفات

هل طلب الميزة الخاص بك متعلق بمشكلة؟ يرجى الوصف.

تعد المناطق المتعددة ميزة رائعة تتيح تشغيل عدة تطبيقات next.js على نفس المجال ، ولكنها لا تسمح بتحديد مسار أساسي تقبله جميع أجزاء next.js. نظرًا لأننا غير قادرين على استخدام تطبيقات مساحة الاسم في الوقت الحالي ، فلا يمكن الحصول على نفس الأسماء للصفحات في مختلف التطبيقات.

صِف الحل الذي تريده

أريد أن أكون قادرًا على تكوين basepath في الملف next.config.js. بفضل هذا التكوين ، ستكون جميع أجزاء next.js (جهاز التوجيه والرابط والأصول الثابتة وما إلى ذلك) على دراية بالمسار الأساسي وسيتم إنشاء المسارات الصحيحة ومطابقتها تلقائيًا.

صِف البدائل التي فكرت فيها

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

سياق إضافي

يتيح لنا الحل assetPrefix تحديد بادئة مختلفة لكل تطبيق. ولكن بقدر ما أعلم أنه يعمل فقط مع مضيفين مختلفين.

مثال على المناطق

module.exports = {
  assetPrefix: NOW_URL ? `https://${alias}` : 'http://localhost:4000'
}

إذا أضفت مسارًا أساسيًا إليه ، فسيخفق كل شيء

module.exports = {
  assetPrefix: NOW_URL ? `https://${alias}/account` : 'http://localhost:4000/account'
}

screen shot 2018-08-21 at 10 47 08

في رأيي يجب تقسيمها إلى متغيرين:

module.exports = {
  assetPrefix: NOW_URL ? `https://${alias}` : 'http://localhost:4000',
  basepath: '/account'
}

القضايا ذات الصلة

story needs investigation

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

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

لست متأكدًا مما تتوقعه من خلال نشر هذا.

يتم العمل على Next.js بدوام كامل بواسطة فريقي (5 أشخاص) ، ونحن نعمل على العديد من الميزات في نفس الوقت. في العام الماضي ، عملنا على هذه:

جعل تطبيقات Next.js (الجديدة والحالية) بشكل فعال أصغر حجمًا وأسرع وأكثر قابلية للتوسع.

إذا كنت ترغب في التعبير عن "التصويت الإيجابي" لميزة ما ، يمكنك ذلك. استخدم ميزة 👍 في الخيط الأولي.

أوافق بالتأكيد على أن يكون basePath ميزة مضمنة. إنه موجود بالفعل على خريطة الطريق وقد قمت بكتابة إعلان عام أولي ، والذي كان من الممكن أن تراه من خلال إعادة قراءة الموضوع.

هنا العلاقات العامة: https://github.com/zeit/next.js/pull/9872

لا تتردد في التواصل مع [email protected] إذا كنت تريد المساهمة مالياً في تحقيق هذه الميزة.

ال 73 كومينتر

ccjxnblk

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

أحب أن يكون لديك ملاحظاتك 👍

بعد اللعب بالرمز ، أدركت أنه سيكون من الأسهل بكثير تقسيم assetPrefix إلى أجزاء متعددة:

module.exports = {
  host: NOW_URL ? `https://${alias}` : 'http://localhost:3000',
  basePath: '/account',
}

لا يزال بإمكاننا الاحتفاظ بمتغير assetPrefix داخليًا ، ولكن يجب على المستخدم تحديد ما يحتاج إليه بدقة أكبر.

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

كأثر جانبي ، يؤدي هذا أيضًا إلى تغييرات أقل في الكود.
من الواضح تمامًا إذا قارنت هذين النوعين من العلاقات العامة:
https://github.com/panter/next.js/pull/2 (انقسام)
https://github.com/panter/next.js/pull/1 (مرر كليهما)

في رأيي ، يجب أن يكونا منفصلين ، والسبب في ذلك هو أنه ليس منكسر وأكثر مرونة للاحتفاظ بـ assetPrefix ولديك basePath منفصل.

هل assetPrefix هو الاسم الصحيح إذن؟ كلا المتغيرين هما في الواقع بادئة ، أليس كذلك؟

assetPrefix للأصول مثل: حزم الصفحات. سيكون basePath لجهاز التوجيه.

الطريقة التي يجب أن تعمل بها هي:

  • إذا تم تعريف assetPrefix استخدم assetPrefix لتحميل الحزم ، فلا تلمس جهاز التوجيه (السلوك الحالي)
  • إذا تم توفير assetPrefix و basePath استخدم assetPrefix لتحميل الحزم ، أضف basePath إلى جهاز التوجيه
  • إذا لم يتم تعريف assetPrefix و basePath ، فاستخدم basePath لتحميل الحزم ، وأضف basePath إلى جهاز التوجيه
  • إذا لم يتم تعريف assetPrefix ولا basePath فإننا لا نفعل شيئًا مختلفًا (السلوك الحالي عندما لا يتم توفير assetPrefix )

سم مكعبalexindigoDullReferenceException @ 3-عدن

هل يمكنك إبداء ملاحظاتك على الاقتراح أعلاه: https://github.com/zeit/next.js/issues/4998#issuecomment -414978297

tomaswitek لست متأكدًا مما لم ينجح تمامًا بالنسبة لك مع assetPrefix ، فهذه هي بادئة الأصول التي نستخدمها في الإنتاج: "assetPrefix":"https://static.trulia-cdn.com/javascript" وهي تعمل كما هو متوقع.

وبشكل عام ، نحن نستخدم مناطق متعددة (نسميها جزر) في نفس المجال و "مسار القاعدة" لم يخطر ببالنا مطلقًا ، نظرًا لأنه سيعقد إمكانية التشغيل البيني بين الجزر. اسمحوا لي أن أشرح بالتفصيل قليلاً:

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

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

  2. عبر الروابط بين الجزر - للحفاظ على روح الجزر ككيانات منفصلة قابلة للنشر ، لا ينبغي أن يكون هناك أي تسرب داخلي للمعرفة بالتنفيذ بين الجزر المختلفة.
    لذا فإن أفضل طريقة للجزر للإشارة إلى صفحات بعضها البعض ، هي تصدير المسارات المتاحة للجزر (الجزر) الأخرى للاستهلاك (_ وفي عالم nextjs ، يبدو أن نوع المكونات <IslandALink> المخصص سيكون المفضل طريقة_).
    حتى الآن ، كل شيء مستقيم للأمام - تفترض جميع الجزر مشاركة نفس المجال ولديها مجموعة من المسارات المطلقة ( /path1 ، path2 ، إلخ). بهذه الطريقة تستورد الجزيرة الثانية قائمة المسارات هذه وتعتمد عليها لتكون مستقرة. في الوقت نفسه ، من الضروري جدًا أن تحافظ كل جزيرة على توافق مساراتها مع الإصدارات السابقة (وهو أمر جيد في الويب على أي حال) :)

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

أو كيف تصورت ذلك الجزء من القصة؟

شكرا لك.

^ لقد تمت كتابته قبل قهوة الصباح ، لذا يرجى إعلامي إذا كنت بحاجة إلى شرح أكثر تماسكًا لأي جزء منه. :)

بادئ ذي بدء ، أشكركم يا رفاق على قضاء الوقت في مراجعة مشكلتي.

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

alexindigo Thx

لست متأكدًا مما لم ينجح تمامًا بالنسبة لك مع الأصول الحالية

لدي مشكلتان هنا:

  1. لا يمكنني العمل مع عدة مجالات أو نطاقات فرعية في المشروع الحالي. (قيود المجال وعدم وجود شهادة SSL بدل)
  2. يتطلب التنفيذ الحالي لـ assetPrefix على مجال واحد مزيدًا من التعديلات في توجيه الوكيل ، والملفات الثابتة وما إلى ذلك. يمكننا تقليل هذه التعديلات من خلال تقديم basePath . لن يوقف أي شيء ولن يزيد من التعقيد لأنك لست مضطرًا لتقديم basePath كما هو مذكور بالفعل

التطبيق ليس لديه فكرة عن مكان نشره

لدينا نفس الهدف هنا بالطبع! نحن نحدد الأصول البادئة ديناميكيًا في الحل الحالي الذي لدينا. يتم توفيره عبر رؤوس الطلب بالوكالة.

إذن كيف تختلف عن طريقة عمل الشيء حاليًا؟

سيكون جهاز التوجيه على دراية بـ ContextPath وسيقلل مقدار التعليمات البرمجية المخصصة.

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

لا يجب أن يكون كذلك. يجب أن يتمتع المطور بالحرية هنا. من المفترض أن يكون من الممكن توفير basePath ديناميكيًا بنفس الطريقة التي توفرها AssassPrefix.

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

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

ومع الطريقة الحديثة لنشر الأشياء ، فهذا يعني إعادة نشر جميع الجزر عندما تحتاج إلى إضافة واحدة جديدة.

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

alexindigo ، هل يمكنك أن _next 😄
هل كل جزرك لها نفس التكوين؟
"assetPrefix":"https://static.trulia-cdn.com/javascript"

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

لا يمكنني العمل مع عدة مجالات أو نطاقات فرعية في المشروع الحالي. (قيود المجال وعدم وجود شهادة SSL بدل)

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

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

راجع للشغل ، لم يكن "لا ، لا تضيف هذه الميزة" :) كان الأمر أشبه - "ربما يمكننا التفكير في هذا النهج بشكل أكثر شمولية" :)

لا يجب أن يكون كذلك. يجب أن يتمتع المطور بالحرية هنا. من المفترض أن يكون من الممكن توفير basePath ديناميكيًا بنفس الطريقة التي توفرها AssassPrefix.

نعم. إنه يعمل فقط عندما لا يكون هناك رابط بين الجزر. ويبدو أن هذه هي حالة الاستخدام الخاصة بك. في الوقت نفسه ، أجد صعوبة في فهم ما الذي يجعلها جزرًا بدلاً من كونها مجرد مجموعة من التطبيقات المستقلة ، إذا كانت مستقلة بنسبة 100٪؟ :)

ربما يمكنك أيضًا إضافة basePath في تصدير المسارات.

لا أرى كيف يمكن القيام بذلك (بسهولة) ، نظرًا لأن تصدير المسارات يحدث في وقت الإنشاء ، ويتم تحديد basePath في وقت النشر ، ويمكن أن يكون هناك أكثر من عملية نشر لنفس الأداة البرمجية (stage ، preprod ، prod ، اختبار البيئة ، إلخ).


هل كل جزرك لها نفس التكوين؟
"الأصول": " https://static.trulia-cdn.com/javascript "

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

وبهذه الطريقة ، لدينا طلبات "html عادية" فقط لخوادم تطبيقاتنا ، ولهذا السبب لن أرى أي مسارات "_next" على trulia.com

أما بالنسبة لأمثلة الجزر:

جزيرتنا الجديدة - صفحة الأحياء - https://www.trulia.com/n/ca/san-francisco/pacific-heights/81571 (ويمكنك العثور على المزيد منها هنا: http://www.trulia. كوم / الأحياء)
هذه الجزيرة مسؤولة عن جميع المسارات /n/* .

وجزيرة أخرى هي صفحة تسجيل الدخول الخاصة بنا - https://login.trulia.com/login - تبدو وكأنها مجال مختلف ، لكنها في الحقيقة ليست كذلك ، تبدو بهذه الطريقة لمجموعة مختلفة من الأسباب ، لكنها من الناحية الفنية نفس النشر. :)
وهذه الجزيرة تتعامل مع عناوين url مثل /login ، /signup .

اسمحوا لي أن أعرف إذا كان لديك المزيد من الأسئلة.

alexindigo شكرا جزيلا لك على الأمثلة الخاصة بك.
لدي بعض الأسئلة بعد تحليل الأمثلة 😄

ما زلت تفعل عرض الخادم لكل جزيرة ، لكنك تحاول استخراج أكبر قدر ممكن من الأصول في CDN مشترك ، أليس كذلك؟

هل يمكنك أن تصف أكثر قليلاً ما يحدث بالضبط عند استدعاء https://www.trulia.com/n/ca/san-francisco/pacific-heights/81571 ؟ هل يعرف وكيلك أن /n يشير إلى نظرة عامة على الحي ويعيد توجيهه إلى الجزيرة الصحيحة؟ هل يؤثر بطريقة ما على الطلب قبل وصوله إلى الجزيرة؟

هل تستخدم التوجيه المدمج من التالي داخل الجزيرة أم لديك حل مخصص؟
أردت التحقق من التوجيه داخل جزيرتك. لسوء الحظ ، يحتوي Neighborhood overview على تنقل مشروط أكثر أو أقل دون تغيير عنوان url. في تسجيل الدخول يبدو أن هناك حلًا مخصصًا تمامًا.

أتمنى أن أجيب على جميع أسئلتك في هذا التعليق 😏

راجع للشغل ، لم يكن "لا ، لا تضيف هذه الميزة" :) كان الأمر أشبه - "ربما يمكننا التفكير في هذا النهج بشكل أكثر شمولية" :)

بالتأكيد ، سيكون من الرائع العثور على حل لا أضطر فيه إلى لمس next.js 😏

نعم. إنه يعمل فقط عندما لا يكون هناك رابط بين الجزر. ويبدو أن هذه هي حالة الاستخدام الخاصة بك. في الوقت نفسه ، أجد صعوبة في فهم ما الذي يجعلها جزرًا بدلاً من كونها مجرد مجموعة من التطبيقات المستقلة ، إذا كانت مستقلة بنسبة 100٪؟ :)

لم أكتب ولم أقل إنني أبحث عن حل "جزيرة". لقد أجريت للتو محادثة مع timneutkens حيث وصفت مشكلتي وكانت إجابة تيم أساسًا next.js لا تدعم basepaths. وبعد البحث في googling قليلاً ، أدركت أنني لست الوحيد الذي يبحث عنه. لذلك اعتقدت أنه يمكنني المساهمة قليلاً. بعد ذلك أرسل إليك Tim رسالة لإرسال تعليقات إليّ وأنا ممتن جدًا لملاحظاتك.

لا أرى كيف يمكن القيام بذلك (بسهولة) ، نظرًا لأن تصدير المسارات يحدث في وقت الإنشاء ، ويتم تحديد basePath في وقت النشر ، ويمكن أن يكون هناك أكثر من عملية نشر لنفس الأداة البرمجية (stage ، preprod ، prod ، اختبار البيئة ، إلخ).

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

صباح الخير tomaswitek :)

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

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

يبدو أنك على ما يرام مع الحل حيث أن "basePath" هو جزء من كود التوجيه الخاص بك ، وهو شيء ذكرته في البداية - مثل المجلد الفرعي داخل الدليل pages (راجع للشغل ، هذا الأسلوب سيشير إلى المطورين المختارين basePath جيدًا). لكن الشيء الوحيد الذي أوقفك هو أن مسار nextjs الداخلي للأصول _next غير قابل للتهيئة.

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

ويمكن أن يقودنا إلى أبعد من ذلك ، على سبيل المثال ، إذا كان بإمكاننا تكوين AssetsPath لكل أصل (على سبيل المثال مع خريطة next.config من نوع ما) - سيسمح لنا بمشاركة الأصول بين التطبيقات ، مما سيؤدي إلى تحسين الأداء وأشياء أخرى.

وهناك علاقات عامة مفتوحة لهذه الميزة. ؛) / cctimneutkens يبدو أن الوقت قد حان للعودة إلى هذا الجرو. :)

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

مرحبًا ccarse ، لديّ مفترق عمل نستخدمه في الإنتاج بالفعل: https://github.com/panter/next.js/pull/2
أنا مستعد أيضًا لاستثمار الوقت لفتح علاقات عامة لهذه الميزة.
timneutkensalexindigo هناك طريقة أخرى كيفية حل هذه المشكلة؟
إذا لم نكن بحاجة إلى تهيئة basePath ، فهل يمكنك أن تعطينا مثالًا بسيطًا باستخدام assetPath ؟

شركتي أيضًا تواجه هذا الأمر.

نحن نتولى ببطء تطبيقًا قديمًا ، قسمًا قسمًا ، واستبداله بـ Next.js.

كمثال مبسط:

| URL | التطبيق |
| --- | --- |
| example.com | إرث |
| example.com/shop | التالي |
| example.com/search | إرث |
| example.com/members | التالي |

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

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

نحن أيضًا نستخدم خادمًا مخصصًا (hapi) ، لذلك سيكون من الجيد أن نتمكن من الاستفادة من كل ما يتم إنشاؤه هنا داخل خادم مخصص أيضًا.

ربما هناك مزيج من إعدادات now.config.json أو بعض استخدام الوكيل الصغير الذي يمكننا استخدامه لإنجاز هذا الشيء نفسه ، لكننا لم نكتشف المجموعة الصحيحة حتى الآن.

نحن نواجه ، على ما أعتقد ، نفس المشكلة مع العديد من تطبيقات Next.js المصدرة بشكل ثابت والمستضافة على Now v2.

| URL | التطبيق |
| - | - |
| example.com | التالي |
| example.com/dashboard | التالي |

كما هو متوقع ، يعمل تطبيق الجذر بشكل جيد. لكن الأمور تنحرف في الحالة الثانية. نحن نلتف حاليًا next/link والذي ، مع assetPrefix ، يحل معظم المشكلة:

export default ({ children, href, ...rest }) => (
      <Link href={process.env.NODE_ENV === "production" ? `/dashboard${href}` : href} {...rest}>
        {children}
      </Link>
);

ومع ذلك ، فإن هذا يكسر prefetch لأنه بعد ذلك يحاول البحث عن ملفات .js على عنوان URL غير صحيح:

الحل الحالي لدينا هو تعطيل prefetch ، وهذا ليس مثاليًا.

ما هو الوضع في هذا؟

كما تبحث عن تحديث لهذا من فضلك.

timneutkens أنا مستعد لاستثمار الوقت لفتح

نحتاج أيضًا إلى حل لهذا

سنقوم بتقديم واجهة برمجة تطبيقات جديدة قريبًا والتي ستجعل هذا الاقتراح قديمًا.

كما تأثرت بهذا. تحتاج إلى تشغيل المشروع التالي ضمن مسار دليل فرعي. نتطلع إلى الميزة الرسمية. هل هناك ETA؟

API

فكيف الحال؟ :د

من فضلك لا ترسل بريدًا عشوائيًا إلى سلسلة الرسائل واستخدم ميزة GitHub في المشكلة نفسها.

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

قد لا يكون هذا مرتبطًا تمامًا بالمناطق المتعددة ولكنه قد يساعد ...

لقد قمت بحل شيء مشابه لهذا عن طريق إنشاء خادم مخصص واستخدام وسيط وكيل

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

const proxy = require('http-proxy-middleware');

app.setAssetPrefix('/dashboard');

  // Express custom server
  // Proxy so it works with prefix and without...
  // So if asset prefix is set then it still works
  const server = express();
  server.use(
    proxy('/dashboard', {
      target: 'http://localhost:3000', 
      changeOrigin: true,
      pathRewrite: {
        [`^/dashboard`]: '',
      },
    }),
  );

الاقتراح الذي أشرت إليه هو # 7329

الاقتراح الذي أشرت إليه هو # 7329

تضمين التغريدة
هل يمكنك الثابتة والمتنقلة تقديم مزيد من التفاصيل حول كيفية قيام الخطاف المقترح بحل مشاكل مسار القاعدة لدينا؟
وماذا عن عمليات إعادة التوجيه مثل Router.push('/about') هل سيتم استبدالها بخطاف أيضًا؟

شكرا لك على وقتك 😏

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

أي تحديث حول متى يمكننا الحصول على حل أو على الأقل حل بديل لهذا؟

استخدم 👍 في الإصدار الأولي بدلاً من نشر أي تحديث.

@ MMT-LD يعمل نوع الحل الخاص بك بالنسبة لي ، ولكن الآن يتم إعادة تحميل الصفحة في كل نقرة على الرابط أو حدث دفع للموجه

لقد جربت حل Zertz وقد نجح على أكمل وجه!
كما يمكنني إصلاح مشكلة prefetch بنسخ ملفات الإخراج إلى المسارات مسبقة الجلب.
https://github.com/fand/MDMT/blob/master/scripts/copy-preload.js

... إنها خدعة قذرة ، لكنها تعمل على أي حال🤪

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

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

واجهت هذه المشكلة ولكن تم إصلاحها باستخدام المعلمة "as" على الرابط ، لذا يشير الرابط إلى الملف الداخلي ، لكن "as" متعلق بالمسار
على سبيل المثال:
<Link href={"/${item.link}"} as={"./${item.link}"}>

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

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

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

// WithConfig component
import getConfig from 'next/config';

const { publicRuntimeConfig } = getConfig();

const WithConfig = ({ children }) =>
  children && children({ config: publicRuntimeConfig });

export default WithConfig;
// Extended Link component

 import React from 'react';
import PropTypes from 'prop-types';
import Link from 'next/link';
import { WithConfig } from '../WithConfig';
/* 
    <Link> component has two main props:
    href: the path inside pages directory + query string. e.g. /page/querystring?id=1
    as: the path that will be rendered in the browser URL bar. e.g. /page/querystring/1

*/

const NextLink = ({
  browserHref,
  pagesHref,
  whatever,
}) => {
  return (
    <WithConfig>
      {({ config: { pathPrefix } = {} }) => (
        <Link
          as={pathPrefix ? `${pathPrefix}${browserHref}` : browserHref}
          href={pagesHref}
          passHref
        >
          <a>{whatever}</a> // this bit is up to you - children or whatever
        </Link>
      )}
    </WithConfig>
  );
};

NextLink.propTypes = {
  browserHref: PropTypes.string.isRequired,
  pagesHref: PropTypes.string,
};

NextLink.defaultProps = {
  pagesHref: undefined,
};

export default NextLink;

استعمال:

import NextLink from '../NextLink'

<NextLink browserHref={`/page/1`} pagesHref={`/page?querystring=1`} whatever='I'm the link' />

حظا سعيدا: مبتسم:

نظرًا لأنه تم رفض طلب RFC useLink (# 7329) وسيساعدنا الحصول على دعم basePath بشكل كبير ، فهل يسعد مشروع Next.js بقبول الممثلين المستقلين الذين ينفذونه؟ أنا على استعداد للقيام بذلك.

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

بشكل عام ، أعتقد أن التصميم واضح ، مجرد متغير تكوين واحد:

module.exports = {
  basePath: '/demo'
}

يتم تحديد التفاعلات مع assetPrefix هنا: https://github.com/zeit/next.js/issues/4998#issuecomment -414978297.


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

هذه المشكلة موجودة منذ عام 2017 ، هل هناك أي حل بديل؟ أو رد رسمي على طلب basePath الخاص بنا؟

لذلك بعد محاولة جعل هذا يعمل مع مزيج من assetPrefix <Link> ومكون https://github.com/zeit/next.js/issues/4998#issuecomment -464345554 أو https://github.com/zeit/next.js/issues/4998#issuecomment -521189412 ، لا أعتقد أنه يمكن القيام به ، لسوء الحظ.

كان تحديد assetPrefix بسيطًا نسبيًا ، شيء من هذا القبيل في next.config.js :

const assetPrefix = process.env.DEPLOYMENT_BUILD ? '/subdir' : '';

module.exports = {
  assetPrefix,
  env: {
    ASSET_PREFIX: assetPrefix,
  },
}

الخطوة التالية هي مكون Link مخصص. الفكرة الأولى ، على سبيل المثال في https://github.com/zeit/next.js/issues/4998#issuecomment -464345554 ، هي بادئة href مثل هذا (مبسط):

export default ({ children, href, ...rest }) => (
  <Link href={`${process.env.ASSET_PREFIX}${href}`} {...rest}>
    {children}
  </Link>
);

كما أفاد آخرون في هذا الموضوع ، فإن هذا يقطع الجلب المسبق لأن الطلبات فجأة إلى / subdir /_next/static/.../pages/ subdir /example.js - يجب ألا يكون "subdir" الآخر موجودًا. ولكن باستخدام المكوِّن المخصص Link ، نقوم بتعيين href على /subdir/example ، لذلك لا عجب أن يطلب Next.js حزمة من الصفحة pages/subdir/example.js .

حسنًا ، الجلب المسبق الإشكالي لا يبدو وكأنه نهاية العالم (على الرغم من أن UX قبيح جدًا) ولكن في تطبيقنا ، تزداد الأمور سوءًا لأننا نستخدم التوجيه الديناميكي لـ Next.js 9 لذلك ، نحتاج إلى تعيين as بشكل صحيح حتى يبدو تطور المكون المخصص Link كما يلي:

export default ({ children, href, as, ...rest }) => (
  <Link 
    href={`${process.env.ASSET_PREFIX}${href}`}
    as={`${process.env.ASSET_PREFIX}${as}`}
    {...rest}
  >
    {children}
  </Link>
);

الاستخدام:

<CustomLink href='/post/[id]' as='/post/1'>...</CustomLink>

الذي يتم تحويله إلى:

<Link href='/subdir/post/[id]' as='/subdir/post/1'>...</Link>

وهذا لم يكن مفيدًا بالنسبة لي عند النشر على الآن على الإطلاق - محاولة الانتقال إلى https://deployment-id.now.sh/subdir/post/1 يؤدي إلى 404. لست متأكدًا تمامًا من السبب ، ربما تكون أيضًا مشكلة في @now/next builder ( تحديث : إنه بسبب https://github.com/zeit/next.js/pull/8426#issuecomment-522801831) ولكن في النهاية ، نحن نربك جهاز توجيه Next.js عندما نطلب /subdir/post/[id] component في حالة عدم وجود مثل هذا الملف على القرص.

هناك مثال آخر في هذا الموضوع، https://github.com/zeit/next.js/issues/4998#issuecomment -521189412، أن البادئات كما فقط، وليس أ href، مثل هذا (المبسطة):

export default ({ children, href, as, ...rest }) => (
  <Link href={href} as={`${process.env.ASSET_PREFIX}${as}`} {...rest}>
    {children}
  </Link>
);

لكن هذا سيؤدي إلى ظهور هذا الخطأ في المتصفح:

قيمة <Link> as غير متوافقة مع قيمة href . هذا غير صالح.

إنها مشكلة تم الإبلاغ عنها في https://github.com/zeit/next.js/issues/7488.

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

borekb أنا أيضًا على استعداد للمساعدة كما ذكرت مرتين من قبل. جميع الحلول التي رأيتها حتى الآن لا تحل سوى جزء من المشكلة. في الوقت الحالي ، نستخدم تفرع next.js في الإنتاج والذي ينفذ basePath.

سنقوم بتقديم واجهة برمجة تطبيقات جديدة قريبًا والتي ستجعل هذا الاقتراح قديمًا.

tim هل ما زالت الحالة كذلك أم أن الاقتراح الجديد لـ API مغلق؟ https://github.com/zeit/next.js/issues/7329

بالمناسبة. غدا سيكون بالضبط سنة واحدة فتحت هذا العدد

تتمثل إحدى الأفكار الجامحة نسبيًا في جعل الصفحات بشيء مثل src/pages ثم ربطها بالموقع الصحيح. فمثلا:

  • للنشر إلى myapp.example.com ، سأقوم بربط src/pages بـ pages
  • للنشر إلى example.com/myapp ، سأربط رمز src/pages بـ pages/myapp

بالاقتران مع مكون <Link> المخصص و assetPrefix ، يمكن أن يعمل لكنني لست شجاعًا بما يكفي لتجربته 😄.

أي تحديث مع ذلك؟

أي تقدم في دعم basePath ؟ :)

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

الآن في كل نقرة على الرابط أو حدث دفع للموجه ، تعيد الصفحة تحميل frowning_face

واجهت هذه المشكلة ولكن تم إصلاحها باستخدام المعلمة "as" على الرابط ، لذا يشير الرابط إلى الملف الداخلي ، لكن "as" متعلق بالمسار
على سبيل المثال:
<Link href={"/${item.link}"} as={"./${item.link}"}>

لقد أنقذت يومي! :)))

أفعل الشيء نفسه مع Router.push(`/route`, `${process.env.BASE_PATH}route`);

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

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

واجهت هذه المشكلة ولكن تم إصلاحها باستخدام المعلمة "as" على الرابط ، لذا يشير الرابط إلى الملف الداخلي ، لكن "as" متعلق بالمسار
على سبيل المثال:
<Link href={"/${item.link}"} as={"./${item.link}"}>

لا يعمل هذا الحل مع التوجيه المستند إلى الملفات التسعة التالية. /route/[id] ، ${process.env.BASE_PATH}/route${id} يظهر هذا الخطأ

يشرح هذا التعليق المشكلة جيدًا.

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

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

يؤدي هذا بشكل أساسي إلى كسر ذاكرة التخزين المؤقت لـ Apollo Client الخاصة بنا ، حيث يتم إعادة إنشائها في كل مسار.

أعتقد أن التطبيق يقارن الصفحة الأساسية href بدون الأصول ، بالمسارات التالية href (التي تتضمن أصل بريفكس) - مما يؤدي إلى مسار عميق.

على سبيل المثال ، إذا كنت على href /prefix/page (الصفحة الأساسية هي /page ) ومسارك href هو /prefix/page/[id] (لأنه بدون البادئة سيكون 404) هذا طريق مختلف تمامًا والطريق الضحل غير ممكن.

النظر في الحلول البديلة في الدقيقة باستخدام الطرق السريعة

عند الاستخدام المكون الذي يحتوي على خاصيات href وهو basePath ، فإن الجلب المسبق لا يعمل.
PLZ support basePath والإحضار المسبق ، سيكون رائعًا

أنا حقا يمكن استخدام هذا. أنا أقوم بتشغيل تطبيقات متعددة من مصدر خادم واحد وتم فصل كل منها إلى web/appX/{next project files} . سيكون من الرائع أن يكون لديك المزيد من التحكم في basePath. لقد توصلت إلى حل بديل في الوقت الحالي ، لكنه ليس جميلًا جدًا.

يحتاج التصدير الثابت أيضًا إلى basePath 😊

يبدو نجاح العمل 👏

{
  experimental:{
    basePath: '/some/dir',
  }
}

هذا قيد سيء جدًا بالنسبة لنا للأسف :(

لدينا جميع التطبيقات خلف وكيل عكسي ، لذا يجب أن تكون المسارات مسبوقة (في المثال أدناه ، هذه بادئة من /auction-results )

نحن نستخدم البادئة assetPrefix بالفعل - وهذا يسمح للتطبيقات بالعمل بشكل جيد للطلبات من جانب الخادم.
على سبيل المثال: mydomain.com/auction-results/ يعمل بشكل جيد باستخدام بعض التوجيه السريع مثل:

router.get(`/${appPrefix}/`, (req, res) => {
  nextApp.render(req, res, '/national', req.params);
});

ولكن عندما نحاول ونقوم بالتنقل من جانب العميل عبر next/link ، على سبيل المثال:

حيث /auction-results هي بادئة التطبيق و /national هي الصفحة الموجودة في ~pages/national

<Link href="/national" as="/auction-results/">
  <a>Goto National Page</a>
</Link>

هذا لا يفعل شيئا (شبح النقر)

وجود روابط تحديث الصفحة كاملة أقل من مثالي.

إذا كان هناك أي طريقة يمكنني المساعدة في ذلك ، فأنا أحب ذلك

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

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

لست متأكدًا مما تتوقعه من خلال نشر هذا.

يتم العمل على Next.js بدوام كامل بواسطة فريقي (5 أشخاص) ، ونحن نعمل على العديد من الميزات في نفس الوقت. في العام الماضي ، عملنا على هذه:

جعل تطبيقات Next.js (الجديدة والحالية) بشكل فعال أصغر حجمًا وأسرع وأكثر قابلية للتوسع.

إذا كنت ترغب في التعبير عن "التصويت الإيجابي" لميزة ما ، يمكنك ذلك. استخدم ميزة 👍 في الخيط الأولي.

أوافق بالتأكيد على أن يكون basePath ميزة مضمنة. إنه موجود بالفعل على خريطة الطريق وقد قمت بكتابة إعلان عام أولي ، والذي كان من الممكن أن تراه من خلال إعادة قراءة الموضوع.

هنا العلاقات العامة: https://github.com/zeit/next.js/pull/9872

لا تتردد في التواصل مع [email protected] إذا كنت تريد المساهمة مالياً في تحقيق هذه الميزة.

ما هي الحالة على هذا؟ نحن نعتمد حقًا على هذا: /

دعم Sletheren basePath تجريبي الآن ، استخدمه على مسؤوليتك.

راجع https://github.com/zeit/next.js/pull/9872

دعم Sletheren basePath تجريبي الآن ، استخدمه على مسؤوليتك الخاصة.

راجع # 9872

@ مارتبي رأيته بالفعل ، ولكن ل. إن حالتي basePath ليست واحدة فقط ، بل يمكن أن تكون متعددة المسار ، نظرًا لأننا نقدم تطبيقنا من خلال "عناوين URL" مختلفة وإعداد basePath خلال وقت الإنشاء ليس خيارًا (على الرغم من أنه لدعم مجموعة من المسارات بدلاً من سلسلة واحدة)

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

  1. هل سيكون هذا مخصصًا للمؤسسة فقط (تسببت الإشارة إلى الاتصال بمبيعات الشركات في بعض الانزعاج)؟

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

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

شكرا لتفهمك والبحث عن ملاحظاتك.

FWIW ، لقد نجحت الآن في العمل وللآخرين بقيادة:

ضع هذا في next.config.js :

module.exports = {
  experimental: {
    basePath: '/custom',
  },
}

بعد ذلك ، كنت بحاجة إلى إعادة تشغيل الخادم وإعداد البرامج الوسيطة لخادم الويب بشكل صحيح:

تلقيت جميع الطلبات عبر مسار مخصص ، على سبيل المثال. app.use('/custom', (req, res...) => { ... وبعد ذلك (وهو أمر مهم) ، أحتاج إلى الوكيل لعنوان URL للنظام حيث يتم تشغيل Next (لذا العنوان الداخلي لتزامن الحاوية ومرة أخرى مع المسار المعني إذا كنت تستخدم http-proxy => على سبيل المثال ، ... target: 'http://next:3000/custom ) ، لذلك ليس المضيف فقط بدون المسار المخصص. إذا كنت تستخدم http-proxy-middleware فأنت لست بحاجة إلى هذا.

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

تحرير: جربت هذا أيضًا في وضع الإنتاج في Next ويبدو أنه يعمل أيضًا.

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

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

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

شكرا لتفهمك والبحث عن ملاحظاتك.

@ pe-s أعتقد أنك تسيء فهم رسالتي.

لا يوجد "إصدار Enterprise Next.js" حتى الآن. كنت أشير إلى المناسبات العديدة التي تواصلت فيها الشركات الخارجية للدفع مقابل الاستشارات لإنشاء ميزات مثل هذه في فترة زمنية أقصر. تم إنشاء دعم المناطق على سبيل المثال بالتعاون مع Trulia.

لا يزال يتم العمل على هذه الميزة وهي موجودة على خريطة الطريق. جميع الميزات التي يتم العمل عليها مفتوحة المصدر ، كما قلت لا توجد نسخة مؤسسية من Next.js. لدينا أولويات متعددة للعمل عالي التأثير على خريطة الطريق ، ولهذا السبب أشرت إلى الاتصال بـ [email protected] إذا كنت بحاجة إلى هذه الميزة في أقرب وقت ممكن / لمناقشة دعم المؤسسة لـ Next.js.

timneutkens tx لاستجابة سريعة
استمروا في العمل العظيم!

يتوفر دعم Basepath على next@canary الآن ، ولم يعد تجريبيًا. سيكون على القناة الثابتة قريبا.

لقد تأخرت كثيرًا في هذا ولكن هل فكرت في استخدام HTML <base> الفعلي بدلاً من التعامل مع هذا يدويًا؟

يتوفر دعم Basepath على next@canary الآن ، ولم يعد تجريبيًا. سيكون على القناة الثابتة قريبا.

timneutkens ، شكرا لك على هذه الإضافة. هل تعرف متى سيتم إطلاق دعم basePath غير التجريبي رسميًا؟

أيضًا ، عندما أقوم بتعيين المسار الأساسي ، يتم تقديم الأصول (الموجودة في المجلد العام) إلى عنوان url المناسب كما هو متوقع. ولكن ، عندما أشير إليها في الكود الخاص بي ، يتعين علي إضافة المسار الأساسي إلى src يدويًا ، وإلا فسيتم الرجوع إليها من المسار العادي. هل هذا هو الاستخدام المتوقع لـ basePath؟ لقد حاولت أيضًا استخدام originPrefix ، لكن لم يكن لها أي تأثير على الكود الخاص بي الذي يمكنني تحديده.

مثال :

  1. باستخدام next v9.4.5-canary.24
  2. basePath على /alerts في next.config.js:
const basePath = '/alerts';
module.exports = {
  basePath: basePath,
  env: {
    BASE_PATH: basePath,
  },
};
  1. الأصل الموجود في public/images/example.png
  2. مثال على استخدام الأصل في مكون التفاعل:
const ExampleImage = () => (
  <img src={`${process.env.BASE_PATH}/images/example.png`} />
);

في اختباراتي ، لا يتم تحديث عناوين url الخاصة بالأصول.

لقد قمت بتثبيت أحدث إصدار من الكناري:
npm install [email protected]

next.config.js

const isProd = process.env.NODE_ENV === 'production';

module.exports = {
  basePath: isProd ? '/example' : ''
}

يتم تحميل جميع الصفحات والروابط بشكل صحيح:
http: // localhost : 3000 / example / posts / pre-rendering
http: // localhost : 3000 / example / posts / ssg-ssr
http: // localhost : 3000 / example / posts / pre-rendering

لكن الصور والأشكال المفضلة وما إلى ذلك لم يتم تعيينها على الخريطة:
http: // localhost : 3000 / favicon.ico 404
http: // localhost : 3000 / images / profile.jpg 404

هل اختبر أحد هذا؟ حاولت أيضًا استخدام الأصول ، لكن ذلك لم ينجح أيضًا.

بالإضافة إلى ذلك ، أنا في حيرة من أمري ، لماذا لا تستخدم وظيفة المتصفح المضمنة لهذا الغرض؟
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base

شكرًا لك على النظر في هذا الأمر من جانبك أيضًا
timneutkens ، هل يجب علينا إعادة فتح هذه المشكلة / إنشاء مشكلة جديدة لهذا الخطأ؟

عليك أن تسبق الصور يدويا. يمكنك الحصول على basePath باستخدام

const {basePath} = useRouter()

https://nextjs.org/docs/api-reference/next.config.js/cdn-support-with-asset-prefix

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

الآن ، أدركت أن هناك طرقًا متعددة لربط الملفات في / عامة. على سبيل المثال ، <img/> <link/> ...
هل لهذا السبب يتعين علينا تحديد basePath يدويًا لكل منها؟

إذا كان هناك مكون مثل أدناه متاح ، أعتقد أنه سيوفر الوقت ويقلل من الارتباك لكثير من الناس؟

<WithinBasePath>
  {/* automatically fixes the path with basePath */}
  <img src="/logo.png" />
</WithinBasePath>

لا أعتقد حقًا أن هذا مناسب ، لكن هذا ما قصدته.

// src/components/WithinBasePath/index.tsx

import React from "react"
import path from "path"
import { useRouter } from "next/router"
interface Props {}

const WithinBasePath: React.FC<Props> = (props) => {
  const { basePath } = useRouter()
  const children = [props.children].flatMap((c) => c) as React.ReactElement[]
  return (
    <>
      {children.map((child, key) => {
        let newChild = null

        switch (child.type) {
          case "img":
            newChild = React.createElement(child.type, {
              ...child.props,
              src: path.join(basePath, child.props.src),
              key,
            })
            break
          case "link":
            newChild = React.createElement(child.type, {
              ...child.props,
              href: path.join(basePath, child.props.href),
              key,
            })
            break
          default:
            newChild = React.createElement(child.type, {
              ...child.props,
              key,
            })
        }
        return newChild
      })}
    </>
  )
}
export default WithinBasePath

// pages/test.tsx

import React from "react"
import WithinBasePath from "@src/components/WithinBasePath"
interface Props {}

const test: React.FC<Props> = (props) => {
  return (
    <WithinBasePath>
      <img src="/123.jpg" />
      <link href="/abc.jpg" />
      <div>other element</div>
    </WithinBasePath>
  )
}
export default test

لأولئك الذين يحاولون استخدام const {basePath} = useRouter() وهو خطاف ، للعمل مع الفئات والمكونات والحصول على هذا الخطأ:

تحذير غير صالح من استدعاء الخطاف

https://reactjs.org/warnings/invalid-hook-call-warning.html

يمكنك تشغيله باستخدام:

import { withRouter, Router } from 'next/router'

class Example extends Component<{router: Router}, {router: Router}> {
  constructor(props) {
    super(props)
    this.state = {
      router: props.router
    }
  }
  render() {
    return (
      <Layout home>
        <Head><title>Example title</title></Head>
        <img src={`${this.state.router.basePath}/images/creators.jpg`} />
      </Layout>
    )
  }
}
export default withRouter(Example)

إذا كنت تريد استخدام basePath مع تخفيض السعر ، فيبدو أنك بحاجة إلى البحث والاستبدال في السلسلة:

const content = this.state.doc.content.replace('/docs', `${this.state.router.basePath}/docs`);
return (
<Layout>
  <Container docs={this.state.allDocs}>
    <h1>{this.state.doc.title}</h1>
    <div
      className={markdownStyles['markdown']}
      dangerouslySetInnerHTML={{ __html: content }}
    />
  </Container>
</Layout>
)

عليك أن تسبق الصور يدويا. يمكنك الحصول على basePath باستخدام

const {basePath} = useRouter()

هذا الحل لا يأخذ في الاعتبار الصور المستوردة في ملف css أو scss. هل لديك حل لكيفية تعيين المسار الأساسي عند استيراد أصل من داخل ملف css أو scss؟
باستخدام هذا الحل ، سيتعين علينا التأكد من استيراد جميع الصور إما من خلال علامة img أو التصميم المضمّن أو علامة النمط. إنه ليس مثاليًا ، لأنه سيقسم أنماطك ليتم تنفيذها في أماكن متعددة.

peetjvv إليك حل دون المستوى الأمثل لاستخدام الأصول ذات basePaths مسبوقة في CSS. قم بإنشاء واستيراد وإضافة مكون <CSSVariables> في _app.tsx ، والذي يقوم بحقن عنصر <style> مضمن عالميًا يحتوي على متغيرات CSS ، والتي يمكنك استخدامها بعد ذلك في جميع أنحاء أوراق الأنماط الخاصة بك.

على سبيل المثال عند افتتاح متغيرات الإنشاء والحقن <body> :

<style>
:root {
      --asset-url: url("${basePath}/img/asset.png");
}
</style>

للحصول على هذا المسار الأساسي ، kmturley باستخدام withRouter .
إليك كيف يمكن أن يبدو هذا المكون:

import { withRouter, Router } from "next/router";
import { Component } from "react";

export interface IProps {
  router: Router;
}

class CSSVariables extends Component<IProps> {
  render() {
    const basePath = this.props.router.basePath;
    const prefixedPath = (path) => `${basePath}${path}`;
    const cssString = (value) => `\"${value}\"`;
    const cssURL = (value) => `url(${value})`;
    const cssVariable = (key, value) => `--${key}: ${value};`;
    const cssVariables = (variables) => Object.entries(variables)
      .map((entry) => cssVariable(entry[0], entry[1]))
      .join("\n");
    const cssRootVariables = (variables) => `:root {
      ${cssVariables(variables)}
    }`;

    const variables = {
      "asset-url": cssURL(
        cssString(prefixedPath("/img/asset.png"))
      ),
    };

    return (
      <style
        dangerouslySetInnerHTML={{
          __html: cssRootVariables(variables),
        }}
      />
    );
  }
}

export default withRouter(CSSVariables);
هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات