يا الله شو بتذكر هداك اليوم… كان عنا بالفريق شب جديد، خلينا نسميه “سامر”، شب شاطر ونشيط ومليان حماس. قدّم أول Pull Request (طلب دمج) لإلو، وكان الكل متحمس يشوف شغله. فتحت الـ PR، الكود شغال، والمنطق البرمجي سليم، بس يا ويلي على التنسيق! مرة الفاصلة المنقوطة (semicolon) موجودة ومرة لأ، مرة بستخدم علامات تنصيص مفردة (‘) ومرة مزدوجة (“)، والمسافات البادئة (indentation) قصة لحالها.
وهون بلشت المعركة… واحد من الشباب كتب تعليق: “الرجاء استخدام الفاصلة المنقوطة في نهاية كل سطر”. رد عليه مهندس تاني: “الأفضل بدون فواصل منقوطة، هيك الـ Standard الجديد”. وأنا، أبو عمر، دخلت على الخط: “يا جماعة، المهم نوحد الأسلوب، بس أنا بفضل علامات التنصيص المفردة عشانها أوضح”.
خلال ساعة، صار في أكتر من 30 تعليق على الـ PR، ولا واحد فيهم بحكي عن منطق الكود نفسه! كل الحكي عن الشكل والزينة. شفت سامر وجهه قلب ألوان، الشب حس حاله انه عمل مصيبة، وهو كل اللي عمله إنه كتب كود شغال. وقتها وقفت لحظة وقلت بصوت عالي في المكتب: “يا جماعة الخير، إحنا بنحرق وقتنا وطاقتنا في شغلات لازم الكمبيوتر يعملها لحاله! عيب علينا نضيّع وقتنا ووقت سامر في جدال الفواصل!”.
من هداك اليوم، تغير كل شيء. قررنا ننهي “جحيم التنسيق اليدوي” للأبد. وهذه هي قصتنا وكيف يمكنك أن تفعل الشيء نفسه.
ما هو “جحيم التنسيق” ولماذا هو مشكلة حقيقية؟
قد تبدو قصة الفواصل والمسافات تافهة، لكنها في عالم تطوير البرمجيات عرض لمشكلة أكبر بكثير. “جحيم التنسيق” (Formatting Hell) هو الحالة التي يقضي فيها فريقك وقتًا ثمينًا في النقاش والمراجعة والتعديل اليدوي لتنسيق الكود بدلاً من التركيز على جودة الكود ومنطقه. وهذه بعض أضراره:
- إهدار الوقت والجهد: كل دقيقة تقضيها في تعديل مسافة أو إضافة فاصلة هي دقيقة ضائعة كان يمكن استثمارها في حل مشكلة حقيقية.
- تثبيط المطورين الجدد: عندما يكون أول انطباع لمطور جديد هو سيل من التعليقات على التنسيق، فإنه يشعر بالإحباط وبأن مساهمته غير مرحب بها.
- قاعدة كود غير متناسقة: عندما يكتب كل مطور بأسلوبه الخاص، يصبح الكود صعب القراءة والصيانة على المدى الطويل. العين تحتاج وقتًا لتعتاد على أساليب مختلفة في نفس الملف.
- جدالات لا طائل منها: هذه النقاشات شخصية في معظمها (“أنا أحب” مقابل “أنا أفضل”) وليست مبنية على أساس تقني متين، مما يخلق بيئة عمل سلبية.
الحل السحري: Prettier – منسّق الكود “العنيد”
الحل يكمن في إزالة العامل البشري من معادلة التنسيق. نحن بحاجة إلى “ديكتاتور” عادل يفرض نفس القواعد على الجميع. هذا الديكتاتور هو Prettier.
ما هو Prettier؟
Prettier هو أداة لتنسيق الكود، لكن ميزته الأساسية أنه “عنيد” (Opinionated). هذا يعني أنه لا يأتي مع مليون خيار وإعداد. بل يفرض مجموعة من القواعد المحددة مسبقًا بهدف تحقيق التناسق المطلق. هو يأخذ الكود الذي كتبته، يتجاهل تنسيقك بالكامل، ثم يعيد طباعته من الصفر بأسلوبه الخاص الذي لا يتغير.
يدعم Prettier العديد من اللغات مثل JavaScript, TypeScript, JSX, HTML, CSS, JSON, Markdown وغيرها الكثير.
كيف نبدأ مع Prettier؟
الأمر أسهل مما تتخيل. لنقم بإعداده في مشروع Node.js كمثال:
-
تثبيت Prettier: قم بتثبيته كـ “اعتمادية تطوير” (dev dependency).
npm install --save-dev --save-exact prettierنصيحة أبو عمر: استخدم
--save-exactلضمان أن كل أعضاء الفريق يستخدمون نفس الإصدار بالضبط من Prettier، لتجنب أي اختلافات طفيفة في التنسيق بين التحديثات. -
إنشاء ملف الإعدادات (اختياري ولكن موصى به): أنشئ ملفًا باسم
.prettierrc.jsonفي جذر مشروعك. يمكنك ترك هذا الملف فارغًا لاستخدام الإعدادات الافتراضية، أو تعديل بعض الخيارات القليلة المتاحة.{ "semi": true, "singleQuote": true, "tabWidth": 2, "trailingComma": "es5" }هذه الإعدادات تخبر Prettier بأننا نريد فواصل منقوطة، وعلامات تنصيص مفردة، ومسافة بادئة بحجم 2، وفاصلة زائدة (trailing comma) متوافقة مع ES5.
-
إنشاء ملف التجاهل: تمامًا مثل
.gitignore، يمكنك إنشاء ملف.prettierignoreلتخبر Prettier بالملفات والمجلدات التي يجب ألا يلمسها.# .prettierignore node_modules dist build package-lock.json -
التجربة اليدوية: الآن يمكنك تشغيل Prettier لتنسيق كل الملفات في مشروعك.
npx prettier --write .الأمر
--writeيخبر Prettier بتعديل الملفات مباشرة. بدون هذا الأمر، سيقوم فقط بطباعة النتائج في الطرفية (Terminal) دون حفظها.
رائع! الآن لدينا أداة لتوحيد التنسيق. لكن هذا يحل نصف المشكلة فقط. ماذا لو نسي أحد أعضاء الفريق تشغيل الأمر قبل رفع الكود؟
المشكلة الثانية: النسيان… وهنا يأتي دور Husky
البشر ينسون. الاعتماد على أن يتذكر الجميع تشغيل أمر يدويًا هو وصفة للفشل. نحتاج إلى طريقة لفرض عملية التنسيق بشكل تلقائي قبل أن يصل أي كود غير منسق إلى مستودع Git الخاص بنا.
ما هو Husky وخطافات Git (Git Hooks)؟
ببساطة، Git Hooks هي عبارة عن سكربتات (نصوص برمجية) تعمل تلقائيًا عند نقاط معينة في دورة حياة Git. على سبيل المثال، يمكنك تشغيل سكربت قبل عملية الـ commit (يُسمى pre-commit) أو قبل عملية الـ push (يُسمى pre-push).
Husky هي أداة تسهل إدارة هذه الـ “الخطافات” بشكل كبير داخل مشروعك مباشرةً باستخدام ملف package.json.
إعداد Husky لتشغيل Prettier تلقائيًا
هدفنا: قبل كل عملية commit، نريد أن يتم تشغيل Prettier تلقائيًا على الملفات التي تم تعديلها.
-
تثبيت Husky:
npm install husky --save-dev -
تفعيل Husky:
npx husky installهذا الأمر يُنشئ مجلد
.huskyالذي ستعيش فيه خطافاتنا. -
إضافة خطاف pre-commit: الآن سنطلب من Husky إضافة أمر إلى خطاف ما قبل الـ commit.
npx husky add .husky/pre-commit "npx prettier --write ."هذا جيد، ولكنه غير فعال. في كل مرة تقوم بعمل commit، سيحاول Prettier تنسيق المشروع بأكمله، وهذا قد يكون بطيئًا جدًا في المشاريع الكبيرة. نريد فقط تنسيق الملفات التي قمنا بتعديلها وإضافتها للـ commit (الملفات في منطقة الـ staging). وهنا يأتي دور البطل الأخير في قصتنا.
المستوى المتقدم: استخدام `lint-staged` للفعالية القصوى
lint-staged هي أداة ذكية تعمل مع Husky لتشغيل الأوامر على الملفات الموجودة في منطقة الـ staging فقط. هذا يجعل العملية سريعة وفعالة للغاية.
إعداد `lint-staged`
-
تثبيت `lint-staged`:
npm install lint-staged --save-dev -
إضافة إعدادات `lint-staged` إلى `package.json`:
افتح ملف
package.jsonوأضف القسم التالي:"lint-staged": { "*.{js,jsx,ts,tsx,json,css,md}": "prettier --write" }هذا الإعداد يعني: “لأي ملف ينتهي بالامتدادات المذكورة وموجود في منطقة الـ staging، قم بتشغيل أمر
prettier --writeعليه”. -
تعديل خطاف Husky: الآن، بدلاً من أن يقوم Husky بتشغيل Prettier مباشرة، سنجعله يشغل
lint-staged، والذي بدوره سيشغل Prettier.عدّل ملف
.husky/pre-commit(أو أعد تشغيل الأمر add) ليحتوي على ما يلي فقط:npx lint-staged
وهكذا اكتملت المنظومة! الآن، عندما يقوم أي مطور في الفريق (حتى أبو عمر) بتنفيذ git commit، سيحدث التالي في الخلفية:
- Husky يعترض عملية الـ commit ويشغل خطاف
pre-commit. - الخطاف يشغل
lint-staged. lint-stagedيجمع كل الملفات التي تم إضافتها (staged files).- يقوم بتمرير هذه الملفات إلى Prettier لتنسيقها.
- بعد التنسيق، يقوم
lint-stagedتلقائيًا بإضافة هذه التعديلات إلى الـ commit. - تتم عملية الـ commit بنجاح، مع كود نظيف ومنسق 100%.
نصائح من خبرة أبو عمر
- التكامل مع محرر الأكواد: شجع فريقك على تثبيت إضافة Prettier في محرر الأكواد المفضل لديهم (مثل VS Code) وتفعيل خيار “Format on Save”. هذا يعطي المطور تغذية راجعة فورية ويجعل عملية الـ commit أكثر سلاسة.
- النقاش مرة واحدة فقط: اجلس مع فريقك مرة واحدة، اتفقوا على إعدادات
.prettierrc.json، ثم ضعوا الملف في الـ repository وأغلقوا باب النقاش. الهدف هو التناسق، وليس إرضاء الذوق الشخصي للجميع. “الاتفاق سيد الأحكام يا جماعة”. - لا تخف من “العناد”: جمال Prettier في عناده. لا تحاول التحايل عليه. اقبل أسلوبه وركز على ما هو أهم. صدقني، بعد أسبوع، لن تتذكر حتى كيف كنت تفضل تنسيق الكود سابقًا.
- للمشاريع القديمة: إذا كنت تطبق هذا على مشروع قديم وضخم، قم بإنشاء commit واحد كبير مخصص للتنسيق فقط (A massive formatting commit). أبلغ الفريق بهذا الـ commit حتى لا يتعارض مع عملهم، وبعدها يصبح كل شيء سهلاً.
الخلاصة: ركز على ما يهم، ودع الآلة تعمل
في النهاية، تحولت مراجعات الكود لدينا من جدالات تافهة حول الفواصل إلى نقاشات مثمرة حول بنية الكود، وأفضل الممارسات، والحلول المبتكرة. أصبح سامر (المطور الجديد) يساهم بثقة، وتحسنت إنتاجية الفريق بشكل ملحوظ.
وقتك كمبرمج أثمن من أن يضيع في تعديل المسافات يدويًا. استثمر ساعة واحدة في إعداد هذه الأدوات، وستوفر على فريقك مئات الساعات من الجهد والجدال على المدى الطويل. حوّل “جحيم التنسيق” إلى “نعيم الأتمتة”، واجعل مراجعات الكود تركز على العقل والمنطق، وليس على الشكل والزينة.
يلا، شدّوا حيلكم ورتبوا كودكم! 🚀