アプリのさまざまなページ間の動的ルーティングで 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 読み込み例外をキャッチし、ユーザーにアプリをリロードするメッセージを表示します。この解決策はうまくいくかもしれませんが、あなたが私に尋ねると、それは迷惑なUXです.
この種の問題を経験した人はいますか?助言がありますか?
編集 - 解決策:
2 番目のアプローチ (解決策 2) を使用することにしました。読み込みエラーをキャッチするには、require.ensure 実装が require ファイル例外のキャッチをサポートしていないため、webpack を webpack 2 にアップグレードする必要がありました。System.import
エラー処理をサポートするwebpack 2を使用できます。だから基本的に私がしたことは次のとおりです。
を使用してコンポーネントを動的にロードします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)}/>