LoginSignup
11
11

More than 5 years have passed since last update.

create-react-appにpush通知を受信するservice workerを追加する

Last updated at Posted at 2019-03-03

Push通知やってみたい!!! :triumph:

けどkotlinもswiftも書けないしな〜 :cry:
ブラウザにしてもwebsocket?なにそれ食えるの :baby:
インフラエンジニアの自分には厳しいかな :thinking:
...
等思ってたらなんとservice workerというものを使えば簡単にブラウザで試せるという噂をキャッチ

しかもcreate-react-app(cra)でテンプレを作ればservice workerのボイラープレートもくっついてくるっぽいのでこれを使うことにしました

なお筆者はフロントエンドに造詣が全くないですので意味・単語等間違いがありましたらご指摘ください。

環境

  • linux
    • chromium(72.0.3626.119)
    • firefox dev edition(66.0b12)

成果物

step by step

登場人物

  • フロントエンド(react)
  • バックエンド(適当なwebサーバー)
  • pushサービス(firefoxならmozilla, chromiumならgoogleになります)

いつもの依存モジュールのインストール

カタカタしていると安心するのでtypescriptにてお送りします

eslintはcraに入っています(最新版入れるとyarn start時に怒られます)

yarn create create-react-app pj --typescript
cd pj
yarn add -D @typescript-eslint/eslint-plugin @typescript-eslint/parser @typescript-eslint/typescript-estree esli
nt-config-prettier eslint-plugin-prettier eslint-plugin-react husky lint-staged

ServiceWorkerの登録

commit

そのままだとprecacheしかやってくれませんので、通知を受信できるように編集します

src/serviceWorker.ts に3点追記します

  • applicationServerPublicKey
    • web-push使って生成しておきます
  • urlB64ToUint8Array
  • registration.pushManager.subscribe({})...
    • pushManagerにsubscribe情報を登録します
    • pushサービスからエンドポイント情報が返ってくるのでそれをバックエンドに通知します
    • この際、デフォルトのままだと型定義がが無いと怒られるのでtsconfig.jsonのlibにwebworkerを追記します

ServiceWorkerの有効化

commit

デフォルトではserviceworkerのregisterが切られてますので有効化します
src/index.tsxserviceWorker.unregister()serviceWorker.register()に変更します
こいつを有効にしてもproductionなenvじゃないと動きません(reactのdocumentにもbuildして試してみてねと書いてあります)

通知ボタンの配置

commit

App.tsxにコンポーネントを配置します。イメージとしてはポチると通知が飛ぶ感じですね
デバッグ時にめんどくさいのでservice workerのunregisterボタンも用意しておきます

swの差し替え

このままでもserviceworkerは動きますが、デフォルトのwebpack.config.jsはworkboxのGenerateSWによってserviceworkerを生成しているため、precache機能しか発揮してくれません
というわけで自作のswに差し替えちゃいましょう

react-app-rewiredの追加

commit
参考

yarn eject を行って出てきたwebpack.config.jsを書き換えても良いですが不可逆的変化怖い... :chicken:
故にcraのconfigを上書きできるreact-app-rewiredを使います

yarn add -D react-app-rewired

config-overrides.jsに書いていきます

自作service workerを書く

commit

本当はtypescriptで書きたかったけど、webpack力がないので断念 :sob:

バックエンドを書く

otiai10さんの記事を参考に実装しました
やったことはtypescript化したことくらいなので省略します

動かす

yarn build && serve -s build

image.png

:thinking: oO(なぜかchromiumはアイコンが変わらない・・・)

所感

  • serviceworkerをtypescriptで書けなかったの悔しい!!!
  • serviceworker自体はドキュメントが充実している事もあってさくっと作れた
  • 微妙にchromimとfirefoxで挙動が違った(エラーとか)のに苦労した(chromiumの方がエラー多かった印象)
  • ブラウザのdevtoolというのを初めて触ったが、以下の点でchromiumの方が使いやすかった
    • Javascript contextを指定できる(例えばsw.jsにするとselfがServiceWorkerGlobalScopeになる)
    • Service Workerのunregisterをdevtoolで行える(firefoxはabout:serviceworkers)
      • 当初この記事に従ってabout:debugging#workersを使用したが、なぜかこのページを開いているだけでCPU負荷が高騰してFirefox全体がフリーズするまでになってしまった
        • warningにも書かれていたが、multiple content processesとの併用が原因なのかもしれない
    • pushサービスのendpointのurlが短い(気持ちの問題)
  • フロントエンドすごい(特にエコシステム)

その他備忘

  • serviceworkerはhttps経由もしくは通知元がlocalhostの場合のみ有効になる
  • typescriptでservice-workerを書く時はひと工夫必要

参考文献

11
11
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
11