Golang 1.11Module研究

2018-11-07| Category: ethereum| website:
work-single-image

go1.11对module有了新的支持, 在下一个版本可能对移除掉对GOPATH的支持。目前这个功能是根据一个环境变量GO111MODULE的值来进行控制的。

开启MODULE特性

go1.11对module有了新的支持, 在下一个版本可能对移除掉对GOPATH的支持。目前这个功能是根据一个环境变量GO111MODULE的值来进行控制的。

GO111MODULE=off 关闭module特性 会从GOPATH和vender中查找依赖

GO111MODULE=on 开启module特性 忽略GOPATH和vender的文件夹 根据go.mod去下载依赖 并将依赖放到$GOPATH/pkg/mod

GO111MODULE=auto 这个是默认值 在 $GOPATH/src 外面且根目录有 go.mod 文件时,开启模块支持。 注意是有两个条件要求。

在使用模块特性的时候,过它还是会把下载的依赖储存在 $GOPATH/pkg/mod 中,也会把 go install 的结果放在 $GOPATH/bin 中。

go mod 子命令

	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

如何创建mod

使用go 子命令自动生成

使用go mod init -module 包名称会创建一个go.mod文件 并且会在文件的第一行写入模块名称。

这个时候我们可以使用go build go test go list 来自动去解析包需要的依赖,然后会将依赖写入go.mod中的require中。 但是这个时候依赖的版本号会是自动按着依赖包最新的版本生成。

一份go.mod的文件格式类似于下面这样:

module example.com/m 

require (
    golang.org/x/text v0.3.0
    gopkg.in/yaml.v2 v2.1.0 
)

replace (
    golang.org/x/text => github.com/golang/text v0.3.0
)

go.mod中的replace可以用于替换替换依赖,这样对于一些需要翻墙而不能下载的包有很大的帮助。

我们可以使用go list -m -json all 来查看依赖信息

手动编辑go.mod文件

对于自动生成的go.mod文件依赖可能是不是我们需要的版本,这个时候我们需要手动修改到指定版本。 对于一些翻墙的包依赖可以进行替换成内网能下载的包。 go mod edit -require path@version go mod edit -replace=old[@v]=new[@v] 可以命令行修改文件。

关于版本和选择

有一些场景可能对依赖包的版本不是确定的,比如是小于或者大于某个版本 这个时候我们可以直接修改require的版本号类似于这个样子 golang.org/x/text >v0.3.0 或者直接使用命令行进行编辑 go mod edit -require golang.org/x/text >v0.3.0

minimal version selection(MVS)进行包依赖选择, 由于复杂项目中可能存在对同一个依赖包的不同版本依赖,如何选择版本是个问题.

rsc-mvs-version-select-1.png

rsc-mvs-version-select-list.png

MVS以build list为中心,从一个空的build list集合开始,先加入main module(A1),然后递归计算main module的build list,我们看到在这个过程中,先得到C 1.2的build list,然后是B 1.2的build list,去重合并后形成A1的rough build list,选择集合中每个module的最新version,最终形成A1的build list。

vendor和go module的配合

Go modules支持通过go mod -vendor命令将某个module的所有依赖保存一份copy到root module dir的vendor下, 这个时候我们编译的时候依然可以使用vendor中的依赖。 go build -getmode=vendor main.go 注意这个时候并不是说使用了GOPATH的依赖模式,只是说编译的时候查找go mod不在从$PATH/pkg/mod中 而是从根目录下的vendor中查找。

Clients
wupeaking
date
November 20, 2018
category
Investment, Business