9

我正在努力解决 react-router + webpack 代码拆分 + 服务工作者(或缓存)的问题。

基本上问题如下,代码拆分工作正常,但有时我会从 sentry.io 的客户那里收到错误报告,例如:

"Dynamic page loading failed Error: Loading chunk 19 failed."

我的反应路由器代码如下:

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 等的报告。

关于我可能做错了什么或如何解决这个问题的任何线索?

4

1 回答 1

6

编辑2:我结束了使用带有哈希的块,并做了一个inside window.location.reload(),所以当浏览器无法加载一个块时,它会重新加载窗口并获取新文件。errorLoadingcatch()

<Route path="about" 
  getComponent={(location, callback) => {
    System.import('./about')
    .then(module => { callback(null, module.default) })
    .catch(() => {
      window.location.reload()
    })
  }} 
/>

它也发生在我身上,我认为我还没有合适的解决方案,但我注意到这通常发生在我部署新版本的应用程序时,块的哈希值发生变化,以及当我尝试导航到另一个地址(块)块不存在(似乎它没有被缓存),我得到了错误。

我设法通过删除缓存内容的服务工作人员并部署新版本来重现这一点(我猜这模拟了没有服务工作人员运行的用户?)。

  1. 删除 service worker 代码
  2. 在 devtools 中注销 service worker
  3. 重新加载页面
  4. 部署新的应用版本
  5. 导航到另一个块(例如从 /home 到 /about)

在我的情况下,当旧文件未缓存(因此不再可用)并且用户没有重新加载页面以请求新文件时,似乎会发生错误。重新加载“修复”了该问题,因为应用程序具有正确加载的新块名称。

我尝试的其他方法是在没有哈希的情况下命名块文件,因此它们只有 3.js 而不是 3.something.js。当我部署一个新版本时,这些块显然仍然存在,但这不是一个好的解决方案,因为文件将被浏览器缓存,而不是被缓存插件缓存。

编辑:与您相同的设置,使用 sw-precache-webpack-plugin。

于 2017-04-11T15:40:27.183 回答