مقدمة: ما هو المستودع الواحد ولماذا يحتاجه مطور PHP؟
غالبًا ما يواجه تطوير مشاريع PHP الكبيرة مشكلة تنظيم الكود. يؤدي النهج التقليدي باستخدام مستودعات منفصلة لكل مكون (مكتبات، خدمات مصغرة، واجهة أمامية) إلى التجزئة، وتكرار التبعيات، وصعوبات في إعادة الهيكلة. البديل هو المستودع الواحد - وهو مستودع واحد يحتوي على جميع المشاريع والحزم ذات الصلة.
في هذه المقالة، سنشرح عمليًا كيفية تنظيم مستودع واحد لمشروع PHP. ستتعلم كيفية إعداد Composer، وهيكلة المجلدات، وإدارة التبعيات، وتنظيم CI/CD. المقال موجه لمطوري PHP من المستوى المتوسط، الملمين بأساسيات Git و Composer.
المزايا الرئيسية للمستودع الواحد:
- سجل تغييرات موحد وإرسالات ذرية
- سهولة إعادة هيكلة التبعيات المشتركة
- أدوات وتكوينات موحدة
- تبسيط CI/CD من خلال خط أنابيب واحد
هيكل المستودع الواحد: اختيار البنية الصحيحة
العنصر الأساسي للمستودع الواحد الناجح هو هيكل مجلدات مدروس جيدًا. لمشاريع PHP، نوصي بالنموذج التالي، القائم على التقسيم إلى حزم وتطبيقات:
monorepo/├── apps/ # التطبيقات الجاهزة (مواقع الويب، API، نصوص الأوامر)│ ├── api/ # REST API باستخدام Slim أو Laravel│ │ ├── public/│ │ ├── src/│ │ └── composer.json│ └── admin/ # لوحة الإدارة│ ├── public/│ ├── src/│ └── composer.json├── packages/ # حزم PHP قابلة لإعادة الاستخدام (مكتبات)│ ├── core/ # نواة النظام: الفئات الأساسية، الاستثناءات│ │ ├── src/│ │ └── composer.json│ ├── users/ # حزمة إدارة المستخدمين│ │ ├── src/│ │ └── composer.json│ └── payments/ # حزمة الدفع│ ├── src/│ └── composer.json├── tools/ # نصوص البناء والمساعدة├── tests/ # اختبارات التكامل و E2E للمشروع بأكمله├── composer.json # البيان الجذري (عادةً "type": "project")├── composer.lock├── phpstan.neon├── phpunit.xml.dist└── .gitignoreكل حزمة في packages/ هي مكتبة Composer مستقلة مع ملف composer.json الخاص بها. التطبيقات في apps/ تقوم بتوصيل هذه الحزم كتبعيات محلية. يسمح هذا الهيكل بما يلي:
- عزل المنطق واختبار الحزم بشكل مستقل
- استخدام الكتابة الصارمة والتحميل التلقائي PSR-4
- إعادة استخدام الكود بين التطبيقات المختلفة دون نسخ
إعداد Composer للعمل مع المستودع الواحد
Composer هو الأداة الرئيسية لإدارة التبعيات في PHP. للعمل مع المستودع الواحد، نستخدم آليتين رئيسيتين: المسارات المحلية (path) و البيان الجذري.
الخطوة 1: ملف composer.json الجذري
في جذر المشروع، نقوم بإنشاء بيان أدنى يحدد أن هذا مستودع واحد:
{ "name": "mycompany/monorepo", "type": "project", "require": { "php": "^8.1" }, "autoload": { "psr-4": { "MyCompany\\\\": "packages/" } }, "scripts": { "test": "phpunit", "phpstan": "phpstan analyse" }}الخطوة 2: التبعيات المحلية في الحزم
يجب أن تحتوي كل حزمة في packages/users/ على ملف composer.json الخاص بها. على سبيل المثال:
{ "name": "mycompany/users", "type": "library", "require": { "php": "^8.1", "mycompany/core": "*" }, "autoload": { "psr-4": { "MyCompany\\\\Users\\\\": "src/" } }}