文章目录
1.Go依赖管理的发展
1.1 为什么要有依赖管理
我们经常需要接触依赖管理,而我们为什么需要依赖管理呢?
我们平时写项目,时常需要依赖一些第三方库,而随着项目越来越复杂,依赖的第三方库也越来越多,此时再依靠手动的去管理我们的依赖已经变得不现实,尤其是企业中的开发。因此我们就需要一些工具或者模式去帮我们更好的管理我们依赖。
下面简单介绍一下Go依赖管理发展的几个阶段
1.2 Go依赖管理的三个阶段
1.2.1 GOPATH
在Go 1.5
之前,主要使用GOPATH
环境变量来管理包的位置。
此时如果使用go get
命令安装第三方包,则该第三方依赖的源码会放到$GOPATH/src
下,当你的项目进行编译时,则会自动去$GOPATH
底下找到该依赖包。使用这种方式管理依赖就相当于不管哪个项目的依赖,全部都放在$GOPATH
下面统一管理,简化了项目的构建,但同时带来如下两个问题
问题
- 所有项目必须都在
$GOPATH
下,否则编译器找不到对应的依赖包;否则的话,你就要将你的项目路径添加到$GOPATH
中,这对于开发者来说无疑是做了很多重复无意义的工作的。 - 因为所有第三方依赖源码都在
$GOPATH/src
路径下,所以同一个依赖只能在本地保存一个版本。如果有两个项目A
,B
,他们同时依赖C
,但是A -> C(v1.1)
,B -> (C v1.2)
(既依赖不同的版本),则会出现冲突。
1.2.2 Vendor
基于以上GOPATH
依赖管理存在的问题,在Go 1.5
提出在项目目录下引入vendor
文件夹存放第三方包,将第三方依赖的源码放到该文件夹底下,不同的项目有属于他们自己的vendor
文件夹。
问题
- 每个项目都有一个
vendor
文件夹,随着项目越来越大,代码库也会越来越大,有时只是依赖某个第三包的某个小功能,却需要将整个第三方依赖都下载下来放在项目目录下,造成冗余。
1.2.3 GO MODULE
之前两个阶段的依赖管理虽然都完成了依赖管理的工作,但同时也带来了不可忽视的一些问题,基于此,Go 1.11
推出了 GO MODULE 模式,给GO依赖管理带来 船新版本,船新体验
2.Go Module
2.1 基本介绍
go module
是 Go 1.11
版本之后官方推出的版本管理工具,在 Go 1.13
以后成为Go语言默认的依赖管理工具
2.2 关键文件 —— go.mod
go.mod
文件定义module
路径以及列出其他需要在build
时引入的模块的特定的版本,还可以指定要替换和排除的版本。
2.3 环境变量 —— GO111MODULE
要启用go module
模式需要设置环境变量 GO111MODULE
,通过它了开启或关闭模块支持,其有三种模式on
、off
、auto
,默认值为auto
。
2.3.1 修改 GO111MODULE
go env -w GO111MODULE=on
2.3.2 三种模式的区别
- off:禁用
MODULE
支持,编译时会从GOPATH
和vendor
文件下寻找包 - on:启用
MODULE
支持,编译时会忽略GOPATH
和vendor
,使用go.mod
下载依赖。此时GOPATH
不再充当导入的角色,当仍然承担存放第三方依赖源码的角色,会将第三方依赖源码放在$GOPATH/pkg/mod
下 - auto:当项目在
$GOPATH/src
目录外,且项目根目录有go.mod
文件时,启用模块支持
2.3.3 不同模式下的 go get 命令的区别
-
GOPATH 模式:依赖存放在
$GOPATH/src
下 -
MODULE 模式:依赖存放在
$GOPATH/pkg/mod
下
2.4 Go Module模式导入依赖的示例
-
使用 Go版本(>= 1.11)
-
设置
GO111MODULE
为开启go env -w GO111MODULE=on
-
任意位置创建项目文件
test/
,进入项目文件mkdir test cd test
-
初始化项目文件夹,生成
go.mod
文件,至此一个项目的框架基本搭成,可以开始开发~/test> go mod init [objectName] go: creating new go.mod: module test
-
某文件需要导入第三方依赖时,只需要添加下面导入语句
import github.com/XXXX/test
-
这里有一个疑问,以上只是在代码中声明了,我需要的第三方依赖的名字,并没有找到第三方的位置,那
GO MODULE
又是怎么找到依赖的位置的呢?在执行
go build
构建命令后,会如下图去找到第三方依赖包:
2.5 Go mod 其他命令
go mod download // 下载依赖的module到本地cache(默认为$GOPATH/pkg/mod目录)
go mod edit // 编辑go.mod文件
go mod graph // 打印模块依赖图
go mod init // 初始化当前文件夹, 创建go.mod文件
go mod tidy // 添加缺失的模块以及移除无用的模块
go mod vendor // 将依赖复制到vendor下
go mod verify // 验证依赖项是否达到预期的目的
go mod why // 解释为什么需要依赖
【参考文章】