هناك استراتيجيتان رئيسيتان لاستضافة وإدارة التعليمات البرمجية من خلال Git: monorepo مقابل multi-repo. كلا النهجين لهما إيجابيات وسلبيات.
يمكننا استخدام أي من الطريقتين لأي مصدر برمجي بأي لغة. يمكنك استخدام أي من هذه الاستراتيجيات للمشاريع التي تحتوي على عدد قليل من المكتبات للآلاف منها. حتى إذا كان يتضمن عددًا قليلاً من أعضاء الفريق أو المئات ، أو كنت ترغب في استضافة كود خاص أو مفتوح المصدر ، فلا يزال بإمكانك استخدام monorepo أو متعدد الريبو بناءً على عوامل مختلفة.
ما هي مزايا وعيوب كل نهج؟ متى يجب أن نستخدم أحدهما أو الآخر؟ هيا نكتشف!
ما هي الريبو؟
المستودع (اختصارًا للمستودع) هو تخزين لجميع التغييرات والملفات من المشروع ، مما يتيح للمطورين “التحكم في الإصدار” في أصول المشروع طوال مرحلة التطوير.
نشير عادة إلى بوابة مستودعات (على النحو المنصوص عليه جيثب ، GitLab ، أو Bitbucket )، ولكن ينطبق عليها المفهوم أيضا إلى أنظمة التحكم في الإصدار الأخرى (مثل زئبقي).
ما هو المونوريبو؟
يستخدم نهج monorepo مستودعًا واحدًا لاستضافة جميع التعليمات البرمجية للمكتبات أو الخدمات المتعددة التي تؤلف مشاريع الشركة. في أقصى حالاته ، يتم استضافة قاعدة الكود الكاملة من شركة – التي تشمل مشاريع مختلفة ومشفرة بلغات مختلفة – في مستودع واحد.
فوائد مونوريبو
توفر استضافة قاعدة التعليمات البرمجية بالكامل على مستودع واحد الفوائد التالية.
يخفض حواجز الدخول
عندما يبدأ الموظفون الجدد العمل في شركة ، فإنهم يحتاجون إلى تنزيل الكود وتثبيت الأدوات المطلوبة لبدء العمل في مهامهم. لنفترض أن المشروع منتشر عبر العديد من المستودعات ، ولكل منها تعليمات التثبيت والأدوات المطلوبة. في هذه الحالة ، سيكون الإعداد الأولي معقدًا ، وفي أغلب الأحيان ، لن تكون الوثائق مكتملة ، مما يتطلب من أعضاء الفريق الجدد التواصل مع الزملاء للحصول على المساعدة.
يبسط monorepo الأمور. نظرًا لوجود موقع واحد يحتوي على جميع التعليمات البرمجية والوثائق ، يمكنك تبسيط الإعداد الأولي.
إدارة الكود في موقع مركزي
يمنحك وجود مستودع واحد رؤية لجميع التعليمات البرمجية لجميع المطورين. إنه يبسط إدارة الكود لأنه يمكننا استخدام أداة تعقب واحدة للمشكلات لمراقبة جميع المشكلات طوال دورة حياة التطبيق.
على سبيل المثال ، تكون هذه الخصائص ذات قيمة عندما تمتد المشكلة إلى مكتبتين فرعيتين (أو أكثر) مع وجود الخطأ في المكتبة التابعة. مع وجود مستودعات متعددة ، قد يكون من الصعب العثور على جزء من التعليمات البرمجية حيث تحدث المشكلة.
علاوة على ذلك ، سنحتاج إلى معرفة المستودع الذي يجب استخدامه لإنشاء المشكلة ثم دعوة أعضاء الفرق الأخرى ووضع العلامات المشتركة لهم للمساعدة في حل المشكلة.
مع monorepo ، على الرغم من ذلك ، يصبح كل من تحديد مشكلات التعليمات البرمجية والتعاون لاستكشاف الأخطاء وإصلاحها أسهل في تحقيقه.
إعادة تصنيع غير مؤلمة على نطاق واسع
عند إنشاء إعادة هيكلة التعليمات البرمجية على مستوى التطبيق ، ستتأثر مكتبات متعددة. إذا كنت تستضيفهم عبر مستودعات متعددة ، فإن إدارة جميع طلبات السحب المختلفة لإبقائها متزامنة مع بعضها البعض يمكن أن يكون تحديًا.
يجعل monorepo من السهل إجراء جميع التعديلات على جميع التعليمات البرمجية لجميع المكتبات وإرسالها بموجب طلب سحب واحد.
أكثر صعوبة لكسر الوظائف المجاورة
باستخدام monorepo ، يمكننا إعداد جميع الاختبارات لجميع المكتبات للتشغيل كلما تم تعديل أي مكتبة واحدة. نتيجة لذلك ، أدى احتمال إجراء تغيير في بعض المكتبات إلى تقليل التأثيرات الضارة على المكتبات الأخرى.
تشارك الفرق ثقافة التنمية
على الرغم من أنه ليس مستحيلًا ، مع نهج monorepo ، يصبح من الصعب إلهام ثقافات فرعية فريدة بين الفرق المختلفة. نظرًا لأنهم سيشاركون في نفس المستودع ، فمن المرجح أنهم سيشاركون في نفس منهجيات البرمجة والإدارة ويستخدمون نفس أدوات التطوير .
مشاكل مع نهج Monorepo
استخدام مستودع واحد لجميع الكود لدينا له عيوب عديدة.
دورات تنمية أبطأ
عندما تحتوي التعليمات البرمجية الخاصة بمكتبة على تغييرات متقطعة ، مما يؤدي إلى فشل اختبارات المكتبات التابعة ، يجب أيضًا إصلاح الكود قبل دمج التغييرات.
إذا كانت هذه المكتبات تعتمد على فرق أخرى ، منشغلة بالعمل في مهمة أخرى وغير قادرة (أو راغبة) في تكييف كودها لتجنب التغييرات الفاصلة واجتياز الاختبارات ، فقد يتعطل تطوير الميزة الجديدة.
علاوة على ذلك ، قد يبدأ المشروع في التقدم فقط بسرعة أبطأ فريق في الشركة. قد تؤدي هذه النتيجة إلى إحباط أعضاء أسرع الفرق ، وتهيئة الظروف لهم كي يرغبوا في مغادرة الشركة.
بالإضافة إلى ذلك ، ستحتاج المكتبة إلى إجراء الاختبارات لجميع المكتبات الأخرى أيضًا. ل مزيد من الفحوص لتشغيل ، والمزيد من الوقت الذي يستغرقه لتشغيلها، وتباطؤ سرعة يمكننا تكرار على رمز لنا.
يتطلب تنزيل Codebase بالكامل
عندما يحتوي monorepo على جميع الأكواد الخاصة بشركة ما ، يمكن أن يكون ضخمًا ، ويحتوي على غيغابايت من البيانات. للمساهمة في أي مكتبة مستضافة بداخلها ، سيطلب أي شخص تنزيل المستودع بأكمله.
إن التعامل مع قاعدة بيانات ضخمة يعني استخدامًا سيئًا للمساحة على محركات الأقراص الثابتة وتفاعلات أبطأ معها. على سبيل المثال ، git statusقد تستغرق الإجراءات اليومية مثل التنفيذ أو البحث في قاعدة الشفرة باستخدام regex عدة ثوانٍ أو حتى دقائق أطول مما قد تستغرقه في عمليات إعادة الشراء المتعددة.
المكتبات غير المعدلة قد تكون حديثة الإصدار
عندما نضع علامة على monorepo ، يتم تعيين العلامة الجديدة لكل التعليمات البرمجية الموجودة داخلها. إذا أدى هذا الإجراء إلى تشغيل إصدار جديد ، فسيتم إصدار جميع المكتبات المستضافة في المستودع حديثًا برقم الإصدار من العلامة ، على الرغم من أن العديد من هذه المكتبات ربما لم يتم إجراء أي تغيير عليها.
الشوكة أكثر صعوبة
يجب أن تجعل المشاريع مفتوحة المصدر الأمر سهلاً قدر الإمكان على المساهمين للمشاركة. باستخدام مستودعات متعددة ، يمكن للمساهمين التوجه مباشرة إلى المستودع المحدد للمشروع الذي يريدون المساهمة فيه. مع وجود monorepo يستضيف مشاريع مختلفة ، يجب على المساهمين أولاً التنقل في طريقهم إلى المشروع الصحيح وسيحتاجون إلى فهم كيفية تأثير مساهمتهم على جميع المشاريع الأخرى.
ما هو ملتي ريبو؟
يستخدم نهج متعدد الريبو عدة مستودعات لاستضافة مكتبات أو خدمات متعددة لمشروع طورته شركة. في أقصى حالاتها ، ستستضيف كل مجموعة دنيا من التعليمات البرمجية القابلة لإعادة الاستخدام أو الوظائف المستقلة (مثل خدمة مصغرة) ضمن مستودعها.
فوائد Multi-Repo
توفر استضافة كل مكتبة بشكل مستقل عن الآخرين مجموعة كبيرة من الفوائد.
إصدارات المكتبة المستقلة
عند وضع علامات على أحد المستودعات ، يتم تخصيص علامة “جديدة” لقاعدة التعليمات البرمجية الخاصة به. نظرًا لأن رمز مكتبة معينة فقط موجود في المستودع ، يمكن تمييز المكتبة وإصدارها بشكل مستقل عن جميع المكتبات الأخرى المستضافة في مكان آخر.
يساعد وجود إصدار مستقل لكل مكتبة في تحديد شجرة التبعية للتطبيق ، مما يتيح لنا تكوين إصدار كل مكتبة لاستخدامه.
إصدارات الخدمة المستقلة
نظرًا لأن المستودع يحتوي فقط على رمز لبعض الخدمات ولا شيء آخر ، فيمكن أن يكون له دورة نشر خاصة به ، بغض النظر عن أي تقدم يتم إحرازه في التطبيقات التي تصل إليه.
يمكن للخدمة استخدام دورة إصدار سريعة مثل التسليم المستمر (حيث يتم نشر رمز جديد بعد اجتيازه لجميع الاختبارات). قد تستخدم بعض المكتبات التي تصل إلى الخدمة دورة إصدار أبطأ ، مثل تلك التي تنتج إصدارًا جديدًا مرة واحدة فقط في الأسبوع.
يساعد في تحديد التحكم في الوصول عبر المنظمة
يجب فقط إضافة أعضاء الفريق المشاركين في تطوير مكتبة إلى المستودع المقابل وتنزيل الكود الخاص بها. نتيجة لذلك ، هناك استراتيجية ضمنية للتحكم في الوصول لكل طبقة في التطبيق . سيتم منح الأشخاص المعنيين بالمكتبة حقوق التحرير ، وقد لا يتمكن أي شخص آخر من الوصول إلى المستودع. أو قد يتم إعطاؤهم حقوق القراءة ولكن ليس حقوق التحرير.
يسمح للفرق بالعمل بشكل مستقل
يمكن لأعضاء الفريق تصميم بنية المكتبة وتنفيذ كودها الذي يعمل بمعزل عن جميع الفرق الأخرى. يمكنهم اتخاذ قرارات بناءً على ما تفعله المكتبة في السياق العام دون أن تتأثر بالمتطلبات المحددة من فريق أو تطبيق خارجي.
مشاكل مع نهج Multi-Repo
يمكن أن يؤدي استخدام مستودعات متعددة إلى ظهور العديد من المشكلات.
يجب إعادة مزامنة المكتبات باستمرار
عندما يتم إصدار إصدار جديد من مكتبة تحتوي على تغييرات متقطعة ، يجب تكييف المكتبات التي تعتمد على هذه المكتبة لبدء استخدام أحدث إصدار. إذا كانت دورة إصدار المكتبة أسرع من دورة المكتبات التابعة لها ، فقد تصبح غير متزامنة مع بعضها البعض بسرعة.
ستحتاج الفرق إلى اللحاق بالركب باستمرار لاستخدام أحدث الإصدارات من الفرق الأخرى. نظرًا لأن الفرق المختلفة لها أولويات مختلفة ، فقد يكون تحقيق ذلك في بعض الأحيان أمرًا شاقًا.
وبالتالي ، قد ينتهي الأمر بالفريق غير القادر على اللحاق بالركب إلى التمسك بالنسخة القديمة من المكتبة المعتمدة. سيكون لهذه النتيجة آثار على التطبيق (من حيث الأمان والسرعة واعتبارات أخرى) ، وقد تتسع فجوة التطوير عبر المكتبات فقط.
قد شظية فرق
عندما لا تحتاج الفرق المختلفة إلى التفاعل ، فقد يعملون في صوامعهم الخاصة. على المدى الطويل ، قد ينتج عن ذلك فرق تنتج ثقافاتها الفرعية داخل الشركة ، مثل استخدام منهجيات مختلفة من البرمجة أو الإدارة أو استخدام مجموعات مختلفة من أدوات التطوير.
إذا احتاج بعض أعضاء الفريق في النهاية إلى العمل في فريق مختلف ، فقد يعانون قليلاً من الصدمة الثقافية ويتعلمون طريقة جديدة لأداء عملهم .
Monorepo مقابل Multi-Repo: الاختلافات الأساسية
كلا النهجين يتعاملان في النهاية مع نفس الهدف: إدارة قاعدة الكود. ومن ثم ، يجب أن يحل كلاهما نفس التحديات ، بما في ذلك إدارة الإصدار ، وتعزيز التعاون بين أعضاء الفريق ، والتعامل مع المشكلات ، وتشغيل الاختبارات ، وغيرها.
يتعلق الاختلاف الرئيسي بينهما بتوقيتهما على أعضاء الفريق لاتخاذ القرارات: إما مقدمًا لـ monorepo أو أسفل الخط لـ multi-repo.
دعونا نحلل هذه الفكرة بمزيد من التفصيل.
نظرًا لأن جميع المكتبات يتم إصدارها بشكل مستقل في الريبو المتعدد ، فإن الفريق الذي يصدر مكتبة مع تغييرات عاجلة يمكنه القيام بذلك بأمان عن طريق تعيين رقم إصدار رئيسي جديد إلى أحدث إصدار. يمكن للمجموعات الأخرى أن تلتزم مكتباتها التابعة بالإصدار القديم وتتحول إلى الجديدة بمجرد أن يتم تكييف الكود الخاص بها.
يترك هذا النهج قرارًا بشأن موعد تكييف جميع المكتبات الأخرى مع كل فريق مسؤول ، والذي يمكنه القيام بذلك في أي وقت. إذا قاموا بذلك بعد فوات الأوان وتم إصدار إصدارات مكتبة جديدة ، فسيصبح سد الفجوة عبر المكتبات أمرًا صعبًا بشكل متزايد.
وبالتالي ، في حين أن فريقًا واحدًا يمكنه التكرار بسرعة وفي كثير من الأحيان على الكود الخاص بهم ، فقد تثبت الفرق الأخرى أنها غير قادرة على اللحاق بالركب ، مما يؤدي في النهاية إلى إنشاء مكتبات متباينة.
من ناحية أخرى ، في بيئة monorepo ، لا يمكننا إصدار إصدار جديد من مكتبة واحدة يكسر بعض المكتبات الأخرى لأن اختباراتهم ستفشل. في هذه الحالة ، يجب على الفريق الأول التواصل مع الفريق الثاني لدمج التغييرات.
يجبر هذا النهج الفرق على تكييف جميع المكتبات تمامًا كلما حدث تغيير في مكتبة واحدة. جميع الفرق مجبرة على التحدث مع بعضها البعض والتوصل إلى حل معًا.
هل سئمت من دعم استضافة WordPress من المستوى 1 دون الإجابات؟ جرب فريق الدعم العالمي! تحقق من خططنا
نتيجة لذلك ، لن يكون الفريق الأول قادرًا على التكرار بالسرعة التي يرغبون فيها ، لكن الكود عبر المكتبات المختلفة لن يبدأ في أي نقطة في التباعد.
باختصار ، يمكن أن يساعد نهج إعادة الشراء المتعدد في إنشاء ثقافة “التحرك بسرعة وكسر الأشياء” بين الفرق ، حيث يمكن للفرق المستقلة الذكية إنتاج مخرجاتها بالسرعة التي تناسبها. بدلاً من ذلك ، يفضل نهج monorepo ثقافة الوعي والرعاية ، حيث لا ينبغي ترك الفرق متأخرة للتعامل مع مشكلة بمفردها.
نهج متعدد الهجين
إذا لم نتمكن من تحديد ما إذا كنا سنستخدم إما نهج mult-repo أو monorepo ، فهناك أيضًا طريقة بينية: استخدام مستودعات متعددة واستخدام بعض الأدوات للحفاظ عليها متزامنة ، مما يجعلها تشبه monorepo ولكن بمزيد من المرونة.
ميتا هي واحدة من هذه الأدوات. ينظم مستودعات متعددة ضمن أدلة فرعية ويوفر واجهة سطر أوامر تنفذ نفس الأمر على كل منهم في وقت واحد.
يحتوي مستودع التخزين الفوقي على المعلومات التي تشكل بها المستودعات مشروعًا. سيؤدي استنساخ هذا المستودع عبر meta بعد ذلك إلى استنساخ جميع المستودعات المطلوبة بشكل متكرر ، مما يسهل على أعضاء الفريق الجدد بدء العمل في مشاريعهم على الفور.
لاستنساخ Meta-repository وجميع مستودعاته المتعددة المحددة ، يجب علينا تنفيذ ما يلي:
meta git clone [meta repo url]
ستنفذ Meta git cloneلكل مستودع وتضعه في مجلد فرعي:
من ذلك الحين فصاعدًا ، meta execسيؤدي تنفيذ الأمر إلى تنفيذ الأمر في كل مجلد فرعي. على سبيل المثال ، يتم التنفيذ git checkout masterفي كل مستودع على النحو التالي:
meta exec "git checkout master"
نهج الهجين أحادي البولي
طريقة أخرى هي إدارة الكود عبر monorepo للتطوير ، ولكن نسخ كود كل مكتبة إلى مستودعها المستقل للنشر.
هذه الإستراتيجية سائدة داخل نظام PHP البيئي لأن Packagist ( مستودع Composer الرئيسي ) يتطلب عنوان URL لمستودع عام لنشر حزمة ، ولا يمكن الإشارة إلى أن الحزمة موجودة داخل دليل فرعي من المستودع.
بالنظر إلى قيود Packagist ، لا يزال بإمكان مشاريع PHP استخدام monorepo للتطوير ، ولكن يجب أن تستخدم نهج متعدد الريبو للنشر.
لتحقيق هذا التحويل ، يمكننا تنفيذ برنامج نصي باستخدامgit subtree split أو استخدام إحدى الأدوات المتاحة التي تؤدي نفس المنطق:
بوابة تقسيم الشجرة الفرعية
بوابة فرعية
إجراء GitHub لتقسيم Monorepo
من يستخدم Monorepo مقابل Multi-Repo
تفضل العديد من شركات التكنولوجيا الكبرى نهج monorepo ، بينما قررت شركات أخرى استخدام طريقة الريبو المتعدد.
لقد أيدت كل من Google و Facebook و Twitter و Uber علنًا نهج monorepo. تدير Microsoft أكبر Git monorepo على هذا الكوكب لاستضافة الكود المصدري لنظام التشغيل Windows.
على الجانب الآخر ، تعد Netflix و Amazon و Lyft شركات مشهورة تستخدم نهج الريبو المتعدد.
على الجانب الهجين متعدد الأحادي ، يقوم Android بتحديث مستودعات متعددة ، والتي تتم إدارتها مثل monorepo.
على الجانب الهجين الأحادي والبولي ، يحتفظ Symfony بالشفرة لجميع مكوناته في monorepo. قاموا بتقسيمه إلى مستودعات مستقلة للنشر (مثل symfony/dependency-injectionو symfony/event-dispatcher.)
أمثلة على Monorepo و Multi-Repo
على حساب ورد على جيثب المضيفين أمثلة على كل من monorepo ومتعددة الريبو-النهج.
يتكون Gutenberg ، محرر قوالب WordPress ، من عدة عشرات من حزم JavaScript . يتم استضافة جميع هذه الحزم على WordPress/gutenbergmonorepo وتتم إدارتها من خلال Lerna للمساعدة في نشرها في مستودع npm .
Openverse ، محرك البحث عن وسائل الإعلام المرخص لها علنا، يستضيف أجزائه الرئيسية في مستودعات مستقلة: الأمامية ، كتالوج ، و API .
Monorepo مقابل Multi-Repo: كيف تختار؟
كما هو الحال مع العديد من مشاكل التطوير ، لا توجد إجابة محددة مسبقًا حول النهج الذي يجب عليك استخدامه. ستستفيد الشركات والمشاريع المختلفة من استراتيجية واحدة أو أخرى بناءً على ظروفها الفريدة ، مثل:
ما هو حجم قاعدة الشفرة؟ هل يحتوي على غيغا بايت من البيانات؟
كم عدد الأشخاص الذين سيعملون على قاعدة البيانات؟ هل هي حوالي 10 أم 100 أم 1000؟
كم عدد الحزم سيكون هناك؟ هل هي حوالي 10 أم 100 أم 1000؟
كم عدد الحزم التي يحتاج الفريق للعمل عليها في وقت معين؟
ما مدى إحكام الترابط بين الحزم؟
هل لغات البرمجة المختلفة متضمنة؟ هل تتطلب تثبيت برنامج معين أو أجهزة خاصة للتشغيل؟
كم عدد أدوات النشر المطلوبة ، وما مدى تعقيد إعدادها؟
ما هي الثقافة في الشركة؟ هل يتم تشجيع الفرق على التعاون؟
ما هي الأدوات والتقنيات التي تعرف الفرق كيفية استخدامها؟
ملخص
هناك استراتيجيتان رئيسيتان لاستضافة الكود وإدارته: monorepo vs multi-repo. يستلزم نهج monorepo تخزين الكود للمكتبات أو المشاريع المختلفة – وحتى جميع الرموز من شركة – في مستودع واحد. ويقسم نظام الريبو المتعدد الكود إلى وحدات ، مثل المكتبات أو الخدمات ، ويحافظ على استضافتها في مستودعات مستقلة.
يعتمد أي نهج للاستخدام على العديد من الشروط. لكلتا الاستراتيجيتين مزايا وعيوب عديدة ، وقد غطيناها جميعًا بالتفصيل في هذه المقالة.

