DEV Community

Pallat Anchaleechamaikorn
Pallat Anchaleechamaikorn

Posted on

go.mod มีที่มาอย่างไร (2)

เล่าต่อจากครั้งที่แล้วที่จะออกแนวเล่าประวัติศาสตร์มากกว่าจะบอกว่า go.mod คืออะไรจริงๆ ครั้งนี้ก็เลยจะขอเล่าต่ออีกสักหน่อยหนึ่ง ซึ่งก็ขอเริ่มต้นจากค่า env ที่น่าสนใจ 2 ค่าอันได้แก่

  • GOPATH
  • GOROOT

ซึ่งในยุคแรกเริ่มที่ยังไม่มี Go Module ใช้กัน ผมเห็นกับตาว่ามีคนสับสน 2 ค่านี้จริงจังมาก และเห็นบ่อยๆที่กำหนด 2 ค่านี้ให้ชี้ไปที่ path เดียวกัน ซึ่งมันพอรับในได้วันแรกๆที่เขียน code แต่ถ้าปล่อยไว้นานวันเข้า มันอาจจะมีบางอย่างผิดปกติไป ซึ่งก็เห็นอีกว่า หลายคนไม่เข้าใจสิ่งนี้และก็ลงเอยด้วยการต้องลง Go กันใหม่ หรือยอมแพ้เลิกเขียนไปเลยก็มี

GOROOT ค่านี้คือ path ของ Go หรือจะเรียกว่า SDK ของ Go ก็ได้เช่นกัน เป็นที่ที่เมื่อเราติดตั้งภาษา Go ไว้ที่ไหนก็ตาม เราก็จะต้องกำหนดค่า GOROOT ไปไว้ที่นั่นเช่น ถ้าติดตั้ง Go ไว้ที่ /usr/local/go ค่า GOROOT ก็จะหน้าตาแบบนี้

GOROOT=/usr/local/go
Enter fullscreen mode Exit fullscreen mode

ซึ่งในนั้นก็จะประกอบไปด้วย Go compiler และพวก standard libraries ต่างๆที่มาพร้อมกับตัว compiler

GOPATH ค่านี้ เดิมทีเคยถูกกำหนดให้เป็น workspace เพื่อใช้เขียนโปรแกรม และเก็บพวก open source lib ต่างๆ และ tools ทั้งหลายที่เขียนด้วย Go โดยจะมีโครงสร้างหลัก 3 directories

- bin
- pkg
- src
Enter fullscreen mode Exit fullscreen mode

และโดย deafult แล้ว เจ้าค่า GOPATH มักจะถูกกำหนดให้อยู่ที่ HOME directory เช่น /Users/pallat/go (โดยชื่อ pallat คือชื่อ account ของเรานะครับ)

ิ- bin จะมีไว้สำหรับ program ต่างๆที่ถูกเขียนด้วย Go และเมื่อใช้คำสั่ง go install มันก็จะถูก bulid และนำมาวางไว้ที่นี่โดยอัตโนมัติ ซึ่งเราก็ควร append เจ้า path นี้เข้าไปใน PATH env ด้วย เพื่อความสะดวกในการเรียกใช้งาน ตัวอย่าง program ที่อยู่ในนั้นก็เช่น golangci-lint, gosec, gopls, etc.

  • pkg เดิมจะถูกเก็บ lib ลงไปตรงๆตาม path ที่เราไป go get มาเลย แต่เมื่อเราเริ่มใช้ Go Module แล้ว การเก็บ lib จะถูกนำไปไว้ใน pkg/mod อีกที
  • src ในยุคก่อนที่จะใช้ Go Module เราจะต้องไปเขียนโค้ดกันในนี้เท่านั้น โดยจะสร้าง directory ให้แต่ละ repo แยกกันให้รู้ว่าเราเขียนอะไรเช่น src/myapp หรือ src/github.com/pallat/myapp

เล่าจนเหนื่อย มาเข้าเรื่อง go.mod กันสักหน่อย
ทุกวันนี้เราไปเขียน Go ที่ path ไหนก็ได้ทั้งนั้น และถ้าไม่ได้ใช้อะไรเกินเลยจาก standard lib ที่มีให้ และทำ flat structure เราก็ไม่จำเป็นต้องมี go.mod เลยก็ยังได้ แต่ที่ถูกที่ควรแล้ว การสร้างให้ถูกต้องตั้งแต่แรกก็น่าจะดีกว่า โดยคำสั่งในการสร้าง go.mod หรือก็คือ Go Module ของเราก็คือ

  1. สร้าง project directory ก่อน
  2. cd เข้าไปใน project นั้น
  3. ใช้คำสั่ง go mod init [projectname] ตั้งชื่อ project name ที่ต้องการได้เลย

การตั้งชื่อ projectname มี 2 รูปแบบหลักๆคือ

  1. ตั้งตามใจ
  2. ตั้งตาม URI ของ repo จริงๆเช่น go mod init github.com/pallat/demo

การตั้งชื่อตาม URI มีประโยชน์เพื่อให้ repo เราจะสามารถถูก import ไปใช้จาก repo อื่นๆได้

หลักจากนั้นเราจะเห็นไฟล์ go.mod เกิดขั้น ซึ่งเมื่อสร้างใหม่ๆมันจะมีแค่ 2 บรรทัดหน้าตาแบบนี้

module github.com/pallat/demo

go 1.20
Enter fullscreen mode Exit fullscreen mode

และเมื่อตอนรันคำสั่งเสร็จเราก็จะเห็นข้อความแบบนี้

go: creating new go.mod: module github.com/pallat/demo
go: to add module requirements and sums:
    go mod tidy
Enter fullscreen mode Exit fullscreen mode

ในข้อความจะชี้จุดต่อไปให้เราว่า เมื่อเราเริ่มมีการใช้ lib หรือนำ module อื่นๆจากภายนอกเข้ามาใช้ ให้รันคำสั่ง go mod tidy ซึ่งความจริง เราจะใช้คำสั่ง go get [URI] แบบเดิมก็ได้เช่นกัน เพียงแต่ต้องทำกับทุก mod ที่เราต้องการใช้ แต่การใช้คำสั่ง go mod tidy จะช่วยให้สะดวกกว่า กรณีที่เราเขียนโค้ดเรียกใช้ mod/lib ไปก่อน แล้วพอใช้คำสั่ง tidy มันก็จะไปวิ่งหาว่าเราเรียกใช้อะไรที่ยังไม่ได้ go get มาบ้าง แล้วมันก็จะไป get ลงมาให้ แถมตัวไหนไม่ใช้แล้วมันก็จะเอาออกให้ด้วย

ยังมีคำสั่งอื่นๆในหมวด go mod อีก โดยเราสามารถขอดู help ได้ด้วยคำสั่ง go mod help

อื่นๆก็เช่น go mod download ในกรณีที่เรามี go.mod แล้ว เราต้องการ download dependencies ลงมาใหม่หมด หรือ go mod vendor เพื่อเอา dependencies หรือ mod ที่เราต้องการใช้ ลงมาไว้ใน directory ชื่อ vendor ใน repo ของเราเลยเป็นต้นครับ

Top comments (0)