オープンソース版LWCのPWAをGithub Pages(サブディレクトリ)で動かす

[Lightning Web Components](https://developer.salesforce.com/docs/component-library/documentation/en/48.0/lwc)（LWC）というSalesforceのフロントエンドフレームワークがあります。これはSalesforceプラットフォーム上でしか動かないのですが、そのオープンソース版があります。

https://lwc.dev/

こちらを試してみたところ、PWA（Progressive Web Apps）で動かすオプションがあったので、動かしてみました。とりあえずGithub Pagesで動かそうとしたら、サブディレクトリで動かすのに少し悩んだので、主にそこのところを書いていきます。

LWC関係なく、サブディレクトリでPWAを動かしたい人が検索したときに役に立ったらいいなと思います。

※Salesforceはあんまり関係ないので今回はSalesforceのブログキャンペーンではありません。

# できたもの

https://atskimura.github.io/lwc-oss-pwa-example/

MacのChromeで開くとこのようにインストールボタンが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27267/38109de7-9dd8-88ef-65e8-0debdd5fa799.png)

インストールするとデスクトップアプリのように起動します。
（なお、アンインストールしたいときはこの右上のメニューからアンインストールできます。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27267/fa3bf17c-59f7-f992-dd7d-e6ae4c3ffabe.png)

Spotlightから検索もできるし、Dockに追加もできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27267/f840231a-59f5-8e47-0110-c42acf7cd1c2.png)

もはやデスクトップアプリはこれでよさそうですね。Electron要らなそう。
もちろんモバイルでもアプリのように動きますが、今回私が作りたいのはデスクトップアプリだったので、特にモバイルは試していません。

# リポジトリ

リポジトリはこちらです。

https://github.com/atskimura/lwc-oss-pwa-example

Github Pagesはmasterのdocsフォルダで動かすように設定しているので、docsフォルダの中身がホスティングされています。

# サブディレクトリで動かす

```
https://lwc-oss-pwa-example.example.com/
``` 
のようにルートで動かすなら、`npx create-lwc-app my-app`でできたサイトそのままで動きますが、

今回[Github Pages](https://pages.github.com/)のプロジェクトサイトで動かそうとしたので、URLが

```
http://<username>.github.io/<repository>/
```

のようになります。

## manifest.jsonの修正

一番重要なところですが、manifest.jsonを以下のように変更します。

今回は`https://atskimura.github.io/lwc-oss-pwa-example/`で動かすので、`Scope`をサブディレクトリの`lwc-oss-pwa-example`にしています。
`start_url`はScopeからの相対パスでPWAを起動したときに読み込んで欲しいURLを記載します。

```json:manifest.json
     "Scope": "/lwc-oss-pwa-example/",
     "start_url": "./index.html",
```

manifest.jsonの仕様は[ウェブアプリマニフェスト | MDN](https://developer.mozilla.org/ja/docs/Web/Manifest)を参照してください。

修正箇所: https://github.com/atskimura/lwc-oss-pwa-example/compare/664bb2c...67b62d0#diff-898656577829f3ff69c0ab8c788664e1

## scripts/webpack.config.jsの修正

ビルドしたjs,cssの読み込み処理をindex.htmlにwebpackが追加してくれるので、それも相対パスになるように、以下のように`output`を追加します。

```javascript:webpack.config.js
module.exports = {
    output: {
        publicPath: './',
    },
    plugins: [new GenerateSW({ swDest: 'sw.js' })]
};
```

修正箇所: https://github.com/atskimura/lwc-oss-pwa-example/compare/664bb2c...67b62d0#diff-4a5ee2343b9d772e602c958b1feb98a4

## Service Workerの登録も相対パスに

`create-lwc-app` でPWAを作ると、[Workbox webpack Plugins](https://developers.google.com/web/tools/workbox/modules/workbox-webpack-plugin)でservice workerファイル（`sw.js`）を自動生成します（これでjsやcssをオフラインキャッシュできるようにしています）。これの読み込みも相対パスにします。

修正箇所: https://github.com/atskimura/lwc-oss-pwa-example/compare/664bb2c...67b62d0#diff-1fdf421c05c1140f6d71444ea2b27638

## リソースを読み込む箇所を相対パスに

画像などを読み込みところを全部相対パスにします。

修正箇所:

* https://github.com/atskimura/lwc-oss-pwa-example/compare/664bb2c...67b62d0#diff-e249faefed5757034596c5096d33dab6
* https://github.com/atskimura/lwc-oss-pwa-example/compare/664bb2c...67b62d0#diff-3bafa5640792037c499909503ce5df90

# 終わりに

GithubのCompareを見るだけでわかると思うのですが、何も書かないのも寂しかったので、ちょっと解説を入れてみました。
https://github.com/atskimura/lwc-oss-pwa-example/compare/664bb2c...67b62d0

肝は`manifest.json`の修正だけです。LWC関係なく、サブディレクトリでPWAを動かしたい人もここの書き方は役に立つかなと思います。