Nuxt.js(SPA)+FirebaseなWebサービスで強制的に更新する(リビジョンアップ対策)

SPAはとてもすてきだけど、Hostingにアップロードしてもすぐに更新されない。。
たとえば、メンテナンス画面に変更しても、キャッシュが残っててメンテナンスモードにならないとか。。

この[記事](https://qiita.com/okkuyama/items/484fdd868b17d8c960a9#%E3%83%AA%E3%83%93%E3%82%B8%E3%83%A7%E3%83%B3%E7%AE%A1%E7%90%86%E3%82%92%E5%90%AB%E3%82%93%E3%81%A0%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4%E3%82%92%E8%87%AA%E5%8B%95%E5%8C%96%E3%81%99%E3%82%8B)をみると、Reactで強制的にリビジョンアップする方法が載っていたので、
Nuxt.jsでもできないかやってみたときの備忘録。

#### 追記 2018/10/17

@hecateballさんの記事によると、あまりよくない方法のよう。。
PWAでキャッシュ戦略を設定するか、Remote Configがよさそう(*´ω｀*)
- [Nuxt.js(SPA)とFirebaseで強制リビジョン（バージョン）アップするならPWAモジュールを使おう - Qiita](https://qiita.com/hecateball/items/29f726430d204c964f04)

## ざっくりとした流れ

流れとしては、こんな感じ。

1. staticディレクトリにJSONファイルでバージョン番号を用意
2. 環境変数にリビジョン番号を保持するように設定
3. JSONファイルと環境変数のバージョン番号が異なっていたら、強制リロードする

用意するJSONファイルはこんな感じ

```json
{"version":1}
```

## やりかた

バージョンチェックするタイミングや更新の契機はいろいろあるけど、
ページ遷移時にチェックするよう、middlewareで対応。

[参考記事](https://qiita.com/okkuyama/items/484fdd868b17d8c960a9#%E3%83%AA%E3%83%93%E3%82%B8%E3%83%A7%E3%83%B3%E7%AE%A1%E7%90%86%E3%82%92%E5%90%AB%E3%82%93%E3%81%A0%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4%E3%82%92%E8%87%AA%E5%8B%95%E5%8C%96%E3%81%99%E3%82%8B))にあるような、ダイアログを出すパターンもある。

### バージョンをチェックするmiddlewareを用意

`middleware/checkUpdate.ts`として、バージョンをチェックするミドルウェアを追加する。

```typescript
import axios from "axios";

export default async function() {
  try {
    // revision.jsonファイルから最新のバージョンを取得
    const res = await axios.get("/version.json");
    const data = res.data;
    const latestVersion = data.version;

    // 環境変数から現在のバージョンを取得
    const curVersion = !!process.env.VERSION ? Number(process.env.VERSION) : 0;

    // 最新バージョンよりも古かったら、強制的にリロードする
    if (curVersion < latestVersion) location.reload(true);
  } catch(error) {
    console.error(error);
    // エラーのときはなにもしない
  }
}
```

`location.reload(true)`を使うとキャッシュを無視して、強制的にリロードするらしい
・参考: [Location.reload() - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/Location/reload)

### nuxt.config.tsの設定

middlewareを使うようにするのとあわせて、

1. 環境変数(`VERSION`)の設定したり、
2. JSONファイル(`version.json`)を生成する

```typescript
import fs from "fs";
import NuxtConfiguration from "@nuxt/config";


// バージョン番号を設定
const VERSION = 1;
// revision.jsonをstatic配下に生成
fs.writeFileSync("static/version.json", JSON.stringify({ version: VERSION }));

const config: NuxtConfiguration = {
  env: {
    VERSION: VERSION // 環境変数にバージョンを設定
  },

  router: {
    middleware: ["checkUpdate"] // バージョンチェックのmiddlewareを設定
  }
}
```


### firebase.jsonで`version.json`をキャッシュしないように

そのままだと、`version.json`自体もキャッシュされてしまうので、
あまり意味がない感じになる。。

なので、firebase.jsonでversion.jsonをキャッシュしないように設定

```json
{
  "hosting": {
    "public": "public",
    "ignore": ["firebase.json", "**/node_modules/**", "**/README.md"],
    "headers": [
      {
        "source": "/version.json",
        "headers": [
          {
            "key": "Cache-Control",
            "value": "private, no-store, no-cache, must-revalidate"
          }
        ]
      }
    ]
  },
}
```

以上!!

## こんなのつくってます!!

積読用の読書管理アプリ 『積読ハウマッチ』をリリースしました！
[積読ハウマッチ](https://tsundoku.site)は、Nuxt.js+Firebaseで開発してます!

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/572d4947-f40b-e4dc-1c9c-bc584cd2a66c.png" width="200"/>

もしよかったら、遊んでみてくださいヽ(=´▽`=)ﾉ

要望・感想・アドバイスなどあれば、
公式アカウント([@MemoryLoverz](https://twitter.com/MemoryLoverz))や開発者([@kira_puka](https://twitter.com/kira_puka))まで♪


# 参考にしたサイトさま
- [javascript – シングルページアプリケーション（SPA）ページを強制的に更新する方法 - コードログ](https://codeday.me/jp/qa/20190305/329882.html)
- [【React.js】SPAでのリビジョンアップ対策 - Qiita](https://qiita.com/okkuyama/items/484fdd868b17d8c960a9#%E3%83%AA%E3%83%93%E3%82%B8%E3%83%A7%E3%83%B3%E7%AE%A1%E7%90%86%E3%82%92%E5%90%AB%E3%82%93%E3%81%A0%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4%E3%82%92%E8%87%AA%E5%8B%95%E5%8C%96%E3%81%99%E3%82%8B)