使用基于 React Route 的代码拆分进行全新构建后的白页
White page after fresh build using React Route-based code splitting
该应用正在使用 React 和基于 React Route 的代码拆分:https://reactjs.org/docs/code-splitting.html#route-based-code-splitting
该应用运行良好。一个用户在主页上。
然后我更改代码并重新构建应用程序。
用户正在单击 link,他正登陆一个白色页面。
当然,bundle 已经改变,加载新页面(感谢React.lazy
)会报错。
Uncaught SyntaxError: Unexpected token <
如何防止这种情况并显示例如:"Site has been updated, please reload" 而不是白页?
解决方法是:
你知道我们在 lazy 上使用的 import(...) 函数只是一个 returns 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
这是根据 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')));
该应用正在使用 React 和基于 React Route 的代码拆分:https://reactjs.org/docs/code-splitting.html#route-based-code-splitting
该应用运行良好。一个用户在主页上。 然后我更改代码并重新构建应用程序。
用户正在单击 link,他正登陆一个白色页面。
当然,bundle 已经改变,加载新页面(感谢React.lazy
)会报错。
Uncaught SyntaxError: Unexpected token <
如何防止这种情况并显示例如:"Site has been updated, please reload" 而不是白页?
解决方法是:
你知道我们在 lazy 上使用的 import(...) 函数只是一个 returns 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
这是根据 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')));