前言:記錄一個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時,還是出現了問題

最後顯示如下錯誤

現在網上找了一番。

方案一:

Step1: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之間似乎多了一份親切感!最後,希望下一次面對一種全新的語種會更加從容。