首页 / Wails 入门教程 / 本地开发联调

Wails 入门教程

本地开发联调

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

Wails桌面开发wails dev热重载调试

31. 本地开发联调

本节目标

  • 说清 wails dev 启动时到底做了哪几件事
  • 会用 http://localhost:34115 在浏览器里调试并直接调用 Go 方法
  • 掌握 -assetdir-frontenddevserverurl-appargs 等常用调试参数
  • 分清前端热重载和 Go 重编译这两条独立链路
  • 需要用未发布版本的 Wails 时,会用 replace 指令接源码

31-1 wails dev 做了哪些事

在项目根目录敲下这行:

wails dev

看起来只是「跑起来」,实际上背后有一串动作。

  • 把项目 go.mod 里的 Wails 版本同步成和 CLI 一致
  • 编译并运行应用
  • 启动一个文件监视器,检测到 .go 文件变化就重新编译、重新运行
  • http://localhost:34115 起一个 Web 服务,把整个应用(不只是前端)通过 http 暴露出来
  • 所有资产从磁盘加载。前端文件改了,应用自动重新加载页面(是 reload,不是 rebuild),所有连着的浏览器也一起刷新
  • 生成 JS 模块:Go 方法的 JavaScript 包装器(带自动生成的 JSDoc,有代码提示)、Go 结构体的 TypeScript 版本
  • 再生成一个模块,提供运行时的包装和 TS 声明
  • macOS 上会把应用打成 .app 再运行,用的是 build/darwin/Info.dev.plist

第四条是本章的重点,很多人装了 Wails 半年都不知道有这个东西。

31-2 34115 端口:在浏览器里调你的桌面应用

wails dev 跑起来之后,用 Chrome 打开 http://localhost:34115,你会看到和应用窗口里一模一样的界面。

这不是「前端预览」,是完整的应用。window.gowindow.runtime 都在,也就是说你能在浏览器控制台里直接调 Go 方法:

// 在浏览器控制台里执行
await window.go.main.App.Greet("码上学")

这个能力有多好用?举几个实际场景。

验证绑定有没有生效。 前端调不通 Go 方法时,先在控制台敲 window.go.main.App,看看方法在不在。在,说明是前端调用姿势有问题;不在,说明绑定没成功。

用熟悉的浏览器插件。 React DevTools、Redux DevTools 这些在 WebView 内置的 devtools 里往往装不了,浏览器里随便用。

手动构造边界数据。 想测试 Go 方法收到空字符串、超长文本、特殊字符时的表现,控制台里敲一行就行,不用改 UI。

想让它自动打开浏览器,加个参数:

wails dev -browser

端口被占用了可以换:

wails dev -devserver "localhost:8899"
Tip

浏览器里跑的是同一个应用实例,你在浏览器里点的操作,Go 侧真的会执行。测试删除、写文件这类操作时留点神,那不是模拟。

Warning

有些运行时能力在浏览器标签页里表现和真实窗口不同,比如剪贴板、窗口控制、原生对话框。这类功能的最终验证要以应用窗口为准。

31-3 两条独立的重载链路

初学者常有个误解,以为改什么代码都会重启应用。实际上有两条链路,触发条件和后果完全不同。

链路一:前端资产变化 → 页面 reload。.tsx.css 这些文件,Vite 检测到变化,页面重新加载。应用进程不重启,Go 侧的状态(比如内存里的缓存、已建立的连接)都还在。这条链路很快,通常几十毫秒。

链路二:Go 文件变化 → 重新编译 + 重启。.go 文件,监视器触发重新编译,然后杀掉旧进程、起新进程。Go 侧所有状态清零,窗口会闪一下重开。这条慢一些,取决于项目大小。

分清这两条,调试时就知道该期待什么。改了 Go 的结构体字段,前端 TS 类型没更新?那是因为你只改了 Go 但监视器没触发重编译,或者绑定生成被跳过了。

控制这两条链路的参数有这些:

参数作用
-extensions触发重新编译的扩展名,逗号分隔,默认 go
-reloaddirs额外触发 reload 的目录,逗号分隔
-debounce检测到资产变化后等多久再 reload,默认 100 毫秒
-noreload关闭资产变化时的自动 reload
-forcebuild强制重新构建应用
-skipbindings跳过绑定生成
-s跳过前端构建

-debounce 在保存频繁的编辑器里有用。有些编辑器保存时会先清空再写入,短时间产生两次文件变化,把 debounce 调到 300 毫秒左右能避免重复 reload。

31-4 接入自己的前端开发服务器

react-ts 模板默认已经配好了 Vite,一般不用管。但如果你的前端项目结构比较特殊,或者想用自己那套已经调教好的 dev server,就需要这两个参数。

-assetdir 指定资产目录,覆盖 wails.json 里的配置:

wails dev -assetdir ./frontend/dist

-frontenddevserverurl 让 Wails 直接用第三方 dev server 提供的资产:

wails dev -frontenddevserverurl http://localhost:5173

设成 auto 的话,Wails 会自己去探测 Vite 服务器:

wails dev -frontenddevserverurl auto

探测超时时间用 -viteservertimeout 调,默认 10 秒。前端依赖多、首次启动慢的项目可以调大一点。

-wailsjsdir 决定生成的 JS 模块放哪:

wails dev -assetdir ./frontend/dist -wailsjsdir ./frontend/src -browser

这条命令的效果是:构建并运行应用,把 Wails JS 模块生成到 ./frontend/src,监视 ./frontend/dist 的变化并 reload,同时打开浏览器连上去。

每次都敲这么长一串很累,加 -save 存进 wails.json

wails dev -assetdir ./frontend/dist -wailsjsdir ./frontend/src -save

之后直接 wails dev 就会沿用这些设置。-save 能保存的包括 assetdirreloaddirswailsjsdirdebouncedevserverfrontenddevserverurlviteservertimeout 这几项。

Note

单独跑 npm run dev 然后用浏览器打开 Vite 的地址,是调不通 Go 方法的。那个进程里没有 Wails 注入的桥,window.go 是 undefined。必须通过 wails dev 启动,或者访问 34115。

31-5 调试参数速查

剩下几个参数在特定场景下很救命。

-appargs:模拟带参数启动。 调试文件关联和深链时不用反复打包:

wails dev -appargs "C:\test\demo.wails"
wails dev -appargs "myapp://note/open?id=123"

-loglevel:控制日志详细程度。 可选 Trace、Debug、Info、Warning、Error,默认 Debug:

wails dev -loglevel Trace

排查启动流程问题时开 Trace,能看到 Wails 内部做了什么。

-race:打开 Go 的竞态检测。 应用里有 goroutine、有共享状态时值得跑一次:

wails dev -race

第 28 到 30 章那些待处理队列、单实例回调,都涉及多 goroutine 访问同一份数据。用 -race 跑一遍能提前发现忘加锁的地方。

-tags:传递构建标签。 需要按标签区分编译内容时用:

wails dev -tags "dev,mock"

-v:输出详细程度。 0 静默、1 标准、2 详细。

31-6 用未发布版本的 Wails

Wails 一直在迭代,新代码合进 master 之后要攒够一批、测过一轮才会打 tag 发版。你需要的某个修复或特性可能还在路上。

这时候可以直接用源码版。三步:

git clone https://github.com/wailsapp/wails
cd wails/v2/cmd/wails
go install

克隆下来的那个目录,后面统称 clonedir。执行完这三步,你机器上的 Wails CLI 就是最新代码编译出来的了。

但这只换了 CLI,项目里引用的 Wails 还是发布版。要让项目也用源码,得改 go.mod,在文件底部加一行 replace

replace github.com/wailsapp/wails/v2 => <clonedir>

实际写法,Windows 上:

replace github.com/wailsapp/wails/v2 => C:\Users\leaan\Documents\wails-v2-beta\wails\v2

Linux 或 macOS 上:

replace github.com/wailsapp/wails/v2 => /home/me/projects/wails/v2

注意路径要指到 v2 目录,不是仓库根目录。

想退回稳定版,把 replace 那行删掉,再重新安装官方 CLI:

go install github.com/wailsapp/wails/v2/cmd/wails@latest
Warning

replace 是本地路径,别把带 replacego.mod 提交到团队仓库。别人拉下来编译会直接失败,因为他们机器上没有那个目录。

31-7 测试某个分支或某个 PR

上一节的流程稍作调整,就能用来验证还没合并的代码。

测试分支,clone 之后先切分支再安装:

git clone https://github.com/wailsapp/wails
cd wails
git checkout -b branch-to-test --track origin/branch-to-test
cd v2/cmd/wails
go install

测试 PR,把 PR 的代码 fetch 成本地分支。命令里的 [IDofThePR] 换成 GitHub 上显示的 PR 编号:

git clone https://github.com/wailsapp/wails
cd wails
git fetch -u origin pull/[IDofThePR]/head:test/pr-[IDofThePR]
git checkout test/pr-[IDofThePR]
git reset --hard HEAD
cd v2/cmd/wails
go install

两种情况都别忘了按上一节的方法在项目 go.mod 里加 replace,否则你测的还是发布版。

这套流程在什么时候用得上?你在 GitHub 上提了个 issue,维护者说「已经在 #1234 里修了」,你可以立刻拉下来验证是不是真的解决了你的问题,而不用等下一个版本。这对开源项目的推进很有帮助。

常见误区

误区一:34115 打不开就以为 dev 没起来。 先看端口是不是被别的程序占了,用 -devserver 换一个试试。

误区二:改了 Go 代码但前端拿不到新方法。 确认监视器有没有触发重编译,看终端输出。也可能是加了 -skipbindings 导致绑定没重新生成。

误区三:在浏览器里测所有功能。 剪贴板、原生对话框、窗口操作这些在标签页里行为不一致,最终要在应用窗口里验证。

误区四:把 replace 提交上去。 团队协作的大坑,提交前检查 go.mod

误区五:用源码版遇到问题就报 bug。 master 上的代码本来就可能不稳定。报 issue 前先确认稳定版是否也有同样问题,说清你用的是哪个 commit。

小结

wails dev 不只是「跑起来」。它同时维护着前端 reload 和 Go 重编译两条链路,还额外送你一个 34115 上的完整应用副本。学会用浏览器控制台直接调 Go 方法,排查绑定问题的效率会有明显提升。

参数不用背,记住几个高频的就够:-browser 开浏览器,-appargs 模拟启动参数,-loglevel Trace 看细节,-race 查竞态,-save 把常用配置存进 wails.json

需要尝鲜未发布版本时,go install 换 CLI,go.modreplace 换库,两步缺一不可。用完记得清理,别把本地路径带进仓库。

到这里,系统能力与集成这一部分就讲完了。下一章开始进入构建分发,看看怎么把应用交到用户手上。