مستودع واحد مع Go: تنظيم الكود للمبتدئين

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

ما هو المستودع الواحد (monorepo) ولماذا هو مفيد في Go؟



المستودع الواحد (monorepo) هو نهج لإدارة الكود يتم فيه تخزين جميع المشاريع والمكتبات والخدمات في مستودع واحد. في نظام Go البيئي، أصبح هذا النهج شائعًا بشكل خاص بفضل الدعم المدمج للوحدات (modules) ومساحات العمل (workspaces).



للمطورين المبتدئين، يوفر المستودع الواحد عدة مزايا رئيسية:

  • إصدار موحد للكود — جميع التبعيات متزامنة
  • إعادة هيكلة مبسطة — التغييرات تظهر فورًا في جميع المشاريع
  • توحيد المعايير — إعدادات موحدة لأدوات التحليل (linters) و CI/CD والاختبارات
  • الشفافية — سهولة فهم كيفية ارتباط الأجزاء المختلفة من النظام


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



الهيكل الأساسي للمستودع الواحد بلغة Go



التنظيم الصحيح للكود هو أساس نجاح المستودع الواحد. دعنا نلقي نظرة على الهيكل النموذجي:



my-monorepo/├── apps/│   ├── web-api/          # التطبيق الرئيسي│   │   ├── main.go│   │   ├── go.mod│   │   └── internal/│   └── worker/           # معالج الخلفية│       ├── main.go│       └── go.mod├── libs/│   ├── config/           # الإعدادات المشتركة│   │   ├── config.go│   │   └── go.mod│   └── logger/           # التسجيل│       ├── logger.go│       └── go.mod├── scripts/              # البرامج النصية المساعدة├── docs/                 # التوثيق├── go.work               # مساحة عمل Go└── README.md


المبادئ الأساسية لهذا الهيكل:

  • apps/ — التطبيقات القابلة للتنفيذ (الملفات الثنائية)
  • libs/ — المكتبات القابلة لإعادة الاستخدام
  • scripts/ — الأتمتة والأدوات المساعدة
  • docs/ — توثيق المشروع


إعداد مساحة عمل Go (Go Workspace) للمستودع الواحد



بدءًا من Go 1.18، أصبح هناك دعم رسمي لمساحات العمل من خلال ملف go.work. يتيح ذلك العمل مع عدة وحدات في وقت واحد دون الحاجة إلى نشرها في مستودع بعيد.



لنقم بإنشاء مساحة عمل لمستودعنا الواحد:



// go.workgo 1.22

use ( ./apps/web-api ./apps/worker ./libs/config ./libs/logger)


بعد إنشاء go.work، ستكون جميع الوحدات من قائمة use متاحة لبعضها البعض محليًا. هذا مناسب بشكل خاص أثناء التطوير — التغييرات في المكتبة تظهر فورًا في التطبيقات.



تهيئة الوحدات



لكل مكون، يجب إنشاء ملف go.mod خاص به. مثال لمكتبة الإعدادات:



// libs/config/go.modmodule github.com/your-org/libs/config

go 1.22


وللتطبيق web-api:



// apps/web-api/go.modmodule github.com/your-org/apps/web-api

go 1.22

require github.com/your-org/libs/config v0.0.0

replace github.com/your-org/libs/config => ../../libs/config


لاحظ استخدام replace — فهو يوجه Go لاستخدام النسخة المحلية من المكتبة بدلاً من البحث عنها على الإنترنت.



مثال كود: مكتبة وتطبيق



لنقم بإنشاء مكتبة بسيطة للإعدادات وتطبيق يستخدمها.



مكتبة libs/config



// libs/config/config.gopackage config

import ( "fmt" "os")

type Config struct { Port string Env string}

func Load() (*Config, error) { port := os.Getenv("PORT") if port == "" { port = "8080" }

env := os.Getenv("ENV") if env == "" { env = "development" }

return &Config{ Port: port, Env: env, }, nil}

func (c *Config) String() string { return fmt.Sprintf("Config{

المدونات

توصيات الكتب