技术咨询、项目合作、广告投放、简历咨询、技术文档下载
点击这里 联系博主
# 记一次 React.lazy 加载页面导致 chunk load error 问题
你是否 使用了 React.lazy 做异步加载,并在部署了代码之后 发现存在 ChunkLoadError的问题; 如果是 可以继续查看一下当前文章
首先了解一下 React.lazy
(opens new window) 如何使用
import React, { Suspense } from 'react';
const App = React.lazy(() => import('./App'));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<App />
</Suspense>
</div>
);
}
那么 什么情况回导致如上的代码 加载失败,导致 chunk load error 呢?
# 导致 chunk load error 的原因
前置知识
- 异步组件,资源并不会一次性加载,而是执行到某块才会加载
- 在webpack 中我们打包资源通常会使用 contenthash/hash/chunk-hash, 重新打包发布后 hash 值不一样
根本原因是:打包之后hash 值变化,之前页面无法找到老的chunk 导致页面加载失败
举个例子:
现在假设您的代码发布线上,用户加载了您的主应用程序
app.js
他们点击一个按钮来查看他们的个人信息。这是一个单独的代码块
chunk-1a.min.js
。
if
如果从用户加载应用程序后没有发生任何变化,代码块将加载;用户也可以正常使用。
else
如果在加载应用程序和 查看个人信息之间,部署了新 代码。
如果新的个人信息模块 chunk 为
chunk-1b.min.js
。很有可能,您的生产环境将创建一个全新的构建,旧的块已经消失,新的已经准备就绪。此时用户已经加载了旧版本的代码(html),它会寻找旧的
chunk chunk-1a.min.js
此时用户就会发送load chunk error
# 如何修复 chunk load error
我们发现 出现
chunk load error
的主要原因是无法找到 新的资源;所以一种可行的解决方案是 在导入失败时,引导用户刷新页面;
const lazyRetry = function(componentImport, name) {
return new Promise((resolve, reject) => {
// 检查是否已经刷新过了
const hasRefreshed = JSON.parse(
window.sessionStorage.getItem(`${name}-retry-lazy-refreshed`) || 'false'
);
// 动态导入组件
componentImport().then((component) => {
window.sessionStorage.setItem(`${name}-retry-lazy-refreshed`, 'false');
resolve(component);
}).catch((error) => {
if (!hasRefreshed) { // 没有刷新过,需要刷新页面刷新
window.sessionStorage.setItem(`${name}-retry-lazy-refreshed`, 'true');
return window.location.reload(); //
}
reject(error);
});
});
}
// 将原本的 const App = React.lazy(() => import('./App')); 替换成如下即可
const App = React.lazy(() => lazyRetry(() => import(/* webpackChunkName: "main-app" */ './App'), "main-app"));
- 本文链接: https://mrgaogang.github.io/react/react_load_chunk_error.html
- 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 许可协议。转载请注明出处!