Embedding static files in Go
Embedding static files in 2021 has become a bit easier since the release of Go 1.16. The new release comes with a new package embed
which provides a handy set of interface and methods to attach static file in go binaries
Letβs have a short look at how to use this.
First of all you will need Go 1.16,
$ go get golang.org/dl/go1.16.15
$ go1.16.5 download
$ go1.16.5 version
go version go1.16.5
Head over to install instructions to install go binaries directly.
Now before we do anything, letβs create a project directory
$ mkdir embed-demo && cd $_
$ tree
.
βββ assets
βΒ Β βββ report.html
βββ sample.txt
βββ static-demo.go
Our code will be in static-demo.go
Go provides us with 3 ways to embed content:
- On type
string
- On type
byte
- On type
FS
Letβs explore each one of these one by one
package main
import (
_ "embed"
"fmt"
)
func main() {
//go:embed sample.txt
var s string
fmt.Println(s)
}
To specify what variable holds our static file, go directive //go:embed
is used followed by the name of file or a pattern to embed. Note that there must be no space between //
and go
because that is a regular one line comment in Go.
The //go:embed directive requires importing βembedβ, even when using a
string or []byte & since we are not referring to the embed
module directly we are using a blank _ import.
In our code we are embedding a text file sample.txt
here is what it contains
This is a sample file
with multiple lines
and π§οΈ emojis too!
Now lets execute our code to see if actually works
$ go run static-demo.go
This is a sample file
with multiple lines
and π§οΈ emojis too!
Ok thatβs pretty cool (dodge this Javascript!). Now lets see how to share some data to a text file
package main
import (
"embed"
"fmt"
"html/template"
"os"
)
func main() {
//go:embed assets/*
var assetData embed.FS
t, err := template.ParseFS(assetData, "assets/report.html")
if err != nil {
fmt.Println(err)
}
templateData := struct {
Title string
}{
Title: "File inside Go",
}
t.Execute(os.Stdout, templateData)
}
embed.FS
enables us to embed a tree of static files i.e in our case the assets directory as dictated by the directive //go:embed assets/*
which contains a file report.html with following contents
<html>
<head>
<title>{{$.Title}}</title>
</head>
<body>
<h1>Go is cool af!</h1>
</body>
</html>
Patterns in the go directive cannot contain β.β or β..β path elements nor begin with a leading slash. To match everything in the current directory, use β*β
A FS (file system) in Go is a read-only collection of files, usually initialized with a //go:embed directive.
template.ParseFS
takes a FS as first argument followed by a list of glob patterns,
Running this prints out our title correctly inside the HTML template.
$ go run static-demo.go
<html>
<head>
<title>File inside Go</title>
</head>
<body>
<h1>Go is cool af!</h1>
</body>
</html>
It worked!
Resources
- embed - golang
- You can also run
go doc embed
to view the documentaion locally