Go 1-18 的工作區模式

當一個項目越來越複雜的時候,一定會拆分爲多個模塊,以便進行代碼複用和更好的多人協作開發。

假設我們已經有了兩個模塊 flysnow.org/util 和 flysnow.org/product ,模塊 flysnow.org/product 依賴 flysnow.org/util 。

現在有一個需求,需要同時修改這兩個模塊,以便讓 flysnow.org/util 新增的方法給模塊 flysnow.org/product 使用。

但是當同事 A 在模塊 flysnow.org/util 中增加新的方法後,要麼推送到 VCS 中,讓負責模塊 flysnow.org/product 的同事 B 使用,這是發佈的場景。

如果模塊 flysnow.org/util 沒有發佈呢?那麼就只能通過 go.mod 中的 replace 指令進行替換,把對模塊 flysnow.org/util 的引用,換成本地的未發佈的版本,比如:

replace flysnow.org/util => /Users/flysnow/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/flysnow/go/demo/util /Users/flysnow/go/demo/product

在以上示例中,workspace 是我創建的一個工作區, 可以在你的電腦的任何地方, 名字也可以自取。

然後 go work init 後是兩個 go.mod 的絕對路徑,用空格分開,當然你也可以用相對路徑。

運行以上代碼後, 就會在 workspace 目錄下生成一個 go.work 文件,它的內容如下:

go 1.18
use (
  /Users/flysnow/go/demo/product
  /Users/flysnow/go/demo/util
)

use 是 go.work 文件的一個指令,用於管理包含的 go.mod 模塊。

除了 use 指令,go.work 還有 replace 指令,它和 go.mod 的 replace 很像,它用於把 Go 工作區間管理的 go.mod 全部替換爲指定的路徑,並且它的優先級要比 go.mod 的 replace 要高。

現在,我們用到的這兩個模塊都在同一個工作區了,那麼就不需要再修改模塊 flysnow.org/product 的 go.mod replace 指令完成本地的依賴了。

這時候,在工作區 workspce 目錄下,運行如下命令,即可進行驗證。

➜  workspace go run flysnow.org/product
你好

因爲都在一個工作區,go 可以幫你找到模塊 flysnow.org/product 所依賴的 flysnow.org/util 模塊。

如果你只是切換到 product 目錄下運行以上命令,只會提示你:

  product go run main.go 
main.go:3:8: no required module provides package flysnow.org/util; to add it:
  go get flysnow.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 中,想怎麼改就怎麼改,又不會動到所管理模塊的 go.mod,所以就不會影響其他協作的開發人員,非常安全。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/xnNjvhErkJJeZ0QFa3mvZA