Embed Js, Html/Template and Css Files Within Go App

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/

 

 

1 thought on “Embed Js, Html/Template and Css Files Within Go App”

Yorum bırakın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Scroll to Top