2022年7月30日 星期六

Go 開發筆記 - 透過 Electron 實現 PC app GUI 之 go-astilectron / go-astilectron-bundler / go-astilectron-bootstrap


前陣子練習 Golang 後,除了建制後端 API 及網頁服務外,在想該怎樣做個 Windows / macOS 的 PC App 時,逛了一下熱門的 GUI 套件,有常見的 QT, GTK3/GTK4 等等,最後想起 Electron 這套,找了一下果真也有人串好 Go 與 Electron 整合方式。就來試試看 go-astilectron 這套吧!

處理的項目:
專案初始化:

% cat main.go 
package main

import (
    "github.com/asticode/go-astilectron"
)

func main() {

}

% go mod init github.com/changyy/study-go-electron
% go mod tidy

接著切一個目錄 web 做網頁開發管理:

% tree -L 1 web
web
├── README.md
├── dist
├── env_nvm.sh
├── env_vim.sh
├── node_modules
├── package-lock.json
├── package.json
├── src
├── webpack.common.js
├── webpack.development.js
└── webpack.production.js

3 directories, 8 files

其中 package.json 內使用 webpack 安置開發模式和發版封裝、使用 eslint 做 coding style 規範:

% cat web/package.json | jq '.scripts'
{
  "eslint": "eslint --ext .js src/",
  "eslint-fix": "eslint --fix --ext .js src/",
  "watch": "webpack --config webpack.development.js --watch",
  "start": "webpack serve --config webpack.development.js --open",
  "build": "webpack --config webpack.production.js"
}

而 web 程式碼入口點:

% tree web/src     
web/src
├── index.html
└── js
    ├── helper-old-style.js
    ├── helper.js
    └── index.js

1 directory, 4 files

試試看在 web/src/index.html 內,在 body.onload 內呼叫 hehe(),而 web/src/js/index.js 是一個統整區,而 webpack 在 production mode 會精簡程式碼,因此要匯出的功能都必須做點處理,像是故意埋在 windows.xx 等等,或是要調整 webpack 包裝的機制,如 output 區要多描述 libraryTarget 和 library 資訊,會自動綁定在 window.xx 環境。

回過頭來,關於 go astilectron 的使用,在不需要封裝成各平台的環境時,可以很簡單地用以下程式碼,並在根目錄用 `% go run .` 就可以運行了:

    a, _ := astilectron.New(log.New(os.Stderr, "", 0), astilectron.Options{
        AppName: "MyGoAstilectronProject",
    })
    defer a.Close()

    // Start astilectron
    a.Start()

    w, _ := a.NewWindow("./resources/app/index.html", &astilectron.WindowOptions{
        Center: astikit.BoolPtr(true),
        Height: astikit.IntPtr(600),
        Width:  astikit.IntPtr(600),
    })
    w.Create()

    // Blocking pattern
    a.Wait()

如此,在開發網頁版型時,單純在 web 目錄做事,如 npm run start 就可以喚起瀏覽器來瀏覽,等做完事後,在靠 npm run build 封裝到 web/dist 目錄以及複製一份到 resource/app 目錄中,後續就著靠 ~/go/bin/astilectron-bundler 封裝成 PC App,在封裝成 PC app 時,會面臨到 resources 目錄內的文件也得跟著封裝進去,也就是上述程式碼指定的 "./resources/app/index.html" 網頁資源,或者網頁位址要改成絕對路徑也是一招,但等同也要求使用此 PC app 者,下需要自行配置好網頁資料。

這時,就要使用 go-astilectron-bundler 跟 go-astilectron-bootstrap ,前者是編譯出 PC app ,後者是封裝好資源,使得執行 PC app 時,可以順道把對應的資源("./resources/app/")擺定位,這時程式碼就會變得稍微複雜一點,並且執行執行 `go run .` 不見得能常運行,將使得開發週期拉的很長(每次編譯要花幾分鐘的時間)

% ~/go/bin/astilectron-bundler cc
% time ~/go/bin/astilectron-bundler
...
~/go/bin/astilectron-bundler  63.79s user 10.56s system 108% cpu 1:08.21 total

最後,就把他配置成可以傳一個 -dev 參數,使用該參數時,不經過 ~/go/bin/astilectron-bundler 運行(運行的速度也只是小減 20% 時間而已 XD)

% go run . -dev

目前覺得用 Go 與 Electron framework 一起使用的好處還不夠強烈,以及整合開發的優勢頂多是用 Go 寫工具(api)等等,以及使 Electron 時,本來就是重度倚賴 HTML/JS/CSS 在 UI 呈現,因此直接 node.js 的整合優勢仍是最佳的。

更多資訊就在這邊:github.com/changyy/study-go-electron ,或是直接觀看 github.com/asticode/go-astilectron 內有提到 demo 範例,可以直接看 demo 內的實作。

沒有留言:

張貼留言