专栏首页MudOnTireVue项目中出现Loading chunk {n} failed问题的解决方法

Vue项目中出现Loading chunk {n} failed问题的解决方法

最近有个Vue项目中会偶尔出现Loading chunk {n} failed的报错,报错来自于webpack进行code spilt之后某些bundle文件lazy loading失败。但是这个问题的根本原因没有被找到,因为这个问题出现的偶然性太高了,而且有的手机上会出现,有的不会,用模拟器不会出现,用真机又会出现,不知道是网络原因还是webpack的bug。在github、stackoverflow等各种地方也找不到原因和解决方案,这是github上关于这个问题的讨论: Loading chunk {n} failed #742,虽然最后还是不了了之,但是大家可以参考一下。

这个问题出现概率比较小但是一旦出现就会导致页面崩溃,所以还是得解决,下面就贴出我的解决方案:

我的思路是既然找不到报错的原因那么尝试去捕获这个错误并做容错处理,有两种实现,一是在服务端捕获这个错误,一个是在前端捕获。

服务端实现

报错的原因是某些js bundle没有被找到,所以在服务端接收到获取该js文件的请求时先判断该js文件是否存在,如果存在直接返回js文件,如果不存在则返回一个提示信息给前端,让前端处理。假设服务端用express作为静态文件服务器,代码如下:

app.all(/\.js$/, (req, res) => {
    const fileName = req.path.slice(req.path.lastIndexOf('/') + 1);
    const filePath = path.resolve(__dirname, './public/static/js/' + fileName);
    if (fs.existsSync(filePath)) {
        fs.sendFile(filePath);
    } else {
        res.setHeader('Content-Type', 'application/javascript; charset=UTF-8')
        res.setHeader('Accept-Ranges', 'bytes')
        res.setHeader('Vary', 'Accept-Encoding')
        res.setHeader('Transfer-Encoding', 'chunked')
        res.setHeader('Last-Modified', new Date().toUTCString())
        res.setHeader('Cache-Control', 'no-cache')
        res.send('window.serverRebuildHook && window.serverRebuildHook();')
    }
});

当js文件未找到时,通过res.send('window.serverRebuildHook && window.serverRebuildHook();')向前端返回一条消息,并执行前端定义的serverRebuildHook方法。

接着我们在前端实现serverRebuildHook方法:

window.serverRebuildHook = function () {
  alert('服务器版本已更新,正在刷新本地缓存,请稍后...');
  location.replace(kk);
}

方法很简单,提示一下用户服务端更新然后重新刷新当前页面。

这种实现是参考 github上的回答, 相对比较繁琐,而且用户体验并不好,只能刷新当前页面,不能跳转到目标页。

前端实现

由于项目里面用到了vue-router,vue-router的错误处理函数 onError 是不是能够捕获该错误呢?我们来看一下官方文档的说明:

当在渲染一个路由的过程中,需要尝试解析一个异步组件时发生错误。 完全符合我们场景,所以在onError方法中我们实现如下代码:

router.onError((error) => {
  const pattern = /Loading chunk (\d)+ failed/g;
  const isChunkLoadFailed = error.message.match(pattern);
  const targetPath = router.history.pending.fullPath;
  if (isChunkLoadFailed) {
    router.replace(targetPath);
  }
});

当捕获到Loading chunk {n} failed的错误时我们重新渲染目标页面,这种实现明显更简单和友好。

后续如果发现了导致Loading chunk {n} failed的本质原因会再更新本文,欢迎关注!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • GitHub超过30000星,Python算法新手入门大全

    GitHub:https://github.com/TheAlgorithms/Python

    昱良
  • Commitizen 互联网公民的简单提交惯例

    安装就像运行以下命令一样简单(如果看到 EACCES 错误,阅读 修复 npm 权限 可能有帮助):

    iOSDevLog
  • Git冲突解决: git checkout高级用法

    Git冲突的原因,一般是修改了同一个文件导致的,这个文件有可能是别人提交到远程仓库里面,还有就是需要合并这个文件导致的。

    叉叉敌
  • 中文语境下的手机号识别

    最近在做一个关于中文大段文本中的手机号码识别,由于属于对抗性的一个文本,发现传统的手机号码识别方法,比如正则匹配并不是很适用。

    sladesal
  • 同一个github账户绑定两个域名

    一个github账号可以建立很多仓库,但是只能有一个个人主页仓库,其余都是项目仓库。主页仓库就是你的名字.github.io这个,其余的就是https://gi...

    Y大宽
  • Vue PC端框架和Vue移动端UI框架

    在学习Vue的过程之中,我发现不管是 BAT 大厂,还是创业公司,Vue 都有着广泛的应用,而且框架层出不穷,学习文档也越来越多,Vue也越来越受欢迎。下面是我...

    祈澈菇凉
  • Android app自动更新总结(已适配9.0)

    接下来是工具类,来自github,参考,https://github.com/vondear/RxTool

    Android技术干货分享
  • 前大疆程序员离职后,把代码上传 GitHub,令公司损失百万,获刑半年!

    该员工之前在大疆的子公司担任软件工程师,公司对他很器重,负责编写农业无人机的管理平台和农机喷洒系统代码。他在Github 开设账号,并建立了“公有仓库”,把代码...

    一墨编程学习
  • Vue项目dist文件夹不能上传至github问题

    本地demo上传至github五步曲 https://www.jianshu.com/p/40f48a007c50

    祈澈菇凉
  • 使用Jenkins来实现内部的持续集成流程(上)

    Jenkins和TeamCity都是大杀器,用于搭建内部持续集成环境都是妥妥的。本篇主要介绍Jenkins的安装,下篇将介绍相关配置和使用。

    雪雁-心莱科技

扫码关注云+社区

领取腾讯云代金券