golang自动构建和重启Go项目的热加载插件gaper的使用

Golang自动构建和重启Go项目的热加载插件gaper的使用

gaper logo

简介

gaper是一个用于在Go项目崩溃或某些监视文件更改时自动构建和重启的工具,仅用于开发环境

安装

使用go工具安装:

go get -u github.com/maxcnunes/gaper/cmd/gaper

或者下载二进制文件(以1.1.0版本为例,请确保使用最新版本):

curl -SL https://github.com/maxcnunes/gaper/releases/download/v1.1.0/gaper_1.1.0_linux_amd64.tar.gz | tar -xvzf - -C "${GOPATH}/bin"

使用说明

基本用法

NAME:
   gaper - 用于在Go项目崩溃或某些监视文件更改时自动构建和重启

USAGE:
   gaper [global options] command [command options] [arguments...]

GLOBAL OPTIONS:
   --bin-name value                 由gaper构建的可执行文件的名称(默认为当前目录名)
   --build-path value               程序源代码的路径(默认:".")
   --build-args value               构建程序时使用的参数
   --program-args value             执行程序时使用的参数
   --verbose                        开启gaper的详细消息
   --disable-default-ignore         关闭对隐藏文件和文件夹、*_test.go文件和vendor文件夹的默认忽略
   --watch value, -w value          要监视更改的文件夹或文件列表
   --ignore value, -i value         要忽略更改的文件夹或文件列表
   --poll-interval value, -p value  轮询监视文件更改的时间间隔(毫秒,默认:500)
   --extensions value, -e value     要监视更改的文件扩展名(默认:"go")
   --no-restart-on value, -n value  在以下情况下不自动重启受监督的程序:
                                     如果为"error",退出码为0仍会重启。
                                     如果为"exit",无论退出码如何都不重启。
                                     如果为"success",仅当退出码为0时不重启。
   --help, -h                       显示帮助
   --version, -v                    打印版本

监视和忽略路径

对于这些选项,gaper支持静态路径(如build/seed.go)或glob路径(如migrations/**/up.go*_test.go)。

使用目录路径时,请在末尾添加/(如build/),以确保gaper不会包含以相同值开头的其他匹配项(如build/build_settings.go)。

默认忽略设置

由于在大多数项目中不需要监视以下文件的更改:

  • 隐藏文件和文件夹
  • 测试文件(*_test.go
  • vendor文件夹

gaper默认已经忽略了这些情况。不过,如果你需要gaper监视这些文件,可以使用--disable-default-ignore参数禁用此设置。

监视方法

目前gaper使用轮询来监视文件更改。我们计划在不久的将来支持fs事件。

示例

使用gaper提供的所有默认值:

gaper

提供一些自定义配置的示例:

gaper \
    --bin-name build/api-dev \
    --build-path cmd/server \
    --build-args "-ldflags=\"-X 'main.Version=dev'" \
    -w 'public/**' -w '*.go' \
    -e js -e css -e html \
    --ignore './**/*_mock.go' \
    --program-args "-arg1 ok -arg2=nope" \
    --watch .

参考

这个包主要受到了ginnode-supervisor的启发。

基本上,gaper是上述项目的混合体。它从gin的代码库开始,我重写了它,目标是获得类似于node-supervisor(但更简单)的东西。非常感谢这些项目和背后的人们!👏👏

gaper与Gin的主要区别

主要区别在于gaper从Gin中移除了一层复杂性,Gin在执行的服务器上运行了一个代理。它允许推迟构建并在第一次调用时重新加载服务器。而gaper不关心这个功能,它只是在发生更改时重启你的服务器。


更多关于golang自动构建和重启Go项目的热加载插件gaper的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang自动构建和重启Go项目的热加载插件gaper的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用Gaper实现Go项目的热加载

Gaper是一个Go语言开发的工具,可以监控项目文件变化并自动重新构建和重启应用程序,非常适合开发阶段使用。

安装Gaper

go install github.com/maxcnunes/gaper@latest

安装完成后,可以通过gaper -v验证是否安装成功。

基本使用

最简单的使用方式是直接在项目根目录运行:

gaper run main.go

这会监控当前目录下的所有.go文件变化,当检测到修改时会自动重新构建并重启应用。

配置选项

Gaper支持多种配置选项,可以通过命令行参数或配置文件(.gaper.json)指定:

gaper run --build="go build -o myapp" --verbose main.go

常用参数:

  • --build: 自定义构建命令
  • --run: 自定义运行命令
  • --watch: 监控的目录(默认当前目录)
  • --ignore: 忽略的文件/目录模式
  • --delay: 文件更改后的延迟时间(毫秒)
  • --verbose: 显示详细日志

示例配置文件(.gaper.json)

{
  "build": "go build -o myapp",
  "run": "./myapp",
  "watch": ["./cmd", "./pkg"],
  "ignore": ["vendor/*", "*.log"],
  "delay": 1000,
  "verbose": true
}

完整示例

假设我们有一个简单的web服务项目:

// main.go
package main

import (
	"fmt"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, Gaper! (v1.0)")
	})
	
	fmt.Println("Server running on :8080")
	http.ListenAndServe(":8080", nil)
}

使用Gaper运行:

gaper run --build="go build -o app" --run="./app" --watch="./" --ignore="*.log" main.go

与标准库集成

Gaper也可以与标准库的http包配合使用,实现更平滑的重启:

// main.go
package main

import (
	"context"
	"fmt"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"
)

func main() {
	server := &http.Server{
		Addr:    ":8080",
		Handler: http.HandlerFunc(handler),
	}

	go func() {
		fmt.Println("Server running on :8080")
		if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			fmt.Printf("ListenAndServe error: %v\n", err)
		}
	}()

	// 优雅关闭
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
	fmt.Println("Shutting down server...")

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	if err := server.Shutdown(ctx); err != nil {
		fmt.Printf("Server forced to shutdown: %v\n", err)
	}

	fmt.Println("Server exited")
}

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello, Gaper with graceful shutdown! (v1.0)")
}

注意事项

  1. Gaper不适合用于生产环境,仅作为开发工具
  2. 对于大型项目,构建时间可能较长,可以调整--delay参数
  3. 如果项目使用模块外的依赖,确保go.mod文件正确配置
  4. 某些IDE的自动保存功能可能触发频繁重建,可以适当增加延迟

替代方案

除了Gaper,还有其他类似工具:

这些工具各有特点,可以根据项目需求选择最适合的。

回到顶部