gin: 打包模板文件、静态文件到二进制文件中

一,默认html模板不会打包到二进制文件中

如果二进制文件的当前目录下不包含html模板文件路径,会报错如下

$ ./mediabank 
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /static/*filepath         --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (3 handlers)
[GIN-debug] HEAD   /static/*filepath         --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (3 handlers)
panic: html/template: pattern matches no files: `templates/**/*.html`

goroutine 1 [running]:
html/template.Must(...)
        /usr/local/soft/go/src/html/template/template.go:368
github.com/gin-gonic/gin.(*Engine).LoadHTMLGlob(0xc0001c3ba0, {0xa8207b, 0x13})
        /data/gopath/pkg/mod/github.com/gin-gonic/gin@v1.10.1/gin.go:263 +0x2f2
mediabank/routes.Routes()
        /data/goapp/mediabank/routes/routes.go:15 +0x5b
main.main()
        /data/goapp/mediabank/main.go:10 +0x13

二,用打包到二进制文件中

代码

main

package main

import (
    "embed"
    "mediabank/routes"
)

// 嵌入文件只能为源码文件同级目录和子目录下的文件
//go:embed static/* templates/*
var embedFs embed.FS

// 入口函数
func main() {
    //引入路由
    r := routes.Routes(embedFs)

    //run
    r.Run(":8080")
}

route

package routes

import (
	"embed"
	"github.com/gin-gonic/gin"
	"html/template"
	"io/fs"
	"mediabank/controller"
	"net/http"
)

func Routes(embedFs embed.FS) *gin.Engine {

	router := gin.Default()

	//1, 加载模板文件
	tmpl := template.Must(template.New("").ParseFS(embedFs, "templates/**/*.html"))
	router.SetHTMLTemplate(tmpl)
	//2, 加载静态文件
	fp, _ := fs.Sub(embedFs, "static")
	router.StaticFS("/static", http.FS(fp))
    //3,加载favicon
	//static是存放favicon.ico的目录
	faviconHandler := http.FileServer(http.FS(fp))
	router.GET("/favicon.ico", func(c *gin.Context) {
		faviconHandler.ServeHTTP(c.Writer, c.Request)
	})


	//media
	media := controller.NewMediaController()
	mediaGroup := router.Group("/media")
	{
		mediaGroup.GET("/detail", media.Detail)
		mediaGroup.GET("/list", media.List)
		mediaGroup.GET("/user", media.User)
	}

	return router
}

三,运行结果:

$ ./mediabank 
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /static/*filepath         --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (3 handlers)
[GIN-debug] HEAD   /static/*filepath         --> github.com/gin-gonic/gin.(*RouterGroup).createStaticHandler.func1 (3 handlers)
[GIN-debug] GET    /favicon.ico              --> mediabank/routes.Routes.func1 (3 handlers)
[GIN-debug] GET    /media/detail             --> mediabank/controller.(*MediaController).Detail-fm (3 handlers)
[GIN-debug] GET    /media/list               --> mediabank/controller.(*MediaController).List-fm (3 handlers)
[GIN-debug] GET    /media/user               --> mediabank/controller.(*MediaController).User-fm (3 handlers)
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
[GIN-debug] Listening and serving HTTP on :8080

 

posted @ 2025-09-20 09:46  刘宏缔的架构森林  阅读(19)  评论(0)    收藏  举报