源码来了:用 Wails v3 写一个本地开发者工具箱,完整代码解析
上一篇发了一个 Wails v3 本地开发者工具箱,没想到留言不少朋友都在问源码。 这篇就把代码整理出来,顺便把项目结构和几个关键实现拆开讲一下。 源码地址: https://github.co

源码来了:用 Wails v3 写一个本地开发者工具箱,完整代码解析

发布时间:2026-05-03 (1小时前)

上一篇发了一个 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.parseJSON.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 编码和解码要注意中文。

直接用 btoaatob 处理中文会出问题,所以这里加了一层 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 编码和解码主要是 encodeURIComponentdecodeURIComponent

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、本地文件读取、日志查看这些更感兴趣,我再继续拆。