go modules包管理

记录一下go工程迁移go modules的过程。

go mod

golang从1.11版本之后引入了包管理-go mod,并通过环境变量GO111MODULE 设置:

  • 默认GO111MODULE 为auto 在gopath路径下会从gopath 或者vendor中寻找依赖包,在外部会使用go module的方式寻找依赖包。
  • GO111MODULE =on 只会使用go module的方式寻找依赖包。
  • GO111MODULE =off 只会从gopath中寻找依赖包。

go mod 命令

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

go mod新建工程步骤

  • 在工程根目录下(如果GO111MODULE 为auto则工程不可以在gopath中)go mod init [module name]。在工程根目录下会产生一个go.mod文件。
    go mod 初始化的时候会自动导入vendor目录中的包。
    goland也支持使用go mod管理包,配置如图:

    go mod 会贯穿go tool工具链,go test, go vet, go build等工具都会先检查依赖。go mod会自动工作。
  • 执行 go build main.go会依次下载依赖包到gopath/pkg/mod中,并在go.mod中进行管理。
    执行go mod vendor会将所有的依赖包复制到工程vendor目录中。
    go.mod示例:
module server
go 1.12
require (      
github.com/360EntSecGroup-Skylar/excelize/v2 v2.0.2      
github.com/YoungPioneers/blog4go v0.5.9      
github.com/a8m/kinesis-producer v0.2.0      
github.com/antlr/antlr4 v0.0.0-20191115170859-54daca92f7b0 // 
indirect      
github.com/apache/thrift v0.13.0     
github.com/astaxie/beego v1.12.0      
github.com/aws/aws-dax-go v1.0.1      
github.com/aws/aws-sdk-go v0.0.0-20180828194226-46ffe7480c9d      
github.com/fortytw2/leaktest v1.3.0 // indirect
)

go mod 会默认拉取最新的relase tag,如果没有,便拉取最新的commit记录。并支持版本控制。
indirect表明是间接引用。
注意:
"If an old package and a new package have the same import path, the new package must be backwards compatible with the old package."
“如果旧软件包和新软件包具有相同的导入路径,则新软件包必须与旧软件包向后兼容。”

  • If the module is version v2 or higher, the major version of the module must be included as a /vN at the end of the module paths used in go.mod files (e.g., module github.com/my/mod/v2, require github.com/my/mod/v2 v2.0.1) and in the package import path (e.g., import "github.com/my/mod/v2/mypkg"). This includes the paths used in go get commands (e.g., go get github.com/my/mod/v2@v2.0.1. Note there is both a /v2 and a @v2.0.1 in that example. One way to think about it is that the module name now includes the /v2, so include /v2 whenever you are using the module name).
  • If the module is version v0 or v1, do not include the major version in either the module path or the import path.
  • In general, packages with different import paths are different packages. For example, math/rand is a different package than crypto/rand. This is also true if different import paths are due to different major versions appearing in the import path. Thus example.com/my/mod/mypkg is a different package than example.com/my/mod/v2/mypkg, and both may be imported in a single build, which among other benefits helps with diamond dependency problems and also allows a v1 module to be implemented in terms of its v2 replacement or vice versa.
    来自于golang wiki
    如果导入了不兼容的高版本的包时,需要在import时表明版本。例import("github.com/360EntSecGroup-Skylar/excelize/v2")(restful 风格)。
  • 如果需要导入本地包,可以编辑go.mod文件,添加replace github.com/gohouse/goroom => /path/to/go/src/goroom
    ,并且需要在本地包根目录下执行go mod init [package name]
    否则go mod在本地包目录中找不到go.mod会报错。
    也可以是用go mod edit编辑。
  • 执行go mod tidy 增加丢失的module,去掉未用的module。
  • 配置好以后最后再执行go build main.go便会编译成功。
posted @ 2019-11-20 16:05  typeck  阅读(454)  评论(0编辑  收藏  举报