Việc quản lý phụ thuộc trong Golang được xử lý bằng go mod
. go mod
là công cụ quản lý phụ thuộc chính thức được giới thiệu bởi nhóm Golang. Nó hỗ trợ các nhà phát triển trong việc quản lý các phụ thuộc của dự án để đảm bảo sự ổn định và khả năng bảo trì của mã dự án. Trong go mod, các phụ thuộc được phân loại thành hai loại dựa trên cách các gói được nhập vào mã: phụ thuộc trực tiếp và phụ thuộc gián tiếp. Phụ thuộc trực tiếp được tham chiếu rõ ràng trong mã dự án, trong khi phụ thuộc gián tiếp là phụ thuộc của các phụ thuộc trực tiếp. Dưới đây, chúng tôi sẽ cung cấp các giải thích chi tiết về hai loại phụ thuộc này.
Phụ thuộc trực tiếp
Trong Golang, phụ thuộc trực tiếp đề cập đến các gói hoặc mô-đun bên ngoài được dự án tự tham chiếu rõ ràng, được nhập trực tiếp vào mã dự án. Ví dụ, giả sử có một dự án có tên myproject phụ thuộc vào gói github.com/pkg/errors
. Trong tệp go.mod của myproject, bạn có thể tìm thấy nội dung sau:
module myproject
require (
github.com/pkg/errors v0.9.1
)
github.com/pkg/errors
là phụ thuộc trực tiếp của myproject. Khi gói này được sử dụng trong dự án, nó sẽ được tải xuống và cài đặt cục bộ bằng go mod
.
Phụ thuộc gián tiếp
Phụ thuộc gián tiếp đề cập đến các gói mà các phụ thuộc trực tiếp phụ thuộc vào, nhưng chính dự án không sử dụng trực tiếp chúng. Nói cách khác, phụ thuộc gián tiếp là các gói được nhập bởi các gói phụ thuộc của dự án. Các phụ thuộc này không được tham chiếu trực tiếp trong mã của dự án nhưng là cần thiết cho việc xây dựng và thực thi dự án. Phụ thuộc gián tiếp thường được ẩn trong nền và người duy trì dự án không cần phải chú ý trực tiếp đến chúng.
Các phụ thuộc này thường được đánh dấu bằng nhận xét // indirect
trong tệp go.mod. Tiếp tục với ví dụ về myproject, nếu nó cũng phụ thuộc vào gói github.com/stretchr/testify
, việc kiểm tra mã nguồn của gói đó có thể tiết lộ các phụ thuộc vào các gói khác. Các gói được phụ thuộc gián tiếp này là các phụ thuộc gián tiếp của myproject. Trong tệp go.mod của myproject, bạn có thể thấy nội dung như thế này:
module myproject
require (
github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.8.4
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Trong phần require
bên dưới, tất cả các gói đều được đánh dấu bằng các nhận xét // indirect
, cho biết đây là các phụ thuộc gián tiếp của myproject.
Việc quản lý các phụ thuộc gián tiếp tương đối phức tạp vì chúng không được tham chiếu trực tiếp trong mã dự án mà thay vào đó được tham chiếu thông qua các phụ thuộc trực tiếp. Nếu không được quản lý đúng cách, điều này có thể dẫn đến xung đột phiên bản hoặc việc đưa vào các gói phụ thuộc không ổn định trong dự án.
Tại sao phụ thuộc gián tiếp lại cần thiết?
Phụ thuộc gián tiếp đảm bảo tính tương thích giữa tất cả các gói trong toàn bộ cây phụ thuộc của dự án. Nếu không làm như vậy có thể dẫn đến các tình huống mà các phiên bản của một số phụ thuộc thư viện không tương thích với các phụ thuộc khác.
Ghi lại các phụ thuộc gián tiếp đảm bảo rằng các phiên bản phụ thuộc giống nhau được lấy mỗi khi ứng dụng được xây dựng, điều này rất quan trọng đối với khả năng tái tạo các bản build và triển khai.
Hệ thống mô-đun Go sử dụng một thuật toán gọi là Lựa chọn Phiên bản Tối thiểu (MVS) để xác định phiên bản phụ thuộc nào sẽ được sử dụng. Thuật toán này ưu tiên các số phiên bản thấp hơn để giảm nguy cơ không tương thích.
Cách quản lý phụ thuộc gián tiếp?
Khi thêm hoặc cập nhật một phụ thuộc, nếu chính phụ thuộc đó dựa vào các gói khác, go get
sẽ tự động tính toán và thêm các phụ thuộc gián tiếp này vào tệp go.mod.
Lệnh go mod tidy
loại bỏ các phụ thuộc không cần thiết và thêm các phụ thuộc bị thiếu, cả trực tiếp và gián tiếp.
Lệnh go mod why
giúp hiểu tại sao một gói cụ thể tồn tại như một phụ thuộc, hiển thị chuỗi phụ thuộc và giải thích sự cần thiết của một phụ thuộc gián tiếp cụ thể.
Tóm tắt
Trong Golang, việc quản lý phụ thuộc rất quan trọng. Phụ thuộc trực tiếp được tham chiếu rõ ràng trong mã dự án, trong khi phụ thuộc gián tiếp là phụ thuộc của các phụ thuộc trực tiếp. Hệ thống mô-đun Go dễ dàng quản lý các phụ thuộc của dự án, đảm bảo sự ổn định và khả năng bảo trì của mã dự án.