Topik ini membahas cara Laravel mengelola aset frontend melalui Vite, yaitu alat build yang memproses CSS dan JavaScript menjadi berkas siap produksi. Pembahasan mencakup dua berkas konfigurasi utama proyek, directive @vite pada template Blade, mode pengembangan dengan hot reload, serta build untuk produksi. Seluruh perintah dijalankan pada aplikasi catatan sehingga keluaran asli setiap langkah dapat diperiksa.
Peran Vite pada proyek Laravel#
Aset frontend modern jarang berupa satu berkas CSS atau JavaScript yang disalin begitu saja ke browser. Tailwind CSS perlu dikompilasi, JavaScript perlu diperkecil, dan nama berkas perlu diberi hash agar perubahan tidak terjebak cache browser. Vite adalah build tool yang mengerjakan ketiganya, dan kerangka proyek Laravel menyertakan konfigurasi Vite sebagai bagian bawaannya sehingga tidak ada pemasangan manual yang diperlukan.
Dua berkas menjadi pusat integrasi ini. Berkas package.json mencatat dependensi JavaScript beserta perintah npm yang tersedia, sedangkan vite.config.js menetapkan cara Vite memproses proyek. Isi keduanya pada aplikasi catatan adalah berikut.
{
"$schema": "https://www.schemastore.org/package.json",
"private": true,
"type": "module",
"scripts": {
"build": "vite build",
"dev": "vite"
},
"devDependencies": {
"@tailwindcss/vite": "^4.0.0",
"concurrently": "^10.0.3",
"laravel-vite-plugin": "^3.1",
"tailwindcss": "^4.0.0",
"vite": "^8.0.0"
},
"optionalDependencies": {
"@laravel/multiplex": "^0.4.1"
}
}Bagian scripts mendefinisikan dua perintah yang digunakan sepanjang topik ini, yaitu npm run dev untuk mode pengembangan dan npm run build untuk produksi. Konfigurasi Vite bawaan proyek adalah berikut.
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import { bunny } from 'laravel-vite-plugin/fonts';
import tailwindcss from '@tailwindcss/vite';
export default defineConfig({
plugins: [
laravel({
input: ['resources/css/app.css', 'resources/js/app.js'],
refresh: true,
fonts: [
bunny('Instrument Sans', {
weights: [400, 500, 600],
}),
],
}),
tailwindcss(),
],
server: {
watch: {
ignored: ['**/storage/framework/views/**'],
},
},
});Plugin laravel-vite-plugin menghubungkan Vite dengan Laravel. Kunci input mendaftarkan entry point, yaitu berkas sumber yang menjadi titik masuk build, sedangkan refresh: true membuat browser memuat ulang halaman ketika template Blade berubah. Dependensi yang tercantum pada devDependencies baru tersedia setelah penginstalan, dan langkah tersebut memerlukan Node.js serta npm yang terpasang di sistem.
# memeriksa versi Node.js dan npm yang terpasang
node --version
npm --versionv24.22.2
11.19.1Directive @vite dan cara kerjanya#
Template Blade tidak menuliskan tag link dan script secara manual. Directive @vite menerima daftar entry point dan menghasilkan seluruh tag yang dibutuhkan. Layout berikut memuat CSS dan JavaScript aplikasi catatan dengan satu baris directive.
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Aplikasi catatan</title>
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
<main class="mx-auto max-w-2xl p-6">
{{ $slot }}
</main>
</body>
</html>Saat template dikompilasi, directive tersebut diubah menjadi pemanggilan objek Vite milik framework.
// tidak-dijalankan
<?php echo app('Illuminate\Foundation\Vite')(['resources/css/app.css', 'resources/js/app.js']); ?>
Objek Vite menentukan URL setiap aset dari dua sumber yang berlaku menurut kondisi. Apabila berkas public/hot ada, dev server Vite sedang berjalan dan URL merujuk ke server itu. Apabila berkas tersebut tidak ada, URL dibaca dari public/build/manifest.json, yaitu peta antara entry point dan berkas hasil build. Apabila manifest tidak ditemukan, resolusi gagal dengan error yang jelas. Contoh berikut meminta aset dari direktori build-uji yang memang tidak pernah ada, sehingga error-nya dapat direproduksi kapan saja tanpa menyentuh direktori build milik proyek.
# merender directive @vite saat manifest build tidak ditemukan
cd ~/aplikasi-catatan
php artisan tinker --execute='
use Illuminate\Foundation\Vite;
echo app(Vite::class)(["resources/css/app.css"], "build-uji") . PHP_EOL;
' Illuminate\Foundation\ViteManifestNotFoundException Vite manifest not found at: public/build-uji/manifest.json.ViteManifestNotFoundException semacam ini juga muncul pada proyek yang baru disalin dari repository tanpa langkah npm apa pun, karena public/build/manifest.json memang belum ada sebelum build dijalankan. Perbaikannya dibahas pada bagian akhir topik.
Mode pengembangan dengan hot reload#
Pengembangan dimulai dengan menginstal dependensi JavaScript yang tercantum pada package.json, lalu menjalankan dev server Vite.
# tidak-dijalankan
# menginstal dependensi JavaScript lalu menjalankan dev server Vite
cd ~/aplikasi-catatan
npm install
npm run devDev server berjalan terus sampai dihentikan dengan Ctrl+C, sehingga perintahnya tidak dieksekusi ulang di sini. Selama server aktif, Vite menulis URL dev server ke berkas public/hot dan Laravel menggunakan URL itu untuk seluruh tag aset. Keluaran sungguhan dari satu percobaan pemasangan dependensi dan pengoperasian server pada salinan proyek adalah berikut.
added 96 packages, and audited 103 packages in 16s
41 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
> dev
> vite
VITE v8.3.5 ready in 252 ms
➜ Local: http://localhost:5173/Dengan dev server aktif, pemanggilan directive yang sama menghasilkan tag yang merujuk langsung ke berkas sumber.
# tidak-dijalankan
# merender tag @vite selama dev server berjalan
cd ~/aplikasi-catatan
php artisan tinker --execute='
use Illuminate\Foundation\Vite;
echo app(Vite::class)(["resources/css/app.css", "resources/js/app.js"]) . PHP_EOL;
'Keluaran render dari percobaan dengan dev server aktif adalah berikut.
<script type="module" src="http://[::1]:5173/@vite/client"></script><link rel="stylesheet" href="http://[::1]:5173/resources/css/app.css" /><script type="module" src="http://[::1]:5173/resources/js/app.js"></script>Tag pertama memuat @vite/client, yaitu skrip kecil yang membuka koneksi ke dev server. Dua tag berikutnya memuat CSS dan JavaScript langsung dari berkas sumber tanpa proses build. Ketika berkas sumber disimpan, browser menerima modul terbaru hampir seketika tanpa muat ulang halaman, mekanisme yang disebut hot module replacement. Mode inilah yang dimaksud hot reload pada judul bagian ini.
Build untuk produksi#
Untuk lingkungan produksi, aset dibangun dengan perintah npm run build. Vite mengompilasi setiap entry point, memperkecil berkasnya, memberi hash pada nama berkas, lalu menulis hasilnya ke public/build bersama manifest-nya.
# tidak-dijalankan
# membangun aset untuk lingkungan produksi
cd ~/aplikasi-catatan
npm run buildKeluaran sungguhan dari satu percobaan build pada salinan proyek adalah berikut. Baris kedua adalah catatan plugin font opsional, bukan error.
vite v8.3.5 building client environment for production...
[plugin laravel:fonts] Optimized font fallbacks require the optional "fontaine" package. Install it, or set "optimizedFallbacks: false" on your fonts to disable the feature.
transforming...
✓ 3 modules transformed.
rendering chunks...
computing gzip size...
public/build/manifest.json 1.47 kB │ gzip: 0.33 kB
public/build/fonts-manifest.json 5.74 kB │ gzip: 0.71 kB
public/build/assets/instrument-sans-400-normal-DRC__1Mx.woff2 16.86 kB
public/build/assets/instrument-sans-500-normal-Dk9ku72i.woff2 17.23 kB
public/build/assets/instrument-sans-600-normal-B7fBEWYG.woff2 17.40 kB
public/build/assets/instrument-sans-400-normal-D1W7dsQl.woff 21.24 kB
public/build/assets/instrument-sans-500-normal-Z6ESRlEs.woff 21.65 kB
public/build/assets/instrument-sans-600-normal-B9e8oLYv.woff 21.67 kB
public/build/assets/fonts-C9MNnjVw.css 2.35 kB │ gzip: 0.38 kB
public/build/assets/app-XwIzoTLe.css 53.89 kB │ gzip: 11.56 kB
public/build/assets/app-BvRk9kiK.js 0.00 kB │ gzip: 0.02 kB
✓ built in 234msBerkas manifest.json memetakan setiap entry point ke berkas hasil build-nya. Dua entri pertamanya adalah berikut.
{
"resources/css/app.css": {
"file": "assets/app-XwIzoTLe.css",
"name": "app",
"names": [
"app.css"
],
"src": "resources/css/app.css",
"isEntry": true
},
"resources/js/app.js": {
"file": "assets/app-BvRk9kiK.js",
"name": "app",
"src": "resources/js/app.js",
"isEntry": true
}
}Dengan manifest tersedia, directive @vite menghasilkan tag yang merujuk berkas ber-hash tersebut.
# tidak-dijalankan
# merender tag @vite setelah build produksi selesai
cd ~/aplikasi-catatan
php artisan tinker --execute='
use Illuminate\Foundation\Vite;
echo app(Vite::class)(["resources/css/app.css", "resources/js/app.js"]) . PHP_EOL;
'Keluaran render dari percobaan setelah build adalah berikut.
<link rel="preload" as="style" href="http://localhost:8000/build/assets/app-XwIzoTLe.css" /><link rel="modulepreload" as="script" href="http://localhost:8000/build/assets/app-BvRk9kiK.js" /><link rel="stylesheet" href="http://localhost:8000/build/assets/app-XwIzoTLe.css" /><script type="module" src="http://localhost:8000/build/assets/app-BvRk9kiK.js"></script>Tag yang dihasilkan mencakup pemuatan awal (preload) untuk CSS dan JavaScript, tag stylesheet, dan tag script bertipe module. Nama berkas seperti app-XwIzoTLe.css berubah setiap kali isinya berubah, sehingga browser tidak menyajikan versi lama dari cache. Alur dari berkas sumber hingga tag HTML dirangkum pada diagram berikut.
Kesalahan umum#
Kesalahan pertama adalah men-deploy aplikasi tanpa menjalankan npm run build atau tanpa mengunggah direktori public/build. Setiap halaman yang memuat @vite gagal dengan ViteManifestNotFoundException, persis seperti demo pada bagian directive. Perbaikannya adalah menambahkan langkah build pada proses deploy, sebelum aplikasi menerima permintaan.
Kesalahan kedua adalah menyisakan berkas public/hot di server produksi. Berkas tersebut dibuat oleh dev server dan sering tertinggal ketika proses pengembangan dihentikan secara mendadak. Selama berkas itu ada, semua halaman merujuk aset ke http://[::1]:5173, alamat yang hanya berlaku di komputer pengembang, sehingga halaman produksi kehilangan CSS dan JavaScript-nya.
Kesalahan ketiga adalah menyunting berkas hasil build di public/build secara langsung, misalnya memperbaiki warna pada app-XwIzoTLe.css. Perubahan tersebut hilang pada build berikutnya karena seluruh direktori ditulis ulang. Sumber kebenaran tetap berada di resources/, dan setiap perbaikan diakhiri dengan build ulang.
Ringkasan#
- Laravel memaketkan Vite melalui
package.jsondanvite.config.js, dengan pluginlaravel-vite-pluginsebagai penghubungnya dan dua entry point standar, yaituresources/css/app.csssertaresources/js/app.js. - Directive
@vitemenghasilkan tag HTML dari berkaspublic/hotsaat dev server aktif, atau daripublic/build/manifest.jsonsaat produksi. npm run devmemberi hot reload untuk pengembangan, sedangkannpm run buildmenghasilkan berkas ber-hash beserta manifest untuk produksi.- Error
ViteManifestNotFoundExceptionberarti manifest yang dituju tidak ada, dan perbaikannya adalah menjalankan build atau memeriksa direktori build yang diminta.
Referensi#
- Vite — Laravel
— Dokumentasi resmi integrasi Vite pada Laravel, termasuk directive
@vite, mode pengembangan, dan build produksi. - Frontend — Laravel — Gambaran umum tumpukan frontend bawaan Laravel dan perannya di dalam ekosistem.
- Getting Started — Vite — Dokumentasi resmi Vite mengenai dev server dan proses build.