查看原文
其他

Go项目迁移:从 GOPATH 到 go mod

郝林 迭代码 2022-03-17

Go语言的新版本(如 go1.17)已经开始强烈推荐新项目/模块管理工具 go mod 了。我也建议大家去积极地使用这个工具。这个工具用起来很简单。


最近,订阅我的技术专栏《Go语言核心36讲》的一些同学问了我与此有关的问题,所以我在这里统一地回答一下。以下是正文:


1. 前置的假设


我们先假设:


  1. 系统环境变量 GOPATH 所包含的目录(以下简称 GOPATH 目录)的路径是:/path/go

  2. 系统环境变量 GO111MODULE 的值是 on(在 go1.17 下,该值默认就是 on);

  3. 这个路径下原有两个自有项目,分别是 AAABBB

  4. 这两个自有项目的路径分别是 /path/go/src/haolin/AAA/path/go/src/haolin/BBB(路径中的 haolin 可以理解为我个人专用的父代码包,你们的父包肯定与我的不同,请注意鉴别)。


2. 初始化自有项目


你需要先分别在这些原有项目的根目录下执行 go mod init 命令。


例如,在 AAA 项目的根目录下执行命令 go mod init AAA 。注意,我们必须在该命令的末尾带上当前项目的名称。


这个命令会在当前目录下生成一个 go.mod 文件。生成之后,我们再执行 go 命令的时候,它就可以依据这个文件来识别当前项目了。


3. 解决项目内的依赖


如果你的自有项目中有多个代码包,并且它们之间存在依赖关系,那么就需要修改一下原先的导入语句。


原因是,在使用 GOPATH 的时候,这些代码包的导入路径一定都是“基于 GOPATH/src 的相对路径”。一旦我们改用 go mod 工具,这些项目中的代码包的导入路径就必须是“基于当前项目的根目录的相对路径”。


举个例子,项目 AAA 中有两个代码包:liba1liba2 ,并且 liba2 依赖 liba1 。代码包 liba2 中原先导入 liba1 的语句是这样的:


import "haolin/AAA/liba1"


这显然是“基于 GOPATH/src 的相对路径”。那么,我们现在应该把它改为:


import "AAA/liba1"


显然,这是“基于项目 AAA 的根目录的相对路径”。


4. 解决项目间的依赖


如果你的项目有第三方的依赖,那么还需要执行一下 go mod tidy 命令。这个命令会扫描当前项目中的源码,并试图下载和安装对应的第三方模块,最后,将这些依赖项记录到 go.mod 文件中。


如果你的项目所依赖的某个项目只存在于本地,那么执行 go mod tidy 命令是无法解决的。


这时,你需要在 go.mod 中添加相应的配置。


例如,自有项目 BBB 依赖了自有项目 AAA。这时你就需要在项目 BBBgo.mod 文件的最后添加一行配置:


replace AAA => /path/go/src/haolin/AAA


也就是说,我们要把(项目 BBB 里的)导入语句中的 AAA 这个标识符定位到本地的项目(路径)上。


当然了,项目 BBB 中针对 AAA 的导入语句原先肯定都如 import "haolin/AAA/liba1"import "haolin/AAA/liba2" ,我们需要把它们都改成 import "AAA/liba1"import "AAA/liba2"


在这之后,我们还需要在项目 BBB 的根目录下执行命令 go get -d AAA 。这样做是为了把项目 AAA “内置”到项目 BBB 当中。这条命令也会在 go.mod 文件中添加一行相应的配置,如:


require AAA v0.0.0-00010101000000-000000000000 // indirect


5. 小结


好了,经过上述几个简单的步骤,你原先在 GOPATH 目录中的自有项目就可以适配 go mod 命令了。今后,你就可以使用 go mod 命令来管理它们了。这种迁移并不复杂,对吧?


最后,顺便说一下,如果你只迁移了部分的自有项目,并且还想让那些未迁移的项目一如既往的有效,那么就需要把系统环境变量 GO111MODULE 的值设定为 auto 。如此一来,go 命令就会根据当前项目的状态,智能地选择“GOPATH 模式”或“go mod 模式”了。不过需要特别注意的是,Go语言团队可能会在今后取消掉 GO111MODULE ,并强制大家使用 go mod 命令来管理项目/模块。所以,我们最好尽快地把原有项目迁移到“go mod 模式”上。


「正文结束」



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存