Go1.18?新特性之多模塊Multi-Module工作區(qū)模式
背景
在 go 中使用多個(gè)模塊可能真的是一件苦差事。特別是當(dāng)您的一個(gè)模塊依賴(lài)于另一個(gè)模塊時(shí),您需要同時(shí)編輯這兩個(gè)模塊!
您編輯父模塊,但是然后您需要將其推送到repo。然后在依賴(lài)模塊中運(yùn)行 update 以下載新版本。最終使用2行修復(fù)您需要的。至少可以說(shuō)是一種痛苦。
在 Go 1.18之前,建議使用依賴(lài)模塊中的 replace 指令來(lái)處理這個(gè)問(wèn)題。
這個(gè)方法是有效的,但也有自己的問(wèn)題,比如需要手動(dòng)編輯 go.mod,確保你提交代碼時(shí)候,不commit 這個(gè) replace等等。
最后,從 Go 1.18開(kāi)始,引入了一種同時(shí)處理多個(gè)模塊的新方法,這種方法消除了這些問(wèn)題: go.work。
Multi-Module, Single Workspace
https://medium.com/@michael_epps/multi-module-single-workspace-3493528555ad
舉例:未發(fā)布的 module
在做本地的 Go 項(xiàng)目開(kāi)發(fā)時(shí),可能會(huì)在本地同時(shí)開(kāi)發(fā)多個(gè)庫(kù)(項(xiàng)目庫(kù)、工具庫(kù)、第三方庫(kù))等。
如下代碼:
package main import ( "github.com/eddycjy/pkgutil" ) func main() { pkgutil.PrintFish() }
我們看到:該代碼對(duì)外唯一的依賴(lài)是module path為"github.com/eddycjy/pkgutil"的module,但后者是一個(gè)尚在本地進(jìn)行開(kāi)發(fā),還未發(fā)布到http://github.com上的module。
如果這個(gè)時(shí)候運(yùn)行 go run 或是 go mod tidy,都不行,會(huì)運(yùn)行失敗。
報(bào)如下類(lèi)似錯(cuò)誤:
fatal: repository 'https://github.com/eddycjy/pkgutil/' not found
這個(gè)問(wèn)題報(bào)錯(cuò)是因?yàn)?github.com/eddycjy/pkgutil 這個(gè)庫(kù),在 GitHub 是沒(méi)有的,自然也就拉取不到。
因此,許多同學(xué)會(huì)發(fā)出靈魂質(zhì)疑:Go 的依賴(lài)都必須要上傳到 GitHub 嗎,強(qiáng)綁定?
解決方法:在 Go1.18 以前,我們會(huì)通過(guò) replace,又或是直接上傳到 Github 上,自然也就能被 Go 工具鏈拉取到依賴(lài)了。
用replace指示符將該版本指向本地的module的開(kāi)發(fā)目錄。
Go1.18 新特性:多模塊(Multi-Module)工作區(qū)模式
2022 年 3 月 15 日 go 1.18 正式發(fā)布,新版本除了對(duì)性能的提升之外,還引入了很多新功能,其中就有 go 期盼已久的功能泛型(Generics),同時(shí)還引入的多模塊工作區(qū)(Workspaces)和模糊測(cè)試(Fuzzing)。
彌補(bǔ)了當(dāng)前go module構(gòu)建模式的一些不足,堪稱(chēng)是go module構(gòu)建模式的最后一塊拼圖。
Go 多模塊工作區(qū)能夠使開(kāi)發(fā)者能夠更容易地同時(shí)處理多個(gè)模塊的工作,如:
- 方便進(jìn)行依賴(lài)的代碼調(diào)試(打斷點(diǎn)、修改代碼)、排查依賴(lài)代碼 bug
- 方便同時(shí)進(jìn)行多個(gè)倉(cāng)庫(kù)/模塊并行開(kāi)發(fā)調(diào)試
go 使用的是多模塊工作區(qū),可以讓開(kāi)發(fā)者更容易同時(shí)處理多個(gè)模塊的開(kāi)發(fā)。在 Go 1.17 之前,只能使用 go.mod replace 指令來(lái)實(shí)現(xiàn),如果你正巧是同時(shí)進(jìn)行多個(gè)模塊的開(kāi)發(fā),使用它可能是很痛苦的。每次當(dāng)你想要提交代碼的時(shí)候,都不得不刪除掉 go.mod 中的 replace 才能使模塊穩(wěn)定的發(fā)布版本。
Go1.18 工作區(qū)模式
在社區(qū)的多輪反饋下,Michael Matloob 提出了提案《Proposal: Multi-Module Workspaces in cmd/go[1]》進(jìn)行了大量的討論和實(shí)施,在 Go1.18 正式落地。
新提案的一個(gè)核心概念,就是增加了 go work 工作區(qū)的概念,針對(duì)的是 Go Module 的依賴(lài)管理模式。
這個(gè)提案引入一個(gè)go.work文件用于開(kāi)啟Go工作區(qū)模式。go.work通過(guò)directory指示符設(shè)置一些本地路徑,這些路徑下的go module構(gòu)成一個(gè)工作區(qū)(workspace),Go命令可以操作這些路徑下的go module,也會(huì)優(yōu)先使用工作區(qū)中的go module。
其能夠在本地項(xiàng)目的 go.work 文件中,通過(guò)設(shè)置一系列依賴(lài)的模塊本地路徑,再將路徑下的模塊組成一個(gè)當(dāng)前 Go 工程的工作區(qū),也就是 N 個(gè) Go Module 組成 1 個(gè) Go Work, 工作區(qū)的讀取優(yōu)先級(jí)是最高的。
總結(jié): 當(dāng)你的本地有很多module,且這些module存在相互依賴(lài),那么我們可以在這些module的外面建立一個(gè)Go工作區(qū),基于這個(gè)Go工作區(qū)開(kāi)發(fā)與調(diào)試這些module就變得十分方便。
初始化一個(gè)新的工作區(qū)
只要執(zhí)行 go work init 就可以初始化一個(gè)新的工作區(qū),后面跟的參數(shù)就是要生成的具體子模塊 mod。
命令如下:
go work init ./mod ./tools
項(xiàng)目目錄如下:
awesomeProject ├── mod │ ├── go.mod // 子模塊 │ └── main.go ├── go.work // 工作區(qū) └── tools ├── fish.go └── go.mod // 子模塊
go work 支持命令
- 通常情況下,建議不要提交 go.work 文件到 git 上,因?yàn)樗饕糜诒镜卮a開(kāi)發(fā)。
- 推薦在: $GOPATH 路徑下執(zhí)行,生成 go.work 文件
- go work init 初始化工作區(qū)文件,用于生成 go.work 工作區(qū)文件
初始化并寫(xiě)入一個(gè)新的 go.work 到當(dāng)前路徑下,可以指定需要添加的代碼模塊
示例: go work init ./hello 將本地倉(cāng)庫(kù) hello 添加到工作區(qū)
hello 倉(cāng)庫(kù)必須是 go mod 依賴(lài)管理的倉(cāng)庫(kù)(./hello/go.mod 文件必須存在)
go work use 添加新的模塊到工作區(qū)
use 指定使用的模塊目錄
命令示例:
go work use ./example 添加一個(gè)模塊到工作區(qū)
命令示例:
go work use ./example 添加一個(gè)模塊到工作區(qū) go work use ./example ./example1 添加多個(gè)模塊到工作區(qū) go work use -r ./example 遞歸 ./example 目錄到當(dāng)前工作區(qū) 刪除命令使用 go work edit -dropuse=./example 功能
可以使用 go work use hello 添加模塊,也可以手動(dòng)修改 go.work 工作區(qū)添加新的模塊
在工作區(qū)中添加了模塊路徑,編譯的時(shí)候會(huì)自動(dòng)使用 use 中的本地代碼進(jìn)行代碼編譯,和 replaces 功能類(lèi)似。
# 單模塊結(jié)構(gòu) use ./hello # 多模塊結(jié)構(gòu) use ( ./hello ./example )
go work edit 用于編輯 go.work 文件
go work edit
用于編輯 go.work 文件
可以使用 edit 命令編輯和手動(dòng)編輯 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 添加新的模塊到工作區(qū) go work edit -dropuse=./example go.work 從工作區(qū)中刪除模塊
go work sync 將工作區(qū)的構(gòu)建列表同步到工作區(qū)的模塊
go env GOWORK
查看環(huán)境變量,查看當(dāng)前工作區(qū)文件路徑
可以排查工作區(qū)文件是否設(shè)置正確,go.work 路徑找不到可以使用 GOWORK 指定
go.work 文件結(jié)構(gòu)
文件結(jié)構(gòu)和 go.mod 文件結(jié)構(gòu)類(lèi)似,支持 Go 版本號(hào)、指定工作區(qū)和需要替換的倉(cāng)庫(kù)
文件結(jié)構(gòu)示例:
go 1.18 use ( ./hello ./example ) replace ( github.com/link1st/example => ./example1 )
replaces 替換依賴(lài)倉(cāng)庫(kù)地址
replaces 命令與 go.mod 指令相同,用于替換項(xiàng)目中依賴(lài)的倉(cāng)庫(kù)地址
需要注意的是 replaces 和 use 不能同時(shí)指定相同的本地路徑
錯(cuò)誤示例
同時(shí)在 use 和 replace 指定相同的本地路徑
go 1.18 use ( ./hello ./example ) replace ( github.com/link1st/example => ./example )
go.work 文件優(yōu)先級(jí)高于 go.mod 中定義在
同時(shí)使用 go.work 和 go.mod replace 功能的的時(shí)候分別指定不同的代碼倉(cāng)庫(kù)路徑,go.work 優(yōu)先級(jí)高于 go.mod 中定義
如何禁用工作區(qū)
Go 全局變量 GOWORK 設(shè)置 off 則可以禁用工作區(qū)功能
export GOWORK=off
到此這篇關(guān)于Go1.18 新特性之多模塊Multi-Module工作區(qū)模式的文章就介紹到這了,更多相關(guān)Go多模塊工作區(qū)模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
4個(gè)場(chǎng)景教會(huì)你Go中Goroutine和通道是怎么用的
本篇給出了4個(gè)在運(yùn)維開(kāi)發(fā)工作中較為常見(jiàn)的且也是比較典型的場(chǎng)景,通過(guò)這些場(chǎng)景來(lái)帶大家掌握Go中Goroutine和通道是怎么使用的,需要的可以學(xué)習(xí)一下2023-05-05Go語(yǔ)言調(diào)用ffmpeg-api實(shí)現(xiàn)音頻重采樣
最近對(duì)golang處理音視頻很感興趣,對(duì)golang音視頻常用庫(kù)goav進(jìn)行了一番研究。自己寫(xiě)了一個(gè)wav轉(zhuǎn)采樣率的功能。給大家分享一下,中間遇到了不少坑,解決的過(guò)程中還是蠻有意思的,希望大家能喜歡2022-12-12利用go-kit組件進(jìn)行服務(wù)注冊(cè)與發(fā)現(xiàn)和健康檢查的操作
這篇文章主要介紹了利用go-kit組件進(jìn)行服務(wù)注冊(cè)與發(fā)現(xiàn)和健康檢查的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04多階段構(gòu)建優(yōu)化Go?程序Docker鏡像
這篇文章主要為大家介紹了多階段構(gòu)建優(yōu)化Go?程序Docker鏡像,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08Golang?實(shí)現(xiàn)Redis?協(xié)議解析器的解決方案
這篇文章主要介紹了Golang???實(shí)現(xiàn)?Redis?協(xié)議解析器,本文將分別介紹Redis 通信協(xié)議 以及 協(xié)議解析器 的實(shí)現(xiàn),若您對(duì)協(xié)議有所了解可以直接閱讀協(xié)議解析器部分,需要的朋友可以參考下2022-10-10