3

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

1 回答 1

2

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

于 2016-12-18T17:41:48.670 回答