南通高端網(wǎng)站建設(shè)開發(fā)百度站長資源平臺
文章目錄
- 背景
- 核心接口和方法
- 擴展接口
- 遺憾的是
背景
目前為止,已經(jīng)有很多優(yōu)秀的electron應(yīng)用。但其特點也很明顯:使用html+css+js構(gòu)建的布局很精致,但是體積不容小覷(最新版electron-egg打包出來的程序已經(jīng)300MB+)。
- vscode: 微軟開源的編輯器工具,支持各類插件。
- draw.io: 流程圖繪制工具
- tabby: 一款ssh連接工具
- termius:ssh以及sftp連接工具
- typora:一款markdown編輯器
- 微信小程序開發(fā)工具: 基于nw.js, 本質(zhì)和electron差不多。
而webview2是微軟基于chromium做的一個渲染引擎,相當于將electron的公共部分抽離到一個目錄下:C:\Program Files (x86)\Microsoft\EdgeWebView\Application,然后你的核心程序只需要幾M即可運行。
經(jīng)過UPX壓縮后的exe程序,僅需要1.9MB就可跑起一個helloworld頁面。
PS:基于webview2的還有wails這個框架,但是框架變動太頻繁, wails2.5的程序升級到2.9就跑不起來了,很難受。
核心接口和方法
而go語言方面,已經(jīng)有人封裝了調(diào)用webview2來構(gòu)建exe程序的庫。
github.com/jchv/go-webview2
- New():
功能: 創(chuàng)建一個新的 WebView2 實例。
用法: webview, err := webview2.New()
- Destroy():
功能: 銷毀 WebView2 實例。
用法: webview.Destroy()
SetTitle(title string):
功能: 設(shè)置 WebView2 窗口的標題。
用法: webview.SetTitle(“窗口標題”)
- SetSize(width, height int, hint webview2.Hint):
功能: 設(shè)置 WebView2 窗口的大小。
用法: webview.SetSize(800, 600, webview2.HintNone)
- Navigate(url string):
功能: 導(dǎo)航到指定的 URL。
用法: webview.Navigate(“https://example.com”)
- Eval(script string):
功能: 執(zhí)行 JavaScript 代碼。
用法: webview.Eval(“alert(‘Hello, world!’);”)
- Run():
功能: 運行 WebView2 實例,進入事件循環(huán)。
用法: webview.Run()
- Bind(name string, fn interface{}):
功能: 將 Go 函數(shù)綁定到 JavaScript,以便從 JavaScript 調(diào)用 Go 方法。
用法: webview.Bind(“functionName”, func() { /* Go code */ })
擴展接口
通過go調(diào)用win32 api可以擴展更多的功能。
- 提示框(windows原生版本)
/*** @description: 調(diào)用window原生消息彈框* @param {uintptr} hwnd* @param {*} text 消息內(nèi)容* @param {string} caption* @param {uint} uType* @return {*}*/
func ShowMessage(hwnd uintptr, text, caption string, uType uint) int {ret, _, _ := procMessageBoxW.Call(hwnd,uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text))),uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(caption))),uintptr(uType),)return int(ret)
}
- 文件選擇框
/*** @description: 選擇一個文件, import 一下"github.com/sqweek/dialog"* @return {string, error} 文件路徑,錯誤信息*/
func OpenFileDialog() (string, error) {filePath, err := dialog.File().Title("選擇").Load()if err != nil {return "", err}return filePath, nil
}
遺憾的是
- 微軟放棄了webview2在mac和linux上的支持,并未開放渲染引擎和接口。
- go語言庫github.com/jchv/go-webview2并不支持win7,會報錯:kernel32.dll加載失敗??赡苄枰匦屡渲肳ebview2Loader.dll。(win7需要109版本以下的。)
官方nuget倉庫:https://www.nuget.org/packages/Microsoft.Web.WebView2/1.0.2730-prerelease#versions-body-tab
- go-webview2這個庫將函數(shù)綁定到了前端的window對象下, 這就導(dǎo)致了前端原生js編寫的函數(shù), 不能與go注入的函數(shù)同名,不然就gg??梢試L試將go注入的函數(shù)放到window.GoMethods下。替換webview.go 467行
w.Init("(function() { var name = " + jsString(name) + ";" + `var RPC = window._rpc = (window._rpc || {nextSeq: 1});if (!window.GoMethods) window.GoMethods = {};window.GoMethods[name] = function() {var seq = RPC.nextSeq++;var promise = new Promise(function(resolve, reject) {RPC[seq] = {resolve: resolve,reject: reject,};});window.external.invoke(JSON.stringify({id: seq,method: name,params: Array.prototype.slice.call(arguments),}));return promise;}})()`)
- 如果將vue2打包的dist目錄內(nèi)嵌到go-webview2生成的exe中,需要一個httpServer來代理靜態(tài)文件,這樣就會占用至少一個本地端口,顯然不合適。
似乎wails解決了這個問題:
- https://github.com/wailsapp/wails/blob/release/2.7.0/v2/pkg/assetserver/assetserver_webview.go#L25C13-L25C79
- wails目前開發(fā)流程,webview dev時加載vite的http://127.0.0.1:5173,build時實現(xiàn)了一個無本地端口占用,并加載dist內(nèi)文件的方案,可惜我還沒看懂其邏輯。