概述
本文探讨 Wails 框架的使用,从搭建环境到开发,再到最终的构建打包,本项目源码 GitHub 地址:https://github.com/chengchuu/go-run-wechat-demo
前言
Wails 是一个桌面应用开发框架。本项目使用 Go 实现后端方法,使用 React 和 TypeScript 编写界面。Wails 负责窗口管理、资源加载和前后端调用。
Wails v2 主要优势:
- 复用系统渲染引擎: Wails 使用平台提供的 WebView,无需在应用中捆绑完整浏览器。这有助于控制分发体积,但运行环境仍需具备对应组件。
- 复用 Go 后端能力: 文件处理、网络请求和业务逻辑可以直接使用 Go 及其生态库。界面使用 Web 技术,后端使用 Go,便于沿用已有代码和工具。
- 自动生成前后端绑定: Wails 为绑定的 Go 方法生成 JavaScript 封装和 TypeScript 类型声明。前端可直接发起异步调用,减少手动维护桥接接口的工作。
- 集成开发与构建流程:
wails dev支持前端更新和 Go 代码自动重建,也提供浏览器调试入口。wails build串联前端构建、资源嵌入和原生打包。 - 提供桌面系统交互接口: 除窗口控制外,Wails 还提供原生菜单、系统对话框和剪贴板接口。v2 也提供系统通知接口,便于扩展桌面功能。
- 保留前端技术选择: 界面可以沿用 HTML、CSS 和 JavaScript 技术。Wails 提供 React、Vue 和 Svelte 等模板,便于复用已有组件与开发经验。本仓库选择 React 和 TypeScript。

更多信息详见 Wails v2 功能介绍和运行机制。
运行本项目
环境要求
当前依赖以 go.mod 和 frontend/package.json 为准。
| Component | Version |
|---|---|
| Go | 1.25.0 |
| Wails | v2.15.0 |
| Node.js | 22.22.2 |
| npm | 10.9.7 |
安装 Wails
请先安装 Go 和 Node.js,再安装 Wails。
go install github.com/wailsapp/wails/v2/cmd/wails@v2.15.0
确保 Go 的可执行文件安装目录位于 PATH 中,验证安装结果:
wails version
也可以通过 wails doctor 来检查是否所有必要的依赖都已正确安装。
# Wails
# ...
# System
# ...
# Dependencies
# ...
# Diagnosis
# ...
SUCCESS Your system is ready for Wails development!
启动应用
完成安装后,进入本仓库根目录执行:
wails doctor
wails dev
wails doctor 检查原生构建依赖。wails dev 启动桌面开发环境,并按 wails.json 运行前端安装和开发命令。首次运行需要下载依赖。
创建一个 Wails 项目
如果需要从头复现教程,请完成前面的环境准备和 Wails 安装,再创建新项目。
创建新项目
使用 Wails CLI 创建项目。CLI 指命令行工具,下面的命令选择 React TypeScript 模板:
wails init -n go-run-wechat-demo -t react-ts
项目结构

main.go: 应用入口,配置窗口、嵌入资源、启动回调和 Go 方法绑定。app.go: 定义App,保存启动上下文,并提供两个演示方法。frontend/index.html和frontend/src/main.tsx: 加载页面并挂载 React 应用。frontend/src/App.tsx: 定义界面、按钮事件和结果状态。样式与静态资源也位于frontend/src/。frontend/wailsjs/: Wails 生成的 Go 调用封装、类型声明和运行时文件。修改 Go 方法后应重新生成,不要手动编辑。go.mod和go.sum: 记录 Go 模块依赖与校验信息。frontend/package.json: 声明前端依赖与脚本。Vite 和 TypeScript 配置也位于frontend/。wails.json: 定义产物名称,以及前端安装、开发和构建命令。build/: 保存应用图标和平台打包配置。构建产物位于build/bin/。
启动时,main() 创建 App 并交给 wails.Run。app.startup 保存上下文,React 入口随后挂载界面。点击按钮后,生成的封装调用 Go 方法;返回结果通过 Promise 更新页面状态。
项目实战: 仿微信登录界面
进入开发模式
在项目根目录执行 wails dev,首次运行会安装前后端依赖。

开发模式也提供浏览器调试页面:
To develop in the browser and call your bound Go methods from Javascript, navigate to: http://localhost:34115
前端开发服务器使用 Vite。前端组件修改可触发热更新,以下为日志示例。Go 代码由 Wails 的开发流程重新构建。
1:42:21 PM [vite] hmr update /src/App.tsx
修改代码
窗口样式和布局
main.go 使用 Width 和 Height 设置窗口尺寸,使用 BackgroundColour 设置背景色。Title 指定窗口标题,Bind 注册供前端调用的 Go 实例。
以下为 main.go 中的入口函数:
func main() {
// Create an instance of the app structure
app := NewApp()
// Create application with options
err := wails.Run(&options.App{
Title: "WeChat",
Width: 280,
Height: 400,
AssetServer: &assetserver.Options{
Assets: assets,
},
BackgroundColour: &options.RGBA{R: 255, G: 255, B: 255, A: 1},
OnStartup: app.startup,
Bind: []interface{}{
app,
},
})
if err != nil {
println("Error:", err.Error())
}
}
后端实现
app.go 提供两个演示方法,供前端 JavaScript 调用。LogInSuccess 根据传入的名称返回欢迎消息,SwitchAccountSuccess 返回固定提示。两者均只返回字符串,不执行实际登录或切换账号。
// Log In Success
func (a *App) LogInSuccess(name string) string {
return fmt.Sprintf("Welcome %s, You are logged in!", name)
}
// Switch Account Success
func (a *App) SwitchAccountSuccess() string {
return "You have switched accounts!"
}
Wails 根据绑定实例的导出方法生成调用封装,并提供 TypeScript 类型声明。以下声明位于 frontend/wailsjs/go/main/App.d.ts。前端得到的是异步结果,因此返回类型为 Promise<string>。
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
export function LogInSuccess(arg1:string):Promise<string>;
export function SwitchAccountSuccess():Promise<string>;
前端实现
frontend/src/App.tsx 导入生成的调用封装。按钮事件调用 Go 方法,再通过 setResultText 更新显示内容:
import {useState} from "react";
import logo from "./assets/images/logo-universal-w256.jpg";
import "./App.css";
import {LogInSuccess, SwitchAccountSuccess} from "../wailsjs/go/main/App";
function App() {
const [resultText, setResultText] = useState("");
const name = "除";
const updateResultText = (result: string) => setResultText(result);
function logIn() {
LogInSuccess(name).then(updateResultText);
}
function switchAccount() {
SwitchAccountSuccess().then(updateResultText);
}
return (
<div id="App">
<img src={logo} id="logo" alt="logo"/>
<div id="result" className="result name">{resultText || name}</div>
<button className="btn log-in" onClick={logIn}>Log In</button>
<button className="btn switch-account" onClick={switchAccount}>Switch Account</button>
</div>
)
}
export default App
初始名称固定为"除",页面优先显示 resultText。当前事件处理函数没有处理 Promise 拒绝。单独启动 Vite 也不会提供 Go 调用桥接,应使用 Wails 开发环境验证按钮行为。
frontend/src/App.css 定义按钮样式,以下为相关片段:
.btn {
display: block;
margin: 0 auto;
padding: 0;
text-align: center;
border: none;
font-size: 14px;
}
.log-in {
width: 200px;
height: 36px;
line-height: 36px;
color: #ffffff;
background-color: hsla(148, 61%, 46%, 1);
border-radius: 4px;
margin-top: 70px;
}
.switch-account {
background-color: #ffffff;
color: rgb(89, 107, 144);
margin-top: 22px;
}
此时界面如图:

尝试操作 Log In:

尝试操作 Switch Account:

底部图标:

打包应用
在项目根目录执行 wails build,构建当前平台的应用。Wails 生成绑定,运行前端构建,再编译和打包 Go 应用。
wails.json 将前端构建命令设为 npm run build。该脚本先运行 TypeScript 检查,再由 Vite 生成 frontend/dist。main.go 通过 //go:embed all:frontend/dist 嵌入这些资源。
macOS 应用输出为 build/bin/WeChat.app。如果需要清理输出目录后重建,可使用下面的命令;-clean 会清理 build/bin,请先保存需要保留的产物。
wails build -clean
指定 Intel Mac 目标架构的示例:
wails build -platform=darwin/amd64
指定 Windows AMD64 目标的示例:
wails build -platform=windows/amd64

完成 macOS 构建并安装 create-dmg 后,在仓库根目录执行下面的命令。下面的命令将镜像输出到 build/bin/WeChat.dmg:
wechat_dmg_source=$(mktemp -d)
cp -R build/bin/WeChat.app "$wechat_dmg_source/"
create-dmg build/bin/WeChat.dmg "$wechat_dmg_source"

以上文件可以进入 Releases 页面查看:
https://github.com/chengchuu/go-run-wechat-demo/releases/tag/v1.0.0

更新记录
本文首次编辑于 2024-02-19,最近更新于 2026-09-29。
版权声明
本文为原创文章,作者保留版权。转载请保留本文完整内容,并以超链接形式注明作者及原文出处。
作者: 除除
原文: chengchuu.github.io/?p=6551