web-dev-qa-db-ja.com

VueJS /ブラウザキャッシュプロダクションビルド

VueJSアプリを持っています。 npm run buildを実行すると、dist/*ファイルの新しいセットが作成されますが、サーバーに(古いビルドを削除した後)ロードし、ブラウザーでページを開くと、古いビルドがロードされます(キャッシュから私は仮定します)。ページを更新すると、新しいコードが問題なくロードされます。

これは私のindex.htmlです:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
        <meta http-equiv="cache-control" content="max-age=0" />
        <meta http-equiv="cache-control" content="no-cache" />
        <meta http-equiv="expires" content="-1" />
        <meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
        <meta http-equiv="pragma" content="no-cache" />
        <link rel="stylesheet" href="/static/css/bootstrap.min.css"/>
    </head>
    <body>
        <div id="app"></div>
    </body>
</html>

毎回新しいコードをロードするように強制する方法、または(理想的には)サーバーから古いファイルがなくなっているかどうかを確認し、ブラウザを更新する方法はありますか?

23
ierdna

この同じ問題に苦労し、一部の人々のブラウザは手動で更新しない限り最新バージョンをプルすることすらできないことを発見しました。ファイルをホストしたCDNなど、さまざまなレイヤーでのキャッシュに問題がありました。

また、バージョンの維持に苦労し、何か問題が発生した場合に以前のバージョンを迅速に再展開できるようにしました。

当社のソリューション(vue-cli Webpackに基づいたプロジェクトを使用):

1)「静的」ではなくバージョン固有のフォルダーを持つようにディストリビューションを構築します。これは、ビルドを追跡し、必要に応じて展開を「元に戻す」のにも役立ちます。 「静的」ディレクトリを変更するには、index.jsの「build」の下にある「assetsSubDirectory」を変更し、「assetsPublicPath」をCDNパスに変更します。

2) Webpack Assets Manifest を使用して、すべてのアセットを指すmanifest.jsonファイルを作成します。マニフェストには、高度なセキュリティアプリケーションとして、すべてのファイルのハッシュが含まれています。

3)バージョン管理されたフォルダー(jsとcssを含む)をCDNにアップロードします。

4)(オプション)バックエンドサーバーで動的なindex.htmlファイルをホストします。スタイルシートとスクリプトへのリンクは、manifest.jsonのデータから取得したテンプレートシステムを使用して、バックエンドサーバーによって入力されます(#5を参照)。以下のコメントのようにforce-reloadオプションを使用できるため、これはオプションです。これは素晴らしい経験ではありませんが、機能します。

5)新しいバージョンを公開するために、manifest.jsonをバックエンドサーバーに投稿します。 GraphQLエンドポイントを介してこれを行いますが、手動でjsonファイルをどこかに置くことができます。これをデータベースに保存し、それを使用してindex.htmlを作成し、ファイルハッシュを使用してファイルを検証します(CDNがハッキングされていないことを検証するため)。

結果:即時の更新と、バージョンの追跡と変更が簡単になります。ほぼすべてのユーザーのブラウザーですぐに新しいバージョンがプルされることがわかりました。

もう1つのボーナス:高度なセキュリティを必要とするアプリケーションを構築し、(既にセキュリティで保護された)バックエンドでindex.htmlをホストすることで、セキュリティ監査をより簡単にパスできるようになりました。


編集2/17/19

キャッシュなしヘッダーにもかかわらず、企業ネットワークがプロキシキャッシュを実行していることがわかりました。 IE 11もキャッシュヘッダーを無視するようです。したがって、一部のユーザーは最新バージョンを取得していませんでした。

ビルド時にインクリメント/定義されるversion.jsonがあります。バージョン番号はmanifest.jsonに含まれています。ビルドバンドルは自動的にS3にアップロードされます。次に、manifest.jsonをバックエンドに渡します(これは、管理領域のエントリページで行います)。次に、そのUIで「アクティブ」バージョンを設定します。これにより、バージョンを簡単に変更/元に戻すことができます。

バックエンドは、すべての要求に応答ヘッダーとして「currentVersion」を配置します。 currentVersion!== version(version.jsonで定義されている)の場合、ユーザーにクリックしてブラウザを更新するように要求します(ブラウザに強制するのではなく)。

10
For the Name

キャッシュヘッダーに関するこの包括的な回答 に基づいて、あなたが最善を尽くすのは、<meta>タグは、サーバーによって設定されたヘッダーによってオーバーライドされます。

質問に対するコメントは、nginxでこのアプリを提供していることを示しています。上記のリンクされた回答を使用して、Cache-ControlExpiresおよびPragmaヘッダーは、.html私のnginx設定でこのように:

server {

  ...other config

  location ~* \.html?$ {
    expires -1;
    add_header Pragma "no-cache";
    add_header Cache-Control "no-store, must-revalidate";
  }
}

これにより、ブラウザは最新のindex.htmlすべてのページのリロード時に、最新のhtml応答に新しい参照がない限り、キャッシュされたアセット(js/css/fonts/images)を引き続き使用します。

3
Sean Ray

キャッシュを削除するには、rm -rf node_modules/.cacheを実行します

これにより、キャッシュが削除されます。デプロイする前に新しいビルドを実行できます。

私は本番ビルドを実行したときと同じ問題を抱えていましたが、ローカルで実行していても、私のコードは最新の変更ではなく本番ビルドを指していました。

これは関連する問題だと思います: https://github.com/vuejs/vue-cli/issues/245

2
Connor Leech