avatar

使用go embed将前端静态文件打包到二进制程序


假设我们通过react写了一个SPA的应用,配置生成静态文件时所有文件都要加一个访问前缀,比如/console,这样可以在后端中设置要访问前端时走/console路由,访问其它后端接口时走/api开头的路由。 build之后有了一个web目录。

 1web
 2├── assets
 3│   ├── Login-legacy.d8ec9a20.js
 4│   ├── Login.8d3465f0.css
 5│   ├── Login.97e93d5b.js
 6│   ├── SSDInfo-legacy.885e631e.js
 7│   ├── SSDInfo.3f24a7e6.css
 8│   ├── SSDInfo.f4b20045.js
 9│   ├── bg.d7142683.png
10│   ├── diskInfo-legacy.516034a1.js
11│   ├── diskInfo.1424a851.js
12│   ├── diskInfo.4828c959.css
13│   ├── favicon.696aab71.ico
14│   ├── index-legacy.2019e574.js
15│   ├── index-legacy.32054840.js
16│   ├── index-legacy.38cfbc2e.js
17│   ├── index-legacy.788ad445.js
18│   ├── index-legacy.a35f7e23.js
19│   ├── index-legacy.ebb2eb9f.js
20│   ├── index.12f1f848.css
21│   ├── index.1ca34b6a.js
22│   ├── index.1e495cfc.css
23│   ├── index.4be598f8.js
24│   ├── index.6dc2c885.js
25│   ├── index.8fcf2774.js
26│   ├── index.9c6a6e11.js
27│   ├── index.b0134e29.js
28│   ├── manage-legacy.1fb16174.js
29│   ├── manage.5f755f96.js
30│   ├── polyfills-legacy.f248efce.js
31│   ├── request-legacy.e9e53844.js
32│   ├── request.e2a4817a.js
33│   ├── type-legacy.77c68c4b.js
34│   ├── type.d5091ca0.js
35│   ├── vendor-legacy.5cd9a205.js
36│   └── vendor.c9f6ed1a.js
37└── index.html

在main.go中定义全局变量

1//go:embed web/*
2var staticFS embed.FS

编译后staticFS就自动嵌入了整个web目录的内容,如果把staticFS看成文件系统,它里面是一个目录/web, /web里面才是所有的静态文件

1import "io/fs"
2
3httpServer := gin.Default()
4handler.RegisterRoute(httpServer, DB)
5webFS, _ := fs.Sub(staticFS, "web")  // 去掉web前缀,这样可以直接通过/console就可以访问web的内容,否则只能通过/console/web/index.html访问
6httpServer.StaticFS("/console", http.FS(webFS)) // SPA应用添加了统一的访问前缀/console,使前端页面和后端接口走不同的前缀

一般我们通过浏览器打开一个页面时直接输入网址就行了。因此将/重定向到/console优化用户体验

1httpServer.GET("/", func(c *gin.Context) {
2		c.Redirect(http.StatusPermanentRedirect, "/console")
3	})

这样build后端代码生成的就是一个干净的二进制文件,直接执行就可以访问前端页面。这样的交付物可以隐藏一点技术细节。

评论列表:

暂无评论 😭