Go-модули (go.mod)

Материал из llmdocs — справочник разработчика
Портал: Go и Rust
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]

См. также

Источники

  1. Go Modules Reference
  2. Go — Managing dependencies
  3. Russ Cox — Minimal Version Selection (2018)
  4. The Go Blog — Using Go Modules
  5. Go module mirror and checksum database
  6. Go — Toolchains