01介绍在Golang语言中,Golang程序是由GolangPackages组成的,而gobuild的过程实际上就是编译GolangPackages。在本文中,我们介绍了Golang构建模式的三个主要演进阶段,即GOPATH、GOPATH和引入vendor机制的GoModule。02GOPATHGolang早期版本内置了GOPATH构建模式。Golang程序编译时,Golang编译器会在GOPATH环境变量配置的本地路径下查找Golang程序依赖的第三方包。如果依赖包不存在,gobuild命令会返回“找不到包XXX”的错误。这时候我们需要使用goget命令手动下载Golang程序依赖的三方包到GOPATH环境变量配置的本地路径,然后尝试执行gobuild命令。goget命令虽然方便,可以自动下载依赖包和依赖包的依赖包到GOPATH环境变量配置的本地路径,但是读者朋友要注意的是go下载的依赖包get命令是当前依赖包。对于最新版本,如果我们对依赖包的版本有要求,就不能使用goget命令。比如多人开发的Golang项目,新成员在本地下载Golang项目,使用goget命令下载依赖包,正好赶上依赖包的版本更新。此时新成员使用gobuild命令构建Golang程序,Golang程序也会使用最新版本的三方依赖包。如果三方依赖包存在bug或者不兼容,会直接影响到Golang程序的稳定性。03VendorGolang在Golangv1.5中正式引入vendor机制,解决goget命令会下载最新版本依赖包的问题。所谓vendor机制就是在Golang项目的目录下创建一个名为vendor的目录,将Golang项目的所有依赖包缓存在该目录下。Golang程序编译时,Golang编译器会先在vendor目录下寻找Golang程序依赖的三方包,而不是在GOPATH环境变量配置的本地路径下。我们只需要将vendor目录提交到代码仓库即可。新成员下载Golang项目后,构建项目不会改变三方依赖包的版本。读者应该注意到供应商机制也引入了新的问题。例如,如果要使用vendor机制,Golang项目必须在GOPATH环境变量配置的本地路径下的src目录下。随着项目的不断迭代,依赖的第三方包会越来越多,vendor目录也会越来越大。将vendor目录提交到代码仓库,不仅会影响下载代码的速度,还会影响CodeReview。另外vendor目录下的三方依赖包也需要手动管理,比如手动记录依赖的三方包的版本号,手动下载三方依赖包等。为了解决针对vendor机制引入的问题,Golang社区推出了一些比较流行的解决三方包依赖管理的工具,比如dep、gb、glide等三方包依赖管理工具,但是三方包这些社区推出的依赖管理工具有自己的问题。04ModulesGolang在总结Golang社区推出的各种三方包依赖管理工具遇到的问题的基础上,在Golangv1.11正式推出了GoModule构建模式。关于GoModule构建方式,官博有一系列相关文章。在之前的公众号文章中,还有官博发布的GoModule相关文章的翻译。感兴趣的读者可以点播阅读。GoModule构建模式可以将Golang项目代码放在任意目录。它不需要与供应商机制相同。Golang项目代码必须放在GOPATH环境变量配置的本地目录下的src目录下。因为Golang官方同时支持GOPATH构建模式和GoModule构建模式,在Golangv1.11版本中,GoModule构建模式默认是“关闭”的,除非手动开启GoModule构建模式,如果GoModule构建模式设置为“Automatic”,Golang项目在GOPATH环境变量配置的目录下的src目录下,gobuild命令优先使用GOPATH构建模式。在Golangv.13版本中,GoModule构建模式默认为“自动”。不管Golang项目是否在没有在GOPATH环境变量中配置的本地目录下的src目录下,只要项目根目录下有go.mod文件,Go就被启用了。模块构建模式,否则启用GOPATH构建模式。所以在Golangv1.13之前,如果要使用GoModule构建模式,那么Golang项目代码是不能放在$GOPATH/src目录下的。从Golangv1.16开始,Golang默认开启了GoModule构建模式。未来,Golang官方会考虑彻底移除GOPATH构建模式。建议读者朋友们现在就开始将GOPATH构建模式下的旧项目迁移到GoModule构建模式。,并直接在新项目中使用GoModule构建模式。Golang项目使用的是GoModule构建方式,那么还需要使用vendor机制吗?答案是肯定的,因为vendor机制可以把golang项目依赖的三方包缓存在vendor目录下,这样我们就可以在无法访问网络的环境下使用vendor机制。在构建模式中使用GoModule构建模式,或者在构建性能敏感的环境中使用GoModule构建模式,例如在使用内部CI工具构建Golang程序时。在GoModule构建模式下,vendor机制不需要我们像GOPATH构建模式那样手动管理三方依赖包的版本和下载。Golang提供了gomodvendor命令来帮助我们创建和管理vendor目录。当我们想要基于vendor目录下缓存的三方依赖包构建Golang程序,而不是基于本地缓存的GoModule构建Golang程序时,可以在gobuild命令后加上-mod=vendor参数。并且在Golangv1.14及以后的版本中,如果Golang项目根目录下有vendor目录,gobuild命令会优先根据vendor目录下缓存的三方依赖包构建Golang程序默认情况下,除非我们在gobuild命令的mod=mod参数后添加-。05小结在这篇文章中,我们介绍了Golang构建模式的演进过程。Golang正式推出三种构建模式,分别是GOPATH构建模式、GOPATH构建模式和引入vendor机制的GoModule构建模式。介绍了为什么要引入vendor机制,解决什么问题,带来什么问题。基于社区推出的三方依赖包版本管理工具的GoModule构建模式正式上线,如何解决GOPATH构建模式中vendor机制引入的问题。介绍了GOPATH构建模式和GoModule构建模式下使用的vendor机制的区别,GoModule构建模式下为什么还需要vendor机制,以及GoModule构建模式下如何使用vendor机制。
