I’m building a web application using go language. In a typical web application, there are many files besides the binary file. To deploy your application, you should distribute many files (static files, js, css, html/template etc). But I don’t want to distribute hundreds of files. I want to distribute only an exe file.
The solution is bundling. There are several packages that exist for bundling. I decided to use go-bindata. This package converts any file into manageable Go source code. Useful for embedding binary data into a go program. The file data is optionally gzip compressed before being converted to a raw byte slice.
To install the library and command line program, use the following:
go get -u github.com/jteeuwen/go-bindata/...
Sample Web Application (embed2exe)
To show how we can use go-bindata we are developing a very simple web application. The project source code is on GitHub.
Directory Structure:
ui/ scripts/ app.js styles/ style.css index.tmpl main.go
app.js:
console.log('js file loaded')
style.css:
.content { background-color: antiquewhite; width: 30%; }
index.tmpl:
<html> <head> <title>embed static files</title> <link rel="stylesheet" type="text/css" href="/ui/styles/style.css"> </head> <body> <div class="content"> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </p> </div> <script type="text/javascript" src="/ui/scripts/app.js"></script> </body> </html>
main.go:
package main import ( "fmt" "html/template" "log" "net/http" "strings" ) func indexHandler(w http.ResponseWriter, r *http.Request) { fmt.Println("index handler") err := indexTemplate.Execute(w, nil) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } func serveResource(w http.ResponseWriter, req *http.Request) { path := req.URL.Path[1:] data, err := Asset(path) if err == nil { var contentType string if strings.HasSuffix(path, ".css") { contentType = "text/css" } else if strings.HasSuffix(path, ".html") { contentType = "text/html" } else if strings.HasSuffix(path, ".js") { contentType = "application/javascript" } else if strings.HasSuffix(path, ".png") { contentType = "image/png" } else if strings.HasSuffix(path, ".svg") { contentType = "image/svg+xml" } else { log.Println("text plain") contentType = "text/plain" } w.Header().Add("Content-Type", contentType) w.Write(data) } else { w.WriteHeader(404) w.Write([]byte("404 Error - " + http.StatusText(404))) } } var indexTemplate *template.Template func init() { fmt.Println("init") indexData, err := Asset("ui/index.tmpl") if err != nil { log.Fatal(err) } indexTemplate = template.Must(template.New("index.html").Parse(string(indexData))) } func main() { http.HandleFunc("/ui/", serveResource) http.HandleFunc("/", indexHandler) http.ListenAndServe(":8080", nil) }
All static files loaded with Asset function.
To build binary data from static files, use the following:
go-bindata ui/...
All static files embedded in a new Go source file, along with a table of contents and an Asset function, which allows quick access to the asset, based on its name. It includes all assets from the ui directory.
Now we can build our application:
go build
We have learned how to bundle static files into a Golang application. We don’t have to distribute our assets with our exe file.
References:
https://neoteric.eu/how-to-serve-static-files-with-golang
http://www.alexedwards.net/blog/serving-static-sites-with-go
https://www.thepolyglotdeveloper.com/2017/03/bundle-html-css-javascript-served-golang-application/
This article very usefull for using go language. Thanks for your everything.