go mod 与 goproxy 的使用
go modules
是 golang 1.11 新加的特性,Modules官方定义为:
模块是相关Go包的集合。modules是源代码交换和版本控制的单元。 go命令直接支持使用modules,
包括记录和解析对其他模块的依赖性。modules替换旧的基于GOPATH的方法来指定在给定构建中使
用哪些源文件。
使用
- 把 golang 升级到 1.11(现在1.12 已经发布了,建议使用1.12)
- 设置
GO111MODULE
GO111MODULE
GO111MODULE
有三个值:off
, on
和auto(默认值)
。
GO111MODULE=off
,go命令行将不会支持module功能,寻找依赖包的方式将会沿用旧版本那种通过vendor目录或者GOPATH模式来查找。GO111MODULE=on
,go命令行会使用modules,而一点也不会去GOPATH目录下查找。GO111MODULE=auto
,默认值,go命令行将会根据当前目录来决定是否启用module功能。这种情况下可以分为两种情形:- 当前目录在GOPATH/src之外且该目录包含go.mod文件
- 当前文件在包含go.mod文件的目录下面。
GO111MODULE解释, 当为on时则使用Go Modules,go 会忽略 $GOPATH和 vendor文件夹,只根据go.mod下载依赖。当为 off时则不适用新特性 Go Modules支持,它会查找 vendor目录和 $GOPATH来查找依赖关系,也就是继续使用“GOPATH模式”。当为 auto时或未设置时则根据当前项目目录下是否存在 go.mod文件或 $GOPATH/src之外并且其本身包含go.mod文件时才会使用新特性 Go Modules模式,并且auto为 GO111MODULE的默认值。
当modules 功能启用时,依赖包的存放位置变更为
$GOPATH/pkg
,允许同一个package多个版本并存,且多个项目可以共享缓存的 module。
go mod
golang 提供了 go mod
命令来管理包。
go mod 有以下命令:
命令 | 说明 |
---|---|
download | download modules to local cache(下载依赖包) |
edit | edit go.mod from tools or scripts(编辑go.mod |
graph | print module requirement graph (打印模块依赖图) |
init | initialize new module in current directory(在当前目录初始化mod) |
tidy | add missing and remove unused modules(拉取缺少的模块,移除不用的模块) |
vendor | make vendored copy of dependencies(将依赖复制到vendor下) |
verify | verify dependencies have expected content (验证依赖是否正确) |
why | explain why packages or modules are needed(解释为什么需要依赖) |
goproxy
关于goproxy,简单来说就是一个代理,让我们更方便的下载哪些由于墙的原因而导致无法下载的第三方包,比如golang.org/x/下的包,虽然也有各种方法解决,但是,如果是你在拉取第三方包的时候,而这个包又依赖于golang.org/x/下的包,你本地又恰恰没有,当然不嫌麻烦的话,也可以先拉取golang.org/x/下的包,再拉取第三方包。
这个goproxy强大地方就在于代理,而它官网是这样介绍自己的【A Global Proxy for Go Modules】,就是这么强大,全球代理,让世界没有难下的包
使用
一般来说,goproxy是和go modules配合使用的。
首先要确保go modules是开启的,如果没有开启可以在命令行键入下面命令即可
export GO111MODULE=on
export GOPROXY=https://goproxy.io
1
2
不过这种是一次性的,重启之后就会消失,所以可以在环境信息文件/etc/profile的最后面添加上下面这两行
export GO111MODULE=on
export GOPROXY=https://goproxy.io
1
2
最后使用source /etc/profile让其生效。
go.mod 和 go.sum介绍
go.mod是Go项目的依赖描述文件,该文件主要用来描述两个事情:
当前项目名(module)是什么。每个项目都应该设置一个名称,当前项目中的包(package)可以使用该名称进行相互调用。
当前项目依赖的第三方包名称。项目运行时会自动分析项目中的代码依赖,生成go.sum依赖分析结果,随后go编译器会去下载这些第三方包,然后再编译运行。
go.sum依赖分析文件,记录每个依赖库的版本和哈希值
一般情况下,go.sum应当被添加到版本管理中随着go.mod文件一起提交。
在项目中使用
示例一.在新项目中使用
- 在
GOPATH 目录之外
新建一个目录,并使用go mod init
初始化生成go.mod
文件
➜ ~ mkdir hello
➜ ~ cd hello
➜ hello go mod init hello
go: creating new go.mod: module hello
➜ hello ls
go.mod
➜ hello cat go.mod
module hellogo 1.12
复制代码
go.mod文件一旦创建后,它的内容将会被go toolchain全面掌控。go toolchain会在各类命令执行时,比如go get、go build、go mod等修改和维护go.mod文件。
go.mod 提供了module
, require
、replace
和exclude
四个命令
module
语句指定包的名字(路径)require
语句指定的依赖项模块replace
语句可以替换依赖项模块exclude
语句可以忽略依赖项模块
- 添加依赖
新建一个 server.go 文件,写入以下代码:
package mainimport ("net/http""github.com/labstack/echo"
)func main() {e := echo.New()e.GET("/", func(c echo.Context) error {return c.String(http.StatusOK, "Hello, World!")})e.Logger.Fatal(e.Start(":1323"))
}
复制代码
执行 go run server.go
运行代码会发现 go mod 会自动查找依赖自动下载:
$ go run server.go
go: finding github.com/labstack/echo v3.3.10+incompatible
go: downloading github.com/labstack/echo v3.3.10+incompatible
go: extracting github.com/labstack/echo v3.3.10+incompatible
go: finding github.com/labstack/gommon/color latest
go: finding github.com/labstack/gommon/log latest
go: finding github.com/labstack/gommon v0.2.8
# 此处省略很多行
...____ __/ __/___/ / ___/ _// __/ _ \/ _ \
/___/\__/_//_/\___/ v3.3.10-dev
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______O\
⇨ http server started on [::]:1323
复制代码
现在查看go.mod 内容:
$ cat go.modmodule hellogo 1.12require (github.com/labstack/echo v3.3.10+incompatible // indirectgithub.com/labstack/gommon v0.2.8 // indirectgithub.com/mattn/go-colorable v0.1.1 // indirectgithub.com/mattn/go-isatty v0.0.7 // indirectgithub.com/valyala/fasttemplate v1.0.0 // indirectgolang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a // indirect
)
复制代码
go module 安装 package 的原則是先拉最新的 release tag,若无tag则拉最新的commit,详见 Modules官方介绍。 go 会自动生成一个 go.sum 文件来记录 dependency tree:
$ cat go.sum
github.com/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg=
github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s=
github.com/labstack/gommon v0.2.8 h1:JvRqmeZcfrHC5u6uVleB4NxxNbzx6gpbJiQknDbKQu0=
github.com/labstack/gommon v0.2.8/go.mod h1:/tj9csK2iPSBvn+3NLM9e52usepMtrd5ilFYA+wQNJ4=
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
... 省略很多行
复制代码
- 再次执行脚本
go run server.go
发现跳过了检查并安装依赖的步骤。 - 可以使用命令
go list -m -u all
来检查可以升级的package,使用go get -u need-upgrade-package
升级后会将新的依赖版本更新到go.mod * 也可以使用go get -u
升级所有依赖
go get 升级
- 运行 go get -u 将会升级到最新的次要版本或者修订版本(x.y.z, z是修订版本号, y是次要版本号)
- 运行 go get -u=patch 将会升级到最新的修订版本
- 运行 go get package@version 将会升级到指定的版本号version
- 运行go get如果有版本的更改,那么go.mod文件也会更改
示例二:改造现有项目(helloword)
项目目录为:
$ tree
.
├── api
│ └── apis.go
└── server.go1 directory, 2 files
复制代码
server.go 源码为:
package mainimport (api "./api" // 这里使用的是相对路径"github.com/labstack/echo"
)func main() {e := echo.New()e.GET("/", api.HelloWorld)e.Logger.Fatal(e.Start(":1323"))
}
复制代码
api/apis.go 源码为:
package apiimport ("net/http""github.com/labstack/echo"
)func HelloWorld(c echo.Context) error {return c.JSON(http.StatusOK, "hello world")
}
复制代码
- 使用
go mod init ***
初始化go.mod
$ go mod init helloworld
go: creating new go.mod: module helloworld
复制代码
- 运行
go run server.go
go: finding github.com/labstack/gommon/color latest
go: finding github.com/labstack/gommon/log latest
go: finding golang.org/x/crypto/acme/autocert latest
go: finding golang.org/x/crypto/acme latest
go: finding golang.org/x/crypto latest
build command-line-arguments: cannot find module for path _/home/gs/helloworld/api
复制代码
首先还是会查找并下载安装依赖,然后运行脚本 server.go
,这里会抛出一个错误:
build command-line-arguments: cannot find module for path _/home/gs/helloworld/api
复制代码
但是go.mod
已经更新:
$ cat go.mod
module helloworldgo 1.12require (github.com/labstack/echo v3.3.10+incompatible // indirectgithub.com/labstack/gommon v0.2.8 // indirectgithub.com/mattn/go-colorable v0.1.1 // indirectgithub.com/mattn/go-isatty v0.0.7 // indirectgithub.com/valyala/fasttemplate v1.0.0 // indirectgolang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a // indirect
)
复制代码
那为什么会抛出这个错误呢?
这是因为 server.go 中使用 internal package 的方法跟以前已经不同了,由于 go.mod会扫描同工作目录下所有 package 并且变更引入方法
,必须将 helloworld当成路径的前缀,也就是需要写成 import helloworld/api,以往 GOPATH/dep 模式允许的 import ./api 已经失效,详情可以查看这个 issue。
- 更新旧的package import 方式
所以server.go 需要改写成:
package mainimport (api "helloworld/api" // 这是更新后的引入方法"github.com/labstack/echo"
)func main() {e := echo.New()e.GET("/", api.HelloWorld)e.Logger.Fatal(e.Start(":1323"))
}
复制代码
一个小坑
:开始在golang1.11 下使用go mod 遇到过go build github.com/valyala/fasttemplate: module requires go 1.12
这种错误,遇到类似这种需要升级到1.12 的问题,直接升级golang1.12 就好了。幸亏是在1.12 发布后才尝试的go mod
go mod 与 goproxy 的使用相关推荐
- goproxy.io for Go modules
前言: 随着 go1.11 的发布,go 官方引入了 go module 来解决依赖管理问题,go module 被集成到原生的 go cmd 中,但是如果你的代码库在$GOPATH中,go1.11 ...
- 知识分享之Golang——go mod时使用代理模式goproxy和私有模式GOPRIVATE
知识分享之Golang--go mod时使用代理模式goproxy和私有模式GOPRIVATE 背景 知识分享之Golang篇是我在日常使用Golang时学习到的各种各样的知识的记录,将其整理出来以文 ...
- go mod tidy 下载依赖包问题
go: golang.org/x/sys@v0.0.0-20190813064441-fde4db37ae7a: unrecognized import path "golang.org/x ...
- goland 创建工程(go mod)singo
创建 选择 go modules 方式 创建成功,但是你发现这个文件里面只有 go.mod, 我的vendor文件呢?不管了,继续搞 用橙大大的singo试试 $ git clone https:// ...
- 开了gomod不识别gopath_三分钟掌握Go mod常用与高级操作
环境 Windows10 GO:1.13 1. 开启Go module 1.11和1.12版本 将下面两个设置添加到系统的环境变量中 GO111MODULE=on GOPROXY=https://go ...
- 使用athens部署企业内部Gitlab go mod包的Go私服代理
# 1,前言 当前 go 开发,已经全面投入到 mod 的怀抱,国内也有一些优秀的代理,例如 https://goproxy.io,https://goproxy.cn等,但是企业内网的 gitlab ...
- GOPROXY环境变量中direct的含义与用途
当开启go mod时需要设置的环境变量GOPROXY 这个环境变量主要是用于设置 Go 模块代理,主要如下: 它的值是一个以英文逗号","分割的 Go module proxy 列 ...
- go mod的使用细节
1.13版本之后 go env -w GO111MODULE=on go env -w GOPROXY=https://goproxy.cn,https://goproxy.io,direct GoL ...
- Go mod 七宗罪
go mod 是 rsc 主导设计的 Go 版本管理工具,借鉴了 Google 内部的高大上版本管理方式,摒弃了开源社区的版本管理成功经验,借助 MVS 算法,希望能够走出一条不一样的路,然而从发布以 ...
最新文章
- 三十分钟理解:双调排序Bitonic Sort,适合并行计算的排序算法
- 浅析移动端网站建设前都需要考虑哪些因素?
- centos ifconfig_Linux主流发行版本配置IP总结(Ubuntu、CentOS、Redhat、Suse)
- 动态毛玻璃特效html,js和CSS3炫酷毛玻璃面板特效
- Delphi调用Android的.so文件(转)
- MySQL—FTS实现原理介绍PPT
- Jsp+Ssh+Mysql实现的简单的企业物资信息管理系统
- [论文阅读] Deep Transformers For Fast Small Intestine Grounding In Capsule Endoscope Video
- PostMan 之 Mock 接口测试
- go在ubuntu下安装
- R | package基础 | Rstudio + devtools 创建/开发R包(初学者 指南| 简明详细流程)
- java batik_Java Batik框架画SVG图 JSVGCanvas
- 直插电阻的分类和区别
- Django之 Timezone 详解
- inurl home.php,phpweb /version.php Vul
- 把代码写烂点,你在公司就不可代替了?
- c++面试常见题·Part 2 数据结构和STL
- 闲置台式机+文件服务器,闲置电脑打造NAS:安装群晖NAS系统
- OnActionExecuting 中设置跳转指定网址或路由
- 五大经典算法-动态规划 及其算法应用
热门文章