Go-модули (go.mod)
| Появились | Go 1.11 (август 2018) |
|---|---|
| По умолчанию | с Go 1.16 (2021) |
| Заменили | GOPATH и сторонние менеджеры (dep, glide) |
| Файлы | go.mod (зависимости), go.sum (контрольные суммы) |
| Алгоритм версий | минимальный выбор версий (MVS), Расс Кокс |
| Инфраструктура | proxy.golang.org, sum.golang.org |
| Рабочие пространства | go.work (Go 1.18) |
Go-модули — встроенная в Go система управления зависимостями. Модуль — набор пакетов, версионируемых вместе; его корень отмечает файл go.mod, где записаны путь модуля, требуемая версия Go и зависимости с точными версиями. Файл go.sum хранит криптографические контрольные суммы всех загруженных модулей, гарантируя, что сборка использует ровно тот же код, что и у автора.[1]
Модули сделали сборку Go-программ воспроизводимой и избавили от требования держать весь код в одном каталоге GOPATH.
История
До 2018 года весь Go-код должен был лежать в каталоге $GOPATH/src, а команда go get всегда брала последнюю версию зависимости из основной ветки репозитория. Версий как таковых не было, и сообщество создавало сторонние инструменты — godep, glide, dep. В 2018 году Расс Кокс из команды Go предложил собственное решение (проект vgo), которое вошло в Go 1.11 как экспериментальная функция, а с Go 1.16 (2021) стало режимом по умолчанию.[4]
go.mod
mkdir hello && cd hello
go mod init github.com/alice/hello # создать модуль
go get github.com/go-chi/chi/v5@v5.2.1 # добавить зависимость
go mod tidy # добавить недостающие и убрать лишние
go build ./... # собрать все пакеты модуля
// go.mod
module github.com/alice/hello
go 1.25
require (
github.com/go-chi/chi/v5 v5.2.1
golang.org/x/sync v0.16.0
)
require golang.org/x/text v0.27.0 // indirect
module— путь модуля, обычно совпадающий с адресом репозитория; с него начинаются пути импорта пакетов.go— минимальная версия языка. С Go 1.21 директиваtoolchainпозволяет автоматически скачать нужную версию компилятора.[6]require— зависимости; пометка// indirectозначает, что пакет нужен не напрямую, а зависимостям.replace— подменить модуль локальной копией или форком,exclude— запретить версию,retract— автор отзывает свои ошибочные версии.
Версии
Модули используют семантическое версионирование в виде тегов Git: v1.4.2. Особенность Go — семантическое версионирование импортов: начиная с v2 мажорная версия становится частью пути модуля (github.com/go-chi/chi/v5). Версии с несовместимыми API считаются разными модулями и могут сосуществовать в одной программе. Если тегов нет, используется псевдоверсия вида v0.0.0-20251101120000-abcdef123456 — время и хеш коммита.
Минимальный выбор версий
Большинство менеджеров пакетов при установке выбирают самую новую допустимую версию зависимости, и результат зависит от момента сборки. Go использует минимальный выбор версий (MVS): из всех требований в графе зависимостей берётся наименьшая версия, удовлетворяющая каждому, то есть максимальная из явно запрошенных минимумов.[3] Сборка детерминирована без отдельного lock-файла: версии меняются только тогда, когда кто-то явно обновил go.mod. Обновление — осознанное действие:
go list -m -u all # какие обновления доступны
go get -u ./... # обновить зависимости до новых минорных версий
go get example.com/lib@v1.8.0
Прокси и база контрольных сумм
По умолчанию модули скачиваются через публичное зеркало proxy.golang.org, а их хеши сверяются с открытой проверяемой базой sum.golang.org.[5] Зеркало ускоряет загрузку и сохраняет модули даже после удаления исходного репозитория, а база контрольных сумм защищает от подмены версии. Для приватного кода переменная GOPRIVATE=github.com/mycompany/* отключает прокси и проверку для этих путей; компании разворачивают собственные прокси (Athens, Artifactory).
Рабочие пространства и вендоринг
go work(Go 1.18) объединяет несколько локальных модулей в рабочее пространство, чтобы разрабатывать их одновременно без директивreplaceвgo.mod.go mod vendorкопирует все зависимости в каталогvendor/— для сборок без доступа к сети и аудита кода.go mod whyиgo mod graphобъясняют, зачем нужна зависимость и как устроен граф.
Практика
- Коммитьте и
go.mod, иgo.sum. - Запускайте
go mod tidyперед коммитом и проверяйте в CI/CD, что он ничего не меняет. - Ведите список уязвимостей командой
govulncheck ./...— она проверяет, вызывает ли ваш код уязвимые функции зависимостей. - Помните о стабильности: публичная библиотека с версией v1 и выше обещает не ломать API без смены мажорной версии и пути модуля.
Подробное руководство по управлению зависимостями — в документации Go.[2]
См. также
- Go (язык)
- Семантическое версионирование
- Cargo и crates.io
- Обработка ошибок в Go
- uv (менеджер пакетов)