<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Go mod 七宗罪

          共 2243字,需瀏覽 5分鐘

           ·

          2021-04-20 15:17


          源 / 頂級程序員        文/ 曹春暉


          go mod 是 rsc 主導(dǎo)設(shè)計(jì)的 Go 版本管理工具,借鑒了 Google 內(nèi)部的高大上版本管理方式,摒棄了開源社區(qū)的版本管理成功經(jīng)驗(yàn),借助 MVS 算法,希望能夠走出一條不一樣的路,然而從發(fā)布以來給廣大 Gopher 帶來了各種各樣的麻煩。本文簡單列舉一部分罪狀,Google 的并不一定總是世界的。
          當(dāng)然,隨著 Go 1.16 的發(fā)布,其中有些罪證可能已經(jīng)不成立了,讀者可以自行甄別。

          Go 命令的副作用

          Go list,Go test,Go build,所有命令都會去拉取依賴,有些庫是用被墻的服務(wù)做了重定向,只是執(zhí)行一下 go test,然后就被卡一年是家常便飯。
          按照 "By design" 的說法,Google 內(nèi)部的依賴庫版本都會盡量使用能夠兼容的最新版本。對于墻內(nèi)的我們來說,我不管執(zhí)行什么 Go 命令怎么都卡。逐漸患上 go test PTSD。
          解法:配置 GOPROXY 代理,雖然拉取依賴還是慢。

          形同虛設(shè)的 semver 規(guī)范

          社區(qū)里不遵守 semver 規(guī)范的庫很多,有的開源庫在 1.7.4 ~ 1.7.5 中進(jìn)行了 breaking change,而按照 semver 的定義,這是不應(yīng)該發(fā)生的。go mod 過度高估了開源社區(qū)的節(jié)操。
          一開始,我們以為這只是社區(qū)的節(jié)操問題,直到我們碰到了 gRPC。
          好樣的哦,Google 工程師。

          無法應(yīng)對刪庫

          leftpad 悲劇重演

          js 社區(qū)使用集中式的 npm 來管理依賴,在幾年前發(fā)生過一次因?yàn)樽髡邉h庫,導(dǎo)致幾乎所有互聯(lián)網(wǎng)巨頭的前端項(xiàng)目全部 build 失敗的悲劇。同時(shí) js 社區(qū)也進(jìn)行了一些反思 how one programmer broke the internet[1],have we forgotten how to program[2]。
          npm 好歹還是集中式的版本管理方式,Go 號稱分布式,但大多 Go 的依賴庫都是存在 Github 上,如果 Github 上的原作者刪除了該庫,那么也會導(dǎo)致大多數(shù)的依賴用戶 build 失敗。
          即使看起來我們可以靠 go.mod 和 go.sum 來實(shí)現(xiàn) reproducible build,實(shí)際的情況是,像 k8s 這樣的項(xiàng)目,依然會把龐大的依賴庫放在自己 repo 的 vendor 里。
          在筆者從 dd 離職時(shí),也曾經(jīng)不小心刪除過一個認(rèn)為應(yīng)該沒有人再依賴的個人庫,當(dāng)時(shí)給前同事們也造成了一些麻煩。

          Github release/tag 水土不服

          在 Github 上發(fā)布 lib 的 release,或者給某個 commit 打 tag 之后,我們依然可以對這些 tag 和 release 進(jìn)行編輯:
          我們經(jīng)??吹剑行斓淖髡咴诎l(fā)布一個 release 之后,又刪除了這個 release,或?qū)@個 release 進(jìn)行了編輯。對于用戶來說,這樣就會依賴一個已經(jīng)“消失”了的版本,在不存儲 vendor 的情況下,reproducible build 淪為笑談。

          goproxy 的實(shí)現(xiàn)并不統(tǒng)一

          不知道是否是因?yàn)?goproxy 并無規(guī)范,在使用不同的代理幫助我們加速下載依賴時(shí),會出現(xiàn)各種不同的錯誤。
          例如作者 A 開發(fā)的 goproxy,在某個庫不存在時(shí),會返回 404。而作者 B 開發(fā)的 goproxy,在某個庫不存在時(shí),會返回 500。著實(shí)令人困惑。
          而 goproxy 本身的實(shí)現(xiàn)基本都是惰性下載,所以新發(fā)布的庫,我們要走 goproxy 來測試時(shí),就需要手動 go get 觸發(fā)。而大多 goproxy 的實(shí)現(xiàn)并沒有查詢功能,goproxy 服務(wù)內(nèi)部到底什么時(shí)候同步好了,可以 go get 了,還是 go get 的過程中發(fā)生失敗了。作為用戶是不可查的。

          go get 到的 lib 版本在 go build 時(shí)被修改

          在 go get 時(shí),可以 go get lib@ver 來獲取指定版本的依賴,但是在 go build 時(shí)可能發(fā)現(xiàn)又被修改成了別的版本(比如被升級了),非常反直覺。
          我們想要鎖定具體的版本,只能使用 replace。

          版本信息擴(kuò)散

          由于 go mod 的設(shè)計(jì),版本信息被包含在了 import 路徑中。當(dāng)依賴庫從 v1 升級至 v2 時(shí),幾乎一定意味著我們代碼中大量的 import 路徑需要修改。
          修改不兼容的 api 就挺累的了。

          go.sum 合并沖突

          因?yàn)樯厦嬷v到的一系列問題,go.sum 在多人維護(hù)的大項(xiàng)目上,經(jīng)常會發(fā)生變動,也就經(jīng)常會有沖突。對于中心化版本管理系統(tǒng)來說,這個問題根本就不存在。對于 go mod 來說,go.sum 合并本來是個純追加邏輯。
          但這些沖突還是會浪費(fèi)我們的時(shí)間。
          如果你也曾經(jīng)被 go mod 煩到罵娘,歡迎在評論區(qū)分享你的故事。

          推薦閱讀



          35年前,微軟前CEO帶貨是什么水平?


          百度偷偷干了一件事,大家都不知道....


          移動支付大漏洞:手機(jī)一丟,傾家蕩產(chǎn)!



          —  —

          一鍵三連「分享」、「點(diǎn)贊」和「在看」

          技術(shù)干貨與你天天見~


          瀏覽 40
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  av有码第一页 | 亚洲高清无码免费在线观看 | 日韩成人电影在线 | 欧美午夜操大逼 | 黄色一级片电影在线观看 |