【Laravel】キャッシュ対策をVersioningで行う

えび

ChromeやSafariでキャッシュが原因でJSやCSSの変更が反映されない問題
せっかくゴリゴリとVueコンポーネントを作っても、本番アップしたらキャッシュのおかげで真っ白なんてことも…

毎回ユーザーに「キャッシュリセットしてください」なんて言うわけにも行かないので、Laravel Mixのバージョン付けで対策する

Versioning (バージョニング)とは

Laravel Mixが用意してくれている、
その名の通り各ファイルをバージョン付けしてくれる機能
本家の解説はコチラ

この機能を使うと、
コンパイルしたJSやCSSなどのファイルのURLの末尾に一意のハッシュが追加される。
(例) /js/sample.js?id=XXXXXXXXXXXXXXXXXXXX

さらに、ソースが更新される度にこの末尾のハッシュを自動更新してくれるから、
ブラウザ側は常に新しいリソースとして読み込んでくれる構造 ( 便利!)

早速Versioning使ってみる

webpack.mix.jsとリソースの読み込み方法を変更するだけ

  • webpack.mix.js
    .version()を追加
const mix = require('laravel-mix')

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

mix.js('resources/js/app.js', 'public/js').vue()
  .sass('resources/sass/app.scss', 'public/css')
  .version() // ⭐️ 追加

  • コンパイルされたファイル (app.jsapp.css) を読み込んでいる箇所
    → 指定方法をmix()に変更
<link href="{{ mix('css/app.css') }}" rel="stylesheet">
<script src="{{ mix('js/app.js') }}" defer></script>

これで再コンパイルすると、生成されるファイルの末尾にハッシュが付与される

<!-- ⭐️ Before -->
<link href="/css/app.css" rel="stylesheet">
<script src="/js/app.js" defer=""></script>

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

<!-- ⭐️ After -->
<link href="/css/app.css?id=719a24cd95abc07a2129" rel="stylesheet">
<script src="/js/app.js?id=12adc5a0cb676bba8ad0" defer=""></script>

本番環境のみVersioningをするようにする

ローカル環境でバージョン付けは必要ないので、
本番環境でコンパイルする場合のみVersioningするようにしてみる

  • webpack.mix.js
const mix = require('laravel-mix')

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

mix.js('resources/js/app.js', 'public/js').vue()
  .sass('resources/sass/app.scss', 'public/css')

// ⭐️ こっちに追加
if (mix.inProduction()) {
  mix.version()
}

これで、npm run prodをした時だけVersioningがされるようになった