vue 路由懒加载和多层嵌套路由导致线上的项目有时出现加载css,js文件Loading chunk xxx field失败的情况

这是我真实项目中遇到的,现在记录下,问题比较多,我们一一展开来。


前言:下面这些问题的前提是你线上的项目一开始进去是正常的,如果一开始进去就报资源地址错误,那可能是publicPath的配置有问题,无非是这三种中的一种,publicPath:" ./ " , publicPath: "/", publicPath:"文件夹/"。根据实际情况配置就好了。


问题一:vue路由懒加载导致线上环境偶尔出现 Loading chunk xxxx failed 的错误。

vue项目使用路由懒加载的原因是为了减少首屏打开的时间太长而引入的。如component: () => import("@/views/User/User"),在路由懒加载下会有一种情况。就是你的项目代码更新了,发布到线上,但是用户的页面由于他并没有手动刷新,有时点击某个菜单栏的时候就报了上面图片这个错误。原因是没法打包上传的代码hash值一般都不同,而用户的页面还没刷新,资源路径指向还是原来的,所以就报了以上的错误。一般用户刷新页面后这个问题就解决了。但是我们不可能说没发布一个新版本就通知用户一遍,这是不存在的!那么我们怎么处理这个问题。有两种方法:


        (1)把懒加载改为直接引入,就是直接import xxx from xxxx, 缺点就是使得首屏加载的时候时间变长,自己根据实际取舍。


         (2)在路由文件里加上路由错误处理,如果使用下面的办法还是有问题的话,还是乖乖不要使用路由懒加载了。

/ 解决Loading chunk (\d)+ failed问题
router.onError((error) => {
  const pattern = /Loading chunk (\d)+ failed/g; //这个是网上大部分遇到的
  const cssPattern = /Loading CSS chunk (\d)+ failed/g; //这个是我实际项目中遇到的
  const isChunkLoadFailed = error.message.match(pattern) || error.message.match(cssPattern);
  if (isChunkLoadFailed) {
      // 用路由的replace方法,并没有相当于F5刷新页面,失败的js文件并没有从新请求,会导致一直尝试replace页面导致死循环,而用 location.reload 方法,相当于触发F5刷新页面,虽然用户体验上来说会有刷新加载察觉,但不会导致页面卡死及死循环,从而曲线救国解决该问题
      location.reload();
      // const targetPath = $router.history.pending.fullPath;
      // $router.replace(targetPath);
  }
});


问题二:多层嵌套路由导致watch,computed,transtion过渡失效(实际不是失效,下面详解)

我们项目一般会使用到嵌套路由,不过大多就一层嵌套路由,就是父 -> 子,如果2层以上的嵌套路由,既 xx ->爷 -> 爸 -> 儿子。假如 爸 下面有多个儿子,然后你想在 “爸” 这个组件里监听路由变化,好对各个儿子进行相应的逻辑处理。但是这时你会发现watch路由是没有用的,watch没有进去,又或者你用computed监听路由,在里面打印也是没打印的。难道是watch和computed都失效了吗,明明我切换页面路由变化了呀。


        其实并不是watch和computed失效了,你再看看结构,爸的上面是至少来有爷爷的,也就是说当你儿子路由变化的时候,爷爷那里的<router-view />也是重载了“爸”这个组件,那么“爸”这个组件的生命周期就有执行了一遍,既重新绘制渲染了,所以watch里没有打印,不过你想测试,只需在 "爸" 这个组件里的created或者mounted里添加console.log(), 你就可以发现当 “儿子” 路由变化的时候,“爸” 的created等生命周期又执行了。所以如果你这时想在“爸”这个路由里添加transtion路由动画是没效果的,因为监听不到路由变化。


      解决办法:把父这一层路由放出去和爷爷这一层路由同级,由于同级所以没有嵌套关系,这也就意味着爸如果想使用爷爷里面的东西,就得单独引入该组件。同时可以考虑“儿子”组件不用<router-view>来承载,可以用v-if来判断组件的显示隐藏来代替<router-view>


问题三:路由懒加载和多层嵌套导致线上项目偶尔找不到资源,如Loading chunk xxxx failed 的错误。


          这是我的一个线上bug,本地开发环境没有,因为线上会有缓存导致,我用多层嵌套路由后,watch等那些生命周期没起作用,原因跟 问题一 基本一样,解决办法也是一样,多层嵌套并且使用路由懒加载后,线上的项目每次更新版本,点击二级嵌套路由报Loading CSS chunk (\d)+ failed错误,点击一级嵌套路由是没有的。然后我加了路由错误判断,虽然解决了Loading chunk xxx failed 和 Loading CSS chunk failed。单还是有一千文件报引入错误,所以我把二级嵌套路由修改为一级嵌套路由,用于改成一级嵌套路由,所以公用的一些组件得单独再引入一遍,就解决问题。如果实在是找不到问题的解决办法,那就用直接引入而不是懒加载。


更新2021-01-04:我上面的问题其实是由于我vue.config.js里配置publicPath="./"导致的,实则应该为publicPath="/",这个问题我的另一篇博客有详细说明http://chenqichun.com/articleDetails/61513d5f9e58dfeb349becbf 



落魄前端-小陈
0
0
0
评论
浏览
收藏