Go 部落格

熟悉工作區

Beth Brown,Go 團隊成員
2022年4月5日

Go 1.18 向 Go 添加了工作區模式,允許您同時處理多個模組。

您可以透過訪問下載頁面獲取 Go 1.18。發行說明中提供了所有更改的更多詳細資訊。

工作區

Go 1.18 中的工作區允許您同時處理多個模組,而無需為每個模組編輯 go.mod 檔案。工作區內的每個模組在解決依賴關係時都被視為主要模組。

以前,要在某個模組中新增一個特性並在另一個模組中使用它,您需要釋出第一個模組的更改,或者使用 replace 指令編輯依賴模組的 go.mod 檔案,指向您本地未釋出的模組更改。為了在釋出時不出錯,您必須在將本地更改釋出到第一個模組後,從依賴模組的 go.mod 檔案中移除 replace 指令。

使用 Go 工作區,您可以在工作區目錄的根目錄下使用 go.work 檔案控制所有依賴關係。go.work 檔案具有覆蓋單個 go.mod 檔案的 usereplace 指令,因此無需單獨編輯每個 go.mod 檔案。

您可以透過執行 go work init 命令並將其後跟以空格分隔的模組目錄列表來建立工作區。工作區無需包含您正在使用的模組。init 命令建立一個 go.work 檔案,其中列出了工作區中的模組。如果您不帶引數執行 go work init,該命令將建立一個空工作區。

要將模組新增到工作區,請執行 go work use [moddir] 或手動編輯 go.work 檔案。執行 go work use -r . 可以遞迴地將引數目錄中包含 go.mod 檔案的目錄新增到您的工作區。如果某個目錄沒有 go.mod 檔案或不再存在,則該目錄的 use 指令將從您的 go.work 檔案中移除。

go.work 檔案的語法類似於 go.mod 檔案,幷包含以下指令:

  • go: Go 工具鏈版本,例如 go 1.18
  • use: 將磁碟上的模組新增到工作區中的主要模組集。其引數是包含模組 go.mod 檔案的目錄的相對路徑。use 指令不會新增指定目錄子目錄中的模組。
  • replace: 類似於 go.mod 檔案中的 replace 指令,go.work 檔案中的 replace 指令用其他位置的內容替換模組的特定版本或模組的所有版本的內容。

工作流程

工作區具有靈活性,支援各種工作流程。以下章節簡要概述了我們認為最常見的幾種。

向上遊模組新增特性並在您自己的模組中使用它

  1. 為您的工作區建立一個目錄。

  2. 克隆您想要編輯的上游模組。

  3. 將您的特性新增到上游模組的本地版本中。

  4. 在工作區資料夾中執行 go work init [path-to-upstream-mod-dir]

  5. 修改您自己的模組,以便實現新增到上游模組的特性。

  6. 在工作區資料夾中執行 go work use [path-to-your-module]

    go work use 命令將您的模組路徑新增到您的 go.work 檔案中

    go 1.18
    
    use (
           ./path-to-upstream-mod-dir
           ./path-to-your-module
    )
    
  7. 使用新增到上游模組的新特性執行並測試您的模組。

  8. 釋出包含新特性的上游模組。

  9. 釋出使用新特性的您的模組。

在同一個倉庫中處理多個相互依賴的模組

在同一個倉庫中處理多個模組時,由 go.work 檔案定義工作區,而不是在每個模組的 go.mod 檔案中使用 replace 指令。

  1. 為您的工作區建立一個目錄。

  2. 克隆包含您想要編輯的模組的倉庫。模組不必位於您的工作區資料夾中,因為您可以使用 use 指令指定到每個模組的相對路徑。

  3. 在您的工作區目錄中執行 go work init [path-to-module-one] [path-to-module-two]

    示例:您正在處理 example.com/x/tools/groundhog,它依賴於 example.com/x/tools 模組中的其他軟體包。

    您克隆倉庫,然後在您的工作區資料夾中執行 go work init tools tools/groundhog

    您的 go.work 檔案的內容類似於以下內容

    go 1.18
    
    use (
            ./tools
            ./tools/groundhog
    )
    

    tools 模組中進行的任何本地更改都將被工作區中的 tools/groundhog 使用。

切換依賴配置

要使用不同的依賴配置測試您的模組,您可以建立多個帶有獨立 go.work 檔案的工作區,或者保留一個工作區並在單個 go.work 檔案中註釋掉您不想要的 use 指令。

建立多個工作區

  1. 為不同的依賴需求建立單獨的目錄。
  2. 在您的每個工作區目錄中執行 go work init
  3. 透過 go work use [path-to-dependency] 在每個目錄中新增您想要的依賴。
  4. 在每個工作區目錄中執行 go run [path-to-your-module],以使用其 go.work 檔案指定的依賴。

要在同一個工作區中測試不同的依賴,請開啟 go.work 檔案並新增或註釋掉所需的依賴。

還在使用 GOPATH 嗎?

也許使用工作區會改變您的想法。GOPATH 使用者可以使用位於其 GOPATH 目錄基礎的 go.work 檔案來解析依賴關係。工作區不旨在完全重新建立所有 GOPATH 工作流程,但它們可以建立一種設定,該設定共享 GOPATH 的部分便利性,同時仍然提供模組的好處。

為 GOPATH 建立工作區

  1. 在您的 GOPATH 目錄的根目錄下執行 go work init
  2. 要在您的工作區中使用本地模組或特定版本作為依賴,請執行 go work use [path-to-module]
  3. 要替換模組 go.mod 檔案中現有的依賴,請使用 go work replace [path-to-module]
  4. 要新增 GOPATH 或任何目錄中的所有模組,請執行 go work use -r 遞迴地將包含 go.mod 檔案的目錄新增到您的工作區。如果某個目錄沒有 go.mod 檔案或不再存在,則該目錄的 use 指令將從您的 go.work 檔案中移除。

注意:如果您有不帶 go.mod 檔案但想要新增到工作區的專案,請進入其專案目錄並執行 go mod init,然後使用 go work use [path-to-module] 將新模組新增到您的工作區。

工作區命令

除了 go work initgo work use 之外,Go 1.18 還為工作區引入了以下命令:

  • go work sync: 將 go.work 檔案中的依賴關係同步回每個工作區模組的 go.mod 檔案。
  • go work edit: 提供一個命令列介面用於編輯 go.work,主要供工具或指令碼使用。

模組感知構建命令和一些 go mod 子命令會檢查 GOWORK 環境變數,以確定它們是否處於工作區上下文中。

如果 GOWORK 變數指定的檔案路徑以 .work 結尾,則啟用工作區模式。要確定正在使用哪個 go.work 檔案,請執行 go env GOWORK。如果 go 命令未處於工作區模式,則輸出為空。

啟用工作區模式後,將解析 go.work 檔案以確定工作區模式的三個引數:Go 版本、目錄列表和替換列表。

在工作區模式下可以嘗試的一些命令(前提是您已經知道它們的作用!):

go work init
go work sync
go work use
go list
go build
go test
go run
go vet

編輯器體驗改進

我們對 Go 語言伺服器 goplsVSCode Go 擴充套件的升級感到特別興奮,這些升級使得在相容 LSP 的編輯器中處理多個模組成為一種順暢且有益的體驗。

查詢引用、程式碼補全和跳轉到定義在工作區內的模組之間正常工作。版本 0.8.1gopls 引入了針對 go.work 檔案的診斷、補全、格式化和懸停功能。您可以在任何 LSP 相容的編輯器中利用這些 gopls 特性。

編輯器特定說明

  • 最新的 vscode-go 版本允許透過 Go 狀態列的 Quick Pick 選單快速訪問工作區的 go.work 檔案。

Access the go.work file via the Go status bar’s Quick Pick menu

  • GoLand 支援工作區,並計劃為 go.work 檔案新增語法高亮和程式碼補全。

有關在不同編輯器中使用 gopls 的更多資訊,請參閱 gopls文件

下一步?

下一篇文章:何時使用泛型
上一篇文章:Go 如何緩解供應鏈攻擊
部落格索引