go基础--依赖管理

MasutaaDAO · · 1541 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

在Go语言编程中,我们经常会接触到依赖管理。简单来讲,这是对项目所需外部包的管理,包括确定所需外部包及其正确版本,并确保在构建和测试项目时其存在。 基础依赖管理则涉及到添加、更新和删除依赖包,锁定依赖包版本等工作。尽管看似琐碎,但这些工作对项目开发至关重要。 但实际上,go的依赖管理让人一言难尽,甚至可以说乱成一团。官方推出了好几种管理机制,比如gopath、vender、dep等,但都用起来不是那么顺手。到了Go 1.11版本,推出了go mod,虽然稍微好些,但和maven比起来,还是差了好几条街。 更让人费解的是,Go居然没有像maven、pip那样的官方依赖包站点。第三方包可以在任意开源站点发布,这就导致了一堆问题,比如下载地址、版本管理、包说明文档等。 由于没有统一的下载地址,Go的解决方案是把包名就当做包的下载地址。虽然很多包都发布在github.com,但也有很多包用其他站点发布,比如`k8s.io、bazil.org、gobot.io`等等。这就导致无法建立加速镜像站点,国内的加速都只能通过代理的方式。 包名的格式也有限制,只要是会被其他项目用到的包,名字就得是下载地址。就算是公司内部的私有包也不能例外,否则就得人工维护依赖。 包的文档格式和API说明也没有标准,直到go官方推出了`pkg.go.dev`站点,才统一了文档风格和包检索。但奇怪的是,这个站点只提供包信息和展示,包还是得在各自的站点发布。 吐槽归吐槽,要用的时候我们还是得用go语言,下面我会给大家讲一讲go的那些管理机制。 ## Gopath GOPATH是Go的一个重要环境变量,被称为工作目录。在Go 1.5版本之前,通过执行`go get ${packageName}`命令,我们可以下载依赖包。这个命令总是下载最新版本的依赖包,并且这些依赖包都会被存放在`${GOPATH}/src`目录下,但是并没有版本控制。 当我们使用import命令导入依赖包时,会按照以下路径查找:`${GOROOT}/src -> ${GOPATH}/src`。其中,`${GOROOT}/src`是Go SDK的安装目录,src文件夹存放了Go的标准库。而`${GOPATH}/src`则是Go的工作目录,src文件夹存放了所有的Go项目。 需要注意的是,当我们需要导入项目内部模块时,也需要从这些固定路径计算,因此所有项目都必须放在工作目录下,否则会出现找不到依赖的问题。这与其他语言有很大的区别,例如Java和Python都支持从项目路径计算,这意味着项目可以放在任意目录。 例如,如果我们的项目名称是demo,那么导入依赖的方式如下: ``` import "fmt" // 导入标准库包 import "demo/utils" // 导入项目内的工具模块包, 注意也从绝对路径查找 import "github.com/forgoer/openssl" // 导入外部第三方包 ``` fmt是Go语言的标准库,它的源代码位于`GOROOT/src`目录下。其他非标准库的包,例如你自己编写的包或者第三方包,都应该放在`GOPATH/src`目录下。这是Go语言的包管理机制决定的,它帮助Go语言在编译时找到所需要的包。 如果你想修改fmt包的代码,你可以直接在`GOROOT/src`目录下找到fmt包的源代码进行修改。 但是,我不推荐你这样做,因为这样会改变Go语言的标准行为。 如果你只是想使用修改过的fmt包,你可以在GOPATH/src目录下创建一个新的包,然后在新包中导入fmt包,并在新包中添加或修改你需要的功能。这样,你的代码就可以使用修改过的fmt包,而不会影响到其他使用标准fmt包的代码。 ## Vender Go 1.5版本引入了一个新的特性,叫做vendor机制。这个机制允许每个项目在其目录下有一个名为vendor的文件夹,用来存放该项目所依赖的包。在执行`go build`命令时,Go语言会首先在vendor目录下查找依赖,如果没有找到,才会去GOPATH目录下查找。依赖查找的顺序是:`${GOROOT}/src -> ${Project}/vendor -> ${GOPATH}/src`。 vendor机制的出现主要是**为了解决依赖版本管理**的问题。 它的基本思想是,每个项目的依赖都可以在自己的目录下独立管理,这样就避免了不同项目之间的依赖冲突。但是,这个机制并没有解决依赖包的版本问题,只是将依赖包放在了独立的目录下。如果你想要固定依赖包的版本,你需要将整个vendor目录一起提交到代码仓库。 这种做法虽然在一定程度上解决了版本管理的问题,但是也带来了一系列新的问题。 **首先**,vendor目录通常会非常大,提交到代码仓库会占用大量的空间,并且会降低仓库的下载和更新速度。 **其次**,大量的依赖代码会干扰代码审查,对代码统计和其他性能工具也会产生影响。 **最后**,对于多人协作的项目来说,管理项目的依赖包,记录版本,获取和存放依赖包等工作会变得更加复杂。从某种意义上说,蛮鸡肋的。 ## Go mod 它是从Go1.11版本开始引入的模块支持(module)功能的一部分,比起其他依赖管理,挺实用的。GoMod提供了对依赖包的自动获取、版本控制、依赖图分析等功能。 每个项目都会新增一个`go.mod`文件,用于维护该项目的依赖包信息,包括依赖包的版本号。可以使用`go mod init ${ProjectName}`命令来创建这个文件,而文件的内容则由Go自动维护。每次下载或升级依赖时,Go都会自动更新这个文件。 要使用go mod,需要先通过环境变量`GO111MODULE`来启用这个功能。"off"意味着关闭go mod,Go将继续从vendor目录或GOPATH中查找依赖。"on"则表示开启go mod,这时项目必须包含`go.mod`文件。如果没有设置环境变量,或者设置为"auto"(这是Go 1.13及以后版本的默认模式),那么Go会自动判断是否启用go mod:如果项目不在`GOPATH/src`目录下,并且包含`go.mod`文件,那么Go就会启用go mod。 使用GoMod的好处包括: 1. 简化依赖管理:你不再需要将所有的依赖复制到你的项目目录下,GoMod会自动为你下载和管理这些依赖。 2. 便于协作:当其他开发者克隆你的项目时,他们不需要手动安装所有的依赖,只需要运行`go mod download`命令即可。 3. 便于版本控制:你可以在`go.mod`文件中明确指定依赖的版本,这样就可以避免因为依赖包的更新导致的不兼容问题。 4. 提供依赖图分析:通过`go mod graph`命令,你可以查看项目的依赖图,了解各个依赖之间的关系。 当然go mod也有其他的操作: go mod download :手动触发下载依赖包到本地 cache go mod graph :打印项目的模块依赖结构 go mod edit :编辑 go.mod 文件 go mod verify:校验模块是否被篡改过 go mod why: 查看为什么需要依赖 go mod vendor:导出项目所有依赖到 vendor 下 总的来说,GoMod是一个强大且易用的依赖管理工具,它可以极大地提高Go语言开发的效率和质量。 ## 关于Masutaa Masutaa是个互联网从业者自由协作交流平台,链接行业内TOP10%人才!目前平台上已经有将近400名互联网尖端人才,其中近70%的从业者从业年限超3年。加入Masutaa,加入自由生活!感兴趣的朋友可以搜索masutaa官网!

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1541 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传