前言
Go,又稱Golang,是谷歌在21世紀(jì)開發(fā)的一種新的編程語(yǔ)言,它靜態(tài)強(qiáng)類型、從語(yǔ)言層面支持并發(fā)(Goroutine)、支持垃圾回收GC。
Go語(yǔ)言有一些筆者很喜歡的特點(diǎn),譬如跨平臺(tái)、交叉編譯(在某個(gè)環(huán)境中編譯其他平臺(tái)的程序)、支持并發(fā)、語(yǔ)言上做“減法”精簡(jiǎn)關(guān)鍵字、直接靜態(tài)編譯成單個(gè)二進(jìn)制可執(zhí)行文件(告別缺少vcruntime.dll的痛苦)。
Go語(yǔ)言像是C++和python的融合,存在著Go語(yǔ)言開發(fā)者的一些“固執(zhí)”,比如花括號(hào){}
的換行,也有一些缺陷。Go適合寫服務(wù)器的后端應(yīng)用,但是用來(lái)寫帶有GUI的應(yīng)用程序還不是那么成熟,官方原生不支持,故有許多相關(guān)GUI庫(kù),如:Qt、ui、walk、gio、go-flutter-desktp。經(jīng)過(guò)若干比較之后筆者認(rèn)為使用Go+wails的方式是大勢(shì)所趨。
Wails的思路是使用Web端的技術(shù)(html/css/js)作為前端,可以使用js框架如vue和react,后端使用Go語(yǔ)言,前后端交互通過(guò)go與js綁定某種方法實(shí)現(xiàn),如此前端便可使用各種成熟的框架,似乎學(xué)習(xí)web端的技術(shù)、Go語(yǔ)言、另一個(gè)網(wǎng)頁(yè)后端的Go語(yǔ)言框架(如Gin)即可打通全棧,想法是好,但是還得一步步學(xué)習(xí)。
Wails 和 electron 不同,electron是把chromium瀏覽器內(nèi)核打包,包括ffmpeg.dll等,體積上非常臃腫,首次啟動(dòng)慢,所占存儲(chǔ)空間和內(nèi)存都偏大,和筆者體積較小、功能齊全
的理念相悖。wails則是直接調(diào)用系統(tǒng)自帶瀏覽器內(nèi)核,至于內(nèi)存...有待驗(yàn)證。
經(jīng)過(guò)測(cè)試,wails的hello-world.exe
體積10.2MB、zip壓縮包4.3MB、7z壓縮3.5MB、UPX壓縮后3.93MB,內(nèi)存占用43.7MB。
接下來(lái)筆者會(huì)把整個(gè)學(xué)習(xí)的過(guò)程記錄下來(lái),目前只有wails的官網(wǎng)可以提供較好的文檔,其中也會(huì)涉及純Golang的知識(shí)點(diǎn),因?yàn)楣P者也在Go語(yǔ)言學(xué)習(xí)初期。
環(huán)境搭建
官方文檔:https://wails.app/gettingstarted/
折騰了很久,最后決定在虛擬機(jī)中使用Win10企業(yè)版LTS搭建Go+wails的環(huán)境,裝MacOS出現(xiàn)了兼容問(wèn)題,linux中也有一些難處、需要大量的時(shí)間深入了解linux,故當(dāng)下選擇win10。
有錢了也組臺(tái)黑蘋果吧,windows最大的問(wèn)題是它不夠優(yōu)雅。
安裝Go
下載對(duì)應(yīng)安裝包并安裝。下載地址
安裝Node
下載安裝,如此便有了npm。下載地址
再用如下命令安裝cnpm,國(guó)內(nèi)使用的速度提升很大。
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n19" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">npm install -g cnpm --registry=https://registry.npm.taobao.org</pre>
如有其它web端的依賴請(qǐng)自行安裝。
安裝GCC庫(kù)
Windows下需要安裝GCC庫(kù)用來(lái)編譯。下載地址
安裝Git Bash
可能會(huì)用到Git操作Push/Clone,建議安裝。下載地址
安裝Docker
官方文檔似乎提到Docker在wails交叉編譯時(shí)會(huì)用到。下載地址
安裝IDE
這里推薦兩個(gè)IDE/編輯器:微軟的VSCode 和 jetbrains的Goland。
各有優(yōu)劣,這里筆者用的是Goland,學(xué)生使用教育郵箱可白嫖,開源項(xiàng)目也可申請(qǐng)。
VSCode:https://code.visualstudio.com/
Goland:https://www.jetbrains.com/go/
IDE的配置略過(guò),注意VSCode可以安裝sync插件,把所有配置同步到github gist上,之后到任意機(jī)器上安裝sync插件粘貼一串代碼、登錄github即可同步所有插件設(shè)置。
設(shè)置Goproxy
按照Goproxy官網(wǎng)的說(shuō)明設(shè)置代理:
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n68" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct</pre>
其他(非必須)
筆者做了一些美化工作,包括安裝 Mactype
、安裝Sarasa字體和Firacode字體、使用NoMeiryoUI
更改全局字體為10pt Sarasa SC,使用百分瀏覽器并關(guān)閉DW,這樣字體終于能看了。
Go語(yǔ)言項(xiàng)目文件結(jié)構(gòu)
GOPATH下共有三個(gè)文件夾:bin、pkg、src
bin存放編譯好的程序
pkg存放編譯后生成的各種文件和各種包(代碼中import的外部包)
src存放源代碼
一般需要配置GOROOT、GOPATH、GOBIN的環(huán)境變量,不過(guò)用Goland似乎可以懶一點(diǎn),因?yàn)槭翘摂M機(jī)所以全默認(rèn)很方便,src文件夾直接發(fā)送到桌面快捷方式。
測(cè)試純Go語(yǔ)言
可以用Goland創(chuàng)建一個(gè)項(xiàng)目,比如命名為test
,即新建src/test/main.go
,輸入以下內(nèi)容:
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n47" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">package main
?
import(
"fmt"
)
?
func main() {
fmt.Println("Hello World!")
}</pre>
在終端,位置src/test/
處使用命令go run main.go
,編譯和運(yùn)行第一個(gè)Go程序。
使用命令go build main.go
編譯得到可執(zhí)行程序,運(yùn)行main.exe
,結(jié)果如下:
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n50" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">C:\Users\Purp1e\go\src\test>main.exe
That's Good!</pre>
運(yùn)行第一個(gè)Wails程序
在終端中輸入wails,配置一下名字和郵箱。
然后cd到src文件夾,使用wails init
,有的選項(xiàng)可直接使用ENTER大法xd。
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n55" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">C:\Users\Purp1e\go\src>wails init
Wails v1.7.1 - Initialising project
?
The name of the project (My Project): tutorial
Project Name: tutorial
The output binary name (tutorial):
Output binary Name: tutorial
Project directory name (tutorial): tutorial
Project Directory: tutorial
Please select a template:
1: Angular - Angular 8 template (Requires node 10.8+)
2: React JS - Create React App v3 template
3: Vanilla - A Vanilla HTML/JS template
4: Vue2/Webpack Basic - A basic Vue2/WebPack4 template
5: Vuetify1.5/Webpack Basic - A basic Vuetify1.5/Webpack4 template
6: Vuetify2/Webpack Basic - A basic Vuetify2/Webpack4 template
Please choose an option [1]: 4
Template: Vue2/Webpack Basic
Generating project...
Building project (this may take a while)...
Project 'tutorial' built in directory 'tutorial'!</pre>
項(xiàng)目結(jié)構(gòu)如下圖:
其中frontend是前端的文件夾,main.go中做了前后端的綁定,appicon.png
是程序的圖標(biāo)。
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n59" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">C:\Users\Purp1e\go\src\tutorial>wails -help
| | / /___ () /____
| | /| / / __ `/ / / /
| |/ |/ / // / / ( ) v1.7.1
|/|/_,///____/ https://wails.app
The lightweight framework for web-like apps
?
Available commands:
?
setup Setup the Wails environment [default]
migrate Migrate projects to latest Wails release
init Initialises a new Wails project
build Builds your Wails project
serve Run your Wails project in bridge mode
update Update to newer [pre]releases or specific versions
issue Generates an issue in Github
?
Flags:
?
-help
Get help on the 'wails' command.
?</pre>
其中wails build
是構(gòu)建項(xiàng)目并生成到build
文件夾里,wails serve
則是把項(xiàng)目運(yùn)行在localhost中,可以熱調(diào)試。
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n61" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">C:\Users\Purp1e\go\src\tutorial>wails build
Wails v1.7.1 - Building Application
?
Skipped frontend dependencies (-f to force rebuild)
Building frontend...
Ensuring Dependencies are up to date...
Packing + Compiling project...
Awesome! Project 'tutorial' built!
?
C:\Users\Purp1e\go\src\tutorial>cd build
?
C:\Users\Purp1e\go\src\tutorial\build>tutorial.exe</pre>
運(yùn)行結(jié)果如圖: