Golang Go语言项目迁移到go mod踩坑记

Golang Go语言项目迁移到go mod踩坑记

记录项目迁移到 go mod 里面的一些坑

下面聊的一些坑都是在模拟环境上说的,除非想要 n+1,就不露真实目录结构了。一开始项目的目录结构是 src 风格,和现在的 github 风格很不一样,记录下迁移遇到的问题。

模拟环境

目录结构

.
└── src
    ├── main.go
    └── nocode
        └── nocode.go

main.go 内容

package main

import ( “fmt” “nocode” )

func main() { nocode.NoCode() fmt.Println(“vim-go”) }

nocode.go

package nocode

import ( “fmt” )

func NoCode() { fmt.Printf(“no code\n”) }

迁移过程

  • 直接编译看下错误
src/main.go:5:2: cannot find package "nocode" in any of:
	/home/guo/go-version/go1.13.1/src/nocode (from $GOROOT)
	/home/guo/go/src/nocode (from $GOPATH)
  • 先构造 go.mod(第一步)
go mod init main
  • go build src/main.go
build command-line-arguments: cannot load nocode: malformed module path "nocode": missing dot in first path element
  • 需要解决本地包,修改 go.mod 文件(使用 replace 指令)
module main

replace nocode => ./src/nocode

go 1.13

  • go run src/main.go
go: nocode: parsing src/nocode/go.mod: open /home/guo/talk_go_mod/src/nocode/go.mod: no such file or directory

  • cd src/nocode/ && go mod init nocode

  • go run src/main.go

no code
vim-go

重点总结

  • 使用 replace 指令 重定向本地包的位置
  • 本地包没有 go.mod 会报错

github

https://github.com/guonaihong/gout


更多关于Golang Go语言项目迁移到go mod踩坑记的实战教程也可以访问 https://www.itying.com/category-94-b0.html

27 回复

go mod init main

import "main/nocode"


不需要放 src 目录

更多关于Golang Go语言项目迁移到go mod踩坑记的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你使用的方式就直接往坑里去了吧…

1l+1
新项目的话不应该这样玩
旧项目的话 换我也全部改了(

第一次看到你这样的使用方式

这个方法要修改源码里面的 import 路径,所以当初没有选用。。。

好几年的老工程。

我当时是一狠心把 import 路径全改了.

你搞错了,如果要迁到 mod 的话,直接把代码 clone 到一个新目录,在这个新目录里改造。
因为 clone 下来的代码肯定都在一个目录下,就不再用 replace 了。

这不叫坑,这叫根本不懂

直接把人往坑里带啊…

改 import 基本 0 风险都不愿意改

go mod 迁移的最佳实践应该就是改 import,用编辑器批量修改一下就完事了

你说的方式没玩过,可否详细说下。如何处理不能通过域名访问的本地包?比如上面的 nocode 包。

如何理解带坑里,janxin 兄的做法是?

懂于不懂的区别是? reus 兄处理这个问题的做法是?

哪怕用了 go.mod 可以叫 main 啥的,但最好还是叫 github.com/aaa/bbb 这种三级目录,不然迟早挖坑

应该是你例子的问题,你这个例子里面会让人以为 nocode 是当前包的一部分存在的,而你后面表述的事情跟这种表现又不一致,存在很多歧义问题。我想很多人也不会按照这种模式在 GOPATH 下组织目录的。

你上面为了在 main.go 中引用 nocode 包里的方法,加了 replace 和 go mod init 初始化了 nocode 包。

因为要用 go mod 来管理依赖包,可以这么搞。
假设你把 src 下的代码全部都上传到了 github.com/v2ex 下。
1.把代码 clone 到 /data/v2ex 下,所有的代码都在 ve2x 目录这里。
2.开启 go mod 功能,再在 V2EX 下 go mod init。
3.go build main.go 自动下载外部依赖包,这时要用到内部包 nocode,直接改下 import 路径即可( goland 可以自动找到更改),不用再在 nocode 里 go init 和 replace。

你这是不会用,不叫坑
坑的是多版本依赖,logrus 路径大小写,v2 版本,还有本地库的使用

多版本依赖,何时会出现? pkg/mod 里面的包都是带版本的号的,很好奇?

我懂你的意思了,和在 github 做法类似。

本地包,我上面展示了用 replace 指令搞定。还有别的坑吗?

10w+行代码的项目 我一天就改完了
小坑平推就完了

厉害厉害。

去年 11 月 我看 prometheus 的 node_exporter 用了 go mod
然后我也把项目用了 node_export 如果没出意外 go dep 转 go mod 一行命令就转了
但我们项目里有个库 接口变了 我记得 golang-x-crypto 上的 也没改几行

在将Golang项目迁移到go mod的过程中,确实可能会遇到一些挑战和“坑”。以下是一些常见的问题及解决方案,希望能帮助到你:

  1. 初始化项目:确保在项目根目录下执行go mod init <模块名>来初始化项目。这会生成一个go.mod文件,用于定义项目的模块路径和依赖关系。
  2. 解决依赖问题
    • 如果项目中有多个代码包且存在依赖关系,需要更新导入语句为基于项目根目录的相对路径。
    • 使用go mod tidy命令来自动解决和记录项目依赖。
    • 如果项目依赖了本地其他项目,需要在go.mod文件中使用replace指令来指定本地路径。
  3. 编译问题
    • 如果遇到编译错误,可以使用go build -x来查看详细的编译过程,有助于定位问题。
    • 如果因为依赖问题导致编译失败,尝试使用go get命令来更新或降级依赖版本。
  4. 环境变量
    • 确保GOPATHGO111MODULE环境变量设置正确。GO111MODULE应设置为on以启用go mod模式。
    • 如果在不同用户(如普通用户和root)下运行go命令遇到问题,可能是因为环境变量设置不一致。确保所有用户的环境变量都正确设置。
  5. 代码问题
    • 注意避免使用空指针或未初始化的变量进行操作。
    • 正确使用newmake来创建和初始化变量。
    • 在使用goroutine和for循环时,注意循环变量的作用域和生命周期。

总的来说,迁移到go mod需要仔细检查和调整项目配置和代码,但一旦完成,你将享受到go mod带来的依赖管理和版本控制的便利。

回到顶部