赞
踩
虽然golang已经从1.17废弃了gopath的包管理方式,但目前gopath是对ide最友好的,vendor也可以,但会造成本地磁盘代码膨胀,以现在流行的微服务架构,动辄上百个项目,磁盘受不了。
通过 GO111MODULE="off" 启用gopath。
GOPATH 环境变量可以设置多个目录,比如共享的gopath和本项目自身的根目录(/myroot/src/mydomain/myproject/*中的myroot),当go get时使用第一个目录存放拉取的包。
当 GOPATH 包含多个目录时,在windows下和linux下目录列表分隔符是不同的,如下:
linux:
- const (
- PathSeparator = '/' // OS-specific path separator
- PathListSeparator = ':' // OS-specific path list separator
- )
windows:
- const (
- PathSeparator = '\\' // OS-specific path separator
- PathListSeparator = ';' // OS-specific path list separator
- )
对import中大版本的支持:
GO111MODULE="off" 时,如源码引入了:import "github.com/go-acme/lego/v3/acme",
通过 go get github.com/go-acme/lego/v3/acme 只能下载最新版本的包,并不能自动切到v3下。
只能通过两种方式解决:
1、到lego目录下手动切到v3下,如:git checkout v3.9.0
缺点:没办法处理版本冲突,如果存在一个代码库多个 /vN 的大版本依赖,只能通过下面的方式解决:
2、将lego目录更名为v3,并在v3前面新增lego目录,然后到v3目录下手动切到v3.9.0的tag下。
是否启用 GO111MODULE 对go get命令的版本格式也有影响,甚至诡异,以go1.18为例:
一、当 GO111MODULE = off 时,下载存放目录是gopath/src/,版本表示如下:
当使用 go get example.com/pkg 时,下载的是最新版。
当使用 go get example.com/pkg/v2.1.0 时,下载的仍然是最新版,指定的tag无效。
当使用 go get example.com/pkg@v2.1.0 时,报语法错误。
二、当 GO111MODULE = on 时,下载存放目录是gopath/pkg/mod/,版本表示如下:
2.1 当要下载的目标包在 go.mod 文件中未指定大版本时:
当使用 go get example.com/pkg 时,下载的是最新版。
当使用 go get example.com/pkg/v2 时,大版本不生效,下载的是最新tag。
当使用 go get example.com/pkg/v2@v2.1.0 时,大版本不生效,下载的是指定tag v2.1.0。
当使用 go get example.com/pkg@v2.1.0 时,下载很顺滑,下载的是指定tag v2.1.0。
2.2 当要下载的目标包在 go.mod 文件中通过 module example.com/pkg/v2 指定大版本时:
当使用 go get example.com/pkg 时,下载的也许是本地也许是远程代理的缓存版本,未必是最新版。
当使用 go get example.com/pkg/v2 时,下载的是v2大版本下的最新tag。
当使用 go get example.com/pkg/v2@v2.1.0 时,下载的是v2大版本下的指定tag v2.1.0。
当使用 go get example.com/pkg@v2.1.0 时,报错invalid version,也就是tag需要放到大版本下。
观察 GOPROXY 的代理是否生效:
go get -x example.com/pkg
将gopath目录中的依赖移到项目vendor目录下:
可以通过govendor工具解决,github.com/kardianos/govendor 已经停止更新,但是还可以使用。
一、安装govendor:
go install github.com/kardianos/govendor
二、初始化vendor目录:
GO111MODULE="off" GOPATH=/my_gopath:/project_root govendor init
三、将gopath依赖移到vendor:
GO111MODULE="off" GOPATH=/my_gopath:/project_root govendor add +e
此命令会全量扫描项目代码和项目依赖的代码,找出所有依赖,然后复制到vendor目录下,很耗时。
缺点:govendor 不能识别go.mod中的大版本标识,所以对于类似 github.com/go-acme/lego/v3/acme 的依赖会提示找不到,只有依赖包名和gopath路径完全一致时才能工作。
四、基于vendor目录编译项目:
GO111MODULE="off" GOPATH=/project_root go build main.go
1、修改项目的环境变量:
打开workspace里的go插件配置,如下图,然后点击edit in settings.json
在settings.json里添加环境变量如下:
- {
- "go.toolsEnvVars": {
- "GO111MODULE" : "off"
- },
- "go.inferGopath": true
- }
2、打开go插件的根据项目root推断gopath设置:
vscode会自动在settings.json里添加一行:"go.inferGopath": true
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。