使用基于React Route的代码拆分进行全新构建后的白页

时间:2019-04-27 18:28:16

标签: reactjs code-splitting

该应用程序正在使用React和基于React Route的代码拆分:https://reactjs.org/docs/code-splitting.html#route-based-code-splitting

该应用正常运行。用户在主页上。 然后,我对代码进行更改,然后再次构建应用程序。

用户单击一个链接,他就进入了白页。 当然,捆绑包已更改,并且加载新页面(感谢React.lazy)将导致错误。

enter image description here Uncaught SyntaxError: Unexpected token <

如何防止这种情况并显示例如:“网站已更新,请重新加载”而不是白页?

2 个答案:

答案 0 :(得分:1)

这是根据Alan的评论建立的,它不能完全解决原始问题的问题。我遇到了一个类似的问题,即在服务器上完成的构建更改了我使用React.lazy()加载的包的所有文件名,而没有刷新其页面的用户将寻找不再存在的包,结果他描述的错误。

再次,这主要是基于Alan的代码,但是很好地解决了问题...

export default function lazyReloadOnFail(fn) {
  return new Promise(resolve => {
    fn()
      .then(resolve)
      .catch(() => {
        window.location.reload();
      });
  });
}


const Report = React.lazy(() => lazyReloadOnFail(() => import('./views/Reports/Report')));

答案 1 :(得分:0)

解决方案是:

您知道我们在惰性上使用的import(...)函数仅仅是返回Promise的函数吗?这基本上意味着您可以像其他任何Promise一样链接它。

function retry(fn, retriesLeft = 5, interval = 1000) {
  return new Promise((resolve, reject) => {
    fn()
      .then(resolve)
      .catch((error) => {
        setTimeout(() => {
          if (retriesLeft === 1) {
            // reject('maximum retries exceeded');
            reject(error);
            return;
          }

          // Passing on "reject" is the important part
          retry(fn, retriesLeft - 1, interval).then(resolve, reject);
        }, interval);
      });
  });
}

现在,我们只需要将其应用于延迟导入。

// Code split without retry login
const ProductList = lazy(() => import("./path/to/productlist"));

// Code split with retry login
const ProductList = lazy(() => retry(() => import("./path/to/productlist")));

如果浏览器无法下载模块,它将重试5次,每次尝试之间的间隔为1秒。如果甚至在尝试5次后导入,也会引发错误。

感谢Guilherme Oenning来自:https://dev.to/goenning/how-to-retry-when-react-lazy-fails-mb5