Lección 15 de 45 15 min de lectura

Assets con Vite

Vite es el bundler moderno que Laravel usa por defecto para gestionar CSS, JavaScript e imágenes. Ofrece recarga instantánea en desarrollo y optimización automática en producción.

¿Qué es Vite?

Vite es una herramienta de build que reemplaza a Laravel Mix (webpack). Sus ventajas principales:

  • Hot Module Replacement (HMR): Los cambios se reflejan al instante sin recargar la página
  • Arranque instantáneo: No necesita compilar todo al iniciar
  • Build optimizado: Genera bundles pequeños y eficientes para producción

Estructura de archivos

Los assets se organizan en la carpeta resources/:

text
resources/
├── css/
│   └── app.css          # Estilos principales
├── js/
│   ├── app.js           # JavaScript principal
│   └── bootstrap.js     # Configuración inicial
└── views/               # Plantillas Blade

Configuración de Vite

El archivo vite.config.js en la raíz del proyecto configura los entry points:

javascript
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
    plugins: [
        laravel({
            input: [
                'resources/css/app.css',
                'resources/js/app.js',
            ],
            refresh: true,
        }),
    ],
});

Incluir assets en Blade

Usa la directiva @vite en tu layout para cargar CSS y JavaScript:

blade
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Mi App</title>

    @vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
    @yield('content')
</body>
</html>

En desarrollo, @vite conecta con el servidor de Vite. En producción, carga los archivos compilados.

Comandos de desarrollo

Instala las dependencias e inicia el servidor de desarrollo:

bash
# Instalar dependencias npm
npm install

# Iniciar servidor de desarrollo con HMR
npm run dev

# Compilar para producción
npm run build
Ejecutar ambos servidores

Debes tener npm run dev ejecutándose junto con php artisan serve para que funcione el HMR.

Instalar Tailwind CSS

Tailwind es el framework CSS más popular con Laravel. Para instalarlo:

bash
# Instalar Tailwind y sus dependencias
npm install -D tailwindcss postcss autoprefixer

# Crear archivos de configuración
npx tailwindcss init -p

Configura las rutas de tus plantillas en tailwind.config.js:

javascript
/** @type {import('tailwindcss').Config} */
export default {
    content: [
        "./resources/**/*.blade.php",
        "./resources/**/*.js",
        "./resources/**/*.vue",
    ],
    theme: {
        extend: {},
    },
    plugins: [],
}

Añade las directivas de Tailwind en resources/css/app.css:

css
@tailwind base;
@tailwind components;
@tailwind utilities;

Importar imágenes

Las imágenes en resources/ pueden importarse en JavaScript:

javascript
// resources/js/app.js
import logo from '../images/logo.png';

document.getElementById('logo').src = logo;

En Blade, usa el helper Vite::asset():

blade
<img src="{{ Vite::asset('resources/images/logo.png') }}" alt="Logo">

Assets públicos

Los archivos en public/ son accesibles directamente sin procesamiento:

blade
{{-- Archivo en public/images/foto.jpg --}}
<img src="{{ asset('images/foto.jpg') }}" alt="Foto">

{{-- Archivo en public/css/custom.css --}}
<link rel="stylesheet" href="{{ asset('css/custom.css') }}">
resources/ vs public/

Usa resources/ para assets que necesitan procesamiento (Tailwind, imports JS). Usa public/ para archivos estáticos que no cambian.

Múltiples entry points

Puedes tener diferentes bundles para distintas secciones de tu app:

javascript
// vite.config.js
laravel({
    input: [
        'resources/css/app.css',
        'resources/js/app.js',
        'resources/css/admin.css',
        'resources/js/admin.js',
    ],
    refresh: true,
}),
blade
{{-- Layout del admin --}}
@vite(['resources/css/admin.css', 'resources/js/admin.js'])

Importar bibliotecas npm

Instala paquetes npm e impórtalos en tu JavaScript:

bash
npm install axios alpinejs
javascript
// resources/js/app.js
import axios from 'axios';
import Alpine from 'alpinejs';

window.axios = axios;
window.Alpine = Alpine;

Alpine.start();

Alias de rutas

Define alias para simplificar los imports:

javascript
// vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import path from 'path';

export default defineConfig({
    plugins: [
        laravel({
            input: ['resources/css/app.css', 'resources/js/app.js'],
            refresh: true,
        }),
    ],
    resolve: {
        alias: {
            '@': path.resolve(__dirname, 'resources/js'),
            '@components': path.resolve(__dirname, 'resources/js/components'),
        },
    },
});
javascript
// Ahora puedes importar así
import { Modal } from '@components/Modal';
import utils from '@/utils';

Build para producción

Ejecuta el build para generar los assets optimizados:

bash
npm run build

Esto genera archivos en public/build/ con hash en el nombre para cache busting. El manifest en public/build/manifest.json permite a Laravel localizar los archivos correctos.

Ejercicios

Ejercicio 1: Configurar Tailwind

Instala Tailwind CSS en un proyecto Laravel y crea un componente de botón usando clases de Tailwind.

Ver solución
# Instalar
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
{{-- resources/views/components/button.blade.php --}}
@props(['variant' => 'primary'])

@php
$classes = match($variant) {
    'primary' => 'bg-blue-600 hover:bg-blue-700 text-white',
    'secondary' => 'bg-gray-200 hover:bg-gray-300 text-gray-800',
    'danger' => 'bg-red-600 hover:bg-red-700 text-white',
    default => 'bg-blue-600 hover:bg-blue-700 text-white',
};
@endphp

<button {{ $attributes->merge(['class' => "px-4 py-2 rounded font-medium transition $classes"]) }}>
    {{ $slot }}
</button>

Ejercicio 2: Múltiples bundles

Configura Vite para tener un bundle separado para el panel de administración con su propio CSS y JavaScript.

Ver solución
// vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
    plugins: [
        laravel({
            input: [
                'resources/css/app.css',
                'resources/js/app.js',
                'resources/css/admin.css',
                'resources/js/admin.js',
            ],
            refresh: true,
        }),
    ],
});
{{-- resources/views/layouts/admin.blade.php --}}
<!DOCTYPE html>
<html>
<head>
    <title>Admin - @yield('title')</title>
    @vite(['resources/css/admin.css', 'resources/js/admin.js'])
</head>
<body class="admin-layout">
    @yield('content')
</body>
</html>

Ejercicio 3: Alpine.js

Instala Alpine.js e implementa un toggle de visibilidad para mostrar/ocultar un elemento.

Ver solución
npm install alpinejs
// resources/js/app.js
import Alpine from 'alpinejs';

window.Alpine = Alpine;
Alpine.start();
{{-- En una vista --}}
<div x-data="{ open: false }">
    <button @click="open = !open" class="btn">
        <span x-text="open ? 'Ocultar' : 'Mostrar'"></span>
    </button>

    <div x-show="open" x-transition class="mt-4 p-4 bg-gray-100 rounded">
        <p>Contenido que se muestra/oculta</p>
    </div>
</div>

Resumen

  • Vite es el bundler por defecto de Laravel con HMR instantáneo
  • @vite() incluye CSS y JS en tus layouts
  • npm run dev inicia el servidor de desarrollo
  • npm run build compila para producción
  • Tailwind CSS se integra fácilmente con PostCSS
  • Vite::asset() referencia imágenes procesadas
  • asset() referencia archivos en public/

¿Te está gustando el curso?

Tenemos cursos premium con proyectos reales, soporte personalizado y certificado.

Descubrir cursos premium