Proyectos reales con Vite y el ecosistema
💡 🎯 Al terminar esta lección podrás…
- Crear y recorrer un proyecto de React con Vite.
- Organizar componentes en módulos y estilos.
- Entender cómo funcionan las rutas en una SPA.
- Publicar una aplicación en GitHub Pages.
1.Anatomía de un proyecto con Vite
Hasta ahora escribiste todo en un solo cuadro. Un proyecto real separa el código en archivos y carpetas. Esta es la estructura que crea npm create vite@latest mi-app -- --template react:
mi-app/
├── index.html ← la única página; tiene <div id="root"></div>
├── package.json ← dependencias y comandos (dev, build, preview)
├── vite.config.js ← configuración de Vite
├── public/ ← archivos estáticos que se copian tal cual (favicon…)
└── src/
├── main.jsx ← punto de entrada: monta <App /> en #root
├── App.jsx ← tu componente principal
├── App.css ← estilos de App
├── index.css ← estilos globales
├── assets/ ← imágenes y otros recursos importables
└── components/ ← (lo creas tú) un archivo por componente
| Comando | Qué hace |
|---|---|
npm install | Descarga las dependencias a node_modules/ (una vez, o al añadir paquetes). |
npm run dev | Arranca el servidor de desarrollo con recarga instantánea al guardar. |
npm run build | Genera la versión optimizada para publicar en la carpeta dist/. |
npm run preview | Sirve dist/ localmente para probar el resultado final. |
npm install paquete | Añade una biblioteca nueva (se anota en package.json). |
⚠️ Importante · Qué va en Git
Sube a Git el código y package.json, pero no node_modules/ ni dist/. El archivo .gitignore que crea Vite ya los excluye. Cualquiera puede recrear node_modules/ con npm install.
2.Módulos: import y export
Cada archivo es un módulo. Un archivo exporta lo que quiere compartir y otro lo importa. En React lo normal es un componente por archivo, exportado por defecto:
export default function Tarjeta({ titulo, children }) {
return (
<article className="tarjeta">
<h2>{titulo}</h2>
{children}
</article>
);
}
import { useState } from "react"; // exportación con nombre
import Tarjeta from "./components/Tarjeta.jsx"; // exportación por defecto
import "./App.css"; // solo estilos
export default function App() {
const [n, setN] = useState(0);
return (
<Tarjeta titulo="Hola">
<button onClick={() => setN(n + 1)}>Pulsado {n}</button>
</Tarjeta>
);
}
| Tipo | Se exporta | Se importa |
|---|---|---|
| Por defecto (una por archivo) | export default function Tarjeta() {} | import Tarjeta from "./Tarjeta.jsx" (el nombre lo eliges tú) |
| Con nombre (varias) | export function useTema() {} | import { useTema } from "./tema.js" (nombre exacto, entre llaves) |
💡 Consejo · Rutas relativas
./ significa «esta carpeta» y ../ «la carpeta de arriba». Los archivos de React llevan extensión .jsx y conviene escribirla en el import. Los paquetes de npm se importan solo por nombre: import { useState } from "react".
3.Estilos en un proyecto de React
| Opción | Cómo funciona | Cuándo usarla |
|---|---|---|
| CSS global | import "./index.css"; reglas normales para toda la página | Estilos base, variables, tipografía |
| CSS por componente | import "./Tarjeta.css" junto al componente (siguen siendo globales) | Proyectos pequeños, con nombres de clase cuidados |
| CSS Modules | Archivo Tarjeta.module.css; las clases se vuelven únicas por componente | Evitar choques de nombres |
| Utilidades (Tailwind) | Clases como p-4 text-lg directamente en el JSX | Equipos que prefieren velocidad sin escribir CSS |
/* Tarjeta.module.css */
.caja { border: 1px solid #ccc; border-radius: 12px; padding: 1rem; }
.titulo { color: #4f46e5; }
import estilos from "./Tarjeta.module.css";
export default function Tarjeta({ titulo }) {
return (
<article className={estilos.caja}>
<h2 className={estilos.titulo}>{titulo}</h2>
</article>
);
}
Todo lo que aprendiste en el curso de CSS (Flexbox, Grid, variables, diseño responsivo) se aplica igual: React solo cambia cómo organizas los archivos.
4.Varias páginas: el enrutador
Una aplicación de React es una sola página HTML (por eso se llama *SPA*, «aplicación de una página»). Para simular varias pantallas con su propia dirección (/, /productos, /contacto) se usa un enrutador. El estándar es React Router. Para entender qué hace, este es un enrutador de juguete con estado:
// npm install react-router-dom
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
export default function App() {
return (
<BrowserRouter>
<nav>
<Link to="/">Inicio</Link> <Link to="/productos">Productos</Link>
</nav>
<Routes>
<Route path="/" element={<Inicio />} />
<Route path="/productos" element={<Productos />} />
<Route path="/productos/:id" element={<Detalle />} /> {/* parámetro en la URL */}
</Routes>
</BrowserRouter>
);
}
📌 Nota · Por qué Link y no <a>
Un <a href> normal recarga la página completa. Link cambia la pantalla sin recargar, conservando el estado de la aplicación y haciendo la navegación instantánea.
5.Variables de entorno
A veces necesitas valores que cambian según el entorno: la dirección de la API en desarrollo y en producción, por ejemplo. En Vite se guardan en un archivo .env y los nombres deben empezar por VITE_:
VITE_API_URL=https://api.ejemplo.com
const url = import.meta.env.VITE_API_URL;
fetch(url + "/usuarios");
⚠️ Importante · Todo lo que empieza por VITE_ se publica
Esas variables se incluyen en el código final que descarga cualquiera. Sirven para direcciones y opciones, jamás para claves secretas o contraseñas. Y no subas tu .env a Git si contiene datos privados.
6.Publicar tu proyecto en GitHub Pages
El comando npm run build produce la carpeta dist/, que es HTML, CSS y JavaScript estáticos: puedes publicarla en GitHub Pages, Netlify, Vercel o cualquier hosting. En GitHub Pages hay dos detalles clave:
- La ruta base: tu sitio vive en
https://usuario.github.io/mi-app/, no en la raíz. Díselo a Vite conbase: "/mi-app/"envite.config.js. - La publicación automática: un flujo de GitHub Actions construye el proyecto en cada
pushy lo despliega.
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
base: "/mi-app/", // el nombre de tu repositorio
});
name: Publicar en GitHub Pages
on:
push:
branches: [main]
permissions:
pages: write
id-token: write
contents: read
jobs:
desplegar:
runs-on: ubuntu-latest
environment:
name: github-pages
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: 24
- run: npm ci
- run: npm run build
- uses: actions/upload-pages-artifact@v5
with:
path: dist
- uses: actions/deploy-pages@v5
💡 Consejo · Activa Pages con Actions
En el repositorio, ve a Settings → Pages y elige GitHub Actions como origen. Con el archivo anterior, cada vez que hagas push a main tu aplicación se actualiza sola. Repasa la lección de Git y publicación si necesitas el flujo básico.
7.El ecosistema: hacia dónde seguir
| Necesidad | Herramientas habituales |
|---|---|
| Sitios completos (rutas, servidor, SEO) | Next.js, Remix, Astro (frameworks construidos sobre React) |
| Datos del servidor | TanStack Query, SWR |
| Estado global grande | Zustand, Redux Toolkit |
| Formularios complejos | React Hook Form, Zod (validación) |
| Componentes ya hechos | shadcn/ui, Material UI, Chakra UI |
| Tipos y menos errores | TypeScript (casi estándar en equipos) |
| Pruebas | Vitest + Testing Library |
| Animaciones | Framer Motion |
No necesitas aprender todo: elige según el problema que tengas. Lo importante es dominar lo que has visto en este curso, porque todas esas herramientas están construidas sobre ello.
📌 Nota · Una prueba pequeña con Testing Library
Con Vitest y Testing Library pruebas tus componentes como lo haría una persona: render(<Contador />), click en el botón, y compruebas que aparece «1». Es el mismo enfoque que usan los comprobadores de los ejercicios de este curso.
8.Errores frecuentes
- Subir
node_modules/a Git: pesa cientos de megas y es innecesario. - Olvidar
baseal publicar en GitHub Pages: la página queda en blanco y los archivos dan 404. importcon mayúsculas/minúsculas distintas (./tarjeta.jsxvsTarjeta.jsx): funciona en tu PC y falla en el servidor.- Olvidar la extensión
.jsxo la ruta relativa./. - Guardar secretos en
.envcon prefijoVITE_: se publican con el código. - Usar
<a href>para navegar dentro de una SPA: recarga la página y pierde el estado. - Instalar paquetes sin necesidad: cada biblioteca añade peso y mantenimiento.
- Probar solo con
npm run dev: comprueba tambiénnpm run build && npm run previewantes de publicar.
📒 Apuntes para llevar
- Un proyecto con Vite tiene
index.html,src/main.jsx,src/App.jsxypackage.json. - Comandos:
npm install,npm run dev,npm run build,npm run preview. - Un archivo = un módulo; un componente por archivo con
export defaulteimport. - Estilos: CSS global, por componente, CSS Modules o utilidades (Tailwind).
- Una app de React es una SPA; React Router gestiona las pantallas y rutas.
- Variables de entorno
VITE_*se publican: nada de claves secretas. - Para GitHub Pages:
base: "/repositorio/"y un flujo de GitHub Actions. - Sube a Git el código, no
node_modules/nidist/.
9.Glosario
| Término | Significado |
|---|---|
| Vite | Herramienta de desarrollo que compila y sirve proyectos con recarga instantánea. |
| npm | Gestor de paquetes de Node.js para instalar bibliotecas. |
| Módulo | Archivo que exporta e importa código. |
| SPA | Aplicación de una sola página: el navegador no recarga entre pantallas. |
| React Router | Biblioteca estándar de rutas para aplicaciones de React. |
| CSS Modules | Archivos CSS cuyas clases se vuelven únicas para cada componente. |
dist/ | Carpeta con la versión final y optimizada que se publica. |
| GitHub Actions | Sistema de automatización de GitHub (por ejemplo, para construir y desplegar). |
🧠 Comprueba lo aprendido
Elige una respuesta en cada pregunta. Verás al instante si acertaste y por qué.
¿Qué comando genera la versión lista para publicar?
npm run build crea la carpeta dist/ optimizada.
¿Qué NO debe subirse a Git?
node_modules/ se recrea con npm install y es enorme.
¿Por qué hay que configurar base al publicar en GitHub Pages?
Sin base, los archivos se piden a la raíz del dominio y dan 404.
Una variable VITE_CLAVE_SECRETA en .env, ¿es segura?
Las variables VITE_* se publican; los secretos viven en un servidor.
¿Qué ventaja tiene Link de React Router frente a <a>?
Cambia la pantalla dentro de la SPA sin recarga completa.
Tu progreso se guarda en este navegador y se refleja en el índice del curso.
💡 🚀 ¡Ahora te toca!
La práctica fija lo aprendido. Pasa al ejercicio de esta lección.