تخطَّ إلى المحتوى

‏Next.js مقابل Express: واحدٌ منهما فقط يعرض

‏Express خادم تبنون عليه، و Next.js إطار عرضٍ معه خادم. والاختيار بينهما في حقيقته اختيارٌ لمقدار ما تريدون كتابته بأنفسكم.

4 دقيقة قراءة

يُقارَن هذان لأن كليهما Node وكليهما يخدم HTTP، وعند هذا الحدّ ينتهي التشابه تقريبًا. Express إطار HTTP بسيط تركّبونه أنتم. و Next.js إطار عرض يصادف أن فيه خادمًا.

والقرار ليس مقارنةً في حقيقته، بل سؤال عمّا تبنونه.

ExpressNext.js
ما الذي يمنحكمخطّ معالجة للطلباتمسار عرض
التوجيهما تكتبونه بأنفسكمنظام الملفات، مع تخطيطات
العرضلا شيءكل الغرض منه
تحزيم العميلليس عملهمدمج
الاتصالات طويلة العمرأصيلةمن مُربك إلى مستحيل
ما تُركّبونه بأنفسكممعظم واجهة أماميةمعظم خلفية

إن كنتم تبنون واجهة برمجية فقط

استخدموا Express أو Fastify أو Hono. معالِجات مسارات Next.js موجودة وتعمل، لكنكم ستتحمّلون إطار عرض وخطوة بناء وموجّه مبنيًّا على نظام الملفات واعتمادية على React، من أجل خدمة لا تعرض شيئًا.

وتحديدًا، يبقى Express أفضل حين تكون لواجهتكم:

  • مستهلكون خارجيون. مسارات ذات إصدارات، ومفاتيح واجهة، وعقود موثَّقة.
  • سلسلة وسطاء خاصة بها. تحديد معدّل، والتحقّق من الطلبات، ومصادقة مخصّصة، وسجلّات تخصّكم.
  • أي شيء طويل العمر. WebSockets، والأحداث المُرسَلة من الخادم، واتصالات تتجاوز عمر الطلب.
  • قيود نشر. عملية Node بسيطة أسهل تشغيلًا على بنية تحتية لها آراؤها.

ونقطة الوسيطات تستحقّ أكثر من بند في قائمة، لأنها تُكتشف متأخّرًا. تطبيق Express خطّ معالجة تُركّبونه: كل طلب يمرّ بالدوالّ التي سجّلتموها، بالترتيب الذي سجّلتموها به، ويمكن استيعاب السلسلة كلّها بقراءة ملف واحد. ولا يملك Next.js ما يكافئ ذلك على مستوى التطبيق. فـproxy.ts - العُرف الذي حلّ محلّ الوسيطات في الإصدار 16 - يعمل على مُطابِق، وعلى طلبات ربما لم تقصدوها، و ليس خطّ معالجة للطلبات. ومحاولة استعماله كذلك هي أشيع طريقة ينقل بها فريق عادةً من Express إلى قاعدة شيفرة لا تحتملها.

وإن كنتم تعرضون صفحات، فلا تبنوه بأنفسكم

الاتجاه المعاكس أقوى وأقلّ وضوحًا.

الفرق التي تبدأ بـ Express وتضيف React فوقه تنتهي إلى أن تكتب بيدها ما حسمه Next.js أصلًا: التوجيه، وتقسيم الشيفرة، وجلب البيانات على الخادم، والبثّ، وحدّ حزمة العميل، ومعالجة الصور، والتخزين المؤقّت. كل واحد منها أسبوع. ومجتمعةً هي إطار عمل، وسيكون إطارًا أسوأ، لأنه مشروع جانبي لا المنتج نفسه.

إن كان لتطبيقكم صفحات، فالحجّة لصالح Express هي الحجّة لصالح كتابة إطار عمل خاص بكم. وهذا صحيح أحيانًا، وغير صحيح غالبًا.

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

أين تكفي معالِجات المسارات فعلًا

لواجهة برمجية لا يستهلكها إلا واجهتكم الأمامية، تؤدّي معالِجات مسارات Next.js الغرض:

// app/api/products/route.ts
export async function GET(request: Request) {
  const products = await db.product.findMany();
  return Response.json(products);
}

نشرٌ واحد، وقاعدة شيفرة واحدة، وأنواع مشتركة بين الواجهة البرمجية والمكوّنات التي تستدعيها. ولمعظم تطبيقات المنتجات، هذا هو القدر الصحيح من الآلية.

ومن المفيد معرفته: بالنسبة للبيانات التي تحتاجها صفحاتكم أنتم، لا تحتاجون مسارًا في الغالب. فـ Server Component يستطيع الاستعلام مباشرةً، و Server Action يستطيع التعديل - والالتفاف عبر واجهتكم البرمجية عادةٌ موروثة من بنية معروضة على العميل.

وأين تكفّ معالِجات المسارات عن الكفاية

ثلاثة حدود، بالترتيب الذي تبلغه الفرق.

أن يبقى الاتصال مفتوحًا. معالِج المسار مبنيّ حول طلب ينتهي. أحداث الخادم المُرسَلة ممكنة عبر استجابة مبثوثة؛ أما WebSocket فلا، وعلى هدف بلا خوادم لا ينجو أيٌّ منهما من عمر الدالّة. وكل ما فيه اتصال دائم مكانه عملية تتحكّمون بها.

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

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

الترتيب الذي تنتهي إليه معظم الفرق

‏Express - أو Fastify، أو خدمة بـ Go، أو Laravel - يحمل منطق العمل والمهام. و Next.js يحمل الواجهة الأمامية. ويتحادثان عبر HTTP.

هذه هي الخلاصة نفسها التي في ‏Next.js مقابل Laravel، وللسبب نفسه: مسار العرض ومنطق العمل مشكلتان مختلفتان، وأطر العمل تجيد واحدةً منهما لكلٍّ.

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

ما ينبغي تجنّبه

خادم Express مخصّص أمام Next.js. مدعوم، ويعطّل التحسين الثابت التلقائي للمسارات التي يخدمها - أي معظم ما جئتم من أجله. إن احتجتم وكيلًا، ضعوه أمام العمليتين بدل وضعه داخل إحداهما.

نقل سلسلة وسطاء Express إلى proxy.ts. الاصطلاح الذي حلّ محلّ الـ middleware في الإصدار 16 يعمل على Node، و بيئة تشغيله غير قابلة للضبط، ويعمل على طلبات لم تقصدوها. هو لقرارات التوجيه، لا لخطّ معالجة طلبات.

أسئلة ذات صلة

وماذا عن WebSockets؟
هذا من أوضح الخطوط الفاصلة بينهما. اتصال WebSocket يعيش أطول من الطلب الذي فتحه، ومعالِجات مسارات Next.js مبنيّة حول طلب ينتهي. وعلى هدف بلا خوادم لا تستطيع الإمساك به أصلًا. الاتصالات طويلة العمر مكانها عملية تتحكّمون بها.
أليست Fastify أو Hono مقارنة أنسب من Express؟
لواجهة برمجية جديدة، غالبًا نعم؛ كلتاهما أسرع وأفضل في الأنواع. لكن حجّة هذه الصفحة ليست عن Express تحديدًا، بل عن اختياركم بين خادم تُركّبونه وإطار عمل قرّر سلفًا. استبدلوا المفضّل لديكم في كل الصفحة.
هل يستطيع Next.js أن يحلّ محلّ واجهة Express لدينا بالكامل؟
لواجهة برمجية لا يستهلكها إلا واجهتكم الأمامية، نعم غالبًا. أما لواجهة لها مستهلكون خارجيون وإصدارات وحدود معدّل ومصادقة خاصة بها، فستكونون تعيدون بناء Express داخل معالِجات المسارات.
هل أستطيع تشغيل Express و Next.js معًا؟
تستطيعون، عبر خادم مخصّص، وكلفته أعلى مما تبدو: الخادم المخصّص يعطّل التحسين الثابت التلقائي للمسارات التي يخدمها. تشغيلهما كعمليتين خلف وكيل عكسي أنظف عادةً.

← العودة إلى كل المقالات

اتصل بنا+1 848 272 7583واتساب+90 850 308 5436البريدinfo@codefacture.comصفحة التواصل