hertz add fs documentation
在golang的1.16版本增加了embed的标签,方便我们将静态资源文件打包为二进制文件。
package main
import (
_ "embed"
"fmt"
)
//go:embed index.html
var index string
func main() {
fmt.Printf("测试文件内容: %s\n", index)
}
例如
//go:embed static/imgs
static/imgs下面所有的文件
//go:embed static/imgs/1.png
static/imgs下面的1.png文件
//go:embed static/imgs/*.jpg
static/imgs下面的所有的jpg文件
//go:embed static/imgs/a?.png
static/imgs下面的a1.png/a2.png
下面是hertz 示例(我的打包文件在 dist文件夹下)
文件路径
...
├── router
│ ├── router.go
├── dist
│ ├── 210.async.js
│ ├── 25.async.js
│ ├── 333.async.js
│ ├── 548.async.js
│ ├── 65.async.js
│ ├── 910.async.js
│ ├── favicon.ico
│ ├── index.html
│ ├── p__Home__index.async.js
│ ├── p__Login__index.async.js
│ ├── p__Teacher__edit.async.js
│ ├── p__Teacher__index.async.js
│ ├── t__plugin-layout__Layout.async.js
│ ├── t__plugin-layout__Layout.chunk.css
│ ├── umi.css
│ └── umi.js
├── go.main
├── go.mod
├── go.sum
...
main.go
package main
import (
"embed"
"server/router"
)
//go:embed dist
var Dist embed.FS
func main() {
router.InitRouter(Dist)
}
路由文件 router.go
package router
import (
"context"
"embed"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/app/server"
"server/internal/result"
"server/internal/xerr"
"strings"
)
func InitRouter(file embed.FS) {
h := server.Default()
h.StaticFS("/", &app.FS{
Root: "dist", // 根目录
IndexNames: []string{"index.html"}, // 索引文件
GenerateIndexPages: true, // 生成索引页面
Compress: false, // 压缩
AcceptByteRange: false, // 接受字节范围
PathRewrite: nil, // 路径重写
PathNotFound: func(ctx context.Context, c *app.RequestContext) {
path := string(c.Path())
// 这个函数是路径找不到绘执行这个,例如 /login /home
// css js 文件会在 Root 文件 里面找
// 下面匹配路径
switch {
case strings.HasSuffix(path, ".js"):
return
case strings.HasSuffix(path, ".css"):
return
default:
// 必须有这一步 react vue 项目 不是 '/'路径 刷新后找不到 报 404
// 上面匹配 js css 可以不要,样式文件 会在 Root 文件 里面找,找不到会执行上面的函数
data, err := file.ReadFile("dist/index.html") // 读取react vue 项目的 index.html
if err != nil {
result.HttpError(c, xerr.ErrMsg(xerr.FIleNotExist))
return
}
c.Data(200, "text/html; charset=utf-8", data)
}
}, // 路径未找到
CacheDuration: 0, // 缓存持续时间
CompressedFileSuffix: "", // 压缩文件后缀
})
h.Spin()
}
PathNotFound 必须配置到项目打包文件 index.html 否则报下面错错误
下面可以去掉,忽略
case strings.HasSuffix(path, ".js"):
return
case strings.HasSuffix(path, ".css"):
return
登录页面仍然会打印下面语句
2023/11/09 12:23:02.469640 fs.go:856: [Error] HERTZ: Cannot open file="dist/login", error=open dist/login: no such file or directory
我测试了几遍,可以忽略,不知道各位大佬有没有更好的解决方法。
same to https://github.com/cloudwego/hertz/issues/630
@xu756 其实你的问题不是怎么使用 fs, 你其实应该像我维护过的这个项目的这样的用法来实现你的目的 https://github.com/polarismesh/polaris-console/blob/main/router/router.go
@Skyenought 我有点看不懂你的意思,不知道你想表达什么,我在飞书群里问这个问题,然后解决了。有大佬让我提issue分享出来,我才提了这个issue。 的确,我写的这个有些需要完善。我看不懂你发个gin代码是什么意思,我提这个issue方便以后其他用户遇到这个问题可以找到,我也是在百度找了,再看源码,最终才问群的大佬,得到这个结果。gin实现这个功能,网上资源很多,非常简单。 hertz刚起步,很多功能我非常喜欢(对比gin),我刚才看了,hertz文档关于StaticFS的内容有点少。但hertz是一个非常好的框架,作为一个全栈,我现在单体已经开始从gin转到hertz,微服务也在看kitex源码。
@xu756 我重新打开了这个 issue,用来跟进 StaticFS 文档的添加。
这是一个需要前后端配合的场景,刷新404,在 umi 文档也有几种解决方案,需要从前端配置,( 到配合 nginx 的解决形式,最后切换 nginx 的解决方案 ) 到 hertz 配合 embed 实现
括号内容可跳过。
you can do this
fs 的功能长期并没有很好维护,后续准备下掉。
建议参考 http.Handler adaptor, 直接使用 net/http 相关实现,可以兼容 embed.FS