最近由于业务需求,需要新开一个 Go 的项目。听朋友说 Go 从 1.11 开始有了个叫 Modules 的新特性,于是打算看看能否用在我的新项目中。
为什么我对 Modules 这么感兴趣呢?因为写项目总是逃不开各种包管理,而之前 Go 不管是官方还是非官方的包管理器,都是基于 GOPATH
或者 vendor
目录,也无法很好的解决不同版本的冲突。Modules 据说可以解决这些问题。
我们之前的项目用的是 Go 官方的包管理器 dep
,真是被我们吐槽了好久:
- 它默认不显示进度,除非手动添加
-v
参数; - 命令十分诡异,以安装为例,我见过的有:
npm install
、gem install
、pip install
,还有……dep ensure
; - 我无法把 Go 的项目跟其它项目放在同一个 Workspace 下面,而必须放到
GOPATH
下面。
试用了一下 Modules,发现有这几个好处:
- 它默认在安装时会显示进度,在国内众所周知的网络环境下可以轻松确定网络是否有问题;
- 它是 Go 的原生命令,使用起来跟 Go 的其它命令比较像,没有违和感;
- 它允许我们把 Go 项目放到任意的地方;
- 它有一些很棒的功能,例如生成依赖关系图、生成 vendor 文件夹、验证包的内容、解释为何需要依赖某个包。
对于大部分人来说,照着网上的教程来做就可以了,我在做的时候,遇到了一些问题,于是就在这里记录一下。
VSCode 插件
VSCode 的插件 ms-vscode.go
已经可以完美支持 Go Modules 了,更新到最新版即可。由于我还有项目需要使用 dep
,因此我在 settings.json
里面新增了这些:
{
"go.toolsEnvVars": {
"GO111MODULE": "auto"
},
}
环境变量 GO111MODULE
的取值有三个:off
表示强行使用 GOPATH
的方法(适用于 dep
),on
表示强行使用 Modules,auto
表示如果发现你的项目在 GOPATH
那么就用传统方法(即使有了 go.mod
文件),否则就用 Modules。
报错 no package for import "fmt"
这种错误就比较奇葩了,我相信很多人都遇到过找不到其它包的情况,但我这儿连 fmt
都找不到……
搜了一下,这是 gopls
的报错,于是用 gopls -rpc.trace -v check file.go
看了一下,发现由于我项目文件的问题,报错 initial workspace load failed
,这个 Workspace 里面应当包含 ./...
和 builtin
,fmt
属于后者,因此也跟着找不到了。
那么该如何在项目中引用项目本身的包呢?例如我的项目叫 myproj
,我要在 cmd/main.go
里面依赖 cmd/server
包。
通过搜索,我得知可以在 go.mod
里面配置一行 replace myproj => ./
,整个文件如下:
module myproj
replace myproj => ./
go 1.13
require (
....
)
之后的引用就可以这样写了:
import (
"myproj/cmd/server"
)
最后测了一下,VSCode 插件的各种功能(自动导入、格式化、跳转、调试)都没有什么问题,这就算是大功告成了。至于用起来具体怎么样,还有没有其它的坑,可能得等过一段时间才能知道了。
参考资料
- x/tools/gopls: failure to import package · Issue #32762 · golang/go
- vgo - How do I resolve "cannot find module for path X" importing a local Go module? - Stack Overflow
版权声明:除文章开头有特殊声明的情况外,所有文章均可在遵从 CC BY 4.0 协议的情况下转载。