我是靠谱客的博主 震动海燕,最近开发中收集的这篇文章主要介绍go mod vendor 如何使用1. go vendor2. golang 使用 vendor 目录来管理依赖包,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目录

  • 1. go vendor
    • 1.1. go mod vendor 如何使用
    • 1.2. vendor 里面的 package 要更新
    • 1.3. Update All Go Modules
    • 1.4. replace modules
    • 1.5. go mod 全部操作命令
  • 2. golang 使用 vendor 目录来管理依赖包
    • 2.1. Vendor 目录介绍
    • 2.2. 一些建议
    • 2.3. 举个例子
    • 2.4. 为什么用 vendor 目录
    • 2.5. 推荐
      • 2.5.1. Glide
    • 2.6. golang vendor 使用

1. go vendor

1.1. go mod vendor 如何使用

go mod vendor 的功能是将新增的依赖包自动写入当前项目的 vendor 目录。

  1. 首先写一个 test,在 test 中 “使用新增依赖包的” 代码

  2. go mod tidy

  3. go mod vendor

1.2. vendor 里面的 package 要更新

go get -u gitlab.xxx.com/project_name@dev
go mod vendor
go mod tidy

example: go get -u github.com/GuanceCloud/dockertest/v3@v3.9.3

1.3. Update All Go Modules

Wanting to update all dependencies in a way that it doesn’t break is somewhat more complicated than expected.

I used to only do go get -u all which unfortunately broke, or forgot some dependencies, under certain conditions. After some GitHub issue spelunking, I’ve ended up with the following that works reliably:

$ go get -d -u -t ./...

Specifically the -t flag ensures that test dependencies are updated too.

To ensure that my go.mod and go.sum files contain all necessary checksums and removes the ones I don’t need anymore, I always run the following right after:

$ go mod tidy

Relevant docs:

  • go get
  • go mod tidy

1.4. replace modules

go.mod:

require (
github.com/pyroscope-io/pyroscope v0.36.0
)
replace (
github.com/pyroscope-io/pyroscope v0.36.0 => github.com/GuanceCloud/pyroscope v0.36.1
)

1.5. go mod 全部操作命令

# go mod 初始化
go mod init 模块名
# go mod 下载到本地Cache
go mod download
# go mod 清理本地Cache
go clean -modcache
# go mod 编辑go.mod文件:更多go mod查看 `go help mod edit`
go mod edit
# go mod 打印依赖图
go mod graph
# go mod 删除错误或者不使用的modules
go mod tidy
# go mod 生成vendor目录
go mod vendor
# go mod 验证依赖是否正确
go mod verify
# go mod 查找依赖
go mod why
# go mod 更新依赖到最新版本
go get -u github.com/golang/protobuf
# go mod 更新到指定版本
go get -u github.com/golang/protobuf@指定版本
# go mod 查看有哪些版本
go list -m -versions github.com/golang/protobuf
# go mod 替换包源
go mod edit -replace=golang.org/x/crypto@v0.0.0=github.com/golang/crypto@latest
go mod edit -replace=golang.org/x/sys@v0.0.0=github.com/golang/sys@latest

2. golang 使用 vendor 目录来管理依赖包

2.1. Vendor 目录介绍

随着 Go 1.5 release 版本的发布, vendor 目录被添加到除了 GOPATHGOROOT 之外的依赖目录查找的解决方案。在 Go 1.6 之前, 你需要手动的设置环境变量 GO15VENDOREXPERIMENT=1 才可以使 Go 找到 Vendor 目录, 然而在 Go 1.6 之后, 这个功能已经不需要配置环境变量就可以实现了。

Note, 即使使用 vendor, 也必须在 GOPATH 中, 在 go 的工具链中, 你逃不掉 GOPATH

那么查找依赖包路径的解决方案 (顺序) 如下:

  • 当前包下的 vendor 目录。
  • 向上级目录查找, 直到找到 src 下的 vendor 目录。
  • GOPATH 下面查找依赖包。
  • GOROOT 目录下查找

2.2. 一些建议

在使用 vendor 中, 给出如下建议:

  1. 一个库工程 (不包含 mainpackage) 不应该在自己的版本控制中存储外部的包在 vendor 目录中, 除非他们有特殊原因并且知道为什么要这么做。
  2. 在一个应用中, (包含 mainpackage), 建议只有一个 vendor 目录在代码库一级目录。

上面建议的原因如下:

  • 在目录结构中的每个包的实例, 即使是同一个包的同一个版本, 都会打到最终的二进制文件中, 如果每个人都单独的存储自己的依赖包, 会迅速导致生成文件的二进制爆发(binary bloat)
  • 在一个目录的某个 pacage 类型, 并不兼容在同一个 package 但是在不同目录的类型, 即便是同一个版本的 package, 那意味着 loggers, 数据库连接, 和其他共享的实例都没法工作。

2.3. 举个例子

工程目录如下:

- $GOPATH/src/github.com/mattfarina/golang-broken-vendor
- foo.go
- vendor/
- a/
- b/
- vendor/a/

在这个例子中, 两个 a package 都是完全一样的, b package 在代码库中保存了 a package, 在顶级应用代码中也引用了 a 包。

文件 foo.go 做了很简单的事情:

func main() {
var it a.A
it = "foo"
b.Do(it)
}

那么问题来了, 当我们 build 的时候, 发现出问题了, 返回了下面的错误:

$ GO15VENDOREXPERIMENT=1 go build
./foo.go:12: cannot use it (type "github.com/mattfarina/golang-broken-vendor/vendor/a".A) as type "github.com/mattfarina/golang-broken-vendor/vendor/b/vendor/a".A in argument to b.Do
你可以 clone 这个测试工程到本地重现。

2.4. 为什么用 vendor 目录

如果我们已经使用 GOPATH 去存储 packages 了, 问什么还需要使用 vendor 目录呢? 这是一个很实战的问题。

假如多个应用使用一个依赖包的不同版本? 这个问题不只是 Go 应用, 其他语言也会有这个问题。

vendor 目录允许不同的代码库拥有它自己的依赖包, 并且不同于其他代码库的版本, 这就很好的做到了工程的隔离。

2.5. 推荐

2.5.1. Glide

我们发现 Glide 是非常好的包管理解决方案, 他将依赖包平展开存放在顶级 vendor 目录中, 如果一个包被另一个程序引用了, 那么这个包最好不要存储外部依赖项。如果使用 Glide, 你可以在 glide.yml 文件中指定依赖包, Glide 会帮你管理, 并使用正确的版本。

2.6. golang vendor 使用

使用 golang 编译程序时总遇到找不到包之类的情况, 尤其制作 docker 镜像时候如果全部在 Dockerfile 里面 go get 会很卡, 还必须上网下载依赖包, 使用 golang 的包以来管理可以很轻松的解决这些问题, build 镜像时候把 vendor 拷贝进去, 制作 docker image 也是十分的快。下面是步骤

  1. 先下载 vendor
go get -u github.com/kardianos/govendor
  1. cd 到这个目录编译出二进制

go build 生成 govendor 文件

  1. 把这个可执行文件拷贝到 bin 目录, 或者添加到 gopath(或者知道这个目录地址直接用也行)

  2. cd 到自己的工程目录

  3. 执行 ./govendor init 生成 vendor 目录

  4. 执行 ./vendor add +external 导入依赖包

此时你的工程目录已经导入依赖的编译包, 此时执行 go build 使用的包全在 vendor

最后

以上就是震动海燕为你收集整理的go mod vendor 如何使用1. go vendor2. golang 使用 vendor 目录来管理依赖包的全部内容,希望文章能够帮你解决go mod vendor 如何使用1. go vendor2. golang 使用 vendor 目录来管理依赖包所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部