问题
在gin项目中如果单纯的只是实现api接口,那打包出来的是一个可执行文件。但如果项目中如果包含一些页面,则必定会引入一些css,jss,html文件。这样会使打包出来后会挂着对应的静态资源文件夹,部署的时候就要带上这些文件夹,没有api项目打包后只有一个可执行文件那么方便。有什么好的方法能解决这个问题呢。
embed
embed是在Go 1.16中新加包。它通过//go:embed指令,可以在编译阶段将静态资源文件打包进编译好的程序中,并提供访问这些文件的能力。这样就能解决部署带页面的项目时候静态文件的问题了。
使用
// 项目目录
├── Dockerfile
├── README.md
├── asset // 静态资源文件
│ ├── bootstrap.min.css
│ ├── bootstrap.min.js
│ └── j.js
├── go-video
├── go.mod
├── go.sum
├── html // html模版文件
│ └── index.html
└── server.go
package main
import (
"embed"
"html/template"
"net/http"
"github.com/gin-gonic/gin"
)
//go:embed html/*
var htmlFS embed.FS
//go:embed asset/*
var assetFS embed.FS
func main() {
app := gin.Default()
// 推荐:引入js css等 例如j.js 访问地址为 localhost:8080/asset/j.js
app.Any("/asset/*filepath", func(c *gin.Context) {
staticServer := http.FileServer(http.FS(assetFS))
staticServer.ServeHTTP(c.Writer, c.Request)
})
// 不推荐:引入js css等 例如j.js 访问地址为 localhost:8080/asset1/asset/j.js
// app.StaticFS("/asset1", http.FS(assetFS))
// 引入html
app.SetHTMLTemplate(template.Must(template.New("").ParseFS(htmlFS, "html/*")))
app.Handle("GET", "/", index)
app.Run()
}
func index(c *gin.Context) {
c.HTML(http.StatusOK, "index.html")
}