本地开发联调
本教程共 42 篇 · 第 31 篇 · 更新于 2026-08-03
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.go 和 window.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 能保存的包括 assetdir、reloaddirs、wailsjsdir、debounce、devserver、frontenddevserverurl、viteservertimeout 这几项。
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是本地路径,别把带replace的go.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.mod 加 replace 换库,两步缺一不可。用完记得清理,别把本地路径带进仓库。
到这里,系统能力与集成这一部分就讲完了。下一章开始进入构建分发,看看怎么把应用交到用户手上。