air是当前Fiber项目最主流的热重载工具,它不依赖框架特性,纯监听文件变化并重启进程,与fiber.New()配合最稳;Fiber本身无内置热重载,所有方案均为外部进程管理器。

air 是当前 Fiber 项目最主流的热重载工具,它不依赖框架特性,纯监听文件变化 + 重启进程,和 fiber.New() 配合最稳。别被“Fiber 官方热重载”这类说法误导——它压根没内置热重载,所有方案都是外部进程管理器。
为什么不用 fresh 或自写脚本?
fresh 对 Go modules 支持弱,遇到 replace 或本地路径依赖容易漏编译;自写 inotify 脚本在 Windows/macOS 上行为不一致,且无法优雅终止旧进程(残留 server 占用端口)。而 air 默认支持 GOOS/GOARCH、自动 kill 子进程、可配置构建前清理,实测在 v2 项目中 reload 延迟稳定在 300–600ms。
air 安装与最小配置
全局安装(推荐):go install github.com/cosmtrek/air@latest
项目根目录建 .air.toml,只保留必要项:
[build] cmd = "go build -o ./server ." bin = "./server" include_ext = ["go", "mod", "sum"] exclude_dir = ["node_modules", "vendor", ".git"]
关键点:
-
cmd必须显式加-o ./server,否则air启动的是默认go run,和生产go build行为不一致 - 别碰
full_bin字段——它会强制走 shell 解析,在 Windows 上常因空格路径炸掉 -
include_ext不加tmpl或html,Fiber 默认不读模板文件,加了反而误触发无意义重启
Fiber 启动逻辑必须适配热重载
直接跑 air 却报端口占用?大概率是上一次崩溃后 server 进程没退出干净。解决方案只有两个:
- 每次改完代码,手动
killall server(Linux/macOS)或taskkill /f /im server.exe(Windows) - 在
main.go开头加端口检测逻辑:if isPortUsed("localhost:3000") { log.Fatal("port 3000 occupied") }
更稳妥的做法是:开发时把 app.Listen(":3000") 换成 app.Listen("127.0.0.1:3000"),避免 IPv6 双栈导致的端口冲突误判。
调试断点失效?检查 CGO_ENABLED 和构建标签
用 Delve(dlv)调试时断点不命中,90% 是因为 air 默认开启 CGO_ENABLED=1,而 Fiber 依赖的 fasthttp 在 CGO 模式下会内联部分函数,Delve 无法注入。解决方法:
- 在
.air.toml的[build]下加:env = ["CGO_ENABLED=0"] - 确保
go.mod里没有//go:build cgo类型的构建约束 - VS Code 的
launch.json中env字段也同步设为{"CGO_ENABLED": "0"}
注意:关 CGO 后,出站 HTTPS 请求若依赖系统证书池会失败,开发期可临时用 curl -k 测接口,或在 main() 开头加 fasthttp.AppendRootCA(...) 手动加载证书。
Fiber 本身不参与热重载流程,所有问题本质是进程生命周期管理与构建环境对齐。最容易被忽略的是:你改了路由但页面还是 404,不是 air 没生效,而是浏览器缓存了 301 重定向(比如 StrictRouting 触发的斜杠跳转),此时要清空浏览器历史记录再试。











