I prefer to let the user refresh rather than refreshing automatically (this prevents the potential for an infinite refresh loop bug).
The following strategy works well for a React app, code split on routes:
策略
设置索引.html永远不会缓存.这可以确保请求初始assets资源 的主文件始终是新的(通常它不太大,所以不缓存它不应该是一个问题).见MDN Cache Control.
对块使用一致的块哈希.这确保了只有更改的块才会有不同的散列.(请参阅下面的webpack.config.js片段)
不要在部署时使CDN的缓存失效,这样旧版本在部署新版本时不会丢失其块.
在路由之间导航时,请判断应用程序版本,以便通知用户它们是否在旧版本上运行,并请求刷新.
最后,万一发生ChunkLoadError does:添加一个错误边界.(参见下面的错误边界)
来自网页包的片段.配置.js(网页包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 Docs for 误差边界
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('误差边界 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),否则错误边界将持续超过内部导航,并且仅在真正的导航或页面刷新时消失.