Menu
flag Ar iconالعربيةdown icon

go mod init ووحدات Go: go.mod وgo get وgo mod tidy

كيف تعمل وحدات Go (modules): إنشاء وحدة بـ go mod init، اختيار مسار الوحدة، إضافة الاعتماديات بـ go get، التنظيف بـ go mod tidy، الغرض من go.sum، وreplace للتطوير المحلي.

تحتوي هذه الصفحة على محررات قابلة للتشغيل - حرّر، شغّل، وشاهد النتيجة فوراً.

الوحدة (module) شجرة مجلدات من حزم Go في جذرها ملف go.mod. يسمّي go.mod الوحدة ويسرد إصدارات كل وحدة أخرى تعتمد عليها. تنشئ وحدة بـ go mod init:

mkdir myapp
cd myapp
go mod init example.com/myapp
go: creating new go.mod: module example.com/myapp

ملف go.mod الناتج:

module example.com/myapp

go 1.24.5

هذا يكفي للبناء. كل مشروع Go منذ Go 1.16 وحدة، وترفض go build وgo run . وgo test العمل دونها:

go: go.mod file not found in current directory or any parent directory; see 'go help modules'

اختيار مسار الوحدة

مسار الوحدة بادئة كل مسار استيراد داخلها. مع الوحدة example.com/myapp تُستورد الحزمة الموجودة في المجلد internal/store بالمسار example.com/myapp/internal/store.

الحالةمسار الوحدة
شيفرة مستضافة على GitHub قد يستوردها آخرونgithub.com/yourname/project
شيفرة شركتكyourcompany.com/project أو عنوان المستودع
برنامج خاص أو تمرينexample.com/myapp أو myapp فقط
الإصدار 2 أو ما بعده من وحدة منشورةgithub.com/yourname/project/v2

في المكتبة يجب أن يطابق المسار مكان وجود الشيفرة، لأن go get يستخدمه لإيجاد المستودع. أما في برنامج تشغّله أنت وحدك فالمسار مجرّد اسم. تجنّب كلمة واحدة تطابق حزمة من المكتبة القياسية، مثل go mod init fmt أو go mod init strings: يفشل البناء عندها برسالة ambiguous import: found package fmt in multiple modules.

تشغيل go mod init دون وسيط يفشل خارج تخطيط GOPATH القديم:

go: cannot determine module path for source directory /home/ana/myapp (outside GOPATH, module path must be specified)

أعطه مسارًا.

إضافة الاعتماديات

اكتب الاستيراد، ثم دع Go يجلبه. لنفترض أن main.go يستورد github.com/google/uuid. البناء قبل أن تعرف الوحدة به يعطي تعليمات واضحة:

main.go:6:2: no required module provides package github.com/google/uuid; to add it:
	go get github.com/google/uuid

أي من الأمرين يصلح ذلك:

go get github.com/google/uuid
# or, to sync go.mod with every import in the module:
go mod tidy

يبلغ go get عمّا غيّره:

go: downloading github.com/google/uuid v1.6.0
go: added github.com/google/uuid v1.6.0

ويبلغ go mod tidy عن طريقة حلّه للاستيراد:

go: finding module for package github.com/google/uuid
go: downloading github.com/google/uuid v1.6.0
go: found github.com/google/uuid in github.com/google/uuid v1.6.0

صار في go.mod سطر require:

module example.com/myapp

go 1.24.5

require github.com/google/uuid v1.6.0

go get مع الإصدارات

الأمرالأثر
go get pkgإضافة pkg بآخر إصدار له، أو الإبقاء على الإصدار الحالي إن كان مطلوبًا مسبقًا
go get pkg@v1.5.0استخدام v1.5.0 بالضبط (ترقية أو تخفيض)
go get pkg@latestالانتقال إلى آخر إصدار
go get pkg@abc1234استخدام commit محدّد (يُسجَّل كإصدار زائف)
go get -u ./...ترقية كل اعتمادية إلى آخر إصدار فرعي أو تصحيحي
go get -u=patch ./...الترقية إلى آخر الإصدارات التصحيحية فقط
go get pkg@noneإزالة المتطلّب
go get go@1.24رفع الحد الأدنى لإصدار Go في الوحدة

يغيّر go get ملف go.mod. ولم يعد يبني البرامج أو يثبّتها؛ فمنذ Go 1.18 هذه وظيفة go install pkg@version.

الاعتماديات غير المباشرة

المتطلّبات الموسومة بـ // indirect وحدات لا تستوردها شيفرتك مباشرة لكن البناء يحتاجها. منذ Go 1.17 يسرد go.mod كل وحدة توفّر حزمة للبناء، فتظهر اعتماديات اعتمادياتك هنا مع هذه العلامة. يدير go mod tidy هذه العلامات؛ ولا تضيفها بنفسك.

go mod tidy

شغّل go mod tidy كلما أضفت استيرادات أو أزلتها. فهو:

  • يضيف متطلّبات للحزم المستوردة الناقصة،
  • يزيل المتطلّبات التي لم يعد يستوردها شيء،
  • يضيف مدخلات go.sum التي يحتاجها البناء ويحذف القديمة.

يفحص كل حزمة في الوحدة، بما في ذلك الاختبارات وكل تركيبات وسوم البناء، فيُبقي أحيانًا على اعتمادية لا تراها مستخدمة على منصّتك. تشغيل go mod tidy قبل كل commit، والتحقّق في CI من أنه لا ينتج أي فرق، يُبقي go.mod صادقًا.

go.sum

يسجّل go.sum بصمة لكل إصدار وحدة يستخدمه البناء:

github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=

السطر الأول بصمة ملفات الوحدة، والثاني بصمة go.mod الخاص بها فقط. عندما ينزّل الأمر go وحدة يطابق البصمة مع go.sum ومع قاعدة بيانات البصمات العامة (sum.golang.org)، فيفشل البناء إذا عُبث بإصدار أو تغيّر بصمت. ارفع go.sum بجوار go.mod، ولا تعدّله يدويًا أبدًا.

كيف تختار Go الإصدارات

تستخدم Go اختيار الإصدار الأدنى (minimal version selection). تسرد كل وحدة الحد الأدنى من إصدار كل اعتمادية تحتاجها، ويستخدم البناء أعلى هذه الحدود الدنيا، ولا شيء أحدث منها أبدًا. إذا تطلّبت وحدتك uuid v1.5.0 وتطلّبت اعتمادية uuid v1.6.0، يستخدم البناء v1.6.0 حتى لو كان v1.7.0 موجودًا. لا شيء يُرقّى ما لم يطلب أحد ذلك بـ go get.

النتيجة أن البناء قابل للتكرار دون ملف قفل: go.mod مع رسم الاعتماديات يحدّدان كل إصدار بالكامل. يطبع go list -m all النتيجة:

go list -m all
example.com/myapp
github.com/google/uuid v1.6.0

الإصدارات الرئيسية

الوحدة في الإصدار v2 أو ما فوقه يجب أن يتضمّن مسارها رقم الإصدار الرئيسي: github.com/yourname/project/v2. ويتغيّر مسار الاستيراد معه، فتكون project وproject/v2 وحدتين مختلفتين يمكن أن تجتمعا في بناء واحد. هذه قاعدة Go للتغييرات الكاسرة، ولهذا ترى استيرادات مثل github.com/jackc/pgx/v5.

replace: العمل على اعتمادية محليًا

لاختبار تغييرات على اعتمادية قبل نشرها، وجّه مسارها إلى مجلد محلي:

module example.com/myapp

go 1.24.5

require example.com/mylib v1.2.0

replace example.com/mylib => ../mylib

أو من سطر الأوامر:

go mod edit -replace example.com/mylib=../mylib
go mod tidy

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

لتعديل عدة وحدات معًا دون المساس بملفات go.mod الخاصة بها، أضافت Go 1.18 مساحات العمل (workspaces):

go work init . ../mylib

يكتب هذا ملف go.work يجعل mylib المحلية تتقدّم. أبقِ go.work خارج نظام التحكّم بالإصدارات ما لم يستخدم الفريق كله التخطيط نفسه.

اعتماديات الأدوات (Go 1.24)

أضافت Go 1.24 التوجيه tool، فصار بالإمكان تثبيت إصدارات مولّدات الشيفرة وأدوات الفحص في go.mod بدل تثبيتها على مستوى النظام:

go get -tool golang.org/x/tools/cmd/stringer
go tool stringer -type=Color

func init شيء آخر

عمليات البحث عن "golang init" تقصد غالبًا الدالة init، التي لا علاقة لها بـ go mod init. يمكن لأي حزمة تعريف func init(). لا تأخذ وسائط، ولا يمكن لشيفرتك استدعاؤها، وتُنفَّذ مرة واحدة تلقائيًا بعد ضبط متغيّرات الحزمة وقبل main:

يمكن أن يحتوي ملف واحد على عدة دوال init، وتُنفَّذ بترتيب ظهورها. الحزم المستوردة تنهي تهيئتها أولًا. أبقِ init صغيرة: العمل الذي قد يفشل أسهل في المعالجة والاختبار كدالة عادية تُستدعى من main.

الوحدات الخاصة والوسطاء

افتراضيًا ينزّل go الوحدات عبر proxy.golang.org. لا يرى هذا الوسيط المستودعات الخاصة، فأخبر Go بالمسارات الخاصة:

go env -w GOPRIVATE=github.com/yourcompany/*

تُجلب الوحدات المطابقة لـ GOPRIVATE مباشرة من المستودع ببيانات اعتماد git الخاصة بك وتتخطّى قاعدة بيانات البصمات.

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

ماذا يفعل go mod init؟

ينشئ ملف go.mod في المجلد الحالي، فيصبح ذلك المجلد جذر وحدة. يكتب go mod init example.com/myapp مسار الوحدة وإصدار Go:

module example.com/myapp

go 1.24.5

شغّله مرة واحدة لكل مشروع، قبل go build أو go get.

ماذا أستخدم كمسار للوحدة في go mod init؟

العنوان الذي ستُجلب منه الشيفرة إذا استوردها آخرون، وعادة يكون مسار المستودع: go mod init github.com/yourname/project. لبرنامج لن يستورده أحد يصلح أي اسم (go mod init myapp)، لكن مسارًا بنقاط على شكل نطاق مثل example.com/myapp يتجنّب التعارض مع أسماء حزم المكتبة القياسية.

ما الفرق بين go get وgo mod tidy؟

يضيف go get pkg@version اعتمادية أو يغيّر إصدارها. أما go mod tidy فيقرأ ملفاتك المصدرية، ويضيف أي وحدة تحتاجها استيراداتك وتنقص في go.mod، ويزيل المتطلّبات التي لا يستوردها شيء، ويحدّث go.sum. التسلسل الشائع: اكتب الاستيراد، ثم شغّل go mod tidy.

هل أرفع go.sum إلى نظام التحكّم بالإصدارات؟

نعم. يحمل go.sum بصمات تشفيرية لكل إصدار وحدة يستخدمه بناؤك. رفعه يتيح للأمر go التحقّق من أن الجميع ينزّلون اعتماديات متطابقة بايتًا ببايت. لا تعدّله يدويًا أبدًا؛ go mod tidy يعتني به.

هل "golang init" هو نفسه go mod init؟

لا، هما شيئان مختلفان يتشاركان كلمة. go mod init أمر طرفية ينشئ go.mod. أما func init() فدالة تكتبها في شيفرة Go؛ تُنفَّذ تلقائيًا مرة واحدة، قبل main، بعد تهيئة متغيّرات الحزمة.

Coddy programming languages illustration

تعلّم البرمجة مع Coddy

ابدأ الآن