iris
iris copied to clipboard
[FEATURE REQUEST]Does iris support 'embed' package in Go 1.16 release?
The currently released new version 1.16 of Go provide package embed, so we can embed files like *.html and others into the compiled binary executable file.
I want to know how iris works with embed package when serving static files.
I find out a solution to serve static files with 'embed' package, what we need to do is coverting embed.FS to http.FileSystem. Note that we need to strip off the directory prefix from the embed.FS with fs.Sub so that it matches what is produced by the os.DirFS.
Reference: how-to-use-go-embed
The below are the code: embed build folder (a react.js single page application) to embed.FS
//go:embed build
var build embed.FS
GetFileSystem function in tools package to convert embed.FS to http.FileSystem
package tools
import (
"io/fs"
"log"
"net/http"
"os"
)
// GetFileSystem ..
func GetFileSystem(useOS bool, dir string, fsys fs.FS) http.FileSystem {
if useOS {
log.Print("using live mode")
return http.FS(os.DirFS(dir))
}
log.Print("using embed mode")
fsys, err := fs.Sub(fsys, dir)
if err != nil {
panic(err)
}
return http.FS(fsys)
}
serving static files in iris
app.HandleDir("/", tools.GetFileSystem(false, "build", build), iris.DirOptions{
IndexName: "index.html",
ShowList: false,
SPA: true,
})
But i have no idea how to use Localization feature with 'embed' package in Go 1.16, without using go-bindata, except for your reply!
This is my way, looking forward to a better way.
//go:embed web var embedWeb embed.FS
type webFS struct { FS embed.FS }
func (e *webFS) Asset(name string) ([]byte, error) { return e.FS.ReadFile(name) }
func (e *webFS) AssetInfo(name string) (fs.FileInfo, error) { file, err := e.FS.Open(name) if err != nil { return nil, err } return file.Stat() }
// file list manually func (e *webFS) AssetNames() []string { names := []string{ "web/index.html", "web/public/js/app.js", "web/public/css/app.css", } return names }
server := iris.New()
myWebFS := &webFS{FS: embedWeb}
server.HandleDir("/", "./web", iris.DirOptions{ Asset: myWebFS.Asset, AssetInfo: myWebFS.AssetInfo, AssetNames: myWebFS.AssetNames, })
Try my way.
first update your iris to master latest. go get github.com/kataras/iris/v12@master
then
//go:embed dist/*
var embedWeb embed.FS
fsys, _ := fs.Sub(embedWeb, "dist")
app.RegisterView(iris.HTML(http.FS(fsys), ".html"))
app.HandleDir("/", http.FS(fsys))
That works for me.
better way:
//go:embed dist/*
var embedWeb embed.FS
fsys := iris.PrefixDir("dist", http.FS(embedWeb))
app.RegisterView(iris.HTML(fsys, ".html"))
app.HandleDir("/", fsys)
@Sloaix your code is really much more concise and clean than mine! and i will have a check if it works correctly.
About the further question, do u know how can the Localization feature of Iris works with the 'embed' package in Go 1.16 release?
here is my solution, works fine for me.
{
app.OnErrorCode(http.StatusNotFound, func(c *irisContext.Context) {
req := c.Request()
req.URL.Path = "/frontend/dist" + req.URL.Path
println(req.URL.Path)
fs := http.FileServer(http.FS(EmbedWeb))
fs.ServeHTTP(c.ResponseWriter(), req)
})
}
@axetroy thanks! It works fine.
Hello @yuanzicheng, @Sloaix , @bladewhite, @huyinghuan , @yuanzicheng, @axetroy
This is directly supported to view engines (e.g. app.RegisterView(iris.HTML(..))
) and File Server (app.HandleDir
).
Please update:
go get github.com/kataras/iris/v12@master
go mod tidy