很多文章里介绍了go1.16的embed
使用方式,但很少讲怎么把embed
运用到项目中,大家在使用这些新功能的感觉就如下图所示:
本文介绍下go1.16的embed
新特性,如何运用到实际项目中。
演示命令行启动一个WEB
为了方便大家体验embed新特性,我写了一个demo。该demo,可以通过go install直接安装。安装条件是需要你的Go必须大于等于Go1.16。
-
~
go install github.com/gotomicro/embedctl@latest
-
~ embedctl
访问 http://127.0.0.1:8888 可以看到以下界面可以看到Go可以通过命令行,快速启动一个web,这得益于Go1.16的embed
新特性。接下来我们就介绍如何使用embed
。
Embed简单用法
embed一共有三种数据格式
数据类型 | 说明 |
---|---|
[]byte | 表示数据存储为二进制格式,如果只使用[]byte和string需要以import (_ "embed") 的形式引入embed标准库 |
string | 表示数据被编码成utf8编码的字符串,因此不要用这个格式嵌入二进制文件比如图片,引入embed的规则同[]byte |
embed.FS | 表示存储多个文件和目录的结构,[]byte和string只能存储单个文件 |
我们使用一个最简单方式演示下嵌入一个 text
文件
-
import (
-
_
"embed"
-
)
-
//go:embed test.txt
-
var txt
string
test.txt文件与embed
的go文件同级,我们就可以读取到txt里的字符串内容。
Embed嵌入到Gin框架
要想将Embed
投入当实际生产项目,那么我们就需要用到 embed.FS
这个数据类型,它表示存储多个文件和目录的结构。目前gin框架支持的静态文件的代码如下所示
func (group *RouterGroup) StaticFS(relativePath string, fs http.FileSystem) IRoutes
我们主流框架是还未支持embed.FS
数据类型,所以需要做下改造,将embed.FS
转换为http.FileSystem
。
-
// 嵌入普通的静态资源
-
type webui
struct {
-
webuiEmbed embed.FS
// 静态资源
-
path
string
// 设置embed文件到静态资源的相对路径,也就是embed注释里的路径
-
}
-
-
// 静态资源被访问的核心逻辑
-
func (w *webui) Open(name string) (http.File, error) {
-
if filepath.Separator !=
'/' && strings.ContainsRune(name, filepath.Separator) {
-
return
nil, errors.New(
"http: invalid character in file path")
-
}
-
fullName := filepath.Join(w.path, filepath.FromSlash(path.Clean(
"/"+name)))
-
file, err := w.webuiEmbed.Open(fullName)
-
wf := &WebuiFile{
-
File: file,
-
}
-
return wf, err
-
}
-
-
type WebuiFile
struct {
-
io.Seeker
-
fs.File
-
}
-
-
func (*WebuiFile) Readdir(count int) ([]fs.FileInfo, error) {
-
return
nil,
nil
-
}
做完转换后,我们就可以使用gin返回embed
提供的静态资源。
-
// 设置简单的演示静态资源
-
webuiSimpleObj := &webui{
-
webuiEmbed: simple.WebUI,
-
path:
"webui",
-
}
-
-
// 设置简单的演示静态资源
-
handler.StaticFS(
"/webui/", webuiSimpleObj)
访问http://127.0.0.1:8888/webui,可以看到数据
Embed嵌入Ant Desgin
依葫芦画瓢,我们将整个ant design嵌入进来
-
// 设置ant design的路径,在config.ts里配置
-
handler.StaticFS(
"/ant/", webuiAntObj)
-
// 访问首页跳转到ant design的welcome页面
-
handler.GET(
"/",
func(ctx *gin.Context) {
-
ctx.Redirect(
302,
"/welcome")
-
return
-
})
-
// Ant Design前端访问,try file到index.html
-
handler.GET(
"/welcome",
func(context *gin.Context) {
-
context.FileFromFS(
"/welcome", webuiAntIndexObj)
-
})
在设置前后端分离的项目,我们需要做try file到index.html操作,否则刷新页面,会走到后端,详细操作看https://github.com/gotomicro/embedctl
1·访问http://127.0.0.1:8888,可以看到ant design页面
Show Me Code
演示代码: https://github.com/gotomicro/embedctl
扩展阅读搭建Go1.16
wget https://golang.org/dl/go1.16rc1.darwin-amd64.tar.gz
将二进制下载到/usr/local/目录下
设置go软链接到go1.16,如下所示
总结Go Embed有什么用处
能够在命令行工具里嵌入WEB
-
go install 快速安装,启动web
该web可以提供生成代码的平台
该web可以提供例如json to struct等数据结构转换
可以大大提高Go的工具链能力
能够将前端资源打包到一个二进制包里,方便部署和安装
静态资源访问没有io操作,速度非常快
转载:https://blog.csdn.net/RA681t58CJxsgCkJ31/article/details/113777516