Saltar al contenido

Migrar desde Create React App (CRA)

La integración de React de Astro proporciona soporte para usar componentes de React dentro de componentes de Astro, ¡incluyendo apps completas de React como Create React App (CRA)!

src/pages/index.astro
---
// Import your root App component
import App from '../cra-project/App.jsx';
---
<!-- Use a client directive to load your app -->
<App client:load />
Mira cómo construir una Single Page Application (SPA) con Astro Externo usando React Router.

Muchas apps “simplemente funcionarán” como apps completas de React cuando las añades directamente a tu proyecto de Astro con la integración de React instalada. Esta es una gran manera de poner tu proyecto en marcha inmediatamente y mantener tu app funcional mientras migras a Astro.

Con el tiempo, puedes convertir tu estructura pieza por pieza a una combinación de componentes .astro y .jsx. ¡Probablemente descubrirás que necesitas menos componentes de React de los que crees!

Aquí hay algunos conceptos clave y estrategias de migración para ayudarte a empezar. ¡Usa el resto de nuestra documentación y nuestra comunidad de Discord para seguir adelante!

Cuando reconstruyas tu sitio de CRA en Astro, notarás algunas diferencias importantes:

  • CRA es una single-page application que usa index.js como raíz de tu proyecto. Astro es un sitio multi-página, e index.astro es tu página de inicio.

  • Los componentes .astro no se escriben como funciones exportadas que devuelven plantillas de página. En su lugar, dividirás tu código en un “code fence” para tu JavaScript y un body exclusivamente para el HTML que generas.

  • orientado a contenido: Astro fue diseñado para mostrar tu contenido y permitirte optar por interactividad solo cuando sea necesario. Una app de CRA existente podría estar construida para alta interactividad del lado del cliente y puede requerir técnicas avanzadas de Astro para incluir elementos que son más difíciles de replicar usando componentes .astro, como dashboards.

Tu app existente puede ser renderizada directamente dentro de un nuevo proyecto de Astro, a menudo sin cambios en el código de tu app.

Usa el comando create astro de tu gestor de paquetes para lanzar el asistente CLI de Astro y seleccionar un nuevo proyecto de Astro “vacío”.

Ventana de la terminal
npm create astro@latest

Añade la integración de React usando el comando astro add de tu gestor de paquetes. Si tu app usa otros paquetes soportados por el comando astro add, como Tailwind y MDX, puedes añadirlos todos con un solo comando:

Ventana de la terminal
npx astro add react
npx astro add react tailwind mdx

Si tu CRA requiere alguna dependencia (p. ej. paquetes NPM), instálalas individualmente usando la línea de comandos o añadiéndolas al package.json de tu nuevo proyecto de Astro manualmente y luego ejecutando un comando de instalación. Ten en cuenta que muchas, pero no todas, las dependencias de React funcionarán en Astro.

Copia los archivos y carpetas fuente de tu proyecto existente de Create React App (CRA) (p. ej. components, hooks, styles, etc.) a una nueva carpeta dentro de src/, manteniendo su estructura de archivos para que tu app siga funcionando. Ten en cuenta que todas las extensiones de archivo .js deben renombrarse a .jsx o .tsx.

No incluyas ningún archivo de configuración. Usarás el propio astro.config.mjs, package.json, y tsconfig.json de Astro.

Mueve el contenido de la carpeta public/ de tu app (p. ej. assets estáticos) a la carpeta public/ de Astro.

  • Directoriopublic/
    • logo.png
    • favicon.ico
  • Directoriosrc/
    • Directoriocra-project/
      • App.jsx
    • Directoriopages/
      • index.astro
  • astro.config.mjs
  • package.json
  • tsconfig.json

Importa el componente raíz de tu app en la sección frontmatter de index.astro, luego renderiza el componente <App /> en tu plantilla de página:

src/pages/index.astro
---
import App from '../cra-project/App.jsx';
---
<App client:load />

Después de añadir tu app existente a Astro, probablemente querrás convertir tu app misma a Astro.

Replicarás un diseño similar basado en componentes usando componentes de plantillas HTML de Astro para tu estructura básica mientras importas e incluyes componentes individuales de React (¡que pueden ser apps enteras!) para islas de interactividad.

Cada migración será diferente y se puede hacer de forma incremental sin interrumpir tu app funcional. Convierte piezas individuales a tu propio ritmo para que cada vez más de tu app esté impulsada por componentes de Astro con el tiempo.

Al convertir tu app de React, decidirás qué componentes de React reescribirás como componentes de Astro. Tu única restricción es que los componentes de Astro pueden importar componentes de React, pero los componentes de React solo deben importar otros componentes de React:

src/pages/static-components.astro
---
import MyReactComponent from '../components/MyReactComponent.jsx';
---
<html>
<body>
<h1>Use React components directly in Astro!</h1>
<MyReactComponent />
</body>
</html>

En lugar de importar componentes de Astro dentro de componentes de React, puedes anidar componentes de React dentro de un solo componente de Astro:

src/pages/nested-components.astro
---
import MyReactSidebar from '../components/MyReactSidebar.jsx';
import MyReactButton from '../components/MyReactButton.jsx';
---
<MyReactSidebar>
<p>Here is a sidebar with some text and a button.</p>
<div slot="actions">
<MyReactButton client:idle />
</div>
</MyReactSidebar>

Puede que te resulte útil aprender sobre Astro islands y componentes de Astro antes de reestructurar tu CRA como un proyecto de Astro.

Compara el siguiente componente de CRA y un componente de Astro correspondiente:

StarCount.jsx
import React, { useState, useEffect } from 'react';
import Header from './Header';
import Footer from './Footer';
const Component = () => {
const [stars, setStars] = useState(0);
const [message, setMessage] = useState('');
useEffect(() => {
const fetchData = async () => {
const res = await fetch('https://api.github.com/repos/withastro/astro');
const json = await res.json();
setStars(json.stargazers_count || 0);
setMessage(json.message);
};
fetchData();
}, []);
return (
<>
<Header />
<p style={{
backgroundColor: `#f4f4f4`,
padding: `1em 1.5em`,
textAlign: `center`,
marginBottom: `1em`
}}>Astro has {stars} 🧑‍🚀</p>
<Footer />
</>
)
};
export default Component;

Aquí hay algunos tips para convertir un componente .js de CRA en un componente .astro:

  1. Usa el JSX devuelto por la función del componente de CRA existente como base para tu plantilla HTML.

  2. Cambia cualquier sintaxis de CRA o JSX a Astro o a estándares web de HTML. Esto incluye {children} y className, por ejemplo.

  3. Mueve cualquier JavaScript necesario, incluyendo declaraciones de importación, a un “code fence” (---). Nota: JavaScript para renderizar contenido condicionalmente a menudo se escribe directamente dentro de la plantilla HTML en Astro.

  4. Usa Astro.props para acceder a cualquier prop adicional que se pasara previamente a tu función de CRA.

  5. Decide si algún componente importado también necesita convertirse a Astro. Puedes mantenerlos como componentes de React por ahora, o para siempre. Pero, puede que eventualmente quieras convertirlos a componentes .astro, ¡especialmente si no necesitan ser interactivos!

  6. Reemplaza useEffect() con declaraciones de importación o import.meta.glob() para consultar tus archivos locales. Usa fetch() para obtener datos externos.

Como Astro devuelve HTML crudo, es posible escribir tests end-to-end usando la salida del paso de build. Cualquier test end-to-end escrito previamente podría funcionar out-of-the-box si has podido igualar el markup de tu sitio CRA. Librerías de testing como Jest y React Testing Library pueden importarse y usarse en Astro para testear tus componentes de React.

Consulta la guía de testing de Astro para más.

Actualiza cualquier importación de archivos para referenciar rutas de archivos relativas exactamente. Esto se puede hacer usando alias de importación, o escribiendo una ruta relativa completa.

Ten en cuenta que los archivos .astro y varios otros tipos de archivo deben importarse con su extensión completa.

src/pages/authors/Fred.astro
---
import Card from '../../components/Card.astro';
---
<Card />

Convierte cualquier instancia de {children} a un <slot /> de Astro. Astro no necesita recibir {children} como una prop de función y renderizará automáticamente el contenido hijo en un <slot />.

src/components/MyComponent.astro
---
---
export default function MyComponent(props) {
return (
<div>
{props.children}
</div>
);
}
<div>
<slot />
</div>

Los componentes de React que pasan múltiples conjuntos de children se pueden migrar a un componente de Astro usando named slots.

Ve más sobre uso específico de <slot /> en Astro.

Obtener datos en un componente de Create React App es similar a Astro, con algunas ligeras diferencias.

Tendrás que eliminar cualquier instancia de un hook de efecto secundario (useEffect) para usar import.meta.glob() o getCollection()/getEntry() para acceder a datos de otros archivos en el código fuente de tu proyecto.

Para obtener datos remotos, usa fetch().

Estas solicitudes de datos se hacen en el frontmatter del componente de Astro y usan top-level await.

src/pages/index.astro
---
import { getCollection } from 'astro:content';
// Get all `src/content/blog/` entries
const allBlogPosts = await getCollection('blog');
// Get all `src/pages/posts/` entries
const allPosts = Object.values(import.meta.glob('../pages/post/*.md', { eager: true }));
// Fetch remote data
const response = await fetch('https://randomuser.me/api/');
const data = await response.json();
const randomUser = data.results[0];
---

Ve más sobre importaciones de archivos locales con import.meta.glob(), consultas con content collections o obtención de datos remotos.

Puede que necesites reemplazar cualquier librería CSS-in-JS (p. ej. styled-components) con otras opciones de CSS disponibles en Astro.

Si es necesario, convierte cualquier objeto de estilo inline (style={{ fontWeight: "bold" }}) a atributos de estilo HTML inline (style="font-weight:bold;"). O, usa una etiqueta <style> de Astro para estilos CSS scoped.

src/components/Card.astro
<div style={{backgroundColor: `#f4f4f4`, padding: `1em`}}>{message}</div>
<div style="background-color: #f4f4f4; padding: 1em;">{message}</div>

Tailwind es soportado después de instalar el plugin de Vite de Tailwind. ¡No se requieren cambios a tu código de Tailwind existente!

Ve más sobre estilos en Astro.

¡Tu CRA podría “simplemente funcionar” en Astro! Pero, es probable que necesites hacer ajustes menores para duplicar la funcionalidad y/o los estilos de tu app existente.

Si no puedes encontrar tus respuestas dentro de esta documentación, visita el Discord de Astro y haz preguntas en nuestro foro de soporte.

Más guías de migración

Contribuir Comunidad Patrocinar