Go 包管理機制深入分析
前言
隨著 Go 語言的深入使用,其依賴管理機制也一直是各位 Gopher 熱衷於探討的話題。Go 語言的原始碼依賴可透過 go get 命令來獲取,但自動化程度不高,於是官方提供了 Dep 這樣的自動化批次管理依賴的工具。雖然 Go 語言的依賴管理在很多方面還是不如人意,但整個體系正在日趨完善,本篇就將從最基本的依賴管理場景出發,一同探討 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 是 Go 語言官方提供的依賴管理工具,跟其他依賴管理工具類似,都是透過一個檔案描述依賴的座標資訊,然後批次管理(下載、升級等)依賴包(原始碼)。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 更多深入內容,可以參考
總結
Go dep 目前是一款比較好用的依賴管理工具,很多比較大型的專案都在使用,從中可以學習到依賴管理的一些基本思路,對於理解其他語言,比如 NPM 的依賴管理模型也是比較有好處的。
更多精彩內容可以專注我們的線上課堂
微信搜尋公眾號:jfrogchina 獲取課程通知
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69954434/viewspace-2698096/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SPI機制深入分析
- ATL Thunk機制深入分析
- 包機制
- Java包機制Java
- 深入分析Redis的主從複製機制Redis
- Go語言之包(package)管理GoPackage
- Go反射機制ReflectGo反射
- 對Koa-middleware實現機制的深入分析
- Go GC 機制的大坑GoGC
- Day10-包機制
- 函式閉包機制函式
- Go語言基於go module方式管理包(package)GoPackage
- Flutter 命令本質之 Flutter tools 機制原始碼深入分析Flutter原始碼
- Android包管理機制Android
- 學java12包機制Java
- Redis哨兵機制全面深入分析與講解[實戰演示篇]Redis
- 三元運算+包機制
- Go通道機制與應用詳解Go
- 深入理解Go-垃圾回收機制Go
- Go語言錯誤處理機制Go
- Go小工具系列——重試機制Go
- 執行緒同步機制-包裝類執行緒
- js--閉包與垃圾回收機制JS
- Java記憶體管理機制Java記憶體
- jvm記憶體管理機制JVM記憶體
- javaScript 記憶體管理機制JavaScript記憶體
- Glibc堆管理機制基礎
- 使用 Go Mod 進行包管理並代理拉包Go
- 深入理解GO語言之併發機制Go
- 用 Go 語言實作 Job Queue 機制Go
- Java基礎(五):包機制、文件註釋Java
- Java__包機制__使用者輸入Java
- Go:context包GoContext
- Go strconv包Go
- Go unsafe包Go
- Go語言處理—Day11—反射機制Go反射
- Java基礎語法:運算子、包機制、JavaDocJava
- Istio流量管理實現機制深度解析