Go Zero to Hero - Bài 4: Quản lý dự án với Go Modules (go mod)
Trước phiên bản Go 1.11, việc quản lý thư viện trong Go khá đau đầu. Mọi project bắt buộc phải nằm trong thư mục GOPATH/src, và việc kiểm soát phiên bản (versioning) của các thư viện dùng chung là một thảm họa. Go Modules ra đời đã thay đổi hoàn toàn cục diện, cho phép bạn khởi tạo dự án ở bất kỳ đâu và quản lý version một cách chặt chẽ.
1. Linh hồn của dự án: go.mod và go.sum
Khi bạn khởi tạo một dự án bằng Go Modules, hệ thống sẽ sinh ra hai file cực kỳ quan trọng:
go.mod(Khai sinh của dự án): Đây là file khai báo tên module của bạn, phiên bản Go đang sử dụng, và danh sách các thư viện bên ngoài (dependencies) cùng với version cụ thể mà dự án đang dùng.go.sum(Sổ cái bảo mật): File này chứa các mã băm (checksum) mã hóa của tất cả các thư viện được tải về. Mục đích là để đảm bảo rằng code của thư viện trên Github không bị ai đó âm thầm thay đổi (hack) sau khi bạn đã cài đặt. Mỗi khi bạn build code, Go sẽ đối chiếu với mã hash này để đảm bảo tính toàn vẹn (Integrity).
2. Bộ 3 câu lệnh "Thần thánh" cần nằm lòng
Khi làm việc với Go, bạn sẽ thao tác với module chủ yếu qua 3 câu lệnh này:
Khởi tạo dự án: go mod init
Để bắt đầu một dự án mới, hãy tạo một thư mục trống và chạy lệnh:
go mod init github.com/username/ten-du-an
Mẹo thực chiến: Không giống như Node.js bạn có thể đặt tên project là
my-app, trong Go, người ta thường đặt tên module theo dạng URL của repository chứa mã nguồn (ví dụ:github.com/gin-gonic/gin). Điều này giúp cho việc sau này nếu bạn muốn publish code của mình thành một thư viện cho người khác xài (import) trở nên hợp lệ và dễ dàng hệ thống hóa.
Cài đặt thư viện: go get
Khi bạn muốn thêm một thư viện bên ngoài, ví dụ như Web Framework nổi tiếng Gin, bạn chạy lệnh:
go get -u github.com/gin-gonic/gin
Lệnh này sẽ tải mã nguồn của Gin về máy, tự động cập nhật file go.mod và sinh ra/cập nhật file go.sum. Cờ -u (update) sẽ kéo version mới nhất của thư viện đó về.
Người dọn dẹp tận tụy: go mod tidy
Đây là lệnh bạn sẽ dùng nhiều nhất trong vòng đời phát triển dự án Go.
Như đã nói ở bài trước, Go cực kỳ ghét sự thừa thãi. Lệnh go mod tidy sẽ làm hai việc:
- Quét toàn bộ mã nguồn của bạn. Nếu phát hiện bạn có
importmột thư viện nhưng chưa tải về, nó sẽ tự động tải về. - Dọn dẹp rác: Nếu trong file
go.modcó ghi nhận một thư viện, nhưng trong code của bạn đã xóa hết những chỗ gọi đến thư viện đó, lệnh này sẽ gỡ bỏ thư viện đó ra khỏigo.mod.
Nguyên tắc: Trước khi commit code lên Git, hãy luôn chạy
go mod tidyđể đảm bảo filego.modsạch sẽ nhất.
3. Khái niệm Vendor (go mod vendor)
Khi bạn triển khai (deploy) ứng dụng lên môi trường CI/CD (như Jenkins, GitLab CI) hoặc build Docker, hệ thống sẽ cần đọc go.mod và tải lại các thư viện từ Github.
Nhưng nếu Github bị sập hoặc mạng nội bộ server của bạn không được ra Internet thì sao?
Lúc này lệnh go mod vendor sẽ cứu cánh. Chạy lệnh này, Go sẽ copy toàn bộ mã nguồn của các thư viện đang dùng (đang giấu trong cache của máy) vào một thư mục có tên là vendor nằm ngay trong project của bạn.
Lúc build, Go sẽ ưu tiên dùng code trong thư mục vendor này mà không cần kết nối mạng để tải lại nữa.
Tổng kết
Tổ chức một dự án bằng Go Modules vô cùng thanh lịch và gọn gàng. Bạn không cần phải đối mặt với thư mục node_modules khổng lồ, mọi thứ được quản lý tập trung và cache hiệu quả.
Quy trình chuẩn khi bắt đầu dự án:
- Tạo thư mục.
- Chạy
go mod init <tên-repo>. - Bắt đầu viết code, cần thư viện gì thì cứ gõ
import "tên/thư/viện". - Mở terminal gõ
go mod tidyđể Go tự động tải đồ về cho bạn.
All rights reserved