【入門】AngularでPWAアプリを作ってGithub.ioに投稿するまで

# TL;DR

- ネット上の記事を組み合わせれば一日でなんとか作れる
- しかし落とし穴も多いのでポイントも交えて解説してみる

# 重要なキーワード

## PWA

- Progressive Web Applicationの略
- Webアプリの一種だが、「**スマホアプリのように**ボタンなどのUI操作ができる」「**ネットに繋がなくても**操作できる」「**ネイティブアプリのように**ホーム画面配置やpush通知を行える」のが特徴
- スマホに「インストール」するには、PWA(Webアプリ)を公開しているサイトにスマホでアクセスし、「ホーム画面に追加」操作を行えばいい
- 例えば[シャニマス](https://shinycolors.enza.fun/)もPWAとして扱われたりする。詳しくは次の記事を参照

　[シャニマスはPWA時代のGoogleMapなのかもしれないという話 - MANA-DOT](http://blog.manaten.net/entry/shinymas_pwa)

## Angular

- TypeScript(JavaScript)で書ける、フロントエンドWebアプリケーション用のフレームワーク
- プラグインが豊富なので、PWAアプリも比較的簡単に作ることができる
- これを採用した主な理由は「自分が慣れていた」ため

## Github.io

- 自作サイト(Webアプリ含む)を無料で配信できるプラットフォームの1つ
  - 難しく言うと「静的ホスティングサイト」の一種
- 具体的には、GitHubのリポジトリに「デプロイ」したHTMLファイルを「表示」している
- なお、XXXさんがリポジトリYYYにうｐしたデータをGithub.ioで表示させた際、**https://XXX.github.io/YYY/**といったURLで公開される

# 開発手順

## 1. Angular-Cliでプロジェクトを作成し、必要なライブラリをnpmで導入する

　今回はhttps://github.com/puku0x/angular-pwa-sample を参考にしました。英語が苦手な方は[Qiita記事](https://qiita.com/puku0x/items/16f3e134dc6a425601fd)を参照していただきたい……と言いたかったのですが、**Qiita記事は少し情報が古い**(関連ライブラリのバージョンアップに伴う変更)ため、[GitHubの説明](https://github.com/puku0x/angular-pwa-sample)を読むことをおすすめします。

## 2. Angularの作法に従いアプリを開発する

　この辺は趣味も多分に影響してきますが、PWA作成が目標なので、ボタンなどのデザインをカッコよくできる**Angular Material**を導入しておくといいでしょう。

　[Angular Materialのインストールから使い始めまで](https://qiita.com/donuzium/items/c9af982b02a9c4a2aaa8)
　　(当該記事の冒頭にもありますが、「MdButtonModule→MatButtonModule」
　　「\<button md-raised-button\>→\<button mat-raised-button\>」などと
　　　表記が一部異なっていますのでご注意ください)

　また、[上記記事](https://qiita.com/puku0x/items/16f3e134dc6a425601fd)を見ながら環境を導入していた場合、次のようなコマンドを走らせながら開発を行うはずです。

- `ng serve`→常時動かしておくビルドサーバー。デフォルトではhttp://localhost:4200/ で待機している
- `ng run nzsz:app-shell:production`→本番用ビルド
- `npx pushstate-server フォルダパス`→本番用ビルドしたものを起動して動作確認できる

## 3. ビルドしたものをGithub.ioにデプロイする

　**最初の難関**です。Github.ioにデプロイする方法は何種類かありますが、今回は
　　「masterブランチの/docフォルダに成果物を置いておき、そこを参照させる」
方式にしました。ここで言うところの成果物とは、`ng run nzsz:app-shell:production`したものを指します。
　フォルダ構成としてはこんなイメージですね↓。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/29802/d4db9147-8a33-b54c-aea9-3e72e787183f.png)

　さて、angular-cliでビルドする際、.gitがあるフォルダではなく、my-appフォルダをカレントディレクトリにしてから「`ng serve`」などのコマンドを叩きます。その上で、docフォルダに成果物を書き出す必要があるので、my-app/angular.jsonを次のように書き換えます。また、baseHrefを「"."」と設定することで、後述するパス問題も解決させています(デフォルト設定では「"/"」と設定されてしまうため)。

```angular.json(一部)
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {

            // これを
            "outputPath": "dist/my-app",
            // このように修正
            "outputPath": "../docs",
            "baseHref": ".",

            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",

```

　また、my-app/src/app/app.module.tsにて、次のような書き換えを行います。これは、GitHub.ioでデプロイするにあたり、アップロード先が「[https://XXX.github.io/YYY/](https://XXX.github.io/YYY/)」になる以上、「/ngsw-worker.js」表記だと「[https://XXX.github.io/YYY/ngsw-worker.js](https://XXX.github.io/YYY/ngsw-worker.js)」ではなく「[https://XXX.github.io/ngsw-worker.js](https://XXX.github.io/ngsw-worker.js)」を参照してしまうためです。~~何を言っているのかわからねーと思うが~~

```app.module.ts(一部)
  imports: [
    BrowserModule.withServerTransition({ appId: 'serverApp' }),
    AppRoutingModule,

    // これを
    ServiceWorkerModule.register('/ngsw-worker.js', { enabled: environment.production }),
    // このように修正
    ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production }),

    RouterModule,
    BrowserAnimationsModule,
    MatButtonModule,
    MatCheckboxModule
  ],
```

 さらに、my-app/src/manifest.jsonについて、start_urlを次のように書き換えます。これもさっきと同じく、「/」だと意図した参照位置にならないからですね。

```manifest.json(一部)
  "background_color": "#fafafa",
  "display": "standalone",
  "scope": "/",

  // これを
  "start_url": "/",
  // このように修正
  "start_url": "/my-app/",

  "icons": [
    {
      "src": "assets/icons/icon-72x72.png",
```

## 4. スマホでアクセスし、「インストール」する

　百聞は一見にしかず。次のツイートにまとめてみました。まだまだ開発中ですが、[https://ysrken.github.io/NZSZ/](https://ysrken.github.io/NZSZ/)から試せます。

<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="ja" dir="ltr">これをこうしてこうじゃ！<a href="https://twitter.com/hashtag/PWA?src=hash&amp;ref_src=twsrc%5Etfw">#PWA</a> <a href="https://t.co/NR1KBbqMSZ">pic.twitter.com/NR1KBbqMSZ</a></p>&mdash; YSR@普通デューサー (@YSRKEN) <a href="https://twitter.com/YSRKEN/status/1008002341767819269?ref_src=twsrc%5Etfw">June 16, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>