我在应用程序的不同页面之间使用动态路由的 react/react-router/webpack 堆栈,这意味着每个页面都按需异步加载。一切都很好,但是当我部署一个新版本时,我当前的活跃用户没有获取所有页面的所有 Js 文件,一旦他们尝试导航到他们尚未访问过的另一个页面,就会卡住。
示例
假设我有一个代码拆分应用程序,其中包含以下 .js 生成的文件和 md5(用于缓存清除):
main.123.js
profile.456.js
用户访问我的主页,只得到main.123.js
。
与此同时,我部署了一个具有不同 md5 的新版本(我在 profile.js 和 main.js 中都进行了更改)
main.789.js
profile.891.js
用户尝试导航到个人资料页面,应用程序尝试获取 profile.456.js
但出现错误,因为 profile.js 文件已被交换,现在有办法让应用知道新文件名。
我想出了 2 个解决方案,但没有一个能真正解决问题
解决方案 1? 始终保持 2 个版本在生产中可用。但这是一个滑坡,因为 2 个版本有时是不够的。也就是说,用户可以让他的选项卡打开几天,这样就可以进行多次部署,直到他决定再次使用该应用程序。
解决方案 2? 捕获 js 加载异常并向用户显示一条消息以重新加载应用程序。这个解决方案可以工作,但如果你问我,它是一个令人讨厌的用户体验。
有人遇到过这种问题吗?有什么建议吗?
编辑 - 解决方案:
我决定采用第二种方法(解决方案 2)。为了捕获加载错误,我不得不将我的 webpack 升级到 webpack 2,因为 require.ensure 实现不支持捕获 require 文件异常。在 webpack 2 中,我可以使用支持错误处理的 System.import
。所以基本上我所做的是:
使用 System.import
动态加载我的组件:
function getMyComponent(nextState, cb, path) {
return System.import('components/myComponent').then(module => {
cb(null, module);
});
并捕获错误:
function getAsyncComponent(getComponent) {
return function (nextState, cb, path) {
getComponent(nextState, cb, path, store).catch(err => {
store.dispatch(notificationSend({message: <span>Uh oh.. Something went wrong.}));
cb(err);
});
}
}
<Route path="foo" getComponent={getAsyncComponent(getMyComponent)}/>
最佳答案
我会选择#2 的变体,在检测到路由文件不再存在于服务器上时,您使用 window.location.reload(true)
为用户刷新.那应该进行一次硬刷新,这将加载新文件。
关于javascript - Webpack + React router动态路由——如何用require.ensure捕获require加载异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41208647/