前言:記錄一個go新手第一次構建複雜開源庫的經歷。go雖然是新手,但是程式設計上還是有多年的經驗,除了c/c++,用過IDEA能進行簡單的java程式設計、甚至scala程式設計。所以最開始還是有點信心的。所以也有點急於求成。而整個過程比我想象的複雜。
一、準備
今天已經927週一了,昨天補國慶的班。
從上上週918週五開始就熟悉go語言最簡單的hello程式。中間有個中秋。922週二下載開源庫,有關loraserver的,有三個模組如下圖:
最後幾個數字表示當前生產環境上執行的版本號。當時先在windows上編譯,發現有些欄位的定義已經沒法找到源庫了,如下圖:
再下載了最新的版本如下圖:
可以看出, 最新版本號和當前版本號之間的跨度還是有點大的。當前版本號好像是2019年(當時的情況已經沒法求證,我也是第一次介入這個產品),相差約兩年。然後可以對比一下程式碼變化也是挺大的。如下圖:
可以看出go版本和一些庫都在變化。程式碼比較改動量很大,用對比工具可以看出來,一片中國紅。
所以,我就直接試著編譯windows的版本,果然,最新版本還是比較順利。所以我想一定要升級了,否則老版本雖然有程式碼,但是即使改了也沒法編譯!
然後開始嘗試編譯linux的版本,竟然也很順利,因為vscode能支援go的跨平臺編譯。我當時還竊喜,認為go語言也許就這樣!go確實好用!
時間到了9-23,保持了當前環境的資料庫表格和資料。就試著開始在linux上執行,現在才知道,惡夢開始了。
二、問題
問題1、自己編譯的庫刷不出介面,而下載的庫能!
當然,這只是其中提供介面的那個庫(三個之一)。庫的功能是沒問題的,因為我用下載的庫,發現了之前的資料是在的。
同時,後面所有問題都是圍繞解決這個問題而來的。也可以說,後面的問題是對這個問題的分解。
問題2、go與web,npm與node都是些啥,有啥關係?而npm install老是失敗!
1、編譯與go embed
在前面編譯的時候,有介面的庫在下面這個檔案有錯誤的。後面查"//go:embed "是go的一個新特性,是一個配置項。所以當時我刪除了很多後面的配置項才能通過。
其實這個才是問題。我們搜尋一下:
“
embed是什麼
embed是在Go 1.16中新加包。它通過//go:embed指令,可以在編譯階段將靜態資原始檔打包進編譯好的程式中,並提供訪問這些檔案的能力。
”
所以,試圖看官網怎麼編譯
然後結合makefile檔案。前面兩項就是編譯UI。
2、npm install
再回到第一個問題我們看到,同樣是web介面刷不出來。go實現了web service!然後這兩天買了兩本go語言的書,也看到了一些go web的書,看來go開發web是不錯。而c/c++個人認為短板恰恰是網路程式設計這塊。但這些只是概念,當看到工程檔案Makefile中UI用到了npm(工具),一臉懵懂!哦,是nodejs啥相關的,可是nodejs也就是知道概念。就跟知道go一樣,只知道都是程式語言。好吧,硬著頭皮上,網上找方法唄,下載了一個最新版本的nodejs,node和npm都裝好了。這下可以編譯web的功能了吧。
然後npm intall出現“run `npm audit fix` to fix them, or `npm audit` for details”等錯誤,網上找方法,提示
npm audit fix
npm audit fix --force
npm intall
按這三個步驟還是失敗。最後求助公司web端負責人,說版本太高了,降低一下版本試試,然後他電腦上安裝的版本是這個:
我按這個版本重新安裝,再次npm intall,竟然成功了。
3、Linux下npm intall
在Linux安裝npm intall時,還是出現了問題
最後顯示如下錯誤
現在網上找了一番。
方案一:
npm cache clean --force
Step2:
rm -rf node_modules
Step3:
rm -rf package-lock.json
Step4:
npm install
說一下最後的解決辦法
1、首先降低npm版本
npm install [email protected] -g
2、使用淘寶映象
npm config set registry https://registry.npm.taobao.org
3、驗證一下是否成功
npm config get registry
4、清楚一下安裝快取
npm cache clean --force
5、安裝cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org
6、cnpm -v檢視是否安裝成功
我執行了234,還是不行。
然後再次請教web端負責人,說可以安裝cnpm,後面的命令都改為cnpm。如果可行!
最後,懷著一種好奇心,查了查cnpm和npm之間到底啥關係。可以參考《主流包管理工具npm、yarn、cnpm、pnpm之間的區別與聯絡——原理篇》。似乎,npm發展到cnpm、再到yarn、最後到pnpm。但是這幾者都有不少人在使用。對於我們這些新手而言,出問題了就換一個吧。
問題3、linux下依賴包下載失敗
前面提到,go似乎能支援跨平臺編譯,所以我開始總是想著在windows上尋求編譯的解決方案。裝mingw、裝gcc、裝make工具。但是還需要安裝linux的go語言工具,git工具等等。所以直接到Linux環境下進行構建。前面提到的編譯UI在windows下也沒問題,但是Linux下有問題的。同樣的編譯主程式也是。
提示X509證書找不到錯誤。但是windows為啥OK的,我後來想起windows下裝了github,難道是這樣原因?我還真找了資訊保安組的同事,希望給一個windows下類似的證書。同時繼續在網上找方案,和同事溝通。同事說要f.q.,因這些都是國外的網站。然後我想起了,java都是有阿里雲的映象,go沒有嗎?有同事給了一個程式碼的地址,hubfast。代替github.com這個域名可以,但是代替golang.org就不行。其實現在想想或許可以replace。
但問題的關鍵是,如何修改?因為這些依賴包都是放在go.mod檔案種,如下圖:
可是這個檔案是什麼,當時有同事跟我說用go mod download試試,我第一次知道這個命令!那麼這個檔案和go mod又有啥關係?
1、go mod是什麼?GOPATH配置項到底要不要配?go vendor 模式又是什麼鬼?這三者可有聯絡?
文章《golang中使用GOPATH模式和GoModule(gomod)模式的區別》對這三個概念和原理講得比較清楚。如果總結一句話,三者都是包管理模式,依次從go path演進到go vendor、再演進到go mod。那麼我們要關注的就是go mod,其他兩項基本要淘汰了。與上述的npm工具不一樣。從功能看,npm側重包管理,而這三者側重依賴包管理。npm側重Web UI包,而這三種主要面向go語言。
前面苦苦納悶在Linux下配置GOPATH提示不能和GOROOT相同,而windows卻又可以。其實不必在意。
所以看了這篇文章後,對go.mod的檔案構成和go mod一系列命令就恍然大悟了。和java的maven很相似。 同時也說明go語言發展非常迅速!
2、依賴包如何配置代理?!
從前面可以得知,go mod是可以管理依賴包的,但是這網站都是國外的。需要配置代理。
windows下vscode搭建go的開發環境時,配置過go env。但是Linux上沒有改動過。所以當我再次想配置set GO111MODULE=on總是失敗,所以在網上再次搜尋一番。
找到《GO111MODULE的設定(及GOPROXY)》,原來要用 go env -w修改。然後的然後看到標題了沒有,這不還有proxy嗎?這不是第一次搭建windows vscode go環境就用到了的嗎?
go env -w GOPROXY=https://goproxy.io,direct
go env -w GO111MODULE=on
而且文章也提到了“可以用go env -u 恢復初始設定;GOPROXY的值應該還可以是https://mirrors.aliyun.com/goproxy/ 或 https://goproxy.cn”。
原來早就打過招呼的。原來windows能下載這些庫並不是因為證書的原因。
我們也再次回到GO111MODULE的真正含義:
GO111MODULE=off禁用模組支援,編譯時會從GOPATH和vendor資料夾中查詢包。
GO111MODULE=on啟用模組支援,編譯時會忽略GOPATH和vendor資料夾,只根據 go.mod下載依賴。
GO111MODULE=auto,當專案在$GOPATH/src外且專案根目錄有go.mod檔案時,自動開啟模組支援。
到這裡,Linux下的編譯終於成功了!
問題3、linux下其他問題
上述linux編譯完成後,執行正常。但是以上問題解決比較零散,makefile檔案基本上全是單步執行。那麼整體執行會不會真的可以了呢。還是出現了兩個小問題。
其中之一如下:
git clone 遇到問題:fatal: unable to access ‘https://github.comxxxxxxxxxxx’: Failed to connect to xxxxxxxxxxxxx
解決方法:將命令列裡的http改為git重新執行。
還有其中之一就是cnpm的問題了,前面已經提到。
三、總結
現在再回過頭看,這些問題也不復雜。所以還是沒有經驗。做技術就是如此,經歷過覺得沒什麼,但是在這個過程中還是比較忐忑的。人生也是如此,第一次經歷總是苦澀的、難忘的。也許正是這樣,才是成長。現在再看起來,和go之間似乎多了一份親切感!最後,希望下一次面對一種全新的語種會更加從容。