hertz icon indicating copy to clipboard operation
hertz copied to clipboard

hertz add fs documentation

Open xu756 opened this issue 1 year ago • 5 comments

在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 否则报下面错错误 image

下面可以去掉,忽略

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 我测试了几遍,可以忽略,不知道各位大佬有没有更好的解决方法。

xu756 avatar Nov 09 '23 04:11 xu756