React Router 代码拆分“随机”在加载块时失败

Posted

技术标签:

【中文标题】React Router 代码拆分“随机”在加载块时失败【英文标题】:React Router code split "randomly" fails at loading chunks 【发布时间】:2017-08-19 10:51:24 【问题描述】:

我正在努力解决 react-router + webpack 代码拆分 + servicer worker(或缓存)的问题。

基本上问题如下,代码拆分工作正常,但我不时收到来自 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 等的报告。

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

【问题讨论】:

【参考方案1】:

编辑 2:我结束了使用带有哈希的块,并在 errorLoadingcatch() 中执行 window.location.reload(),因此当浏览器无法加载块时,它将重新加载窗口并获取新文件。

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

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

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

    删除服务工作者代码 在 devtools 中取消注册服务工作者 重新加载页面 部署新的应用版本 导航到另一个块(例如从 /home 到 /about)

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

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

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

【讨论】:

以上是关于React Router 代码拆分“随机”在加载块时失败的主要内容,如果未能解决你的问题,请参考以下文章

使用 webpack、bundle-loader react-router 进行隐式代码拆分

使用 webpack 代码拆分,如何加载块和 HTML 布局?

使用 react router 4 动态加载 redux reducer

使用 React.lazy、Suspense 和 react-router-dom 进行代码拆分不起作用

使用 Webpack 2 和 React Router 进行 CSS 代码拆分

如何使用 Webpack 代码拆分处理部署?