前言介紹
在 golang 1.16之後官方提供的工具包裡面有個 `embed` 可以使用,這使得把檔案嵌入 golang 的二進制編譯更為容易,以至於方便我們部署一些並非 .go 的副檔名檔案。
這裡要介紹的是如何把 vue 作為前端,編譯至我們的 golang 專案內,起一個網頁服務。
在開始前...
我們要先了解 embed 這個工具能帶給我們什麼,我們先實做一個簡單的專案先用指令建立一個 go module
go mod test-embed
然後再專案資料夾建立一個檔案 `sample.txt` 內容長這樣的
hello embedding
這時我們可以撰寫我們的 `main.go`
package main
import (
_ "embed"
"fmt"
)
//go:embed sample.txt
var app string
func main() {
fmt.Println(app)
}
這樣我們可以讀取到 sample.txt 的內文並且顯示在 command line 上,這樣很簡單對吧,並且在編譯後刪除 sample.txt 執行結果不受影響,原因其實很簡單,因為 sample.txt 皆編譯進入 go binary code 內了
go run main.go
以及編譯結果
hello embedding
接下來我們把它 build 出來
go build -o app && ./app
接下來我們開始我們正式的實作
首先我們先建立 golang 專案並建立 go module
go mod init cool-embedding-project
在專案資料夾內建立我們 vue 的前端內容
pnpm create vite --template vue-ts web
這時,我們的專案資料夾內容會長這樣
.
├── go.mod
├── main.go
└── web
├── README.md
├── index.html
├── package.json
├── public
│ └── vite.svg
├── src
│ ├── App.vue
│ ├── assets
│ │ └── vue.svg
│ ├── components
│ │ └── HelloWorld.vue
│ ├── main.ts
│ ├── style.css
│ └── vite-env.d.ts
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts
然後我們到 web 的資料夾內進行前端該有的安裝和編譯
pnpm install && pnpm build
然後我們會產出一個 dist 的資料夾,那是前端編譯出來的 html,js,css結果
接著我們可以開始處理我們的主程式了
package main
import (
"embed"
"io/fs"
"log"
"net/http"
)
//go:embed testwow/dist
var app embed.FS
func main() {
dist, err := fs.Sub(app, "web/dist")
if err != nil {
log.Fatalf("sub error")
return
}
http.Handle("/", http.FileServer(http.FS(dist)))
log.Fatal(http.ListenAndServe(":8080", nil))
}
好了,我們完成了,我們使用 go 提供的 net/http 包去監聽 8080 port,並且我們利用 io/fs 提供的方法去抓取 embed 內的資料,去起一個網頁服務
go run main.go
這時我們會在 http://localhost:8080 看到我們的 vue 畫面了
是時候把他編譯成二進制 code
go build -o app && ./app
由於我們已經打包完成,所以即使我們把 web 資料夾內容刪除,執行
./app
也不會影響到我們的結果,我們成功把 vue 的前端內容編進去我們的 Go語言應用了。