管理相依性

當您的程式碼使用外部套件時,那些套件(以模組的形式發行)就會成為相依性。隨著時間推移,您可能需要升級或取代它們。Go 提供相依性管理工具,協助您在納入外部相依性時,保持 Go 應用程式的安全性。

本主題說明如何執行任務,以管理您在程式碼中承擔的相依性。您可以使用 Go 工具執行其中大部分任務。本主題也說明如何執行其他一些您可能會覺得有用的相依性相關任務。

另請參閱

使用和管理相依性的工作流程

您可以使用 Go 工具取得和使用有用的套件。在 pkg.go.dev 上,您可以搜尋您可能覺得有用的套件,然後使用 go 指令將這些套件匯入您自己的程式碼中以呼叫其函式。

下列列出最常見的相依性管理步驟。如需每個步驟的詳細資訊,請參閱本主題中的各個區段。

  1. pkg.go.dev 上找出有用的套件。
  2. 在您的程式碼中匯入您想要的套件
  3. 將你的程式碼加入模組以進行相依性追蹤(如果它還不在模組中)。請參閱啟用相依性追蹤
  4. 加入外部套件作為相依性,以便你可以管理它們。
  5. 升級或降級相依性版本,以符合隨著時間推移的需求。

將相依性管理為模組

在 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 保證以下字串不會用於套件名稱中。

新增相依性

一旦您從已發佈的模組匯入套件,您可以使用 go get 指令 將該模組新增為相依性進行管理。

該指令會執行下列動作

以下說明幾個範例。

該指令也會驗證它下載的每個模組。這可確保它與模組發佈時相同。如果模組在發佈後已變更(例如,開發人員變更提交內容),Go 工具會顯示安全性錯誤。此驗證檢查可保護您免於遭到可能已遭竄改的模組影響。

取得特定相依性版本

您可以透過在 go get 指令中指定相依性模組的版本,來取得該模組的特定版本。該指令會更新 go.mod 檔案中的 require 指令(不過您也可以手動更新)。

您可能想要執行此操作,如果

以下是使用 go get 命令 的範例

下列 go.mod 檔案 require 指令範例(請參閱 go.mod 參考 以取得更多資訊)說明如何要求特定版本號碼

require example.com/theirmodule v1.3.4

找出可用的更新

您可以查看您目前模組中已使用的依賴項是否有較新版本。使用 go list 命令顯示模組依賴項的清單,以及該模組可用的最新版本。找出可用的升級後,您可以使用您的程式碼試用它們,以決定是否升級到新版本。

有關 go list 命令的更多資訊,請參閱 go list -m

以下是幾個範例。

升級或降級依賴項

您可以使用 Go 工具找出可用的版本,然後新增不同版本作為依賴項,以升級或降級依賴項模組。

  1. 若要找出新版本,請使用 找出可用的更新 中所述的 go list 命令。

  2. 若要新增特定版本作為依賴項,請使用 取得特定依賴項版本 中所述的 go get 命令。

同步您的程式碼依賴項

您可以確保管理所有程式碼的已匯入套件的相依性,同時移除不再匯入的套件相依性。

當您對程式碼和相依性進行變更時,這項功能會很有用,可能會建立一個受管理的相依性和已下載模組的集合,不再與程式碼中匯入的套件特別需要的集合相符。

若要保持受管理的相依性設定井然有序,請使用 go mod tidy 指令。此指令會使用程式碼中匯入的套件集合,編輯您的 go.mod 檔案,以新增必要的但遺失的模組。它也會移除未使用的模組,這些模組不會提供任何相關套件。

此指令沒有任何引數,只有一個旗標 -v,用於列印已移除模組的資訊。

$ go mod tidy

針對未發布的模組程式碼進行開發和測試

您可以指定您的程式碼應使用可能未發布的相依性模組。這些模組的程式碼可能位於其各自的儲存庫中,在這些儲存庫的分支中,或與使用它們的目前模組位於同一個磁碟機中。

您可能想在下列情況下執行此操作

在本地目錄中需要模組程式碼

您可以指定所需模組的程式碼與需要它的程式碼位於同一個本機磁碟機上。當您

若要指示 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 editgo 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 儲存庫中的模組。

移除相依性

當您的程式碼不再使用模組中的任何套件時,您可以停止追蹤模組作為相依性。

若要停止追蹤所有未使用的模組,請執行 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 模組經常在版本控制伺服器和模組代理程式上開發和散佈,而這些伺服器和代理程式並未在公共網際網路上提供。您可以設定 GOPRIVATE 環境變數,以設定 go 指令從私人來源下載和建置模組。然後,go 指令便可以從私人來源下載和建置模組。

GOPRIVATEGONOPROXY 環境變數可以設定為與私人模組前綴相符的 glob 模式清單,且不應從任何代理程式要求這些前綴。例如

GOPRIVATE=*.corp.example.com,*.research.example.com