Angular CLI 1.5によるAngular Service Workerクイックスタート
この記事では、Angular v5でリリースされた新しい @angular/service-worker
(Angular Service Worker)を、Angular CLI v1.5のプロジェクトに導入するクイックスタートを紹介します。Angular Service Workerについての包括的な解説についてはMaxim Salnikov氏が投稿した以下の記事を参考にしてください。
- A new Angular Service Worker — creating automatic progressive web apps . Part 1: theory
- A new Angular Service Worker — creating automatic progressive web apps. Part 2: practice
この記事は以下の動作環境を対象としています。
_ _ ____ _ ___
/ \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _|
/ △ \ | '_ \ / _` | | | | |/ _` | '__| | | | | | |
/ ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | |
/_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___|
|___/
Angular CLI: 1.5.0
Node: 8.5.0
OS: darwin x64
この記事のサンプルコードは こちら です
プロジェクトの作成
まずはAngular CLIを使ってプロジェクトを作成します。v1.6からは --service-worker
オプションを使えるようになりますが、v1.5では今までどおりのコマンドです。今回はユニットテストを必要としないので、 --minimal
オプションで最低限のファイルだけを生成します。
ng new ngsw-example --minimal
プロジェクトの作成が完了したら、カレントディレクトリを ngsw-example
ディレクトリに移動して、アプリケーションを実行します。動作確認ができたら次に進みましょう。
ng serve
Angular Service Workerのセットアップ
まずは、次のコマンドで @angular/service-worker
パッケージとデバッグ用に node-static
パッケージをインストールします。
npm i --save @angular/service-worker
npm i --save-dev node-static # デバッグ用サーバー
Angular Service Workerは次の2つのファイルを使用します
- ngsw-worker.js: Angular Service Workerの本体
- ngsw.json: ngsw-worker.jsが使う設定ファイル
まずはngsw.jsonファイルを用意します。このファイルはアプリケーションの実行時にngsw-worker.jsと同じディレクトリに配置されている必要があります。
ngsw.jsonファイルはAngular Service Workerが提供する ngsw-config
コマンドを使って生成します。設定の元になる src/ngsw.json
ファイルを作成し、次のように最低限の設定だけを記述します。
そして、package.jsonファイルに、distディレクトリにngsw.jsonファイルを生成するためのスクリプトを追加します。
{
"scripts": {
"ngsw-config": "ngsw-config dist src/ngsw.json"
}
}
ngsw-worker.jsファイルは、node_modulesの中からコピーします。今回はAngular CLIのassets機能を使ってコピーします。
.angular-cli.jsonのアプリケーション設定にあるassetsプロパティを次のように変更します。この設定により、ビルドのたびに node_modules/@angular/service-worker/ngsw-worker.js ファイルが、出力先のルートディレクトリにコピーされます。
"assets": [
"assets",
"favicon.ico",
{
"input": "../node_modules/@angular/service-worker",
"glob": "ngsw-worker.js",
"output": "."
}
],
最後に、ビルドに含まれるようになったngsw-worker.jsファイルをService Workerとして登録するために ServiceWorkerModule
をアプリケーションに導入します。app.module.tsファイルを開き、次のように編集します。
これで準備はできました。実際に動かしてみましょう。ファイルのコピーを行なう必要があるので、package.jsonのstartスクリプトを次のように変更します。
{
"start": "ng build --prod && npm run ngsw-config && static dist"
}
それではアプリケーションを実行してみましょう!
npm start
立ち上がった開発サーバーをブラウザで開き、開発者コンソールでService Workerの登録状況を確認してみましょう。
ご覧のとおり、Service Workerが登録されています。また、ngsw.jsonで記述したキャッシュ設定により、オフライン対応までが完了しています。Chromeの場合はオフラインモードでリロードしてみましょう。(Chrome 62にはオフラインエミュレーションのバグがあるので、Canaryでの確認をおすすめします)
Angular Service Workerのセットアップがあっという間に完了しました。ここからはアプリケーションコードや設定ファイルを編集して、ワーカーの更新制御と、オフラインキャッシュの設定を追加します。
Service Workerの更新制御
Service Workerはアプリケーションとは別のライフサイクルで管理されているため、インストール済みのService Workerと配信中のService Workerのバージョンが食い違うことになります。Angular Service Workerでは SwUpdate
というAPIを提供して、アプリケーションからService Workerの新バージョンの検知と、更新の実行ができます。
今回はアプリケーションが起動するたびに最新のService Workerのバージョンをチェックして、更新があればリロードを促す仕組みを実装します。app.component.tsを開き、次のように編集します。 swUpdate.available
プロパティは新しいService Workerが有効になったときに発火するイベントを提供するObservableです。 swUpdate.checkForUpdate
メソッドは、新しいService Workerが存在するかどうかをチェックします。もしここで新しいバージョンがあれば、 swUpdate.available
にイベントが流れます。
まずは一度Service Workerとキャッシュをすべて破棄します。その後、改めて npm start
コマンドでアプリケーションを起動し、新しいService Workerを登録します。
この状態ではビルド後のJSファイルなどはすべてキャッシュされているので、どれだけリロードしてもすべてのタブを閉じてService Workerが更新されるまではキャッシュが生き続けます。
それではアプリケーションを更新してみましょう。app.component.tsの title
プロパティを適当な文字列に変えて、再度 npm start
コマンドを実行します。
OKボタンを押すと、キャッシュが更新されてページがリロードされます。
このように、Service Workerのライフサイクル管理をアプリケーションのロジックに簡単に組み込めます。
キャッシュ設定の追加
現在のngsw.jsonでは、アプリケーションの実行に最低限必要なindex.htmlやJS, CSSファイルをキャッシュするように設定しています。これに加えて、Google Fontsのフォントファイルもキャッシュするようにしてみましょう。
今回はOpen Sansフォントをindex.htmlで読み込みます。次のlinkタグをindex.htmlのheadタグ中に配置しましょう。
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
次に、src/ngsw.jsonを次のように変更します。Google Fontsへのリクエストにマッチするようにurlsを定義します。
最後に、フォントが適用されていることがわかるように、styles.cssに次のスタイルを追加しましょう。
body {
font-family: 'Open Sans', sans-serif;
}
それではふたたび npm start
コマンドでアプリケーションを起動しましょう。さきほどと同じくアップデートの確認ダイアログをOKしたら、Open Sansが適用されているはずです。そして、オフラインモードにしてもフォントは同様に適用されるでしょう。
開発者コンソールのCache Storageを確認すれば、Open Sansフォントファイルがキャッシュされていることを確認できます。
このように、動的にリクエストするファイルについても、簡単にngsw.jsonの設定でオフライン対応できます。
まとめ
- 新しいAngular Service Workerがリリースされた
- Angular CLI 1.5ではマニュアルセットアップが必要
- Angular Service Workerはngsw-worker.jsとngsw.jsonで動作する
SwUpdate
APIでService Workerのアップデートを制御できる- ngsw.jsonでキャッシュ設定を制御できる
もっと詳しい解説は冒頭で紹介したMaxim Salnikov氏の記事をご覧ください。公式ドキュメンテーションが用意されるまでは、彼の記事がもっとも信頼性のあるリソースです。