1. 程式人生 > >在go modules中使用replace替換無法直接獲取的package(golang.org/x/...)

在go modules中使用replace替換無法直接獲取的package(golang.org/x/...)

報錯 href 操作 ast med tag 無法 獲取 技術分享

上一篇裏我們介紹了使用go get進行包管理。

不過因為某些未知原因,並不是所有的包都能直接用go get獲取到,這時我們就需要使用go modules的replace功能了。(當然大部分問題掛個梯子就能解決,但是我們也可以有其它選項)

使用replace替換package

replace顧名思義,就是用新的package去替換另一個package,他們可以是不同的package,也可以是同一個package的不同版本。看一下基本的語法:

go mod edit -replace=old[@v]=new[@v]

old是要被替換的package,new就是用於替換的package。

這裏有幾點要註意:

  • replace應該在引入新的依賴後立即執行,以免go tools自動更新mod文件時使用了old package導致可能的失敗
  • package後面的version不可省略。(edit所有操作都需要版本tag)
  • version不能是master或者latest,這兩者go get可用,但是go mod edit不可識別,會報錯。(不知道是不是bug,雖然文檔裏表示可以這麽用,希望go1.12能做點完善措施)

基於以上原因,我們替換一個package的步驟應該是這樣的:

  1. 首先go get new-package(如果你知道package的版本tag,那麽這一步其實可以省略,如果想使用最新的版本而不想確認版本號,則需要這一步)
  2. 然後查看go.mod,手動復制new-package的版本號(如果你知道版本號,則跳過,這一步十分得不人性化,也許以後會改進)
  3. 接著go mod tidy或者go build或者使用其他的go tools,他們會去獲取new-package然後替換掉old-package
  4. 最後,在你的代碼裏直接使用old-package的名字,golang會自動識別出replace,然後實際你的程序將會使用new-package,替換成功

下面我們仍然用chromedp的example做一個示例。

示例

chromedp使用了golang.org/x/image,這個package一般直連是獲取不了的,但是它有一個github.com/golang/image的鏡像,所以我們要用replace來用鏡像替換它。

我們先來看看如果不replace的情況下的依賴情況:

技術分享圖片

沒錯,我們使用了原來的包,當然如果你無法獲取到它的話是不會被記錄進來的。

下面我們go get它的鏡像:

# master表示獲取最新的commit
go get github.com/golang/image@master

然後我們查看版本號:

cat go.mod

技術分享圖片

有了版本號,我們就能replace了:

go mod edit -replace=golang.org/x/image@v0.0.0-20180708004352-c73c2afc3b81=github.com/golang/image@v0.0.0-20180708004352-c73c2afc3b81

現在我們查看一下go.mod:

技術分享圖片

replace信息已經更新了,現在我們只要go mod tidy或者go build,我們的代碼就可以使用new-package了。

更新後的go.sum,依賴已經替換成了鏡像:

技術分享圖片

目前來看,replace做的遠不如go get那樣方便人性化,不過畢竟還只是測試階段的功能,期待一下它在go1.12的表現吧。

如果有錯誤和疑問,歡迎在評論指出,也感謝@goozp提出的問題。

在go modules中使用replace替換無法直接獲取的package(golang.org/x/...)