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 นั่นเอง

อย่างไรก็ตาม สิ่งนี้จะเปลี่ยนเวิร์กโฟลว์ของคุณ:

ตัวอย่าง: 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 คุณสามารถฉีด (inject) เวอร์ชันเข้าไปใน binary ของคุณในขณะ build ได้โดยใช้ ldflags ซึ่งจะช่วยให้แอปของคุณสามารถตอบสนองต่อคำสั่งเรียกดูเวอร์ชันได้

ข้อแลกเปลี่ยนนั้นเรียบง่าย: ฟิลด์เวอร์ชันนั้นอ่านและรีวิวได้ง่าย แต่ก็อาจให้ข้อมูลที่ไม่เป็นจริงได้ git tag นั้นมองเห็นได้ยาก แต่ข้อมูลจะเป็นความจริงเสมอ

Go เลือกความถูกต้องมากกว่าความสะดวกสบาย

ถึงเหล่านักพัฒนา Go: นี่คือโมเดลที่ดีที่สุดแล้วหรือยัง? คุณจะชอบให้มีฟิลด์เวอร์ชันใน go.mod มากกว่าไหม ถ้าหากเครื่องมือต่างๆ สามารถตรวจสอบความถูกต้องเทียบกับ git tag ได้?

ที่มา: https://dev.to/dalirnet/packagejson-vs-gomod-where-did-the-version-field-go-3301