تسلّم شيفرة Next.js لا أحد يريد لمسها
الاندفاع الأول هو إعادة الكتابة. بدلًا من ذلك نجري توجيهًا من أسبوعين، وهذا ما يُنتجه، وكيف تميّز بين شيفرة سيّئة فعلًا وأخرى غير مألوفة فحسب.
يرث فريقٌ تطبيقًا. ومن كتبوه رحلوا. كل عملية نشر حدثٌ صغير، ولا أحد واثقًا من الأجزاء الحاملة، وخلال شهر يقول أحدهم كلمة «إعادة كتابة» في اجتماع.
أحيانًا تكون إعادة الكتابة صوابًا. وهي صواب أقلّ بكثير ممّا يُقترَح، والقرار يُتَّخذ غالبًا قبل أن يملك أحدٌ المعلومات اللازمة لاتخاذه.
أسبوعان من القراءة قبل سطر واحد من الكتابة
التوجيه الذي نجريه على شيفرة موروثة ثابت: اقرأ، وارسم الخريطة، ووثّق، ولا تغيّر شيئًا. أسبوعان، والمُخرَج وثيقة لا طلب دمج.
ما يدخل فيها:
خريطة المسارات. كل مسار، ونمط عرضه، وما يقرأه من بيانات وما يكتبه. في App
Router يمكن استرجاع أغلب ذلك من مخرجات البناء ومن ملفات page.tsx؛ وفي تطبيق
Pages Router يعني قراءة أجساد getServerSideProps. عمل ممل، وهو أثمن أثرٍ
تنتجه، لأن سؤال «ماذا يفعل هذا التطبيق فعلًا» يتبيّن أنه سؤال لا يعرف أحد
إجابته.
حدّ البيانات. أي استدعاء يذهب إلى أي خدمة، وأيّها موثَّق، وأيّها مخزَّن
مؤقّتًا. انتبه للاستدعاء الذي لم يوثّقه أحد: واجهة داخلية تُستدعى من مكوّن
عميل بمفتاح في NEXT_PUBLIC_.
مسار النشر. ما الذي يبنيه، وما الاختبارات التي تعمل، وما متغيّرات البيئة، وماذا يحدث حين يفشل. إن كانت الإجابة «علي يعرف» وقد رحل علي، فهذا أعلى بند أولويةً في الوثيقة كلّها.
نطاق أثر كل منطقة. أي الملفات يستوردها كل شيء، وأيّها يستورده مسار واحد.
ملف utils.ts مشترك بأربعين تصديرًا ومئة مستورِد يخبرك أين يتحوّل التغيير
الصغير إلى كبير.
ما الذي يجعل الشيفرة صعبة التغيير حقًّا
بعد تدقيق كثير من هذه المشاريع، تبيّن أن الخصائص المرتبطة بالخوف ضيّقة ومتكرّرة.
- لا أنواع عند الحدود. ليس «لا TypeScript» - أغلب هذه المشاريع فيها
TypeScript. لكنها
anyعند كل استدعاء جلب، فيتحقّق المترجِم من داخل التطبيق في مقابل افتراضات لم يتحقّق منها أحد عند الحافة. - الحالة في أكثر من مكان. ذاكرة خادم ومخزن عميل ومعاملات رابط، تدّعي كلّها حفظ القيمة نفسها، بلا قاعدة تحدّد أيّها يفوز.
- آثار جانبية داخل العرض. سلاسل
useEffectتجلب، ثم تضبط الحالة، ثم تطلق أثرًا آخر. هذه هي التغييرات التي تكسر شيئًا على بُعد ثلاث شاشات. - لا فاصل بين الإطار والمجال. قواعد العمل المكتوبة داخل معالِجات المسارات لا يمكن اختبارها بلا طلب، فلا تُختبر.
لاحظ ما ليس في القائمة: اعتماديات قديمة، وبنية مجلّدات غير عصرية، ومكوّنات صنفية، وCSS لا يعجب أحدهم. هذه ظاهرة ورخيصة التغيير. وليست هي ما يجعل النشر مخيفًا، وإعادة كتابة مبرَّرة بها تشتري سنةً من الخطر مقابل تحسين جمالي.
اجعلها آمنة أولًا، ثم اجعلها جيّدة
الترتيب مهم، وهو ليس الترتيب الممتع.
- اجعل النشر قابلًا للتكرار. ما لم تستطع النشر متى شئت والتراجع متى شئت، فكل تحسين مقامرة.
- حدّد أنواع الحدود. حلّل البيانات الخارجية عند الحافة - بـ
zodأو ما يعادله - كي تفشل البيانات الخاطئة عند الجلب برسالة مفيدة بدل أن تفشل بعد ثلاثة مكوّنات على هيئةundefined is not a function. - أضف اختبارات حيث المال. لا تغطية. صفحة الدفع، ومسار المصادقة، والحسبة الواحدة التي يعتمد عليها العمل.
- ثم أعد الهيكلة، منطقةً منطقة، خلف تلك الاختبارات.
معظم الخوف يزول بعد الخطوة الثانية، والخطوة الثانية عادةً أسبوع عمل على شيفرة كان الناس يصفونها بأنها لا تُنقَذ.
متى تكون إعادة الكتابة هي الجواب فعلًا
هناك حالات. في خبرتنا، تستحقّ حين يكون الإطار نفسه هو المشكلة - تطبيق مبني على إطار وسيط متروك، أو تطبيق لا يستطيع نموذج عرضه إنتاج الصفحات التي تحتاجها. وتستحقّ أيضًا حين يكون التطبيق صغيرًا بما يكفي لتُقاس إعادة كتابته بالأسابيع، وعندها لا يكاد الجدل يهمّ.
ولا تستحقّ لأن الشيفرة قبيحة، أو لأنها على إصدار رئيسي أقدم، أو لأن الفريق الحالي لم يكتبها. وهذه هي الأسباب الثلاثة التي تُقترَح من أجلها عادةً.
وإن كانت المشكلة الحقيقية أن التطبيق على Pages Router وأن الطريق إلى الأمام غير واضح، فهذه أيضًا ليست إعادة كتابة، بل الترحيل من Pages Router إلى App Router دون تجميد التطوير، وهو عمل مختلف وأرخص بكثير.
ما تدين به لمن يأتي بعدك
مهما قرّرت، اترك الوثيقة. الشيفرة كانت مخيفة لأن فهم الفريق السابق لها رحل معه، والعلاج الدائم الوحيد لذلك أن يُكتَب حيث يمكن قراءة الشيفرة إلى جانبه.
نسلّم تلك الخريطة سواء أكمل العميل معنا أم لا. وهي الجزء الأطول عمرًا في المشروع كلّه.
