Golang静态文件打包成可执行文件

208 阅读1分钟

1. 背景

web后台使用gin轻量化框架,要求将html页面、图片、js以及css静态文件打包到可执行的二进制文件,简化部署。

2. packr/v2

采用 packr2 开源软件实现静态文件打包。以下为代码对比

// 初始代码
func main() {
		engine := gin.Default()
		// 加载html模板
		engine.LoadHTMLFiles("static/index.html")
		// html模板调用的js
		engine.StaticFS("/js", http.Dir("static/js"))
		engine.StaticFS("/css", http.Dir("static/css"))
		engine.StaticFS("/img", http.Dir("static/img"))
		engine.StaticFile("/favicon.ico", "static/favicon.ico")
		engine.GET("/", index)
		group := engine.Group("/api/cc/")
		group.POST("/login", login)
		engine.Run("127.0.0.1:9090")
}
func index(c *gin.Context) {
	c.HTML(http.StatusOK, "index.html", gin.H{})
}

func login(c *gin.Context) {
	type RetHeader struct {
		RetCode int 	`json:"ret_code"`
		RetMessage string	`json:"ret_message"`
	}
	h := &RetHeader{RetCode: -1, RetMessage: ""}
	h.RetCode = 0
	h.RetMessage = "SUCC"
	c.JSON(http.StatusOK, h)
}

使用packr2以后

func main() {
	engine := gin.Default()
    // 初始化packr2,
	box := packr.New("static", "./static")
	engine.StaticFS("/web", box)
	engine.GET("/", index)
	group := engine.Group("/api/cc/")
	group.POST("/login", login)
	engine.Run("127.0.0.1:9090")
}
func index(c *gin.Context) {
    // 将页面请求转交给packr2处理
	c.Redirect(http.StatusFound, "/web")
}

func login(c *gin.Context) {
	type RetHeader struct {
		RetCode int 	`json:"ret_code"`
		RetMessage string	`json:"ret_message"`
	}
	h := &RetHeader{RetCode: -1, RetMessage: ""}
	h.RetCode = 0
	h.RetMessage = "SUCC"
	c.JSON(http.StatusOK, h)
}

3. 打包步骤

下载 packr/v2 运行环境,以及运行依赖

go get -u github.com/gobuffalo/packr/v2/...
go get -u github.com/gobuffalo/packr/v2/packr2

go install github.com/gobuffalo/packr/v2/packr2@latest

到静态文件依赖代码所在目录执行

gaea@CB6261:/home/gaea/Gaea/cc>packr2

执行完毕后会生成以下文件

gaea@CB6261:/home/gaea/Gaea/cc>tree
.
|-- cc-packr.go
|-- packrd
|   `-- packed-packr.go

注意:packr2生成的文件,默认以项目名为首,也就是注意 cc-packr.go 文件中 import 引入路径

// +build !skippackr
// Code generated by github.com/gobuffalo/packr/v2. DO NOT EDIT.

// You can use the "packr clean" command to clean up this,
// and any other packr generated files.
package cc

import _ "Gaea/cc/packrd"

而我们项目名通常以go mod init初始化指定的路径为准,因此需要改成对应的路径,否则编译的时候会出现以下错误

gaea@CB6261:/home/gaea/Gaea/cc>go build 
cc-packr.go:8:8: package Gaea/cc/packrd is not in GOROOT (/home/gaea/go/src/Gaea/cc/packrd)

修改完成后,直接编译即可。