• go1.14下Go mod使用实践


    https://www.jianshu.com/p/c666ebdb462b

    Go mod 简介

    Golang一直存在一个被人诟病的问题是缺少一个官方的包依赖管理工具。从我个人的角度上来看存在两个问题:

    1. GOPATH特性对于多工程的情况下,支持不算友好。
    2. GOPATH无法对依赖包进行有效的版本管理,没有任何地方能够表明依赖包的具体版本号,无法简单清晰获取到有效的依赖包版本信息等。

    在Go1.11时,官方推出了go mod作为官方的依赖管理工具。而go mod与之前的利用vendor特性的依赖管理工具的不同点在于,go mod 更类似于maven这种本地缓存库的管理方式,不论你有多少个工程,只要你引用的依赖的版本是一致的,那么在本地就只会有一份依赖文件的存在。而vendor即使依赖的版本是相同的,但如果在不同的工程中进行了引用,也会在工程目录下的vendor产生一份依赖文件。

    所以Golang在1.11版本中引入了go mod机制,在统一的位置对依赖进行管理。

    go mod不同于以往基于GOPATH和Vendor的构建方式,其主要是通过GOPATH/pkg/mod下的缓存包来对工程进行构建。在Go 1.11中已经可以使用,同以往新添加的功能一样,go mod 可以通过GO111MODULE来控制是否启用,GO111MODULE有一下三种类型。

    • on 所有的构建,都使用Module机制
    • off 所有的构建,都不使用Module机制,而是使用GOPATH和Vendor
    • auto 在GOPATH下的工程,不使用Module机制,不在GOPATH下的工程使用

    Go mod化处理步骤

    这里我主要说一下,对旧工程如何进行go mod化处理。通过网上搜索的文档加上自我实践,我总结成了以下三个步骤。对于新工程的处理可直接从第二部分开始。

    • 将需要进行版本管理的代码从GOPATH路径下移出
    • 在项目的根目录下使用命令go mod init projectName
    • 在该目录下执行go build main.go

     从GOPATH中移出工程

    这一步其实是不一定需要的,不过个人认为可以将工程从GOPATH下移出,单独存放。只在GOPATH/pkg/mod目录下只存放依赖文件。

    在go1.12环境下,我试验了一下环境变量GO111MODULE还是起作用的。但是编译时默认为使用Module机制进行编译(即GO111MODULE=on)。

    1. 如果工程中存在go.mod文件,编译时是从GOPATH/pkg/mod下查找依赖。
    2. 如果主动使用export GO111MODULE=off命令不使用Module机制,进行编译就会从GOPATH/src下查找依赖。会产生以下输出。(编译失败是由于相应目录下无依赖文件)

    go mod命令简介

    这个子命令用来处理 go.mod 文件,上一小节我们已经见过 go mod init 了。下面介绍下几个用得到的命令。

    • go mod edit -fmt 格式化 go.mod 文件。

    • go mod edit -require=path@version 添加依赖或修改依赖版本,这里支持模糊匹配版本号,详情可以看下文 go get 的用法。()

    • go mod edit -replace=path1@version=path2@version使用path2路径的包来代替path1路径的包。

      对于国内用户来说,手动维护这个文件是必然的,因为你需要把 golang.org/x/text 替换成 github.com/golang/text。示例

      go mod edit -replace=golang.org/x/sys@v0.0.0-20180830151530-49385e6e1522=github.com/golang/sys@v0.0.0-20180830151530-49385e6e1522

    • go mod tidygo.mod 删除不需要的依赖、新增需要的依赖,这个操作不会改变依赖版本。

    • go mod download命令会根据go.mod文件下载对应的依赖项到GOPATH/pkg/mod路径下。

    go get 命令

    在Go1.11后,可以用此命令来获取依赖的特定版本,可以用来升级和降级依赖。会自动修改 go.mod 文件,而且依赖的依赖版本号也可能会变。在 go.mod 中使用 exclude 排除的包,不能 go get 下来。

    与以前不同的是,新版 go get 可以在末尾加 @ 符号,用来指定版本。go get 命令需在go.mod同级目录下执行,否则会报出错误go: cannot use path@version syntax in GOPATH mode。而且在使用go get下载依赖时,要求仓库必须用 vX.Y.Z 格式打 tag,以下是简单罗列的匹配规则。

    go get github.com/gorilla/mux    # 匹配最新的一个 tag
    go get github.com/gorilla/mux@latest    # 和上面一样
    go get github.com/gorilla/mux@v1.6.2    # 匹配 v1.6.2
    go get github.com/gorilla/mux@e3702bed2 # 匹配 v1.6.2
    go get github.com/gorilla/mux@c856192   # 匹配 c85619274f5d
    go get github.com/gorilla/mux@master    # 匹配 master 分支

    go build 命令

    • go build -mod=readonly 防止隐式修改 go.mod,如果遇到有隐式修改的情况会报错,可以用来测试 go.mod 中的依赖是否整洁,但如果明确调用了 go modgo get 命令则依然会导致 go.mod 文件被修改。
    • go build -mod=vendor 在开启模块支持的情况下,用这个可以退回到使用 vendor 的时代

    使用本地包进行开发测试

    单独把这个拿出来说一下的原因是,基于我们自己项目的一个需求,我们是把一些公共的配置与函数部分统一成了一个单独的公共库,但是在go mod的情况下,就会出现一个问题,每次对公共库的修改测试都需要走提交更新、修改go.mod文件、更新本地依赖才可以进行测试,这样明显是及其不方便的。所以通过查询资料和实践,发现可以通过使用replace使用本地包来进行测试。

    使用本地包代提线上包进行测试的方法,例如修改公共库commons,在go mod中我可以增加一条这样的替换

    replace github.com/test/commons v1.1.1 => /Users/test/Workspace/bizgocommons,这样就把使用的报的路径指向了本地的包,省去了提交修改在下载的麻烦了。

    注意:本地包在使用的时候不需要带上版本信息。


    go mod时遇到的问题

    1. 在工程中go.etcd.io/etcd依赖时,在本地环境(mac)下可以成功编译,放到docker环境下(基础镜像为go1.12)的情况加会出现以下的错误信息。
    verifying go.etcd.io/etcd@v3.3.12+incompatible: checksum mismatch
        downloaded: h1:V6PRYRGpU4k5EajJaaj/GL3hqIdzyPnBU8aPUp+35yw=
        go.sum:     h1:xR2YQOYo5JV5BMrUj9i1kcf2rEbpCQKHH2sKTtpAHiQ=
    

    使用download中的值替换后,即可在docker下成功编译。

    通过实践和上网查询,个人觉得原因是mac和docker环境下下载的etcd是有区别的,可能含有某些操作系统相关的内容。导致两者的校验值不同。



  • 相关阅读:
    request.getParameter() 、 request.getInputStream()和request.getReader() 使用体会
    HTTP之Content-Length
    关于spring3中No Session found for current thread!and Transaction的配置和管理(转)
    Java数据类型和MySql数据类型对应一览
    Spring MVC 解读——View,ViewResolver(转)
    LeetCode 441. Arranging Coins
    LeetCode 415. Add Strings
    LeetCode 400. Nth Digit
    LeetCode 367. Valid Perfect Square
    LeetCode 326. Power of Three
  • 原文地址:https://www.cnblogs.com/smallleiit/p/12493404.html
Copyright © 2020-2023  润新知