Go语言从入门到规范-4.2、使用go module解决本地包需要go get的问题
文章目录
1、前言
最近在使用模块间调用时发现了一个问题,我们按照GitHub、gitee、gitlab进行src目录划分后,GitHub的依赖包通过go get下载这样没啥问题,gitee下载时私有仓库出现了问题,暂时没有深究通过public方式绕过了,但是gitlab我们通常还没有将代码上传到仓库中,只是我本地进行模块间的调用,但是编译时却提示找不到包,需要go get来添加对应的包,但是实际上我根本就没有提交,这就麻烦了,我不可能为了go get将没有测试过的包提交到仓库,于是就找了一下如何导入本地包进行测试,这里做下总结,实际我们在使用时利用go.mod的方式也是比较规范的官方推荐的管理包依赖的方式。
2、官方博客
这个是官方对应go module是的一个博客:
https://blog.golang.org/using-go-modules
通过通看可以了解到go module的一些基本用法和作用:
Go模块是Go中依赖管理的未来。现在,所有受支持的Go版本(即Go 1.11和Go 1.12)都提供模块功能。
这篇文章使用Go模块介绍了这些工作流程:
- go mod init创建一个新模块,初始化go.mod描述它的文件。
- go build,go test以及其他程序包构建命令go.mod根据需要向其中添加新的依赖项。
- go list -m all 打印当前模块的依赖项。
- go get 更改所需版本的依赖项(或添加新的依赖项)。
- go mod tidy 删除未使用的依赖项。
3、replace替换导入本地包
上面的文章可以让我们了解到go module机制的概念和用法,我们可以了解到go鼓励我们在本地也加入go.mod和go.sum来进行模块依赖管理,因此我们尝试使用这种方式来管理我们的模块以及解决不同模块间的依赖调用问题。
不管是本地还是远程的包,我们在使用时都通过import来导入,这对于远程包没有什么问题,编译时会自动从远程进行下载,但是就像我在最开始提到的问题,我本地存在,但是远程还没有,如果自动去远程下载肯定会报错,这时我们生成的go.mod中对于required的包的路径需要修改成本地的,go使用replace来更加兼容这种情况,当我们使用本地包时我们可以使用replace来将远程路径替换成本地路径,当我们测试通过后可以使用远程路径时则删除replace即可。
这里是官方提供的go mod所有相关的内容,其中就包含了replace指令的介绍(如果有必要的话可以全部看一下):
https://golang.org/ref/mod
这个是找到的一个比较详细的介绍如何使用replace进行本地包导入的博客:
https://www.liwenzhou.com/posts/Go/import_local_package_in_go_module/
4、示例和处理步骤
这里给个go.mod的本地示例:
一般生成和修改go.mod的步骤:
- 1、go mod init根据提示处理
- 2、go mod tidy一般根据上述步骤会提示执行这一步
- 3、编译模块
- 4、根据编译模块的提示进行go get,一般编译时会提示所依赖的模块没有,需要添加:no required module provides package xxx; to add it: go get xxx
- 5、运行各个go get xxx,这时go.mod会更新
- 6、修改需要replace的包路径,比如我上面的gitlab相关的包,replace为本地相对路径即可
- 7、重新编译
- 8、如果还是提示gitlab相关内容没有则再次执行go get xxx,在有replace的情况下会自动添加,比如:
- 9、如果还是不行则手动添加required和replace的内容,当我们没有设置包版本时为v0.0.0,即:
5、最后
其实replace也可用在当我们没有代理获取go包时通过replace方式替换google的一些包路径为GitHub的包路径,因为go是开源的,所以google的官方包都是有GitHub地址的,而GitHub地址大多情况下是没有被墙的。