Tema
Crear proyecto con Vite
Vas a crear tu primer proyecto React profesional con Vite, la herramienta de construcción más rápida y popular hoy. Entenderás cada archivo que genera, los scripts y cómo dejar tu entorno listo para trabajar.
Concepto
El navegador no entiende JSX ni sabe resolver import React from 'react'. Necesitas una herramienta que:
- En desarrollo: sirva tu código, transforme JSX al vuelo y recargue al instante al guardar (Hot Module Replacement, HMR).
- En producción: empaquete, minifique y optimice todo en archivos estáticos.
Esa herramienta es Vite (se pronuncia "vit", "rápido" en francés). Reemplazó a Create React App, que ya está obsoleto.
¿Y los frameworks?
La documentación oficial de React recomienda frameworks como Next.js o React Router (modo framework) para apps completas. Para aprender React y para muchas SPAs (paneles, dashboards, apps internas), Vite es la opción más simple y directa. Luego darás el salto a Next.js.
Crear el proyecto
Necesitas Node 20.19+ o 22.12+ (instalación).
bash
npm create vite@latest mi-app -- --template react
cd mi-app
npm install
npm run devAbre http://localhost:5173 y verás la página de bienvenida con un contador.
Plantillas disponibles: react (JavaScript), react-ts (TypeScript), react-swc y react-swc-ts (usan SWC, un compilador más rápido). En este curso usamos JavaScript (.jsx); si ya sabes TypeScript, elige react-ts.
Estructura generada
txt
mi-app/
├── node_modules/
├── public/ ← archivos que se copian tal cual (favicon, robots.txt)
│ └── vite.svg
├── src/ ← tu código
│ ├── assets/ ← imágenes que importas desde el código
│ │ └── react.svg
│ ├── App.css
│ ├── App.jsx ← componente principal
│ ├── index.css ← estilos globales
│ └── main.jsx ← punto de entrada
├── .gitignore
├── eslint.config.js ← reglas de calidad de código
├── index.html ← la única página HTML (SPA)
├── package.json
└── vite.config.jsLos archivos clave
html
<!doctype html>
<html lang="es">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Mi app</title>
</head>
<body>
<!-- React dibuja TODA la app dentro de este div -->
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>jsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.jsx'
// Crea la "raíz" de React en el div#root y dibuja <App />
createRoot(document.getElementById('root')).render(
<StrictMode>
<App />
</StrictMode>
)js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()]
})json
{
"name": "mi-app",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"react": "^19.1.0",
"react-dom": "^19.1.0"
},
"devDependencies": {
"@vitejs/plugin-react": "^5.0.0",
"eslint": "^9.30.0",
"vite": "^7.0.0"
}
}react: la librería de componentes.react-dom: conecta React con el DOM del navegador.StrictMode: en desarrollo ejecuta algunas funciones dos veces para detectar errores. No afecta producción.
Scripts
| Comando | Qué hace |
|---|---|
npm run dev | Servidor de desarrollo con HMR |
npm run build | Genera la versión optimizada en dist/ |
npm run preview | Sirve dist/ localmente para probar el build |
npm run lint | Revisa errores con ESLint |
Limpiar y escribir tu primer componente
Borra App.css y el contenido de index.css, y reemplaza App.jsx:
jsx
import { useState } from 'react'
import './App.css'
function App() {
const [nombre, setNombre] = useState('')
return (
<main className="contenedor">
<h1>¡Hola, {nombre || 'mundo'}! 👋</h1>
<input
placeholder="Escribe tu nombre"
value={nombre}
onChange={(e) => setNombre(e.target.value)}
/>
<p>Edita <code>src/App.jsx</code> y guarda para ver los cambios al instante.</p>
</main>
)
}
export default Appcss
.contenedor {
max-width: 600px;
margin: 4rem auto;
padding: 0 1rem;
font-family: system-ui, sans-serif;
text-align: center;
}
.contenedor input {
padding: 0.6rem 1rem;
font-size: 1rem;
border: 1px solid #ccc;
border-radius: 8px;
width: 100%;
max-width: 320px;
}Guarda y verás el cambio sin recargar la página. Escribe en el input y el saludo se actualiza: ya estás usando estado.
Imágenes y archivos
jsx
// Desde src/assets: Vite le pone un nombre con hash (bueno para caché)
import logo from './assets/react.svg'
function Logo() {
return (
<>
<img src={logo} alt="Logo de React" width="80" />
{/* Desde public/: se usa la ruta absoluta */}
<img src="/vite.svg" alt="Logo de Vite" width="80" />
</>
)
}Alias de rutas (@/)
Para evitar ../../../components/Boton:
js
// vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import path from 'node:path'
export default defineConfig({
plugins: [react()],
resolve: {
alias: { '@': path.resolve(import.meta.dirname, 'src') }
}
})json
// jsconfig.json (para que VS Code autocomplete el alias)
{
"compilerOptions": {
"baseUrl": ".",
"paths": { "@/*": ["src/*"] }
}
}jsx
import Boton from '@/components/Boton'Herramientas recomendadas
- React Developer Tools: extensión para Chrome/Firefox/Edge que muestra el árbol de componentes, sus props y estado.
- VS Code con ESLint, Prettier y "ES7+ React snippets" (escribe
rafce+ Tab para crear un componente). - Prettier para formato automático:
bash
npm i -D prettierjson
// .prettierrc
{ "semi": false, "singleQuote": true, "printWidth": 100 }Buena práctica
Nombra los archivos de componentes en PascalCase con extensión .jsx (TarjetaProducto.jsx). Vite sólo transforma JSX en archivos .jsx/.tsx.
Error común
Escribir JSX en un archivo .js. Verás un error como The JSX syntax extension is not currently enabled. Renombra el archivo a .jsx.
Error común
Abrir dist/index.html con doble clic: verás una página en blanco porque los archivos se cargan con rutas absolutas. Usa npm run preview o súbelo a un servidor (lo verás en Despliegue).
Ejercicios
- Crea un proyecto
perfilcon Vite y haz queAppmuestre tu nombre, una foto (ensrc/assets) y una lista de 3 tecnologías que quieres aprender. - Configura el alias
@y mueve el título a un componentesrc/components/Titulo.jsximportado con@/components/Titulo.
Ver solución
jsx
import foto from './assets/foto.jpg'
import Titulo from '@/components/Titulo'
function App() {
const tecnologias = ['React', 'Node.js', 'Next.js']
return (
<main style={{ maxWidth: 500, margin: '3rem auto', fontFamily: 'system-ui' }}>
<Titulo />
<img src={foto} alt="Mi foto" width="120" style={{ borderRadius: '50%' }} />
<h2>Quiero aprender:</h2>
<ul>
{tecnologias.map((t) => (
<li key={t}>{t}</li>
))}
</ul>
</main>
)
}
export default Appjsx
function Titulo() {
return <h1>Hola, soy Erick</h1>
}
export default TituloRecuerda agregar el alias en vite.config.js y jsconfig.json, y reiniciar npm run dev.
Resumen
npm create vite@latest mi-app -- --template reactcrea un proyecto React moderno.index.htmltiene eldiv#root;main.jsxmontaAppconcreateRoot.npm run devpara desarrollar,npm run buildpara producción,npm run previewpara probar el build.- Instala React DevTools y configura alias, ESLint y Prettier desde el inicio.