写点什么

Go workspace 的使用

作者:fliter
  • 2024-02-26
    上海
  • 本文字数:1582 字

    阅读完需:约 5 分钟

<br>

引入背景

<br>


Go Workspace和泛型,模糊测试一样, 也是 Go 语言在 1.18 版本中引入的一个新特性,目的是为了解决在开发涉及多个模块(module)的 Go 项目时的依赖管理问题。


在引入 Workspace 之前,当项目被拆分成多个模块进行管理时,依赖于本地模块的管理可能会变得复杂。特别是在本地开发环境中,开发者需要频繁地使用replace指令在go.mod文件中手动指定模块的本地路径,以便在不发布到远程仓库的情况下引用本地模块。这种方法虽然可行,但对于涉及多个模块的大型项目来说,维护成本较高,而且容易出错。


即对于较大的项目,一般会抽离出一个或多个公用组件(往往叫做 go-base,go-common). 当开发这个公共组件库时,不太方便 push 到远程仓库,再通过 go get 等拉取到本地(因为多人共用这个库), 之前的办法是在 go.mod 中增加一个或多个replace块.


而 Workspace 的引入旨在简化和优化这一流程,使得开发者能够更方便地在本地环境中管理和编译涉及多个模块的项目,而无需修改go.mod文件或使用多个replace指令。


<br>

之前用 replace 的方式

<br>


假设项目抽离出了两个模块:commonserviceservice模块对外提供服务, 其依赖于common模块。在没有 Workspace 功能之前,如果common模块在本地进行了修改,service模块需要通过replace指令在其go.mod文件中指定common模块的本地路径来引用这些更改,从而进行调试.


mkdir workspace-democd workspace-demo
mkdir commoncd commoncode utils.gogo mod init dashen.tech/common
mkdir servicecd servicecode main.gogo mod init dashen.tech/servicecode go.mod
复制代码


其中 utils.go:


package utils
import "math/rand"
func GenerateOrderID() string { return "order-" + randomString(10)}
func randomString(n int) string { b := make([]byte, n) for i := range b { b[i] = byte(65 + rand.Intn(26)) // A = 65, Z = 90 } return string(b)}
复制代码


<br>


修改 service/go.mod 为:


module dashen.tech/service
go 1.21rc2
require dashen.tech/common v0.0.0-incompatible // 引入这个包
replace dashen.tech/common => ../common // 将此包指向本地目录的路径
复制代码


<font size=1>


replace 的作用很多,可以


  • 替换无法下载的包

  • 调试依赖包(或引用本地包)

  • 使用 fork 的仓库

  • 禁止被依赖


此处仅用到了引用本地包的功能


更多可参考:



</font>


<br>


main.go:


package main
import ( "fmt"
utils "dashen.tech/common")
func main() {
fmt.Println(utils.GenerateOrderID())
}
复制代码


执行 go run main.go,输出:



<br>


IDE 可能会有错误提示,忽略即可


<br>

使用 workspace 方式

<br>


使用 Go Workspace 方式也非常简单,主要有以下几个步骤:


  1. 初始化 Workspace: 在项目的根目录下,使用go work init命令初始化一个新的 Workspace。这将创建一个go.work文件。

  2. 添加模块到 Workspace: 通过go work use命令,可以将一个或多个模块的路径添加到 Workspace 中。这样做可以告诉 Go 工具链在构建和测试时考虑这些模块。

  3. 构建和测试: 在 Workspace 环境中,可以像平常一样使用go buildgo test等命令,Go 工具链会自动解析 Workspace 中的模块依赖关系。


<br>


清空 service/go.mod 中的 require 和 replace 信息



cd workspace-demogo work initgo work use ./service go work use ./common
复制代码


此时会新生成一个 go.work 文件,内容为如下:



<br>


无需修改 main.go, 直接执行 go run main.go, 可输出预期结果


<br>


不仅仅是go run, 在项目目录下运行go buildgo test命令时,Go 工具链也会自动识别这两个模块之间的依赖关系,通过 Go Workspace 这种方式,一定程度上简化了涉及多个模块的项目的本地开发和测试流程,提高了开发效率。


(我感觉只是比之前 replace 的方式优雅了一点点,效率其实大差不差)


另外,go.work 需要加入到.gitignore 中,不要提交到仓库.


<br>

用户头像

fliter

关注

www.dashen.tech 2018-06-21 加入

Software Engineer. Focus on Micro Service,Containerization

评论

发布
暂无评论
Go workspace的使用_fliter_InfoQ写作社区