go modules模式 2021-10-21

2021-10-24  本文已影响0人  9_SooHyun

#go modules模式

GOPATH模式下第三方库都必须放置在$GOPATH/src下才可以使用,并且当多个项目依赖第三方库的不同版本时,很容易引起混乱
go modules模式是一种全新的package管理模式,它以module的方式来组织和管理package

在go modules模式下:

#go.mod 文件

go.mod文件是go modules模式的核心文件
go.mod 位于项目的根目录,支持 4 条命令:module、require、replace、exclude。示例:

module github.com/my/repo

require (
    github.com/some/dependency v1.2.3
    github.com/another/dependency/v4 v4.0.0
)

假如一个 module 有如下目录结构,go.mod 采用上面的示例

repo
|-- bar
|   `-- bar.go
|-- foo
|   `-- foo.go
`-- go.mod

那么 bar 包的 import path 即为:

import "github.com/my/repo/bar"

更多参考 https://liujiacai.net/blog/2019/10/24/go-modules/

#go mod 常用命令

go mod 是 go modules 模式下的依赖管理命令前缀

go mod init  # 初始化go.mod
go mod download  # 下载依赖文件。根据go.mod文件下载所有依赖的模块到本地缓存中,本地缓存的默认路径是$GOPATH/pkg/mod目录
go mod tidy  # 更新依赖文件
go mod vendor  # 将依赖转移至本地的vendor文件
go mod edit  # 手动修改依赖文件
go mod graph  # 打印依赖图
go mod verify  # 校验依赖
go mod why # 解释为什么需要依赖

注意:

go mod init module_path

if your module will be imported by other modules, the module path should reflect its published location, where Go tools could find it to download it

如果你的module需要被其他module引入,那么你的module path必须指向module源码存放的位置。比如你的go.mod首行声明了module github.com/google/uuid,那么这个module的源码就须对应存放到github.com/google/uuid这个地址下
->顾名思义嘛,module path~

当然啦,也可以在go.mod中使用replace来规避这些问题

replace 代码中引用的module路径 => module存放的真实路径

go.mod 的 replace 主要用于替换 module path,这对于引用本地依赖非常有帮助。比如有一个库 github.com/user/lib 有 bug,你需要 fork 到本地去修复,这时在自己的项目中需要引用本地 fork 的分支,那么就可以这么用,而保持代码里面的 import path 不变

replace github.com/user/lib => /some/path/on/your/disk

类似的原理,项目的 module 名字,也不必加上托管平台前缀了。比如我创建了一个示例项目 [demo],托管在https://github.com/xxx/demo,其 go.mod 如下:

module demo

go 1.15

如果要引用这个项目,只需要这么做:

// go.mod
replace demo => github.com/xxx/demo

// demo_test.go
import demo

func TestModule(t *testing.T) {
    demo.Hello("hello")
}

#go mod downloadgo mod tidy 的区别

go mod download is downloading all of the modules in the dependency graph, which it can determine from reading only the go.mod file. It doesn't know which of those modules are actually needed to satisfy a build, so it doesn't pull in the checksums for those modules (because they may not be relevant).
go mod download只依据go.mod去下载依赖,而不关心这些依赖是否仍然被项目需要

On the other hand, go mod tidy will download all the dependencies that are required in your source files and update go.mod file with that dependency. go mod tidy has to walk the package graph in order to ensure that all imports are satisfied. So it knows, for a fact, without doing any extra work, that the modules it walks through are needed for a go build in some configuration. see https://golangbyexample.com/go-mod-tidy/
go mod tidy会整理项目的依赖关系后,再去下载

一般使用go mod tidy来更新项目的依赖项

#GOPROXY

GOPROXY 是Go官方提供的一种通过中间代理来为用户提供包下载服务的方式
eg. go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/,direct

// ps:【七牛云】为中国的gopher提供了一个免费合法的代理goproxy.cn
go env -w GOPROXY=https://goproxy.cn,direct

#go mod依赖管理的内部原理

关于go modules 模式下,module管理机制的原理图示如下:


gomod.png
上一篇 下一篇

猜你喜欢

热点阅读