Wails 是一个 Go 语言编写的框架,用于使用 Go 语言的强大后端能力和熟悉的 Web 前端技术(HTML、CSS、JavaScript/TypeScript、以及任何前端框架如 React、Vue、Angular、Svelte 等)构建轻量级、高性能、原生的跨平台桌面应用程序。它与 Tauri 类似,都是 Electron 的替代品,但 Wails 的核心优势在于其后端是 Go 语言,这对于 Go 开发者来说更具亲和力。

核心思想:将现代 Web 前端技术与 Go 语言编写的原生后端无缝结合,通过操作系统的 WebView 渲染 UI,实现高性能、低资源消耗且易于 Go 开发者上手的桌面应用开发。


一、为什么选择 Wails?

与 Electron 相比,Wails 提供了一系列优势,特别吸引 Go 语言开发者:

  1. 极小的捆包体积:Wails 应用同样不捆绑 Chromium 或 Node.js 运行时。它利用操作系统自带的 WebView 控件(如 Windows 上的 WebView2/EdgeHTML、macOS 上的 WKWebView、Linux 上的 WebKitGTK/WebView2),使得最终应用体积非常小,通常只有几MB。
  2. 低内存占用:由于使用系统 WebView,内存占用大幅降低,更接近原生应用。
  3. 高性能 Go 后端:开发者可以使用 Go 语言编写应用程序的后端逻辑,利用 Go 的高性能、并发能力和丰富的标准库。这对于需要处理大量数据、网络通信或复杂业务逻辑的应用尤其有利。
  4. Go 语言亲和性:对于已经熟悉 Go 语言的开发者,Wails 提供了非常自然的开发体验,无需学习 Rust(像 Tauri 那样)或 Node.js(像 Electron 那样)来编写后端。
  5. 跨平台:一套 Go 和 Web 代码库可以构建 Windows、macOS 和 Linux 平台上的应用。
  6. Web 技术栈:前端开发者可以继续使用熟悉的 HTML、CSS、JavaScript 和各种前端框架。

二、Wails 的核心架构与概念

Wails 的架构设计与 Tauri 有相似之处,但核心后端语言是 Go:

2.1 WebView (前端渲染)

  • 定义:与 Tauri 类似,Wails 也利用操作系统提供的原生 Web 内容渲染组件来显示前端 UI。
  • 优势:捆包体积小、内存占用低、外观与系统更协调。
  • 跨平台差异
    • Windows:WebView2 (基于 Edge Chromium),如果不可用则回退到 EdgeHTML (IE 的 MSHTML 引擎)。
    • macOS:WKWebView (基于 Safari 的 WebKit)。
    • Linux:通常使用 WebKitGTK 或 WebView2。
  • 与 Web 交互:前端 Web 代码运行在 WebView 中,通过 Wails 提供的 Runtime 桥接器与 Go 后端进行通信。

2.2 Go 后端 (业务逻辑)

  • 定义:Wails 的核心后端逻辑由 Go 语言编写,负责处理文件系统操作、网络请求、调用操作系统原生 API、应用生命周期管理、系统托盘、菜单、通知以及所有业务逻辑。
  • 优势
    • 性能:Go 提供了出色的性能,尤其适合高并发和 I/O 密集型任务。
    • 并发模型:Goroutines 和 Channels 使得编写并发代码非常简单高效。
    • 丰富的生态:Go 拥有强大的标准库和成熟的第三方库生态系统。
    • 单文件可执行程序:Go 应用程序可以被编译成单一的静态链接可执行文件,便于分发。
  • API 接口:Wails 提供了一套 Go API 和结构体,用于在后端实现业务逻辑,并通过 JSON-RPC 风格的机制暴露给前端。

2.3 Runtime 桥接 (IPC)

  • 定义:Wails 框架在前端 JavaScript 和后端 Go 之间建立了一个高效的通信桥梁。
  • 工作原理
    • 前端调用后端 (Go 方法):前端 JavaScript 通过 window.go.main.<YourStruct>.<YourMethod>() 这样的 API 来调用 Go 后端注册的结构体方法。这些 Go 方法会被自动暴露给前端。Wails 会自动进行参数和返回值的序列化/反序列化(JSON)。
    • 后端发送事件到前端 (Event):Go 后端可以通过 runtime.EventsEmit(ctx, "eventName", data) 向前端发送自定义事件,JavaScript 可以在前端使用 runtime.EventsOn("eventName", callback) 监听这些事件。
  • 数据绑定:Wails 的数据绑定功能允许前端直接调用 Go 方法并获取返回值,或者订阅 Go 发出的事件,实现前后端数据的实时同步和交互。

2.4 Wails CLI (Command Line Interface)

  • 定义:Wails CLI 是一个强大的命令行工具,用于创建、开发、构建 Wails 项目。
  • 功能
    • wails init:初始化 Wails 项目,可以选择前端框架模板。
    • wails dev:开发模式运行应用,支持热重载。
    • wails build:构建生产环境的应用,生成安装包(.exe, .app, .deb 等)。
    • wails generate:生成绑定代码等。

2.5 配置文件 (wails.json)

  • 定义:Wails 项目的核心配置文件,定义了应用的元数据、构建选项、桌面原生特性等。
  • 关键配置项
    • name:应用名称。
    • shortname:短名称。
    • description:应用描述。
    • frontend:前端构建命令、分发目录等。
    • wails
      • app:配置应用窗口属性(标题、大小、是否可调整大小等)、图标、菜单等。
      • webview:WebView 特有的配置。
      • build:Go 模块路径、编译标志等。

三、Wails 的开发流程

3.1 准备环境

  1. Go 语言环境:安装 Go SDK (Go 1.18+)。
  2. Node.js 和 npm/yarn:用于前端项目管理。
  3. 系统 WebView 依赖
    • Windows:需要安装 WebView2 Runtime(如果系统没有)。
    • Linux:需要安装 webkit2gtkwebkitgtk 等依赖。
    • macOS:通常无需额外安装。
  4. Wails CLIgo install github.com/wailsapp/wails/v2/cmd/wails@latest

3.2 创建项目

使用 Wails CLI 初始化一个新项目。

1
2
wails init -n my-wails-app -t vue # 选择 Vue 模板
# 或者 wails init -n my-wails-app -t react

项目结构示例:

1
2
3
4
5
6
7
8
my-wails-app/
├── frontend/ # 前端 Web 代码 (例如 Vue/React 项目)
│ ├── index.html
│ ├── src/
│ └── package.json
├── main.go # Go 后端代码和应用入口点
├── wails.json # Wails 核心配置文件
└── go.mod / go.sum # Go 模块文件

3.3 编写前端代码

frontend/ 目录下像往常一样编写你的 Web 应用。
示例 (前端调用后端 Go 方法):
frontend/src/App.vue (Vue 示例)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<template>
<div>
<h1>Hello Wails!</h1>
<input v-model="name" placeholder="Enter your name">
<button @click="greet">Greet</button>
<p v-if="greeting">{{ greeting }}</p>
</div>
</template>

<script setup>
import { ref } from 'vue';

const name = ref('');
const greeting = ref('');

async function greet() {
if (name.value) {
// 调用 Go 后端的 'Greet' 方法,这里的 'App' 是 Go 结构体的实例名
// 假设 Go 后端有一个名为 'App' 的结构体,上面有一个 'Greet' 方法
greeting.value = await window.go.main.App.Greet(name.value);
}
}
</script>

3.4 编写后端代码 (Go)

main.go 中定义 Go 结构体和方法,并注册到 Wails 应用中。
示例 (Go 后端方法):
main.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package main

import (
"context"
"fmt"
"github.com/wailsapp/wails/v2/pkg/runtime"
)

// App struct 包含应用程序的上下文和业务逻辑
type App struct {
ctx context.Context
}

// NewApp 创建一个新的 App 结构体实例
func NewApp() *App {
return &App{}
}

// startup 是在应用启动时调用的方法,用于注入上下文
func (a *App) startup(ctx context.Context) {
a.ctx = ctx
}

// Greet 方法是一个暴露给前端的 Go 方法
// 前端可以调用这个方法,并传递一个 name 参数
func (a *App) Greet(name string) string {
// 可以在这里执行 Go 的业务逻辑,例如文件操作、网络请求等
// 也可以通过 runtime.Log.Info 等记录日志
runtime.LogInfo(a.ctx, fmt.Sprintf("Greet method called with name: %s", name))
return fmt.Sprintf("Hello %s, from Go!", name)
}

func main() {
app := NewApp()

err := wails.Run(&options.App{
Title: "My Wails App",
Width: 1024,
Height: 768,
AssetServer: &options.AssetServer{
Handler: assets.NewFileSystem(),
},
BackgroundColour: &options.RGBA{R: 27, G: 38, B: 54, A: 1},
OnStartup: app.startup, // 注册 startup 方法
Bind: []interface{}{ // 注册 Go 结构体实例,其方法将暴露给前端
app,
},
})

if err != nil {
println("Error:", err.Error())
}
}

3.5 运行与构建

  • 开发模式
    1
    wails dev
    这会启动你的前端开发服务器,并在一个 Wails 窗口中加载它。支持热重载。
  • 构建生产版本
    1
    wails build
    这会编译你的 Go 后端,打包前端资源,并生成针对当前操作系统架构的原生应用安装包或可执行文件。

四、Wails 与 Tauri 的对比

Wails 和 Tauri 都是优秀的 Electron 替代品,它们共享许多核心理念(如使用系统 WebView、小体积、低内存)。主要区别在于后端语言和生态:

特性 Wails Tauri
后端语言 Go 语言 Rust 语言
后端性能 高,Go 的并发和运行时性能优异 极高,Rust 提供极致的内存安全和运行时性能
语言门槛 Go 开发者友好,学习曲线相对平缓 Rust 学习曲线陡峭,对新人可能更具挑战
生态系统 依赖 Go 生态,标准库和工具链成熟 依赖 Rust 生态,内存安全和系统编程能力强
安全强调 良好的安全实践,但也依赖 Go 的安全性 默认安全,Rust 语言特性和严格的权限控制提供更高级别的安全保障
社区活跃度 活跃,但相对 Tauri 稍小 极度活跃,社区成长迅速,获得更多关注和投资
打包体积 极小 (几MB) 极小 (几MB)
内存占用 低,接近原生应用 低,接近原生应用

选择建议:

  • 如果你是 Go 开发者,或者你的项目已经有大量 Go 代码,Wails 可能是更自然、更高效的选择。你可以直接复用 Go 的库和经验。
  • 如果你关注极致的性能、内存安全,或者你的团队已经有 Rust 经验,并且愿意投入学习 Rust,Tauri 提供了更强大的底层控制和更强的安全保证。

五、总结

Wails 提供了一个出色的解决方案,让 Go 开发者能够利用他们熟悉的语言构建高性能、轻量级、跨平台的桌面应用程序。它结合了 Go 语言的简洁、高效和 Web 前端技术的灵活性,为桌面应用开发带来了新的活力。

虽然它仍是一个相对年轻的框架,但其核心优势(小体积、低内存、Go 后端)使其在特定场景下成为 Electron 或其他更重型框架的有力竞争者。对于 Go 语言生态中的开发者而言,Wails 无疑是构建桌面应用时一个值得认真考虑的优秀选择。