Angular6を使用したPWAの構築
公開: 2022-03-10 このチュートリアルでは、最新のAngular 6を使用して、PWAを構成するコア原則を実装することでPWAを構築します。 まず、JSONAPIを使用するフロントエンドWebアプリケーションを作成します。 この問題については、Angular HttpClient
モジュールを使用して、Simplified JavaScript JargonGitHubリポジトリから生成された静的にJSONAPIにHTTPリクエストを送信します。 また、AngularMaterialパッケージを介してUIを構築するためにマテリアルデザインを使用します。
次に、Chrome DevToolsの「監査」パネル(Lighthouse)を使用して、PWAのコア原則に照らしてWebアプリケーションを分析します。 最後に、Lighthouseレポートの「プログレッシブWebアプリ」セクションに従って、PWA機能を説明してWebアプリケーションに追加します。
PWAの実装を開始する前に、まずPWAとLighthouseを紹介しましょう。
推奨読書:ネイティブおよびPWA:チャレンジャーではなく、選択肢!
PWAとは何ですか?
プログレッシブウェブアプリまたはPWAは、ユーザーにアプリのようなエクスペリエンスを提供する一連の機能(ネイティブアプリと同様)を備えたウェブアプリケーションです。 PWAは、次に説明する一連の重要な要件を満たす必要があります。 PWAはネイティブアプリに似ていますが、URLを介してウェブサーバーからデプロイおよびアクセスできるため、アプリストアを経由する必要はありません。
PWAは次のようにする必要があります。
- プログレッシブ
彼らはコアの信条としてプログレッシブエンハンスメントで構築されているため、ブラウザの選択に関係なく、すべてのユーザーのために働きます。 - レスポンシブ
任意のフォームファクタ、デスクトップ、モバイル、タブレット、または次にあるものに適合します。 - 接続に依存しない
サービスワーカーによって強化され、オフラインまたは低品質のネットワークで作業できるようになりました。 - アプリのような
アプリシェルモデルを使用して、アプリスタイルのナビゲーションとインタラクションを提供します。 - 新鮮
Service Workerの更新プロセスにより、常に最新の状態に保たれます。 - 安全
スヌーピングを防ぎ、コンテンツが改ざんされていないことを確認するために、HTTPS経由で提供されます。 - 発見可能
W3Cマニフェストとサービスワーカー登録スコープのおかげで「アプリケーション」として識別でき、検索エンジンがそれらを見つけることができます。 - 再エンゲージ可能
プッシュ通知などの機能を使用して、再エンゲージメントを簡単にします。 - インストール可能
ユーザーがアプリストアの手間をかけずに、ホーム画面で最も役立つと思うアプリを「保持」できるようにします。 - リンク可能
URLを介して簡単に共有でき、複雑なインストールは必要ありません。
灯台の紹介
Lighthouseは、Googleが作成したオープンソースの監査ツールであり、ユーザー補助のパフォーマンス、SEO、ベストプラクティス、PWA機能についてウェブサイトやアプリケーションを監査するために使用できます。
Chrome DevToolsの[監査]タブから、Node.jsのモジュールまたはCLIツールとしてLighthouseにアクセスできます。 Lighthouseを使用するには、URLを指定してから監査を実行します。これにより、監査結果を含むレポートが提供されます。これは、基本的にWebアプリケーションを改善する方法に関する提案です。
Angular CLIv6のインストールとプロジェクトの生成
このセクションでは、最新バージョンのAngular CLIをインストールし、それを使用して新しいAngular6プロジェクトを作成します。
AngularCLIにはNode.js> = 8.9+が必要なので、最初に次のコマンドを実行して、必要なバージョンがインストールされていることを確認してください。
$ node -v

Node.jsがインストールされていない場合は、公式のNodeダウンロードページにアクセスして、システムのNodeバイナリを取得できます。
これで、次のコマンドを実行して、AngularCLIの最新バージョンをインストールできます。
$ npm install -g @angular/cli
注: npmの構成によっては、パッケージをグローバルにインストールするには_sudo_
を追加する必要がある場合があります。
ターミナルで次のコマンドを実行すると、Angular6プロジェクトを生成できます。
$ ng new pwademo
これにより、次のような構造のプロジェクトが作成されます。

行われるほとんどの作業は、アプリケーションのソースコードを含むsrc/
フォルダー内にあります。
Angularアプリケーションの作成
プロジェクトを生成した後、JSON APIを使用し、ホームページにアイテムを表示するWebアプリケーションを構築します。 HTTPリクエストの送信にはHttpClientサービスを使用し、UIの構築にはAngularMaterialを使用します。
Angularマテリアルの追加
Angular CLIv6と新しいngaddコマンドのおかげで、プロジェクトにAngularMaterialを追加するのはたった1つのコマンドです。 ターミナルから次のコマンドを実行する必要があります。
$ cd pwademo $ ng add @angular/material

スクリーンショットから、コマンドがnpmから必要なパッケージをインストールし、以前は手動で更新する必要があったプロジェクトでAngularMaterialをセットアップするための一連のファイルを更新することがわかります。
HttpClient
のセットアップとJSONAPIの使用
次に、HTTPリクエストの送信にHttpClient
を使用するようにAngularプロジェクトを設定しましょう。 まず、 src/app/app.module.ts
ファイルのメインアプリケーションモジュールにHttpClientModule
モジュールをインポートする必要があります。
/*...*/ import { HttpClientModule } from '@angular/common/http'; @NgModule({ declarations: [ AppComponent ], imports: [ /*...*/ HttpClientModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
それでおしまい。 これで、メインモジュールに属する任意のコンポーネントまたはサービスにHttpClient
を挿入して使用できます。
デモの目的で、 Simplified JavaScript JargonGitHubリポジトリから静的に生成されたJSONAPIを使用します。 他のリソースを消費している場合は、CORSが有効になっていることを確認してください。これにより、同一生成元ポリシーが原因でブラウザがリモートリソースの読み取りを許可しなくなります。
APIとインターフェースするサービスを作成しましょう。 プロジェクトフォルダ内で、次を実行します。
$ ng g service api
これにより、 src/app/api.service.ts
ファイルにApiService
というサービスが作成されます。
次に、 src/app/api.service.ts
ファイルを開き、次の変更を反映するように更新します。
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; export interface Item{ name: string; description: string; url: string; html: string; markdown: string; } @Injectable({ providedIn: 'root' }) export class ApiService { private dataURL: string = "https://www.techiediaries.com/api/data.json"; constructor(private httpClient: HttpClient) {} fetch(): Observable<Item[]>{ return <Observable<Item[]>this.httpClient.get(this.dataURL); } }
最初にHttpClient
クラスとObservable
クラスをインポートし、次にHttpClient
をhttpClient
としてコンストラクターに挿入し、 HttpClient
のget()
メソッド(HTTP GETリクエストをJSONエンドポイントに送信するため)を呼び出してObservableを返すfetch()
メソッドを追加しました。後でサブスクライブできます。
また、返されたJSONデータの単一のアイテムを表すItem
インターフェイスを宣言しました。
次に、このサービスをアプリケーションコンポーネントからインポートします。 src/app/app.component.ts
ファイルを開き、以下を追加します。
import { Component, OnInit } from '@angular/core'; import { ApiService } from './api.service'; import { Item } from './api.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit{ title = 'pwademo'; items: Array<Item>; constructor(private apiService: ApiService){ } ngOnInit(){ this.fetchData(); } fetchData(){ this.apiService.fetch().subscribe((data: Array<Item>)=>{ console.log(data); this.items = data; }, (err)=>{ console.log(err); }); } }
以前に作成したApiService
をインポートし、それをapiService
として挿入します。また、JSONデータの単一アイテムを表すItem
クラスをインポートし、フェッチされたアイテムを保持するタイプArray<Item>
のitems
変数を宣言します。
次に、Observableを返すApiService
で定義したfetch()
メソッドを呼び出すfetchData()
メソッドを追加します。 JSONエンドポイントにGETリクエストを送信し、最終的にitems
配列に割り当てる応答データを取得するために、このオブザーバブルをサブスクライブするだけです。
ngOnInit()
ライフサイクルイベントでfetchData()
メソッドを呼び出すため、 AppComponent
コンポーネントが初期化されると呼び出されます。
アプリケーションUIの追加
アプリケーションUIは、ナビゲーションバーとAngularMaterialで作成されるページのスケルトンで構成されます。
Angular Materialコンポーネントを使用する前に、そのモジュールをインポートする必要があります。 各マテリアルコンポーネントは、独自のモジュールに属しています。
src/app/app.module.ts
ファイルを開き、次のインポートを追加します。
/*...*/ import { MatToolbarModule } from '@angular/material/toolbar'; import { MatCardModule } from '@angular/material/card'; import { MatButtonModule } from '@angular/material/button'; @NgModule({ declarations: [ AppComponent ], imports: [ /*...*/ MatToolbarModule, MatCardModule, MatButtonModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
ツールバー、カード、ボタンコンポーネントのモジュールをインポートし、それらをAppModule
のimports配列に追加します。
次に、 src/app/app.component.html
ファイルを開き、そこにあるものを削除して、以下を追加します。
<mat-toolbar color="primary"> <mat-toolbar-row> <span>JS-jargon</span> </mat-toolbar-row> </mat-toolbar> <main> <mat-card *ngFor="let item of items"> <mat-card-header> <mat-card-title>{{item.name}}</mat-card-title> </mat-card-header> <mat-card-content> {{item.description}} </mat-card-content> <mat-card-actions> <a mat-raised-button href="{{item.url}}" color="primary">More</a> </mat-card-actions> </mat-card> </main>
マテリアルコンポーネントを使用してUIを作成します。 <mat-toolbar>
コンポーネントはマテリアルツールバーを作成するために使用され、 <mat-card>
コンポーネントはマテリアルカードなどを作成するために使用されます。
コンポーネントの初期化時にfetchData()
メソッドによって入力されるitems
配列を繰り返し処理し、アイテムをマテリアルカードとして表示します。 各カードには、名前、説明、および詳細情報へのリンクが含まれています(リンクは、 mat-raised-button
ディレクティブを使用してMaterialボタンとしてスタイル設定されます)。
これは、アプリケーションのスクリーンショットです。

本番用アプリケーションの構築
通常、アプリケーションでPWA機能を確認するときは、ほとんどのPWA機能が開発時に追加されないため、最初に本番用にビルドする必要があります。 たとえば、ファイルを定期的に更新する必要があるため、開発時にサービスワーカーとキャッシュを有効にしたくない場合があります。
次のコマンドを使用して、本番用のアプリケーションを作成しましょう。
$ ng build --prod
本番ビルドは、 dist/pwademo
フォルダーから入手できます。 http-server
ようなツールを使用してサービスを提供できます。

まず、次のコマンドを使用してhttp-server
をインストールします。
$ npm i -g http-server
その後、次のコマンドを使用して実行できます。
$ cd dist/pwademo $ http-server -o
-o
オプションを使用すると、システムのデフォルトブラウザが自動的に開き、Webアプリケーションを利用できるhttps://127.0.0.1:8080/
アドレスに移動します。
Lighthouseを使用したアプリケーションの分析
Lighthouseを使用してアプリケーションを分析してみましょう。 まず、Chromeを起動し、アプリケーションアドレスhttps://127.0.0.1:8080/
にアクセスします。
次に、開発ツールを開くか、 Ctrl + Shift + Iを押して[監査]パネルをクリックします。

モバイル環境をエミュレートするには、できれば、エミュレーションをデスクトップではなくモバイルに設定する必要があります。 次に、[監査の実行... ]青いボタンをクリックします。 Webアプリケーションに対して実行する監査のタイプを選択する必要があるダイアログが開きます。 プログレッシブウェブアプリ以外のすべてのタイプのチェックを外し、[監査の実行]ボタンをクリックします。

灯台がレポートを生成するのを待ちます。 これは、この段階での結果のスクリーンショットです。

Lighthouseは、PWAチェックリストで指定されたプログレッシブWebアプリの側面を検証する一連のチェックを実行します。 いくつかの監査に合格したため、初期スコアは36⁄100になります。
私たちのアプリケーションは、主にサービスワーカー、プログレッシブエンハンスメント、 HTTPS 、およびPWAのコアアスペクトであるWebアプリマニフェストに関連する7つの監査に失敗しました。
サービスワーカーの登録
最初の2つの失敗した監査(「サービスワーカーを登録しない」および「オフライン時に200で応答しない」)は、サービスワーカーとキャッシングに関連しています。 では、サービスワーカーとは何ですか?
Service Workerは、最新のブラウザで利用できる機能であり、アプリケーションがアセットとデータをキャッシュするためのネットワークリクエストをインターセプトできるようにするネットワークプロキシとして使用できます。 これは、オフラインサポートやプッシュ通知などのPWA機能を実装するために使用できます。
これらの監査に合格するには、サービスワーカーを登録し、それを使用してファイルをローカルにキャッシュする必要があります。 オフラインの場合、SWはローカルにキャッシュされたバージョンのファイルを返す必要があります。 1つのCLIコマンドでそれを追加する方法については少し後で説明します。
推奨読書:サービスワーカーの作成:ケーススタディ
プログレッシブエンハンスメント
3番目に失敗した監査(「JavaScriptが利用できない場合はフォールバックコンテンツを提供しない」)は、PWAの重要な側面であるプログレッシブエンハンスメントに関連しており、さまざまなブラウザーで実行するPWAの機能を指しますが、次の場合は高度な機能を提供します。それらは利用可能です。 PEの簡単な例の1つは、 <noscript>
HTMLタグの使用です。これは、JavaScriptが有効になっていない場合に、JavaScriptを有効にしてアプリケーションを実行する必要があることをユーザーに通知します。
<noscript> Please enable JavaScript to run this application. </noscript>
HTTPS
4番目に失敗した監査(「HTTPトラフィックをHTTPSにリダイレクトしない」)は、PWAのコアアスペクトでもあるHTTPSに関連しています(サービスワーカーは、ローカルホストを除き、安全なオリジンからのみサービスを提供できます)。 ローカルホストを監査しているため、「HTTPSを使用」監査自体はLighthouseによって渡されたと見なされますが、実際のホストを使用するには、SSL証明書が必要です。 Let's Encrypt、Cloudflare、Firebase、Netlifyなどのさまざまなサービスから無料のSSL証明書を取得できます。
Webアプリマニフェスト
失敗した3つの監査(「ユーザーはWebアプリをインストールするように求められません」、「カスタムスプラッシュ画面用に構成されていません」、「アドレスバーがブランドの色と一致しません」)は、欠落しているWebアプリマニフェストに関連しています。 PWAに必要な名前、説明、アイコン、およびその他の情報を提供するJSON形式のファイル。 これにより、ユーザーは、アプリストアを経由せずに、ネイティブアプリと同じようにホーム画面にWebアプリをインストールできます。
Webアプリマニフェストを提供し、 rel
プロパティがmanifest
に設定された<link>
タグを使用してindex.html
ファイルから参照する必要があります。 次に、1つのCLIコマンドでこれを自動的に実行する方法を説明します。
PWA機能の実装
Angular CLI v6を使用すると、既存のAngularアプリケーションにPWA機能をすばやく追加できます。 プロジェクトのルートからターミナルで次のコマンドを実行するだけで、アプリケーションをPWAに変えることができます。
$ ng add @angular/pwa
このコマンドは、次のようなPWA機能をAngularアプリケーションに自動的に追加します。
-
manifest.json
ファイル、 -
src/assets/icons
フォルダー内のさまざまなサイズのアイコン。 -
ngsw-worker.js
サービスワーカー。
本番ビルドが含まれているdist/
フォルダーを開きます。 さまざまなファイルがありますが、前述のPWA機能に関連するファイルに集中しましょう。
manifest.json
ファイルが次の内容で追加されました。
{ "name": "pwademo", "short_name": "pwademo", "theme_color": "#1976d2", "background_color": "#fafafa", "display": "standalone", "scope": "/", "start_url": "/", "icons": [ { "src": "assets/icons/icon-72x72.png", "sizes": "72x72", "type": "image/png" }, { "src": "assets/icons/icon-96x96.png", "sizes": "96x96", "type": "image/png" }, { "src": "assets/icons/icon-128x128.png", "sizes": "128x128", "type": "image/png" }, { "src": "assets/icons/icon-144x144.png", "sizes": "144x144", "type": "image/png" }, { "src": "assets/icons/icon-152x152.png", "sizes": "152x152", "type": "image/png" }, { "src": "assets/icons/icon-192x192.png", "sizes": "192x192", "type": "image/png" }, { "src": "assets/icons/icon-384x384.png", "sizes": "384x384", "type": "image/png" }, { "src": "assets/icons/icon-512x512.png", "sizes": "512x512", "type": "image/png" } ] }
ご覧のとおり、追加されたmanifest.json
ファイルには、名前、説明、 start_url
など、PWAに必要なすべての情報が含まれています。

さまざまなサイズのアイコンへのリンクでmanifest.json
ファイルは、 assets/icons
フォルダーにも自動的に追加されました。 もちろん、PWAの最終バージョンを作成する準備ができたら、これらのアイコンを独自のアイコンに変更する必要があります。

index.html
ファイルでは、 manifest.json
ファイルは次を使用して参照されます。
<link rel="manifest" href="manifest.json">
ngsw-worker.js
ファイルも自動的に追加され、サービスワーカーが含まれています。 このServiceWorkerをインストールするコードは、 src/app/app.module.ts
ファイルに自動的に挿入されます。
... import { ServiceWorkerModule } from '@angular/service-worker'; @NgModule({ declarations: [ AppComponent ], imports: [ ... ServiceWorkerModule.register('/ngsw-worker.js', { enabled: environment.production }) ],
@angular/service-worker
は、 ng add
コマンドによってインストールされ、 pwademo/package.json
への依存関係として追加されます。
"dependencies": { ... "@angular/service-worker": "^6.1.0" }
ServiceWorkerビルドサポートもCLIで有効になっています。 angular.json
ファイルに"serviceWorker": true
構成オプションが追加されています。
index.html
ファイルに、値が#1976d2
のtheme-color
のメタタグが追加されます( manifest.json
ファイルのtheme_color
値にも対応します)。
<meta name="theme-color" content="#1976d2">
テーマの色は、アドレスバーなどのUI要素に色を付ける色をブラウザに指示します。
index.html
ファイルとmanifest.json
ファイルの両方にテーマの色を追加すると、アドレスバーがブランドの色と一致する監査が修正されます。
ServiceWorker構成ファイル
別のファイルsrc/ngsw-config.json
がプロジェクトに追加されますが、これはPWAに必須のファイルではありません。 これは、AngularサービスワーカーがキャッシュするファイルとデータURL、およびキャッシュされたファイルとデータを更新する方法を指定できる構成ファイルです。 このファイルに関するすべての詳細は、公式ドキュメントから見つけることができます。
注:この記事の執筆時点では、最新の6.1.3では以前のng add @angular/pwa
コマンドはこのエラーで失敗します: Path “/ngsw-config.json” already exists
ため、今のところ解決策は@angular/cli
をダウングレードすることですおよび@angular @angular/pwa
からバージョン6.0.8へ。
プロジェクトで次のコマンドを実行するだけです。
$ npm i @angular/[email protected] $ ng i @angular/[email protected] $ ng add @angular/pwa
次に、ローカルでホストされているローカルPWAに対して監査を再実行しましょう。 これは新しいPWAスコアです。

Angular CLIは、プログレッシブエンハンスメントのセクションで説明したJavaScriptフォールバックコードを自動的に追加しないため、 src/index.html
ファイルを開いて追加します。
<noscript> Please enable JavaScript to run this application. </noscript>
次に、アプリケーションを再構築し、監査を再実行します。 これが今の結果です:

HTTPSリダイレクトに関連する監査に失敗したのは1つだけです。 アプリケーションをホストし、HTTPからHTTPSへのリダイレクトを構成する必要があります。
次に、ホストされ保護されたバージョンのPWAに対して監査を実行してみましょう。

100⁄100のスコアを取得します。これは、PWAのすべてのコア原則を正常に実装したことを意味します。
このデモPWAの最終的なコードは、このGitHubリポジトリから入手できます。
結論
このチュートリアルでは、単純なAngularアプリケーションを構築し、AngularCLIを使用してそれをPWAに変換しました。 GoogleのLighthouseを使用して、PWA機能のアプリケーションを監査し、オフラインサポートやプッシュ通知を追加するためのServiceWorkerなどのPWAのさまざまなコア原則について説明しました。 ホーム画面への追加機能とスプラッシュ画面機能、プログレッシブエンハンスメント、およびHTTPSを有効にするためのWebマニフェストファイル。
強調表示されている他の項目を手動で確認する必要がある場合もありますが(「手動で確認する追加項目」セクションの下)、Lighthouseによって自動的に確認されるわけではありません。 これらのチェックは、GoogleによるベースラインPWAチェックリストで必要です。 これらはPWAスコアには影響しませんが、手動で確認することが重要です。 たとえば、サイトがクロスブラウザで機能し、各ページにソーシャルメディアでの共有可能性の目的で重要なURLが含まれていることを確認する必要があります。
PWAは、パフォーマンスやアクセシビリティの向上などの他の側面にも関係しているため、Lighthouseを使用して、これらの側面についてPWA(または一般的なWebサイト)を監査し、必要に応じて改善することもできます。