Skip to content

将静态资源打包进go binary

在使用 Go 进行开发的时候,经常会遇到一些需要以来静态资源的情况,例如:

  • 配置文件
  • 管理后台的静态资源(各种 HTML、CSS、JS、图片等)

在这种情况下,如果最终的发布包是一个二进制文件和一堆所依赖的静态资源,使用起来就会非常不方便,例如:

  • 由于资源路径等问题导致的资源无法解析
  • 误删资源文件导致程序崩溃

在这种情况下,我们可以通过 embed 包将静态资源打包进二进制文件中,这样最终只需要发布一个二进制文件即可。

通过引入 embed 包以及 //go: embed 指令就可以将静态资源打包进发布包,支持将文件打包为如下三种格式:

  • string
  • []byte
  • embed.FS

例如:

go
package main

import (
  "embed"
  "fmt"
)

//go:embed hello.txt
var s string

//go:embed hello.txt
var b []byte

//go:embed hello.txt greeting.txt
var f embed.FS

func main() {
  fmt.Println(s)
  fmt.Println(b)

  data, _ := f.ReadFile("greeting.txt")
  print(string(data))
}

基于这样的能力,我们还可以将整个静态网站打包进二进制包,例如管理后台、文档、博客等。参考如下:

.
├── blog
│   ├── 404.html
│   ├── assets
│   ├── favicon.ico
│   └── index.html
├── go.mod
└── main.go
go
package main

import (
  "embed"
  "fmt"
  "io/fs"
  "net/http"
)

//go:embed blog
var f embed.FS

func main() {
  blog, _ := fs.Sub(f, "blog")

  fmt.Println("Go to http://localhost:8080")
  http.Handle("/", http.FileServer(http.FS(blog)))
  http.ListenAndServe(":8080", nil)
}