الترقية إلى Next.js 16: ملاحظات ميدانية من تطبيقين إنتاجيين
جدول المحتويات
عن الكاتب

Ahmed Mahmoud
كاتب ومطوّر
مهندس برمجيات شغوف بتطوير الويب وتصميم تجربة المستخدم.
مؤسّس ديفيا · eng-ahmed.com ↗في Devya Solutions قمنا مؤخرًا بترقية تطبيقين إنتاجيين — منصة ويب موجهة للعملاء ولوحة تحكم داخلية للعمليات — من Next.js 15 إلى 16. الوقت الإجمالي: نحو نصف يوم لكل تطبيق. ولم يذهب هذا الوقت تقريبًا إلى حيث توقعنا؛ فأداة codemod الرسمية تتكفل بالأجزاء المملة، بينما تكمن المفاجآت في ملفات الإعداد وسكربتات CI.
الإصدار 16 من Next.js هو الإصدار الذي يتخلص فيه إطار العمل أخيرًا من إرث حقبة webpack. أصبح Turbopack هو المجمّع الافتراضي لكل من التطوير والبناء، وأُزيلت المخارج القديمة (الوصول المتزامن إلى params وأمر next lint وruntime config) بدلًا من مجرد إهمالها، وحصل ملف middleware.ts على اسم جديد يعبّر أخيرًا عن وظيفته. هذه ليست إعادة سرد لسجل التغييرات — بل قائمة مرتبة بما تعطّل فعلًا لدينا، مع الإصلاح والوقت الذي كلّفه كل بند.
مسار الترقية في 30 ثانية
تبدأ الترقية بأمر واحد: npx @next/codemod@canary upgrade latest. تقوم الأداة بتحديث next وreact وreact-dom، وتعيد كتابة الأجزاء الميكانيكية — وأبرزها واجهات الطلب غير المتزامنة. نصيحتنا: شغّلها على فرع نظيف ثم اقرأ مخرجات البناء بعناية شديدة. كل ما يلي هو ما لم تلتقطه الأداة لدينا.
أصبح Turbopack هو الافتراضي
أكبر تغيير سلوكي: يعمل كل من next dev وnext build عبر Turbopack ما لم تختر غير ذلك. في لوحة التحكم لدينا، تسببت كتلة webpack() متبقية في next.config.ts بتحذير صريح بأن الإعداد سيتم تجاهله. هناك ثلاث حالات ممكنة لأي مشروع: إن لم يكن لديك إعداد webpack مخصص فقد انتهيت — وستحصل على بناء أسرع بشكل كبير: انخفض أحد إصداراتنا الإنتاجية من 41 ثانية إلى 19. وإن كان لديك إعداد يمكن استبداله، فمعظم اللودرز لها مكافئ تحت turbopack.rules — استغرق نقل SVG كمكوّن خمس دقائق لدينا. أما إن وُجد شيء لا مسار له في Turbopack بعد، فيمكنك الاستثناء لكل أمر عبر next build --webpack وجدولة الترحيل لاحقًا. نحن لا نسمح للودر واحد بتعطيل ترقية كاملة.
أصبح middleware.ts هو proxy.ts
إعادة التسمية شكلية؛ لكن تحول النموذج الذهني ليس كذلك. كان الملف يعمل دائمًا كاعتراض عند حدود الشبكة، والاسم الجديد يمنع الفرق من التعامل معه كخطاف في طبقة التطبيق. أعد تسمية الملف، وأعد تسمية الدالة المصدَّرة إلى proxy، وانتهى الأمر — انتقل منطق بوابة المصادقة لدينا دون أي تغيير سلوكي، في نحو عشر دقائق شاملة استيرادات الاختبارات.
اختفى next lint — وستلاحظ CI ذلك أولًا
هذا البند أصابنا في CI وليس محليًا. كان سكربت lint في كلا المستودعين يستدعي next lint، الذي لم يعد موجودًا في 16. الحل هو تشغيل ESLint مباشرة في سكربتات الحزمة. وبينما أنت هناك، لاحظ أن Next 16 يتماشى مع عالم إعدادات ESLint المسطّحة — إن كان مشروعك لا يزال على .eslintrc فخصص عشرين دقيقة للانتقال إلى eslint.config.js.
params غير المتزامنة: انتهت فترة السماح
سمح Next 15 بالوصول المتزامن إلى params مع تحذير إهمال. أما Next 16 فيزيل المسار المتزامن كليًا — كل واجهة ديناميكية أصبحت Promise. حوّلت الأداة جميع ملفات المسارات لدينا بشكل صحيح. ما فاتها: دالة مساعدة كانت تستقبل params كوسيط وتفككها بشكل متزامن على عمق مستويين. التقطها TypeScript قبل وقت التشغيل. درسنا: بعد تشغيل الأداة، ابحث في الشيفرة عن استخدامات params وراجع كل ما لم يُنتظر بـ await.
تشديد افتراضيات الصور
تغييران في next/image يظهران كتراجعات خفية لا كأخطاء. قيم الجودة أصبحت من قائمة مسموح بها (images.qualities والافتراضي [75]) — أي مكوّن يطلب quality={90} سيقدّم 75 بصمت حتى تُضاف 90 إلى الإعداد. كما توقفت الصور المحلية ذات سلاسل الاستعلام عن العمل في إحدى الصفحات حتى سجّلنا النمط تحت images.localPatterns.
ارتفع الحد الأدنى: Node 20.9+ وReact 19.2
يتطلب Next 16 إصدار Node.js 20.9 أو أحدث ويعمل مع React 19.2. ترقية Node هي ما يجب فحصه في صور CI وبيئات التشغيل المستضافة ذاتيًا — كان أحد سكربتات النشر لدينا لا يزال يجهّز Node 18 وفشل في فحص engines فورًا. أما React 19.2 نفسه فلم يكن حدثًا يُذكر لشيفرة التطبيق.
ماذا تكسب مقابل هذا العناء
سرعة البناء أولًا: من 41 ثانية إلى 19 في تطبيق، ومن 68 إلى 24 في الآخر، بناء بارد دون كاش. ومكوّنات الكاش تواصل النضوج — تخزين مؤقت صريح وقابل للتركيب بدلًا من لعبة التخمين الضمنية. وسطح إطار أصغر: دعم AMP وruntime config وغلاف lint القديم كلها اختفت. سحر أقل، وصفحات توثيق أقل قدرة على تضليلك.
قائمتنا للترقية
شغّل codemod على فرع نظيف وارفع ذلك الفارق في commit منفصل عن إصلاحاتك اليدوية. احذف كتلة webpack() أو انقلها. أعد تسمية middleware.ts إلى proxy.ts. استبدل next lint في كل سكربت ومهمة CI. ابحث عن params غير المنتظرة في الدوال المساعدة لا الصفحات فقط. راجع next/image بحثًا عن قيم جودة غير افتراضية. ارفع Node إلى 20.9+ في كل مكان يعمل فيه التطبيق. نصف يوم لكل تطبيق — ومكسب سرعة البناء وحده استعاد التكلفة خلال الأسبوع الأول من التطوير.
إذا كان فريقك يخطط لترقية Next.js — أو عالقًا على إصدار قديم ويريد إنجاز الترحيل بأمان — فهذا بالضبط نوع العمل الذي نقوم به في Devya Solutions. تواصلوا معنا وسنحدد نطاق العمل معكم.
قراءات إضافية
هندسة الواجهات
الوضع الداكن دون وميض في Next.js 16: كيف نستخدم سكربت سمة حاجبًا وcolor-scheme وزر تبديل آمنًا مع الـ Hydration
وميض الوضع الداكن عند إعادة تحميل الصفحة مشكلة توقيت: الخادم لا يستطيع قراءة localStorage. نشرح سكربت السمة الحاجب الذي نستخدمه في Next.js 16، ولماذا لا نضع السمة في cookie حفاظًا على الرسم الثابت، وكيف نبني زر تبديل يمر بالـ hydration دون أي عدم تطابق.
هندسة الواجهات
صور Open Graph الديناميكية في Next.js 16: كيف نبني opengraph-image.tsx ونتحقق من إصدار Satori الذي تضمّنه next/og ونحافظ على صحة معاينات الروابط
واجهت بطاقات المشاركة المولّدة لدينا ثلاث مفاجآت: خط WOFF2 لم يستطع المحرّك قراءته، وملف README لـ Satori يصف محرّكًا أحدث من المضمّن في Next.js، وصفحة ظلّت تعرض صورة الـ layout. هذه ملاحظاتنا الميدانية حول opengraph-image.tsx في Next.js 16 وأولوية البيانات الوصفية وفحص og:image قبل مشاركة أي رابط.