COMMIT - Laravel Cache Busting

Sebagai Developer Laravel, Mungkin anda pernah mengalami ketika sudah melakukan compiled assets, namun halaman belum melakukan pembaharuan, terutama ketika kalian mengcompile asset itu dengan laravel-mix. Dan Ketika Projek Laravel anda sudah di deploy, anda mungkin akan tidak akan bisa membuat Versioning karena mix manifest salah mendeteksi path projek kita. Nah, Pada tutorial ini, kita akan melakukan Cache Busting / Versioning agar ketika Asset sudah di compile dengan menjalankan npm run prod/dev , browser otomatis akan mengupdate asset kita tanpa harus melakukan hapus history secara manual pada tiap user

Versioning / Cache Busting

Sebelum mengkonfigurasi asset webpack kita, kita harus ketahui dulu struktur Folder yang kita punya, karena biasanya setelah melakukan deployment , anda mungkin memisah antara folder public dengan folder-folder lainnya seperti ini

Cache Busting Commit

Dimana Folder laravel berisi komponen utama Projek Laravel kita ( app,bootstrap,config dll kecuali folder public) dan public_html adalah folder yang berisi asset halaman kita seperti storage,index.php, mix manifest.

Dan dari sini lah mix manifest tidak bisa terdeteksi karena secara default mix manifest akan mengarahkanpathnya ke folder public yang sama dengan folder laravel pada gambar diatas.

Untuk itu kita ubah dulu pathnya dengan membuat custom helpers, didalam folder http ( laravel/app/Http/helpers.php , lalu masukan code seperti ini :

<?php
use Illuminate\Support\Str;
use Illuminate\Support\Carbon;
use Illuminate\Support\HtmlString;

if (!function_exists('mixUrl')) {
    /**
     * Get the path to a versioned Mix file.
     *
     * @param  string  $path
     * @param  string  $manifestDirectory
     * @param  string  $baseUrl
     * @return \Illuminate\Support\HtmlString
     *
     * @throws \Exception
     */
    function mixUrl($path, $manifestDirectory = '', $baseUrl = null)
    {
        static $manifests = [];
        $public_hot = '../public_html/hot';
        $public_dir = '../public_html/mix-manifest.json';
        if(App::environment('local')){
            $public_hot = '../public/hot';
            $public_dir = '../public/mix-manifest.json'; 
        }
        if (!Str::startsWith($path, '/')) {
            $path = "/{$path}";
        }

        if ($manifestDirectory && !Str::startsWith($manifestDirectory, '/')) {
            $manifestDirectory = "/{$manifestDirectory}";
        }

        if (file_exists(base_path($manifestDirectory . $public_hot))) {
            if(App::environment('local')){
                return new HtmlString("//localhost:8000{$path}");
            }
            else{
                return new HtmlString("https://your-real-domain.com{$path}");
            }
        }

        $manifestPath = base_path($manifestDirectory . $public_dir);

        if (!isset($manifests[$manifestPath])) {
            if (!file_exists($manifestPath)) {
                throw new Exception('The Mix manifest does not exist.');
            }

            $manifests[$manifestPath] = json_decode(file_get_contents($manifestPath), true);
        }

        $manifest = $manifests[$manifestPath];

        if (!isset($manifest[$path])) {
            report(new Exception("Unable to locate Mix file: {$path}."));

            if (!app('config')->get('app.debug')) {
                return $path;
            }
        }

        return new HtmlString($manifestDirectory . $manifest[$path]);
    }
}

Setelah itu buka composer.json dan daftarkan helpers ini ke bagian autoload setelah classmap

  "autoload": {
        "classmap": [
            "database/seeds",
            "database/factories"
        ],
        "files": [
          "app\Http\helpers.php"
        ],
        "psr-4": {
            "App\\": "app/"
        }
    },

lalu jalankan composer dump-autoload

Laravel Mix

Setelah helpers dibuat kita akan menambahkan method/helper version pada file webpack.mix.js laravel\webpack.mix.js

let mix = require('laravel-mix');
let path = require('path');
/*
 |--------------------------------------------------------------------------
 | 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.setPublicPath(`..${path.sep}public_html`);
mix.js('resources/assets/js/app.js', 'js')
   .sass('resources/assets/sass/app.scss', 'css').version();

mix.setPublicPath akan mengubah path ketika kita menjalankan npm run dev/prod, jadi sudah tidak lagi di folder public yang, tapi pada folder public_html. dan method version ini akan menambahkan semacam id pada mix-manifest.json, didalam folder public_html seperti ini

{
    "/js/app.js": "/js/app.js?id=f16eabe2152645551b2c",
    "/css/app.css": "/css/app.css?id=29b119a0229d16789d67"
}

Setiap kali, anda melakukan compile dengan npm run dev/prod id ini mungkin akan berubah-ubah, tentu saja kalian tidak akan memasukan id itu secara manual pada komponen master blade kalian, untuk itulah fungsi dari helpers yang baru saja kita buat tadi, jadi anda dapat menggunakan helper mixUrl pada komponen master blade anda seperti ini

<script src="{{ mixUrl('/js/app.js')}}"></script>

perlu diingat jika anda ingin membuat style css atau fungsi javascript baru, semua tercompile pada app.css atau app.js karena selain itu, anda harus melakukan manual hapus history lagi.Alternatifnya, file scss pada folder resources/assets/sass/_variable.scss bisa anda gunakan untuk membuat style css yang baru.

ketika project anda di deploy, pastikan anda mengubah  APP_ENV di .env file dari local ke production, agar helper yang dibuat dapat mendeteksi apakah anda sedang pada local development atau production

webpack.mix.js di local dapat anda atur seperti ini:

let 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.setPublicPath(`public`);
mix.react('resources/assets/js/app.js', 'js')
    .sass('resources/assets/sass/app.scss', 'css').version();

 

Enjoy this post? Share It!