yan's blog

Go Workspace 简介

在 Go 1.18 发布之后,新增了一个功能,Go workspace。以下是对这个功能的简单介绍。

为什么需要 go workspace

在 Go 1.18 之前的版本,如果你想引用另外一个本地 module A,有两种方法

  1. 将要引用的那个 module push
  2. 在当前项目中,用 replace 来指定引用的 module 为本地路径

这样做会带来一些问题

  1. 某些情况下,你无法 push 代码到远程仓库,这样上面的方法 1 就无法使用了
  2. 当你使用方法2的时候,需要手动去修改 go.mod 文件,添加 replace。而当 module A 被 push 之后,你还要记得把当前项目的 go.mod 文件中的 replace 去掉。

是不是感觉很麻烦?并且好多操作是需要人去确认的,不仅不适合自动化也容易出错。Go 1.18 推出的 workspace 功能,就很好的解决了这个问题。

一个简单的场景介绍

你在开发一个项目,需要用到其他人的 module,你需要在他的 module 上新增一些功能,以便于你正在开发的项目能用到。

比如你用到了 golang.org/x/example/stringutil,这个里面目前只有一个 Reverse 函数用来反转字符串。你需要在这个 module 上新增一个 Upper 函数用来将字符串转换为全部大写。

  1. 新建文件夹 workspace-tour,用来做 workspace
  2. 进入 workspace 目录,clone golang.org/x/example 的代码。
  3. 进入 example 目录,也就是我们依赖的 module 的目录。在 stringutil/reverse.go 中新增一个函数 Upper
  4. 进入 workspace 目录,创建你的项目,如
    mkdir workspace-tour/my-project
    cd my-project
    go mod init github.com/wilkice/workspace-tour
    
  5. 我们这边就只创建一个最简单的main.go文件,文件内容如下
    package main
    
    import (
       "fmt"
      "golang.org/x/example/stringutil"
    )
    
    func main() {
      fmt.Println(stringutil.Upper("hello, world"))
      }
    
  6. 接下来我们进入到 workspace-tour目录,执行 go work use ./example ./my-project 初始化 worksapce,执行完成会在此目录下生成一个 go.work文件。你如果查看这个文件的话,会发现它和 go.mod十分相似。
  7. 好了,现在我们可以直接进入 my-project 目录,执行 go run main.go 就可以看到我们新增的函数被调用了。不用修改 go.mod,是不是很方便?
  8. 假如你使用这个 Upper函数之后觉得很好用,于是提了一个 PR,人家也接受了。因为后面可能会用到 golang.org/x/example 的其他函数,你准备不用你本地的那个clone 的 example代码了。这个时候,只需要把 go.work 文件删除或者从 go.work 里面移除 example 这个目录。当你下次在 my-project 目录下执行 go run main.go,就会使用 golang.org/x/example 而不会使用你本地的了。

总结

应用场景

在我看来,目前主要有两个应用场景

  1. 本地离线开发。有些 module 因为某些原因,不能 push 到任何仓库上,那么用 workspace 就会方便很多。因为你不用每做一个项目,就去手动修改 go.mod 了。你只需要在新建一个目录,把离线的这个 repo 放在这里。有新的项目需要用到这个 module 的时候,就在这个目录下建新的项目。
  2. 你fork 了一份别人的 module,然后在上面新增了某个功能。之所以这里能用上 workspace 是因为你新增的这个功能如果在原 module 上有了实现(比如你提了一个 PR),那么你可以很快的切换过去,只需要把 go.work 删除就可以了。

参考资料

Get familiar with workspaces - The Go Programming Language Tutorial: Getting started with multi-module workspaces