前言

为了使前端页面可以独立运行,我在上一篇 React + TypeScript + Electron 示例 中使用 Electron来打包,奈何打包出来的文件太大,调试也相对麻烦(果然步子迈大了,容易扯着蛋)。如果能把前端页面打包到Go二进制文件呢?这样既能跨平台,也可以使前后端分离。

Go 1.16版本添加了embed功能,使我们可以很方便的将文件和Go一起打包。

如何使用 embed

使用//go:embed 指令从文件初始化字符串等。有三种方法使用embed包,

  • 以字符串形式获取文件
  • 以byte切片形式获取文件
  • 将文件转为embed.FS类型

以字符串形式获取文件

和go文件同级目录新建hello.txt文件。

package main

import (
	_ "embed"
	"fmt"
)

//go:embed hello.txt
var s string

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

以byte切片形式获取文件

package main

import (
	_ "embed"
	"fmt"
)

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

func main() {
	fmt.Println(string(b))
}

将文件转为embed.FS类型

package main

import (
	"embed"
	"fmt"
)

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

func main() {
  data, _ := f.ReadFile("hello.txt")
  print(string(data))
}

如何使用 Go embed 服务前端应用程序

将打包好的前端文件放于main.go同级目录

示例代码:

package main

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

//go:embed client/build
var content embed.FS

func clientHandler() http.Handler {
	fsys := fs.FS(content)
	contentStatic, _ := fs.Sub(fsys, "client/build")
	return http.FileServer(http.FS(contentStatic))

}
func main() {
	mux := http.NewServeMux()
	mux.Handle("/", clientHandler())
	http.ListenAndServe(":3000", mux)

}

完整代码参见:https://github.com/akmittal/go-embed

Reference