Go 1.16 中 Module 功能新變化
原文地址:https://blog.golang.org/go116-module-changes
原文作者:Jay Conrod
譯者:Kevin
希望您喜歡 Go 1.16! 這個版本有很多新功能,特別是對 Module 而言。發行說明中簡要介紹了這些變化,但讓我們深入發掘一下其中的一些變化。
Module 功能預設開啟
go 命令現在預設以 module-aware 模式構建包,即使沒有go.mod
檔案存在。這是向在所有專案中使用 Module 功能邁出的一大步。
通過設定GO111MODULE
環境變數為off
,仍然可以在GOPATH
模式下構建包。你也可以將GO111MODULE
設定為auto
,只有噹噹前目錄或任何父目錄中存在go.mod
檔案時才啟用 module-aware 模式。這在以前是預設的。請注意,您可以使用go env -w
來永久地設定GO111MODULE
和其他變數。
go env -w GO111MODULE=auto
我們計劃在 Go 1.17 中放棄對GOPATH
模式的支援。換句話說,Go 1.17 將忽略GO111MODULE
。如果您的專案沒有以 module-aware 模式構建,現在是時候遷移了。如果有問題妨礙您遷移,請考慮提交問題或體驗報告。
不會自動更改 go.mod 和 go.sum
在之前的版本中,當go
命令發現go.mod
或go.sum
有問題時,比如缺少require
指令或缺少sum
,它會嘗試自動修復問題。我們收到了很多反饋,認為這種行為是出乎大家意料的,尤其是對於像go list
這樣通常不會產生副作用的命令。自動修復並不總是可取的:如果一個匯入的包沒有被任何需要的 Module 提供,go
命令會新增一個新的依賴關係,可能會觸發普通依賴關係的升級。即使是拼寫錯誤的匯入路徑也會導致(失敗的)網路查詢。
在 Go 1.16 中,module-aware 命令在發現go.mod
或go.sum
中的問題後會報告一個錯誤,而不是嘗試自動修復問題。在大多數情況下,錯誤資訊建議使用命令來修復問題。
$ go build
example.go:3:8: no required module provides package golang.org/x/net/html; to add it:
go get golang.org/x/net/html
$ go get golang.org/x/net/html
$ go build
和之前一樣,如果存在vendor
目錄,go
命令可能會使用該目錄(詳見Vendoring
)。像go get
和go mod tidy
這樣的命令仍然會修改go.mod
和go.sum
,因為它們的主要目的是管理依賴關係。
在特定版本上安裝可執行檔案
go install
命令現在可以通過指定@version
字尾來安裝特定版本的可執行檔案。
go install golang.org/x/tools/gopls@v0.6.5
當使用這種語法時,go install
命令會從該 Module 的制定版本安裝,而忽略當前目錄和父目錄中的任何 go.mod 檔案。(如果沒有@version字尾,go install 會像往常一樣繼續執行,使用當前 Module 的 go.mod 中列出的版本要求和替換來構建程式。)
我們曾經推薦使用go get -u
程式來安裝可執行檔案,但這種使用方式對go.mod
中新增或更改 Module 版本需求的意義造成了太多的混淆。而為了避免意外修改go.mod
,人們開始建議使用更復雜的命令,比如:
cd $HOME; GO111MODULE=on go get program@latest
現在我們都可以用go install program@latest
來代替。詳情請看go install。
為了消除使用哪個版本的歧義,當使用這種安裝語法時,對程式的 go.mod 檔案中可能存在的指令有一些限制。特別是,至少在目前,替換和排除指令是不允許的。從長遠來看,一旦新的go install program@version
在足夠多的用例中執行良好,我們計劃讓go get
停止安裝命令二進位制檔案。詳情請參見issue 43684。
Module 撤回
您是否曾經在 Module 版本準備好之前不小心釋出過?或者您是否在版本釋出後就發現了一個需要快速修復的問題?釋出的版本中的錯誤是很難糾正的。為了保持 Module 構建的確定性,一個版本在釋出後不能被修改。即使你刪除或更改了版本標籤,proxy.golang.org
和其他代理可能已經有了原始版本的快取。
Module 作者現在可以使用go.mod
中的retract
指令撤回 Module 版本。撤回的版本仍然存在,並且可以被下載(所以依賴它的構建不會中斷),但在解析@latest
這樣的版本時,go
命令不會自動選擇它,go get
和go list -m -u
會列印關於現有使用版本的警告。
例如,假設一個流行庫example.com/lib
的作者釋出了v1.0.5
,然後發現了一個新的安全問題。他們可以在他們的 go.mod 檔案中新增如下指令。
// Remote-triggered crash in package foo. See CVE-2021-01234.
retract v1.0.5
接下來,作者可以標記並推送v1.0.6
版本,即新的最高版本。在這之後,已經依賴 v1.0.5 的使用者在檢查更新或升級依賴的軟體包時,就會被通知版本撤回。通知資訊可能會包含來自retract
指令上方註釋的文字。
$ go list -m -u all
example.com/lib v1.0.0 (retracted)
$ go get .
go: warning: example.com/lib@v1.0.5: retracted by module author:
Remote-triggered crash in package foo. See CVE-2021-01234.
go: to switch to the latest unretracted version, run:
go get example.com/lib@latest
關於互動式的、基於瀏覽器的使用指南,請檢視play-with-go.dev
上的Retract Module Versions
。可以檢視retract指令文件
以瞭解語法細節。
用 GOVCS 控制版本管理工具
go
命令可以從proxy.golang.org
這樣的映象中下載 Module 原始碼,或者直接從使用git
、hg
、svn
、bzr
或fossil
的版本管理倉庫中下載。直接的版本控制訪問是很重要的,特別是對於那些在代理上無法使用的私有 Module,但這也是一個潛在的安全問題:版本控制工具中的一個 bug 可能會被惡意伺服器利用,執行非預期的程式碼。
Go 1.16 引入了一個新的配置變數GOVCS
,讓使用者可以指定哪些 Module 可以使用特定的版本控制工具。GOVCS
接受一個以逗號分隔的pattern:vcslist
規則列表。pattern
是一個path.Match
模式,匹配一個 Module 路徑的一個或多個字首元素。特殊模式 public 和 private 匹配公共和私有 Module(private 被定義為由 GOPRIVATE 中的模式匹配的 Module;public 是其他所有 Module)。vcslist
是一個以管道符分隔的允許的版本控制命令列表,或關鍵字all
或off
。
例如
GOVCS=github.com:git,evil.com:off,*:git|hg
在此設定下,路徑在github.com
上的 Module 可以使用git
下載;路徑在evil.com
上的 Module 不能使用任何版本管理程式下載,其他所有路徑(* 匹配所有)可以使用git
或hg
下載。
如果沒有設定GOVCS
,或者一個 Module 不符合任何模式,go
命令就會使用這個預設值:公共 Module 允許使用git
和hg
,私有 Module 允許使用所有工具。只允許Git
和Mercurial
的理由是,這兩個系統作為不受信任的伺服器的客戶端執行的問題最受關注。相比之下,Bazaar
、Fossil
和Subversion
主要是在受信任的、經過認證的環境中使用,作為攻擊面的審查程度不高。也就是說,預設的設定是
GOVCS=public:git|hg,private:all
更多細節請參見使用GOVCS控制版本管理工具
。
下一步?
我們希望您覺得這些功能很有用。我們已經在努力為 Go 1.17 開發新的 Module 功能,特別是懶惰Module載入
,這將使 Module 載入過程更快、更穩定。和以往一樣,如果您遇到新的 bug,請在問題跟蹤上告訴我們。Happy coding!
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- Go 1.16 中值得關注的幾個變化Go
- Go 1.16 新功能特性不完全前瞻Go
- Go 1.16 推出 Embedding FilesGo
- Go 1.16 中關於 go get 和 go install 你需要注意的地方Go
- Go module vendorGo
- go vendor moduleGo
- Go學習總結-go moduleGo
- golang1.16新特性速覽Golang
- Go 1.17中值得關注的幾個變化Go
- Go module 本地導包方式Go
- 把 Go 放到 Nginx C module 之中GoNginx
- go-carbon 2.0.0 版本釋出, 要求最低 golang 版本 1.16Golang
- Go的包管理工具(四):Go Module ProxyGo
- Go語言基於go module方式管理包(package)GoPackage
- Go初始化變數的招式Go變數
- SAP S/4 HANA新變化-CO技術變化
- Android8.0 新SupportLibrary26、27功能及變化介紹Android
- Laravel 5.8 新特性和新變化 — 影片Laravel
- Visual Basic.NET 中的語言新變化 (轉)
- golang專案包管理(go module模式)Golang模式
- 架設 Go Proxy 服務加速 go module 下載速度Go
- dubbo-go v3 版本 go module 踩坑記Go
- 讓Go Module重新Respect Go Vendor系列博文3篇Go
- Go 1.21的2個語言變化Go
- go 中 defer 的一個隱藏功能Go
- Go 常用的一些格式化樣式中的動詞及功能Go
- [ Module ] 環境變數管理工具 Module 安裝和使用變數
- Go 中的動態作用域變數Go變數
- iOS 7.1 API 有哪些新變化iOSAPI
- VSCODE安裝GO語言並配置go module啟動VSCodeGo
- 對 Go 1.16 io/fs 設計的第一感覺:得勁兒!Go
- Go 1.16 io/fs 設計與實現及正確使用姿勢Go
- 前端模組化之ES Module前端
- Go Module 支援 HTTP 協議的私有庫方案GoHTTP協議
- Go Module 如何釋出 v2 以上版本Go
- Python 3.10 中新的功能和變化Python
- Parallels Desktop 18亮點功能改變與變化總整理Parallel
- 機器學習的產業化變革中,華為雲ModelArts的新成績單機器學習產業