简介

目前 vue 与 gin 的项目基本都是前后端分离部署

二者合并部署的教程非常少,且各有各的问题

结合各个教程后 找到一种比较完美的合并部署方案

vue

使用 axios 时进行如下配置

1
2
3
4
5
const request = axios.create({
baseURL: `${currentDomain}/api`,
timeout: 5000,
headers: { "Cache-Control": "no-cache" },
});

对 baseURL 进行设置是为了能够使用户请求时,前后端的域名端口完全一致,避免造成跨域(必须

并且对于非域名部署的情况,能够方便地动态调整,避免写死 baseURL

headers 的设置是为了 vue dev 环境下,前后端的联调

同时

为了 dev 联调避免出现跨域问题,还应添加代理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
export default defineConfig({
// 其他参数
server: {
// port: 8080,
// open: true,
proxy: {
"/api": {
target: "http://localhost:5731",
changeOrigin: true,
// rewrite: (path) => path.replace(/^\/api/, ""), // 移除 /api 前缀 根据前后端代码 自行修改
},
},
},
});

额外配置 build 后任务,将构建好的 dist 复制到后端目录下

1
2
3
4
5
"scripts": {
"dev": "vite",
"build": "vite build && robocopy ./dist 后端路径/vue /e /z /r:0",
"preview": "vite preview"
},

方便一部送到位

gin

1
2
3
4
5
6
7
8
❯ tree
文件夹 PATH 列表
卷序列号为 AE05-588D
C:.
├─main.go
├─其他
└─vue /* 可改 */
└─assets

main.go 添加 embed 和路由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//go:embed  vue/index.html
var indexHtml []byte

//go:embed vue/*
var vue embed.FS

func main() {
// 其他设置

// 配置允许跨域 方便dev联调
r.Use(cors.New(cors.Config{
AllowOrigins: []string{"*"}, // 允许的域名
AllowMethods: []string{"GET", "POST", "PUT", "DELETE"},
AllowHeaders: []string{"Origin", "Content-Type", "Authorization", "Cache-Control"},
AllowCredentials: true,
}))

// 配置vue路由
assets, _ := fs.Sub(vue, "vue/assets")
r.StaticFS("/assets", http.FS(assets))
icon, _ := fs.ReadFile(vue, "vue/favicon.ico")
r.GET("/favicon.ico", func(c *gin.Context) { c.Data(200, "image/x-icon", icon) })
r.NoRoute(func(c *gin.Context) {
c.Data(200, "text/html; charset=utf-8", indexHtml)
})

// 其他路由
}

使用r.NoRoute将非后端路由全部导向 index.html,并由 index.html 获取 css、js 等

vue 中设置的 router 会被 build 进 js

通过 js 获取 url 来切换页面

对未使用 embed 的方法同理,参考代码自行设置

embed

对于使用embed

由于StaticFSembed的底层代码逻辑

在前端根目录的文件一般不多,这里只有index.html和 icon 文件

可通过单独获取、或通过fs.ReadFile获取,分别参考index.htmlfavicon.ico

对于前端其他文件,需要通过fs.Sub下移到对应目录后才能通过r.StaticFS("/assets", http.FS(assets))配置路由,且前端文件夹名和后端路由必须相同,二者缺一不可,否则会出现空白页面,即请求 js 等文件不存在的,页面无法加载等情况