管理相依性
當您的程式碼使用外部套件時,那些套件(以模組的形式發行)就會成為相依性。隨著時間推移,您可能需要升級或取代它們。Go 提供相依性管理工具,協助您在納入外部相依性時,保持 Go 應用程式的安全性。
本主題說明如何執行任務,以管理您在程式碼中承擔的相依性。您可以使用 Go 工具執行其中大部分任務。本主題也說明如何執行其他一些您可能會覺得有用的相依性相關任務。
另請參閱
- 如果您是第一次使用模組處理相依性,請參閱 入門教學 以取得簡要介紹。
- 使用
go
指令管理相依性有助於確保您的需求保持一致,且 go.mod 檔案的內容有效。如需指令的參考資訊,請參閱 go 指令。您也可以輸入go help
指令名稱 從指令列取得說明,例如go help mod tidy
。 - 您用來變更相依性的 Go 指令會編輯您的 go.mod 檔案。如需檔案內容的詳細資訊,請參閱 go.mod 檔案參考。
- 讓您的編輯器或 IDE 認識 Go 模組可以讓管理模組的工作更輕鬆。如需支援 Go 的編輯器的詳細資訊,請參閱 編輯器外掛程式和 IDE。
- 這個主題沒有說明如何開發、發布和版本化模組供其他人使用。如需詳細資訊,請參閱 開發和發布模組。
使用和管理相依性的工作流程
您可以使用 Go 工具取得和使用有用的套件。在 pkg.go.dev 上,您可以搜尋您可能覺得有用的套件,然後使用 go
指令將這些套件匯入您自己的程式碼中以呼叫其函式。
下列列出最常見的相依性管理步驟。如需每個步驟的詳細資訊,請參閱本主題中的各個區段。
- 在 pkg.go.dev 上找出有用的套件。
- 在您的程式碼中匯入您想要的套件。
- 將你的程式碼加入模組以進行相依性追蹤(如果它還不在模組中)。請參閱啟用相依性追蹤
- 加入外部套件作為相依性,以便你可以管理它們。
- 升級或降級相依性版本,以符合隨著時間推移的需求。
將相依性管理為模組
在 Go 中,你可以將相依性管理為包含你匯入套件的模組。此程序由下列項目支援:
- 一個分散式系統,用於發布模組並擷取其程式碼。開發人員讓其他開發人員可以從自己的儲存庫使用其模組,並使用版本號發布。
- 一個套件搜尋引擎和文件瀏覽器 (pkg.go.dev),你可以在其中找到模組。請參閱尋找並匯入有用的套件。
- 一個模組版本編號慣例,以幫助你了解模組的穩定性和向後相容性保證。請參閱模組版本編號。
- Go 工具,讓你可以更輕鬆地管理相依性,包括取得模組的來源、升級等。請參閱本主題的各節以取得更多資訊。
尋找並匯入有用的套件
你可以搜尋pkg.go.dev,以找到具有你可能覺得有用的函式的套件。
當你找到要在程式碼中使用的套件時,請找到頁面頂端的套件路徑,然後按一下「複製路徑」按鈕,將路徑複製到你的剪貼簿。在你的程式碼中,將路徑貼到匯入陳述式中,如下例所示
import "rsc.io/quote"
在你的程式碼匯入套件後,請啟用相依性追蹤並取得套件的程式碼以進行編譯。如需更多資訊,請參閱在你的程式碼中啟用相依性追蹤和加入相依性。
在你的程式碼中啟用相依性追蹤
若要追蹤和管理你加入的相依性,你可以先將你的程式碼放入其自己的模組中。這會在你的來源樹的根目錄建立一個 go.mod 檔案。你加入的相依性會列在該檔案中。
若要將程式碼新增至其自己的模組,請使用 go mod init
命令。例如,從命令列變更至程式碼的根目錄,然後執行命令,如下例所示
$ go mod init example/mymodule
go mod init
命令的參數是模組的模組路徑。如果可以,模組路徑應為原始碼的儲存庫位置。
如果您一開始不知道模組最終的儲存庫位置,請使用安全的替代方案。這可能是您擁有的網域名稱或您控制的其他名稱(例如您的公司名稱),以及從模組名稱或原始碼目錄中繼承的路徑。有關詳細資訊,請參閱 命名模組。
當您使用 Go 工具管理依賴項時,這些工具會更新 go.mod 檔案,以便維護依賴項的最新清單。
當您新增依賴項時,Go 工具也會建立 go.sum 檔案,其中包含您依賴的模組的檢查總和。Go 使用此檔案來驗證已下載模組檔案的完整性,特別是針對其他開發人員在您的專案上作業時。
將 go.mod 和 go.sum 檔案與程式碼一起包含在您的儲存庫中。
請參閱 go.mod 參考 以取得更多資訊。
命名模組
當您執行 go mod init
來建立模組以追蹤依賴項時,您會指定一個模組路徑作為模組的名稱。模組路徑會成為模組中套件的匯入路徑前綴。請務必指定一個不會與其他模組的模組路徑衝突的模組路徑。
模組路徑至少需要指出其來源,例如公司或作者或擁有者名稱。但路徑也可能更詳細地說明模組是什麼或具有什麼功能。
模組路徑通常具有下列格式
<prefix>/<descriptive-text>
-
前綴通常是部分描述模組的字串,例如描述其來源的字串。這可能是
-
Go 工具可找到模組原始碼的儲存庫位置(如果您要發布模組,則需要)。
例如,可能是
github.com/<project-name>/
。如果您認為可能會發布模組供其他人使用,請使用此最佳實務。如需發布的更多資訊,請參閱 開發和發布模組。
-
您控制的名稱。
如果您未使用儲存庫名稱,請務必選擇您確信不會被其他人使用的前綴。一個好的選擇是您公司的名稱。避免使用常見的術語,例如
widgets
、utilities
或app
。
-
-
對於描述性文字,一個好的選擇是專案名稱。請記住,套件名稱承載了描述功能的大部分權重。模組路徑為這些套件名稱建立命名空間。
保留的模組路徑前綴
Go 保證以下字串不會用於套件名稱中。
-
test
– 您可以將test
作為模組路徑前綴,用於其程式碼設計為在另一個模組中測試函式的模組。對於作為測試的一部分而建立的模組,請使用
test
路徑前綴。例如,您的測試本身可能會執行go mod init test
,然後以特定方式設定該模組,以便使用 Go 原始碼分析工具進行測試。 -
example
– 用於一些 Go 文件中的模組路徑前綴,例如在您建立模組只是為了追蹤依賴項的自學課程中。請注意,Go 文件也使用
example.com
來說明範例可能是已發布的模組的情況。
新增相依性
一旦您從已發佈的模組匯入套件,您可以使用 go get
指令 將該模組新增為相依性進行管理。
該指令會執行下列動作
-
如果需要,它會在您的 go.mod 檔案中為指令列中指定的套件名稱新增
require
指令。require
指令會追蹤您的模組所依賴的模組的最低版本。請參閱 go.mod 參考 以取得更多資訊。 -
如果需要,它會下載模組原始碼,讓您可以編譯依賴它們的套件。它可以從模組代理程式(例如 proxy.golang.org)或直接從版本控制存放庫下載模組。原始碼會快取在本地。
您可以設定 Go 工具下載模組的位置。如需更多資訊,請參閱 指定模組代理伺服器。
以下說明幾個範例。
-
若要新增模組中套件的所有相依性,請執行類似下列指令的指令(「.」是指目前目錄中的套件)
$ go get .
-
若要新增特定相依性,請將其模組路徑指定為指令的引數。
$ go get example.com/theirmodule
該指令也會驗證它下載的每個模組。這可確保它與模組發佈時相同。如果模組在發佈後已變更(例如,開發人員變更提交內容),Go 工具會顯示安全性錯誤。此驗證檢查可保護您免於遭到可能已遭竄改的模組影響。
取得特定相依性版本
您可以透過在 go get
指令中指定相依性模組的版本,來取得該模組的特定版本。該指令會更新 go.mod 檔案中的 require
指令(不過您也可以手動更新)。
您可能想要執行此操作,如果
- 您想要取得模組的特定預發行版本來試用。
- 您發現您目前需要的版本無法為您運作,因此您想要取得您知道可以依賴的版本。
- 您想要升級或降級您已要求的模組。
以下是使用 go get
命令 的範例
-
若要取得特定編號版本,請附加模組路徑,後面加上 @ 符號,後接您要的版本
$ go get example.com/theirmodule@v1.3.4
-
若要取得最新版本,請附加模組路徑,後面加上
@latest
$ go get example.com/theirmodule@latest
下列 go.mod 檔案 require
指令範例(請參閱 go.mod 參考 以取得更多資訊)說明如何要求特定版本號碼
require example.com/theirmodule v1.3.4
找出可用的更新
您可以查看您目前模組中已使用的依賴項是否有較新版本。使用 go list
命令顯示模組依賴項的清單,以及該模組可用的最新版本。找出可用的升級後,您可以使用您的程式碼試用它們,以決定是否升級到新版本。
有關 go list
命令的更多資訊,請參閱 go list -m
。
以下是幾個範例。
-
列出您目前模組所有依賴項的模組,以及每個模組可用的最新版本
$ go list -m -u all
-
顯示特定模組可用的最新版本
$ go list -m -u example.com/theirmodule
升級或降級依賴項
您可以使用 Go 工具找出可用的版本,然後新增不同版本作為依賴項,以升級或降級依賴項模組。
同步您的程式碼依賴項
您可以確保管理所有程式碼的已匯入套件的相依性,同時移除不再匯入的套件相依性。
當您對程式碼和相依性進行變更時,這項功能會很有用,可能會建立一個受管理的相依性和已下載模組的集合,不再與程式碼中匯入的套件特別需要的集合相符。
若要保持受管理的相依性設定井然有序,請使用 go mod tidy
指令。此指令會使用程式碼中匯入的套件集合,編輯您的 go.mod 檔案,以新增必要的但遺失的模組。它也會移除未使用的模組,這些模組不會提供任何相關套件。
此指令沒有任何引數,只有一個旗標 -v,用於列印已移除模組的資訊。
$ go mod tidy
針對未發布的模組程式碼進行開發和測試
您可以指定您的程式碼應使用可能未發布的相依性模組。這些模組的程式碼可能位於其各自的儲存庫中,在這些儲存庫的分支中,或與使用它們的目前模組位於同一個磁碟機中。
您可能想在下列情況下執行此操作
- 您想要對外部模組的程式碼進行自己的變更,例如在分岔和/或複製它之後。例如,您可能想要準備一個模組的修正程式,然後將它作為拉取請求傳送給模組的開發人員。
- 您正在建置一個新的模組,但尚未發布它,因此它在
go get
指令可以存取的儲存庫中不可用。
在本地目錄中需要模組程式碼
您可以指定所需模組的程式碼與需要它的程式碼位於同一個本機磁碟機上。當您
- 開發您自己的獨立模組,並想從目前的模組進行測試時,您可能會覺得這很有用。
- 修正外部模組中的問題或新增功能,並想從目前的模組進行測試時。(請注意,您也可以從您自己的儲存庫分支中需要外部模組。如需更多資訊,請參閱從您自己的儲存庫分支中需要外部模組程式碼。)
若要指示 Go 指令使用模組程式碼的本機副本,請在 go.mod 檔案中使用 replace
指令,以取代 require
指令中提供的模組路徑。請參閱go.mod 參考,以進一步了解指令。
在以下 go.mod 檔案範例中,目前的模組需要外部模組 example.com/theirmodule
,並使用不存在的版本號碼 (v0.0.0-unpublished
) 來確保取代作業正確運作。然後,replace
指令會將原始模組路徑取代為 ../theirmodule
,這個目錄與目前的模組目錄位於同一層級。
module example.com/mymodule
go 1.16
require example.com/theirmodule v0.0.0-unpublished
replace example.com/theirmodule v0.0.0-unpublished => ../theirmodule
在設定 require
/replace
配對時,請使用go mod edit
和go get
指令,以確保檔案所描述的需求保持一致
$ go mod edit -replace=example.com/theirmodule@v0.0.0-unpublished=../theirmodule
$ go get example.com/theirmodule@v0.0.0-unpublished
注意:當您使用 replace 指令時,Go 工具不會驗證外部模組,如新增相依性中所述。
如需有關版本號碼的更多資訊,請參閱模組版本編號。
從您自己的儲存庫分支中需要外部模組程式碼
當您已分岔外部模組的儲存庫(例如,修正模組程式碼中的問題或新增功能)時,您可以讓 Go 工具使用您的分支作為模組的來源。這對於從您自己的程式碼測試變更很有用。(請注意,您也可以在需要它的模組的本機磁碟機上的目錄中需要模組程式碼。如需更多資訊,請參閱在本地目錄中需要模組程式碼。)
您可以透過在 go.mod 檔案中使用 replace
指令,將外部模組的原始模組路徑替換為儲存庫中分岔的路徑來執行此操作。這會指示 Go 工具在編譯時使用替換路徑(分岔的位置),例如,同時允許您將 import
陳述式保留為原始模組路徑。
如需有關 replace
指令的更多資訊,請參閱 go.mod 檔案參考。
在以下 go.mod 檔案範例中,目前的模組需要外部模組 example.com/theirmodule
。然後,replace
指令會將原始模組路徑替換為 example.com/myfork/theirmodule
,這是模組自己儲存庫的分岔。
module example.com/mymodule
go 1.16
require example.com/theirmodule v1.2.3
replace example.com/theirmodule v1.2.3 => example.com/myfork/theirmodule v1.2.3-fixed
在設定 require
/replace
配對時,請使用 Go 工具指令來確保檔案所描述的要求保持一致。使用 go list
指令取得目前模組所使用的版本。然後使用 go mod edit
指令將所需的模組替換為分岔
$ go list -m example.com/theirmodule
example.com/theirmodule v1.2.3
$ go mod edit -replace=example.com/theirmodule@v1.2.3=example.com/myfork/theirmodule@v1.2.3-fixed
注意:當您使用 replace
指令時,Go 工具不會驗證外部模組,如 新增相依性 中所述。
如需有關版本號碼的更多資訊,請參閱模組版本編號。
使用儲存庫識別碼取得特定提交
您可以使用 go get
指令從其儲存庫中的特定提交新增模組的未發佈程式碼。
為執行此操作,請使用 go get
指令,並使用 @
符號指定您要的程式碼。當您使用 go get
時,指令會在您的 go.mod 檔案中新增 require
指令,該指令需要外部模組,並使用基於提交詳細資料的偽版本號碼。
以下範例提供一些說明。這些範例基於來源在 git 儲存庫中的模組。
-
若要取得特定提交的模組,請附加 @commithash 表單
$ go get example.com/theirmodule@4cf76c2
-
若要取得特定分支的模組,請附加 @branchname 表單
$ go get example.com/theirmodule@bugfixes
移除相依性
當您的程式碼不再使用模組中的任何套件時,您可以停止追蹤模組作為相依性。
若要停止追蹤所有未使用的模組,請執行 go mod tidy
指令。此指令也可能會新增建置模組中套件所需的遺漏相依性。
$ go mod tidy
若要移除特定相依性,請使用 go get
指令,指定模組的模組路徑並附加 @none
,如下例所示
$ go get example.com/theirmodule@none
go get
指令也會將相依於已移除模組的其他相依性降級或移除。
指定模組代理伺服器
當您使用 Go 工具處理模組時,這些工具會預設從 proxy.golang.org(一個 Google 營運的公開模組鏡像)或直接從模組的儲存庫下載模組。您可以指定 Go 工具改為使用其他代理伺服器來下載和驗證模組。
如果您(或您的團隊)已設定或選取要使用的不同模組代理伺服器,您可能想要這麼做。例如,有些人會設定模組代理伺服器,以便更能控制相依性的使用方式。
若要為 Go 工具指定其他模組代理伺服器,請將 GOPROXY
環境變數設定為一個或多個伺服器的 URL。Go 工具會依您指定的順序嘗試每個 URL。預設情況下,GOPROXY
會先指定一個 Google 營運的公開模組代理伺服器,然後直接從模組的儲存庫(如其模組路徑中所指定)下載(如其模組路徑中所指定)
GOPROXY="https://proxy.golang.org,direct"
如需瞭解更多關於 GOPROXY
環境變數的資訊,包括支援其他行為的值,請參閱 go
指令參考。
您可以將變數設定為其他模組代理伺服器的 URL,並使用逗號或直線分隔 URL。
-
當您使用逗號時,Go 工具只會在目前的 URL 傳回 HTTP 404 或 410 時,才會嘗試清單中的下一個 URL。
GOPROXY="https://proxy.example.com,https://proxy2.example.com"
-
當您使用管線時,Go 工具會嘗試清單中的下一個 URL,而不管 HTTP 錯誤碼為何。
GOPROXY="https://proxy.example.com|https://proxy2.example.com"
Go 模組經常在版本控制伺服器和模組代理程式上開發和散佈,而這些伺服器和代理程式並未在公共網際網路上提供。您可以設定 GOPRIVATE
環境變數,以設定 go
指令從私人來源下載和建置模組。然後,go 指令便可以從私人來源下載和建置模組。
GOPRIVATE
或 GONOPROXY
環境變數可以設定為與私人模組前綴相符的 glob 模式清單,且不應從任何代理程式要求這些前綴。例如
GOPRIVATE=*.corp.example.com,*.research.example.com