JavaScript
Tutorial JavaScript: Configuración de Bundlers como Vite
JavaScript y los bundlers, herramientas esenciales para optimizar aplicaciones web modernas garantizando modularidad, rendimiento y compatibilidad.
Aprende JavaScript y certifícate¿Qué es y para qué sirve un bundler?
Un bundler es una herramienta de desarrollo que toma todos los archivos y recursos de tu aplicación JavaScript y los empaqueta en uno o varios archivos optimizados para producción. Imagina que tienes decenas o cientos de archivos JavaScript, CSS, imágenes y otros recursos distribuidos en una estructura de carpetas compleja; un bundler los procesa, optimiza y combina para que puedan ser entregados eficientemente al navegador.
Problemas que resuelven los bundlers
En el desarrollo web moderno nos enfrentamos a varios desafíos que los bundlers ayudan a resolver:
- Modularización del código: Al trabajar con aplicaciones complejas, necesitamos dividir nuestro código en módulos independientes.
// math.js
export function sum(a, b) {
return a + b;
}
// app.js
import { sum } from './math.js';
console.log(sum(5, 3)); // 8
Dependencias: Las aplicaciones modernas utilizan numerosas bibliotecas externas que deben gestionarse correctamente.
Compatibilidad entre navegadores: No todos los navegadores soportan las últimas características de JavaScript.
Optimización de recursos: Cargar muchos archivos pequeños es ineficiente debido a las múltiples peticiones HTTP.
Procesamiento de diferentes tipos de archivos: Además de JavaScript, necesitamos manejar CSS, imágenes, fuentes, etc.
Funcionalidades principales de un bundler
Los bundlers modernos ofrecen varias capacidades esenciales:
- Resolución de dependencias: Analizan las importaciones y exportaciones para crear un grafo de dependencias.
// El bundler detecta esta dependencia y la incluye en el paquete final
import { createApp } from 'vue';
Transformación de código: Convierten código moderno en versiones compatibles con navegadores antiguos.
Minificación y optimización: Reducen el tamaño de los archivos eliminando espacios, comentarios y acortando nombres de variables.
// Código original
function calculateTotal(items) {
return items.reduce((total, item) => total + item.price, 0);
}
// Código minificado
function c(i){return i.reduce((t,i)=>t+i.price,0)}
Code splitting: Dividen el código en múltiples paquetes que pueden cargarse bajo demanda.
Hot Module Replacement (HMR): Permiten actualizar módulos en tiempo real durante el desarrollo sin recargar toda la página.
Tree shaking: Eliminan código no utilizado para reducir el tamaño final.
// Biblioteca con múltiples funciones
import { useState } from 'react'; // Solo se incluirá useState en el bundle final
Bundlers populares
Existen varios bundlers en el ecosistema JavaScript, cada uno con sus propias características:
Webpack: El más completo y configurable, aunque con una curva de aprendizaje pronunciada.
Rollup: Especializado en bibliotecas, con excelente soporte para tree shaking.
Parcel: Enfocado en la simplicidad, con configuración cero.
esbuild: Destaca por su velocidad extremadamente rápida.
Vite: Combina un servidor de desarrollo basado en ESM nativo con un proceso de compilación potente.
Beneficios de usar un bundler
La implementación de un bundler en tu flujo de trabajo ofrece ventajas significativas:
Mejor rendimiento: Menos solicitudes HTTP y archivos más pequeños significan cargas más rápidas.
Desarrollo más eficiente: Características como HMR aceleran el ciclo de desarrollo.
Organización del código: Facilita la estructuración del proyecto en módulos reutilizables.
Compatibilidad: Permite usar características modernas de JavaScript sin preocuparse por la compatibilidad.
Optimización automática: Procesos como minificación y compresión se realizan automáticamente.
Flujo de trabajo básico con un bundler
El proceso típico al trabajar con un bundler incluye:
- Configuración: Definir cómo debe procesar los diferentes tipos de archivos.
// Ejemplo simplificado de configuración
export default {
entry: './src/main.js',
output: {
filename: 'bundle.js',
path: '/dist'
}
}
Desarrollo: Utilizar el servidor de desarrollo con recarga en caliente.
Compilación: Generar archivos optimizados para producción.
Despliegue: Publicar los archivos compilados en un servidor web.
¿Cuándo necesitas un bundler?
No todos los proyectos requieren un bundler. Considera usar uno cuando:
- Trabajas con aplicaciones de una sola página (SPA).
- Necesitas gestionar múltiples dependencias externas.
- Utilizas frameworks modernos como React, Vue o Angular.
- Requieres optimización avanzada para producción.
- Trabajas con equipos grandes donde la modularización es crucial.
Para proyectos pequeños o sitios estáticos simples, un bundler podría ser innecesariamente complejo. Sin embargo, para aplicaciones web modernas, se ha convertido en una herramienta prácticamente indispensable en el flujo de desarrollo.
Primeros pasos con Vite
Vite (pronunciado como "veet", que significa "rápido" en francés) es un bundler moderno que destaca por su velocidad extraordinaria y su enfoque en la experiencia de desarrollo. A diferencia de bundlers tradicionales, Vite aprovecha los módulos ES nativos del navegador durante el desarrollo, lo que elimina la necesidad de empaquetar todo el código cada vez que realizas un cambio.
Instalación de Vite
Para comenzar a utilizar Vite, necesitas tener Node.js instalado (versión 14.18+ o 16+). Puedes crear un nuevo proyecto utilizando npm, yarn o pnpm:
# Usando npm
npm create vite@latest my-vite-app
# Usando yarn
yarn create vite my-vite-app
# Usando pnpm
pnpm create vite my-vite-app
Al ejecutar este comando, se iniciará un asistente interactivo que te permitirá seleccionar un framework (como React, Vue, Svelte) o vanilla JavaScript, así como la variante de TypeScript si lo deseas:
✔ Select a framework: › Vanilla
✔ Select a variant: › JavaScript
Estructura del proyecto
Una vez creado el proyecto, obtendrás una estructura básica similar a esta:
my-vite-app/
├── node_modules/
├── public/
│ └── favicon.ico
├── src/
│ ├── main.js
│ └── style.css
├── index.html
├── package.json
└── vite.config.js
Aspectos clave de esta estructura:
- El archivo index.html está en la raíz del proyecto, no en una carpeta pública como en otros bundlers.
- El directorio src/ contiene tu código fuente JavaScript.
- La carpeta public/ almacena archivos estáticos que se copiarán directamente a la carpeta de distribución.
Iniciando el servidor de desarrollo
Para iniciar el servidor de desarrollo, navega a la carpeta del proyecto y ejecuta:
# Navegar al directorio del proyecto
cd my-vite-app
# Instalar dependencias
npm install
# Iniciar servidor de desarrollo
npm run dev
Verás un mensaje indicando que el servidor está funcionando, generalmente en http://localhost:5173
. Al abrir esta URL en tu navegador, podrás ver tu aplicación en funcionamiento.
Modificando el proyecto
Vamos a realizar algunos cambios básicos para entender cómo funciona Vite. Abre el archivo src/main.js
y modifícalo:
// src/main.js
import './style.css'
document.querySelector('#app').innerHTML = `
<h1>Hello Vite!</h1>
<div class="card">
<button id="counter" type="button">Count: 0</button>
</div>
`
// Añadimos funcionalidad al botón
const counterButton = document.querySelector('#counter')
let count = 0
counterButton.addEventListener('click', () => {
count++
counterButton.textContent = `Count: ${count}`
})
Al guardar estos cambios, notarás que la página se actualiza instantáneamente sin recargar completamente, gracias al Hot Module Replacement (HMR) integrado en Vite.
Configuración básica
Vite está diseñado para funcionar con configuración mínima, pero puedes personalizarlo según tus necesidades mediante el archivo vite.config.js
:
// vite.config.js
import { defineConfig } from 'vite'
export default defineConfig({
// Cambiar el puerto del servidor
server: {
port: 3000
},
// Configurar alias para importaciones
resolve: {
alias: {
'@': '/src'
}
}
})
Esta configuración cambia el puerto del servidor a 3000 y crea un alias @
que apunta al directorio src
, permitiéndote importar módulos de forma más limpia:
// En lugar de:
import { helper } from '../../utils/helper'
// Puedes usar:
import { helper } from '@/utils/helper'
Añadiendo dependencias
Puedes instalar y utilizar cualquier paquete npm en tu proyecto Vite. Por ejemplo, añadamos una biblioteca de utilidades como Lodash:
npm install lodash-es
Luego, puedes importarla en tu código:
// src/main.js
import { debounce } from 'lodash-es'
// Crear una función con debounce
const handleSearch = debounce((event) => {
console.log('Searching for:', event.target.value)
}, 300)
// Añadir un campo de búsqueda
document.querySelector('#app').innerHTML += `
<div class="search">
<input type="text" placeholder="Search..." id="search">
</div>
`
document.querySelector('#search').addEventListener('input', handleSearch)
Vite optimizará automáticamente estas importaciones, incluyendo solo el código necesario en el bundle final gracias al tree shaking.
Trabajando con archivos estáticos
Vite maneja diferentes tipos de archivos de forma nativa. Por ejemplo, puedes importar imágenes directamente en tu JavaScript:
// Importar una imagen
import logoUrl from './assets/logo.png'
// Añadirla al DOM
const logo = document.createElement('img')
logo.src = logoUrl
logo.alt = 'Logo'
document.querySelector('#app').appendChild(logo)
También puedes colocar archivos en la carpeta public/
para que sean servidos directamente:
<!-- Referencia a un archivo en public/ -->
<link rel="icon" href="/favicon.ico" />
Uso de CSS y preprocesadores
Vite soporta la importación directa de CSS y varios preprocesadores. Para CSS normal:
// Importar CSS
import './style.css'
Si quieres usar Sass, solo necesitas instalar el preprocesador:
npm install -D sass
Y luego puedes importar archivos .scss directamente:
// Importar SCSS
import './style.scss'
Vite detectará automáticamente el preprocesador instalado y procesará los archivos correctamente.
Plugins básicos
El ecosistema de Vite incluye numerosos plugins que extienden su funcionalidad. Por ejemplo, para añadir soporte para archivos SVG como componentes React:
npm install -D vite-plugin-react-svg
Luego, configúralo en tu vite.config.js
:
import { defineConfig } from 'vite'
import reactSvgPlugin from 'vite-plugin-react-svg'
export default defineConfig({
plugins: [
reactSvgPlugin({
defaultExport: 'component'
})
]
})
Con esta configuración, podrás importar SVGs como componentes React:
import Logo from './assets/logo.svg'
// Usar como componente
function Header() {
return <Logo className="header-logo" />
}
Desarrollo y compilación
Una vez configurado Vite y familiarizado con su entorno de desarrollo, es fundamental entender los comandos esenciales que utilizarás durante el ciclo de vida de tu proyecto. Vite proporciona un conjunto de herramientas optimizadas tanto para el desarrollo ágil como para la compilación eficiente de aplicaciones listas para producción.
Comandos de desarrollo
El flujo de trabajo de desarrollo con Vite se centra en proporcionar una experiencia rápida y fluida. Los comandos principales que utilizarás durante esta fase son:
- Iniciar el servidor de desarrollo:
npm run dev
# o
npx vite
Este comando inicia el servidor de desarrollo con Hot Module Replacement (HMR) activado por defecto. Cuando ejecutas este comando, Vite muestra información útil en la terminal:
VITE v4.4.9 ready in 237 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
➜ press h to show help
- Opciones del servidor de desarrollo:
Puedes personalizar el comportamiento del servidor añadiendo flags al comando:
# Exponer en la red local (útil para pruebas en dispositivos)
npm run dev -- --host
# Cambiar el puerto
npm run dev -- --port 3000
# Abrir automáticamente el navegador
npm run dev -- --open
- Modo de depuración:
Si necesitas información más detallada sobre lo que está ocurriendo internamente:
# Activar logs de depuración
npm run dev -- --debug
Comandos de compilación
Cuando tu aplicación está lista para ser desplegada, necesitas compilarla para producción. Vite optimiza automáticamente tu código, aplicando minificación, tree-shaking y otras técnicas para reducir el tamaño del bundle final.
- Compilar para producción:
npm run build
# o
npx vite build
Este comando genera una versión optimizada de tu aplicación en la carpeta dist/
por defecto. La salida en la terminal te mostrará información sobre el proceso:
vite v4.4.9 building for production...
✓ 94 modules transformed.
dist/index.html 0.49 KiB │ gzip: 0.32 KiB
dist/assets/logo-5d5d9eae.svg 0.14 KiB │ gzip: 0.14 KiB
dist/assets/index-92d87d34.css 1.33 KiB │ gzip: 0.70 KiB
dist/assets/index-d526a0c5.js 142.95 KiB │ gzip: 45.30 KiB
- Personalizar la compilación:
Puedes ajustar el proceso de compilación mediante opciones:
# Especificar un directorio de salida diferente
npm run build -- --outDir my-dist
# Generar reportes de tamaño de bundle
npm run build -- --reportCompressedSize
- Modo de compilación específico:
# Compilar para un entorno específico
npm run build -- --mode staging
Previsualización de la compilación
Antes de desplegar tu aplicación, es recomendable verificar que la versión compilada funciona correctamente. Vite incluye un comando específico para esto:
npm run preview
# o
npx vite preview
Este comando inicia un servidor local que sirve los archivos de la carpeta dist/
, simulando un entorno de producción:
➜ Local: http://localhost:4173/
➜ Network: use --host to expose
La previsualización es útil para detectar problemas que solo aparecen en el código compilado, como rutas incorrectas o problemas de optimización.
Configuración de entornos
Vite permite definir variables de entorno para diferentes contextos de ejecución. Esto es especialmente útil para manejar configuraciones específicas por entorno:
- Archivos de entorno:
Puedes crear diferentes archivos para cada entorno:
.env # Variables para todos los entornos
.env.local # Variables locales (ignoradas en git)
.env.development # Solo para desarrollo
.env.production # Solo para producción
Ejemplo de un archivo .env.production
:
VITE_API_URL=https://api.example.com
VITE_DEBUG_MODE=false
- Acceso a variables de entorno:
En tu código, puedes acceder a estas variables mediante el objeto import.meta.env
:
// Solo las variables con prefijo VITE_ son accesibles
const apiUrl = import.meta.env.VITE_API_URL;
fetch(`${apiUrl}/users`)
.then(response => response.json())
.then(data => console.log(data));
Optimización avanzada
Durante la compilación, Vite aplica varias optimizaciones automáticas, pero también puedes configurar aspectos específicos:
- División de código (code splitting):
Vite implementa automáticamente code splitting basado en los puntos de entrada y las importaciones dinámicas:
// Esta importación se cargará bajo demanda
const loadFeature = async () => {
const { setupFeature } = await import('./features/special-feature.js');
setupFeature();
};
document.querySelector('#load-feature').addEventListener('click', loadFeature);
- Pre-empaquetado de dependencias:
Vite pre-empaqueta las dependencias para mejorar el rendimiento:
// vite.config.js
export default defineConfig({
optimizeDeps: {
include: ['lodash-es', 'vue'], // Dependencias a pre-empaquetar
exclude: ['slow-dependency'] // Dependencias a excluir
}
})
- Configuración de rollup:
Puedes ajustar la configuración de Rollup (el bundler que Vite usa para producción):
// vite.config.js
export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks: {
vendor: ['react', 'react-dom'],
utils: ['./src/utils/format.js', './src/utils/helpers.js']
}
}
}
}
})
Integración con herramientas de CI/CD
Para automatizar el proceso de compilación en entornos de integración continua, puedes utilizar los comandos de Vite en tus scripts:
// package.json
{
"scripts": {
"build:ci": "vite build --mode production",
"test:e2e": "start-server-and-test 'vite preview' http://localhost:4173 'cypress run'"
}
}
Un flujo típico en un pipeline de CI podría ser:
# Ejemplo simplificado de GitHub Actions
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
- run: npm ci
- run: npm run build:ci
- name: Archive production artifacts
uses: actions/upload-artifact@v3
with:
name: dist
path: dist
Solución de problemas comunes
Durante el desarrollo y compilación pueden surgir algunos problemas habituales:
- Errores de importación:
# Limpiar la caché de Vite
npm run dev -- --force
- Problemas con dependencias:
# Reconstruir el directorio node_modules
rm -rf node_modules
npm install
- Verificar la compilación en modo debug:
# Ver más información sobre el proceso de build
npm run build -- --debug
Estos comandos esenciales te permitirán aprovechar al máximo las capacidades de Vite tanto en desarrollo como en la preparación de tu aplicación para producción, manteniendo un flujo de trabajo eficiente y optimizado.
Ejercicios de esta lección Configuración de Bundlers como Vite
Evalúa tus conocimientos de esta lección Configuración de Bundlers como Vite con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
Funciones flecha
Polimorfismo
Array
Transformación con map()
Gestor de tareas con JavaScript
Manipulación DOM
Funciones
Funciones flecha
Async / Await
Creación y uso de variables
Excepciones
Promises
Funciones cierre (closure)
Herencia
Herencia
Estructuras de control
Selección de elementos DOM
Modificación de elementos DOM
Filtrado con filter() y find()
Funciones cierre (closure)
Funciones
Mapas con Map
Reducción con reduce()
Callbacks
Manipulación DOM
Promises
Async / Await
Eventos del DOM
Async / Await
Promises
Filtrado con filter() y find()
Callbacks
Creación de clases y objetos Restaurante
Reducción con reduce()
Filtrado con filter() y find()
Reducción con reduce()
Conjuntos con Set
Herencia de clases
Eventos del DOM
Clases y objetos
Modificación de elementos DOM
Mapas con Map
Introducción a JavaScript
Funciones
Tipos de datos
Clases y objetos
Array
Conjuntos con Set
Array
Encapsulación
Clases y objetos
Uso de operadores
Uso de operadores
Estructuras de control
Excepciones
Transformación con map()
Funciones flecha
Selección de elementos DOM
Encapsulación
Mapas con Map
Creación y uso de variables
Polimorfismo
Tipos de datos
Estructuras de control
Todas las lecciones de JavaScript
Accede a todas las lecciones de JavaScript y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Introducción A Javascript
Introducción Y Entorno
Tipos De Datos
Sintaxis
Variables
Sintaxis
Operadores
Sintaxis
Estructuras De Control
Sintaxis
Funciones
Sintaxis
Funciones Cierre (Closure)
Sintaxis
Arrays Y Métodos
Estructuras De Datos
Conjuntos Con Set
Estructuras De Datos
Mapas Con Map
Estructuras De Datos
Funciones Flecha
Programación Funcional
Filtrado Con Filter() Y Find()
Programación Funcional
Transformación Con Map()
Programación Funcional
Reducción Con Reduce()
Programación Funcional
Clases Y Objetos
Programación Orientada A Objetos
Excepciones
Programación Orientada A Objetos
Encapsulación
Programación Orientada A Objetos
Herencia
Programación Orientada A Objetos
Polimorfismo
Programación Orientada A Objetos
Manipulación Dom
Dom
Selección De Elementos Dom
Dom
Modificación De Elementos Dom
Dom
Eventos Del Dom
Dom
Callbacks
Programación Asíncrona
Promises
Programación Asíncrona
Async / Await
Programación Asíncrona
Certificados de superación de JavaScript
Supera todos los ejercicios de programación del curso de JavaScript y obtén certificados de superación para mejorar tu currículum y tu empleabilidad.
En esta lección
Objetivos de aprendizaje de esta lección
- Comprender el concepto y la función de los bundlers en el desarrollo web.
- Identificar problemas que resuelven como modularización del código y compatibilidad entre navegadores.
- Familiarizarse con las capacidades esenciales de los bundlers, como la minificación y el tree shaking.
- Conocer bundlers populares como Webpack, Rollup, Parcel, esbuild y Vite.
- Reconocer los beneficios de implementar un bundler en el flujo de trabajo.
- Seguir un flujo de trabajo básico desde la configuración hasta el despliegue de aplicaciones.
- Decidir cuándo es necesario utilizar un bundler en un proyecto.