用Wails开发桌面应用的踩坑经验与核心技巧总结
先看效果,再看代码
最近用 Wails 做了个小工具,亲测有效!如果你也需要一个能调用本地能力的桌面应用,Wails 是个不错的选择。简单来说,Wails 让你可以用前端的技术(HTML、CSS、JavaScript)来构建桌面应用,同时还能直接调用 Go 的能力。
先来看个简单的例子吧:
package main
import (
"github.com/wailsapp/wails/v2"
"github.com/wailsapp/wails/v2/pkg/runtime"
)
type App struct{}
func (a *App) Greet(name string) string {
return "Hello, " + name
}
func main() {
app := &App{}
err := wails.Run(&wails.AppConfig{
Title: "My Wails App",
Width: 800,
Height: 600,
JS: module.exports = { greet: (name) => window.backend.App.Greet(name) };,
CSS: ``,
}, app)
if err != nil {
runtime.LogError(nil, "Error starting app: "+err.Error())
}
}
上面这段代码就是 Wails 的一个最基础的示例,跑起来后会弹出一个窗口,窗口里可以通过 JavaScript 调用 Go 的方法。
这个场景最好用
我为啥要用 Wails?其实是因为有个需求需要读取本地文件系统,然后对文件内容做一些处理,最后再展示出来。如果用纯 Web 技术,权限问题会很头疼,而 Electron 又太重了。Wails 就刚刚好,轻量又能直接调用 Go 的能力。
举个具体的场景吧:
// 前端部分
window.backend.App.ReadFile("path/to/file").then((content) => {
console.log(content);
});
// Go 部分
func (a *App) ReadFile(path string) (string, error) {
data, err := os.ReadFile(path)
if err != nil {
return "", err
}
return string(data), nil
}
这种前后端无缝衔接的方式真的很好用。尤其是需要频繁调用本地资源的时候,Wails 的优势就体现出来了。
踩坑提醒:这三点一定注意
不过,Wails 也不是完全没有坑,我自己踩过几个,分享一下:
- 坑1:JS 和 Go 的数据传递问题。Go 的方法返回值如果是复杂类型(比如结构体),在前端接收到的数据可能会有点奇怪。建议尽量返回字符串或者基本类型,复杂的对象可以用 JSON 序列化后再传。
- 坑2:调试不方便。刚开始用的时候,发现调试特别麻烦,尤其是前端和 Go 同时改的时候。后来我发现,可以把前端单独跑起来,用 vite 或者 webpack 开发服务器,等逻辑都调通了再打包到 Wails 里。
- 坑3:打包后的路径问题。打包后的应用,文件路径和开发环境不太一样,特别是涉及到静态资源加载的时候。解决办法是用相对路径,并且在开发和生产环境分别配置。
这里注意下,我踩过好几次坑,折腾了半天才发现是路径问题导致的。建议在项目初期就把路径问题理清楚,避免后续返工。
高级技巧:自定义菜单和事件监听
如果你需要给应用加点高级功能,比如自定义菜单或者全局快捷键,Wails 也是支持的。下面是一个自定义菜单的例子:
func main() {
app := &App{}
menu := wails.BuildMenu([]wails.MenuItem{
{
Label: "File",
SubMenu: []wails.MenuItem{
{
Label: "Open",
Click: func(ctx context.Context) {
runtime.MessageDialog(ctx, runtime.MessageDialogOptions{
Title: "Open File",
Message: "You clicked Open!",
})
},
},
},
},
})
err := wails.Run(&wails.AppConfig{
Title: "My Wails App",
Width: 800,
Height: 600,
Menu: menu,
}, app)
if err != nil {
runtime.LogError(nil, "Error starting app: "+err.Error())
}
}
这个菜单会在应用的顶部显示,点击“Open”会弹出一个对话框。类似的,你还可以监听全局事件,比如键盘快捷键。
一些实战中的小技巧
在实际项目中,我还摸索出了一些小技巧,分享给大家:
- 使用 Vite 提升开发体验。默认情况下,Wails 使用的是 webpack,但我觉得 Vite 更快。切换到 Vite 很简单,只需要在项目初始化时选择 Vite 模板即可。
- 封装常用方法。比如读取文件、写入文件这些操作,可以封装成一个工具类,在 Go 和 JS 中都能复用。
- 多窗口支持。虽然 Wails 默认只支持单窗口,但你可以通过创建多个实例来实现多窗口功能。
这里补充一句,多窗口的实现不是最优的方案,但确实是最简单的。如果你有更优的实现方式,欢迎评论区交流。
结尾:这个技术的拓展用法还有很多
总的来说,Wails 是一个非常实用的工具,尤其适合那些需要调用本地能力的桌面应用。它的学习成本不高,文档也比较齐全,推荐大家试试。
以上是我踩坑后的总结,希望对你有帮助。这个技巧的拓展用法还有很多,后续会继续分享这类博客。

暂无评论