【學習筆記】Go Modules 使用

icecho發表於2019-09-17
  • 在不借助任何額外工具的情況下,依賴包只能手動下載。
  • 手動下載第三方包也沒有版本的概念。
  • 需要配置 GOPATH,協同開發需要統一依賴包。
  • 如果使用的包引用了其他已經轉移的包,需要自己修改。
  • 第三方包和自己開發的包都在 GOPATH 下的 src 目錄,比較混亂。
  • 依賴包自動下載。
  • 會給第三方包標上準確的版本號。
  • 專案根目錄下會自動生成 go.mod 檔案,列出依賴。
  • 對於轉移了的包,可以使用 replace 特性進行替換。
  • 專案可以放在 GOPATH 下的 src 目錄之外的地方。

第一步

  • 先確保您的 golang 版本大於等於 1.12。
    go version
    //go version go1.12.9
  • 新增環境變數 GO111MODULE。

    要注意這裡 GO111MODULE 可設定為三種值:

    • auto 自動模式,如果專案在 $GOPATH/src裡,就會使用 $GOPATH/src 的依賴包,在$GOPATH/src之外,就會使用 go.mod 裡 require 的包。
    • on 開啟模式,go 1.12 後,無論專案是不是在 $GOPATH/src 裡,都會使用 go.mod 裡 require 的包。
    • off 關閉模式,就是原始的樣子啦。
// 這裡我使用的是 fish shell,配置命令如下  

vim ~/.config/fish/config.fish

新增 set -x GO111MODULE on     

第二步

  • $GOPATH/src 路徑外,我們嘗試建立一個專案。
cd ~/www/go

mkdir hello-golang && cd hello-golang

vim main.go

package main

import "fmt" 

func main() {
    fmt.Println("Hello, golang!")
}

go mod init my-first-go-project
  • 執行完上面的命令之後,專案根目錄下會生成一個 go.mod 檔案,是一個包管理檔案。

    官方說明:除了 go.mod 之外,go 命令還維護一個名為 go.sum 的檔案,其中包含特定模組版本內容的預期加密雜湊
    go 命令使用 go.sum 檔案確保專案所依賴的模組不會出現意外更改,無論是出於惡意、意外還是其他原因。 go.mod 和 go.sum 都應檢入版本控制。但是這裡 go.sum 不需要手工維護,所以可以不用太關注。

  • 檢視一下 go.mod 檔案。
    cat go.mod
    // 可以看到模組名稱以及 go 的版本號
    module my-first-go-project
    go 1.12

    第三步

  • 嘗試依賴一下第三方包,這裡以 iris 為例。
  • 修改 main.go 檔案,鍵入如下 iris-demo。
    package main
    import "github.com/kataras/iris"
    func main() {
    app := iris.Default()
    app.Get("/ping", func(ctx iris.Context) {
        ctx.JSON(iris.Map{
            "message": "pong",
        })
    })
    app.Run(iris.Addr(":8080"))
    }
  • 按照以前的傳統方法,應該要先 go get 安裝 iris 到 $GOPATH/src,但是現在我們不用這麼做啦。
  • 直接執行如下命令,它會自動檢查程式碼中依賴的包,自動下載,並且把依賴關係以及版本寫入 go.mod 以及 go.sum 中。
    go run main.go

    這裡如果遇到了超時的問題,需要新增 GOPROXY 環境變數,可參考 GOPROXY 官網進行配置。

  • 執行成功之後,我們再次檢視 go.mod 檔案
    cat go.mod
    //
    module my-first-go-project
    go 1.12
    require (
    github.com/BurntSushi/toml v0.3.1 // indirect
    github.com/Joker/jade v1.0.0 // indirect
    github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398 // indirect
    github.com/aymerick/raymond v2.0.2+incompatible // indirect
    github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 // indirect
    github.com/fatih/structs v1.1.0 // indirect
    github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4 // indirect
    github.com/gorilla/schema v1.1.0 // indirect
    github.com/iris-contrib/blackfriday v2.0.0+incompatible // indirect
    github.com/iris-contrib/formBinder v5.0.0+incompatible // indirect
    github.com/iris-contrib/go.uuid v2.0.0+incompatible // indirect
    github.com/json-iterator/go v1.1.7 // indirect
    github.com/kataras/golog v0.0.0-20190624001437-99c81de45f40 // indirect
    github.com/kataras/iris v11.1.1+incompatible // indirect
    github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d // indirect
    github.com/klauspost/compress v1.8.3 // indirect
    github.com/klauspost/cpuid v1.2.1 // indirect
    github.com/microcosm-cc/bluemonday v1.0.2 // indirect
    github.com/ryanuber/columnize v2.1.0+incompatible // indirect
    github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
    golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7 // indirect
    )
  • 到這裡,使用 Go Modules 的一個小 Demo 就完成啦。

你可能想知道?

  • 包去哪了?
    使用 Go Modules 方式管理第三方包,第三包都被下載到了 $GOPATH/pkg/mod 目錄下。

  • 版本怎麼控制?
    版本可以在 go.mod 中指定,如果沒有指定預設依賴最新版。可用 require 語句來依賴指定包以及版本。

  • 地址失效了怎麼修復?
    在 go.mod 檔案中運用 replace 來替換第三方包,例如

    replace golang.org/x/text => github.com/golang/text latest

    這樣就可以完成包的替換,它就會拉github.com/golang/text 的最新版到 $GOPATH/pkg/mod/golang.org/x/text 下完成替換。

Hello。

相關文章