Vue项目中会偶尔出现Loading chunk {n} failed的报错,报错来自于webpack进行code spilt之后某些bundle文件lazy loading失败
原因分析
- 网络问题:网络抖动导致加载异步chunk时请求失败
- 缓存问题:静态资源更新发版版本号发生变化,但是html页面命中了缓存,请求的异步chunk还是旧版的导致资源加载异常
解决方法
- 让html页面每次加载不走缓存,增加禁用缓存的
meta标签
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
- 捕获到此异常错误时,可根据自己的业务场景选择:
- 尝试强制重新加载页面
- 弹窗或者toast提示用户刷新页面
- …其它交互方案
// 强制刷新页面
function forceReloadPage() {
// 设置只强制刷新一次页面,防止死循环刷新
if (!sessionStorage.getItem("forceReloadPage")) {
sessionStorage.setItem("forceReloadPage", "RELOADED");
window.location.reload(true);
}
}
// vue-router中监听错误
router.onError(error => {
const pattern = /Loading chunk (\d)+ failed/g;
const isChunkLoadFailed = error.message.match(pattern);
if (isChunkLoadFailed) {
// 命中错误,可根据自己的业务场景实现交互方案
forceReloadPage();
}
});
扩展
非vue项目,可以通过框架提供的api捕获到错误进行处理。或者下面更通用的方案:
// 强制刷新页面
function forceReloadPage() {
// 设置只强制刷新一次页面,防止死循环刷新
if (!sessionStorage.getItem("forceReloadPage")) {
sessionStorage.setItem("forceReloadPage", "RELOADED");
window.location.reload(true);
}
}
window.addEventListener(
"error",
function (error) {
const pattern = /Loading chunk (\d)+ failed/g;
const isChunkLoadFailed = error.message.match(pattern);
if (isChunkLoadFailed) {
// 命中错误,可根据自己的业务场景实现交互方案
forceReloadPage();
}
},
true
);