GO Module 记录

Goproxy中国

地址:goproxy.cn

(1)Go Modules proxy:七牛云模块代理(开源非盈利)

(2)阿里云模块代理

 

 

Go Modules使用教程

andyidea · 2018-10-16 17:34:40 · 1405 次点击 · 预计阅读时间 4 分钟 · 不到1分钟之前 开始浏览    

这是一个创建于 2018-10-16 17:34:40 的文章,其中的信息可能已经有所发展或是发生改变。

引入

https://talks.godoc.org/github.com/myitcv/talks/2018-08-15-glug-modules/main.slide#1

Go Modules介绍

Modules是Go 1.11中新增的实验性功能,基于vgo演变而来,是一个新型的包管理工具。

常见的包管理工具

  • govendor
  • dep
  • glide
  • godep

这些包管理工具都是基于GOPATH或者vendor目录,并不能很好的解决不同版本依赖问题。Modules是在GOPATH之外一套新的包管理方式。

如何激活Modules

首先要把go升级到1.11。

升级后,可以设置通过一个环境变量GO111MODULE来激活modules:

  • GO111MODULE=off,go命令行将不会支持module功能,寻找依赖包的方式将会沿用旧版本那种通过vendor目录或者GOPATH模式来查找。
  • GO111MODULE=on,go命令行会使用modules,而一点也不会去GOPATH目录下查找。
  • GO111MODULE=auto,默认值,go命令行将会根据当前目录来决定是否启用module功能。这种情况下可以分为两种情形:当前目录在GOPATH/src之外且该目录包含go.mod文件,或者当前文件在包含go.mod文件的目录下面。

当module功能启用时,GOPATH在项目构建过程中不再担当import的角色,但它仍然存储下载的依赖包,具体位置在$GOPATH/pkg/mod。

初始化Modules

Go1.11新增了命令go mod来支持Modules的使用。

> go help mod Go mod provides access to operations on modules. Note that support for modules is built into all the go commands, not just 'go mod'. For example, day-to-day adding, removing, upgrading, and downgrading of dependencies should be done using 'go get'. See 'go help modules' for an overview of module functionality. 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.

首先创建一个项目helloworld:

cd && mkdir helloworld && cd helloworld

然后创建文件main.go并写入:

package main import ( log "github.com/sirupsen/logrus" ) func main() { log.WithFields(log.Fields{ "animal": "walrus", }).Info("A walrus appears") }

初始化mod:

go mod init helloworld

系统生成了一个go.mod的文件:

module helloworld

然后执行go build,再次查看go.mod文件发现多了一些内容:

module helloworld

初次使用报错及错误处理:require github.com/sirupsen/logrus v1.1.1

注意:如果某个包被墙下载超时,会报错

 

报错“go: error loading module requirements”因为“dial tcp 216.239.37.1:443: i/o timeout”,如下:

因为go的代码库在美国,国内访问不了。此时就需要GOPROXY 这个环境变量,它能够我们控制go从哪里去下载源代码。

设置GOPROXY 如下

export GOPROXY=https://goproxy.io

 

goproxy.io官网中的解决方案如下

In Linux or macOS, you can execute the below commands.

Bash /

# Enable the go modules feature export GO111MODULE=on # Set the GOPROXY environment variable export GOPROXY=https://goproxy.io

Or, write it into the .bashrc or .bash_profile file.

In Windows, you can execute the below commands.

PowerShell 

# Enable the go modules feature $env:GO111MODULE="on" # Set the GOPROXY environment variable $env:GOPROXY="https://goproxy.io"

Now, when you build and run your applications, go will fetch dependencies via goproxy.io. See more information in the goproxy repository.

If your Go version >= 1.13, the GOPRIVATE environment variable controls which modules the go command considers to be private (not available publicly) and should therefore not use the proxy or checksum database. For example:

Go version >= 1.13

go env -w GOPROXY=https://goproxy.io,direct # Set environment variable allow bypassing the proxy for selected modules go env -w GOPRIVATE=*.corp.example.com

 

同时多了一个go.sum的文件:

github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sirupsen/logrus v1.1.1 h1:VzGj7lhU7KEB9e9gMpAV/v5XT2NVSvLJhJLCWbnkgXg= github.com/sirupsen/logrus v1.1.1/go.mod h1:zrgwTnHtNr00buQ1vSptGe8m1f/BbgsPukg8qsT7A+A= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=

go.sum不是一个锁文件,是一个模块版本内容的校验值,用来验证当前缓存的模块。go.sum包含了直接依赖和间接依赖的包的信息,比go.mod要多一些。

go.mod

有四种指令:module,require,exclude,replace。

  • module:模块名称
  • require:依赖包列表以及版本
  • exclude:禁止依赖包列表(仅在当前模块为主模块时生效)
  • replace:替换依赖包列表 (仅在当前模块为主模块时生效)

其他命令

go mod tidy //拉取缺少的模块,移除不用的模块。

go mod download //下载依赖包

go mod graph //打印模块依赖图

go mod vendor //将依赖复制到vendor下

go mod verify //校验依赖

go mod why //解释为什么需要依赖

go list -m -json all //依赖详情

 

使用 go module proxy 的好处

默认情况下, go 命令会直接从版本管理系统下载代码。 GOPROXY 环境变量允许在下载源的进一步控制。配置该环境变量后,go 命令可以使用 Go module proxy。

设置环境变量 GOPROXY 开启 Go module proxy 后,将解决上边提到的所有问题。

  • Go module proxy 默认永久缓存所有依赖(不可变存储)。这意味着,不必再使用 vendor 文件夹。
  • 抛弃 vendor 文件夹,它将不会再消耗代码库的空间。
  • 因为依赖项存储在不可变存储中,即使依赖项从网上消失,你的代码也会受到保护。
  • 一旦 Go module(依赖) 存储在 Go proxy 中,就无法覆盖或删除它。这可以保护你免受可能使用相同版本注入恶意代码的攻击。
  • 你不再需要任何 VSC 工具来下载依赖项,因为依赖项是通过 HTTP 获取的( Go proxy 在后台使用 HTTP)。
  • 下载和构建 Go module 的速度要快得多,因为 Go proxy 通过 HTTP 独立提供源代码(.zip 存档)go.mod。与从 VCS 获取相比,由于更少的开销,这使得下载花费更少的时间。 相比之前它必须获取整个存储库,解决依赖关系也更快,因为 go.mod 可以独立获取。Go 官方团队对它进行了测试,他们看到快速网络上的速度提高了 3 倍,而慢速网络则提高了 6 倍!
  • 你可以轻松运行自己的 Go proxy ,这可以让你更好地控制构建管道的稳定性,并防止 VCS 关闭时的罕见情况。

如你所见,使用Go module proxy 对人人都有好处。但是我们如何使用它呢?如果你不想维护自己的Go module proxy怎么办?这里还有许多替代方案。

Go Modules简介

是Go Team强推出的一个理想化的类语言级依赖管理解决方案,为了淘汰GOPATH而生

官方地址:github.com/golang/go/wiki/Modules

环境变量

GO111MODULE

他共有三个值:

(1)auto:只有在项目包含了go.mod文件时启用GO Modules在Go 1.13中农仍然是默认值

(2)on:无脑启用Go Modules,推荐设置,未来版本中的默认值,让gopath称为历史

(3)off:禁用Go Modules

GOPROXY

(1)它的值是一个以英文逗号“,”分割的Go module proxy 列表,用于使Go在后续拉取模块版本时能够脱离传统的VCS方式从镜像站点快速拉取,它的值也可以是“off”即禁止GO从任何地方拉取模块版本

(2)拥有默认值:https://proxy.golang.org,diret

(3)proxy.golang.org在中国无法访问,故而建议使用goproxy.com来代替:

go env -w GOPROXY=https://goproxy.cn,diret

(4)值列表中的direct作为特殊指示符,用于指示GO回源到模块版本的原地址去抓取(比如GitHub等)

(5)当列表中上一个Go module proxy返回404或401错误时,GO会自动尝试列表中的下一个,遇见direct时终止并回源,遇见EOF时终止并抛出类似“invalid version:unknow revision...”的错误

GOSUMDB

它的值是一个Go checksum database,用于使Go在拉取模块版本时(无论是通过Go Module proxy拉取还是通过源站拉取)保证拉取的模块版本数据未经篡改,它的值可以是“off”即禁止Go校验任何模块版本。

GONOPROXY、GONOSUMDB和GOPRIVATE

(1)这三个环境变量都是用在当前项目依赖了私有弄快,也就是有GOPROXY执指定的Go module proxy或由GOSUMDB指定的GO checksum database 无法访问到的模块时的场景

(2)他们三个的值都是一个以英文逗号“,”分割的模块路径前缀,匹配规则同path.Match

(3)其中GOPRIVATE较为特殊,它的值将作为GONOPROXY和GONOSUMDB的默认值,所以建议的最佳姿势是只使用GOPRIVATE:

比如GOPRIVATE="*.corp.example.com"表示所有模块路径以corp.example.com的下一级域名(如team1.corp.example.com)为前缀的模块版本都将不经过Go module proxy和Go checksum database,需要注意的是不包括corp.example.com本身

Global Caching

(1)同一个模块版本的数据之缓存一份,所有其他模块共享使用

(2)目前所有模块版本数据均缓存在$GOPATH/pkg/mod和$GOPATH/pkg/sum下,未来将移至$GOCACHE/mod和$GOCACHE/sum下(当gopath被淘汰后)

(3)可以使用go clean -modcache清理所有已经缓存的版本数据。

如何将一个项目快速的迁移至Go Modules

(1)第一步:升级到Go 1.13(不建议在Go 1.11x或Go 1.12x时迁移至Go modules,因为问题太多)

(2)第二步:让GOPATH从你的脑海中完全消失,早一步踏入未来

go env -w GOBIN=$HOME/bin

go env -w GO111MODULE=on

go env -2 GOPROXY=https://goproxy.cn,direct #在中国是必须的,因为他的默认值被墙了

 

(3)第三步(可选):按照你喜欢的结构重新组织你所有的项目(再也不用在$GOPATH/src里挣扎了!)

(4)第四步:在你的项目根目录下执行go mod init <OPTIONAL_MODULE)_PATH>以生成go.mod文件

(5)想办法让身边所有人都去走一下前四步

迁移至Go Modules之后常用的命令

(1)go help module-get和go help gopath-get分别去了解Go modules 启用和未启用两种状态下的go get 的行为。

(2)用go get 拉取新的依赖

go get golang.org/x/text@latest #拉取最新版本(优先选取tag)

go get golang.org/x/text@master #拉取master分支的最新commit

go get golang.org/x/text@v.3.2 #拉取v0.3.2的commit

go get golang.org/x/text@342b2e1 #拉取hash为342b2e1的commit,最终会被转换为v0.3.2

(3)用go get -u 更新现有的依赖

(3)用go mod download下载go.mod文件中指明的所有依赖

(4)用go mod tidy 整理现有的依赖

(5)用go mod graph查看现有的依赖结构

(6)用go mod init生成go.mod文件(Go 1.13中唯一一个可以生成go.mod文件的子命令)

(7)用go mod edit编辑go.mod文件

(8)用go mod vendor导出现有的所有依赖(事实上Go modules 正在淡化Vendor的概念)

(9)用go mod verify 校验一个模块是否被篡改过

如何判断项目中是否启用了Go module

(1)切记,在Go 1.13中,一个项目只要包含了go.mod文件,且他所处的环境中的GO111MODULE不为off,那么Go就会为这个项目启用Go modules

(2)为了一劳永逸的解决这个判断烦恼,建议大家将GO111MODULE设置为on

go env -w GO111MODULE=on

(3)另外,若当前项目中没有包含go.mod文件且GO111MODULE为on,那么每一次构建代码时都会从头推算并拉去所需要的模块版本,但是并不会自动生成go.mod文件(以前会自动生成,Go 1.13做了调整)

管理GO环境变量常见问题

(1)在Go 1.13中管理环境变量会变得稍显混乱,因为Go 1.13建议将所有跟GO相关的环境变量都交由新出的go env -w来管理,比如执行go env -w GO111MODULE=on就会在$HOME/.config/go/env文件中追加一行“GO111MODULE=on”

(2)但go env -w 不会覆盖你的系统环境比变量

(3)所以建议大家在升级到Go 1.13后做一次环境变量的管理方式的转变,比如删除你系统中所有跟Go相关的环境变量,并使用go env -w重写

从dep、glide等迁移至Go Modules不经过Go module proxy问题

(1)如果项目中包含了老的依赖管理文件的时候,Go会用他们所制定的依赖版本信息来推算并生成go.mod文件,此时所有的推算行为都是直接回源的,并不会经过Go module proxy 这是个bug

(2)临时解决方案:先按照go help go.mod里指定的规则手动创建一个go.mod文件(可以只包含一行的模块路径),然后再执行go mod tidy 来推算并补充go.mod文件,这样就可以走Go module proxy了

更新现有的模块常见的问题

使用go get -u 只会更新主要模块,忽略了单元测试,推荐使用go get -u all 更新所有模块

Go Module Proxy简介

(1)一个主要环境变量:GOPROXY(默认值为国内无法访问的https://proxy.golang.org,direct)

(2)一个辅助环境变量:GONOPROXY

(3)从GO 1.13起,以后在国内必须修改GOPROXY才能正常开发GO程序

go env -w GOPROXY=https://goproxy.cn,driect

(4)可以指定GONOPROXY来指使Go在拉去那些模块时忽略Go module proxy 并无脑回源

如 go env -w GONOPROXY=*.corp.example.com,git.example.com/foo/bar 就意味着Go在拉取所有模块路径的前缀和列表相匹配的模块版本时都将无脑回源,匹配规则同path.match

如何快速搭建私有的Go Moduel Proxy

两个主流方法:

(1)使用现成软件 Athens:github.com/gomods/athens(使用最多的方式)

(2)使用Goproxy以编码的形式实现:github.com/goproxy/goproxy

代码实现比较简单:

package main

 

import(

"net/http"

"github.com/goproxy/goproxy"

)

 

func main(){

//功能实现语句

http.ListenAndServe("localhost:8080", goproxy.New())

}

goproxy.cn(Go 中国)

中国Go语言社区迫切地需要一个自己的Go Module Proxy

在Go 1.13中GOPROXY和GOSUMDB这两个环境变量都有了在中国无法访问的默认值,今后中国所有的Go语言开发者,只要是使用了Go Modules的,那么必须要吸纳修改GOPROXY和GOSUMDB才只能正常使用Go做开发,否则可能连一个最简单的程序都跑步起来(只要他有依赖第三方库)

 

Goproxy使用方法

Go 1.13 及以上(推荐)

打开你的终端并执行

$ go env -w GO111MODULE=on $ go env -w GOPROXY=https://goproxy.cn,direct

完成。

macOS 或 Linux

打开你的终端并执行

$ export GO111MODULE=on $ export GOPROXY=https://goproxy.cn

或者

$ echo "export GO111MODULE=on" >> ~/.profile $ echo "export GOPROXY=https://goproxy.cn" >> ~/.profile $ source ~/.profile

完成。

Windows

打开你的 PowerShell 并执行

C:\> $env:GO111MODULE = "on" C:\> $env:GOPROXY = "https://goproxy.cn"

或者

1. 打开“开始”并搜索“env” 2. 选择“编辑系统环境变量” 3. 点击“环境变量…”按钮 4. 在“<你的用户名> 的用户变量”章节下(上半部分) 5. 点击“新建…”按钮 6. 选择“变量名”输入框并输入“GO111MODULE” 7. 选择“变量值”输入框并输入“on” 8. 点击“确定”按钮 9. 点击“新建…”按钮 10. 选择“变量名”输入框并输入“GOPROXY” 11. 选择“变量值”输入框并输入“https://goproxy.cn” 12. 点击“确定”按钮

完成。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值