JHipsterでService WorkerでWeb Pushを、 と思っていて、Angularだから、 前やったように app.modules.tsでServiceWorkerModule.register('./service-worker.js',...);してから@angular/service-workerでSwPushをinjectして、 って思ってたんですが、違うんですね。 JHipsterではworkboxでService Worker使うようになってるんですね予め。 確かにindex.htmlでservice-worker.jsを有効にして挙動を見てると、 cachingは綺麗に行っている様子です。 えーでも調べてみると、workboxってWeb Pushはないじゃーないですかー。
特に私の知っている範囲ではworkboxはプッシュ通知のロジックを作ってくれないので、そこは自分で書いてやる必要があります。 ServiceWorkerを簡単に書けるworkbox-swの使い方
しかも、自分のcodeとmergeする、 即ちworkboxPlugin(...)にswSrc:を追加すると、 generateSWが使えず自分で書かないといけないの!? ですか? いやー、jhipsterで生成されるservice-worker.jsとか見ると、 色んなfilesにhash値?が付与されているから、 これを自分で作るというのはあり得ないでしょー。 どーしたらいーのー?!
と、途方に暮れました。
workboxを捨ててAngularのSwPushにする? いやー、でもjhipsterでのbuildではng実行されないので、 いくら.angular-cli.jsonに"serviceWorker": trueと書いても効かないんですよー。 Angularのservice workerは生成されないわけですね。
jhipsterで生成されたbuild/www/service-worker.jsを見ていると、 上部のコメントに、
1 2 3 4 | |
とあります。言われるままにそのURLを見てみると、 importScriptsというoptionがあることがわかりました。 これを指定するとどうなるのかなー、試してみます。 指定する場所は、webpackでworkboxのservice worker生成をやっているので、 webpack/webpack.prod.jsになります。 それの最下段、new WorkboxPlugin.GenerateSW({...})の中に importScripts: ['push-notifications.js']と書いてみると、 自動生成されたbuild/www/service-worker.js中に、 importScripts("push-notifications.js",...)と出ます。 なるほど。 ではこのpush-notifications.jsというのを作ってwww root folderに置き、 そこにpush notificationのlogicを書いておけばいいんじゃーん。 でも、基本的には全てのfile名はhash化?されてしまいます。 どうやって名前をhash化されないようにするの?! favicon.ico等の例から手探りで探し当てました。 webpack/webpack.common.jsのnew CopyWebpackPlugin([..])に 書いておけばいーんですね。なるほど。
結局要するにworkboxのimportScriptsを使うということで、具体的には、
src/main/webapp/push-notification.jsにWeb Push通知時の処理addEventListener('push', function(event) {...});と通知をclickした時の処理addEventListener('notificationclick', function(event) {...});を書いておくwebpack/webpack.prod.jsのnew WorkboxPlugin.GenerateSW({...})にimportScripts: ['push-notifications.js']を書くwebpack/webpack.common.jsのnew CopyWebpackPlugin([..])に{ from: './src/main/webapp/push-notifications.js', to: 'push-notifications.js' },を書く
で目出度くJHipster application上でのWeb Push通知が出来ました。
尚、通知の許可を求める処理やendpoint、auth、publicKeyを求める処理では、 AngularのSwPushを使うことが出来ます。 JavaScriptでゴリゴリ書かなくてもthis.swPush.requestSubscription()だけで済むのでラクです。