package.json מול go.mod: לאן נעלם שדה הגרסה?
אם תעברו מ-JavaScript ל-Go, דבר אחד יפתיע אתכם.
פתחו קובץ package.json. תראו שדה version ממש למעלה. קל לקרוא אותו. ניתן לשנות אותו ב-pull request. הוא נמצא בתוך הקוד שלכם.
עכשיו פתחו קובץ go.mod.
הגרסה לא נמצאת שם. זו לא טעות. זו בחירה.
Go לא משתמשת בשדה גרסה עבור המודול שלכם. במקום זאת, היא משתמשת ב-git tags.
איך זה עובד:
• מריצים git tag v1.2.3
• דוחפים (push) את ה-tag למאגר (repository) שלכם
• ה-tag הזה הופך לגרסה שלכם
כשמישהו מריץ go get, Go בודקת את ה-git tags שלכם כדי למצוא את ה-commit המתאים. ה-tag הוא המקור היחיד לאמת (single source of truth).
לתכנון הזה יש יתרון משמעותי. גרסה לעולם לא יכולה להצביע על הקוד הלא נכון. ב-npm, הקוד שפורסם ושדה הגרסה יכולים להשתנות ולהיפרד זה מזה. ב-Go, הם אותו הדבר. הגרסה היא ה-commit.
עם זאת, זה משנה את זרימת העבודה (workflow) שלכם:
- נראות (Visibility): אי אפשר לראות את הגרסה שלכם פשוט על ידי הסתכלות בקובץ. עליכם להריץ פקודת git כדי למצוא אותה.
- סקירת קוד (Code Reviews): עדכון גרסה (version bump) לא מופיע ב-code diff. זוהי דחיפה של tag, לא שינוי בקוד.
- בנייה מקומית (Local Builds): commit ללא tag מציג גרסה מסורבלת מסוג
pseudo-version. תקבלו גרסה נקייה רק לאחר שתתייגו (tag) את ה-commit. - גרסאות ראשיות (Major Versions): זהו השינוי הגדול ביותר. ב-Go, גרסאות v2 ומעלה חייבות לכלול את הגרסה בנתיב הייבוא (import path).
דוגמה:
v1 משתמשת ב-github.com/you/my-app
v2 משתמשת ב-github.com/you/my-app/v2
זה מאפשר לתוכנית אחת להשתמש בשתי גרסאות ראשיות שונות של אותה ספרייה ללא התנגשות.
רוב השפות האחרות שומרות את הגרסה בקובץ: • Node: package.json • Rust: Cargo.toml • Python: pyproject.toml • Java: pom.xml
Go היא החריגה. היא מסתמכת אך ורק על git tags.
אם אתם מתגעגעים לחוויית ה-npm, תוכלו להזריק את הגרסה לתוך ה-binary שלכם בזמן הבנייה (build time) באמצעות ldflags. זה מאפשר לאפליקציה שלכם להגיב לפקודת גרסה.
הפשרה (trade-off) היא פשוטה: שדה גרסה הוא קל לקריאה ולסקירה, אך הוא עלול לשקר. git tag הוא קשה לזיהוי, אך הוא תמיד אמת.
Go בחרה באמת על פני נוחות.
למפתחי Go: האם זה המודל הטוב ביותר? האם הייתם מעדיפים שדה גרסה ב-go.mod אם הכלים היו מאמתים אותו מול ה-git tag?
מקור: https://dev.to/dalirnet/packagejson-vs-gomod-where-did-the-version-field-go-3301