Astro 4.10 ya está disponible con variables de entorno type-safe experimentales, así como mejoras a la Container API y los Rewrites.
Los aspectos destacados completos del lanzamiento incluyen:
- Experimental: módulo astro:env
- Rewrite para todos los métodos HTTP
- Embebiendo Astro en frameworks de servidor
- Helpers de la Container API
Para actualizar un proyecto existente, usa la herramienta CLI automatizada @astrojs/upgrade. Alternativamente, actualiza manualmente ejecutando el comando de actualización para tu gestor de paquetes:
# Recommended:npx @astrojs/upgrade
# Manual:npm install astro@latestpnpm upgrade astro --latestyarn upgrade astro --latestExperimental: astro:env
Astro 4.10 introduce un nuevo módulo experimental integrado, astro:env, para facilitar el uso de variables de entorno.
Las variables de entorno te permiten configurar tu app con diferentes valores en diferentes entornos. Pero esto viene con una gran cantidad de complejidad:
- Algunas variables se necesitan en el cliente y otras solo en el servidor.
- Las variables de servidor son a menudo secretos, cosas como claves de API que no quieres que se expongan en el cliente ni que se incrusten en la compilación del servidor (que puede ser vista por cualquiera con acceso a la salida de la compilación).
- Algunas variables son obligatorias para que tu app funcione; mientras que otras son mejoras opcionales.
- Las variables pueden definirse en tu shell, en un archivo
.env, o en la configuración de compilación. - Runtimes como Cloudflare y Deno tienen diferentes APIs para leer variables, creando una diferencia dev/prod con la que tienes que lidiar.
Construimos astro:env para proporcionar más control y estructura sobre las variables de entorno. Gestiona esa complejidad con un schema, directamente en tu configuración:
import { defineConfig, envField } from 'astro/config';
export default defineConfig({ experimental: { env: { schema: { API_PORT: envField.number({ context: 'server', access: 'secret', default: 7000 }), PUBLIC_DASHBOARD_V2: envField.boolean({ context: 'server', access: 'public', default: false }), } } }})Una vez definidas, puedes usar tus variables importándolas desde los módulos astro:env/server y astro:env/client:
import { PUBLIC_DASHBOARD_V2, getSecret } from 'astro:env/server';
if (PUBLIC_DASHBOARD_V2) { const API_PORT = getSecret("API_PORT") // number await fetch(`https://my-secret-api.com:${API_PORT}/v2`)}El módulo del lado del cliente astro:env/client puede usarse en componentes, scripts, o cualquier otro lugar donde ejecutes código de cliente. Por ejemplo, muestra una característica mejorada solo si tienes un feature flag habilitado:
import { SOME_FEATURE_FLAG } from 'astro:env/client';
export default function() { return ( <section> { SOME_FEATURE_FLAG && ( <div id="fancy-enhanced-feature"></div> )}
... </section> )}Cuando necesitas leer una variable que no está definida en tu schema, usa getSecret(), que funciona en cualquier runtime (Cloudflare, Node.js, Deno).
import { getSecret } from 'astro:env/server';
function getServerEndpoint(num: number) { return getSecret(`BACKUP_SERVER_${num}`); // string | undefined}astro:env es una característica experimental y, como con todas las características experimentales, está sujeta a cambios. ¡Gracias a Florian Lefebvre por ser el campeón del RFC y proporcionar la implementación! Deja tu feedback en el RFC para ayudar a guiar su desarrollo mientras esta nueva característica se estabiliza.
Rewrite para todos los métodos HTTP
Rewriting es una nueva característica experimental lanzada en 4.9. La primera versión se dirigía a peticiones GET, el caso más común para un rewrite. Ahora en 4.10, los rewrites pueden usarse para cambiar la ruta de cualquier petición clonando la petición inicial.
Aquí hay un ejemplo de rewriting en middleware para dirigirte a la versión por defecto de una API versionada:
import { defineMiddleware } from 'astro:middleware';
export const onRequest = defineMiddleware(({ request, url }, next) => { if(request.method === 'POST' && url.pathname === '/api') { return next('/api/v2'); }});Al hacer rewriting, se crea una nueva petición apuntando a la nueva URL. Los headers y el body existentes se copian a la nueva petición.
Embebiendo Astro
En 4.9 introdujimos la Container API, una nueva forma de renderizar componentes de Astro fuera del contexto del framework Astro. Nuestro enfoque inicial fue en el testing: usar la container API para probar componentes de Astro. Crea un container, renderiza un componente con container.renderToString(), e inspecciona el HTML generado.
Siempre supimos que la gente querría usar la Container API de otras formas, y no teníamos intención de decepcionar. En 4.10, ahora puedes usar esta API para renderizar cualquier componente construido con astro build, ¡lo que significa que puedes usarlos fuera de un sitio de Astro!
Para demostrar cómo funciona, construimos una app de demo de Astro-en-PHP. ¡No juzguéis el código, expertos en PHP! 😅
La parte del container se ve así:
import * as components from './dist/server/all.mjs';import { renderers } from './dist/server/renderers.mjs';import { manifest } from './dist/server/entry.mjs';import { experimental_AstroContainer as AstroContainer } from 'astro/container';
const container = await AstroContainer.create({ manifest, renderers, resolve(s) { const found = manifest.entryModules[s]; if(found) { return `/astro-project/dist/client/${found}`; } return found; }});
const html = await container.renderToString(components.ReactWrapper);
// Log to the console so that PHP injects the HTML into its page.console.log(html);La Container API es de bajo nivel y refleja lo que Astro hace internamente para renderizar sus propias rutas. Estamos ansiosos por que la comunidad construya integraciones que suavicen las asperezas y proporcione formas más simples de embeber Astro. ¡Pruébalo tú mismo, y muéstranos todos los sitios donde añadas Astro!
Helpers de la Container API
También añadimos algunas funciones helper convenientes para usar la Container API en entornos de Vite (vitest, integraciones de Astro, etc.) al renderizar tus componentes de framework de UI.
Esto significa que ya no necesitas conocer (¡ni averiguar!) las rutas de archivo individuales y directas a los scripts de renderizado de cliente y servidor para cada paquete. La nueva función getContainerRenderer() proporciona los scripts de renderizado apropiados desde nuestros paquetes oficiales de integración de renderizado (@astrojs/react, @astrojs/preact, @astrojs/solid-js, @astrojs/svelte, @astrojs/vue, @astrojs/lit, y @astrojs/mdx). ¡Asegúrate de actualizar tus integraciones al mismo tiempo para tener esta nueva función!
La función loadRenderers() del nuevo módulo virtual astro:container cargará estos renderers desde cada paquete por ti:
import { experimental_AstroContainer as AstroContainer } from 'astro/container';import ReactWrapper from '../src/components/ReactWrapper.astro';import { loadRenderers } from "astro:container";import { getContainerRenderer } from "@astrojs/react";
test('ReactWrapper with react renderer', async () => { const renderers = await loadRenderers([getContainerRenderer()]) const renderers = [ { name: '@astrojs/react', clientEntrypoint: '@astrojs/react/client.js', serverEntrypoint: '@astrojs/react/server.js', }, ]; const container = await AstroContainer.create({ renderers, }); const result = await container.renderToString(ReactWrapper);
expect(result).toContain('Counter'); expect(result).toContain('Count: <!-- -->5');});Este cambio de tipo en renderers también permitirá a entornos sin Vite cargar y pasar los módulos de renderizado manualmente.
Para más información, consulta la documentación de la Container API.
Corrección de Bugs
Como siempre, Astro 4.10 incluye más correcciones de bugs y mejoras menores que no han podido entrar en este post! Consulta las notas del lanzamiento completas para saber más, y mira la presentación completa del lanzamiento 4.10 desde Astro Together! Gracias especiales a Sarah, Erika, Bjorn, Ema, Chris, Florian, y a todos los demás que contribuyeron a este lanzamiento.
