隨著 Go 語言的深入使用,其依賴管理機制也一直是各位 Gopher 熱衷于探討的話題。Go 語言的源碼依賴可通過 go get 命令來獲取,但自動化程度不高,于是官方提供了 Dep 這樣的自動化批量管理依賴的工具。雖然 Go 語言的依賴管理在很多方面還是不如人意,但整個體系正在日趨完善,本篇就將從最基本的依賴管理場景出發,一同探討 Go 語言依賴管理的一些最佳實踐。
在 Go 語言中,我們通過 go get 命令將 GitHub 或者 Google Code 上的代碼下載到本地指定目錄,然后在開發代碼中通過 import 的形式引用本地的代碼。
Go 語言可以通過直接分析代碼中的 import 語句來查詢依賴關系。go get 命令在執行時,就會自動解析 import 來安裝所有的依賴。那么下載的依賴在本地是如何存儲的呢?
這里就涉及到 Go 語言的 WORKSPACE 概念,簡單來說就是通過 GOPATH 環境變量來設置 Go 代碼的位置。一般來說,GOPATH 目錄下會包含 pkg、src 和 bin 三個子目錄,這三個目錄各有用處。
bin 目錄用來放置編譯好的可執行文件,為了使得這里的可執行文件可以方便的運行,在 shell 中設置PATH變量。
src 目錄用來放置代碼源文件,在進行 import 時,是使用這個位置作為根目錄的。自己編寫的代碼也應該放在這下面,不同的項目放在不同的目錄下進行管理。
pkg 用來放置安裝的包的鏈接對象(Object)的。這個概念有點類似于鏈接庫,Go 會將編譯出的可連接庫放在這里,方便編譯時鏈接。不同的系統和處理器架構的對象會在 pkg 存放在不同的文件夾中。
當項目在 src 目錄下管理時,多個項目可能都會使用相同的依賴,如果每個項目都存一份依賴顯然會帶來大量的冗余,這里我們推薦一個設置 GOPATH 環境變量時的小技巧。
這樣第三方包就會默認放置在第一個路徑中,而你可以在第二個路徑下編寫自己的代碼,多個項目共享一份依賴。
dep 是 Go 語言官方提供的依賴管理工具,跟其他依賴管理工具類似,都是通過一個文件描述依賴的坐標信息,然后批量管理(下載、升級等)依賴包(源碼)。dep 是一個開源項目, 大家可以在 https://github.com/golang/dep 了解詳細信息,其安裝方式大家可以參考官方說明,這里我們主要介紹其使用。
通過 dep init 命令來初始化,會創建Gopkg.lock,Gopkg.toml文件和一個空的vendor目錄。
我們在代碼中通過 import 命令添加依賴后,通過 dep ensure 就可以下載依賴到本地 $GOPATH/src 目錄下。
main.go
Gopkg.lock
通過 dep status 我們可以查看當前依賴引用的情況
另外有一個 dep check 命令來檢查是否存在依賴被引用,但是代碼中并沒有使用的情況,Go 語言對于依賴的引用比較嚴格,不允許引用了但是沒使用的情況。從軟件安全的角度考慮,這是一個很好的實踐,避免引入一些安全風險。
當然,這種時候我們就需要移除本地依賴,最好不要手動刪除vendor中的內容,而是通過 dep ensure -update 命令來移除。
從 dep 的目錄結構,我們可以分析出 dep 的基本工作思路:
這里面有兩個關鍵的步驟:
解析依賴
從當前項目的 import 文件中解析出整個工程的依賴情況,并結合 Gopkg.toml 定義的規則,然后將依賴關系輸出給 Gopkg.lock,注意這個 lock 文件最好不要手動修改。
獲取依賴
通過 Gopkg.lock 了解整個依賴關系之后,將依賴的具體內容拉取下來放到 vendor 目錄中,然后執行 Go build 時從本地的 vendor 讀取依賴并完成構建。
這一些都是在 dep ensure 時完成的,其實在執行這個命令時還可以傳參數,最主要的是 -no-vendor 和 -vendor-only 這兩個參數。
-no-vendor 參數只會導致運行 resolve 函數,結果是創建一個新的Gopkg.lock 文件,不會更新 vendor;而 -vendor-only 參數將跳過 resolve 并僅運行 vendoring 函數,導致 vendor/ 從已存在的Gopkg.lock 重新更新。
關于 dep 更多深入內容,可以參考
https://golang.github.io/dep/docs/introduction.html
Go dep 目前是一款比較好用的依賴管理工具,很多比較大型的項目都在使用,從中可以學習到依賴管理的一些基本思路,對于理解其他語言,比如 NPM 的依賴管理模型也是比較有好處的。
更多精彩內容可以專注我們的在線課堂
微信搜索公眾號:jfrogchina 獲取課程通知
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。