Go modules

2021-02-18  本文已影响0人  JunChow520

Golang具有相当长的包管理工具的变迁史,由于官方没有实现足够好用的包管理工具,各种包管理工具层出不穷。

GOPATH

Golang的包管理方式最初采用的是monorepo模式,即所有包都放在GOPATH下,使用类似命名空间的包路径来区分包。

几乎所有的包管理工具在Golang1.11版本之前都绕不开GOPATH环境变量,GOPATH主要用来放置项目依赖包的源代码。由于GOPATH不区分项目,代码中任何import的路径都需要从GOPATH为根目录的位置开始查找。

$ go env | grep GOPATH
set GOPATH=F:\Go\workspce

GOPATH目录下包含三个子目录分别是bin、pkg、src

子目录 描述
bin 存储编译后生成的二进制文件
pkg 存储预编译的目标文件,以加快程序后续编译速度。
src 存储源代码

使用GOPATH方式管理项目依赖时,编写Go应用程序时,程序包和库文件会以$GOPATH/src/github.com/foo/bar的路径形式进行存放。因此就必须将项目源代码固定存放在$GOPATH/src目录下,若执行go get拉取外部依赖时会自动下载并安装到GOPATH目录下。

使用GOPATH环境变量管理项目依赖包的缺点

为解决GOPATH的缺陷,Go官方和社区推出了许多解决方案,比如godep、govendor、glide等。但这些工具要么无法彻底解决GOPATH存在的问题,要么使用起来繁冗。

Go Modules

使用Go Modules后无需再将代码放置到GOPATH下的src目录中,Go Modules替换旧的基于GOPATH来指定在给定构件中使用的源文件。Go Modules可将项目文件夹下所有依赖整理后写入名为go.mod的项目依赖管理文件中。

使用Go Modules管理项目依赖包时会在项目根目录下生成两个文件,分别是go.modgo.sum

go env

查看当前Go版本

$ go version
go version go1.15.6 windows/amd64

查看环境变量中Go模块的配置项,查看是否已开启Go Modules功能。

配置项 默认值 描述
GO111Modules off 是否开启Go Modules功能
GOPROXY https://proxy.golang.org,direct 设置Golang代理商为用户提供包下载的地址
$ go env
set GO111MODULE=on
set GOPROXY=https://goproxy.io

GO111MODULE

描述
auto 默认值,根据当前目录来决定是否启用Go Modules功能。
off 禁用Go Modules功能
on 启用Go Modules功能

命令行开启Go Modules功能

$ export GO111MODULE = on

当Go Modules模块功能开启后,依赖包的存放位置将会变更为$GOPATH/pkg,同时会允许同一个package包多个版本共存,且多个项目可以共享缓存的模块。

GOPROXY

$ go env | grep GOPROXY
set GOPROXY=https://goproxy.cn,direct

中国Golang中间代理商包下载地址

代理商 地址
Golang中国 https://goproxy.io
阿里云 https://mirrors.aliyun.com/proxy/
七牛云 https://goproxy.cn

设置Golang代理商为七牛云

$ go env -w GOPROXY=https://goproxy.cn,direct
$ go env|grep GOPROXY
set GOPROXY=https://goproxy.cn,direct

go mod

Go Modules包管理器提供了go mod命令用于管理项目依赖项。

$ go help mod 
Usage:

        go mod <command> [arguments]

The commands are:

        download    download modules to local cache
        edit        edit go.mod from tools or scripts
        graph       print module requirement graph
        init        initialize new module in current directory
        tidy        add missing and remove unused modules
        vendor      make vendored copy of dependencies
        verify      verify dependencies have expected content
        why         explain why packages or modules are needed

Use "go help mod <command>" for more information about a command.
命令 描述
go mod download 下载依赖包
go mod edit 编辑go.mod文件
go mod graph 打印模块依赖图
go mod init 当前目录下初始化模块
go mod tidy 拉取缺少的依赖项或移除无用的依赖项
go mod vendor 将依赖复制到项目根目录下的vendor目录中
go mod verify 验证依赖项的哈希值是否正确
go mod why 解释为什么需要依赖

go mod init

初始化Go Modules,首先需要进入项目根目录,执行Go Modules初始化命令,生成go.mod项目依赖管理文件。

$ mkdir projname && cd projname
$ go mod init projname

使用go mod init初始化项目依赖后会生成两个文件

文件 描述
go.mod 项目依赖包管理文件
go.sum 项目依赖包的版本控制文件

go.mod

$ vim go.mod
module ginv

go 1.15

require (
    github.com/allegro/bigcache/v2 v2.2.5 // indirect
    github.com/allegro/bigcache/v3 v3.0.0
    github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
)

go.mod文件只能存在于模块(包)的根目录下,子目录中的导入路径会使用“模块的导入路径+子目录路径”的形式。

Go命令行工具会自动处理go.mod中指定的模块版本,当在源代码中使用import导入指定的依赖项不存在于go.mod文件中时,Go命令行工具会自动搜索这个依赖项,并会将最新的版本(最后一个tag且非预发布的稳定版本)添加到go.mod文件中。

github.com/allegro/bigcache/v3 v3.0.0

若依赖项没有tag,则会使用伪版本(专门的版本语法,用于标记没有tag的提交)。

github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect

go.mod文件是面向行的,当前模块或主模块通常会位于第一行,接下来根据路径依次排序需要加载的依赖项。go.mod文件中每一行会包含一个指令,该指令由一个前导动词后跟参数组成。

前导动词 描述
module 指定当前模块的名字或路径
go 设置预期Golang语言的版本号
require 指定给定版本或更高版本的特定依赖项
exclude 指定忽略或排除的特定版本的依赖项
replace 指定可替换的依赖项

go mod vendor

当内部构建系统处于无网环境,依赖项需要纳入内部版本控制时,Go Modules提供go mod vendor工具。

$ go mod vendor

go mod vendor命令会在当前项目根目录下创建vendor目录,然后将项目所有依赖缓存到此,另外vendor目录可直接进入内部版本控制。使用go mod vendor的好处在于不依赖网络上游的版本,在本地内部自由地使用稳定可控的版本进行构建,因此也成为了非开源项目的主要构建方式。

默认情况下go build构建时会主动忽略vendor目录,若希望从本地vendor目录下开始构建则需使用go build -mod vendor命令。

$ go build -mod vendor

若项目目录下存在vendor目录,Go工具链会优先使用vendor内的包进行编译、测试等。之后第三方的管理方式都通过此种方式来实现。

go mod download

go mod download命令用于下载依赖到文本,而非使用go get。若GOPROXY设置镜像地址,此时会将依赖全部下载依赖到本地缓存GOPATH文件夹,依赖项版本数据均会缓存在$GOPATH/pkg/mod$GOPATH/pkg/sum文件夹下。同时会在项目根目录下生成go.sum文件。

go mod edit

编辑go.mod文件,格式化该文件。

$ go mod edit -fmt

添加依赖

$ go mod edit -require=golang.org/x/text

go list

$ go list -m all

go list -m

显示所有import库信息,-json表示使用JSON格式显示,all表示全部库。

$ go list -m -json all
上一篇下一篇

猜你喜欢

热点阅读