← Назад к вопросам

Что такое Vendor?

1.3 Junior🔥 122 комментариев
#Основы Go

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое Vendor в контексте Go?

Vendor — это специальная директория (vendor/) внутри проекта на Go, предназначенная для локального хранения зависимостей проекта. Это механизм, который позволяет "зафиксировать" конкретные версии сторонних библиотек, используемых в проекте, и гарантирует, что сборка всегда будет использовать именно эти локальные копии, а не зависимости, которые могут быть установлены или изменены в глобальном GOPATH (или GOMODCACHE в эпоху модулей). По сути, это реализация концепции "vendoring dependencies" (включение зависимостей в проект) в Go.

Предназначение и решаемые проблемы

Механизм vendor был создан для решения нескольких ключевых проблем, существовавших до появления официальной системы модулей (go modules):

  1. Воспроизводимость сборок (Reproducible builds): Без vendor команда go get загружала зависимости в $GOPATH/src. Если библиотека-зависимость обновлялась, ваша сборка могла внезапно сломаться. vendor фиксирует точные версии, которые вы протестировали.
  2. Изоляция проектов: Разные проекты могут требовать разные, возможно, несовместимые версии одной и той же библиотеки. Глобальный GOPATH не мог этого обеспечить. vendor изолирует зависимости на уровне проекта.
  3. Работа без доступа к сети: Все необходимые для сборки исходные коды зависимостей находятся внутри проекта, что позволяет собирать его в офлайн-режиме (например, на CI-сервере или в продакшн-среде с ограниченным доступом).

Как это работает

Когда компилятор go (начиная с версии 1.5, если включить переменную среды GO15VENDOREXPERIMENT, и по умолчанию с версии 1.6) встречает команду на сборку внутри проекта, он ищет импортируемые пакеты в следующем порядке приоритета:

  1. Корневая директория vendor текущего проекта.
  2. vendor директории выше по иерархии, вплоть до корня проекта (но не выше).
  3. Стандартные пути: $GOPATH/src, $GOROOT/src, и, в эпоху модулей, кэш модулей (GOMODCACHE).

Это означает, что если пакет найден в vendor, он будет использован, даже если в GOPATH лежит другая его версия.

Пример структуры проекта с Vendor

myproject/
├── main.go                # import "github.com/example/dep"
├── go.mod                 # Файл модуля (если используется)
├── vendor/                # Директория vendor
│   └── github.com/
│       └── example/
│           └── dep/
│               ├── dep.go
│               └── ...    # Исходный код конкретной версии зависимости
└── pkg/
    └── mypkg/
        └── mypkg.go

В коде main.go вы просто импортируете как обычно:

import "github.com/example/dep"

А инструменты Go (компилятор, go vet, go test и т.д.) при работе в директории myproject будут автоматически использовать код из ./vendor/github.com/example/dep.

Управление Vendor: Инструменты

Создавать и обновлять директорию vendor вручную неудобно. Для этого использовались сторонние менеджеры зависимостей, которые стали особенно популярны до go modules:

  • Dep (golang/dep): Официальный эксперимент, который мог генерировать vendor/ и файлы блокировки версий (Gopkg.lock).
  • Glide, Godep, govendor: Другие популярные инструменты, которые анализировали код проекта, скачивали нужные версии зависимостей и помещали их в vendor/.

Vendor в эпоху Go Modules

С появлением Go Modules (начиная с Go 1.11) официальная рекомендация сместилась в сторону использования go.mod и go.sum файлов для управления версиями. Однако директория vendor не исчезла и сохранила свою актуальность:

  • Команда go mod vendor: Стандартный инструмент для создания директории vendor на основе версий, указанных в go.mod. Это полностью заменяет сторонние менеджеры.
  • Флаг -mod=vendor: Указывает инструментам Go (go build, go test, go run) использовать зависимости исключительно из директории vendor, игнорируя кэш модулей. Это полезно для:
    *   Гарантированной офлайн-сборки.
    *   Обеспечения абсолютно идентичной среды для сборки в CI/CD (изоляция от потенциальных изменений в удаленных репозиториях).
    *   Интеграции в системы, которые требуют, чтобы все исходники проекта были в одном VCS-репозитории.

Вывод

Vendor — это важный исторический и практический механизм Go. Он сыграл ключевую роль в решении проблем управления зависимостями до появления модулей. В современной экосистеме с Go Modules директория vendor перешла из статуса основного метода управления зависимостями в статус дополнительного инструмента для финальной стабилизации и изоляции. Её использование теперь факультативно и управляется стандартными командами (go mod vendor, -mod=vendor), что делает её мощным вариантом для обеспечения максимально предсказуемых и воспроизводимых сборок в production-окружении.