08 سبتمبر 2025·7 دقيقة قراءة

Monorepo مقابل polyrepo: الحفاظ على تزامن الويب والموبايل والباكند

شرح مبسّط لمقارنة monorepo و polyrepo للفرق التي تصدر تطبيقات ويب وموبايل وباكند. قارن إدارة التبعيات، التنسيق عند الإصدار، وتكتيكات CI للبقاء سريعًا.

Monorepo مقابل polyrepo: الحفاظ على تزامن الويب والموبايل والباكند

المشكلة الحقيقية: نشر تغييرات عبر ثلاث قواعد شيفرة

الفرق لا تناقش monorepo مقابل polyrepo لأنهم مهتمون بفلسفة Git. النقاش يأتي لأن تغييرًا منتجًا صغيرًا يتحول إلى ثلاث تغييرات منفصلة عبر الويب والموبايل والباكند، ثم ينهار شيء ما على الطريق.

ما ينكسر أولًا نادرًا ما يكون الواجهة. عادةً ما يكون الغراء غير المرئي: عقدة API تغيّرت بدون تحديث مطابق، مكتبة مشتركة رُفعت في مكان واحد لكن ليس في مكان آخر، أو خط البناء احتاج خطوة جديدة فجأة. عندما يُطلق جزء قبل الآخرين، يشعر المستخدمون به كأخطاء مثل "الزر ظاهر على الويب لكن التطبيق على الموبايل يقول غير مدعوم" أو "التطبيق يحمل إلى الأبد لأن استجابة الباكند تغيرت".

الويب والموبايل والباكند أيضًا تعمل على ساعات إصدار مختلفة. الويب يمكنه النشر عدة مرات في اليوم. الباكند يمكن أن ينشر كثيرًا لكنه يحتاج نشرًا حذرًا. الموبايل أبطأ لأن مراجعة متاجر التطبيقات وتحديثات المستخدمين تضيف تأخيرًا حقيقيًا. تغيير "بسيط" مثل إعادة تسمية حقل يمكن أن يجبرك على التخطيط وفقًا لأبطأ مسار، حتى لو كانت شاشة واحدة فقط هي التي تحتاجه.

أنت على الأرجح تدفع ضريبة تنسيق المستودعات إذا استمرت هذه الأمور في الحدوث:

  • تغييرات API الكاسرة تُكتشف بعد الدمج.
  • محاذاة الإصدارات تعتمد على تذكيرات يدوية وجداول بيانات.
  • ميزة واحدة تحتاج إلى عدة pull requests منسقة تنتظر بعضها البعض.
  • CI بطيء لأنه يبني ويختبر أكثر مما لمسه التغيير فعلاً.
  • التراجع يبدو محفوفًا بالمخاطر لأنه غير واضح أي كوميت يطابق أي إصدار.

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

إذا كان كل تغيير مهم يجب أن يهبط في ثلاث أماكن، فستدفع تلك الضريبة بطريقة ما. استراتيجية المستودعات هي في الغالب عن كيفية رغبتك في دفعها.

أساسيات monorepo و polyrepo بدون مصطلحات معقدة

المستودع هو مجرد مكان يعيش فيه الكود مع تاريخه. عندما لديك ويب، موبايل، وباكند، الاختيار بسيط: اجمع كل شيء معًا، أم فرقّه.

الـ monorepo هو مستودع واحد يحتوي تطبيقات متعددة وغالبًا كودًا مشتركًا أيضًا. الويب، iOS/Android، خدمات الباكند، والمكتبات المشتركة تجلس جنبًا إلى جنب.

الـ polyrepo هو العكس: كل تطبيق (وأحيانًا كل خدمة) له مستودع منفصل. الكود المشترك عادةً يصبح حزمة منفصلة، أو تنسخ الفرق قطعًا صغيرة عند الحاجة.

يوميًا، عادةً ما يشعر الناس بالآتي مع monorepos: مشاركة الكود سهلة، تغييرات عبر التطبيقات يمكن أن تكون في pull request واحد، والقواعد متسقة. المقابل اجتماعي: الملكية يمكن أن تصبح ضبابية ما لم تحدد حدود واضحة، وفحوصات على مستوى المستودع قد تبدو صارمة.

مع polyrepos عادةً ما يشعر الناس أن كل فريق يستطيع التحرك باستقلالية، المستودعات تبقى مركزة، والتحكم في الوصول أبسط. المقابل هو التنسيق: مشاركة الكود تحتاج تخطيطًا، وتغييرات عبر التطبيقات غالبًا ما تصبح عدة pull requests مع توقيت دقيق.

ينتهي الأمر بالعديد من الفرق إلى حل هجين: تطبيقات في مستودعات منفصلة، العقود المشتركة في مكان واحد؛ أو monorepo واحد بحدود قوية بحيث يبقى كل فريق في منطقته معظم الوقت.

إذا استخدمت منصة تولّد الباكند والويب والموبايل من مصدر واحد للحقيقة، فأنت تقلل الانحراف لأن العقود والمنطق تعيش معًا. AppMaster، على سبيل المثال، يولّد backends وويب وتطبيقات موبايل أصلية جاهزة للإنتاج من نموذج واحد. هذا لا يلغي حقائق الإصدارات (الموبايل لا يزال يُطلق أبطأ)، لكنه يمكن أن يقضي على الكثير من سؤال "هل حدثنا الثلاثة؟".

إدارة التبعيات: الحفاظ على الكود المشترك آمنًا

الكود المشترك هو المكان الذي تضيع فيه الفرق الوقت، بغض النظر عن تخطيط المستودعات. تغيير صغير في مكتبة مشتركة أو عقد API يمكن أن يكسر بناء الويب، أو إصدارات الموبايل، أو نشرات الباكند بطرق مختلفة.

عند مشاركة مكتبات (مكونات واجهة، قواعد تحقق، مساعدي المصادقة)، تختار بين نسخة واحدة للجميع أو إصدارات متعددة مع مرور الزمن.

  • نسخة واحدة أبسط وتتجنب مفاجآت "يعمل على فرعي".
  • إصدارات متعددة تسمح للفرق بالتحرك بوتيرة خاصة، لكنها تخلق فوضى وتجعل تصحيحات الأمان أصعب للتوزيع.

عملاء الـ API والمخططات يستحقون عناية إضافية. التحديثات اليدوية بطيئة وعرضة للخطأ. نمط أفضل هو اعتبار مخطط الـ API مصدر الحقيقة وتوليد العملاء منه، ثم إما تسجيلهم في المستودع أو توليدهم في CI. الهدف هو الفشل المبكر: إذا أضاف الباكند حقلًا مطلوبًا، يجب أن يتعطل بناء الموبايل، لا أن يظهر الخطأ بعد ثلاثة أيام في QA.

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

مثال ملموس: الباكند يعيد تسمية status إلى state. إذا حدث وحدث التحديث في الويب اليوم لكن الموبايل لا يستطيع الشحن لأسبوع، على الباكند قبول الحقلين خلال ذلك الأسبوع، أو شحن محول يربط الحقل القديم بالجديد.

بعض القواعد التي تجعل تحديثات التبعيات مملة (بشكل جيد):

  • حدّث وفق إيقاع. تحديثات صغيرة أسبوعية أفضل من تحديثات ربع سنوية ضخمة.
  • اشترط موافقة صريحة على التغييرات الكاسرة، مع ملاحظة ترحيل قصيرة.
  • أتمت الفحوصات: ترقيعات التبعيات، إعادة توليد العملاء، واختبارات العقود الأساسية.
  • عرّف "المكتمل" على أنه "ويب، موبايل، وباكند يبنون بنجاح"، لا "مستوديعي يعمل".

الكود المولَّد يمكن أن يقلل الانحراف، لكنه لا يحل محل الانضباط. ما زلت بحاجة لعقد واحد، إعلانات عدم الاستخدام واضحة، وتحديثات متوقعة.

تنسيق الإصدارات: مواءمة الويب والموبايل والباكند

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

الهدف العملي بسيط: يجب أن تعمل فعلية المستخدم مهما اختلف ترتيب النشر. هذا يعني التخطيط لحالات الإصدارات المختلطة، وعدم افتراض تزامن مثالي.

أنماط إصدار تستخدمها الفرق عمليًا

معظم الفرق تستقر على أحد هذه الأساليب:

  1. قطار إصدار مشترك واحد: الويب والموبايل والباكند يُنشرون كوحدة مُؤشرة واحدة.

  2. إصدارات لكل خدمة مع قواعد توافق: لكل تطبيق/خدمة إصدارها الخاص، والباكند يدعم نطاقًا معرفًا من إصدارات العملاء.

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

تأخيرات الموبايل تغير أيضًا كيفية التعامل مع الإصلاحات العاجلة. إصلاحات الباكند يمكن أن تخرج سريعًا؛ إصلاحات الموبايل قد لا تصل المستخدمين لأيام. فضّل إصلاحات الخادم التي تبقي بنايات الموبايل القديمة تعمل. عندما يجب تغيير العميل، استخدم feature flags وتجنب إزالة الحقول القديمة حتى تتأكد أن معظم المستخدمين حدثوا.

مثال: تضيف "تعليمات التوصيل" إلى عملية الطلب. يضيف الباكند حقلًا اختياريًا جديدًا، الويب يعرضه فورًا، والموبايل يعرضه في السبرينت التالي. إذا قبل الباكند الطلبات القديمة وبقي الحقل اختياريًا، يستمر كل شيء في العمل بينما يلحق الموبايل.

من يملك تقويم الإصدارات

يفشل التنسيق عندما "الجميع يملكه"، فلا أحد يملكه فعليًا. المالك قد يكون قائدًا تقنيًا، مدير إصدار، أو مدير منتج بدعم هندسي قوي. مهمتهم منع المفاجآت بجعل توقعات الإصدار مرئية ومتسقة.

لا يحتاجون إلى عملية معقدة. يحتاجون إلى عادات متكررة: تقويم إصدار بسيط مع مواعيد نهائية ونوافذ تجميد، فحص سريع عبر الفرق قبل نشر تغييرات API، وخطة واضحة لما يحدث عند تأخر الموبايل (توقّف الباكند أم الحفاظ على التوافق).

حتى لو كان سير عملك يولد الويب والموبايل والباكند معًا من نموذج واحد، فإنك ما زلت بحاجة إلى مالك إصدار. غالبًا سيكون لديك لحظات أقل من "هل حدثنا الثلاثة؟"، لكنك لن تهرب من توقيت الموبايل.

إبقاء وقت CI تحت السيطرة

Spin up an internal tool
ابدأ بالمصادقة وانشئ أداة داخلية آمنة دون جمع عدة مستودعات.
أضف المصادقة

يتباطأ CI لنفس الأسباب في كلا النمطين: تعيد بناء أكثر من اللازم، تعيد تثبيت التبعيات مرارًا، وتشغّل كل اختبار على كل تغيير.

من قاتلات الوقت الشائعة: بناء كامل على تغييرات صغيرة، فقدان الكاش، اختبارات تجري كل شيء، ووظائف متسلسلة يمكن أن تعمل متوازية.

ابدأ بتحسينات تفيد الجميع:

  • خزّن تنزيلات التبعيات ومخرجات البناء في الكاش.
  • شغل lint، اختبارات الوحدة، والبناء بالتوازي حيثما أمكن.
  • فرّق الفحوصات السريعة (لكل كوميت) عن الفحوصات الأبطأ (الفرع الرئيسي، ليليًا، أو قبل الإصدار).

تكتيكات monorepo المساعدة

تُصبح monorepos مؤلمة عندما يؤدي كل كوميت إلى خط أنابيب "ابنِ العالم". الحل هو بناء واختبار فقط ما تأثّر بالتغيير.

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

تكتيكات polyrepo لمنع الانحراف

polyrepos يمكن أن تكون سريعة لأن كل مستودع أصغر، لكنها تهدر الوقت عبر التكرار وأدوات مختلفة.

حافظ على مجموعة مشتركة من قوالب CI (نفس الخطوات، نفس الكاشات، نفس الاتفاقيات) حتى لا يعيد كل مستودع اختراع الأداة. ثبّت سلاسل الأدوات (إصدارات runtime، أدوات البناء، linters) لتجنب مفاجآت "يعمل في مستودع واحد". إذا كانت تنزيلات التبعيات عنق زجاجة، جهّز كاشات مشتركة أو مرايا داخلية حتى لا يسحب كل مستودع العالم من الصفر.

مثال ملموس: ميزة تضيف حقل "status" جديد. يغير الباكند، الويب يعرضه، الموبايل يعرضه. في monorepo، يجب أن يشغل CI اختبارات الباكند بالإضافة إلى الأجزاء من الويب والموبايل التي تعتمد على عميل الـ API فقط. في polyrepo، يجب أن يشغل كل مستودع فحوصاته السريعة، وأن يكون هناك خط تكامل منفصل يتحقق من أن الإصدارات الثلاث ما زالت متوافقة.

إذا صدّرت الشيفرة المصدرية وشغّلت CI خاصًا بك، نفس القاعدة تنطبق: ابنِ فقط ما تغيّر، أعد استخدام الكاشات بشكل مكثف، واحتفظ بالفحوصات البطيئة للمواقف التي تضيف قيمة حقيقية.

خطوة بخطوة: اختر استراتيجية مستودعات تناسب فريقك

Choose your deployment path
انشر على AppMaster Cloud أو على AWS أو Azure أو Google Cloud الخاصة بك عندما تكون جاهزًا.
انشر الآن

يصير القرار أسهل عندما تبدأ من عملك اليومي بدلًا من الأيديولوجيا.

1) اكتب ما يجب أن يتغير معًا

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

2) تتبع الكود والقرارات المشتركة

الكود المشترك ليس فقط المكتبات؛ هو العقود (مخططات API)، أنماط الواجهة، وقواعد العمل. سجّل أين توجد الآن، من يحررها، وكيف تُصادق التغييرات. إذا كانت الأجزاء المشتركة تُنسخ بين المستودعات، فهذه علامة أنك تحتاج للتحكم الأشد، إما عبر monorepo أو قواعد إصدار صارمة.

3) عرّف الحدود والمالكين

قرّر ما هي الوحدات (تطبيقات، خدمات، مكتبات)، ثم عين مالكًا لكل وحدة. الحدود أهم من تخطيط المستودعات. بدون مالكين، يصبح monorepo صاخبًا. بدون مالكين، يصبح polyrepo منفصلًا.

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

4) اختر نموذج إصدار يمكنك الالتزام به

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

اجعل قواعد التفريعات مملة: تفريعات قصيرة العمر، دمج صغير، ومسار إصلاح عادل.

5) صمّم CI حول التغييرات الشائعة

لا تصمم CI لأسوأ حالة من اليوم الأول. صممه لما يفعله الناس كل يوم.

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

مثال: ميزة واحدة تمس الويب والموبايل والباكند

تخيّل فريقًا صغيرًا يبني ثلاث أشياء: بوابة العملاء (ويب)، تطبيق ميداني (موبايل)، وواجهة برمجية (باكند). يأتي طلب: أضف حقل "Service status" للوظائف وعرضه في كل مكان.

التغيير يبدو صغيرًا لكنه اختبار للتنسيق. الباكند يضيف الحقل ويحدّث التحقق والاستجابات. الويب يعرضه ويحدّث عوامل التصفية. الموبايل يحتاج عرضه دون اتصال، ومزامنته، والتعامل مع الحالات الحافة.

الآن المشكلة الحقيقية: تغيير الـ API كاسر. اسم الحقل تغير من status إلى service_status، والعميلات القديمة تنهار إن لم تتعامل مع ذلك.

ماذا يغيّر monorepo

هنا غالبًا ما يبدو monorepo أكثر هدوءًا. تحديثات الباكند والويب والموبايل يمكن أن تُدخل في pull request واحد (أو مجموعة من الالتزامات المنسقة). يمكن لـ CI تشغيل الاختبارات المتأثرة، ويمكنك وسم إصدار واحد يحتوي التحديثات الثلاثة.

الخطر الرئيسي اجتماعي، ليس تقني: مستودع واحد يجعل الدمج لتغيير كاسر سهلًا، لذا يجب أن تكون قواعد المراجعة قوية.

ماذا يغيّر polyrepo

مع المستودعات المنفصلة، كل تطبيق يعيش على جدولته الخاصة. قد ينشر الباكند أولًا، ويبذل الويب والموبايل جهداً للحاق. إذا كانت إصدارات الموبايل تتطلب مراجعة متجر التطبيقات، يمكن أن يستغرق "الإصلاح" أيامًا حتى لو كانت الشيفرة صغيرة.

تحل الفرق ذلك عادةً ببنى أكثر تنظيمًا: نقاط نهاية مرقمة، استجابات متوافقة للخلف، نوافذ إيقاف أطول، وخطوات طرح أوضح. هذا يعمل، لكنه عمل مستمر.

إذا كنت تقرر بناءً على الأدلة، انظر لآخر بضعة أشهر:

  • إذا كانت الحوادث غالبًا من نسخ غير متطابقة، فضّل تنسيقًا أقوى.
  • إذا كانت الإصدارات متكررة وحساسة للوقت (خاصة الموبايل)، تجنّب التغييرات الكاسرة أو مركزها.
  • إذا كانت الفرق مستقلة ونادرًا ما تلمس نفس الميزة، فقد تكون تكلفة polyrepo مجزية.

أخطاء شائعة وفخاخ تجنبها

Design once, use everywhere
صمم واجهات الويب والموبايل في مكان واحد حتى لا تتحول تغييرات صغيرة في الواجهة إلى ثلاث مهام.
ابنِ الواجهة

معظم الفرق لا تفشل لأنهم اختاروا بنية "خاطئة" للمستودع. يفشلون لأن العادات اليومية تضيف احتكاكًا ببطء حتى يصبح كل تغيير محفوفًا بالمخاطر.

الكود المشترك يصبح مقبرة

المكتبة المشتركة مغرية: Helpers، Types، أجزاء واجهة، حلول مؤقتة. سرعان ما تصبح المكان الذي تذهب إليه الشيفرة القديمة لتموت، ولا أحد يعرف ما الآمن تغييره.

اجعل الكود المشترك صغيرًا وصارمًا. "مشترك" يجب أن يعني مستخدمًا من فرق كثيرة، ومراجعته بعناية، وتغييره بنية.

تقييد بسبب افتراضات مخفية

حتى في مستودعات منفصلة، يمكن للأنظمة أن تتشابك بقوة. الانتقال فقط يتحول إلى افتراضات: صيغ التواريخ، قيم enum، قواعد الأذونات، و"هذا الحقل موجود دائمًا".

مثال: الموبايل يعتبر status = 2 "مقبول"، الويب يعتبره "مؤكد"، يغيّر الباكند ترتيب enum، وينكسر كل شيء بطريقة تبدو عشوائية.

منع ذلك بتوثيق العقود (ماذا يعني كل حقل، وما القيم المسموحة) ومعاملتها كقواعد منتج، لا كتفاصيل ثانوية.

ملكية غير واضحة

عندما يمكن للجميع تغيير أي شيء، تصير المراجعات سطحية وتدخل الأخطاء. عندما لا يملك أحد منطقة ما، تبقى الأخطاء أسابيع.

حدد ملاكًا للويب، الموبايل، الباكند، والوحدات المشتركة. الملكية لا تمنع المساهمة؛ إنها تضمن أن التغييرات تصل للأعين الصحيحة.

CI يكبر بلا تنظيف

يبدأ CI صغيرًا، ثم تضيف كل حادثة وظيفة "لأجل الأمان". بعد شهور، يصبح بطيئًا ومكلفًا، ويبتعد الناس عنه.

قاعدة بسيطة: كل وظيفة CI يجب أن يكون لها هدف واضح ومالك، ويجب إزالتها إذا توقفت عن الكشف عن مشاكل حقيقية.

علامات التحذير تشمل اختبارات مكررة عبر وظائف، وظائف تبقى حمراء لأيام، "تغييرات سريعة" تستغرق للتحقق أكثر مما تستغرق للبناء، وأنابيب تبني تطبيق الموبايل على تغييرات باكند فقط.

تنسيق الإصدارات يعتمد على معرفة قبلية

إذا كانت الإصدارات تعتمد على شخص واحد يتذكّر الترتيب والحيل السرية، ستبطئ وتنكسر أكثر.

دوّن خطوات الإصدار، اجعلها قابلة للتكرار، وأتمت الفحوصات المملة. حتى لو كان أداتك تولد backends وعملاء متناسقين، تحتاج قواعد إصدار واضحة.

فحوصات سريعة قبل الالتزام بالـ monorepo أو polyrepo

Test monorepo-like workflow
جرّب تدفق عمل يشبه monorepo وشاهد مدى تسارع المراجعة والاختبار.
أنشئ مشروعًا

قبل إعادة تنظيم المستودعات، تحقق من واقع كيفية شحن فريقك اليوم. الهدف ليس بنية مثالية، بل تقليل المفاجآت عندما يلمس تغيير الويب والموبايل والباكند.

اطرح خمسة أسئلة:

  • الاستقلالية في الشحن: هل يمكنك إصدار إصلاح باكند بدون إجبار تحديث تطبيق الموبايل في نفس اليوم؟
  • قواعد تغيير الـ API: هل لديك عقد مكتوب للاستهلاك ومدة بقاء السلوك القديم مدعومًا؟
  • انضباط الكود المشترك: هل تُراجع وتُؤشر المكتبات المشتركة باستمرار؟
  • CI يشغّل ما يهم: هل يستطيع CI تحديد ما تغيّر وتشغيل البناء/الاختبارات فقط للأجزاء المتأثرة؟
  • عرض واحد للإصدار: هل هناك مكان واحد لرؤية ما سيخرج عبر الويب والموبايل والباكند مع ملاك وتواريخ؟

مثال بسيط: يضاف حقل "address" لصفحة الدفع. إذا نشر الباكند أولًا، يجب أن يظل تطبيق الموبايل القديم يعمل. عادةً يعني ذلك أن الـ API يقبل كلا الحمولة القديمة والجديدة لفترة، وتحديثات العميل اختيارية وليست إجبارية.

الخطوات التالية: خفّض عبء التنسيق واطرح بثقة

الهدف ليس بنية المستودع "الصحيحة". الهدف أقل تسليمات بين الفرق، مفاجآت أقل، ولحظات "انتظر، أي إصدار حي؟" أقل.

اكتب سجل قرار قصير: لماذا اخترت نهجك الحالي، ما الذي تتوقع تحسينه، وما التنازلات التي تقبلها. راجع القرار كل 6-12 شهرًا، أو أبكر إذا تغير حجم الفريق أو إيقاع الإصدارات.

قبل نقل الملفات، اختر أصغر تغيير يزيل ألمًا حقيقيًا:

  • أضف واتبع قواعد إصدار للحزم المشتركة.
  • عرّف عقود API وأجبِر عليها باختبارات عقود في CI.
  • اتفق على قائمة مراجعة إصدار واحدة عبر الويب والموبايل والباكند.
  • استخدم بيئات معاينة للتغييرات التي تمس عدة أجزاء.
  • حدّدت ميزانيات زمنية لـ CI (مثلاً: فحوصات PR تحت 15 دقيقة).

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

إذا أردت استكشاف هذا النهج، AppMaster (appmaster.io) مبنية لتوليد خدمات الباكند، تطبيقات الويب، وتطبيقات الموبايل الأصلية بنماذج بيانات وقواعد عمل مشتركة. طريقة منخفضة المخاطر للتقييم هي بناء أداة داخلية صغيرة أولًا، ثم تقرير بناءً على مقدار عمل التنسيق الذي تزيله.

الطريق الواثق ممل عمدًا: دوّن القرار، قلّل الترابط، أتمت الفحوصات، وغيّر بنية المستودعات فقط عندما تُظهر الأرقام أنها ستساعد.

الأسئلة الشائعة

How do I decide between a monorepo and a polyrepo for web, mobile, and backend?

ابدأ من مدى تكرار اضطرار ميزة واحدة لإحداث تغييرات في الويب والموبايل والباكند. إذا كانت معظم الأعمال عابرة للمنصات وكان التنسيق هو ألمك الرئيسي، فغالبًا ما يقلل monorepo أو نهج “عقدة واحدة” قوي من انكسارات التوافق. إذا كانت الفرق نادراً ما تتداخل وتحتاج إلى وصول واستقلالية في الإصدار، فـ polyrepo يمكن أن يكون مناسبًا مع قواعد توافق صارمة.

What usually causes the “everything broke after a small change” problem?

الانحراف في الـ API، عدم تطابق إصدارات المكتبات المشتركة، واختلاف توقيت الإصدارات (خاصة تأخيرات متاجر التطبيقات للموبايل) هي الأسباب الشائعة. الحل هو التخطيط لحالات وجود إصدارات مختلطة في العالم الحقيقي وعدم افتراض إصدارات متزامنة تمامًا، وجعل التغييرات المعرِّضة نادرة ومتعمدة.

What’s the safest way to manage API contracts across web and mobile?

عامل مخطط الـ API كمصدر الحقيقة وولّد العملاء (clients) منه حتى يفشل التوافق أثناء البناء بدلًا من أن يظهر في الـ QA أو الإنتاج. فضّل الإضافات أولاً، ثم أعلن عن الاستهلاك القديم لاحقًا، وحدد نافذة توافق قصيرة عند الضرورة لتغيير اسم أو إزالة حقل.

How should we handle shared libraries without creating a mess?

استهدف تحديثات صغيرة ومنتظمة وفق جداول (التحديث الأسبوعي أفضل من ربع سنوي) واطلب موافقة صريحة على تغييرات الكسر. أضف ملاحظة ترحيل قصيرة مع كل تغيير وعرّف "المكتمل" على أنه "ويب وموبايل وباكند يبنون بنجاح"، لا مجرد مستودع واحد ينجح.

Should we ship everything on one shared version or let each part version independently?

الافضل عادةً هو إصدار كل جزء منفردًا مع قاعدة توافق واضحة: أي إصدارات الباكند تدعم أي إصدارات العميل، ولمدة كم. قطار الإصدار المشترك يعمل في المراحل المبكرة، لكن تأخيرات الموبايل تجعله مؤلمًا ما لم يكن المنتج قادرًا على الانتظار لإيقاف التوزيع حتى موافقة متجر التطبيقات.

How do we avoid breaking mobile users when the backend ships first?

حافظ على الباكند متوافقًا حتى تظل نسخ الموبايل القديمة تعمل بينما يتم التحديث. استخدم حقولًا إضافية بدل إزالتها، لا تزيل السلوك القديم مبكرًا، واعتمد على feature flags عندما تحتاج لطرح تغييرات مرئية للعميل تدريجيًا.

Who should own release coordination across web, mobile, and backend?

عيّن مسؤولًا صريحًا—قد يكون قائد تقني، مدير إصدار، أو مالك منتج بدعم هندسي—ليحافظ على تقويم إصدارات بسيط وقواعد قرار واضحة عند التأخير (إيقاف التغيير أم الحفاظ على التوافق). الهدف هو ممارسات قابلة للتكرار، وليس عملية معقدة.

What’s the best first step to reduce CI time without changing repo structure?

افترض البناء والاختبار فقط لما تغيّر، واخزن كل شيء يمكن تخزينه. فرّق بين الفحوصات السريعة (لكل كوميت) والفحوصات البطيئة (الفرع الرئيسي، ليليًا، أو قبل الإصدارات) حتى يحصل المطورون على ملاحظات سريعة دون دفع تكلفة الاختبار الكاملة في كل مرة.

How do monorepos keep CI from becoming “build the world” on every commit?

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

How do polyrepos avoid drift and inconsistent pipelines across teams?

وحد الأدوات وقوالب CI عبر المستودعات حتى لا يعيد كل واحد اختراع نفس الخطوات والـ caches والاتفاقيات. أضف فحص تكاملي يتحقق من العقود الرئيسية عبر الإصدارات وثبت إصدارات الأدوات لتجنب مفاجآت "يعمل في مستودع واحد فقط".

من السهل أن تبدأ
أنشئ شيئًا رائعًا

تجربة مع AppMaster مع خطة مجانية.
عندما تكون جاهزًا ، يمكنك اختيار الاشتراك المناسب.

البدء