ترحيل المشاريع من Edge Runtime في Vercel: ملاحظات ميدانية
جدول المحتويات
عن الكاتب

Ahmed Mahmoud
كاتب ومطوّر
مهندس برمجيات شغوف بتطوير الويب وتصميم تجربة المستخدم.
مؤسّس ديفيا · eng-ahmed.com ↗أبرز النقاط
- بيئة Edge Runtime بيئة قديمة قيد الإيقاف التدريجي، مبنية على عزل V8، وتوفر سطح برمجي محدود — لا يوجد `fs`، ولا وحدة `crypto` الأصلية في Node، وتعبئة جزئية فقط لـ `Buffer`.
- إزالة `runtime = 'edge'` لا توقف البث. كل من ReadableStream وأحداث الخادم المرسلة (Server-Sent Events) وبث الاستجابات من نماذج الذكاء الاصطناعي عبر AI SDK يعمل على بيئة Node.js الافتراضية دون أي إعداد إضافي.
- تقنية Fluid Compute تعيد استخدام نسخ الدوال الجاهزة عبر الطلبات المتزامنة بدل تشغيل نسخة جديدة لكل طلب — وهذه هي الآلية التي حلّت محل حجة "Edge أسرع في بدء التشغيل البارد" كسبب رئيسي لاختياره.
- الوسطاء (Middleware) في Next.js على Vercel أصبحوا يعملون الآن على بيئة Node.js الكاملة أيضًا، لذلك لم تعد شيفرة الوسيط بحاجة لأن تُكتب وفق قيود Edge.
- الجزء الأكثر عرضة للعطل أثناء الترحيل هو عادة اعتمادية (dependency) تحمل افتراضات خاصة بـ Edge، وليس سطر إعداد runtime نفسه.
لماذا ننقل مشاريع عملائنا بعيدًا عن Edge Runtime؟
لأن بيئة Edge Runtime لم تعد تقدّم لأي مشروع ما لا توفره بيئة Node.js الافتراضية على Vercel. مررنا بقواعد شيفرة لعملاء كانت مثبّتة على `runtime = 'edge'` منذ فترة كانت فيها هذه البيئة الطريقة الوحيدة للحصول على زمن استجابة منخفض وتوزيع عالمي للتنفيذ. هذه الحجة لم تعد قائمة: تمنح Fluid Compute بيئة Node.js نفس نموذج التوزيع، مع الحفاظ على سطح Node.js البرمجي الكامل بدلاً من المجموعة الفرعية المقيّدة لعزل V8 في Edge.
ما القدرات التي يخسرها المسار (route) إن بقي على Edge Runtime؟
بيئة Edge Runtime لا توفر `fs`، ولا توفر وحدة `crypto` الأصلية في Node، وتعبئ `Buffer` جزئيًا فقط. حجم الحزمة (package) مقيّد أيضًا بشكل أكبر بكثير من حد 5 جيجابايت الذي تسمح به Fluid Compute، وهو أمر مهم بمجرد أن تعتمد إحدى الحزم على ربط أصلي (native binding) أو أداة مثل Playwright. على Edge، إما تفشل هذه الاعتماديات وقت البناء أو تتصرف بشكل خاطئ بصمت وقت التشغيل — تتبّعنا أخطاء إنتاجية فعلية كان سببها بالضبط هذه الفجوة في التعبئة (polyfill).
ما أول شيء يتعطل أثناء الترحيل من Edge؟
نادرًا ما يكون جسم المعالج (handler) نفسه هو المشكلة — بل اكتشاف ميزة (feature-detect) أو استيراد كان يفترض وجود Edge. الشيفرة التي تتحقق من المتغير العام `EdgeRuntime` لتغيير السلوك، وعملاء المصادقة أو قواعد البيانات التي توفر نقطة دخول منفصلة متوافقة مع Edge خلف تصدير شرطي، ومطابقات الوسيط (middleware matchers) المكتوبة بشكل ضيق حول قيود Edge، هي الأماكن الثلاثة الجديرة بالفحص قبل لمس إعداد runtime. عادة ما ينجح البناء رغم ذلك؛ والعطل يظهر وقت الطلب بدلاً من ذلك.
هل يستمر البث في العمل عند إزالة Edge Runtime؟
نعم، وهذا هو سوء الفهم الذي يمنع الفرق من الترحيل. بث استجابة — سواء ReadableStream أو أحداث الخادم المرسلة عبر `text/event-stream` أو إخراج نماذج الذكاء الاصطناعي رمزًا بعد رمز — ليست ميزة حصرية لـ Edge. شيفرة المعالج نفسها تمامًا تعمل دون تغيير على بيئة Node.js الافتراضية؛ كل ما يحتاج الحذف هو تصدير `runtime = 'edge'`. ما يتغير هو أن `fs` ووحدة `crypto` الأصلية وبقية مكتبة Node.js القياسية تصبح متاحة إن احتاجها المسار يومًا.
Edge Runtime مقابل Node.js على Fluid Compute: ما الفرق الفعلي؟
- واجهات Node.js البرمجية (fs، crypto، net): مقيّدة أو مُعبّأة جزئيًا على Edge، وصول كامل على Node.js.
- توافق حزم npm: جزئي على Edge (الروابط الأصلية غالبًا ما تفشل)، كامل على Node.js ضمن حد حجم الحزمة.
- حد حجم الحزمة: صغير ومقيّد بالعزل على Edge، يصل إلى 5 جيجابايت على Fluid Compute.
- بدء التشغيل البارد: سريع ومبني على العزل في Edge، ويقل على Fluid Compute بفضل إعادة استخدام النسخ عبر الطلبات المتزامنة.
- أقصى مدة تنفيذ: حد قصير مبني على العزل في Edge، يصل إلى 300 ثانية افتراضيًا على Node.js.
- البث وأحداث الخادم المرسلة: مدعومة في كليهما — ليست ميزة حصرية لـ Edge.
- WebSockets: غير مدعومة على Edge، مدعومة على Node.js.
كيف نتحقق من صحة الترحيل من Edge إلى Node قبل الإطلاق؟
نزيل تصدير runtime من مسار واحد في كل مرة بدلاً من التطبيق كاملاً دفعة واحدة، ما يجعل عزل أي عطل أمرًا بسيطًا. نشغّل مجموعة الاختبارات الكاملة، مع اهتمام خاص بأي شيء يلامس اعتماديات المسار، لأن البدائل الخاصة بـ Edge قد تخفي أخطاء لا تكشفها إلا واجهات Node الحقيقية. نختبر نقاط البث يدويًا عبر `curl -N` للتأكد من أن الاستجابة ما زالت تتدفق تدريجيًا بدلاً من التخزين المؤقت الكامل قبل الإرسال. بعدها نراجع سجلات الدالة لمدة التنفيذ وعدد الاستدعاءات بعد يوم من الحركة الفعلية، وهو ما يخبرنا إن كانت إعادة استخدام النسخ في Fluid Compute تعمل فعليًا على ذلك المسار.
الأسئلة الشائعة
**س:** هل تحتاجون إلى Edge Runtime لبث استجابات الذكاء الاصطناعي في Next.js؟
**ج:** لا. بث استجابة ReadableStream أو أحداث الخادم المرسلة يعمل على بيئة Node.js الافتراضية؛ وبيئة Edge Runtime ليست مطلوبة لإخراج النماذج رمزًا بعد رمز.
**س:** ماذا يحدث للمسارات التي ما زالت مثبّتة على `runtime = 'edge'` اليوم؟
**ج:** تستمر في العمل، لكن Vercel وNext.js يوجّهان الشيفرة الجديدة نحو بيئة Node.js على Fluid Compute، ما يجعل البقاء على Edge تكلفة صيانة بدلاً من ميزة أداء.
**س:** هل تؤثر إزالة Edge Runtime سلبًا على زمن الاستجابة للمستخدمين الموزعين عالميًا؟
**ج:** عمليًا تضيق الفجوة، لأن Fluid Compute تعيد استخدام النسخ الجاهزة عبر الطلبات المتزامنة بدلاً من إنشاء عزل جديد لكل طلب — وهذه كانت الآلية الرئيسية وراء شعور Edge بأنه أسرع.
**س:** هل يمكن لوسطاء Next.js العمل على Node.js بدلاً من Edge؟
**ج:** نعم. الوسطاء على Vercel يدعمون بيئة Node.js الكاملة ضمن Fluid Compute، لذا لم تعد الحاجة لكتابتها وفق سطح Edge المقيّد قائمة.
**س:** ما أكبر خطر في ترحيل من Edge إلى Node؟
**ج:** اعتمادية تحمل افتراضات خاصة بـ Edge فقط — مكتبة لها نقطة دخول منفصلة لـ Edge، أو شيفرة تكتشف المتغير العام `EdgeRuntime` — أكثر عرضة للعطل من معالج المسار نفسه.
قراءات إضافية
هندسة الواجهات الأمامية
معالجات المسارات مقابل إجراءات الخادم في Next.js: متى نستخدم كلًّا منهما
كلٌّ من إجراءات الخادم ومعالجات المسارات ينفّذ كودًا على الخادم في موجّه تطبيقات Next.js، لكنهما يحلّان مشكلتين مختلفتين. في ديفيا نستخدم إجراءات الخادم لعمليات التعديل القادمة من واجهتنا، ومعالجات المسارات لواجهات البرمجة العامة وخطافات الويب والبث.
هندسة الواجهات الأمامية
مُحوِّل React في 2026: ما الذي يحفظه في الذاكرة المؤقتة (وما الذي لا يحفظه)
مُحوِّل React أُطلق بشكل مستقر مع React 19 ويُدرج الحفظ في الذاكرة المؤقتة تلقائياً للمكوِّنات والخطافات وردود الفعل. بعد تفعيله في مشاريع متعددة، هذا ما يُعالجه وما يتجاوزه وما إذا كان يجب حذف استدعاءات useMemo.