كيفية استضافة تطبيق Next.js الخاص بك بنفسك
عند نشر تطبيق Next.js الخاص بك، قد ترغب في تكيف كيفية معالجة الميزات المختلفة بناءً على بنيتك التحتية.
🎥 شاهد: تعرف على المزيد حول استضافة Next.js بنفسك → YouTube (45 دقيقة).
تحسين الصور
تحسين الصور عبر next/image
يعمل مع الاستضافة الذاتية بدون أي تكوين عند النشر باستخدام next start
. إذا كنت تفضل وجود خدمة منفصلة لتحسين الصور، يمكنك تكوين محمل صور.
يمكن استخدام تحسين الصور مع التصدير الثابت عن طريق تعريف محمل صور مخصص في next.config.js
. لاحظ أن الصور يتم تحسينها أثناء التشغيل، وليس أثناء البناء.
معلومة مفيدة:
- في أنظمة لينكس القائمة على glibc، قد يتطلب تحسين الصور تكوينًا إضافيًا لمنع استخدام الذاكرة المفرط.
- تعرف على المزيد حول سلوك التخزين المؤقت للصور المحسنة وكيفية تكوين TTL.
- يمكنك أيضًا تعطيل تحسين الصور والاحتفاظ بفوائد أخرى لاستخدام
next/image
إذا كنت تفضل ذلك. على سبيل المثال، إذا كنت تقوم بتحسين الصور بنفسك بشكل منفصل.
Middleware
Middleware يعمل مع الاستضافة الذاتية بدون أي تكوين عند النشر باستخدام next start
. نظرًا لأنه يتطلب الوصول إلى الطلب الوارد، فهو غير مدعوم عند استخدام التصدير الثابت.
يستخدم Middleware وقت تشغيل Edge، وهو مجموعة فرعية من جميع واجهات برمجة تطبيقات Node.js المتاحة للمساعدة في ضمان زمن انتقال منخفض، حيث قد يعمل أمام كل مسار أو أصل في تطبيقك. إذا كنت لا تريد ذلك، يمكنك استخدام وقت تشغيل Node.js الكامل لتشغيل Middleware.
إذا كنت تريد إضافة منطق (أو استخدام حزمة خارجية) تتطلب جميع واجهات برمجة تطبيقات Node.js، فقد تتمكن من نقل هذا المنطق إلى تخطيط كمكون Server Component. على سبيل المثال، التحقق من الرؤوس و إعادة التوجيه. يمكنك أيضًا استخدام الرؤوس، ملفات تعريف الارتباط، أو معلمات الاستعلام لإعادة التوجيه أو إعادة الكتابة عبر next.config.js
. إذا لم ينجح ذلك، يمكنك أيضًا استخدام خادم مخصص.
متغيرات البيئة
يدعم Next.js متغيرات البيئة في وقت البناء ووقت التشغيل.
بشكل افتراضي، متغيرات البيئة متاحة فقط على الخادم. لكشف متغير بيئة للمتصفح، يجب أن يبدأ بـ NEXT_PUBLIC_
. ومع ذلك، سيتم تضمين متغيرات البيئة العامة هذه في حزمة JavaScript أثناء next build
.
لقراءة متغيرات البيئة في وقت التشغيل، نوصي باستخدام getServerSideProps
أو تبني موجه التطبيق تدريجيًا.
هذا يسمح لك باستخدام صورة Docker واحدة يمكن ترقيتها عبر بيئات متعددة بقيم مختلفة.
معلومة مفيدة:
- يمكنك تشغيل التعليمات البرمجية عند بدء تشغيل الخادم باستخدام وظيفة
register
.- لا نوصي باستخدام خيار runtimeConfig، لأنه لا يعمل مع وضع الإخراج المستقل. بدلاً من ذلك، نوصي بتبني موجه التطبيق تدريجيًا.
التخزين المؤقت و ISR
يمكن لـ Next.js تخزين الردود، الصفحات الثابتة المولدة، مخرجات البناء، والأصول الثابتة الأخرى مثل الصور، الخطوط، والنصوص البرمجية.
يستخدم التخزين المؤقت وإعادة التحقق من الصفحات (مع التجديد الثابت التدريجي) نفس التخزين المؤقت المشترك. بشكل افتراضي، يتم تخزين هذا التخزين المؤقت في نظام الملفات (على القرص) على خادم Next.js الخاص بك. هذا يعمل تلقائيًا مع الاستضافة الذاتية باستخدام كل من موجه الصفحات وموجه التطبيق.
يمكنك تكوين موقع تخزين Next.js المؤقت إذا كنت تريد استمرار الصفحات والبيانات المخزنة مؤقتًا في تخزين دائم، أو مشاركة التخزين المؤقت عبر حاويات أو نسخ متعددة من تطبيق Next.js الخاص بك.
التخزين المؤقت التلقائي
- يضبط Next.js رأس
Cache-Control
لـpublic, max-age=31536000, immutable
للأصول الثابتة حقًا. لا يمكن تجاوزه. تحتوي هذه الملفات الثابتة على تجزئة SHA في اسم الملف، لذا يمكن تخزينها مؤقتًا إلى أجل غير مسمى بأمان. على سبيل المثال، استيراد الصور الثابتة. يمكنك تكوين TTL للصور. - يضبط التجديد الثابت التدريجي (ISR) رأس
Cache-Control
لـs-maxage: <revalidate in getStaticProps>, stale-while-revalidate
. يتم تعريف وقت إعادة التحقق هذا في وظيفةgetStaticProps
بالثواني. إذا قمت بتعيينrevalidate: false
، فسيتم تعيين مدة التخزين المؤقت الافتراضية إلى سنة واحدة. - تقوم الصفحات الممثلة ديناميكيًا بتعيين رأس
Cache-Control
لـprivate, no-cache, no-store, max-age=0, must-revalidate
لمنع تخزين البيانات الخاصة بالمستخدم مؤقتًا. ينطبق هذا على كل من موجه التطبيق وموجه الصفحات. يشمل ذلك أيضًا وضع المسودة.
الأصول الثابتة
إذا كنت تريد استضافة أصول ثابتة على نطاق أو CDN مختلف، يمكنك استخدام تكوين assetPrefix
في next.config.js
. سيستخدم Next.js بادئة الأصل هذه عند استرداد ملفات JavaScript أو CSS. فصل أصولك إلى نطاق مختلف يأتي مع عيب الوقت الإضافي الذي يقضيه في تحليل DNS و TLS.
تعرف على المزيد حول assetPrefix
.
تكوين التخزين المؤقت
بشكل افتراضي، سيتم تخزين أصول التخزين المؤقت المولدة في الذاكرة (الافتراضي 50 ميجابايت) وعلى القرص. إذا كنت تستضيف Next.js باستخدام منصة تنسيق الحاويات مثل Kubernetes، سيكون لكل نسخة نسخة من التخزين المؤقت. لمنع عرض بيانات قديمة نظرًا لأن التخزين المؤقت غير مشترك بين النسخ افتراضيًا، يمكنك تكوين تخزين Next.js المؤقت لتوفير معالج تخزين مؤقت وتعطيل التخزين المؤقت في الذاكرة.
لتكوين موقع تخزين ISR/البيانات المؤقت عند الاستضافة الذاتية، يمكنك تكوين معالج مخصص في ملف next.config.js
الخاص بك:
module.exports = {
cacheHandler: require.resolve('./cache-handler.js'),
cacheMaxMemorySize: 0, // تعطيل التخزين المؤقت في الذاكرة الافتراضي
}
ثم، أنشئ cache-handler.js
في جذر مشروعك، على سبيل المثال:
const cache = new Map()
module.exports = class CacheHandler {
constructor(options) {
this.options = options
}
async get(key) {
// يمكن تخزين هذا في أي مكان، مثل التخزين الدائم
return cache.get(key)
}
async set(key, data, ctx) {
// يمكن تخزين هذا في أي مكان، مثل التخزين الدائم
cache.set(key, {
value: data,
lastModified: Date.now(),
tags: ctx.tags,
})
}
async revalidateTag(tags) {
// tags إما سلسلة أو مصفوفة من السلاسل
tags = [tags].flat()
// التكرار عبر جميع الإدخالات في التخزين المؤقت
for (let [key, value] of cache) {
// إذا كانت علامات القيمة تتضمن العلامة المحددة، احذف هذا الإدخال
if (value.tags.some((tag) => tags.includes(tag))) {
cache.delete(key)
}
}
}
// إذا كنت تريد أن يكون لديك تخزين مؤقت مؤقت في الذاكرة لطلب واحد يتم إعادة تعيينه
// قبل الطلب التالي، يمكنك الاستفادة من هذه الطريقة
resetRequestCache() {}
}
سيسمح لك استخدام معالج تخزين مؤقت مخصص بضمان الاتساق عبر جميع النسخ التي تستضيف تطبيق Next.js الخاص بك. على سبيل المثال، يمكنك حفظ القيم المخزنة مؤقتًا في أي مكان، مثل Redis أو AWS S3.
معلومة مفيدة:
revalidatePath
هي طبقة راحة فوق علامات التخزين المؤقت. استدعاءrevalidatePath
سيتصل بوظيفةrevalidateTag
مع علامة افتراضية خاصة للصفحة المقدمة.
تخزين البناء المؤقت
يولد Next.js معرفًا أثناء next build
لتحديد إصدار التطبيق الذي يتم تقديمه. يجب استخدام نفس البناء وتشغيله عبر حاويات متعددة.
إذا كنت تقوم بإعادة البناء لكل مرحلة من مراحل بيئتك، فستحتاج إلى إنشاء معرف بناء متسق للاستخدام بين الحاويات. استخدم أمر generateBuildId
في next.config.js
:
module.exports = {
generateBuildId: async () => {
// يمكن أن يكون هذا أي شيء، باستخدام أحدث تجزئة git
return process.env.GIT_HASH
},
}
انحراف الإصدار
سيقوم Next.js بالتخفيف التلقائي لمعظم حالات انحراف الإصدار وإعادة تحميل التطبيق تلقائيًا لاسترداد الأصول الجديدة عند الكشف عنها. على سبيل المثال، إذا كان هناك عدم تطابق في deploymentId
، فإن الانتقالات بين الصفحات ستؤدي إلى تنقل صعب مقابل استخدام قيمة مسبقة الجلب.
عند إعادة تحميل التطبيق، قد يكون هناك فقدان لحالة التطبيق إذا لم يتم تصميمه للاستمرار بين تنقلات الصفحات. على سبيل المثال، استخدام حالة URL أو التخزين المحلي سيحافظ على الحالة بعد تحديث الصفحة. ومع ذلك، ستضيع حالة المكون مثل useState
في مثل هذه التنقلات.
عمليات إيقاف التشغيل اليدوية السلسة
عند الاستضافة الذاتية، قد ترغب في تشغيل التعليمات البرمجية عند إيقاف الخادم على إشارات SIGTERM
أو SIGINT
.
يمكنك تعيين متغير البيئة NEXT_MANUAL_SIG_HANDLE
إلى true
ثم تسجيل معالج لتلك الإشارة داخل ملف _document.js
الخاص بك. ستحتاج إلى تسجيل متغير البيئة مباشرة في سكريبت package.json
، وليس في ملف .env
.
معلومة مفيدة: معالجة الإشارة اليدوية غير متاحة في
next dev
.
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "NEXT_MANUAL_SIG_HANDLE=true next start"
}
}
if (process.env.NEXT_MANUAL_SIG_HANDLE) {
process.on('SIGTERM', () => {
console.log('تم استلام SIGTERM: التنظيف')
process.exit(0)
})
process.on('SIGINT', () => {
console.log('تم استلام SIGINT: التنظيف')
process.exit(0)
})
}