Golang应用实时重新加载利器: Air工具指南

使用Air实现Go程序实时热重载

一、简介

Live reloading(实时重载)和 Hot-reload(热重载)并非完全同义,它们都与开发过程中的代码更新反馈机制有关,但在实现方式和效果上存在差异。

Live reloading(实时重载)

  • 原理:当监测到代码发生变化后,它会直接刷新整个应用程序页面或重新启动应用。就好比在开发网页时,一旦保存了修改后的代码,浏览器会自动刷新页面,从而展示最新的效果;在开发桌面应用或者移动应用时,应用程序会被重新启动。
  • 效果:因为是整体刷新或重启,这就会使得之前在应用中的操作状态丢失。比如在网页表单里填写了部分内容,页面刷新后,填写的内容就没了;在游戏应用中玩到一半,重新启动应用后就得从头开始。
  • 使用场景:对于那些对状态保存要求不高,或者页面结构、样式、整体逻辑改动较大的情况比较适用。像静态网站开发、样式文件修改等场景,使用实时重载就能快速看到修改后的效果。

Hot-reload(热重载)

  • 原理:当代码改变时,它不会重新启动整个应用程序,而是仅替换发生改变的那部分代码模块。在运行时动态更新应用的代码,并且尽可能保留应用当前的状态。
  • 效果:极大程度上保留了应用程序的当前状态,用户可以继续之前的操作,不会因为代码更新而受到过多干扰。比如在开发一个单页面应用(SPA)时,修改组件代码后,页面不会刷新,组件会以更新后的状态继续显示,之前在页面上的滚动位置、表单填写内容等都能得以保留。
  • 使用场景:在开发复杂的交互应用时特别有用,比如前端的 React、Vue 等框架开发的项目,后端的 Node.js 项目等。开发人员可以在不中断应用运行状态的情况下,快速验证代码修改的效果,提升开发效率。

1.1 什么是live reloading

Live Reloading是一项功能,它使您的开发环境能够监视代码的更改并自动重新加载应用程序。当您保存文件时,当检测到源码文件变更,会重新构建应用程序并重新启动它。这样就避免了您在每次更改后手动停止服务、重新构建应用程序并再次启动的过程。


Go开发中Live Reloading的好处:

Live Reloading可以显著加快开发过程。对于习惯于在运行代码之前编译代码的Go开发人员来说,实时重新加载意味着改进的工作流程和即时反馈。其益处包括:

  1. 提高生产率:开发人员无需手动重新构建即可保持专注。
  2. 节省时间:实时重新加载减少了在正在运行应用程序中看到代码更改所需的时间。
  3. 错误检测:即时重建和重启使开发人员能够更快地检测和纠正错误。
  4. 流畅工作流:无缝集成到开发过程中,使工作流更加流畅和高效。




1.2 什么是AIR

Air是一款面向Go应用程序的命令行程序,旨在提供实时重新加载功能。它能够监控源代码的变更,并自动重新构建和重启您的Go应用程序。这意味着您可以更多地专注于开发功能,而不是重复性任务。


功能:

Air提供了一系列适用于现代Go开发环境的功能:

  • 自动重新构建:检测文件更改并触发重新构建。
  • 可自定义的构建命令:允许您自定义项目需要的构建命令。
  • 目录排除:允许您指定要排除监视的目录。
  • 支持新目录:可以监视Air启动后添加的新目录。
  • 丰富且易读的日志:通过颜色编码增强输出日志的可读性。
  • CLI参数:可以通过命令行参数直接设置配置字段,以便快速调整。
知识扩展:CLI参数

CLI 是 “Command-Line Interface” 的缩写,即命令行界面。CLI 参数指的是在命令行中运行程序时,跟随在命令后面用来调整程序行为的额外信息。下面从几个方面为你详细介绍:


常见用途

  • 指定文件或路径:很多程序需要处理特定的文件或者在特定的目录下工作。例如,在使用 gcc 编译 C 语言代码时,你需要指定要编译的源文件,像 gcc main.c -o main 命令里,main.c 就是一个 CLI 参数,它告知 gcc 要编译的源文件是 main.c
  • 设置程序选项:可以通过 CLI 参数来控制程序的不同行为。比如在使用 ls 命令列出目录内容时,-l 参数能让它以长格式显示文件信息,像 ls -l 就会显示文件的权限、所有者、大小等详细信息。
  • 传递配置信息:在运行一些复杂的程序时,可能需要传入配置信息。例如,数据库备份脚本可能需要你提供数据库的用户名、密码、主机地址等信息,这些信息可以通过 CLI 参数传递给脚本。

表示形式

  • 短选项:通常以单个连字符 - 开头,后面跟一个字母。例如,ls -a 中的 -a 就是短选项,它的作用是显示所有文件,包含隐藏文件。
  • 长选项:以两个连字符 -- 开头,后面跟一个单词。比如,docker run --name my_container 中的 --name 就是长选项,它用于为新创建的容器指定一个名称。
  • 参数值:有些选项后面需要跟一个具体的值。例如,git clone https://github.com/example/repo.git my_folder 里,https://github.com/example/repo.git 是要克隆的仓库地址,my_folder 是指定的本地目录名称,它们都是参数值。

代码中处理 CLI 参数

在不同的编程语言里,处理 CLI 参数的方式也不一样。下面是 Python 和 Go 处理 CLI 参数的示例:

Python

1
2
3
4
5
6
7
8
9
10
11
import sys

# 打印所有命令行参数
print("所有命令行参数:", sys.argv)

# 打印脚本名称
print("脚本名称:", sys.argv[0])

# 打印第一个参数(如果存在)
if len(sys.argv) > 1:
print("第一个参数:", sys.argv[1])

Go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main

import (
"fmt"
"os"
)

func main() {
// 打印所有命令行参数
fmt.Println("所有命令行参数:", os.Args)

// 打印程序名称
fmt.Println("程序名称:", os.Args[0])

// 打印第一个参数(如果存在)
if len(os.Args) > 1 {
fmt.Println("第一个参数:", os.Args[1])
}
}

在上述示例中,Python 借助 sys.argv 来获取 CLI 参数,而 Go 则使用 os.Args 来获取。





二、安装与配置

2.1 安装

要使用 Air,首先需要安装它。你可以使用 go installbrew install 来安装:

1
2
3
4
5
# 使用 Go 安装
go install github.com/air-verse/air@latest

# 如果使用 Homebrew
brew install air

安装完成后,可以通过以下命令确认 Air 是否成功安装:

1
air -v




2.2 配置

创建配置文件

虽然可以直接使用 Air 的默认配置,但为了更好地定制化,我们可以生成一个配置文件。Air 提供了 init 命令来生成 .air.toml 配置文件:

1
air init

生成的 .air.toml 文件包含了默认的配置,开发者可以根据自己的需求进行调整。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"

[build]
args_bin = []
bin = "./tmp/main"
cmd = "go build -o ./tmp/main ."
delay = 1000
exclude_dir = ["assets", "tmp", "vendor", "testdata"]
exclude_file = []
exclude_regex = ["_test.go"]
exclude_unchanged = false
follow_symlink = false
full_bin = ""
include_dir = []
include_ext = ["go", "tpl", "tmpl", "html"]
include_file = []
kill_delay = "0s"
log = "build-errors.log"
poll = false
poll_interval = 0
post_cmd = []
pre_cmd = []
rerun = false
rerun_delay = 500
send_interrupt = false
stop_on_error = false

[color]
app = ""
build = "yellow"
main = "magenta"
runner = "green"
watcher = "cyan"

[log]
main_only = false
silent = false
time = false

[misc]
clean_on_exit = false

[proxy]
app_port = 0
enabled = false
proxy_port = 0

[screen]
clear_on_rebuild = false
keep_scroll = true

主要配置项包括:

  • cmd: 运行程序的命令
  • bin: 编译输出的二进制文件路径(让air去运行)
  • watch_dir: 需要监听的目录或文件
  • exclude_dir: 排除不需要监听的目录
  • extensions: 监听的文件扩展名

一个常见的配置文件可能如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# .air.toml

# 工作目录
root = "."
tmp_dir = "tmp"

# 需要监控的文件类型
[watch]
extensions = ["go", "tpl", "html", "js"]

# 编译输出的二进制文件路径
[build]
bin = "bin/app"
cmd = "go build -o bin/app main.go"

air 配置的完整示例


启动热重载

配置完成后,只需在项目根目录运行 air 命令,Air 就会自动监控代码变更并实时重载:

1
air




三、工作原理以及使用场景

3.1 工作原理

工作原理分析

Air 的功能背后的核心原理可以分为以下几步:

  1. 文件变更监控Air 使用文件系统监听(类似于 fsnotify 库)来实时监控项目中的代码文件。当监控的文件(如 .go 文件)发生变更时,Air 会捕获到这一事件。
  2. 重新编译:在捕获到文件变更后,Air 会根据 .air.toml 中的配置自动调用 go build 命令,重新编译项目的代码,生成新的可执行文件。
  3. 重启应用:一旦新版本的可执行文件编译完成,Air 会停止当前运行的旧进程,并启动新编译的程序,从而实现实时重载效果。
  4. 增量优化Air 在重载过程中,采用了增量编译的方式,只对修改的部分文件进行编译,减少了整体的编译时间,从而提升了重载的速度。

通过这些机制,Air 能够在文件保存后几乎瞬间完成代码的重载,为开发者提供了流畅的开发体验。





3.2 使用场景

Air 尤其适合以下几种开发场景:

  1. Web开发:在开发Web应用时,前端和后端代码经常需要频繁修改。Air 可以实时监控后端代码,保证每次修改后都能立刻看到效果。
  2. API开发:在API开发过程中,热重载可以减少调试的中断,保持高效的开发节奏。
  3. 快速迭代开发:如果你正在进行快速的功能迭代,Air 可以极大地减少重启的操作,让开发流程更加顺畅。

如果你是Go开发者,并且正在寻找一种快速实现热重载的工具,Air 无疑是一个非常不错的选择。