vue cli3-cli4 打包后项目在二级路径的方法
默认情况vue的build打包,都是基于根路径来进行的,但是,如果我们将打包的文件放置再二级目录,就会导致文件无法加载,页面空白。
原因有两个:
- 路由路径无法正确匹配
- 资源文件路径错误
下面我们就来讲讲做法
路由配置
在路由实例的创建时,我们常常会看到一个base
选项,内容如下:
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
base官方有很明确是解释:
类型:string
默认值:"/"
应用的基路径。例如,如果整个单页应用服务在/app/
下,然后base
就应该设为"/app/"
简单的讲就是你的项目文件存放的目录层级,从域名根目录下开始计算。
那么process.env.BASE_URL
是什么意思呢?
process.env是node的一个系统变量,在vue cli中,会对这个process.env做自己的操作,默认情况,再不添加任何自定义环境变量文件的情况下,process.env只有两个属性:
{
"NODE_ENV": "development",
"BASE_URL": "/"
}
不管是在development
还是production
或者其他模式,默认的BASE_URL都是/
;
当然我们可以通过增加自定义环境变量的方式覆盖BASE_URL的属性,也可以通过简单的三元判断达到我们想要的效果。
假设我们的二级目录是:/web
const router = new VueRouter({
mode: 'history',
base: process.env.NODE_ENV === "production" ? "/web" : process.env.BASE_URL,
routes
})
那就设置打包模式下的二级路径为:/web
,开发模式默认值即可。
资源文件路径配置
路由的配置只是让router能正确的识别路径,但是资源文件目前都是这种绝对路径的形式:
<link href="css/app.1920c275.css" rel="preload" as="style">
<script src="js/chunk-vendors.433f29b4.js"></script>
<script src="js/app.fcce27f5.js"></script>
所以,为了文件的加载正确,我们需要配置一下资源的路径地址
在项目根目录打开vue.config.js文件,没有就手动创建,添加以下代码:
module.exports = {
publicPath: "./"
}
publicPath的属性表示在打包输出的资源文件基本路径,它是vue cli基于webpack的output.publicPath
的自定义实现,所以官方不建议直接动output.publicPath
,因为会影响到vue cli其他基于output.publicPath
的设置,所以我们设置publicPath即可。
基本路径可以用router的base属性去理解,一样的意思。
这里我们使用:./
相对路径表示,那么输出的资源文件引用就变成了:
<link href="./css/app.1920c275.css" rel="preload" as="style">
<script src="./js/chunk-vendors.433f29b4.js"></script>
<script src="./js/app.fcce27f5.js"></script>
在html中,./
相对路径表示的是相对于html文件为起点开始的,所以我们可以准确的找到资源文件,只要不改变打包后的html与资源文件的结构。
换个思维,如果我们不想设置./
是否可行?
答案当然是可以的,还是以/web
为例
module.exports = {
publicPath: "/web"
}
<link href="/web/css/app.1920c275.css" rel="preload" as="style">
<script src="/web/js/chunk-vendors.433f29b4.js"></script>
<script src="/web/js/app.fcce27f5.js"></script>
这样也是可以的,只要路径正确就行。
但是这样的话路径就是写死的了,相对来说灵活性就差了一点,如果路径变了,我们除了路由配置要修改,还得改动这个,就比较麻烦,使用相对路径./
,配置一次就不用每次都改动,更加方便
服务器配置
上面两种方法是前端配置,事实上如果真的使用二级目录,且路由模式为history
,那么后端也是需要设置的。
以Nginx为例,默认官方推荐添加以下设置:
location / {
try_files $uri $uri/ /index.html;
}
但是这是相对于根目录的设置,如果是二级目录
location / {
try_files $uri $uri/ /web/index.html;
}
那么也是需要加上/web
的。
放个宝塔的配置图:
更多服务端配置参考官方文档:后端配置例子
最新的理解
vue-router的mode模式会对二级目录的适配有影响,如果你是history
模式,那么即便你在vue.confing.js中设置了publicPath: "./"
,你也无法正确的打开页面,因为你的路由无法识别成功。
publicPath控制的是资源的加载,设置为./
只是让你的js文件,css文件等加载的路径变得正确,并不能让你的路由正确识别。
因为history的路由是/xxx/xxx
的形式,而你的二级目录地址会对这个路径增加一个二级目录路径:
https://xxxx.xxx.com/二级目录/路由名
而你的路由无法正确识别/二级目录/路由名
。
所以你需要配置路由的base为你的二级目录,配置好后,前端相关处理就完成了。
后端的nginx也是要对应处理的,就是为了能在页面刷新后还能正确访问到该页面,具体上面也已经细说了,不做重复赘述。
如果你是hash模式,那么只需要配置publicPath: "./"
就行了,因为二级目录不会影响到路由的识别,哈希模式的路由是哈希参数。
至此,二级目录适配完美。
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿站点。未经许可,禁止转载。
暂无评论数据