用GoFrame把一个前端产物打包进可执行文件

604 阅读2分钟

总所周知,一般前后端项目都会使用nginx来部署前端项目,有些小伙伴可能会想到go的打包部署非常方便,那有没有一种可能直接把前端内容也打包进产物里面呢?(类似gitea)

有的兄弟,有的,这么简单的需求,只需要用goframe的cli将前端产物文件转译成类似base64编码的的方式,将文件转成一个go代码,然后通过fs读取即可,话不多说咱们直接开始。

gf-cli

首先我们会需要用到gf-cli的pack方法将整个前端产物转译,直接去github下载最新的gf-cli,github.com/gogf/gf/rel… ,比如我的是windows系统就是下载gf_windows_amd64.exe

下载完直接改名gf.exe然后丢到C:\Windows\System32,或者其他在PATH里的目录即可。

image.png

在终端输入gf能正常打印说明安装成功。

创建项目然后打包

我们可以通过gf的init创建一些标准的后端目录结构,但是我这里因为演示的是只是怎么使用gf打包前端项目,这里我们使用最简单的目录结构,一个main.go和那种,我们直接使用goland来创建一个简单项目:

image.png

然后我们再找一个前端项目,我这里就选SoybeanAdmin吧,使用我自己的一个脚手架创建项目:

image.png

修改一下.env.prod加入:

VITE_BASE_URL=/web

然后build出来之后,将dist里的产物放到我们的go项目,然后使用我们的pack命令来打包一下

gf pack ./web packed/data.go -n=packed

image.png

最后修改一下我们的 main.go

package main

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

    "github.com/gogf/gf/v2/frame/g"
    "github.com/gogf/gf/v2/net/ghttp"
    "github.com/gogf/gf/v2/os/gres"

    _ "awesomeProject1/packed"
)

type GFPackFS struct {
    Fallback string
}

// Open GFPackFS实现FS接口
func (f *GFPackFS) Open(name string) (fs.File, error) {
    file := gres.Get(name)
    // file == nil的逻辑用来模仿nginx的try_files配置,如果没有对应的文件,则返回index.html
    // 如果是访问首页,既/web路径的时候,也同样返回我们index.html
    if file == nil || name == "web" {
       fullback := gres.Get(f.Fallback)
       return fullback, nil
    }
    return file, nil
}

func main() {
    s := g.Server()
    // 创建一个路由组,前缀是/web即我们的前端页面
    s.Group("/web", func(group *ghttp.RouterGroup) {
       group.ALL("/*", ghttp.WrapH(http.FileServer(http.FS(&GFPackFS{"web/index.html"}))))
    })
    s.SetPort(8199)
    s.Run()
}

访问一下:http://localhost:8199/web/

image.png

配置下打包参数

众所周知go交叉编译非常方便,而使用gf之后更加方便,只需要在配置文件配置一下目标架构和系统,直接一个build命令即可打包出所有的标架构和系统可执行文件,这里直接创建个配置文件 config.yaml

gfcli:
  build:
    name:     "gf"
    arch:     "amd64"
    system:   "linux,windows"
    path: "./dist/"

然后直接一个 gf build

image.png

就这么简单,部署当然也就一个可执行文件丢上去就完事了!

当然这样只是为了搞个小程序玩玩,正经部署最好还是用nginx哦