Go модули
Жизнь до и после Go Modules
До Go 1.11 существовал GOPATH — одна папка куда нужно было складывать весь Go-код. Это было неудобно: нельзя иметь разные версии одной зависимости в разных проектах, путь проекта был привязан к файловой системе.
Go Modules (Go 1.11, обязательны с Go 1.16) решили эту проблему: проект может лежать где угодно, каждый проект имеет свой список зависимостей с точными версиями.
go.mod: манифест проекта
go mod init github.com/mycompany/myappСоздаёт go.mod:
module github.com/mycompany/myapp
go 1.22
require (
github.com/gin-gonic/gin v1.9.1
github.com/lib/pq v1.10.9
)Три части:
module— имя модуля (путь для импорта внутренних пакетов)go— минимальная версия Gorequire— прямые зависимости с точными версиями
Имя модуля используется в импортах:
// Если module = github.com/mycompany/myapp
// то внутренний пакет myapp/user/store импортируется как:
import "github.com/mycompany/myapp/user/store"go.sum: замок на безопасность
go.sum создаётся автоматически и содержит хэши всех зависимостей:
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
Когда ты запускаешь go build, Go проверяет хэши из go.sum. Если пакет изменился на сервере — сборка упадёт. Это защита от атак на цепочку поставок.
Важно: go.sum нужно коммитить в git. Без него другой разработчик может получить другую версию зависимости.
Управление зависимостями
# Добавить зависимость (последняя версия)
go get github.com/gin-gonic/gin
# Добавить конкретную версию
go get github.com/gin-gonic/gin@v1.9.1
# Обновить до последней minor/patch версии
go get -u github.com/gin-gonic/gin
# Удалить зависимость из кода и go.mod
go mod tidy
# Скачать все зависимости локально (для offline работы)
go mod download
# Проверить зависимости
go mod verifygo mod tidy — самая важная команда. Запускай её после:
- Добавления/удаления импортов
- Обновления зависимостей
- Перед коммитом
Семантическое версионирование
Go modules строго следуют SemVer: vMAJOR.MINOR.PATCH
- PATCH (v1.0.1): баг-фиксы, обратная совместимость сохранена
- MINOR (v1.1.0): новые фичи, обратная совместимость сохранена
- MAJOR (v2.0.0): ломающие изменения API
Главное правило Go modules: мажорная версия ≥ 2 входит в путь импорта:
// v1 — обычный путь
import "github.com/user/pkg"
// v2 — версия в пути!
import "github.com/user/pkg/v2"
// v3
import "github.com/user/pkg/v3"Это позволяет использовать v1 и v2 одной библиотеки в одном проекте — они разные пакеты с точки зрения Go.
Псевдо-версии и pre-release
Иногда нужна версия из конкретного коммита — до тега:
# Получить последний коммит из ветки
go get github.com/user/pkg@main
# Конкретный коммит
go get github.com/user/pkg@abc1234Go создаст псевдо-версию в go.mod:
github.com/user/pkg v0.0.0-20240115123456-abc1234abcde
Формат: v0.0.0-{дата}-{хэш коммита}.
replace: локальная разработка
Когда работаешь одновременно над несколькими связанными модулями:
// go.mod
module github.com/mycompany/service
require (
github.com/mycompany/shared v1.2.0
)
// Переключаем на локальную копию для разработки
replace github.com/mycompany/shared => ../sharedТеперь service использует локальную папку ../shared вместо скачанной версии. Не забудь убрать replace перед коммитом — иначе сборка сломается у других.
Vendor: зависимости в репозитории
go mod vendorКопирует все зависимости в папку vendor/. Плюсы:
- Сборка работает без интернета
- Полный контроль над кодом зависимостей
- Часть команд требует этого (некоторые корпоративные среды)
# Сборка с vendor
go build -mod=vendor ./...
# Проверить что vendor актуален
go mod verifyМинус: vendor/ может быть огромным (сотни МБ). Многие проекты предпочитают не коммитить его и полагаться на кэш модулей ($GOPATH/pkg/mod).
Рабочее пространство (workspace)
Go 1.18 добавил go work для работы с несколькими модулями одновременно:
go work init ./service ./shared ./protoСоздаёт go.work:
go 1.22
use (
./service
./shared
./proto
)
Теперь все три модуля видят изменения друг друга без replace. go.work не коммитить в git — это локальный инструмент разработчика.
github.com/user/app