Go 1.18 的工作区模式

Go 1.18 的工作区模式

当一个项目越来越复杂的时候,一定会拆分为多个模块,以便进行代码复用和更好的多人协作开发。

假设我们已经有了两个模块 xxx.org/utilxxx.org/product ,模块xxx.org/product依赖 xxx.org/util

现在有一个需求,需要同时修改这两个模块,以便让xxx.org/util新增的方法给模块xxx.org/product使用。

但是当同事A在模块xxx.org/util中增加新的方法后,要么推送到VCS中,让负责模块xxx.org/product的同事B使用,这是发布的场景。

如果模块xxx.org/util没有发布呢?那么就只能通过go.mod中的replace指令进行替换,把对模块xxx.org/util的引用,换成本地的未发布的版本,比如:

replace xxx.org/util => /Users/xxx/go/demo/util

相信我们都遇到过以上两种情形,这两种情形都有相应的弊端,比如:

  1. 把没有调试、没有测试的代码发布了,会影响其他正常构建
  2. replace的时候,忘记改回来,提交到VCS中了,影响了其他人使用

为了解决以上问题,Go 团队提出了工作区的概念,并且在Go 1.18 中发布。

Go 工作区,是你的工作区,它和多人协作、VCS等无关。说白了它就是个本地目录,通过go.work文件来管理多个go.mod模块。

要创建一个Go 工作区非常简单,通过如下命令即可:

mkdir workspace
cd workspace
go work init /Users/xxx/go/demo/util /Users/xxx/go/demo/product

在以上示例中,workspace是我创建的一个工作区,可以在你的电脑的任何地方,名字也可以自取。

然后go work init 后是两个go.mod的绝对路径,用空格分开,当然你也可以用相对路径。

运行以上代码后,就会在workspace目录下生成一个go.work文件,它的内容如下:

go 1.18

use (
  /Users/xxx/go/demo/product
  /Users/xxx/go/demo/util
)

usego.work文件的一个指令,用于管理包含的go.mod模块。

除了use指令,go.work还有replace指令,它和go.mod的replace很像,它用于把Go 工作区间管理的go.mod全部替换为指定的路径,并且它的优先级要比go.mod的replace要高。

现在,我们用到的这两个模块都在同一个工作区了,那么就不需要再修改模块xxx/product的go.mod replace 指令完成本地的依赖了。

这时候,在工作区 workspce目录下,运行如下命令,即可进行验证。

  workspace go run xxx.org/product
你好

因为都在一个工作区,go可以帮你找到模块xxx.org/product所依赖的xxx.org/util模块。

如果你只是切换到product目录下运行以上命令,只会提示你:

  product go run main.go 
main.go:3:8: no required module provides package xxx.org/util; to add it:
  go get xxx.org/util

不止我上面这种依赖上游模块的例子可以使用Go工作区,如果你一个代码库中有多个模块也是可以用的,只需要把他们都加入到Go 工作区即可。

go work命令有一个use可以把本地目录的模块加入工作区,如下所示:

go work use [path-to-your-module]

方括号中的路径,可以换成你自己电脑上的本地模块路径。

当然你也可以直接修改go.work文件,效果是一样的,这里不再举例,你可以自己试试。

go.work本质上是一种本地化的解决办法,因为go.mod都是放在VCS中的,和项目息息相关,所以我们很少去修改它来达到一些Hack的操作。

现在有了go.work就好办多了,因为它就是一个本地的东西,不在VCS中,想怎么改就怎么改,又不

Licensed under CC BY-NC-SA 4.0
Built with Hugo
主题 StackJimmy 设计