Webpack + React路由器动态路由 - 如何捕获需要使用require.ensure加载异常

时间:2016-12-18 13:09:47

标签: javascript webpack react-router webpack-2 code-splitting

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

1 个答案:

答案 0 :(得分:2)

我会选择#2的变体,在检测到服务器上不再存在路径文件时,使用window.location.reload(true)为用户刷新。这应该进行硬刷新,这将加载新文件。