我正在使用 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)}/>