Go:在二进制中嵌入静态文件

Go: embed static files in binary

这可能是一个非常业余的问题。我正在尝试将静态文件嵌入到二进制文件中,即。 html。我如何用 https://github.com/jteeuwen/go-bindata 做到这一点?

因此我可以使用此 https://github.com/jteeuwen/go-bindata#accessing-an-asset 访问资产,但是我如何使用 "data" 以及如何解析文件、执行模板并在目录中提供它们?

我无法在网上找到任何示例,非常感谢您的帮助!

给定如下目录结构:

example/
    main.go
    data/hi.html

example/main.go

package main

import (
    "html/template"
    "log"
    "net/http"
    "os"
)

var tmpl *template.Template

func init() {
    data, err := Asset("data/hi.html")
    if err != nil {
        log.Fatal(err)
    }
    tmpl = template.Must(template.New("tmpl").Parse(string(data)))
}

func main() {
    // print to stdout
    tmpl.Execute(os.Stdout, map[string]string{"Name": "James"})

    http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
        tmpl.Execute(w, map[string]string{"Name": "James"})
    })

    log.Fatal(http.ListenAndServe(":8000", nil))
}

example/data/hi.html

<h1>Hi, {{.Name}}</h1>

运行 像这样:

go-bindata data && go build && ./example

控制台输出:

<h1>Hi, James</h1>

HTTP 输出:

嗨,詹姆斯

5/6 年后,使用 Go 1.16(2021 年第一季度)这应该会更容易,它增加了对嵌入式文件的支持(issue/proposal 41191

It will be permitted to use //go:embed naming a single file to initialize a plain string or []byte variable:

//go:embed gopher.png
var gopherPNG []byte

导入需要将文件标记为包含 //go:embed 行并需要处理。
Goimports(和 gopls 等)可以学习此规则,并根据需要自动将导入添加到带有 //go:embed 的任何文件中。

这引发了关于 issue 42328 的辩论,即如何在使用 //go:embed

时避免意外包含“隐藏”文件

这已在 CL 275092 and commit 37588ff

中解决

Decision to exclude files matching .* and _* from embedded directory results when embedding an entire directory tree.

src/embed/internal/embedtest/embed_test.go

    //go:embed testdata/k*.txt
    var local embed.FS
    testFiles(t, local, "testdata/ken.txt", "If a program is too slow, it must have a loop.\n")

    //go:embed testdata/k*.txt
    var s string
    testString(t, s, "local variable s", "If a program is too slow, it must have a loop.\n")

    //go:embed testdata/h*.txt
    var b []byte
    testString(t, string(b), "local variable b", "hello, world\n")

注意:如果支持 CL 281492cmd/go 会将 embedcfg 传递给 gccgo


另见(2021 年 1 月)issue 43854“选择 //go:embed 忽略文件和空目录”。