首頁 > 軟體

Go1.18 新特性之多模組Multi-Module工作區模式

2022-04-11 13:01:28

背景

在 go 中使用多個模組可能真的是一件苦差事。特別是當您的一個模組依賴於另一個模組時,您需要同時編輯這兩個模組!

您編輯父模組,但是然後您需要將其推播到repo。然後在依賴模組中執行 update 以下載新版本。最終使用2行修復您需要的。至少可以說是一種痛苦。

在 Go 1.18之前,建議使用依賴模組中的 replace 指令來處理這個問題。

這個方法是有效的,但也有自己的問題,比如需要手動編輯 go.mod,確保你提交程式碼時候,不commit 這個 replace等等。

最後,從 Go 1.18開始,引入了一種同時處理多個模組的新方法,這種方法消除了這些問題: go.work。

Multi-Module, Single Workspace
https://medium.com/@michael_epps/multi-module-single-workspace-3493528555ad

舉例:未釋出的 module

在做原生的 Go 專案開發時,可能會在本地同時開發多個庫(專案庫、工具庫、第三方庫)等。

如下程式碼:

package main
 
import (
    "github.com/eddycjy/pkgutil"
)
 
func main() {
    pkgutil.PrintFish()
}

我們看到:該程式碼對外唯一的依賴是module path為"github.com/eddycjy/pkgutil"的module,但後者是一個尚在本地進行開發,還未釋出到http://github.com上的module。

如果這個時候執行 go run 或是 go mod tidy,都不行,會執行失敗。
報如下類似錯誤:

fatal: repository 'https://github.com/eddycjy/pkgutil/' not found

這個問題報錯是因為 github.com/eddycjy/pkgutil 這個庫,在 GitHub 是沒有的,自然也就拉取不到。

因此,許多同學會發出靈魂質疑:Go 的依賴都必須要上傳到 GitHub 嗎,強繫結?

解決方法:在 Go1.18 以前,我們會通過 replace,又或是直接上傳到 Github 上,自然也就能被 Go 工具鏈拉取到依賴了。

用replace指示符將該版本指向原生的module的開發目錄。

Go1.18 新特性:多模組(Multi-Module)工作區模式

2022 年 3 月 15 日 go 1.18 正式釋出,新版本除了對效能的提升之外,還引入了很多新功能,其中就有 go 期盼已久的功能泛型(Generics),同時還引入的多模組工作區(Workspaces)和模糊測試(Fuzzing)。

彌補了當前go module構建模式的一些不足,堪稱是go module構建模式的最後一塊拼圖。

Go 多模組工作區能夠使開發者能夠更容易地同時處理多個模組的工作,如:

  • 方便進行依賴的程式碼偵錯(打斷點、修改程式碼)、排查依賴程式碼 bug
  • 方便同時進行多個倉庫/模組並行開發偵錯

go 使用的是多模組工作區,可以讓開發者更容易同時處理多個模組的開發。在 Go 1.17 之前,只能使用 go.mod replace 指令來實現,如果你正巧是同時進行多個模組的開發,使用它可能是很痛苦的。每次當你想要提交程式碼的時候,都不得不刪除掉 go.mod 中的 replace 才能使模組穩定的釋出版本。

Go1.18 工作區模式

在社群的多輪反饋下,Michael Matloob 提出了提案《Proposal: Multi-Module Workspaces in cmd/go[1]》進行了大量的討論和實施,在 Go1.18 正式落地。

新提案的一個核心概念,就是增加了 go work 工作區的概念,針對的是 Go Module 的依賴管理模式。

這個提案引入一個go.work檔案用於開啟Go工作區模式。go.work通過directory指示符設定一些本地路徑,這些路徑下的go module構成一個工作區(workspace),Go命令可以操作這些路徑下的go module,也會優先使用工作區中的go module

其能夠在本地專案的 go.work 檔案中,通過設定一系列依賴的模組本地路徑,再將路徑下的模組組成一個當前 Go 工程的工作區,也就是 N 個 Go Module 組成 1 個 Go Work, 工作區的讀取優先順序是最高的。

總結: 當你的本地有很多module,且這些module存在相互依賴,那麼我們可以在這些module的外面建立一個Go工作區,基於這個Go工作區開發與偵錯這些module就變得十分方便。

初始化一個新的工作區

只要執行 go work init 就可以初始化一個新的工作區,後面跟的引數就是要生成的具體子模組 mod。

命令如下:

go work init ./mod ./tools

專案目錄如下:

awesomeProject
├── mod
│   ├── go.mod      // 子模組
│   └── main.go
├── go.work         // 工作區
└── tools
    ├── fish.go
    └── go.mod      // 子模組
go work 支援命令
  • 通常情況下,建議不要提交 go.work 檔案到 git 上,因為它主要用於原生程式碼開發。
  • 推薦在: $GOPATH 路徑下執行,生成 go.work 檔案
  • go work init 初始化工作區檔案,用於生成 go.work 工作區檔案

初始化並寫入一個新的 go.work 到當前路徑下,可以指定需要新增的程式碼模組
範例: go work init ./hello 將本地倉庫 hello 新增到工作區
hello 倉庫必須是 go mod 依賴管理的倉庫(./hello/go.mod 檔案必須存在)

go work use 新增新的模組到工作區

use 指定使用的模組目錄

命令範例:

go work use ./example 新增一個模組到工作區

命令範例:

go work use ./example 新增一個模組到工作區
go work use ./example ./example1 新增多個模組到工作區
go work use -r ./example 遞迴 ./example 目錄到當前工作區
刪除命令使用 go work edit -dropuse=./example 功能

可以使用 go work use hello 新增模組,也可以手動修改 go.work 工作區新增新的模組
在工作區中新增了模組路徑,編譯的時候會自動使用 use 中的原生程式碼進行程式碼編譯,和 replaces 功能類似。

# 單模組結構
use ./hello
# 多模組結構
use (
    ./hello
    ./example
)
go work edit 用於編輯 go.work 檔案

go work edit 用於編輯 go.work 檔案
可以使用 edit 命令編輯和手動編輯 go.work 檔案效果是相同的
範例:

go work edit -fmt go.work 重新格式化 go.work 檔案
go work edit -replace=github.com/link1st/example=./example go.work 替換程式碼模組
go work edit -dropreplace=github.com/link1st/example 刪除替換程式碼模組
go work edit -use=./example go.work 新增新的模組到工作區
go work edit -dropuse=./example go.work 從工作區中刪除模組
go work sync 將工作區的構建列表同步到工作區的模組

go env GOWORK

檢視環境變數,檢視當前工作區檔案路徑
可以排查工作區檔案是否設定正確,go.work 路徑找不到可以使用 GOWORK 指定

go.work 檔案結構

檔案結構和 go.mod 檔案結構類似,支援 Go 版本號、指定工作區和需要替換的倉庫
檔案結構範例:

go 1.18

use (
    ./hello
    ./example
)

replace (
    github.com/link1st/example => ./example1
)

replaces 替換依賴倉庫地址
replaces 命令與 go.mod 指令相同,用於替換專案中依賴的倉庫地址
需要注意的是 replaces 和 use 不能同時指定相同的本地路徑

錯誤範例
同時在 use 和 replace 指定相同的本地路徑

go 1.18

use (
    ./hello
    ./example
)

replace (
    github.com/link1st/example => ./example
)

go.work 檔案優先順序高於 go.mod 中定義在

同時使用 go.work 和 go.mod replace 功能的的時候分別指定不同的程式碼倉庫路徑,go.work 優先順序高於 go.mod 中定義

如何禁用工作區

Go 全域性變數 GOWORK 設定 off 則可以禁用工作區功能

export GOWORK=off

到此這篇關於Go1.18 新特性之多模組Multi-Module工作區模式的文章就介紹到這了,更多相關Go多模組工作區模式內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com