默认情况vue的build打包,都是基于根路径来进行的,但是,如果我们将打包的文件放置再二级目录,就会导致文件无法加载,页面空白。

原因有两个:

  1. 路由路径无法正确匹配
  2. 资源文件路径错误

下面我们就来讲讲做法

路由配置

在路由实例的创建时,我们常常会看到一个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: "./"就行了,因为二级目录不会影响到路由的识别,哈希模式的路由是哈希参数。

至此,二级目录适配完美。

分类: vue cli 标签: vue cli打包二级目录

评论

暂无评论数据

暂无评论数据

目录