web-dev-qa-db-ja.com

Angular 5+ Service Workersでルーティングを処理する方法?

Angularサービスワーカー実装の以前のバージョンでは、構成オプションの1つは"routing"でした。これはこれで見ることができます 未回答SO質問 、これで参照されました Angular CLI issue 、そして残りの最良のドキュメントは Stephen Fluinのブログ投稿 (Angularチーム)、および I/Oトーク Alex Rickabaugh(Googleから)。

Angular 5を使用すると、ServiceWorkerModuleが適切に構築され、ほとんどの構成をngsw-config.jsonファイルを使用して処理できるようになりました。ただし、ルートのリダイレクトを処理する方法については、 angular.ioガイド または ドキュメント のどこにも言及されていません。そのため、次の問題が発生します。アプリにアクセスしてオフラインになったときに、直接アクセスしてもアプリにアクセスできます。 https://jackkoppa.github.io/cityaq-sw-issue 。ただし、ロード時にアプリはsearchルートにリダイレクトされ、ほとんどのユーザーは https://jackkoppa.github.io/cityaq-sw-issue/searchのようなURLからロードしようとします。 ?cities = Shanghai (簡単にするために、今のところChromeデスクトップとモバイルについて、そして可能な場合はシークレットモードで話しています)。

オフラインでそのURLにアクセスしようとすると、すぐに504-ゲートウェイタイムアウトが発生します。これは、Service Workerがインデックスをキャッシュしているだけで、他のルートがロードできるようにインデックスにリダイレクトする必要があることを知らないために発生しています。 Angularサービスワーカーの実装の以前の反復が、特定のルートのインデックスへのリダイレクトを設定することにより、このシナリオを処理できたと確信しています。 現在のAngular 5+ ngsw-config.json、または生成されたngsw.jsonファイルでこのリダイレクトを処理する方法はありますか?それを除いて、回避策は別のサービスワーカーJSファイルでどのように処理する必要がありますか?

29
Jack Koppa

TL; DR:私の場合、破損の原因となる少なくとも2つの問題を特定しました。 this build script を使用して修正を試み、アプリがオフラインで動作することを確認できます here 。さらなるテストとプルリクエストが必要です。


文書化された答えを見つけることができませんでしたが、ngsw-worker.jsファイルをステップ実行し、@angular/service-workerコミット履歴を読むことで、これまでに見つけたものをここに示します。

「ルーティング」への新しいServiceWorkerModuleアプローチは、「ナビゲーション」リクエスト(つまり、同じドメイン上の非インデックスルート)を取得し、handleFetchメソッドを再実行しますが、 index.htmlリクエスト( source ) SPAがインデックスのキャッシュファイルを取得すると、URLにリダイレクトできる必要があるため、これは正常に機能するはずです。

したがって、オフライン時に上記のサイトが失敗する原因となっている問題は、ルーティングに直接関係していてはならず、これまでのところ2つ見つかっています。これらを回避策で修正することで、アプリをほぼ期待どおりに動作させることができました。元の質問の再現手順で、 cityaq が機能するようになりましたが、元の失敗したサイト cityaq-sw-issue を再現しました。

問題:

  1. ホストのバージョンのAngularアプリ、--base-hrefフラグがCLIから設定されている場合、サービスワーカーリソースの絶対URLを一覧表示します。これらのリソースへの要求を比較する場合、ngsw-worker.jsは相対URLを予期しています

    • ソース
    • 私はこの問題を解決する必要があると確信しており、それを修正するためにプルリクエストに取り組んでいます。 ngsw.jsonが生成されたときにbaseHrefがリソースURLに含まれているために発生します( source
  2. 私の経験では、ngsw-worker.jsが使用できる3つの使用可能な「状態」のうち、EXISTING_CLIENTS_ONLYは間違って設定されているようです。

    • ソース1ソース2
    • whatがこの状態の原因を常に確認することができなかったため、この変更については自信がありません。ただし、Service Workerがこの状態になると、ngsw-worker.jsはキャッシュされたリソース( source )の取得を試行しなくなり、「正しい」と思われる状況でのテストでは、唯一の変更がインターネット接続の削除であっても、アプリは引き続きこの状態になります

問題#1のPRを作成し、問題#2の理解を助けるのを待っている間に、回避策ビルドスクリプトを使用して、ngsw-worker.jsが生成された後に変更します。警告:EXISTING_CLIENTS_ONLYを設定する意図した「安全な」動作をく、間違いなく変更します。ただし、私のアプリの場合、ローカルで実行するとき(http-server)とライブURL(私の場合はGitHubページ)にデプロイするときの両方で、正しいオフラインパフォーマンスが可能です。

回避策を使用するには:(Angular 5、w/Angular 5.2.1)

  1. npm install replace-in-file --save-dev
  2. アプリに このスクリプト を含めます。 build/fix-sw.js
  3. あなたのpackage.json
"scripts": {
   ...
   "sw-build": "ng build --prod && node build/fix-sw",
   "sw-build-live": ng build --prod --base-href https://your-url.com/ && node build/fix-sw"
   ...
}
  1. ローカルで実行するには
npm run sw-build 
 cd dist 
 http-server -p 8080を実行します
  1. そして、サーバーに送信する前に、ライブURLのビルドを準備します(例: angular-cli-ghpages
npm run sw-build-live
8
Jack Koppa