VUE项目在k8s ingress里部署
项目开发前端用的是VUE框架,VUE框架部署的时候,一般把项目编译成静态文件,使用
nginx作为服务器对外发布。但是在k8s的环境下,会有不少坑。
问题描述
通常我们把VUE项目编译成静态文件,部署到nginx服务器的某个目录里。通常的docker脚
本类似于下:
FROM nginx
COPY dist/ /usr/share/nginx/html/
COPY nginx/default.conf /etc/nginx/conf.d/default.conf
然后编译docker,并部署到k8s中。并使用ingress映射到外部域名和地址,比如
http://www.test.com。
如果我们需要使用同一个域名访问不同的VUE站点,如使用
http://www.test.com/v1访问
版本v1.0,
http://www.test.com/v2访问版本v2.0,就会出现问题了。
ingress实际上是一个nginx web服务器。通过 proxy_pass可以将一个url映射到后端的服
务器地址。通常的VUE项目编译,必须要是使用域名
https://www.test.com直接访问,因
为VUE编译缺省会把静态文件地址写成绝对地址。否则,当我们使用·
https://www.test.com/ui打开页面时,index.html里包含url是/static/js/xxx.js,这时候页面就会去请求
`
https://www.test.com/static/js/xxx.js,就会返回404。
解决方案
STEP 1
我们就不能让VUE编译使用绝对地址,这时候需要修改项目中的vue.config.js,修改
publicPath从‘/'为'./'
publicPath: process.env.NODE_ENV === 'production' ? './' : '/',
这时候,我们在ingress里配置时,就可以将v1指向后端的nginx docker服务,这时候VUE
里使用的就是相对地址 ./static/js/xxx.js,页面就会去请求`
https://www.test.com/v1/static/js/xxx.js,能正确返回结果
STEP 2
用 createWebHistory() 创建 HTML5 模式,推荐使用这个模式:
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(),
routes: [
//...
],
})
当使用这种历史模式时,URL 会看起来很 "正常",例如
https://example.com/user/id。漂亮!
不过,问题来了。由于我们的应用是一个单页的客户端应用,如果没有适当的服务器配置
,用户在浏览器中直接访问
https://example.com/user/id,就会得到一个 404 错误。
这就丑了。
通常VUE官方给的解决方案参照
https://router.vuejs.org/zh/guide/essentials/history-mode.html,解决方案是当页面刷新时,无法访问的URL返回到一个缺省的页面,比如
index.html。
但是对于在ingress后面的服务,访问的是`
https://www.test.com/v1/user/id`,刷新后
,页面内的静态文件URL就变成
https://www.test.com/v1/usr/static/js/xxx.js,而这
个文件路径是不存在的,会被nginx变成缺省页面index.html,导致页面挂死。
找了很久的解决方案,最后发现只能在编译的时候指定default router模式为hash,如下
export default new Router({
mode: 'hash', // history会去掉url中的#,导致页面刷新失败
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes
})
这样刷新的时候,静态文件URL能正常解析,问题搞定。
VUE Hash路由和HIstory路由的区别,可以参照
https://juejin.cn/post/6935044153248071716
--
FROM 119.139.198.*