上一篇发了一个 Wails v3 本地开发者工具箱,没想到留言不少朋友都在问源码。
这篇就把代码整理出来,顺便把项目结构和几个关键实现拆开讲一下。
源码地址:
https://github.com/fengfengzhidao/fengfeng_tools_wails
这个项目不复杂,可以通过这个项目入门 Wails。
因为它至少是一个能实际打开用的小工具:有界面、有输入、有结果、有错误提示,也能打包成 exe。
先看效果
这个工具箱目前有 5 个功能:
- JSON 格式化 / 压缩
- Base64 编码 / 解码
- 时间戳转换
- URL 编码 / 解码
- UUID 批量生成
界面是左侧工具导航,右侧输入输出区。

怎么跑起来
运行前需要本地已经安装 Go、Node.js,以及 Wails v3 CLI。可以先用 wails3 doctor 检查环境。
先克隆代码:
git clone git@github.com:fengfengzhidao/fengfeng_tools_wails.git
cd fengfeng_tools_wails
# 或者
git clone https://github.com/fengfengzhidao/fengfeng_tools_wails.git
cd fengfeng_tools_wails
安装前端依赖:
npm install --prefix .\frontend
开发模式运行:
wails3 dev
生产构建:
wails3 build
Windows 下构建出来的 exe 在:
bin/fengfeng_tools_wails.exe
项目结构
这个项目的结构大概是这样:
fengfeng_tools_wails
├─ main.go
├─ frontend
│ ├─ src
│ │ ├─ App.vue
│ │ └─ main.ts
│ ├─ public
│ │ └─ style.css
│ └─ package.json
├─ build
├─ docs
└─ Taskfile.yml
几个比较重要的文件:
| 文件 | 作用 |
|---|---|
main.go |
Wails 应用入口,创建窗口,加载前端资源 |
frontend/src/App.vue |
工具箱的主要界面和转换逻辑 |
frontend/public/style.css |
页面样式 |
build/config.yml |
应用名称、版本、产品信息 |
Taskfile.yml |
Wails 构建任务 |
如果只是想看业务逻辑,主要看 frontend/src/App.vue 就够了。
main.go 做了什么
Wails 项目的 Go 入口在 main.go。
这里主要做三件事:
- 嵌入前端构建产物
- 创建 Wails 应用
- 创建桌面窗口
最关键的是这段:
//go:embed all:frontend/dist
var assets embed.FS
Wails 会把 frontend/dist 里的静态资源嵌入到 Go 程序里。
也就是说,Vue 构建后的页面会被打进最终的 exe。
窗口创建代码大概是这样:
app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: "枫枫工具箱",
BackgroundColour: application.NewRGB(27, 38, 54),
URL: "/",
})
这里的 URL: "/" 表示窗口加载嵌入进去的前端页面。
为什么这版逻辑都写在前端
这个工具箱现在的几个功能都比较轻:
- JSON 处理
- Base64
- 时间戳
- URL 编码
- UUID 生成
它们都不需要访问本地文件,也不需要调用系统能力。
所以我直接把逻辑写在 Vue 里。
这样代码更直观,你们拿到以后也更容易改。
后面如果要加本地文件读取、日志查看、目录扫描,这些就更适合放到 Go 后端里。
JSON 工具
JSON 工具主要用到 JSON.parse 和 JSON.stringify。
格式化:
function formatJson() {
try {
setResult(JSON.stringify(JSON.parse(input.value), null, 2))
} catch (err) {
setFailure(err, 'JSON 解析失败')
}
}
压缩:
function minifyJson() {
try {
setResult(JSON.stringify(JSON.parse(input.value)))
} catch (err) {
setFailure(err, 'JSON 解析失败')
}
}
这里没有封装得太复杂。
输入合法就输出结果,输入不合法就显示错误。

Base64 工具
Base64 编码和解码要注意中文。
直接用 btoa 和 atob 处理中文会出问题,所以这里加了一层 UTF-8 转换。
function encodeBase64() {
try {
setResult(btoa(unescape(encodeURIComponent(input.value))))
} catch (err) {
setFailure(err, 'Base64 编码失败')
}
}
function decodeBase64() {
try {
setResult(decodeURIComponent(escape(atob(input.value.trim()))))
} catch (err) {
setFailure(err, 'Base64 解码失败')
}
}

时间戳工具
时间戳这里做了一个简单判断:
- 10 位以内按秒处理
- 其他情况按毫秒处理
const milliseconds = raw.length <= 10 ? numeric * 1000 : numeric
const date = new Date(milliseconds)
然后输出本地时间、ISO 时间、秒和毫秒。
这个功能很小,但平时看接口返回时挺常用。

URL 工具
URL 编码和解码主要是 encodeURIComponent 和 decodeURIComponent。
function encodeUrl() {
try {
setResult(encodeURIComponent(input.value))
} catch (err) {
setFailure(err, 'URL 编码失败')
}
}
function decodeUrl() {
try {
setResult(decodeURIComponent(input.value))
} catch (err) {
setFailure(err, 'URL 解码失败')
}
}

UUID 工具
UUID 生成用的是浏览器自带的 crypto.randomUUID()。
function generateUuid() {
const count = Math.min(Math.max(Math.floor(uuidCount.value), 1), 50)
uuidCount.value = count
setResult(Array.from({ length: count }, () => crypto.randomUUID()).join('\n'))
}
这里限制最多生成 50 个,避免手滑生成太多内容

可以怎么继续改
这个版本只是一个前端逻辑工具箱
后面比较适合继续加这些功能:
- 文件选择
- 本地文件读取
- 日志查看
- 配置文件格式转换
- JWT 解析
- Hash 计算
- 正则测试
- API 请求小工具
其中“文件选择、本地文件读取、日志查看”就需要用到 Go 后端能力了。
总结
这篇先把源码补上。
整体看下来,这个项目并不复杂,但已经能看到一个 Wails 桌面应用的基本形态:Go 负责应用入口,Vue 负责界面,前端构建产物再被打进最终的 exe 里。
如果你想入门 Wails,可以先把这个项目跑起来,再从里面挑一个功能改一改。
后面要不要继续沿着这个工具箱往下做,我也会看这篇的反馈。如果评论区对前端调用 Go、本地文件读取、日志查看这些更感兴趣,我再继续拆。