react-estructura-proyecto-vite

Estructura de un proyecto React

  • 5 min

Una vez que hemos ejecutado el comando de creación de Vite (npm create vite@latest) e instalado las dependencias, nos encontramos ante una estructura de carpetas que, si venís de otros entornos, puede intimidar un poco al principio.

En este artículo vamos a diseccionar la anatomía de un proyecto React.

Finalmente, haremos una “limpieza” (cleanup) para dejar el proyecto listo para empezar a programar desde cero, eliminando el código de ejemplo que trae la plantilla.

Estructura de carpetas

Si abrimos nuestro editor de código (VS Code, por supuesto), veremos algo similar a esto:

mi-app-react/ ├── node_modules/ # Dependencias instaladas (el agujero negro) ├── public/ # Archivos estáticos públicos │ └── vite.svg ├── src/ # Código fuente (donde trabajaremos el 99% del tiempo) │ ├── assets/ # Imágenes, fuentes, etc. importables │ ├── App.css # Estilos del componente App │ ├── App.jsx # El componente principal │ ├── index.css # Estilos globales │ └── main.jsx # Punto de entrada de JavaScript ├── .eslintrc.cjs # Configuración de Linter ├── index.html # Punto de entrada de la aplicación ├── package.json # Manifiesto del proyecto y scripts └── vite.config.js # Configuración de Vite

Public vs Src

La diferencia entre estas dos carpetas:

  • public: Los archivos aquí no son procesados por Vite. Se copian tal cual a la raíz del servidor. Se usa para el favicon.ico, robots.txt o imágenes que no van a cambiar y queremos referenciar por URL absoluta.
  • src: Aquí está nuestro código. Todo lo que esté aquí será procesado, minificado y empaquetado por Vite.

El flujo de ejecución

Para entender cómo arranca React, debemos seguir el hilo desde el navegador. El orden de ejecución es: index.htmlmain.jsxApp.jsx.

El anfitrión: index.html

A diferencia de herramientas antiguas, en Vite el index.html vive en la raíz del proyecto. Es el primer archivo que sirve el servidor.

Si lo abrís, veréis esto:

<!doctype html>
<html lang="en">
  <body>
    <div id="root"></div>
    
    <script type="module" src="/src/main.jsx"></script>
  </body>
</html>
Copied!

Hay dos puntos críticos aquí:

  1. <div id="root"></div>: Este div está vacío. Es el nodo contenedor. React tomará control total de este elemento y renderizará toda la aplicación dentro de él.
  2. <script type="module" ...>: Aquí es donde se carga nuestro código JavaScript. Fijaos que usa type="module", aprovechando los módulos nativos de ES6 modernos.

El arranque: src/main.jsx

Este es el punto de entrada de la lógica. Su misión es conectar React con el HTML.

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import './index.css'

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
)
Copied!

Analicemos lo que ocurre línea a línea:

  1. Importaciones: Trae la librería React y ReactDOM (necesaria para web).
  2. document.getElementById('root'): Busca ese div vacío que vimos en el HTML.
  3. createRoot(...).render(...): Esta es la API moderna de React 18. Crea una “raíz” de React en ese nodo y le dice: “Renderiza el componente <App /> aquí dentro”.

¿Qué es StrictMode? Veréis que <App /> está envuelto en <React.StrictMode>. Es una herramienta de desarrollo que activa comprobaciones extra para detectar errores y efectos secundarios no deseados. Puede hacer renders adicionales y repetir el ciclo de setup/cleanup de los efectos. No afecta en producción, pero si veis console.log duplicados, es por esto.

El componente raíz: src/App.jsx

Finalmente, llegamos a App.jsx. Este es nuestro primer Componente Funcional.

import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'

function App() {
  const [count, setCount] = useState(0)

  return (
    <>
      {/* ... un montón de HTML de ejemplo ... */}
      <h1>Vite + React</h1>
      <div className="card">
        <button onClick={() => setCount((count) => count + 1)}>
          count is {count}
        </button>
      </div>
    </>
  )
}

export default App
Copied!

Como vimos en la introducción, un componente no es más que una función de JavaScript que devuelve JSX (esa sintaxis que parece HTML pero no lo es).

Limpieza inicial

La plantilla de Vite viene genial para ver que todo funciona, pero para nuestro curso queremos un lienzo en blanco. Vamos a limpiar el proyecto.

Limpiar src/App.jsx

Borramos todo el contenido del return y la lógica de estado, dejándolo en su mínima expresión:

// src/App.jsx limpio
function App() {
  return (
    <div>
      <h1>Hola Mundo desde React</h1>
    </div>
  )
}

export default App
Copied!

Eliminar archivos innecesarios

Podemos borrar sin miedo:

  • src/assets/react.svg (no necesitamos el logo).
  • src/App.css (vamos a empezar los estilos desde cero o usar otra estrategia).

Limpiar src/index.css

Podéis borrar todo el contenido para quitar los estilos por defecto de Vite, o dejar solo lo básico (un reset simple). Yo suelo recomendar vaciarlo para que no interfiera con lo que aprendamos luego.

Arreglar las importaciones

Al borrar archivos, main.jsx o App.jsx se quejarán porque intentan importar cosas que ya no existen.

  • En App.jsx: Elimina los import de los logos y del App.css.
  • En main.jsx: Asegúrate de que todo sigue correcto.