วิธีติดตั้งและใช้งาน Go Modules (Go 1.11+)

Go Modules

พอดีได้มีโอกาสใช้งาน Go Modules แทน Glide (Package Management for Golang เพื่อใช้จัดการ Packages Management เลยอยากมาแชร์เก็บไว้สักหน่อย

ถ้าใครเคยพัฒนาโปรแกรมด้วย Go มาตั้งแต่ก่อนเวอร์ชั่น 1.11 ส่วนใหญ่จะต้องพบเจอประสบการณ์อันยากลำบากเกี่ยวกับ $GOPATHมาอย่างแน่นอน ไม่มากก็น้อย

*สำหรับคนที่ไม่รู้ว่า $GOPATH คืออะไร ไว้ใช้ทำอะไร ขออธิบายสั้นๆเกี่ยวกับสิ่งนี้สักหน่อย ก่อนหน้าที่จะมี Go Modules ส่วนใหญ่นักพัฒนาจะสร้างโปรเจคไว้ใน $GOPATHเพื่อให้สามารถใช้งาน Go compiler เพื่อค้นหา dependencies ต่างๆ ได้ง่าย เพื่อไม่ให้ยุ่งยากเวลารันคำสั่ง Go build เพื่อสร้าง Binary file นั้นเอง

$GOPATH ประกอบโฟลเดอร์หลักๆ ทั้งหมด 3 อัน
1. $GOPATH/src — เก็บซอร์สโค๊ดทั้งหมด
2. $GOPATH/pkg — เก็บ Package ที่ถูกเรียกใช้งานโดย Go
3. $GOPATH/bin — เก็บ Binary สำหรับรันคำสั่ง เช่น godep, golint เป็นต้น

แต่หลังจาก Go ออกเวอร์ชั่น 1.11 มาแล้วนั้น มีสิ่งที่เรียกว่า Go Modules มาให้เราใช้งานเพื่อจัดการ dependencies ต่างๆ ทำให้เราสามารถจัดการมันได้ง่ายขึ้น

ปัญหาที่พบเจอก่อนที่จะที่มี Go Modules

  1. เวลาสร้างโปรเจคใหม่ โดยปกติเราต้องไปสร้างไว้ใน $GOPATHเท่านั้น
    (เราสามารถแก้ไขได้ แต่มันไม่ใช่ท่าปกติที่ออกแบบมา)
  2. ไม่สามารถกำหนดเวอร์ชั่นของ packages ที่เราดึงมาใช้งานได้ เหมือนกับ package.json (ภาษา javascript) ที่สามารถกำหนดเวอร์ชั่นได้
  3. External packages ทั้งหมดของหลายๆโปรเจคจะถูกเก็บไว้ในโฟลเดอร์ vendor ที่เดียวกันหมด ทำให้จัดการได้ยาก ถ้าเรามีหลายๆโปรเจคในนั้น

Go Modules คืออะไร ?

A module is a collection of related Go packages that are versioned together as a single unit. Modules record precise dependency requirements and create reproducible builds.
~ Official Go documentation

มันคือสิ่งที่สร้างขึ้นมาเพื่อจัดการ packages ต่างๆ สามารถกำหนดเวอร์ชั่นได้และมีการจัดการที่มีประสิทธิภาพมากขึ้นนั้นเอง

มาเริ่มใช้ Go Modules กันดีกว่า

** วันนี้เราจะมาลองเขียน Go ให้ส่งข้อความผ่าน Line Notify กัน **

ขั้นตอนแรก สร้าง main.go ขึ้นมาในโฟลเดอร์อะไรก็ได้ แต่ต้องอยู่นอก GOPATH ดังรูป

Create file : main.go

ลองเขียนให้เรียกใช้งาน external packages โดยยังไม่ต้องพิมพ์คำสั่ง go get ให้พิมพ์ไว้ในไฟล์ main.go ที่เราสร้างไว้ หลังจากนั้นพิมพ์คำสั่ง เพื่อติดตั้ง go mod

$ go mod init github.com/{your_username}/{repo_name}
ตัวอย่างคำสั่งของผม
$ go mod init github.com/gokusenz/go-modules-example

หลังจากพิมพ์คำสั่งด้านบนแล้ว ระบบจะสร้าง go.mod ขึ้นใน root โฟลเดอร์ ดังรูป

After run command : go mod init …

หลังจากนั้น ลองพิมพ์คำสั่ง go build

$ ​go build

เราจะสามารถใช้งานคำสั่ง build ได้อย่างไม่มีปัญหา โดยมันจะดึง packages ต่างๆเข้ามาในโปรเจคของเราให้โดยอัตโนมัติแล้วทำการเพิ่มเข้าไปในไฟล์ go.mod เหมือนกับ package.json ในภาษา javascript (แต่ดีกว่า :P )

เราสามารถเพิ่มเข้าไปได้เอง โดยเข้าไปแก้ไขใน go.mod ดังภาพ

go.mod

โดยเลขเวอร์ชั่นนั้น จะใช้งานแบบ semantic versioning : https://semver.org/

แต่ถ้าดูดีๆ จะมีอีกไฟล์ที่เพิ่มขึ้นมานอกเหนือจาก go.mod คือ go.sum โดยไฟล์นี้จะทำการเก็บ cryptographic เพื่อสำหรับการ checksum โดยมันจะมีไว้เพื่อตรวจว่าไฟล์ที่เราโหลดมาถูกต้องตามต้นฉบับหรือเปล่านั้นเอง

go.mod / go.sum

ลองมารันไฟล์ที่เรา build ออกมาดูสักหน่อย

test run on binary file

แล้วก็ผลลัพธ์ที่ได้ (อย่าลืมกรอก token ก่อนนะ)

Yeah!!

Easter Eggs

  1. go mod tidy
    คำสั่งนี้มีไว้เพื่อช่วยในการลบ dependencies ที่ไม่ได้ต้องการใช้งานแล้ว โดยปกติ Go build จะแค่ทำการอัพเดท dependencies แต่จะไม่ต้องการลบอะไรที่เราไม่ได้ใช้งานแล้ว
  2. go mod vendor
    ถ้าเราต้องการให้มีโฟลเดอร์​ vendor ในโปรเจคของเรา สามารถรันคำสั่งนี้เพื่อดาวโหลดทุก dependencies ที่เราเขียนไว้ใน go.mod มาเก็บไว้ในโฟลเดอร์ vendor ใน root โฟลเดอร์ของเรานั้นเอง สำหรับบางเคสที่ต้องการใช้งานนั้นเอง

หวังว่าบทความนี้จะมีประโยชน์กับนักพัฒนาที่ต้องการใช้งาน Go Modules ในอนาคตนะครับ ถ้าผิดพลาดตรงไหน สามารถพิมพ์บอกได้เลยนะครับ

คิดและเขียนคือสิ่งที่ผมชอบ ได้ทดลองทำอะไรใหม่ๆ เพื่อนำมาประยุกต์และต่อยอดในเรื่องต่างๆ พร้อมถ่ายทอดเรื่องราวจากชีวิตจริง จากประสบการณ์ จากแนวคิดของผม :)

--

--