我正在努力解决react-router + webpack代码split + servicer worker(或cache)的问题。
基本上问题如下,代码拆分工作正常但有时我从sentry.io的客户那里收到错误报告,例如:
"Dynamic page loading failed Error: Loading chunk 19 failed."
我的react-router代码如下:
const errorLoading = (err) => {
console.error('Dynamic page loading failed', err);
};
export default (
<Route path="/" component={App}>
<IndexRoute
getComponent={(nextState, cb) => {
System.import('./containers/home/home')
.then((module) => { cb(null, module.default); })
.catch(errorLoading);
}}
/>
</Route>
);
对于我的ServiceWorker,我使用OfflinePlugin进行以下配置:
new OfflinePlugin({
cacheName: 'cache-name',
cacheMaps: [
{
match: function(requestUrl) {
return new URL('/', location);
},
requestTypes: ['navigate']
}
],
externals: [
'assets/images/logos/slider.png',
'assets/images/banners/banner-1-320.jpg',
'assets/images/banners/banner-1-480.jpg',
'assets/images/banners/banner-1-768.jpg',
'assets/images/banners/banner-1-1024.jpg',
'assets/images/banners/banner-1-1280.jpg',
'assets/images/banners/banner-1-1400.jpg'
],
responseStrategy: 'network-first', // One of my failed attempts to fix this issue
ServiceWorker: {
output: 'my-service-worker.js'
}
})
问题与浏览器无关,因为我有来自IE11,safari,chrome等的报告。
关于我可能做错的任何线索或如何解决这个问题?
编辑2 :我结束使用带有哈希的块,并在errorLoading
的catch()
执行window.location.reload()
,因此当浏览器无法加载块时,它将重新加载窗口并获取新文件。
<Route path="about"
getComponent={(location, callback) => {
System.import('./about')
.then(module => { callback(null, module.default) })
.catch(() => {
window.location.reload()
})
}}
/>
它也发生在我身上,我不认为我有一个合适的解决方案,但我注意到这通常发生在我部署新版本的应用程序,块的哈希值发生变化,以及当我尝试导航到另一个地址(块) 旧块不存在(好像它没有被缓存),我得到错误。
我设法通过删除缓存内容和部署新版本的服务工作者(我想模拟没有服务工作者运行的用户?)来重现这一点。
在我的情况下,似乎错误发生在旧文件未缓存时(因此不再可用),并且用户不会重新加载页面以请求新文件。 重新加载“修复”问题,因为应用程序具有正确加载的新块名称。
我尝试的其他东西是命名块文件没有他们的哈希值 ,所以而不是3.something.js他们只有3.js. 当我部署新版本时,显然仍然存在块,但这不是一个好的解决方案,因为文件将由浏览器缓存而不是由缓存插件缓存。
编辑:与您相同的设置,使用sw-precache-webpack-plugin。