我更喜欢让用户刷新而不是自动刷新(这可以防止无限刷新循环错误的可能性)。
以下策略适用于 React 应用程序,路由上的代码拆分:
战略
将您的 index.html 设置为从不缓存。这可确保请求您的初始资产的主文件始终是最新的(通常它并不大,因此不缓存它应该不是问题)。请参阅MDN 缓存控制。
对块使用一致的块散列。这确保只有更改的块才会具有不同的哈希值。(参见下面的 webpack.config.js 片段)
不要在部署时使 CDN 的缓存失效,这样旧版本在部署新版本时就不会丢失它的块。
在路由之间导航时检查应用程序版本,以便通知用户他们是否在旧版本上运行并请求他们刷新。
最后,以防万一 ChunkLoadError确实发生:添加一个错误边界。(参见下面的错误边界)
来自 webpack.config.js (Webpack v4) 的片段
来自Uday Hiwarale:
optimization: {
moduleIds: 'hashed',
splitChunks: {
cacheGroups: {
default: false,
vendors: false,
// vendor chunk
vendor: {
name: 'vendor',
// async + async chunks
chunks: 'all',
// import file path containing node_modules
test: /node_modules/,
priority: 20
},
}
}
错误边界
错误边界的 React 文档
import React, { Component } from 'react'
export default class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
return { hasError: true, error };
}
componentDidCatch(error, errorInfo) {
// You can also log the error to an error reporting service
console.error('Error Boundary Caught:', error, errorInfo);
}
render() {
const {error, hasError} = this.state
if (hasError) {
// You can render any custom fallback UI
return <div>
<div>
{error.name === 'ChunkLoadError' ?
<div>
This application has been updated, please refresh your browser to see the latest content.
</div>
:
<div>
An error has occurred, please refresh and try again.
</div>}
</div>
</div>
}
return this.props.children;
}
}
注意:确保清除内部导航事件上的错误(例如,如果您正在使用 react-router),否则错误边界将在内部导航之后持续存在,并且只会在真正的导航或页面刷新时消失。