热重载工具(air)原理与使用
一句话结论:air 是 Go 社区常用的开发期热重载工具(早期托管在 cosmtrek 名下,现由 air-verse 组织维护,官方安装路径 github.com/air-verse/air)。原理是“监听文件变化 → 合并抖动后重新编译 → 杀掉旧进程 → 启动新进程并接管输出”的循环,与 Gin 无绑定,任何 Go 项目都能用。它只解决“开发时保存即重启”,生产环境不用它,配置热更新(viper WatchConfig)和进程热重启(air 整进程重启)是两回事。
使用
go install github.com/air-verse/air@latest
air init # 生成 .air.toml
air # 开始监听,改动 .go 后自动编译重启
原理拆解
| 环节 | 做什么 | 注意点 |
|---|---|---|
| 监听 | 观察 include_ext 覆盖的源码文件变更 | 抖动合并(delay),避免一次保存触发多次重启 |
| 编译 | 执行 [build] cmd 产出临时二进制(默认 tmp 目录) | 编译失败时保留旧进程继续跑并提示 |
| 重启 | 杀旧进程再启新进程,接管 stdout/stderr | Windows 下需杀整个进程树 |
| 配置 | .air.toml 控制目录与构建 | exclude_dir 排除构建产物/上传目录 |
.air.toml 常用配置
root = "."
tmp_dir = "tmp"
[build]
cmd = "go build -o ./tmp/main ."
bin = "./tmp/main"
include_ext = ["go", "html", "yaml"]
exclude_dir = ["tmp", "uploads", ".git"]
使用注意
- 修改了 .air.toml 或新增依赖(go.mod)通常需重启 air 本身才生效。
- exclude_dir 要排除 tmp、静态上传等,否则保存资源文件会无谓重启。
- 多模块/大仓库里可把监听 root 限定到变更频繁的目录。
- 局限:每次重启进程内存态全丢(本地缓存、连接预热),且要求本机有完整 Go 工具链——所以只用于开发。
追问记忆点
- 追问:air 和 viper 配置热更新什么关系?——air 是“文件变化→重启整个进程”;viper WatchConfig 是“进程内热换配置”,两者互补不冲突。
- 追问:保存一次文件重启两次是什么原因?——编辑器会先删后写或改多个文件,air 靠 delay 合并抖动窗口内的多次事件。
- 记忆点:监听→编译→杀旧启新;.air.toml 管目录与构建;开发专用,生产不用。