Go 开发热更新:告别手动重启,用 Air 实现自动重载
引言
写 Go 代码时,每次改一行都要 Ctrl+C 杀进程、再 go run main.go,这个循环极度打断心流。Node.js 有 nodemon,Python 有 watchdog,Go 生态对应的答案是 Air——一个专为 Go 设计的热重载工具,文件保存后自动重新编译并重启,整个过程不到一秒。
本文讲透 Air 的安装、配置、在 VS Code 中的集成,以及 Gin 框架下的完整使用方式。
核心工具:Air
安装
# 方式一:go install(推荐,自动安装到 GOPATH/bin)
go install github.com/air-verse/air@latest
# 方式二:使用官方安装脚本(Linux/macOS)
curl -sSfL https://raw.githubusercontent.com/air-verse/air/master/install.sh | sh -s -- -b $(go env GOPATH)/bin
安装后验证:
air -v
# 输出: __ _ ___
# / /\ | | | |_)
# /_/--\ |_| |_| \ , built with Go ...
确保
$(go env GOPATH)/bin在你的 PATH 中,否则air命令找不到。Windows 下通常是C:\Users\你的用户名\go\bin。
快速启动(零配置)
在项目根目录直接运行:
air
Air 会自动检测 .go 文件变化,重新编译并重启。效果如下:
__ _ ___
/ /\ | | | |_)
/_/--\ |_| |_| \ , built with Go go1.22.0
watching .
watching handlers
!exclude tmp
building...
running...
修改并保存任意 .go 文件后,终端自动输出:
building...
running...
生成配置文件
air init
这会在项目根目录生成 .air.toml,可以精细控制行为:
# .air.toml
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"
[build]
# 编译命令
cmd = "go build -o ./tmp/main ."
# 编译产物路径
bin = "tmp/main"
# 需要监听的文件后缀
include_ext = ["go", "tpl", "tmpl", "html"]
# 排除的目录(node_modules、vendor 等不需要监听)
exclude_dir = ["assets", "tmp", "vendor", "frontend/node_modules"]
# 排除特定文件名
exclude_file = []
# 排除以下划线开头的文件
exclude_regex = ["_test\\.go"]
# 文件修改后延迟多久重建(毫秒),防止连续保存触发多次构建
delay = 1000
# 停止旧进程的信号
stop_on_error = true
# 构建出错时是否继续运行旧版本
rerun = false
[log]
time = false
main_only = false
[color]
main = "magenta"
watcher = "cyan"
build = "yellow"
runner = "green"
[misc]
# 退出时是否清理 tmp 目录
clean_on_exit = true
在 VS Code 中集成
方式一:直接在集成终端运行 Air(最简单)
打开 VS Code 内置终端(Ctrl+`),在项目根目录运行:
air
保持这个终端运行,正常在编辑器里写代码保存,Air 自动重载。这是最简单的方式,零配置。
方式二:配置 VS Code Task(推荐)
在项目根目录创建 .vscode/tasks.json,把 Air 设为一键启动任务:
{
"version": "2.0.0",
"tasks": [
{
"label": "Air: Hot Reload",
"type": "shell",
"command": "air",
"isBackground": true,
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"reveal": "always",
"panel": "dedicated"
},
"problemMatcher": []
}
]
}
之后按 Ctrl+Shift+B 即可一键启动热重载,Air 在独立的终端面板中运行。
方式三:配合 VS Code 调试器(可断点 + 热重载)
Air 负责自动重建,VS Code Debugger 负责断点调试——两者可以结合。
在 .vscode/launch.json 中配置:
{
"version": "0.2.0",
"configurations": [
{
"name": "Go: Air Debug",
"type": "go",
"request": "attach",
"mode": "remote",
"remotePath": "${workspaceFolder}",
"port": 2345,
"host": "127.0.0.1"
}
]
}
.air.toml 中把构建命令改为带 Delve 调试器的形式:
[build]
cmd = "go build -gcflags='all=-N -l' -o ./tmp/main ."
bin = "tmp/main"
full_bin = "dlv exec --accept-multiclient --log --headless --continue --listen :2345 ./tmp/main"
启动 Air 后,在 VS Code 中 F5 附加调试器,即可在保持热重载的同时打断点。
注意:此模式每次重载后需要重新点
F5附加调试器,适合需要深度调试的场景。日常开发直接用方式一/二即可。
Gin 框架下的完整示例
my-gin-app/
├── .air.toml
├── main.go
├── handlers/
│ └── user.go
└── tmp/ ← Air 自动创建,存放编译产物
// main.go
package main
import (
"log"
"my-gin-app/handlers"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/users", handlers.GetUsers)
log.Println("Server running on :8080")
r.Run(":8080")
}
// handlers/user.go
package handlers
import (
"net/http"
"github.com/gin-gonic/gin"
)
func GetUsers(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"users": []string{"alice", "bob"},
})
}
运行 air 后,修改 handlers/user.go 返回的内容,保存,Air 自动重建,一秒内新代码生效。
常见问题
Air 命令找不到
# Windows PowerShell 中检查 GOPATH/bin 是否在 PATH
$env:GOPATH
# 输出如:C:\Users\YasinDoyle\go
# 手动添加到当前 session
$env:PATH += ";C:\Users\YasinDoyle\go\bin"
# 永久添加:在系统环境变量中把 %GOPATH%\bin 加入 PATH
端口已被占用(address already in use)
Air 在某些情况下旧进程没有完全退出,新进程启动时端口冲突。解决方案:
# .air.toml - 增加停止延迟,等待旧进程释放端口
[build]
delay = 1500 # 毫秒
或者在代码中使用 SO_REUSEPORT,但更简单的做法是增加 delay。
只想监听特定目录
[build]
include_dir = ["handlers", "models", "services"] # 只监听这些目录
.env 文件支持
[build]
# 启动命令前加载 .env 文件
full_bin = "set -a && . ./.env && set +a && ./tmp/main"
Windows 下推荐配合 godotenv 在代码中加载:
import "github.com/joho/godotenv"
func main() {
godotenv.Load() // 加载 .env
// ...
}
关联知识
前置知识:
- Go 模块系统(
go.mod/go env GOPATH) - 系统环境变量 PATH 的配置
延伸知识:
- Delve:Go 专用调试器,与 Air 结合实现热重载 + 断点调试
- Task:Go 版 Makefile,可替代 npm scripts 管理开发命令
- Docker 开发环境中的 Air:在容器内运行 Air,配合 volume 挂载实现容器内热重载
参考文档:
实践建议
-
把
tmp/加入.gitignore:Air 的编译产物不需要提交:tmp/ -
团队统一配置:把
.air.toml提交到 Git,确保所有人的开发体验一致。 -
最小验证:项目根目录直接
air,30 秒内就能感受热重载效果,不需要任何配置文件。
总结
在 VS Code 中写 Go 代码告别手动重启的最佳方案是 Air:go install github.com/air-verse/air@latest 安装后,在项目根目录直接运行 air,文件保存即自动重编译重启;进阶用法可通过 .air.toml 精细控制监听目录、编译参数,配合 VS Code Task 一键启动,或结合 Delve 调试器实现热重载 + 断点调试。
