Blog de ingeniería de web.dev n.o 1: Cómo creamos el sitio y usamos componentes web

Esta es la primera entrada en el blog de ingeniería de web.dev. En los próximos meses, esperamos compartir estadísticas prácticas de nuestro trabajo, así que presta atención a las publicaciones con la etiqueta de blog sobre ingeniería. Aquí abordaremos el proceso de compilación para nuestro sitio estático y el (opcional) JavaScript detrás de nuestros componentes web.

web.dev proporciona contenido sobre cómo crear experiencias web modernas y te permite medir el rendimiento de tu sitio. Es posible que los usuarios expertos hayan notado que nuestra página de Medición es solo una interfaz para Lighthouse, que también está disponible en las Herramientas para desarrolladores de Chrome. Acceder a web.dev te permite ejecutar auditorías de Lighthouse regulares en tu sitio para que puedas ver cómo cambia su puntuación con el tiempo. Volveré a visitar la página Medición más adelante, ya que creemos que es bastante especial. 🎊

Introducción

En esencia, web.dev es un sitio estático que se genera a partir de una colección de archivos de Markdown. Elegimos usar Eleventy porque es una herramienta pulida y extensible que facilita la conversión de Markdown en HTML.

También usamos paquetes modernos de JavaScript que solo publicamos en navegadores que admiten type="module", incluidos async y await. También utilizamos de forma alegre funciones que son compatibles con los navegadores perdurables, pero no por una minoría de las versiones anteriores. Como somos un sitio estático, simplemente no se requiere JavaScript para leer nuestro contenido.

Una vez que se completa el proceso de compilación (que implica generar código HTML estático y empaquetar JavaScript con Rollup), se puede alojar web.dev con un servidor estático simple para realizar pruebas. El sitio es casi completamente estático, pero tenemos algunas necesidades especiales que aún nos benefician de un servidor Node.js personalizado. Esto incluye los redireccionamientos para dominios no válidos y el código para analizar el idioma preferido de un usuario para una próxima función de internacionalización.

Generación estática

Cada página de web.dev se escribe en Markdown. Todas las páginas incluyen la aspecto principal, que describe los metadatos de cada publicación. Estos metadatos se transfieren al diseño de cada página y se crean encabezados, etiquetas, etc. Por ejemplo:

---
layout: post
title: What is network reliability and how do you measure it?
authors:
  - jeffposnick
date: 2018-11-05
description: |
  The modern web is enjoyed by a wide swath of people…
---

The modern web is enjoyed by a wide swath of [people](https://www.youtube.com/watch?v=dQw4w9WgXcQ), using a range of different devices and types of network connections.

Your creations can reach users all across the world...

Esta interfaz nos permite definir propiedades arbitrarias como autores, fecha de publicación y etiquetas. Eleventy expone de manera conveniente el tema principal como datos en casi todos los complementos, las plantillas y otros contextos en los que nos gustaría hacer algo inteligente. El objeto de datos también contiene lo que Eleven describe como la cascada de datos: una variedad de datos extraídos de cada página individual, el diseño que usa la página y los datos que se encuentran en la estructura jerárquica de carpetas.

Cada diseño único describe un tipo diferente de contenido y puede heredar de otros diseños. En web.dev, usamos esta función para enmarcar correctamente diferentes tipos de contenido (como publicaciones y codelabs) y, al mismo tiempo, compartir un diseño HTML de nivel superior.

Colecciones

Eleventy ofrece una manera programática de crear colecciones arbitrarias de contenido. Esto nos permite compilar compatibilidad con la paginación y generar páginas virtuales (páginas que no tienen un archivo de Markdown que coincida en el disco) para los autores de publicaciones. Por ejemplo, construimos nuestras páginas de autores con una plantilla que contiene una expresión para su vínculo permanente (de modo que la plantilla se vuelva a renderizar para cada autor) y una colección de copia de seguridad.

El resultado es, por ejemplo, una página simple que contiene todas las publicaciones de Addy.

Limitaciones

En este momento, no podemos conectar con facilidad el proceso de compilación de Eleven porque es declarativo, en lugar de imperativo: tú describes lo que quieres, en lugar de cómo quieres. Es difícil ejecutar Eleven como parte de una herramienta de compilación más grande, ya que solo se puede invocar a través de su interfaz de línea de comandos.

Creación de plantillas

web.dev usa el sistema de plantillas Nunjucks que Mozilla desarrolló originalmente. Nunjucks tiene las funciones de plantillas típicas, como bucles y condicionales, pero también nos permite definir códigos cortos que generan más código HTML o invocan otra lógica.

Al igual que la mayoría de los equipos que crean sitios de contenido estático, comenzamos con unos pocos y, hasta ahora, agregamos códigos cortos (aproximadamente 20). La mayoría de ellos simplemente generan más código HTML (incluidos nuestros componentes web personalizados). Por ejemplo:

{% Aside %}
See how Asides work in the web.dev codebase
{% endAside %}

Terminará de la siguiente manera:

Sin embargo, en realidad, se crea un archivo HTML que se ve así:

<div class="aside color-state-info-text">
<p>See how Asides work in the web.dev codebase</p>
</div>

Si bien está fuera del alcance de esta publicación, web.dev también usa códigos cortos como un tipo de lenguaje de metaprogramación. Los códigos cortos aceptan argumentos, y uno de ellos es el contenido incluido. No es necesario que los códigos cortos devuelvan nada, por lo que se pueden usar para crear un estado o activar algún otro comportamiento. 🤔💭

Guion

Como se mencionó antes, debido a que web.dev es un sitio estático, se puede entregar y usar sin JavaScript y con navegadores más antiguos que no sean compatibles con type="module" ni nuestro otro código moderno. Esta es una parte muy importante de nuestro enfoque para que web.dev sea accesible para todos.

Sin embargo, nuestro código para navegadores actualizados consta de dos partes principales:

  1. Código de arranque, que incluye código para el estado global, Analytics y enrutamiento SPA
  2. Código y CSS para componentes web que mejoran progresivamente el sitio

El código de arranque es bastante sencillo: web.dev puede cargar páginas nuevas como una aplicación de una sola página (SPA), por lo que instalamos un objeto de escucha global que escucha clics en elementos <a href="..."> locales. El modelo SPA nos ayuda a mantener el estado global de la sesión actual del usuario, ya que, de lo contrario, cada carga de página nueva activaría llamadas a Firebase para acceder al estado de acceso del usuario.

También especificamos un par de puntos de entrada diferentes en nuestro sitio en función de la URL que alcances y cargamos la correcta con import() dinámico. Esto reduce la cantidad de bytes que necesitan nuestros usuarios para que el sitio se mejore con código.

Componentes web

Los componentes web son elementos personalizados que encapsulan la funcionalidad del entorno de ejecución proporcionadas en JavaScript y se identifican con nombres personalizados, como <web-codelab>. El diseño se presta bien a sitios mayormente estáticos como web.dev: el navegador administra el ciclo de vida de un elemento a medida que se actualiza el HTML del sitio, y esto informa correctamente cualquier elemento cuando se adjuntan o separan de la página. Y los navegadores anticuados simplemente ignoran los componentes web y renderizan lo que quede en el DOM.

Cada componente web es una clase con métodos que incluyen connectedCallback(), disconnectedCallback() y attributeChangedCallback(). La mayoría de los elementos personalizados de web.dev se heredan en LitElement, que proporciona una base simple para componentes complejos.

Si bien web.dev usa componentes web en muchas páginas, no es más necesario que en la página Medición. Dos elementos proporcionan la mayor parte de la funcionalidad que se ve en esta página:

<web-url-chooser-container></web-url-chooser-container>
<web-lighthouse-scores-container></web-lighthouse-scores-container>

Estos elementos crean más elementos que proporcionan más funcionalidad. Es importante destacar que estos elementos son solo parte de nuestro código fuente de Markdown normal, y nuestro equipo de contenido puede agregar funcionalidades extendidas a cualquier página, no solo al nodo de medición.

Nuestros componentes web suelen utilizar el modelo Container Component, que se volvió popular por React, aunque este ahora está un poco aprobado. Cada elemento -container se conecta a nuestro estado global (proporcionado por unistore) y, luego, renderiza un elemento visual, que, a su vez, renderiza nodos reales del DOM con estilo o alguna otra funcionalidad integrada.

Un diagrama que muestra la relación entre el estado global y los elementos HTML que lo usan.
Estado global y un componente web

Nuestros componentes web más complejos existen para visualizar acciones y estados globales. Por ejemplo, web.dev te permite auditar tu sitio favorito y, luego, salir de la página Medición. Si regresas, verás que la tarea sigue en curso.

Nuestros componentes simples simplemente mejoran el contenido que por lo general es estático o crean visualizaciones asombrosas (por ejemplo, cada gráfico de líneas tiene su propio <web-sparkline-chart>), que no tiene relación con el estado global.

Conversemos

El equipo de ingeniería de web.dev (Rob, Ewa, Michael y Sam) se comunicarán contigo para realizar análisis más detallados próximamente.

Esperamos que escuchar cómo hacemos las cosas te haya dado algunas ideas para tus propios proyectos. Comunícate con nosotros en Twitter si tienes preguntas o solicitudes de temas para este blog.