Golang切换go mod时遇到构建错误如何解决

Golang切换go mod时遇到构建错误如何解决 我刚刚按照步骤,使用 go mod initgo mod tidy 将我的项目转换为使用模块,但现在遇到了这些“未找到”的错误。详情如下:

>env|grep -i go
OLDPWD=/home/reg/Jobs/Go/src/myproject
_INTELLIJ_FORCE_SET_GOROOT=/usr/lib64/go/1.14
GOPATH=/home/reg/Jobs/Go
PWD=/home/reg/Jobs/Go/src/myproject/server
GOROOT=/usr/lib64/go/1.14
_INTELLIJ_FORCE_PREPEND_PATH=/usr/lib64/go/1.14/bin:/home/reg/Jobs/Go/bin:
PATH=/usr/lib64/go/1.14/bin:/home/reg/Jobs/Go/bin:/home/reg/bin:/usr/local/bin:/usr/bin:/bin:/usr/lib/mit/bin:/usr/lib/mit/sbin:/usr/lib64/go/1.14/bin:/home/reg/Jobs/Go/bin
_INTELLIJ_FORCE_SET_GOPATH=/home/reg/Jobs/Go

例如,我的 main.go 文件之前导入如下时工作得非常好:

import (
	"fmt"
	"os"
	"strconv"
	"time"

	"github.com/davecgh/go-spew/spew"

	`myproject/server/modules/core/boot`
	`myproject/...`
	`myproject/...`
	`myproject/...`
)

现在,所有引用我子模块的导入,即以 myproject/ 开头的导入,都产生了类似以下的错误:

main.go:25:2: package myproject/server/modules/core/boot is not in GOROOT (/usr/lib64/go/1.14/src/myproject/server/modules/core/boot)

go.mod 文件看起来像这样:

module github.com/mycompany/myproject

go 1.14

require (
	github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
	...
	...
	...
)

我确信有一个简单的解决方法,但我从未使用过 go.mod,所以希望有人能告诉我此时需要做什么。


更多关于Golang切换go mod时遇到构建错误如何解决的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

理想情况下是的。不过,如果你正在进行本地开发…

很好的建议,谢谢。

更多关于Golang切换go mod时遇到构建错误如何解决的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


理想情况下是的。然而,如果你正在进行本地开发(例如添加功能),你将需要本地目录子句,以防止编译器每次运行测试或构建时都从远程拉取代码,而不是针对你的本地代码更改。

我不知道为什么这不是内置功能,但我希望在不久的将来会有。

func main() {
    fmt.Println("hello world")
}

谢谢!

根据这个建议以及今晚的大量阅读,我成功让我的项目在模块模式下运行了。

对于其他需要完成此操作的人,我做了三件事:

  1. 我完整阅读了你链接的页面:替换指令
  2. 移动我的项目根目录,使其自然地与git根目录对齐
  3. 执行了go mod initgo mod tidy
  4. 在我的IDE中进行了全局搜索和替换: a) 搜索正则表达式:["](myFirstPathSegment/.*)["] b) 替换为:github.com/myproject/$1

它成功了。完成这些更改后,我甚至不需要在go.mod文件中使用replace指令。

将非模块项目迁移到模块项目从来都不简单,恐怕你得逐一解决每个依赖不匹配的问题。

package myproject/server/modules/core/boot is not in GOROOT

你需要使用 replace 指令 来将所有 myProject 的引用重定向到本地依赖路径。这个问题是由你的 import 语句引起的。假设 myProject 是你的项目根仓库,那么 go.mod 中的子句应该类似于:

replace (
         "myproject" => ./
)

通用实践

在使用 go.mod 时,你应该使用公开路径进行导入,并配合 replace 子句,例如:

import "github.com/<name>/<project>/<path>/<to>/<package>"

然后在 go.mod 中,将远程源替换为本地目录,例如:

replace (
         "github.com/<name>/<project>" => ./
)

这样,Go 模块在拉取远程版本之前会先查找本地目录。对于用户来说,这与有效的 Go 实践保持一致,并且永远不会对导入语句感到困惑。

这是典型的模块路径不匹配问题。你的 go.mod 文件声明模块路径为 github.com/mycompany/myproject,但代码中仍然使用旧的 GOPATH 风格的导入路径 myproject/...

解决方法有两种:

方案一:更新所有导入语句(推荐)

将所有导入路径从 myproject/... 改为 github.com/mycompany/myproject/...

import (
    "fmt"
    "os"
    "strconv"
    "time"

    "github.com/davecgh/go-spew/spew"
    
    "github.com/mycompany/myproject/server/modules/core/boot"
    "github.com/mycompany/myproject/..."
    "github.com/mycompany/myproject/..."
    "github.com/mycompany/myproject/..."
)

然后运行:

go mod tidy

方案二:使用 replace 指令(临时方案)

go.mod 文件中添加 replace 指令,将模块路径映射到本地路径:

module github.com/mycompany/myproject

go 1.14

replace github.com/mycompany/myproject => ./

require (
    github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
    // ...
)

但更推荐方案一,因为:

  1. 这是 Go 模块的标准做法
  2. 确保代码在 CI/CD 和其他开发环境中正常工作
  3. 避免本地开发与生产环境不一致

执行方案一后,构建错误应该会消失。如果还有问题,可以运行:

go clean -modcache
go mod tidy
回到顶部