前端部署踩坑实战记录(部署后404、页面空白)
作者:夜雨声烦1024
问题
废话不多说,目的是将项目部署到xxx.com/app
路径下。
脚手架用的是vite,一开始什么都没有配置,base(如果是vue.config.js则是对应publicPath)是默认的(根目录),路由模式使用的是histroy,规则大致如下:
const routes = [ { path: '/', component: () => import('@/views/Home.vue')}, { path: '/About', component: () => import('@/views/About.vue')}, ]
当时我的理解是,部署的时候将打包后的文件放在/app/
目录下,那么访问xxx.com/app
就能匹配到对应的路由。
当项目部署后,首先是出现两个文件404问题,分别是@vite/client.js和main.js。
当时在网上看到的解决方法是把base修改成’./',也就是相对路径,修改完一部署,果然没报404了,但是页面一片空白,并且控制台也没有任何报错(这时候并不知道nginx的配置和资源在服务器存放的路径)。
这就奇怪了,明明已经加载了main.js部分的内容,但却没有渲染出组件。然后就在同事的nginx上部署了一下,发现是可以正常访问的,但他的情况是没有加上子路径的,一加上/app
就不行了。其实这里就大致知道是nginx配置与前端打包配置没有配合好的原因了。
解决方法
后面了解了nginx的配置,试了许多方案,终于配置好了:
nginx conf server { # xxx其他配置 listen 80; server_name xxx.com; location /app { alias xxx/nginx-1.20.2/html/app/; try_files $uri $uri/ /app/index.html; } # xxx其他配置 } vite.config.js base: '/app' routes const routes = [ { path: '/app/', component: () => import('@/views/Home.vue')}, { path: '/app/About', component: () => import('@/views/About.vue')}, ]
两个页面都能正常访问,经过测试发现,base需要和location保持一致(后面发现不一定,base可以有多种写法),而文件存放的路径不是关键,即使修改也可以正常访问到(文件需要放到对应的目录下):
nginx server { listen 80; server_name xxx.com; location /app { # 将前端打包文件放到dist目录下 alias xxx/nginx-1.20.2/html/dist/; try_files $uri $uri/ /dist/index.html; } }
那么我最开始设置成的base为’./'时,没有渲染组件是什么情况呢?
nginx server { listen 80; server_name xxx.com; location /app { alias xxx/nginx-1.20.2/html/app/; try_files $uri $uri/ /app/index.html; } } vite.config.js base: './' routes const routes = [ { path: '/', component: () => import('@/views/Home.vue')}, { path: '/About', component: () => import('@/views/About.vue')}, ]
现在看来,确实是因为路由规则不对导致的,如果路由规则修改为如下:
const routes = [ { path: '/app', component: () => import('@/views/Home.vue')}, { path: '/app/About', component: () => import('@/views/About.vue')}, ]
则可以正常访问,说明base不一定要与location一致,而是要保证路由前缀和location要匹配的上。
此外,看到有人说需要配置router中的base,会自动为路由加上前缀,如下:
const routes = [ { path: '/', component: () => import('@/views/Home.vue')}, { path: '/About', component: () => import('@/views/About.vue')}, ] const router = createRouter({ history: createWebHistory(), base: '/app', routes, })
但我试了却没有生效,加与不加,访问xxx.com/app
都是空白页面,且不报错,说明就是没有匹配到对应的路由,可能还是我的写法有问题?
其中如果你某些地方没配置好还会出现访问xxx.com/app
正常,xxx.com/app/About
出现404的问题,可以检查下前端和nginx有没有对应配好。
总结
如果使用history模式,并且需要部署到子级目录下,需要配置好以下内容:
vite.config.js的base(vue.config.js对应publicPath)可以有三种设置方式:相对路径
'./'
、服务器存放资源的路径、nginx配置文件location的路径,设置有误可能出现404。nginx配置如下:
server { listen 80; server_name xxx.com; location /app { alias xxx/nginx-1.20.2/html/app/; try_files $uri $uri/ /app/index.html; } }
alias就是匹配到location后去对应路径下找资源,try_files则是在url前缀包含location但却没有匹配的资源时会去使用的资源。
例如这里location没有配置
/app/About
,但是却可以访问到就是因为这条配置,如果删掉则会出现404,这是因为单页面应用只有一个入口文件,所以可以这么做。route规则中的路径前缀需要与location一致。
这三点如果都没错的话应该就能正确部署了,推荐base、路由前缀、location三者统一,方便配置,也可以减少出错。另外,前端打包后的文件也推荐放到对应级别的目录中,如在本例子中,存放的位置为/xxx/nginx/html/app/
。
其他
当你base设置为资源的绝对路径时(如/dist
),如果你跑本地服务的话,可能会访问不到资源,但是打包后部署上去是可以正常访问的。
看到网上有人说使用base使用’./'会出现刷新404的情况,但我这边没有遇到,如果大家遇到可以说明一下情况,共同探讨。
对于单页面应用,location路径的最后可以不带/。这样的好处是,假如你想要部署的地址是xxx.com/app
,那么你使用xxx.com/app
或者xxx.com/app/
都可以访问到,这是因为配置了try_files,即使找不到,但是由于前缀匹配到了location,可以去寻找默认的文件;
如果location最后携带了/
,则xxx.com/app
访问不到。这是因为location最后加了/
需要精确匹配到xxx.com/app/
前缀才能访问。
当然这也要根据项目需求来决定如何配置。
最后,这是本人初次接触nginx部署,如果有说的不对的地方欢迎指出,共同进步。
到此这篇关于前端部署踩坑实战记录的文章就介绍到这了,更多相关前端部署后404、页面空白内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!