Probando Astro por primera vez

jueves, 29 de julio de 2021

Astro es un nuevo framework para construir sitios web. Para mí, lo más importante es que te permite construir un sitio como si estuvieras usando un framework de JavaScript (y lo estás haciendo), pero el resultado es un sitio estático sin JavaScript. Puedes optar por el JavaScript del lado del cliente según sea necesario, y hay opciones inteligentes para hacerlo. En particular, la curva de aprendizaje es un poco aplanada por el hecho de que es compatible con los componentes que ya puede conocer: React/Preact (JSX), Svelte, Vue, o componentes web. Hoy usare esta tecnología para crear mi portfolio ya que me permite reutilizar el conocimiento que he adquirido trabajando con Vue. Así que si estas leyendo esto es que finalmente me enamore de esta tecnología y esta pagina la esta utilizando.

Empecemos.

Crear un nuevo proyecto es tan fácil como escribir una línea de comandos. También puedes poner el nombre del proyecto al iniciar para crear la carpeta correspondiente:

npm init astro mi-projecto
npm install
npm start

Como era de esperar (al igual que con Next o Nuxt o cualquier otro framework de construcción de sitios web) obtendras un servidor de desarrollo en un puerto local que puedes abrir directamente al terminar la inicialización del proyecto.

Un generador de sitios estáticos con componentes reales de verdad

Esto es algo me parece realmente genial. Me gusta mucho la idea detrás de los generadores de sitios web estáticos, creo que tienen mucho sentido en muchas situaciones. El envío de HTML puro a través del navegador mejora mucho el rendimiento, es un buen movimiento para la eficiencia de CDN, SEO, accesibilidad, etc. El caso es que en el pasado solo teníamos dos opciones para conseguir esto:

  • Un generador de sitios estáticos basado en JavaScript, que genera un sitio “estático”, pero que también envía un paquete de JavaScript (por ejemplo, Nuxt o Gatsby)
  • Un generador de sitios estáticos que se centre más en el HTML y tenga sus propias plantillas/formatos que no sean componentes de JavaScript (por ejemplo, Eleventy o Jekyll)

Sé que hay excepciones, pero esto cubre la gran mayoría del mercado de generadores de sitios.

Así que por eso estoy usando Astro, porque no quiero hacerlo ¡a mi manera!

  • Quiero crear sitios a partir de componentes de JavaScript, porque la sintaxis y las herramientas que los rodean son mejores que cualquier otro sistema de componentes que tengamos ahora mismo.
  • Quiero una salida estática que sea realmente cero-JavaScript (a menos que yo opte manualmente por las cosas).

Eso es lo que ocurre con Astro.

¿Esos componentes?

Astro tambien tiene su propio formato (.astro) y su propia sintaxis la cual es muy convincente porque:

  • Es cómodamente parecido a JSX…
  • …excepto que es mejor porque hace cosas como que el <head> funcione automáticamente
  • El scoping con estilo funciona por defecto desde el principio, a través de una etiqueta normal <style>.
  • El JavaScript “cerrado” se ejecuta durante la construcción (buildtime). Veamos esto a continuación.

Astro files

Ya he mencionado algunas de las partes interesantes de la sintaxis .astro. Básicamente, simplemente me gusta cómo se ven. ¡Tan poca palabrería! Directamente al grano.

// Esto es un componente en Astro

---
export interface Props &#123;
  name: string;
  href: string;
}

const &#123; name, href } = Astro.props;
---
<div>
  <p><a href=&#123;href}>&#123;name}</a></p>
</div>

// El mismo componente en Vue
<template>
  <div>
    <p>Por <a :href="href">&#123;&#123; name }}</a></p>
  </div>
</template>
<script>
export default &#123;
  name: 'Author',
  props: &#123;
    name: &#123;
      type: String,
      required: true
    },
    href: &#123;
      type: String,
      required: true
    }
  }
}
</script>

A simple vista podemos ver la claridad con la que podemos escribir exactamente el mismo componente.

Las “vallas” (---) en la parte superior es donde va el JavaScript inicial, este se ejecutara solo durante el buildtime. Ahí es donde se introducen los datos que vaya a usar este componente, si es que se necesitan claro (se pueden escribir si se quiere, no es obligatorio).

Pages- la forma de enrutamiento

Es tentador decir que Next.js popularizó esto, pero en realidad el concepto es tan antiguo como los sistemas de archivos. Piensa en cómo funciona un servidor Apache clásico. Si tienes un sistema de archivos como:

index.html
/about/
  index.html

En un navegador, puedes visitar http://website.com/about y eso hará que la página index.html esté bajo la carpeta /about. Eso es lo que el enrutamiento es como aquí. Si por el contrario tuviesemos:

/pages/
  index.astro
  about.astro

Tendré una página de inicio así como una página /about/ en mi sitio. Es una forma refrescante de tratar con el enrutamiento - en lugar de tener que construir su propio enrutamiento con x librería de Javascript.

Si quieres hacer eso de que todo el contenido de tu sitio viva en archivos Markdown justo en el repositorio, eres un ciudadano de primera clase.

Creo que esto es muy común para cosas como los blogs y la documentación, especialmente porque ya son objetivos populares para los generadores de sitios estáticos. Y en estos primeros días, creo que vamos a ver un montón de sitios Astro en esa línea mientras la gente espera para ver si está listo para las empresas más grandes. Yo por mi parte decidí mezclar Prismic con la capacidad por defecto de Astro para mostrar contenido escrito en markdown, esta entrada de hecho es un archivo en markdown servido por Prismic como Headless CMS.

Otra forma de usar Markdown es hacer páginas directamente en Markdown. El Markdown también tendrá “vallas” (Frontmatter) donde podras escribir los datos que usaras como propiedades (lo mejor es utilizar un archivo .astro) y pasar estos datos si es necesario.

Astro incluye un componente markdown por defecto para que podamos simplemente introducir el contenido y despreocuparnos. Echa un vistazo a este componente y fíjate lo fácil que es usarlo:

---
import &#123; Markdown } from 'astro/components';
import Author from './Author.vue';

export interface Props &#123;
  title: string;
  description: string;
  author: string;
  heroImage: string;
  publishDate: string;
  content: string;
}

const &#123; title, publishDate, heroImage, author, content } = Astro.props;
const publicationDate = Intl.DateTimeFormat('es-ES', &#123;
      weekday: 'long',
      year: 'numeric',
      month: 'long',
      day: 'numeric',
    }).format(new Date(publishDate))
---

<div class="container mx-auto px-4 md:px-0 bg-gradient-to-br from-gray-100 to-gray-300">
  <article>
    <header>
      &#123;heroImage && <img class="w-full h-auto" loading="lazy" src=&#123;heroImage} />}
      <h1 class="md:px-4 mt-4 text-6xl text-transparent bg-clip-text bg-gradient-to-br from-pink-400 to-blue-600 font-black">&#123;title}</h1>
      <Author class="md:px-4 font-serif" name=&#123;author} href="https://twitter.com/FredKSchott" />
      <p class="md:px-4">&#123;publicationDate}</p>
    </header>
    <main class="md:px-4 mt-10 pb-6 md:mb-12">
      <Markdown content=&#123;content} />
    </main>
  </article>
</div>

Supongo que es un poco raro que Astro soporte todos estos frameworks diferentes por defecto.

He escuchado algunos comentarios sobre que Astro es ineficiente a nivel de npm install ya que tienes que bajar un montón de cosas que probablemente no vas a necesitar o usar. He escuchado algunas críticas sobre que mezclar frameworks de JavaScript es una idea terrible.

Estoy de acuerdo en que es una sensación extraña, pero no me preocupan especialmente las cosas que no están orientadas al usuario. Cuando las cosas suceden sólo durante el proceso de construcción y todo lo que el usuario obtiene es HTML, ¡utiliza todas las librerías que quieras! Si al final cargas los frameworks basados en componentes para hacer cosas interactivas en la página, seguramente tiene sentido limitarlo a uno. Y ya se esta haciendo tanto en el momento de la construcción de la página, tal vez tenga sentido usar algo diseñado para mejorar la interactividad súper ligera en la página ya renderizada.

Estilos

Con Astro, la filosofía parece ser la de soportar una amplia gama de técnicas de procesamiento de estilos populares de inmediato, por defecto, sin volverse loco implementando un pre procesador diferente cada vez.

  • Sólo tienes que importar "./style.css"; hojas de estilo vainilla
  • Utiliza un bloque <style> en cualquier parte de los archivos .astro y el CSS se asignará a ese componente…
  • …que es como los módulos CSS, pero eso sólo es necesario si vas por un archivo .jsx, y si lo haces, es compatible.
  • Las capacidades de estilo de los archivos .svelte y .vue funcionan como se espera.
  • Sass está incorporado, sólo hay que poner <style lang="scss"> en los bloques de estilo donde sea.

En la documentación podrás encontras mas detalles sobre los estilos.

El truco elegante para activar JavaScript de manera optativa

Permítanme citar esto desde el README:

  • <MyComponent /> renderizara una version de HTML puro de MyComponent (por defecto)
  • <MyComponent:load /> renderizara MyComponent cuando la pagina cargue
  • <MyComponent:idle /> usara requestIdleCallback() para renderizar MyComponent tan pronto como se libere el hilo principal.
  • <MyComponent:visible /> usara IntersectionObserver para renderizar MyComponent cuando el elemento este a la vista.

Eso es una danza elegante. HTML por defecto, y usted opta por ejecutar sus componentes del lado del cliente (JavaScript) sólo cuando lo desea específicamente, e incluso entonces, bajo condiciones eficientes.

Conclusión

Estoy enamorado de Astro. La idea inicial era simplemente probarlo pero me gusto tanto que acabe rehaciendo mi portfolio entero y creando mi sistema de blog para publicar entradas, así que ahora mismo estas en una página libre de javascript y con un rendimiento excepcional.

Hay algunas cosas que hecho en falta como un gestor central para el estado de la aplicación, pero muchas de estas faltas vienen de la costumbre de escribir aplicaciones monolíticas en Javascript.

Recomiendo mucho que pruebes esta herramienta, yo la seguiré usando para los proyectos menos complejos pero seguramente en un año Astro tendrá todo lo necesario como para usarlo con todo tipo de proyectos.