Go 1.16的Embed最佳实践,命令行启动一个WEB
很多文章里介绍了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操作,速度非常快
评论