首页 / Wails 入门教程 / Wails 是什么

Wails 入门教程

Wails 是什么

本教程共 42 篇 · 第 1 篇 · 更新于 2026-08-03

Wails桌面开发Go前端跨平台

1. Wails 是什么

本节目标

  • 用一句话说清 Wails 在解决什么问题
  • 知道 Wails 能做什么、不适合做什么
  • 看懂一个最小示例里 Go 和前端是怎么连起来的
  • 判断你手上的项目值不值得用 Wails

1-1 一句话说清 Wails

Wails 是一个让你用 Go 写后端逻辑、用 Web 技术(HTML / CSS / 任意前端框架)写界面 来构建桌面应用的框架。最后一打包,出来的是一个原生的二进制文件,双击就能在 Windows、macOS、Linux 上跑,不需要用户装浏览器、装运行时。

如果你用过 Electron,这个故事就很熟悉了:左边是业务逻辑,右边是网页界面。区别在于,Electron 把一整个 Chromium 浏览器塞进安装包,而 Wails 直接复用操作系统自带的渲染引擎——Windows 上是 WebView2,macOS 上是系统的 WebKit,Linux 上是 GTK 的 WebKit。所以同样一个应用,Wails 的产物往往只有十几兆,而 Electron 动辄上百兆。

Note

WebView 是操作系统提供的网页渲染组件。说白了,它就是你系统里那个浏览器用来显示网页的”引擎核心”,只是不单独给你一个浏览器窗口。

换个角度理解:Wails 把”写网站”和”写桌面程序”这两件事缝合了。你不需要去学 C++ 的窗口 API,也不用碰 Qt 那套复杂的信号槽,前端该怎么写还怎么写,Go 该怎么写还怎么写,中间那根连线 Wails 替你接好了。

1-2 它能做什么

Wails 的定位是”能打硬仗的桌面程序”,不是玩具。下面这些能力在 v2.13.0 里都是现成的:

单文件分发。借助 Go 1.16 之后的资源嵌入能力(//go:embed),前端打包后的静态文件会被编译进最终的二进制里。用户拿到一个 exe 或 app,不需要附带任何资源目录。

Go 方法直接暴露给前端。你在 Go 里写一个公开方法,Wails 启动时用反射扫一遍,自动在前端生成一个同名的 JavaScript 函数,调用它就等于调用 Go。没有 HTTP 接口、没有手写 IPC,前端拿到的是一个返回 Promise 的普通异步函数。

原生系统能力。窗口控制、系统托盘、原生菜单、文件选择框、桌面通知、剪贴板读写——这些桌面程序绕不开的东西,Wails 都封装好了,前端一行调用就能用。

内置开发体验。跑 wails dev 之后,前端改代码热重载,Go 改代码自动重新编译,还有一个内置的 dev server 让你用浏览器 devtools 直接调试界面,体验接近写网页。

双向通信。除了前端调 Go,Go 也能主动推消息给前端(事件系统),比如后台任务跑出进度了,实时送到界面上。

1-3 它不适合做什么

工具没有银弹,先把边界说清楚,免得后面踩坑才发现方向错了:

做不了真正的手机 App。Wails 有实验性的 wails mobile 子命令,但截至 v2.13.0,移动端支持仍不稳定,官方文档把它归在”尝鲜”那一类。要正经做 Android/iOS,还是老老实实上原生或 Flutter。

不是浏览器,别当网页服务器用。Wails 的界面跑在本地 WebView 里,不是远程网页。如果你指望它像服务器那样随便加载外链、跑任意第三方脚本,安全和架构上都不对路。它适合”界面 + 本地逻辑”的桌面程序,不适合做需要复杂远程渲染的云客户端。

非常重的图形计算不在它的强项内。比如你要做专业级 3D 建模、实时视频滤镜这种靠 GPU 猛吃的活,WebView 渲染前端 + Go 算逻辑的组合不是最优解,往往要自己接原生图形接口。

一句话判断:你的程序是”有个界面、主要逻辑在本地跑”的桌面工具,那 Wails 大概率很合适;你要做游戏引擎或云 IDE,那它可能不是首选。

1-4 一个最小示例:前后端怎么连起来

光说概念发飘,看一段能跑的代码。这是 react-ts 模板里最核心的两段——Go 侧和前端侧。

Go 侧,写在 app.go

package main

import "context"

type App struct {
	ctx context.Context
}

func NewApp() *App {
	return &App{}
}

func (a *App) Greet(name string) string {
	return "你好," + name + "!"
}

前端侧,写在 React 组件里:

import { Greet } from "../wailsjs/go/main/App";

export default function App() {
  const handleClick = async () => {
    const msg = await Greet("码上学");
    alert(msg);
  };

  return <button onClick={handleClick}>点我打招呼</button>;
}

注意看这条 import:../wailsjs/go/main/App。这个 wailsjs 目录不是你手写的,是 Wails 在编译时根据 Go 的方法自动生成的。“Greet” 这个名字,就是 Go 里那个 Greet 方法。前端调用时,它返回的是一个 Promise——因为跨进程调用本质是异步的。

Tip

第一次见 wailsjs 目录别慌。它是生成的产物,每次 wails devwails build 都会重新生成,不要手改,也建议加进 .gitignore

把这段对照起来看,Wails 的核心套路就清楚了:Go 写方法 → 启动时自动绑定 → 前端 import 后当普通异步函数调。后面十一章,基本都是在展开这条主线的每一环。

1-5 谁适合用 Wails

如果你符合下面任意一条,Wails 值得你花半天试一把:

  • 你本来就会 Go,不想为了写界面去啃 C++ 或 Electron 那套庞大的 JS 生态。
  • 你是个前端开发者,想把自己写的网页”固化”成一个能双击打开的桌面程序,又不想背一个上百兆的 Electron 包。
  • 你要做的工具是内部用的(运维面板、接口调试器、本地笔记、文件批处理),重点是能跑、好分发,界面漂亮顺手就行。

下一章我们拆开看它内部到底怎么把 Go 和前端接在一起,理解架构之后,后面每章的配置和 API 你都会用得更踏实。

常见误区

以为 Wails 内嵌了一个浏览器。不是。它用的是系统自带的 WebView。好处是包小,代价是不同系统的渲染表现会有细微差别,遇到怪异样式要先想到”这是 WebView 的差异”而不是 Wails 的 bug。

以为前端能直接读本地任意文件、起服务。Wails 的界面运行在受控的本地环境里,前端访问本地资源要走 Wails 提供的资产服务或运行时 API,不是浏览器那套随便 open 本地路径的逻辑。

照着三年前的旧博客抄代码发现编译不过。Wails v1 和 v2 的 API 差别很大,旧文里 wails.Run(&wails.AppConfig{...})window.backend.App.xxx 这类写法在 v2 已经移除。本教程全部以 v2.13.0 为准,看到旧写法直接跳过。

小结

Wails = Go 业务逻辑 + Web 前端界面 + 系统原生渲染引擎,打包成一个跨平台二进制。它轻量、能打系统能力、开发体验接近写网页,但别指望它做移动端或重型图形程序。最小示例里 wailsjs 自动生成的绑定文件,就是 Go 和前端之间的那座桥——记住它,后面每章都绕着它转。

上一篇
已经是第一篇啦
下一篇
核心架构:Go 如何驱动前端