Aplikasi web tidak hanya terdiri dari PHP. Halaman kita juga membutuhkan CSS agar rapi, JavaScript agar interaktif, plus gambar dan font. Di Laravel, semua berkas tersebut disebut asset — dan cara kita mengelolanya menentukan kenyamanan pengembangan sekaligus performa halaman produksi. Chapter ini membedah evolusi pengelolaan aset di Laravel: dari berkas mentah di folder public/, melewati era Laravel Mix, sampai Vite yang menjadi standar saat ini. Setelah memahami masalah yang diselesaikan tiap generasi, directive @vite pada chapter berikutnya akan terasa logis, bukan sekadar mantra sihir.
Dulu: Semua Berkas Ada di public #
Cara paling purba adalah menaruh aset langsung di public/ dan merujuknya lewat helper asset(). Folder public adalah document root aplikasi — apa pun di dalamnya dilayani langsung oleh web server tanpa lewat route Laravel. Sebuah berkas public/robots.txt dan public/js/app.js bisa diakses browser apa adanya:
use Illuminate\Support\Facades\Route;
Route::get('/latihan-aset', function () {
return asset('js/app.js') . PHP_EOL . asset('robots.txt');
});Output yang Dihasilkan:
http://localhost:8000/js/app.js
http://localhost:8000/robots.txtHelper asset() hanya membangun URL absolut dari path relatif — ia tidak memproses berkasnya sama sekali. Pada era ini, layout Blade kita menuliskan tag HTML manual:
<link rel="stylesheet" href="{!! asset('css/app.css') !!}">
<script src="{!! asset('js/app.js') !!}"></script>Pendekatan ini bekerja, dan masih sah dipakai untuk berkas yang memang statis. Masalahnya muncul begitu JavaScript kita membesar dan mulai butuh tooling modern.
Masalah yang Tidak Bisa Diselesaikan Folder Statis #
| Masalah | Dampak di folder public mentah |
|---|---|
| Modularitas | Tidak ada import antar-berkas; semua digabung manual lewat urutan <script> |
| Minifikasi | Berkas dikirim apa adanya — komentar dan indentasi ikut terkirim ke pengguna |
| Cache busting | Nama berkas tetap sama; browser memakai versi lama setelah kita mengubah kode |
| Preprocessing | Sass/Less/TypeScript harus dikompilasi manual sebelum masuk public |
| Dependency npm | Package dari node_modules harus disalin dulu ke public agar bisa dirujuk |
Cache busting adalah contoh yang paling terasa. Karena browser menyimpan salinan app.js, perubahan kode tidak terlihat oleh pengguna lama. Solusi jamannya manual dan rapuh: asset('js/app.js?v=2') — dan seseorang harus ingat menaikkan angka versi setiap rilis. PHP sama sekali tidak tahu isi berkas JavaScript, jadi tidak ada yang bisa mengotomatiskannya dari sisi Blade.
Evolusi: Mix ke Vite #
Laravel lama menjawab masalah ini dengan Laravel Mix — pembungkus webpack dengan API mix.js(...) yang dijalankan lewat npm run dev. Mix menyelesaikan minifikasi, hashing, dan preprocessing, tetapi lambat: setiap kali kita menyimpan berkas, seluruh bundle dikompilasi ulang dalam hitungan detik bahkan puluhan detik. Sejak Laravel 9.19 (rilis 13 Juli 2022), Laravel beralih ke Vite
, dan Laravel 13 yang kita pakai sudah memakainya secara bawaan dengan vite v8.
Dua perbedaan mendasar menjadikan Vite terasa cepat. Pertama, saat pengembangan Vite tidak membundling sama sekali — browser meminta tiap modul secara individual, sehingga menyimpan satu berkas hanya memicu pembaruan modul itu (Hot Module Replacement, atau HMR). Kedua, bundling penuh hanya terjadi saat rilis lewat npm run build, yang menghasilkan berkas ter-minifikasi dengan content hash pada namanya seperti app-BvRk9kiK.js. Hash berubah otomatis setiap kali isi berkas berubah, sehingga cache busting tidak lagi urusan kita.
Membagi Peran: resources vs public #
Dengan Vite, rumah aset berpindah. Kode sumber CSS/JS yang akan diproses hidup di resources/, sedangkan public/ tetap untuk berkas yang memang butuh dilayani mentah:
| Lokasi | Isi | Diproses? |
|---|---|---|
resources/css/, resources/js/ | Kode sumber CSS/JS milik aplikasi | Ya, lewat Vite |
resources/images/ | Gambar yang diimpor dari JS/CSS | Ya, di-hash otomatis |
node_modules/ | Dependency package npm | Ya, ikut terbundling |
public/ | favicon.ico, robots.txt, unduhan, gambar yang dirujuk lewat asset() | Tidak |
Blade tidak lagi memanggil asset() untuk aset yang diproses Vite. Sebagai gantinya, satu directive @vite(['resources/css/app.css', 'resources/js/app.js']) mengurus semuanya — URL yang benar untuk mode pengembangan maupun produksi, lengkap dengan versi ter-hash. Bagaimana directive itu bekerja, bagaimana menjalankan dev server, dan apa isi folder public/build hasil npm run build adalah materi chapter berikutnya tentang Vite Integration
.